From 8fa50e3e39b4f65dea2a694dc064038a41036642 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Sun, 29 Jul 2012 19:49:46 +0200 Subject: [PATCH] write: Get rid of gengetopt's string parser. It causes gengetopt to generate quite some additional code for the string parsers of all writers. Moreover, this string parser is inferior to create_argv() and create_shifted_argv() of string.c as gengetopt's parser does not honor any quoting at all. This commit changes the signature of the ->parse_config_or_die method of struct writer to take an (argc, argv) pair instead of a string. All writers can thus call the vanilla command line parser of gengetopt. The single user in write_common.c now calls ->parse_config_or_die() with an (argc, argv) pair obtained from create_shifted_argv(). --- alsa_write.c | 4 ++-- ao_write.c | 4 ++-- audiod.c | 12 +++++++----- file_write.c | 4 ++-- m4/gengetopt/makefile | 2 +- oss_write.c | 4 ++-- osx_write.c | 4 ++-- write.c | 7 +------ write.h | 14 +++++++------- write_common.c | 33 +++++++++++++++++++++++++++------ 10 files changed, 53 insertions(+), 35 deletions(-) diff --git a/alsa_write.c b/alsa_write.c index 2e096c0c..73c9b823 100644 --- a/alsa_write.c +++ b/alsa_write.c @@ -328,12 +328,12 @@ err: t->error = ret; } -__malloc static void *alsa_parse_config_or_die(const char *options) +__malloc static void *alsa_parse_config_or_die(int argc, char **argv) { struct alsa_write_args_info *conf = para_calloc(sizeof(*conf)); /* exits on errors */ - alsa_cmdline_parser_string(options, conf, "alsa_write"); + alsa_cmdline_parser(argc, argv, conf); return conf; } diff --git a/ao_write.c b/ao_write.c index a45d4fb9..165caa0c 100644 --- a/ao_write.c +++ b/ao_write.c @@ -337,12 +337,12 @@ out: t->error = ret; } -__malloc static void *aow_parse_config_or_die(const char *options) +__malloc static void *aow_parse_config_or_die(int argc, char **argv) { struct ao_write_args_info *conf = para_calloc(sizeof(*conf)); /* exits on errors */ - ao_cmdline_parser_string(options, conf, "ao_write"); + ao_cmdline_parser(argc, argv, conf); return conf; } diff --git a/audiod.c b/audiod.c index 9f2aa5ab..4fc04b51 100644 --- a/audiod.c +++ b/audiod.c @@ -806,17 +806,19 @@ static int parse_writer_args(void) } /* Use default writer for audio formats which are not yet set up. */ FOR_EACH_AUDIO_FORMAT(i) { - struct writer *w = writers + DEFAULT_WRITER; + void *writer_conf; + int writer_num; a = afi + i; if (a->num_writers > 0) continue; /* already set up */ - PARA_INFO_LOG("%s writer: %s (default)\n", audio_formats[i], - writer_names[DEFAULT_WRITER]); + writer_conf = check_writer_arg_or_die(NULL, &writer_num); a->writer_nums = para_malloc(sizeof(int)); - a->writer_nums[0] = DEFAULT_WRITER; + a->writer_nums[0] = writer_num; a->writer_conf = para_malloc(sizeof(void *)); - a->writer_conf[0] = w->parse_config_or_die(""); + a->writer_conf[0] = writer_conf; a->num_writers = 1; + PARA_INFO_LOG("%s writer: %s (default)\n", audio_formats[i], + writer_names[writer_num]); } return 1; } diff --git a/file_write.c b/file_write.c index 98d15a43..98175715 100644 --- a/file_write.c +++ b/file_write.c @@ -133,12 +133,12 @@ out: t->error = ret; } -__malloc static void *file_write_parse_config_or_die(const char *options) +__malloc static void *file_write_parse_config_or_die(int argc, char **argv) { struct file_write_args_info *conf = para_calloc(sizeof(*conf)); /* exits on errors */ - file_cmdline_parser_string(options, conf, "file_write"); + file_cmdline_parser(argc, argv, conf); return conf; } diff --git a/m4/gengetopt/makefile b/m4/gengetopt/makefile index e1324115..cc5835c7 100644 --- a/m4/gengetopt/makefile +++ b/m4/gengetopt/makefile @@ -19,7 +19,7 @@ $(cmdline_dir)/%_filter.cmdline.h $(cmdline_dir)/%_filter.cmdline.c: $(ggo_dir)/ --func-name=$(subst _filter.ggo,,$(btrn); } -__malloc static void *oss_parse_config_or_die(const char *options) +__malloc static void *oss_parse_config_or_die(int argc, char **argv) { struct oss_write_args_info *conf = para_calloc(sizeof(*conf)); /* exits on errors */ - oss_cmdline_parser_string(options, conf, "oss_write"); + oss_cmdline_parser(argc, argv, conf); return conf; } diff --git a/osx_write.c b/osx_write.c index 2c6fd0d2..69a781cc 100644 --- a/osx_write.c +++ b/osx_write.c @@ -217,12 +217,12 @@ e0: return ret; } -__malloc static void *osx_write_parse_config_or_die(const char *options) +__malloc static void *osx_write_parse_config_or_die(int argc, char **argv) { struct osx_write_args_info *conf = para_calloc(sizeof(*conf)); /* exits on errors */ - osx_cmdline_parser_string(options, conf, "osx_write"); + osx_cmdline_parser(argc, argv, conf); return conf; } diff --git a/write.c b/write.c index de730008..df37d7ec 100644 --- a/write.c +++ b/write.c @@ -187,12 +187,7 @@ __noreturn static void print_help_and_die(void) static void setup_writer_node(const char *arg, struct btr_node *parent, struct writer_node *wn, struct sched *s) { - if (arg) - wn->conf = check_writer_arg_or_die(arg, &wn->writer_num); - else { - wn->writer_num = DEFAULT_WRITER; - wn->conf = writers[DEFAULT_WRITER].parse_config_or_die(""); - } + wn->conf = check_writer_arg_or_die(arg, &wn->writer_num); register_writer_node(wn, parent, s); } diff --git a/write.h b/write.h index ddf43b69..c43e8dcb 100644 --- a/write.h +++ b/write.h @@ -39,14 +39,14 @@ struct writer { /** * The command line parser of the writer. * - * It should check whether the command line options given by \a options - * are valid and return a pointer to the writer-specific configuration - * data determined by \a options. This function must either succeed or - * call exit(). Note that parse_config_or_die() might be called more - * than once with different values of \a options. \sa \ref - * free_config(). + * It should check whether the command line options given by \a argv + * and \a argc are valid and return a pointer to the writer-specific + * configuration data determined by these options. This function must + * either succeed or call exit(). Note that parse_config_or_die() might + * be called more than once with different values of \a options. \sa + * \ref free_config(). */ - void *(*parse_config_or_die)(const char *options); + void *(*parse_config_or_die)(int argc, char **argv); /** * Dellocate all configuration resources. * diff --git a/write_common.c b/write_common.c index e6a5eeb7..602f94d8 100644 --- a/write_common.c +++ b/write_common.c @@ -50,25 +50,46 @@ void writer_init(void) */ void *check_writer_arg_or_die(const char *wa, int *writer_num) { - int i; - + int i, ret, argc; + const char *cmdline; + char **argv; + void *conf; + + if (!wa || !*wa) { + i = DEFAULT_WRITER; + cmdline = NULL; + goto check; + } PARA_INFO_LOG("checking %s\n", wa); FOR_EACH_WRITER(i) { const char *name = writer_names[i]; size_t len = strlen(name); char c; + if (strlen(wa) < len) continue; if (strncmp(name, wa, len)) continue; c = wa[len]; - if (c && c != ' ') - continue; - *writer_num = i; - return writers[i].parse_config_or_die(c? wa + len + 1 : ""); + if (!c || c == ' ') { + cmdline = c? wa + len + 1 : NULL; + goto check; + } } PARA_EMERG_LOG("invalid writer %s\n", wa); exit(EXIT_FAILURE); +check: + ret = create_shifted_argv(cmdline, " \t", &argv); + if (ret < 0) { + PARA_EMERG_LOG("%s: %s\n", wa, para_strerror(-ret)); + exit(EXIT_FAILURE); + } + argc = ret; + argv[0] = make_message("%s_write", writer_names[i]); + *writer_num = i; + conf = writers[i].parse_config_or_die(argc, argv); + free_argv(argv); + return conf; } /** -- 2.39.2