parse: minimum options values are signed
[fio.git] / parse.c
diff --git a/parse.c b/parse.c
index 086f7864b8b6eb16ee0aa6527e86a32079833bfd..68229d052d95b339f681bcde3e372b894ce50aa1 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -135,6 +135,7 @@ static unsigned long long get_mult_time(const char *str, int len,
        const char *p = str;
        char *c;
        unsigned long long mult = 1;
+       int i;
 
        /*
          * Go forward until we hit a non-digit, or +/- sign
@@ -153,7 +154,7 @@ static unsigned long long get_mult_time(const char *str, int len,
        }
 
        c = strdup(p);
-       for (int i = 0; i < strlen(c); i++)
+       for (i = 0; i < strlen(c); i++)
                c[i] = tolower(c[i]);
 
        if (!strncmp("us", c, 2) || !strncmp("usec", c, 4))
@@ -167,7 +168,7 @@ static unsigned long long get_mult_time(const char *str, int len,
        else if (!strcmp("h", c))
                mult = 60 * 60 * 1000000UL;
        else if (!strcmp("d", c))
-               mult = 24 * 60 * 60 * 1000000UL;
+               mult = 24 * 60 * 60 * 1000000ULL;
 
        free(c);
        return mult;
@@ -207,32 +208,50 @@ static unsigned long long __get_mult_bytes(const char *p, void *data,
                }
        }
 
+       /* If kb_base is 1000, use true units.
+        * If kb_base is 1024, use opposite units.
+        */
        if (!strncmp("pib", c, 3)) {
                pow = 5;
-               mult = 1000;
+               if (kb_base == 1000)
+                       mult = 1024;
+               else if (kb_base == 1024)
+                       mult = 1000;
        } else if (!strncmp("tib", c, 3)) {
                pow = 4;
-               mult = 1000;
+               if (kb_base == 1000)
+                       mult = 1024;
+               else if (kb_base == 1024)
+                       mult = 1000;
        } else if (!strncmp("gib", c, 3)) {
                pow = 3;
-               mult = 1000;
+               if (kb_base == 1000)
+                       mult = 1024;
+               else if (kb_base == 1024)
+                       mult = 1000;
        } else if (!strncmp("mib", c, 3)) {
                pow = 2;
-               mult = 1000;
+               if (kb_base == 1000)
+                       mult = 1024;
+               else if (kb_base == 1024)
+                       mult = 1000;
        } else if (!strncmp("kib", c, 3)) {
                pow = 1;
-               mult = 1000;
-       } else if (!strncmp("p", c, 1) || !strncmp("pb", c, 2))
+               if (kb_base == 1000)
+                       mult = 1024;
+               else if (kb_base == 1024)
+                       mult = 1000;
+       } else if (!strncmp("p", c, 1) || !strncmp("pb", c, 2)) {
                pow = 5;
-       else if (!strncmp("t", c, 1) || !strncmp("tb", c, 2))
+       } else if (!strncmp("t", c, 1) || !strncmp("tb", c, 2)) {
                pow = 4;
-       else if (!strncmp("g", c, 1) || !strncmp("gb", c, 2))
+       } else if (!strncmp("g", c, 1) || !strncmp("gb", c, 2)) {
                pow = 3;
-       else if (!strncmp("m", c, 1) || !strncmp("mb", c, 2))
+       } else if (!strncmp("m", c, 1) || !strncmp("mb", c, 2)) {
                pow = 2;
-       else if (!strncmp("k", c, 1) || !strncmp("kb", c, 2))
+       } else if (!strncmp("k", c, 1) || !strncmp("kb", c, 2)) {
                pow = 1;
-       else if (!strncmp("%", c, 1)) {
+       else if (!strncmp("%", c, 1)) {
                *percent = 1;
                free(c);
                return ret;
@@ -537,8 +556,8 @@ static int __handle_option(struct fio_option *o, const char *ptr, void *data,
                        return 1;
                }
                if (o->minval && ull < o->minval) {
-                       log_err("min value out of range: %llu"
-                                       " (%u min)\n", ull, o->minval);
+                       log_err("min value out of range: %lld"
+                                       " (%d min)\n", ull, o->minval);
                        return 1;
                }
                if (o->posval[0].ival) {
@@ -1250,7 +1269,7 @@ void fill_default_options(void *data, struct fio_option *options)
                        handle_option(o, o->def, data);
 }
 
-void option_init(struct fio_option *o)
+static void option_init(struct fio_option *o)
 {
        if (o->type == FIO_OPT_DEPRECATED || o->type == FIO_OPT_UNSUPPORTED)
                return;
@@ -1301,6 +1320,23 @@ void options_init(struct fio_option *options)
        }
 }
 
+void options_mem_dupe(struct fio_option *options, void *data)
+{
+       struct fio_option *o;
+       char **ptr;
+
+       dprint(FD_PARSE, "dup options\n");
+
+       for (o = &options[0]; o->name; o++) {
+               if (o->type != FIO_OPT_STR_STORE)
+                       continue;
+
+               ptr = td_var(data, o, o->off1);
+               if (*ptr)
+                       *ptr = strdup(*ptr);
+       }
+}
+
 void options_free(struct fio_option *options, void *data)
 {
        struct fio_option *o;
@@ -1309,7 +1345,7 @@ void options_free(struct fio_option *options, void *data)
        dprint(FD_PARSE, "free options\n");
 
        for (o = &options[0]; o->name; o++) {
-               if (o->type != FIO_OPT_STR_STORE || !o->off1)
+               if (o->type != FIO_OPT_STR_STORE || !o->off1 || o->no_free)
                        continue;
 
                ptr = td_var(data, o, o->off1);