aboutsummaryrefslogtreecommitdiff
path: root/src/guile.c
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2011-07-16 22:41:20 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2011-07-16 22:41:20 +0300
commit9a2df634f322d174014ac8d5090bfa87a25bb775 (patch)
tree4346c4b392898c087c55fd20ca998eb39294027b /src/guile.c
parent8d89ce088cc25786cb9520f67e9fe81c86c70277 (diff)
downloadidest-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.c199
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;
}

Return to:

Send suggestions and report system problems to the System administrator.