Remember to free the file structure as well
[fio.git] / parse.c
diff --git a/parse.c b/parse.c
index f0e644f113bf63171fbebc8e0bd2545ae5d0fcd8..f9e0ebeedc3fd635ccbc8605122f37a795289678 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -10,6 +10,7 @@
 #include <limits.h>
 
 #include "parse.h"
+#include "debug.h"
 
 static int vp_cmp(const void *p1, const void *p2)
 {
@@ -106,7 +107,7 @@ static unsigned long get_mult_bytes(char c)
 /*
  * convert string into decimal value, noting any size suffix
  */
-static int str_to_decimal(const char *str, long long *val, int kilo)
+int str_to_decimal(const char *str, long long *val, int kilo)
 {
        int len;
 
@@ -188,8 +189,13 @@ static int check_int(const char *p, int *val)
 {
        if (!strlen(p))
                return 1;
-       if (sscanf(p, "%u", val) == 1)
-               return 0;
+       if (strstr(p, "0x") || strstr(p, "0X")) {
+               if (sscanf(p, "%x", val) == 1)
+                       return 0;
+       } else {
+               if (sscanf(p, "%u", val) == 1)
+                       return 0;
+       }
 
        return 1;
 }
@@ -224,6 +230,9 @@ static int __handle_option(struct fio_option *o, const char *ptr, void *data,
        char **cp;
        int ret = 0, is_time = 0;
 
+       dprint(FD_PARSE, "__handle_option=%s, type=%d, ptr=%s\n", o->name,
+                                                       o->type, ptr);
+
        if (!ptr && o->type != FIO_OPT_STR_SET) {
                fprintf(stderr, "Option %s requires an argument\n", o->name);
                return 1;
@@ -345,7 +354,7 @@ static int __handle_option(struct fio_option *o, const char *ptr, void *data,
                                val_store(ilp, ul1, o->off1, data);
                                val_store(ilp, ul2, o->off2, data);
                        }
-                       if (!more && o->off3 && o->off4) {
+                       if (o->off3 && o->off4) {
                                val_store(ilp, ul1, o->off3, data);
                                val_store(ilp, ul2, o->off4, data);
                        }
@@ -409,6 +418,8 @@ static int handle_option(struct fio_option *o, const char *ptr, void *data)
        const char *ptr2 = NULL;
        int r1, r2;
 
+       dprint(FD_PARSE, "handle_option=%s, ptr=%s\n", o->name, ptr);
+
        /*
         * See if we have a second set of parameters, hidden after a comma.
         * Do this before parsing the first round, to check if we should
@@ -556,6 +567,63 @@ static void show_option_help(struct fio_option *o)
        show_option_values(o);
 }
 
+static struct fio_option *find_child(struct fio_option *options,
+                                    struct fio_option *o)
+{
+       struct fio_option *__o;
+
+       for (__o = options + 1; __o->name; __o++)
+               if (__o->parent && !strcmp(__o->parent, o->name))
+                       return __o;
+
+       return NULL;
+}
+
+static void __print_option(struct fio_option *o, struct fio_option *org,
+                          int level)
+{
+       char name[256], *p;
+       int depth;
+
+       if (!o)
+               return;
+       if (!org)
+               org = o;
+       
+       p = name;
+       depth = level;
+       while (depth--)
+               p += sprintf(p, "%s", "  ");
+
+       sprintf(p, "%s", o->name);
+
+       printf("%-24s: %s\n", name, o->help);
+}
+
+static void print_option(struct fio_option *o)
+{
+       struct fio_option *parent;
+       struct fio_option *__o;
+       unsigned int printed;
+       unsigned int level;
+
+       __print_option(o, NULL, 0);
+       parent = o;
+       level = 0;
+       do {
+               level++;
+               printed = 0;
+
+               while ((__o = find_child(o, parent)) != NULL) {
+                       __print_option(__o, o, level);
+                       o = __o;
+                       printed++;
+               }
+
+               parent = o;
+       } while (printed);
+}
+
 int show_cmd_help(struct fio_option *options, const char *name)
 {
        struct fio_option *o, *closest;
@@ -589,9 +657,10 @@ int show_cmd_help(struct fio_option *options, const char *name)
                if (show_all || match) {
                        found = 1;
                        if (match)
-                               printf("%20s: %s\n", o->name, o->help);
+                               printf("%24s: %s\n", o->name, o->help);
                        if (show_all) {
-                               printf("%-20s: %s\n", o->name, o->help);
+                               if (!o->parent)
+                                       print_option(o);
                                continue;
                        }
                }
@@ -623,6 +692,8 @@ void fill_default_options(void *data, struct fio_option *options)
 {
        struct fio_option *o;
 
+       dprint(FD_PARSE, "filling default options\n");
+
        for (o = &options[0]; o->name; o++)
                if (o->def)
                        handle_option(o, o->def, data);
@@ -636,6 +707,8 @@ void options_init(struct fio_option *options)
 {
        struct fio_option *o;
 
+       dprint(FD_PARSE, "init options\n");
+
        for (o = &options[0]; o->name; o++) {
                if (o->type == FIO_OPT_BOOL) {
                        o->minval = 0;