cmdutils: add support for caller-provided option context.
authorAnton Khirnov <anton@khirnov.net>
Sun, 28 Aug 2011 12:43:54 +0000 (14:43 +0200)
committerAnton Khirnov <anton@khirnov.net>
Sun, 4 Sep 2011 11:12:00 +0000 (13:12 +0200)
This is the first step to removing the globals plague from avtools.

avconv.c
avplay.c
avprobe.c
avserver.c
cmdutils.c
cmdutils.h
ffmpeg.c

index 33da836..92273f1 100644 (file)
--- a/avconv.c
+++ b/avconv.c
@@ -3403,7 +3403,7 @@ static int read_avserver_streams(AVFormatContext *s, const char *filename)
     return 0;
 }
 
     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;
 {
     AVFormatContext *oc;
     int i, err;
@@ -4143,7 +4143,7 @@ int main(int argc, char **argv)
     show_banner();
 
     /* parse options */
     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();
 
     if(nb_output_files <= 0 && nb_input_files == 0) {
         show_usage();
index 212ab2c..198dce1 100644 (file)
--- 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",
 {
     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();
 
 
     show_banner();
 
-    parse_options(argc, argv, options, opt_input_file);
+    parse_options(NULL, argc, argv, options, opt_input_file);
 
     if (!input_filename) {
         show_usage();
 
     if (!input_filename) {
         show_usage();
index a8a0f14..5e83916 100644 (file)
--- a/avprobe.c
+++ b/avprobe.c
@@ -346,7 +346,7 @@ static int opt_format(const char *opt, const char *arg)
     return 0;
 }
 
     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",
 {
     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();
 #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();
 
     if (!input_filename) {
         show_usage();
index 1b11cbf..df9d07d 100644 (file)
@@ -4676,7 +4676,7 @@ int main(int argc, char **argv)
     my_program_dir = getcwd(0, 0);
     avserver_daemon = 1;
 
     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 */
 
 
     unsetenv("http_proxy");             /* Kill the http_proxy */
 
index 53ef7ae..ea25836 100644 (file)
@@ -203,8 +203,8 @@ static inline void prepare_app_arguments(int *argc_ptr, char ***argv_ptr)
 }
 #endif /* WIN32 && !__MINGW32CE__ */
 
 }
 #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;
 {
     const char *opt, *arg;
     int optindex, handleoptions=1;
@@ -249,7 +249,9 @@ unknown_opt:
                     exit_program(1);
                 }
             }
                     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);
             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) {
             } 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);
                 }
                     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)
                 exit_program(0);
         } else {
             if (parse_arg_function)
-                parse_arg_function(opt);
+                parse_arg_function(optctx, opt);
         }
     }
 }
         }
     }
 }
index e72c730..a4716ca 100644 (file)
@@ -124,9 +124,13 @@ typedef struct {
 #define OPT_INT64  0x0400
 #define OPT_EXIT   0x0800
 #define OPT_DATA   0x1000
 #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 *);
      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;
     } 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.
 
 /**
  * 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.
  */
  * @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.
 
 /**
  * Check if the given stream matches a stream specifier.
index 242cd3f..a440b9d 100644 (file)
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -3702,7 +3702,7 @@ static int opt_streamid(const char *opt, const char *arg)
     return 0;
 }
 
     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;
 {
     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 */
                                  "(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();
 
     if(nb_output_files <= 0 && nb_input_files == 0) {
         show_usage();