aboutsummaryrefslogtreecommitdiff
path: root/src/idop.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/idop.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/idop.c')
-rw-r--r--src/idop.c567
1 files changed, 305 insertions, 262 deletions
diff --git a/src/idop.c b/src/idop.c
index 45fd148..fe9c6f5 100644
--- a/src/idop.c
+++ b/src/idop.c
@@ -18,231 +18,136 @@
18#include <file.h> 18#include <file.h>
19#include <signal.h> 19#include <signal.h>
20 20
21gl_list_t input_list, output_list;
22
21void 23void
22set_frame_value(struct id3_frame *frame, const struct ed_item *item) 24input_list_add_assignment(const char *name, const char *value)
23{ 25{
24 const char *value = item->v.value; 26 struct ed_item *itm;
25 union id3_field *field; 27
26 enum id3_field_textencoding encoding = 28 if (!input_list)
27 (latin1_option ? ID3_FIELD_TEXTENCODING_ISO_8859_1 29 input_list = ed_list_create();
28 : ID3_FIELD_TEXTENCODING_UTF_8); 30 itm = ed_item_from_frame_spec(name, strlen(name));
29 id3_ucs4_t *ucs4; 31 itm->value = xstrdup(value);
30 const char *condesc; 32 gl_list_add_last(input_list, itm);
33}
34
35struct ed_item const *
36input_list_locate(struct id3_frame *frame, idest_frame_cmp_t cmp)
37{
38 gl_list_iterator_t itr;
39 const void *p;
40 const struct ed_item *item = NULL;
31 41
32 switch (frame_to_item_id(frame->id)) { 42 itr = gl_list_iterator(input_list);
33 default: 43 while (gl_list_iterator_next(&itr, &p, NULL)) {
34 field = id3_frame_field(frame, 0); 44 item = p;
35 id3_field_settextencoding(field, encoding); 45 if (memcmp(item->id, frame->id, 4) == 0 &&
36 46 (!cmp || item->qc == 0 || cmp(frame, item) == 0))
37 if (latin1_option) 47 break;
38 ucs4 = id3_latin1_ucs4duplicate( 48 item = NULL;
39 (const id3_latin1_t *) value);
40 else
41 ucs4 = id3_utf8_ucs4duplicate(
42 (const id3_utf8_t *)value);
43
44 field = id3_frame_field(frame, 1);
45 id3_field_setstrings(field, 1, &ucs4);
46 free(ucs4);
47 break;
48
49 case item_comment:
50 /* Field 0: Encoding */
51 field = id3_frame_field(frame, 0);
52 id3_field_settextencoding(field, encoding);
53 /* Field 1: Language */
54 field = id3_frame_field(frame, 1);
55 id3_field_setlanguage(field, item->lang ? item->lang : "eng");
56 /* Field 2: Short content descriptor */
57 field = id3_frame_field(frame, 2);
58 condesc = item->condesc ? item->condesc : "";
59 if (latin1_option)
60 ucs4 = id3_latin1_ucs4duplicate(
61 (const id3_latin1_t *)condesc);
62 else
63 ucs4 = id3_utf8_ucs4duplicate(
64 (const id3_utf8_t *)condesc);
65 id3_field_setstring(field, ucs4);
66 /* Field 3: Comment */
67 field = id3_frame_field(frame, 3);
68 if (latin1_option)
69 ucs4 = id3_latin1_ucs4duplicate(
70 (const id3_latin1_t *) value);
71 else
72 ucs4 = id3_utf8_ucs4duplicate(
73 (const id3_utf8_t *)value);
74 id3_field_setfullstring(field, ucs4);
75 free(ucs4);
76 break;
77 } 49 }
50 gl_list_iterator_free(&itr);
51 return item;
78} 52}
79 53
80void 54void
81safe_id3_file_update_and_close(struct id3_file *file) 55parse_ed_items(const char *arg)
82{ 56{
83 sigset_t set, oldset; 57 if (!input_list)
84 58 input_list = ed_list_create();
85 sigemptyset(&set); 59 while (*arg) {
86 sigaddset(&set, SIGINT); 60 struct ed_item *itm;
87 sigaddset(&set, SIGTERM); 61 size_t len = strcspn(arg, " \t,");
88 62
89 sigprocmask(SIG_BLOCK, &set, &oldset); 63 itm = ed_item_from_frame_spec(arg, len);
90 id3_file_update(file); 64 gl_list_add_last(input_list, itm);
91 id3_file_close(file); 65 arg += len;
92 sigprocmask(SIG_SETMASK, &oldset, NULL); 66 if (!*arg)
93} 67 break;
94 68 arg += strspn(arg, " \t,");
95static void
96update_frame(struct id3_tag *tag, const struct ed_item *item)
97{
98 struct id3_frame *frame = id3_tag_findframe(tag, item->id, 0);
99 if (!frame) {
100 frame = id3_frame_new(item->id);
101 if (id3_tag_attachframe(tag, frame))
102 error(1, 0, "cannot attach new frame");
103 } else if (strcmp(item->id, ID3_FRAME_COMMENT) == 0
104 && item->condesc) {
105 /* Special handling for comments */
106 int i = 0;
107
108 do {
109 union id3_field *field = id3_frame_field(frame, 2);
110 char *s;
111
112 if (field && (s = field_to_string(field, 0))
113 && strcmp(s, item->condesc) == 0)
114 break;
115 } while (frame = id3_tag_findframe(tag, item->id, ++i));
116 if (!frame) {
117 frame = id3_frame_new(item->id);
118 if (id3_tag_attachframe(tag, frame))
119 error(1, 0, "cannot attach new frame");
120 }
121 } else {
122 struct id3_frame *fp;
123
124 while (fp = id3_tag_findframe(tag, item->id, 1)) {
125 id3_tag_detachframe(tag, fp);
126 id3_frame_delete(fp);
127 }
128 } 69 }
129 set_frame_value(frame, item);
130} 70}
131 71
132static int 72void
133build_tag_options(struct id3_tag *tag, unsigned long location, 73input_list_init()
134 id3_length_t length, void *data)
135{ 74{
136 unsigned int ver = id3_tag_version(tag); 75 if (all_frames)
137 76 input_list = NULL;
138 if (ID3_TAG_VERSION_MAJOR(ver) == 1) 77 else if (!input_list)
139 *(unsigned int*)data |= IDEST_ID3V_1; 78 parse_ed_items(DEFAULT_ED_LIST);
140 else 79}
141 *(unsigned int*)data |= IDEST_ID3V_2; 80
142 return 0; 81void
82output_list_append(struct ed_item const *item, struct ed_item const *ref)
83{
84 struct ed_item *elt = ed_item_dup(item);
85 if (!output_list)
86 output_list = ed_list_create();
87 elt->ref = ref;
88 gl_list_add_last(output_list, elt);
143} 89}
144 90
145void 91void
146set_tags(const char *name) 92output_list_print()
147{ 93{
148 struct id3_file *file; 94 gl_list_iterator_t itr;
149 struct id3_tag *tag; 95 const void *p;
150 int modified = 0;
151 int vopt = version_option;
152
153 file = id3_file_open(name, ID3_FILE_MODE_READWRITE);
154 if (!file)
155 error(1, errno, "cannot open file %s", name);
156 tag = id3_file_tag(file);
157 if (!tag)
158 abort(); /* FIXME */
159 96
160 if (ed_list) { 97 if (all_frames) {
161 gl_list_iterator_t itr; 98 itr = gl_list_iterator(output_list);
162 const void *p;
163
164 itr = gl_list_iterator(ed_list);
165 while (gl_list_iterator_next(&itr, &p, NULL)) { 99 while (gl_list_iterator_next(&itr, &p, NULL)) {
166 const struct ed_item *item = p; 100 const struct ed_item *item = p;
167 update_frame(tag, item); 101 ed_item_print(item);
168 modified |= 1;
169 } 102 }
170 gl_list_iterator_free(&itr); 103 gl_list_iterator_free(&itr);
171 } 104 } else {
172 105 itr = gl_list_iterator(input_list);
173 /* FIXME */ 106 while (gl_list_iterator_next(&itr, &p, NULL)) {
174 modified |= guile_transform(name, tag); 107 int printed = 0;
175 108 const struct ed_item *input_item = p;
176 if (convert_version == 0) { 109 if (output_list) {
177 if (modified && !vopt) { 110 gl_list_iterator_t oitr;
178 if (id3_file_struct_ntags(file)