Merge branch 'master' into gfio
[fio.git] / parse.c
diff --git a/parse.c b/parse.c
index 51cefcaef4abd3d93db61e658d5ae4c29b6d437a..a701a5bb67b78dbdaa05dd827c776c9dd73ff34f 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -18,8 +18,7 @@
 #include "minmax.h"
 #include "lib/ieee754.h"
 
-static struct fio_option *fio_options;
-extern unsigned int fio_get_kb_base(void *);
+static struct fio_option *__fio_options;
 
 static int vp_cmp(const void *p1, const void *p2)
 {
@@ -140,6 +139,19 @@ static unsigned long get_mult_time(char c)
        }
 }
 
+static int is_separator(char c)
+{
+       switch (c) {
+       case ':':
+       case '-':
+       case ',':
+       case '/':
+               return 1;
+       default:
+               return 0;
+       }
+}
+
 static unsigned long long __get_mult_bytes(const char *p, void *data,
                                           int *percent)
 {
@@ -153,35 +165,40 @@ static unsigned long long __get_mult_bytes(const char *p, void *data,
 
        c = strdup(p);
 
-       for (i = 0; i < strlen(c); i++)
+       for (i = 0; i < strlen(c); i++) {
                c[i] = tolower(c[i]);
+               if (is_separator(c[i])) {
+                       c[i] = '\0';
+                       break;
+               }
+       }
 
-       if (!strcmp("pib", c)) {
+       if (!strncmp("pib", c, 3)) {
                pow = 5;
                mult = 1000;
-       } else if (!strcmp("tib", c)) {
+       } else if (!strncmp("tib", c, 3)) {
                pow = 4;
                mult = 1000;
-       } else if (!strcmp("gib", c)) {
+       } else if (!strncmp("gib", c, 3)) {
                pow = 3;
                mult = 1000;
-       } else if (!strcmp("mib", c)) {
+       } else if (!strncmp("mib", c, 3)) {
                pow = 2;
                mult = 1000;
-       } else if (!strcmp("kib", c)) {
+       } else if (!strncmp("kib", c, 3)) {
                pow = 1;
                mult = 1000;
-       } else if (!strcmp("p", c) || !strcmp("pb", c))
+       } else if (!strncmp("p", c, 1) || !strncmp("pb", c, 2))
                pow = 5;
-       else if (!strcmp("t", c) || !strcmp("tb", c))
+       else if (!strncmp("t", c, 1) || !strncmp("tb", c, 2))
                pow = 4;
-       else if (!strcmp("g", c) || !strcmp("gb", c))
+       else if (!strncmp("g", c, 1) || !strncmp("gb", c, 2))
                pow = 3;
-       else if (!strcmp("m", c) || !strcmp("mb", c))
+       else if (!strncmp("m", c, 1) || !strncmp("mb", c, 2))
                pow = 2;
-       else if (!strcmp("k", c) || !strcmp("kb", c))
+       else if (!strncmp("k", c, 1) || !strncmp("kb", c, 2))
                pow = 1;
-       else if (!strcmp("%", c)) {
+       else if (!strncmp("%", c, 1)) {
                *percent = 1;
                free(c);
                return ret;
@@ -263,7 +280,7 @@ int str_to_decimal(const char *str, long long *val, int kilo, void *data)
        return 0;
 }
 
-static int check_str_bytes(const char *p, long long *val, void *data)
+int check_str_bytes(const char *p, long long *val, void *data)
 {
        return str_to_decimal(p, val, 1, data);
 }
@@ -859,14 +876,14 @@ static int opt_cmp(const void *p1, const void *p2)
 
        if (*(char **)p1) {
                s = strdup(*((char **) p1));
-               o = get_option(s, fio_options, &foo);
+               o = get_option(s, __fio_options, &foo);
                if (o)
                        prio1 = o->prio;
                free(s);
        }
        if (*(char **)p2) {
                s = strdup(*((char **) p2));
-               o = get_option(s, fio_options, &foo);
+               o = get_option(s, __fio_options, &foo);
                if (o)
                        prio2 = o->prio;
                free(s);
@@ -877,9 +894,9 @@ static int opt_cmp(const void *p1, const void *p2)
 
 void sort_options(char **opts, struct fio_option *options, int num_opts)
 {
-       fio_options = options;
+       __fio_options = options;
        qsort(opts, num_opts, sizeof(char *), opt_cmp);
-       fio_options = NULL;
+       __fio_options = NULL;
 }
 
 int parse_cmd_option(const char *opt, const char *val,
@@ -922,9 +939,8 @@ int parse_option(char *opt, const char *input,
                return 1;
        }
 
-       if (!handle_option(*o, post, data)) {
+       if (!handle_option(*o, post, data))
                return 0;
-       }
 
        log_err("fio: failed parsing %s\n", input);
        return 1;
@@ -1140,6 +1156,10 @@ void option_init(struct fio_option *o)
                      (o->roff1 || o->roff2 || o->roff3 || o->roff4))) {
                log_err("Option %s: both cb and offset given\n", o->name);
        }
+       if (!o->category) {
+               log_info("Options %s: no category defined. Setting to misc\n", o->name);
+               o->category = FIO_OPT_C_GENERAL;
+       }
 }
 
 /*
@@ -1152,8 +1172,11 @@ void options_init(struct fio_option *options)
 
        dprint(FD_PARSE, "init options\n");
 
-       for (o = &options[0]; o->name; o++)
+       for (o = &options[0]; o->name; o++) {
                option_init(o);
+               if (o->inverse)
+                       o->inv_opt = find_option(options, o->inverse);
+       }
 }
 
 void options_free(struct fio_option *options, void *data)