diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-07-16 22:41:20 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-07-16 22:41:20 +0300 |
commit | 9a2df634f322d174014ac8d5090bfa87a25bb775 (patch) | |
tree | 4346c4b392898c087c55fd20ca998eb39294027b /src/guile.c | |
parent | 8d89ce088cc25786cb9520f67e9fe81c86c70277 (diff) | |
download | idest-9a2df634f322d174014ac8d5090bfa87a25bb775.tar.gz idest-9a2df634f322d174014ac8d5090bfa87a25bb775.tar.bz2 |
Major rewrite.
* src/idest.h (ed_item): Remove union, leave only value instead.
<ref>: New member.
(describe_option,verbose_option,all_frames): New externs.
(set_frame_value): Return int.
(IDEST_OK,IDEST_ERR_*): New constants.
(_idest_errstr, _idest_nerrs): New externs.
(idest_frame_cmp_t,idest_frame_encoder_t)
(idest_frame_decoder_t): New typedefs.
(idest_frametab): New struct.
(idest_frame_lookup)
(find_matching_frame): New protos.
(ed_list_add_item)
(ed_list_print,ed_list_add_assignment)
(ed_list_clear,ed_item_matches_frame)
(ed_item_set_comment_fields): Remove.
(qv_free,input_list_locate)
(parse_ed_items): New protos.
* src/idop.c: Rewrite.
* src/.gitignore: Add src/frametab.c
* src/Makefile.am (idest_SOURCES): Add editem.c and frametab.c
(BUILT_SOURCES): Add frametab.c
(.gperf.c): New rule
(GPERF_FLAGS): New variable.
* src/editem.c: New source.
* src/frametab.gperf: New source.
* src/cmdline.opt: Use input_list_add_assignment in --set handler.
* src/guile.c (frame_to_scm,scm_to_tag): Rewrite using the new
logic.
Diffstat (limited to 'src/guile.c')
-rw-r--r-- | src/guile.c | 199 |
1 files changed, 139 insertions, 60 deletions
diff --git a/src/guile.c b/src/guile.c index c8b6e47..36427cf 100644 --- a/src/guile.c +++ b/src/guile.c @@ -30,10 +30,9 @@ SCM_GLOBAL_VARIABLE_INIT(sym_idest_main, "idest-main", SCM_EOL); SCM_GLOBAL_VARIABLE_INIT(sym_idest_readonly, "idest-readonly", SCM_BOOL_T); SCM_GLOBAL_SYMBOL(idest_text, "text"); -SCM_GLOBAL_SYMBOL(idest_lang, "lang"); -SCM_GLOBAL_SYMBOL(idest_condesc, "condesc"); SCM_GLOBAL_SYMBOL(idest_descr, "descr"); +SCM_GLOBAL_SYMBOL(idest_error, "idest-error"); static SCM eval_catch_body(void *list) @@ -224,52 +223,54 @@ field_to_scm(union id3_field *field, int genre) static SCM frame_to_scm(struct id3_frame *frame) { - SCM val; - union id3_field *field; - - switch (frame_to_item_id(frame->id)) { - case item_comment: - field = id3_frame_field(frame, 3); - val = scm_list_1( - scm_cons(idest_text, - scm_from_locale_string( - field_to_string(field, 0)))); - - field = id3_frame_field(frame, 1); - if (!field) - break; - val = scm_cons( - scm_cons(idest_lang, - scm_from_locale_string( - field_to_string(field, 0))), - val); - field = id3_frame_field(frame, 2); - if (!field) - break; - val = scm_cons( - scm_cons(idest_condesc, - scm_from_locale_string( - field_to_string(field, 0))), - val); - break; - - case item_genre: - val = scm_list_1( - scm_cons(idest_text, - field_to_scm(id3_frame_field(frame, 1), 1))); - break; - - default: - val = scm_list_1( - scm_cons(idest_text, - field_to_scm(id3_frame_field(frame, 1), 0))); - break; + int rc; + int i; + const struct idest_frametab *ft = idest_frame_lookup(frame->id); + struct ed_item itm; + SCM head = SCM_EOL, tail = SCM_EOL; + + if (!ft) + scm_error(idest_error, "frame_to_scm", + "frame ~A: ~A (~A)", + scm_list_3(scm_from_locale_string(frame->id), + scm_from_locale_string(idest_strerror(IDEST_ERR_BADTYPE)), + scm_from_int(IDEST_ERR_BADTYPE)), + SCM_BOOL_F); + + ed_item_zero(&itm); + itm.name = xstrdup(frame->id); + memcpy(itm.id, frame->id, 4); + + rc = ft->decode(&itm, frame); + if (rc) + scm_error(idest_error, "frame_to_scm", + "frame ~A: ~A (~A)", + scm_list_3(scm_from_locale_string(frame->id), + scm_from_locale_string(idest_strerror(rc)), + scm_from_int(rc)), + SCM_BOOL_F); + + head = scm_cons(scm_cons(idest_text, + scm_from_locale_string(itm.value)), + SCM_EOL); + tail = head; + + for (i = 0; i < itm.qc; i++) { + SCM cell; + + cell = scm_cons( + scm_cons(scm_string_to_symbol(scm_from_locale_string(ft->qv[i])), + scm_from_locale_string(itm.qv[i])), + SCM_EOL); + SCM_SETCDR(tail, cell); + tail = cell; } + ed_item_free_content(&itm); return scm_cons(scm_from_locale_string(frame->id), scm_cons( - scm_cons(idest_descr, - scm_from_locale_string(frame->description)), - val)); + scm_cons(idest_descr, + scm_from_locale_string(frame->description)), + head)); } static SCM @@ -297,11 +298,74 @@ tag_to_scm(struct id3_tag *tag) } static int +qvname_to_ind(const struct idest_frametab *ft, const char *name) +{ + int i; + + for (i = 0; i < ft->qc; i++) + if (strcmp(ft->qv[i], name) == 0) + return i; + return -1; +} + +static void +ed_item_from_scm(struct ed_item *itm, SCM list) +{ + const struct idest_frametab *ft = idest_frame_lookup(itm->id); + + if (!ft) + scm_error(idest_error, "ed_item_from_scm", + "frame ~A: ~A (~A)", + scm_list_3(scm_from_locale_string(itm->id), + scm_from_locale_string(idest_strerror(IDEST_ERR_BADTYPE)), + scm_from_int(IDEST_ERR_BADTYPE)), + SCM_BOOL_F); + itm->qc = ft->qc; + itm->qv = xcalloc(itm->qc, sizeof(itm->qv[0])); + for (; !scm_is_null(list) && scm_is_pair(list); list = SCM_CDR(list)) { + SCM elt = SCM_CAR(list); + SCM key; + char *s; + int n; + + if (!scm_is_pair(elt)) + scm_misc_error(NULL, + "Wrong element type: ~S", + scm_list_1(elt)); + key = SCM_CAR(elt); + if (key == idest_text || key == idest_descr) + continue; + s = scm_to_locale_string(scm_symbol_to_string(key)); + n = qvname_to_ind(ft, s); + if (n == -1) { + /* FIXME: field name? */ + scm_error(idest_error, "ed_item_from_scm", + "frame ~A: ~A (~A)", + scm_list_3(scm_from_locale_string(itm->id), + scm_from_locale_string(idest_strerror(IDEST_ERR_BADFIELD)), + scm_from_int(IDEST_ERR_BADFIELD)), + SCM_BOOL_F); + } + free(s); + itm->qv[n] = scm_to_locale_string(SCM_CDR(elt)); + } +#if 0 + /* FIXME: Provide defaults? */ + for (i = 0; i < itm->qc; i++) { + if (!itm->qv[i]) + itm->qv[i] = xstrdup(""); + } +#endif +} + +static int scm_to_tag(SCM scm, struct id3_tag *tag) { int modified = 0; for (; !scm_is_null(scm) && scm_is_pair(scm); scm = SCM_CDR(scm)) { + int rc; + struct id3_frametype const *frametype; struct id3_frame *frame; struct ed_item itm; char *id; @@ -318,22 +382,29 @@ scm_to_tag(SCM scm, struct id3_tag *tag) "Wrong car type: ~S", scm_list_1(elt)); id = scm_to_locale_string(x); - - memset(&itm, 0, sizeof(itm)); + frametype = id3_frametype_lookup(id, strlen(id)); + if (!id) + scm_error(idest_error, "guile-transform", + "frame ~A: ~A (~A)", + scm_list_3(x, + scm_from_locale_string(idest_strerror(IDEST_ERR_BADTYPE)), + scm_from_int(IDEST_ERR_BADTYPE)), + SCM_BOOL_F); + + ed_item_zero(&itm); + memcpy(itm.id, id, sizeof(itm.id)); + itm.name = id; + x = SCM_CDR(elt); if (scm_is_string(x)) { - itm.v.value = scm_to_locale_string(x); + itm.value = scm_to_locale_string(x); } else if (scm_is_pair(x) && - (text = scm_assoc_ref(x, idest_text)) != SCM_BOOL_F) { - itm.v.value = scm_to_locale_string(text); - text = scm_assoc_ref(x, idest_lang); - if (text != SCM_BOOL_F) - itm.lang = scm_to_locale_string(text); - text = scm_assoc_ref(x, idest_condesc); - if (text != SCM_BOOL_F) - itm.condesc = scm_to_locale_string(text); + (text = scm_assoc_ref(x, idest_text)) != + SCM_BOOL_F) { + itm.value = scm_to_locale_string(text); + ed_item_from_scm(&itm, x); } else scm_misc_error(NULL, "Wrong cdr type: ~S", @@ -341,13 +412,21 @@ scm_to_tag(SCM scm, struct id3_tag *tag) frame = id3_frame_new(id); if (id3_tag_attachframe(tag, frame)) + /* FIXME: user scm_error */ error(1, 0, "cannot attach new frame"); - set_frame_value(frame, &itm); + rc = set_frame_value(frame, &itm); + if (rc) + scm_error(idest_error, "guile-transform", + "frame ~A: ~A (~A)", + scm_list_3(scm_from_locale_string(frame->id), + scm_from_locale_string(idest_strerror(rc)), + scm_from_int(rc)), + SCM_BOOL_F); + modified |= 1; free(id); - free(itm.v.value); - free(itm.condesc); - free(itm.lang); + free(itm.value); + qv_free(itm.qc, itm.qv); } return modified; } |