[FFmpeg-devel] [PATCH 34/47] fftools: handle errors in parse_options()

Anton Khirnov anton at khirnov.net
Sat Jul 15 13:45:58 EEST 2023


---
 fftools/cmdutils.c | 15 ++++++++++-----
 fftools/cmdutils.h |  4 ++--
 fftools/ffplay.c   | 12 ++++++++----
 fftools/ffprobe.c  | 10 +++++++---
 4 files changed, 27 insertions(+), 14 deletions(-)

diff --git a/fftools/cmdutils.c b/fftools/cmdutils.c
index b401b8fb89..330b9c2aba 100644
--- a/fftools/cmdutils.c
+++ b/fftools/cmdutils.c
@@ -364,8 +364,8 @@ int parse_option(void *optctx, const char *opt, const char *arg,
     return !!(po->flags & HAS_ARG);
 }
 
-void parse_options(void *optctx, int argc, char **argv, const OptionDef *options,
-                   void (*parse_arg_function)(void *, const char*))
+int parse_options(void *optctx, int argc, char **argv, const OptionDef *options,
+                  int (*parse_arg_function)(void *, const char*))
 {
     const char *opt;
     int optindex, handleoptions = 1, ret;
@@ -386,13 +386,18 @@ void parse_options(void *optctx, int argc, char **argv, const OptionDef *options
             opt++;
 
             if ((ret = parse_option(optctx, opt, argv[optindex], options)) < 0)
-                exit_program(1);
+                return ret;
             optindex += ret;
         } else {
-            if (parse_arg_function)
-                parse_arg_function(optctx, opt);
+            if (parse_arg_function) {
+                ret = parse_arg_function(optctx, opt);
+                if (ret < 0)
+                    return ret;
+            }
         }
     }
+
+    return 0;
 }
 
 int parse_optgroup(void *optctx, OptionGroup *g)
diff --git a/fftools/cmdutils.h b/fftools/cmdutils.h
index dc041d9fa2..210d52e998 100644
--- a/fftools/cmdutils.h
+++ b/fftools/cmdutils.h
@@ -194,8 +194,8 @@ void show_help_default(const char *opt, const char *arg);
  * argument without a leading option name flag. NULL if such arguments do
  * not have to be processed.
  */
-void parse_options(void *optctx, int argc, char **argv, const OptionDef *options,
-                   void (* parse_arg_function)(void *optctx, const char*));
+int parse_options(void *optctx, int argc, char **argv, const OptionDef *options,
+                  int (* parse_arg_function)(void *optctx, const char*));
 
 /**
  * Parse one given option.
diff --git a/fftools/ffplay.c b/fftools/ffplay.c
index 89cea4d876..4e26b3309d 100644
--- a/fftools/ffplay.c
+++ b/fftools/ffplay.c
@@ -3501,17 +3501,19 @@ static int opt_show_mode(void *optctx, const char *opt, const char *arg)
     return 0;
 }
 
-static void opt_input_file(void *optctx, const char *filename)
+static int opt_input_file(void *optctx, const char *filename)
 {
     if (input_filename) {
         av_log(NULL, AV_LOG_FATAL,
                "Argument '%s' provided as input filename, but '%s' was already specified.\n",
                 filename, input_filename);
-        exit(1);
+        return AVERROR(EINVAL);
     }
     if (!strcmp(filename, "-"))
         filename = "fd:";
     input_filename = filename;
+
+    return 0;
 }
 
 static int opt_codec(void *optctx, const char *opt, const char *arg)
@@ -3630,7 +3632,7 @@ void show_help_default(const char *opt, const char *arg)
 /* Called from the main */
 int main(int argc, char **argv)
 {
-    int flags;
+    int flags, ret;
     VideoState *is;
 
     init_dynload();
@@ -3649,7 +3651,9 @@ int main(int argc, char **argv)
 
     show_banner(argc, argv, options);
 
-    parse_options(NULL, argc, argv, options, opt_input_file);
+    ret = parse_options(NULL, argc, argv, options, opt_input_file);
+    if (ret < 0)
+        exit(1);
 
     if (!input_filename) {
         show_usage();
diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c
index e6fd33492d..ba55437760 100644
--- a/fftools/ffprobe.c
+++ b/fftools/ffprobe.c
@@ -3770,17 +3770,19 @@ static int opt_show_entries(void *optctx, const char *opt, const char *arg)
     return ret;
 }
 
-static void opt_input_file(void *optctx, const char *arg)
+static int opt_input_file(void *optctx, const char *arg)
 {
     if (input_filename) {
         av_log(NULL, AV_LOG_ERROR,
                 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
                 arg, input_filename);
-        exit_program(1);
+        return AVERROR(EINVAL);
     }
     if (!strcmp(arg, "-"))
         arg = "fd:";
     input_filename = arg;
+
+    return 0;
 }
 
 static int opt_input_file_i(void *optctx, const char *opt, const char *arg)
@@ -4121,7 +4123,9 @@ int main(int argc, char **argv)
 #endif
 
     show_banner(argc, argv, options);
-    parse_options(NULL, argc, argv, options, opt_input_file);
+    ret = parse_options(NULL, argc, argv, options, opt_input_file);
+    if (ret < 0)
+        exit_program(1);
 
     if (do_show_log)
         av_log_set_callback(log_callback);
-- 
2.40.1



More information about the ffmpeg-devel mailing list