client: fix segfault for !json output
[fio.git] / parse.c
diff --git a/parse.c b/parse.c
index e70ed20bda7e64b3727e93cacad71de65148862b..df42e227477e14f5082da58741a3a107e5d341f5 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -17,6 +17,7 @@
 #include "options.h"
 #include "minmax.h"
 #include "lib/ieee754.h"
+#include "lib/pow2.h"
 
 #ifdef CONFIG_ARITHMETIC
 #include "y.tab.h"
@@ -51,7 +52,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)
@@ -108,7 +109,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;
@@ -506,6 +507,7 @@ static int __handle_option(struct fio_option *o, const char *ptr, void *data,
                if (!is_time && o->is_time)
                        is_time = o->is_time;
 
+               tmp[sizeof(tmp) - 1] = '\0';
                strncpy(tmp, ptr, sizeof(tmp) - 1);
                p = strchr(tmp, ',');
                if (p)
@@ -520,6 +522,10 @@ static int __handle_option(struct fio_option *o, const char *ptr, void *data,
 
                if (ret)
                        break;
+               if (o->pow2 && !is_power_of_2(ull)) {
+                       log_err("%s: must be a power-of-2\n", o->name);
+                       return 1;
+               }
 
                if (o->maxval && ull > o->maxval) {
                        log_err("max value out of range: %llu"
@@ -705,6 +711,7 @@ static int __handle_option(struct fio_option *o, const char *ptr, void *data,
                char tmp[128];
                char *p1, *p2;
 
+               tmp[sizeof(tmp) - 1] = '\0';
                strncpy(tmp, ptr, sizeof(tmp) - 1);
 
                /* Handle bsrange with separate read,write values: */
@@ -971,7 +978,7 @@ int parse_cmd_option(const char *opt, const char *val,
 
 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;
 
@@ -997,17 +1004,16 @@ int parse_option(char *opt, const char *input,
                return 1;
        }
 
-       if (dump_cmdline) {
-               const char *delim;
+       if (dump_list) {
+               struct print_option *p = malloc(sizeof(*p));
 
-               if (!strcmp("description", (*o)->name))
-                       delim = "\"";
+               p->name = strdup((*o)->name);
+               if (post)
+                       p->value = strdup(post);
                else
-                       delim = "";
+                       p->value = NULL;
 
-               log_info("--%s%s", (*o)->name, post ? "" : " ");
-               if (post)
-                       log_info("=%s%s%s ", delim, post, delim);
+               flist_add_tail(&p->list, dump_list);
        }
 
        return 0;
@@ -1054,6 +1060,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)
 {