diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-07-17 15:48:21 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-07-17 16:01:32 +0300 |
commit | 991737de5e78fecc0073324d18dd2b717c16090c (patch) | |
tree | ce071614c018b6bc59cc26983cbb85afbffbafbb /src/idop.c | |
parent | e952b9e1db69b1752d97c645740074b886927807 (diff) | |
download | idest-991737de5e78fecc0073324d18dd2b717c16090c.tar.gz idest-991737de5e78fecc0073324d18dd2b717c16090c.tar.bz2 |
New feature: copy tags between files.
* NEWS: Update.
* src/cmdline.opt: New option --copy.
Call parse_filter_items instead of parse_ed_items.
* src/editem.c (ed_list_locate): New function.
* src/idest.h (source_file, source_tag): New externs.
(input_list_locate,parse_ed_items): Remove.
(parse_filter_items): New proto.
(ed_list_locate): New proto.
* src/idop.c (filter_list): New list.
(input_list_locate): Remove. Use ed_list_locate with
a proper first argument. All uses updated.
(parse_ed_items): Take 2 args.
(parse_filter_items): New function.
(input_list_init): Rename to filter_list_init.
Operate on filter list.
(output_list_print): Operate on filter_list.
(copy_source_tags): New static function.
(set_tags): Call copy_source_tags.
(del_tags): Operate on filter_list.
* src/main.c (source_file,source_tag): New variables.
(main): Read source tags if --copy is requested.
Diffstat (limited to 'src/idop.c')
-rw-r--r-- | src/idop.c | 101 |
1 files changed, 66 insertions, 35 deletions
@@ -18,7 +18,7 @@ #include <file.h> #include <signal.h> -gl_list_t input_list, output_list; +gl_list_t input_list, output_list, filter_list; void input_list_add_assignment(const char *name, const char *value) @@ -32,36 +32,19 @@ input_list_add_assignment(const char *name, const char *value) gl_list_add_last(input_list, itm); } -struct ed_item const * -input_list_locate(struct id3_frame *frame, idest_frame_cmp_t cmp) -{ - gl_list_iterator_t itr; - const void *p; - const struct ed_item *item = NULL; - - itr = gl_list_iterator(input_list); - while (gl_list_iterator_next(&itr, &p, NULL)) { - item = p; - if (memcmp(item->id, frame->id, 4) == 0 && - (!cmp || item->qc == 0 || cmp(frame, item) == 0)) - break; - item = NULL; - } - gl_list_iterator_free(&itr); - return item; -} - void -parse_ed_items(const char *arg) +parse_ed_items(gl_list_t *plist, const char *arg) { - if (!input_list) - input_list = ed_list_create(); + gl_list_t list; + if (!*plist) + *plist = ed_list_create(); + list = *plist; while (*arg) { struct ed_item *itm; size_t len = strcspn(arg, " \t,"); itm = ed_item_from_frame_spec(arg, len); - gl_list_add_last(input_list, itm); + gl_list_add_last(list, itm); arg += len; if (!*arg) break; @@ -70,12 +53,18 @@ parse_ed_items(const char *arg) } void -input_list_init() +parse_filter_items(const char *arg) +{ + parse_ed_items(&filter_list, arg); +} + +void +query_filter_list_init() { if (all_frames) - input_list = NULL; - else if (!input_list) - parse_ed_items(DEFAULT_ED_LIST); + filter_list = NULL; + else if (!filter_list) + parse_filter_items(DEFAULT_ED_LIST); } void @@ -104,7 +93,7 @@ output_list_print() } gl_list_iterator_free(&itr); } else { - itr = gl_list_iterator(input_list); + itr = gl_list_iterator(filter_list); while (gl_list_iterator_next(&itr, &p, NULL)) { int printed = 0; const struct ed_item *input_item = p; @@ -368,6 +357,47 @@ update_frame(struct id3_tag *tag, const struct ed_item *item) return ft->encode(frame, item); } +static int +copy_source_tags(struct id3_tag *tag) +{ + int i; + struct id3_frame *frame; + + if (!source_tag) + return 0; + + for (i = 0; (frame = id3_tag_findframe(source_tag, NULL, i)); i++) { + const struct idest_frametab *ft = + idest_frame_lookup(frame->id); + if (!ft) { + if (verbose_option) + error(0, 0, + "%s: unsupported frame", frame->id); + continue; + } + if (!filter_list || + ed_list_locate(filter_list, frame, ft->cmp)) { + int rc; + struct ed_item itm; + + ed_item_zero(&itm); + itm.name = xstrdup(frame->id); + memcpy(itm.id, frame->id, 4); + if (ft->decode(&itm, frame)) { + error(0, 0, "%s: decoding failed", frame->id); + continue; + } + rc = update_frame(tag, &itm); + if (rc) + error(1, 0, + "cannot set frame %s: %s", + frame->id, idest_strerror(rc)); + ed_item_free_content(&itm); + } + } + return 1; +} + void set_tags(const char *name) { @@ -400,6 +430,8 @@ set_tags(const char *name) gl_list_iterator_free(&itr); } + modified |= copy_source_tags(tag); + /* FIXME */ modified |= guile_transform(name, tag); @@ -449,14 +481,15 @@ del_tags(const char *name) tag = id3_file_tag(file); if (!tag) abort(); /* FIXME */ - if (input_list) { + if (filter_list) { int i; struct id3_frame *frame; for (i = 0; (frame = id3_tag_findframe(tag, NULL, i)); ) { const struct idest_frametab *ft = idest_frame_lookup(frame->id); - if (input_list_locate(frame, ft ? ft->cmp : NULL)) { + if (ed_list_locate(filter_list, + frame, ft ? ft->cmp : NULL)) { id3_tag_detachframe(tag, frame); id3_frame_delete(frame); } else @@ -503,7 +536,7 @@ show_tags(struct id3_tag *tag) } else { struct ed_item const *ref; - ref = input_list_locate(frame, ft->cmp); + ref = ed_list_locate(filter_list, frame, ft->cmp); if (ref) { struct ed_item outitm; ed_item_zero(&outitm); @@ -529,7 +562,7 @@ query_tags(const char *name) struct id3_file *file; struct id3_tag *tag; - input_list_init(); + query_filter_list_init(); file = id3_file_open(name, ID3_FILE_MODE_READONLY); if (!file) @@ -576,5 +609,3 @@ info_id3(const char *name) id3_file_struct_iterate(file, prinfo, NULL); id3_file_close(file); } - - |