aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2009-03-17 11:59:19 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2009-03-17 11:59:19 +0200
commite25a44d9bdc40ca8bf2efcd12ed73e2104fdb360 (patch)
treeb805996c317f299b5421d6f48c9528664da00981
parenta0a067bde62b828a09f165524dc993580ac7e450 (diff)
downloadidest-e25a44d9bdc40ca8bf2efcd12ed73e2104fdb360.tar.gz
idest-e25a44d9bdc40ca8bf2efcd12ed73e2104fdb360.tar.bz2
Improve scripting, implement v1->v2 conversion, implement --delete command.
* libid3tag/file.c (v2_write): Change for make it possible to convert v1 to v2. * src/.gitignore: Add guile.x. * src/Makefile.am (idest_SOURCES): Add guile.x (BUILT_SOURCES): Add guile.x (SUFFIXES): Add .x (.c.x): New rule * src/cmdline.opt: New option: --trace. * src/guile.c: Rewrite. * src/idest.h (MODE_QUERY, MODE_MOD, MODE_DELETE): New defines (from main.c). (guile_transform, guile_list): New protos. (guile_apply): Remove. * src/idop.c (set_tags): Handle convert_version == 2. (del_tags): New function. * src/main.c (del_id3): Call del_tags
-rw-r--r--libid3tag/file.c20
-rw-r--r--src/.gitignore1
-rw-r--r--src/Makefile.am11
-rw-r--r--src/cmdline.opt10
-rw-r--r--src/guile.c111
-rw-r--r--src/idest.h10
-rw-r--r--src/idop.c39
-rw-r--r--src/main.c9
8 files changed, 161 insertions, 50 deletions
diff --git a/libid3tag/file.c b/libid3tag/file.c
index 5ad025b..9210571 100644
--- a/libid3tag/file.c
+++ b/libid3tag/file.c
@@ -704,17 +704,17 @@ int v2_write(struct id3_file *file,
if (!tmp)
return -1;
- rc = copy_block(file->iofile, tmp, 0, file->tags[0].location);
- if (rc == 0) {
- if (data && length)
- rc = fwrite(data, length, 1, tmp) != 1;
- else
- rc = 0;
+ if (data && length)
+ rc = fwrite(data, length, 1, tmp) != 1;
+ else
+ rc = 0;
- if (rc == 0)
- rc = copy_block(file->iofile, tmp,
- file->tags[0].location + file->tags[0].length, -1);
- }
+ if (rc == 0)
+ rc = copy_block(file->iofile, tmp,
+ /* FIXME: Should I check tag->version instead? */
+ (file->tags[0].location == 0) ?
+ file->tags[0].length : 0, -1);
+
fclose(tmp);
if (rc)
unlink(tmpname);
diff --git a/src/.gitignore b/src/.gitignore
index 97d1ee5..43f7eeb 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -1,3 +1,4 @@
.gdbinit
cmdline.h
idest
+guile.x
diff --git a/src/Makefile.am b/src/Makefile.am
index 7d34d0b..66c9095 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -18,18 +18,25 @@ bin_PROGRAMS=idest
idest_SOURCES=\
backup.c\
guile.c\
+ guile.x\
idest.h\
idop.c\
main.c\
cmdline.h\
slist.c
-BUILT_SOURCES=cmdline.h
+BUILT_SOURCES=cmdline.h guile.x
EXTRA_DIST=cmdline.opt getopt.m4
INCLUDES=-I$(top_srcdir)/gnu -I$(top_builddir)/gnu -I$(top_srcdir)/libid3tag @GUILE_INCLUDES@
LDADD=../gnu/libgnu.a ../libid3tag/libid3tag.a -lz @GUILE_LIBS@
-SUFFIXES=.opt .c .h
+SUFFIXES=.opt .c .h .x
.opt.h:
m4 -s $(srcdir)/getopt.m4 $< | sed '1d' > $@
+DOT_X_FILES = guile.x
+
+snarfcppopts = -I../ $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
+
+.c.x:
+ guile-snarf -o $@ $< $(snarfcppopts)
diff --git a/src/cmdline.opt b/src/cmdline.opt
index faf7323..06fd798 100644
--- a/src/cmdline.opt
+++ b/src/cmdline.opt
@@ -109,6 +109,16 @@ OPTION(function,f,NAME,
BEGIN
guile_function = optarg;
END
+
+OPTION(trace,,[LEVEL],
+ [<Start with debugging evaluator and backtraces>])
+BEGIN
+ if (optarg)
+ guile_debug = atoi(optarg);
+ else
+ guile_debug = 1;
+END
+
>])
OPTIONS_END
diff --git a/src/guile.c b/src/guile.c
index 9b1f9c2..1efcb15 100644
--- a/src/guile.c
+++ b/src/guile.c
@@ -23,10 +23,22 @@
#include <libguile.h>
#include <setjmp.h>
+int guile_inited = 0;
int guile_debug = 1;
char *guile_script;
-char *guile_function = "main";
-SCM guile_proc = SCM_EOL;
+char *guile_function;
+
+SCM_GLOBAL_VARIABLE_INIT (sym_idest_main, "idest-main", SCM_EOL);
+SCM_GLOBAL_VARIABLE_INIT (sym_idest_readonly, "idest-readonly", SCM_BOOL_F);
+
+
+
+static char *
+proc_name(SCM proc)
+{
+ return scm_to_locale_string(
+ scm_symbol_to_string(scm_procedure_name(proc)));
+}
static SCM
eval_catch_body(void *list)
@@ -276,56 +288,107 @@ scm_to_tag(SCM scm, struct id3_tag *tag)
return modified;
}
+SCM
+guile_apply_main(const char *file, struct id3_tag *tag)
+{
+ jmp_buf jmp_env;
+ SCM cell;
+
+ if (setjmp(jmp_env))
+ error(1, 0, "idest-main failed");
+
+ cell = scm_cons(SCM_VARIABLE_REF(sym_idest_main),
+ scm_list_2(
+ scm_cons(SCM_IM_QUOTE, scm_makfrom0str(file)),
+ scm_cons(SCM_IM_QUOTE, tag_to_scm(tag))));
+ return scm_internal_lazy_catch(SCM_BOOL_T,
+ eval_catch_body, cell,
+ eval_catch_handler, &jmp_env);
+}
+
+int
+guile_transform(const char *file, struct id3_tag *tag)
+{
+ SCM result;
+
+ if (!guile_inited)
+ return 0;
+
+ result = guile_apply_main(file, tag);
+
+ if (scm_is_pair(result))
+ return scm_to_tag(result, tag);
+ return 0;
+}
+
int
-guile_apply(const char *file, struct id3_tag *tag)
+guile_list(const char *file, struct id3_tag *tag)
{
- jmp_buf jmp_env;
- SCM cell, result;
+ SCM result;
- if (guile_proc == SCM_EOL)
- return 0;
+ if (!guile_inited)
+ return 0;
- if (setjmp(jmp_env))
- error(1, 0, "%s failed", guile_function);
-
- cell = scm_cons(guile_proc,
- scm_list_2(
- scm_cons(SCM_IM_QUOTE, scm_makfrom0str(file)),
- scm_cons(SCM_IM_QUOTE, tag_to_scm(tag))));
- result = scm_internal_lazy_catch(SCM_BOOL_T,
- eval_catch_body, cell,
- eval_catch_handler, &jmp_env);
- if (scm_is_pair(result))
- return scm_to_tag(result, tag);
- return 0;
+ guile_apply_main(file, tag);
+ return 1;
}
void
guile_init()
{
+ SCM readonly, proc;
+
if (!guile_script)
return;
scm_init_guile();
scm_load_goops();
+#include "guile.x"
+
if (guile_debug) {
SCM_DEVAL_P = 1;
SCM_BACKTRACE_P = 1;
SCM_RECORD_POSITIONS_P = 1;
SCM_RESET_DEBUG_MODE;
}
+
if (guile_load(guile_script))
error(1, 0, "cannot load init script %s", guile_script);
- guile_proc = SCM_VARIABLE_REF(scm_c_lookup(guile_function));
- if (scm_procedure_p(guile_proc) != SCM_BOOL_T)
+ proc = SCM_VARIABLE_REF(sym_idest_main);
+ if (proc == SCM_EOL) {
+ if (guile_function) {
+ proc = SCM_VARIABLE_REF(scm_c_lookup(guile_function));
+ SCM_VARIABLE_SET(sym_idest_main, proc);
+ } else
+ error(1, 0, "idest-main not defined");
+ }
+
+ if (scm_procedure_p(proc) != SCM_BOOL_T)
+ error(1, 0,
+ "idest-main is not a procedure object");
+
+ readonly = SCM_VARIABLE_REF(sym_idest_readonly);
+ if (readonly == SCM_BOOL_F)
+ mode = MODE_MOD;
+ else if (readonly == SCM_BOOL_T)
+ mode = MODE_QUERY;
+ else
error(1, 0,
- "%s is not a procedure object", guile_function);
+ "script %s set non-boolean value of idest-readonly",
+ guile_script);
+ guile_inited = 1;
}
#else
int
-guile_apply(struct id3_tag *tag)
+guile_transform(const char *file, struct id3_tag *tag)
+{
+ return 0;
+}
+
+int
+guile_list(const char *file, struct id3_tag *tag)
{
return 0;
}
diff --git a/src/idest.h b/src/idest.h
index 21960e4..f758977 100644
--- a/src/idest.h
+++ b/src/idest.h
@@ -27,7 +27,7 @@
#include <argmatch.h>
#include <backupfile.h>
#include <id3tag.h>
-#include <libid3tag/frametype.h>
+#include <frametype.h>
#define gettext(s) s
#define _(s) s
@@ -54,6 +54,11 @@ struct ed_item {
} v;
};
+#define MODE_QUERY 0
+#define MODE_MOD 1
+#define MODE_DELETE 2
+
+extern int mode;
extern int latin1_option;
extern enum backup_type backup_type;
extern char *backup_dir;
@@ -92,5 +97,6 @@ int backup_file(const char *file);
/* guile.c */
-int guile_apply(const char *file, struct id3_tag *tag);
void guile_init (void);
+int guile_transform(const char *file, struct id3_tag *tag);
+int guile_list(const char *file, struct id3_tag *tag);
diff --git a/src/idop.c b/src/idop.c
index fb62e98..547edc8 100644
--- a/src/idop.c
+++ b/src/idop.c
@@ -105,14 +105,22 @@ set_tags(const char *name)
}
/* FIXME */
- modified |= guile_apply(name, tag);
-
- if (convert_version == 1) {
+ modified |= guile_transform(name, tag);
+
+ switch (convert_version) {
+ case 1:
id3_tag_options(tag,
ID3_TAG_OPTION_NO_ID3V2,
ID3_TAG_OPTION_NO_ID3V2);
version_option = 1;
modified |= 1;
+ break;
+
+ case 2:
+ id3_tag_options(tag, ID3_TAG_OPTION_ID3V1, 0);
+ version_option = 0;
+ modified |= 1;
+ break;
}
if (version_option == 1) {
@@ -125,6 +133,25 @@ set_tags(const char *name)
id3_file_close(file);
}
+void
+del_tags(const char *name)
+{
+ struct id3_file *file;
+ struct id3_tag *tag;
+
+ file = id3_file_open(name, ID3_FILE_MODE_READWRITE);
+ if (!file)
+ error(1, errno, "cannot open file %s", name);
+ tag = id3_file_tag(file);
+ if (!tag)
+ abort(); /* FIXME */
+ id3_tag_options(tag,
+ ID3_TAG_OPTION_ID3V1|ID3_TAG_OPTION_NO_ID3V2,
+ ID3_TAG_OPTION_NO_ID3V2);
+ id3_file_update(file);
+ id3_file_close(file);
+}
+
char *
idest_ucs4_cvt(id3_ucs4_t const *ucs4)
@@ -230,8 +257,10 @@ query_tags(const char *name)
error(1, errno, "cannot open file %s", name);
tag = id3_file_tag(file);
- if (tag)
- show_tags(tag);
+ if (tag) {
+ if (guile_list(name, tag) == 0)
+ show_tags(tag);
+ }
id3_file_close(file);
}
diff --git a/src/main.c b/src/main.c
index 14a9c97..c88f032 100644
--- a/src/main.c
+++ b/src/main.c
@@ -285,10 +285,6 @@ verify_mp3(FILE *fp, const char *name)
}
}
-#define MODE_QUERY 0
-#define MODE_MOD 1
-#define MODE_DELETE 2
-
void
query_id3(const char *name)
{
@@ -312,8 +308,7 @@ del_id3(const char *name)
{
if (backup_file(name))
error(1, 0, "cannot backup file %s", name);
- error(1, 0, "Deleting ID3 data is not yet implemented");
- abort();
+ del_tags(name);
}
void (*id3_mode[])(const char *) = {
@@ -341,7 +336,7 @@ main(int argc, char **argv)
guile_init();
- if (convert_version || guile_script)
+ if (convert_version)
mode = MODE_MOD;
while (argc--)

Return to:

Send suggestions and report system problems to the System administrator.