diff options
-rw-r--r-- | NEWS | 28 | ||||
-rw-r--r-- | src/idest.h | 2 | ||||
-rw-r--r-- | src/idop.c | 74 | ||||
-rw-r--r-- | src/main.c | 18 |
4 files changed, 99 insertions, 23 deletions
@@ -1,4 +1,4 @@ -IdEst -- history of user-visible changes. 2011-07-10 +IdEst -- history of user-visible changes. 2011-07-11 Copyright (C) 2009-2011 Sergey Poznyakoff See the end of file for copying conditions. @@ -16,6 +16,32 @@ idest --info shows information about input file structure. The argument, if supplied, is a comma-separated list of the frame names to delete. +* Comment classes are displayed at the output. + +In query mode, non-empty comment classes are printed in square +brackets before their corresponding values. All comment fields are +concatenated and shown as a single one, e.g.: + +comment: Test [RESULT] value [CDDB_TrackNumber] 8. + +In all-frames mode, each comment field is shown individually, with the +corresponding language and class: + +comment:eng:RESULT: value +comment:eng:CDDB_TrackNumber: 8 + +* When setting comment fields, language and class qualifiers are accepted. + +The syntax for setting comment fields is extended as follows: + + --set comment:LANG:CLASS=VALUE + +Where LANG is a valid 3-character language code and CLASS is the +comment class. If LANG is omitted, "eng" is assumed. Examples: + + --set comment:esp:mi-comentario="Valor de prueba" + --set comment::my-comment="Test value" + * Guile startup files. When run with the --script option, idest searches for files .idest.scm, diff --git a/src/idest.h b/src/idest.h index 4fe1906..5523938 100644 --- a/src/idest.h +++ b/src/idest.h @@ -75,7 +75,7 @@ extern char *guile_function; extern char **guile_argv; /* idop.c */ -void set_frame_value(struct id3_frame *frame, const char *value); +void set_frame_value(struct id3_frame *frame, const struct ed_item *item); void set_tags(const char *name); void del_tags(const char *name); char *idest_ucs4_cvt(id3_ucs4_t const *ucs4); @@ -19,13 +19,15 @@ #include <signal.h> void -set_frame_value(struct id3_frame *frame, const char *value) +set_frame_value(struct id3_frame *frame, const struct ed_item *item) { + const char *value = item->v.value; union id3_field *field; enum id3_field_textencoding encoding = (latin1_option ? ID3_FIELD_TEXTENCODING_ISO_8859_1 : ID3_FIELD_TEXTENCODING_UTF_8); id3_ucs4_t *ucs4; + const char *class; switch (frame_id(frame->id)) { case item_title: @@ -53,8 +55,19 @@ set_frame_value(struct id3_frame *frame, const char *value) /* Field 0: Encoding */ field = id3_frame_field(frame, 0); id3_field_settextencoding(field, encoding); - /* FIXME: Field 1: Language */ - /* FIXME: Field 2: Short descr */ + /* Field 1: Language */ + field = id3_frame_field(frame, 1); + id3_field_setlanguage(field, item->lang ? item->lang : "eng"); + /* Field 2: Short descr */ + field = id3_frame_field(frame, 2); + class = item->class ? item->class : ""; + if (latin1_option) + ucs4 = id3_latin1_ucs4duplicate( + (const id3_latin1_t *)class); + else + ucs4 = id3_utf8_ucs4duplicate( + (const id3_utf8_t *)class); + id3_field_setstring(field, ucs4); /* Field 3: Comment */ field = id3_frame_field(frame, 3); if (latin1_option) @@ -87,6 +100,44 @@ safe_id3_file_update_and_close(struct id3_file *file) sigprocmask(SIG_SETMASK, &oldset, NULL); } +static void +update_frame(struct id3_tag *tag, const struct ed_item *item) +{ + struct id3_frame *frame = id3_tag_findframe(tag, item->id, 0); + if (!frame) { + frame = id3_frame_new(item->id); + if (id3_tag_attachframe(tag, frame)) + error(1, 0, "cannot attach new frame"); + } else if (strcmp(item->id, ID3_FRAME_COMMENT) == 0 + && item->class) { + /* Special handling for comments */ + int i = 0; + union id3_field *field; + + do { + union id3_field *field = id3_frame_field(frame, 2); + char *s; + + if (field && (s = field_to_string(field, 0)) + && strcmp(s, item->class) == 0) + break; + } while (frame = id3_tag_findframe(tag, item->id, ++i)); + if (!frame) { + frame = id3_frame_new(item->id); + if (id3_tag_attachframe(tag, frame)) + error(1, 0, "cannot attach new frame"); + } + } else { + struct id3_frame *fp; + + while (fp = id3_tag_findframe(tag, item->id, 1)) { + id3_tag_detachframe(tag, fp); + id3_frame_delete(fp); + } + } + set_frame_value(frame, item); +} + void set_tags(const char *name) { @@ -108,22 +159,7 @@ set_tags(const char *name) itr = gl_list_iterator(ed_list); while (gl_list_iterator_next(&itr, &p, NULL)) { const struct ed_item *item = p; - struct id3_frame *frame - = id3_tag_findframe(tag, item->id, 0); - if (!frame) { - frame = id3_frame_new(item->id); - if (id3_tag_attachframe(tag, frame)) - error(1, 0, "cannot attach new frame"); - } else { - struct id3_frame *fp; - - while (fp = id3_tag_findframe(tag, item->id, - 1)) { - id3_tag_detachframe(tag, fp); - id3_frame_delete(fp); - } - } - set_frame_value(frame, item->v.value); + update_frame(tag, item); modified |= 1; } gl_list_iterator_free(&itr); @@ -216,9 +216,23 @@ void ed_list_add_assignment(const char *name, const char *value) { struct ed_item *itm; - + size_t n; + ed_list_create(); - itm = ed_list_new_item(name, strlen(name)); + n = strcspn(name, ":"); + itm = ed_list_new_item(name, n); + if (name[n] == ':') { + name += n + 1; + if (name[0] != ':') { + n = strcspn(name, ":"); + itm->lang = xmalloc(n + 1); + memcpy(itm->lang, name, n); + itm->lang[n] = 0; + name += n; + } + if (name[0] == ':') + itm->class = xstrdup(name + 1); + } itm->v.value = xstrdup(value); } |