aboutsummaryrefslogtreecommitdiff
path: root/src/idop.c
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2011-07-17 15:48:21 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2011-07-17 16:01:32 +0300
commit991737de5e78fecc0073324d18dd2b717c16090c (patch)
treece071614c018b6bc59cc26983cbb85afbffbafbb /src/idop.c
parente952b9e1db69b1752d97c645740074b886927807 (diff)
downloadidest-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.c101
1 files changed, 66 insertions, 35 deletions
diff --git a/src/idop.c b/src/idop.c
index 4dafb25..71e84e3 100644
--- a/src/idop.c
+++ b/src/idop.c
@@ -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);
}
-
-

Return to:

Send suggestions and report system problems to the System administrator.