Add initial support for profile specific options
[fio.git] / parse.c
diff --git a/parse.c b/parse.c
index 13a27cc89ceef37634893945ebc3abad3d737dfc..9c0965f002d31d01156749eebf7868ad0b813e0e 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -327,9 +327,13 @@ static int __handle_option(struct fio_option *o, const char *ptr, void *data,
                        ret = 1;
                        if (!strncmp(vp->ival, ptr, strlen(vp->ival))) {
                                ret = 0;
-                               if (!o->off1)
-                                       break;
-                               val_store(ilp, vp->oval, o->off1, data);
+                               if (o->roff1)
+                                       *(unsigned int *) o->roff1 = vp->oval;
+                               else {
+                                       if (!o->off1)
+                                               break;
+                                       val_store(ilp, vp->oval, o->off1, data);
+                               }
                                break;
                        }
                }
@@ -369,15 +373,31 @@ static int __handle_option(struct fio_option *o, const char *ptr, void *data,
                        ret = fn(data, &ull);
                else {
                        if (o->type == FIO_OPT_INT) {
-                               if (first)
-                                       val_store(ilp, ull, o->off1, data);
-                               if (!more && o->off2)
-                                       val_store(ilp, ull, o->off2, data);
+                               if (first) {
+                                       if (o->roff1)
+                                               *(unsigned long long *) o->roff1 = ull;
+                                       else
+                                               val_store(ilp, ull, o->off1, data);
+                               }
+                               if (!more) {
+                                       if (o->roff2)
+                                               *(unsigned long long *) o->roff2 = ull;
+                                       else if (o->off2)
+                                               val_store(ilp, ull, o->off2, data);
+                               }
                        } else {
-                               if (first)
-                                       val_store(ullp, ull, o->off1, data);
-                               if (!more && o->off2)
-                                       val_store(ullp, ull, o->off2, data);
+                               if (first) {
+                                       if (o->roff1)
+                                               *(unsigned long long *) o->roff1 = ull;
+                                       else
+                                               val_store(ullp, ull, o->off1, data);
+                               }
+                               if (!more) {
+                                       if (o->roff2)
+                                               *(unsigned long long *) o->roff2 =  ull;
+                                       else if (o->off2)
+                                               val_store(ullp, ull, o->off2, data);
+                               }
                        }
                }
                break;
@@ -385,7 +405,11 @@ static int __handle_option(struct fio_option *o, const char *ptr, void *data,
        case FIO_OPT_STR_STORE: {
                fio_opt_str_fn *fn = o->cb;
 
-               cp = td_var(data, o->off1);
+               if (o->roff1)
+                       cp = (char **) o->roff1;
+               else
+                       cp = td_var(data, o->off1);
+
                *cp = strdup(ptr);
                if (fn) {
                        ret = fn(data, ptr);
@@ -427,10 +451,19 @@ static int __handle_option(struct fio_option *o, const char *ptr, void *data,
                        }
 
                        if (first) {
-                               val_store(ilp, ul1, o->off1, data);
-                               val_store(ilp, ul2, o->off2, data);
+                               if (o->roff1)
+                                       *(unsigned long *) o->roff1 = ul1;
+                               else
+                                       val_store(ilp, ul1, o->off1, data);
+                               if (o->roff2)
+                                       *(unsigned long *) o->roff2 = ul2;
+                               else
+                                       val_store(ilp, ul2, o->off2, data);
                        }
-                       if (o->off3 && o->off4) {
+                       if (o->roff3 && o->roff4) {
+                               *(unsigned long *) o->roff3 = ul1;
+                               *(unsigned long *) o->roff4 = ul2;
+                       } else if (o->off3 && o->off4) {
                                val_store(ilp, ul1, o->off3, data);
                                val_store(ilp, ul2, o->off4, data);
                        }
@@ -462,10 +495,18 @@ static int __handle_option(struct fio_option *o, const char *ptr, void *data,
                if (fn)
                        ret = fn(data, &il);
                else {
-                       if (first)
-                               val_store(ilp, il, o->off1, data);
-                       if (!more && o->off2)
-                               val_store(ilp, il, o->off2, data);
+                       if (first) {
+                               if (o->roff1)
+                                       *(unsigned int *)o->roff1 = il;
+                               else
+                                       val_store(ilp, il, o->off1, data);
+                       }
+                       if (!more) {
+                               if (o->roff2)
+                                       *(unsigned int *) o->roff2 = il;
+                               else if (o->off2)
+                                       val_store(ilp, il, o->off2, data);
+                       }
                }
                break;
        }
@@ -475,10 +516,18 @@ static int __handle_option(struct fio_option *o, const char *ptr, void *data,
                if (fn)
                        ret = fn(data);
                else {
-                       if (first)
-                               val_store(ilp, 1, o->off1, data);
-                       if (!more && o->off2)
-                               val_store(ilp, 1, o->off2, data);
+                       if (first) {
+                               if (o->roff1)
+                                       *(unsigned int *) o->roff1 = 1;
+                               else
+                                       val_store(ilp, 1, o->off1, data);
+                       }
+                       if (!more) {
+                               if (o->roff2)
+                                       *(unsigned int *) o->roff2 = 1;
+                               else if (o->off2)
+                                       val_store(ilp, 1, o->off2, data);
+                       }
                }
                break;
        }
@@ -803,8 +852,11 @@ static void print_option(struct fio_option *o)
        } while (printed);
 }
 
-int show_cmd_help(struct fio_option *options, const char *name)
+int show_cmd_help(struct fio_option *options, struct flist_head *ext_opts,
+                 const char *name)
 {
+       struct flist_head *n;
+       struct ext_option *eo;
        struct fio_option *o, *closest;
        unsigned int best_dist;
        int found = 0;
@@ -856,6 +908,18 @@ int show_cmd_help(struct fio_option *options, const char *name)
        if (found)
                return 0;
 
+       flist_for_each(n, ext_opts) {
+               eo = flist_entry(n, struct ext_option, list);
+               o = &eo->o;
+               if (!strcmp(name, o->name) ||
+                   (o->alias && !strcmp(name, o->alias))) {
+                       printf("%20s: %s\n", o->name, o->help);
+                       show_option_help(o, stdout);
+                       printf("%20s: External, valid for '%s'\n", "Restriction", eo->prof_name);
+                       return 0;
+               }
+       }
+
        printf("No such command: %s", name);
        if (closest) {
                printf(" - showing closest match\n");
@@ -893,13 +957,14 @@ void option_init(struct fio_option *o)
                fprintf(stderr, "Option %s: string set option with"
                                " default will always be true\n", o->name);
        }
-       if (!o->cb && !o->off1) {
+       if (!o->cb && (!o->off1 && !o->roff1)) {
                fprintf(stderr, "Option %s: neither cb nor offset given\n",
                                                        o->name);
        }
        if (o->type == FIO_OPT_STR || o->type == FIO_OPT_STR_STORE)
                return;
-       if (o->cb && (o->off1 || o->off2 || o->off3 || o->off4)) {
+       if (o->cb && ((o->off1 || o->off2 || o->off3 || o->off4) ||
+                     (o->roff1 || o->roff2 || o->roff3 || o->roff4))) {
                fprintf(stderr, "Option %s: both cb and offset given\n",
                                                         o->name);
        }