From 7cc8d6385aaf1005700305f21d5d56b51b38c537 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 28 Aug 2011 14:43:54 +0200 Subject: cmdutils: add support for caller-provided option context. This is the first step to removing the globals plague from avtools. --- avconv.c | 4 ++-- avplay.c | 4 ++-- avprobe.c | 4 ++-- avserver.c | 2 +- cmdutils.c | 14 +++++++++----- cmdutils.h | 10 ++++++++-- ffmpeg.c | 4 ++-- 7 files changed, 26 insertions(+), 16 deletions(-) diff --git a/avconv.c b/avconv.c index 33da836a90..92273f1ce7 100644 --- a/avconv.c +++ b/avconv.c @@ -3403,7 +3403,7 @@ static int read_avserver_streams(AVFormatContext *s, const char *filename) return 0; } -static void opt_output_file(const char *filename) +static void opt_output_file(void *optctx, const char *filename) { AVFormatContext *oc; int i, err; @@ -4143,7 +4143,7 @@ int main(int argc, char **argv) show_banner(); /* parse options */ - parse_options(argc, argv, options, opt_output_file); + parse_options(NULL, argc, argv, options, opt_output_file); if(nb_output_files <= 0 && nb_input_files == 0) { show_usage(); diff --git a/avplay.c b/avplay.c index 212ab2c9b2..198dce1d2b 100644 --- a/avplay.c +++ b/avplay.c @@ -3015,7 +3015,7 @@ static void show_help(void) ); } -static void opt_input_file(const char *filename) +static void opt_input_file(void *optctx, const char *filename) { if (input_filename) { fprintf(stderr, "Argument '%s' provided as input filename, but '%s' was already specified.\n", @@ -3048,7 +3048,7 @@ int main(int argc, char **argv) show_banner(); - parse_options(argc, argv, options, opt_input_file); + parse_options(NULL, argc, argv, options, opt_input_file); if (!input_filename) { show_usage(); diff --git a/avprobe.c b/avprobe.c index a8a0f14eb7..5e83916f87 100644 --- a/avprobe.c +++ b/avprobe.c @@ -346,7 +346,7 @@ static int opt_format(const char *opt, const char *arg) return 0; } -static void opt_input_file(const char *arg) +static void opt_input_file(void *optctx, const char *arg) { if (input_filename) { fprintf(stderr, "Argument '%s' provided as input filename, but '%s' was already specified.\n", @@ -406,7 +406,7 @@ int main(int argc, char **argv) #endif show_banner(); - parse_options(argc, argv, options, opt_input_file); + parse_options(NULL, argc, argv, options, opt_input_file); if (!input_filename) { show_usage(); diff --git a/avserver.c b/avserver.c index 1b11cbf973..df9d07d1ad 100644 --- a/avserver.c +++ b/avserver.c @@ -4676,7 +4676,7 @@ int main(int argc, char **argv) my_program_dir = getcwd(0, 0); avserver_daemon = 1; - parse_options(argc, argv, options, NULL); + parse_options(NULL, argc, argv, options, NULL); unsetenv("http_proxy"); /* Kill the http_proxy */ diff --git a/cmdutils.c b/cmdutils.c index 53ef7aed3c..ea25836f8f 100644 --- a/cmdutils.c +++ b/cmdutils.c @@ -203,8 +203,8 @@ static inline void prepare_app_arguments(int *argc_ptr, char ***argv_ptr) } #endif /* WIN32 && !__MINGW32CE__ */ -void parse_options(int argc, char **argv, const OptionDef *options, - void (* parse_arg_function)(const char*)) +void parse_options(void *optctx, int argc, char **argv, const OptionDef *options, + void (* parse_arg_function)(void *, const char*)) { const char *opt, *arg; int optindex, handleoptions=1; @@ -249,7 +249,9 @@ unknown_opt: exit_program(1); } } - dst = po->u.dst_ptr; + /* new-style options contain an offset into optctx, old-style address of + * a global var*/ + dst = po->flags & OPT_OFFSET ? (uint8_t*)optctx + po->u.off : po->u.dst_ptr; if (po->flags & OPT_STRING) { char *str; str = av_strdup(arg); @@ -263,7 +265,9 @@ unknown_opt: } else if (po->flags & OPT_FLOAT) { *(float*)dst = parse_number_or_die(opt, arg, OPT_FLOAT, -INFINITY, INFINITY); } else if (po->u.func_arg) { - if (po->u.func_arg(opt, arg) < 0) { + int ret = po->flags & OPT_FUNC2 ? po->u.func2_arg(optctx, opt, arg) : + po->u.func_arg(opt, arg); + if (ret < 0) { fprintf(stderr, "%s: failed to set value '%s' for option '%s'\n", argv[0], arg, opt); exit_program(1); } @@ -272,7 +276,7 @@ unknown_opt: exit_program(0); } else { if (parse_arg_function) - parse_arg_function(opt); + parse_arg_function(optctx, opt); } } } diff --git a/cmdutils.h b/cmdutils.h index e72c730fa7..a4716cad61 100644 --- a/cmdutils.h +++ b/cmdutils.h @@ -124,9 +124,13 @@ typedef struct { #define OPT_INT64 0x0400 #define OPT_EXIT 0x0800 #define OPT_DATA 0x1000 +#define OPT_FUNC2 0x2000 +#define OPT_OFFSET 0x4000 /* option is specified as an offset in a passed optctx */ union { void *dst_ptr; int (*func_arg)(const char *, const char *); + int (*func2_arg)(void *, const char *, const char *); + size_t off; } u; const char *help; const char *argname; @@ -136,14 +140,16 @@ void show_help_options(const OptionDef *options, const char *msg, int mask, int /** * Parse the command line arguments. + * + * @param optctx an opaque options context * @param options Array with the definitions required to interpret every * option of the form: -option_name [argument] * @param parse_arg_function Name of the function called to process every * argument without a leading option name flag. NULL if such arguments do * not have to be processed. */ -void parse_options(int argc, char **argv, const OptionDef *options, - void (* parse_arg_function)(const char*)); +void parse_options(void *optctx, int argc, char **argv, const OptionDef *options, + void (* parse_arg_function)(void *optctx, const char*)); /** * Check if the given stream matches a stream specifier. diff --git a/ffmpeg.c b/ffmpeg.c index 242cd3ffa7..a440b9dacb 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -3702,7 +3702,7 @@ static int opt_streamid(const char *opt, const char *arg) return 0; } -static void opt_output_file(const char *filename) +static void opt_output_file(void *optctx, const char *filename) { AVFormatContext *oc; int err, use_video, use_audio, use_subtitle, use_data; @@ -4376,7 +4376,7 @@ int main(int argc, char **argv) "(see Changelog for the list of incompatible changes).\n"); /* parse options */ - parse_options(argc, argv, options, opt_output_file); + parse_options(NULL, argc, argv, options, opt_output_file); if(nb_output_files <= 0 && nb_input_files == 0) { show_usage(); -- cgit v1.2.3