parse: warn if option is missing a long option variant
[fio.git] / parse.c
diff --git a/parse.c b/parse.c
index 745056bdc8186e54743d2fb688df926084c91853..963f1f8cdc1f25f26a77a4471aa04a7c617fa43f 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -15,6 +15,7 @@
 #include "parse.h"
 #include "debug.h"
 #include "options.h"
+#include "optgroup.h"
 #include "minmax.h"
 #include "lib/ieee754.h"
 #include "lib/pow2.h"
@@ -52,7 +53,7 @@ static void posval_sort(struct fio_option *o, struct value_pair *vpmap)
 }
 
 static void show_option_range(struct fio_option *o,
-                               int (*logger)(const char *format, ...))
+                             size_t (*logger)(const char *format, ...))
 {
        if (o->type == FIO_OPT_FLOAT_LIST) {
                if (o->minfp == DBL_MIN && o->maxfp == DBL_MAX)
@@ -109,7 +110,7 @@ static void show_option_help(struct fio_option *o, int is_err)
                "no argument (opt)",
                "deprecated",
        };
-       int (*logger)(const char *format, ...);
+       size_t (*logger)(const char *format, ...);
 
        if (is_err)
                logger = log_err;
@@ -483,6 +484,8 @@ static int __handle_option(struct fio_option *o, const char *ptr, void *data,
                        if (!vp->ival || vp->ival[0] == '\0')
                                continue;
                        all_skipped = 0;
+                       if (!ptr)
+                               break;
                        if (!strncmp(vp->ival, ptr, str_match_len(vp, ptr))) {
                                ret = 0;
                                if (o->off1)
@@ -958,8 +961,27 @@ void sort_options(char **opts, struct fio_option *options, int num_opts)
        __fio_options = NULL;
 }
 
+static void add_to_dump_list(struct fio_option *o, struct flist_head *dump_list,
+                            const char *post)
+{
+       struct print_option *p;
+
+       if (!dump_list)
+               return;
+
+       p = malloc(sizeof(*p));
+       p->name = strdup(o->name);
+       if (post)
+               p->value = strdup(post);
+       else
+               p->value = NULL;
+
+       flist_add_tail(&p->list, dump_list);
+}
+
 int parse_cmd_option(const char *opt, const char *val,
-                    struct fio_option *options, void *data)
+                    struct fio_option *options, void *data,
+                    struct flist_head *dump_list)
 {
        struct fio_option *o;
 
@@ -969,16 +991,18 @@ int parse_cmd_option(const char *opt, const char *val,
                return 1;
        }
 
-       if (!handle_option(o, val, data))
-               return 0;
+       if (handle_option(o, val, data)) {
+               log_err("fio: failed parsing %s=%s\n", opt, val);
+               return 1;
+       }
 
-       log_err("fio: failed parsing %s=%s\n", opt, val);
-       return 1;
+       add_to_dump_list(o, dump_list, val);
+       return 0;
 }
 
 int parse_option(char *opt, const char *input,
                 struct fio_option *options, struct fio_option **o, void *data,
-                int dump_cmdline)
+                struct flist_head *dump_list)
 {
        char *post;
 
@@ -1004,19 +1028,7 @@ int parse_option(char *opt, const char *input,
                return 1;
        }
 
-       if (dump_cmdline) {
-               const char *delim;
-
-               if (!strcmp("description", (*o)->name))
-                       delim = "\"";
-               else
-                       delim = "";
-
-               log_info("--%s%s", (*o)->name, post ? "" : " ");
-               if (post)
-                       log_info("=%s%s%s ", delim, post, delim);
-       }
-
+       add_to_dump_list(*o, dump_list, post);
        return 0;
 }
 
@@ -1061,6 +1073,19 @@ int string_distance(const char *s1, const char *s2)
        return i;
 }
 
+/*
+ * Make a guess of whether the distance from 's1' is significant enough
+ * to warrant printing the guess. We set this to a 1/2 match.
+ */
+int string_distance_ok(const char *opt, int distance)
+{
+       size_t len;
+
+       len = strlen(opt);
+       len = (len + 1) / 2;
+       return distance <= len;
+}
+
 static struct fio_option *find_child(struct fio_option *options,
                                     struct fio_option *o)
 {
@@ -1209,6 +1234,8 @@ void option_init(struct fio_option *o)
 {
        if (o->type == FIO_OPT_DEPRECATED)
                return;
+       if (o->name && !o->lname)
+               log_err("Option %s: missing long option name\n", o->name);
        if (o->type == FIO_OPT_BOOL) {
                o->minval = 0;
                o->maxval = 1;