gfio: start of options view and edit
authorJens Axboe <axboe@kernel.dk>
Fri, 16 Mar 2012 09:13:49 +0000 (10:13 +0100)
committerJens Axboe <axboe@kernel.dk>
Fri, 16 Mar 2012 09:13:49 +0000 (10:13 +0100)
This is pretty crap right now, but it's exposing all the options.
Now we just need them to reflect the current job, and be able to
update a remote job with a new set of options.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
Makefile
gfio.c
goptions.c [new file with mode: 0644]
goptions.h [new file with mode: 0644]
options.c
options.h
parse.c
parse.h

index a114a2e89d73f1f8ea5222cc57d716414632971b..4b87ca67b41e8554c83e2fed911d7a6582cfad43 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -69,7 +69,7 @@ endif
 
 OBJS = $(SOURCE:.c=.o)
 FIO_OBJS = $(OBJS) fio.o
-GFIO_OBJS = $(OBJS) gfio.o graph.o tickmarks.o ghelpers.o
+GFIO_OBJS = $(OBJS) gfio.o graph.o tickmarks.o ghelpers.o goptions.o
 
 T_SMALLOC_OBJS = t/stest.o
 T_SMALLOC_OBJS += mutex.o smalloc.o t/log.o
@@ -104,6 +104,9 @@ all: .depend $(PROGS) $(SCRIPTS)
 .c.o: .depend
        $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(CPPFLAGS) $<
 
+goptions.o: goptions.c goptions.h
+       $(QUIET_CC)$(CC) $(CFLAGS) $(GTK_CFLAGS) $(CPPFLAGS) -c goptions.c
+
 ghelpers.o: ghelpers.c ghelpers.h
        $(QUIET_CC)$(CC) $(CFLAGS) $(GTK_CFLAGS) $(CPPFLAGS) -c ghelpers.c
 
diff --git a/gfio.c b/gfio.c
index 56a3887469010f5869f7b09057ee4beabf545b3c..675a87754777bad33f6ff8e02c2f6c4626bce319 100644 (file)
--- a/gfio.c
+++ b/gfio.c
@@ -32,6 +32,7 @@
 #include "fio.h"
 #include "gfio.h"
 #include "ghelpers.h"
+#include "goptions.h"
 #include "graph.h"
 
 static int gfio_server_running;
@@ -291,21 +292,21 @@ static void update_button_states(struct gui *ui, struct gui_entry *ge)
 
        case GE_STATE_NEW:
                connect_state = 1;
-               edit_state = 0;
+               edit_state = 1;
                connect_str = "Connect";
                send_state = 0;
                start_state = 0;
                break;
        case GE_STATE_CONNECTED:
                connect_state = 1;
-               edit_state = 0;
+               edit_state = 1;
                connect_str = "Disconnect";
                send_state = 1;
                start_state = 0;
                break;
        case GE_STATE_JOB_SENT:
                connect_state = 1;
-               edit_state = 0;
+               edit_state = 1;
                connect_str = "Disconnect";
                send_state = 0;
                start_state = 1;
@@ -2507,6 +2508,9 @@ static void send_job_entry(GtkWidget *w, gpointer data)
 
 static void edit_job_entry(GtkWidget *w, gpointer data)
 {
+       struct gui *ui = (struct gui *) data;
+
+       gopt_get_options_window(ui->window);
 }
 
 static void start_job_entry(GtkWidget *w, gpointer data)
diff --git a/goptions.c b/goptions.c
new file mode 100644 (file)
index 0000000..36477f0
--- /dev/null
@@ -0,0 +1,311 @@
+#include <locale.h>
+#include <malloc.h>
+#include <string.h>
+
+#include <glib.h>
+#include <cairo.h>
+#include <gtk/gtk.h>
+
+#include "fio.h"
+#include "gfio.h"
+#include "ghelpers.h"
+#include "parse.h"
+
+struct gopt {
+       GtkWidget *box;
+       unsigned int opt_index;
+       unsigned int opt_type;
+};
+
+struct gopt_combo {
+       struct gopt gopt;
+       GtkWidget *combo;
+};
+
+struct gopt_int {
+       struct gopt gopt;
+       GtkWidget *spin;
+};
+
+struct gopt_bool {
+       struct gopt gopt;
+       GtkWidget *check;
+};
+
+struct gopt_str {
+       struct gopt gopt;
+       GtkWidget *entry;
+};
+
+struct gopt_range {
+       struct gopt gopt;
+       GtkWidget *spins[4];
+};
+
+static struct gopt *gopt_new_str_store(struct fio_option *o)
+{
+       struct gopt_str *s;
+       GtkWidget *label;
+
+       s = malloc(sizeof(*s));
+
+       s->gopt.box = gtk_hbox_new(FALSE, 3);
+       label = gtk_label_new(o->name);
+       gtk_box_pack_start(GTK_BOX(s->gopt.box), label, FALSE, FALSE, 0);
+
+       s->entry = gtk_entry_new();
+       gtk_entry_set_editable(GTK_ENTRY(s->entry), 1);
+
+       if (o->def)
+               gtk_entry_set_text(GTK_ENTRY(s->entry), o->def);
+
+       gtk_box_pack_start(GTK_BOX(s->gopt.box), s->entry, FALSE, FALSE, 0);
+       return &s->gopt;
+}
+
+static struct gopt *gopt_new_combo(struct fio_option *o)
+{
+       struct gopt_combo *combo;
+       struct value_pair *vp;
+       GtkWidget *label;
+       int i, active = 0;
+
+       combo = malloc(sizeof(*combo));
+
+       combo->gopt.box = gtk_hbox_new(FALSE, 3);
+       label = gtk_label_new(o->name);
+       gtk_box_pack_start(GTK_BOX(combo->gopt.box), label, FALSE, FALSE, 0);
+
+       combo->combo = gtk_combo_box_new_text();
+       gtk_box_pack_start(GTK_BOX(combo->gopt.box), combo->combo, FALSE, FALSE, 0);
+
+       i = 0;
+       vp = &o->posval[0];
+       while (vp->ival) {
+               gtk_combo_box_append_text(GTK_COMBO_BOX(combo->combo), vp->ival);
+               if (o->def && !strcmp(vp->ival, o->def))
+                       active = i;
+               vp++;
+               i++;
+       }
+
+       gtk_combo_box_set_active(GTK_COMBO_BOX(combo->combo), active);
+       return &combo->gopt;
+}
+
+static struct gopt *gopt_new_int(struct fio_option *o)
+{
+       struct gopt_int *i;
+       gint maxval, defval;
+       GtkWidget *label;
+
+       i = malloc(sizeof(*i));
+       i->gopt.box = gtk_hbox_new(FALSE, 3);
+       label = gtk_label_new(o->name);
+       gtk_box_pack_start(GTK_BOX(i->gopt.box), label, FALSE, FALSE, 0);
+
+       maxval = o->maxval;
+       if (!maxval)
+               maxval = INT_MAX;
+
+       defval = 0;
+       if (o->def) {
+               long long val;
+
+               check_str_bytes(o->def, &val, NULL);
+               defval = val;
+       }
+
+       i->spin = gtk_spin_button_new_with_range(o->minval, maxval, 1.0);
+       gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(i->spin), GTK_UPDATE_IF_VALID);
+       gtk_spin_button_set_value(GTK_SPIN_BUTTON(i->spin), defval);
+
+       gtk_box_pack_start(GTK_BOX(i->gopt.box), i->spin, FALSE, FALSE, 0);
+       return &i->gopt;
+}
+
+static struct gopt *gopt_new_bool(struct fio_option *o)
+{
+       struct gopt_bool *b;
+       GtkWidget *label;
+       int defstate = 0;
+
+       b = malloc(sizeof(*b));
+       b->gopt.box = gtk_hbox_new(FALSE, 3);
+       label = gtk_label_new(o->name);
+       gtk_box_pack_start(GTK_BOX(b->gopt.box), label, FALSE, FALSE, 0);
+
+       b->check = gtk_check_button_new();
+       if (o->def && !strcmp(o->def, "1"))
+               defstate = 1;
+
+       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b->check), defstate);
+
+       gtk_box_pack_start(GTK_BOX(b->gopt.box), b->check, FALSE, FALSE, 0);
+       return &b->gopt;
+}
+
+static struct gopt *gopt_new_int_range(struct fio_option *o)
+{
+       struct gopt_range *r;
+       gint maxval, defval;
+       GtkWidget *label;
+       int i;
+
+       r = malloc(sizeof(*r));
+       r->gopt.box = gtk_hbox_new(FALSE, 3);
+       label = gtk_label_new(o->name);
+       gtk_box_pack_start(GTK_BOX(r->gopt.box), label, FALSE, FALSE, 0);
+
+       maxval = o->maxval;
+       if (!maxval)
+               maxval = INT_MAX;
+
+       defval = 0;
+       if (o->def) {
+               long long val;
+
+               check_str_bytes(o->def, &val, NULL);
+               defval = val;
+       }
+
+       for (i = 0; i < 4; i++) {
+               r->spins[i] = gtk_spin_button_new_with_range(o->minval, maxval, 1.0);
+               gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(r->spins[i]), GTK_UPDATE_IF_VALID);
+               gtk_spin_button_set_value(GTK_SPIN_BUTTON(r->spins[i]), defval);
+
+               gtk_box_pack_start(GTK_BOX(r->gopt.box), r->spins[i], FALSE, FALSE, 0);
+       }
+
+       return &r->gopt;
+}
+
+static void gopt_add_option(GtkWidget *hbox, struct fio_option *o,
+                           unsigned int opt_index)
+{
+       struct gopt *go = NULL;
+
+       switch (o->type) {
+       case FIO_OPT_STR_STORE:
+               go = gopt_new_str_store(o);
+               break;
+       case FIO_OPT_STR_VAL:
+       case FIO_OPT_STR_VAL_TIME:
+       case FIO_OPT_INT:
+               go = gopt_new_int(o);
+               break;
+       case FIO_OPT_STR_SET:
+       case FIO_OPT_BOOL:
+               go = gopt_new_bool(o);
+               break;
+       case FIO_OPT_STR:
+               if (!o->posval[0].ival) {
+                       go = gopt_new_str_store(o);
+                       break;
+               }
+       case FIO_OPT_STR_MULTI:
+               go = gopt_new_combo(o);
+               break;
+       case FIO_OPT_RANGE:
+               go = gopt_new_int_range(o);
+               break;
+       /* still need to handle this one */
+       case FIO_OPT_FLOAT_LIST:
+               break;
+       case FIO_OPT_DEPRECATED:
+               break;
+       default:
+               printf("ignore type %u\n", o->type);
+               break;
+       }
+
+       if (go) {
+               if (o->help)
+                       gtk_widget_set_tooltip_text(go->box, o->help);
+       
+               gtk_box_pack_start(GTK_BOX(hbox), go->box, FALSE, FALSE, 5);
+               go->opt_index = opt_index;
+               go->opt_type = o->type;
+       }
+}
+
+static void gopt_add_options(GtkWidget **vboxes)
+{
+       GtkWidget *hbox = NULL;
+       int i;
+
+       for (i = 0; fio_options[i].name; i++) {
+               struct fio_option *o = &fio_options[i];
+               unsigned int mask = o->category;
+               struct opt_group *og;
+
+               while ((og = opt_group_from_mask(&mask)) != NULL) {
+                       GtkWidget *vbox = vboxes[ffz(~og->mask)];
+
+                       hbox = gtk_hbox_new(FALSE, 3);
+                       gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
+                       gopt_add_option(hbox, &fio_options[i], i);
+               }
+       }
+}
+
+static GtkWidget *gopt_add_group_tab(GtkWidget *notebook, struct opt_group *og)
+{
+       GtkWidget *box, *vbox, *scroll;
+
+       scroll = gtk_scrolled_window_new(NULL, NULL);
+       gtk_container_set_border_width(GTK_CONTAINER(scroll), 5);
+       gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+
+       vbox = gtk_vbox_new(FALSE, 3);
+       box = gtk_hbox_new(FALSE, 0);
+       gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 5);
+       gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroll), vbox);
+       gtk_notebook_append_page(GTK_NOTEBOOK(notebook), scroll, gtk_label_new(og->name));
+
+       return vbox;
+}
+
+static void gopt_add_group_tabs(GtkWidget *notebook, GtkWidget **vbox)
+{
+       struct opt_group *og;
+       unsigned int i = 0;
+
+       do {
+               unsigned int mask = (1U << i);
+
+               og = opt_group_from_mask(&mask);
+               if (!og)
+                       break;
+               vbox[i] = gopt_add_group_tab(notebook, og);
+               i++;
+       } while (1);
+}
+
+void gopt_get_options_window(GtkWidget *window)
+{
+       GtkWidget *dialog, *notebook;
+       GtkWidget *vboxes[__FIO_OPT_G_NR];
+
+       dialog = gtk_dialog_new_with_buttons("Fio options",
+                       GTK_WINDOW(window), GTK_DIALOG_DESTROY_WITH_PARENT,
+                       GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+                       GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL);
+
+       gtk_widget_set_size_request(GTK_WIDGET(dialog), 1024, 768);
+
+       notebook = gtk_notebook_new();
+       gtk_notebook_set_scrollable(GTK_NOTEBOOK(notebook), 1);
+       gtk_notebook_popup_enable(GTK_NOTEBOOK(notebook));
+       gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), notebook, TRUE, TRUE, 5);
+
+       gopt_add_group_tabs(notebook, vboxes);
+
+       gopt_add_options(vboxes);
+
+       gtk_widget_show_all(dialog);
+
+       gtk_dialog_run(GTK_DIALOG(dialog));
+
+       gtk_widget_destroy(dialog);
+}
diff --git a/goptions.h b/goptions.h
new file mode 100644 (file)
index 0000000..14e54f7
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef GFIO_OPTIONS_H
+#define GFIO_OPTIONS_H
+
+void gopt_get_options_window(GtkWidget *window);
+
+#endif
index 714741a038ae94e248357a3295cb78db155ec7d9..91bec0e840747120cbf106f953e4601a5e23708a 100644 (file)
--- a/options.c
+++ b/options.c
@@ -842,10 +842,107 @@ static int kb_base_verify(struct fio_option *o, void *data)
        return 0;
 }
 
+/*
+ * Option grouping
+ */
+static struct opt_group fio_opt_groups[] = {
+       {
+               .name   = "Description",
+               .mask   = FIO_OPT_G_DESC,
+       },
+       {
+               .name   = "File",
+               .mask   = FIO_OPT_G_FILE,
+       },
+       {
+               .name   = "Misc",
+               .mask   = FIO_OPT_G_MISC,
+       },
+       {
+               .name   = "IO (main)",
+               .mask   = FIO_OPT_G_IO,
+       },
+       {
+               .name   = "IO direction",
+               .mask   = FIO_OPT_G_IO_DDIR,
+       },
+       {
+               .name   = "IO buffer",
+               .mask   = FIO_OPT_G_IO_BUF,
+       },
+       {
+               .name   = "Random",
+               .mask   = FIO_OPT_G_RAND,
+       },
+       {
+               .name   = "OS",
+               .mask   = FIO_OPT_G_OS,
+       },
+       {
+               .name   = "Memory",
+               .mask   = FIO_OPT_G_MEM,
+       },
+       {
+               .name   = "Verify",
+               .mask   = FIO_OPT_G_VERIFY,
+       },
+       {
+               .name   = "CPU",
+               .mask   = FIO_OPT_G_CPU,
+       },
+       {
+               .name   = "Log",
+               .mask   = FIO_OPT_G_LOG,
+       },
+       {
+               .name   = "Zone",
+               .mask   = FIO_OPT_G_ZONE,
+       },
+       {
+               .name   = "Cache",
+               .mask   = FIO_OPT_G_CACHE,
+       },
+       {
+               .name   = "Stat",
+               .mask   = FIO_OPT_G_STAT,
+       },
+       {
+               .name   = "Error",
+               .mask   = FIO_OPT_G_ERR,
+       },
+       {
+               .name   = "Job",
+               .mask   = FIO_OPT_G_JOB,
+       },
+       {
+               .name   = NULL,
+       },
+};
+
+struct opt_group *opt_group_from_mask(unsigned int *mask)
+{
+       struct opt_group *og;
+       int i;
+
+       if (*mask == FIO_OPT_G_INVALID)
+               return NULL;
+
+       for (i = 0; fio_opt_groups[i].name; i++) {
+               og = &fio_opt_groups[i];
+
+               if (*mask & og->mask) {
+                       *mask &= ~(og->mask);
+                       return og;
+               }
+       }
+
+       return NULL;
+}
+
 /*
  * Map of job/command line options
  */
-static struct fio_option options[FIO_MAX_OPTS] = {
+struct fio_option fio_options[FIO_MAX_OPTS] = {
        {
                .name   = "description",
                .type   = FIO_OPT_STR_STORE,
@@ -2413,13 +2510,13 @@ void fio_options_dup_and_init(struct option *long_options)
 {
        unsigned int i;
 
-       options_init(options);
+       options_init(fio_options);
 
        i = 0;
        while (long_options[i].name)
                i++;
 
-       options_to_lopts(options, long_options, i, FIO_GETOPT_JOB);
+       options_to_lopts(fio_options, long_options, i, FIO_GETOPT_JOB);
 }
 
 struct fio_keyword {
@@ -2642,13 +2739,13 @@ int fio_options_parse(struct thread_data *td, char **opts, int num_opts)
        int i, ret, unknown;
        char **opts_copy;
 
-       sort_options(opts, options, num_opts);
+       sort_options(opts, fio_options, num_opts);
        opts_copy = dup_and_sub_options(opts, num_opts);
 
        for (ret = 0, i = 0, unknown = 0; i < num_opts; i++) {
                struct fio_option *o;
-               int newret = parse_option(opts_copy[i], opts[i], options, &o,
-                                         td);
+               int newret = parse_option(opts_copy[i], opts[i], fio_options,
+                                               &o, td);
 
                if (opts_copy[i]) {
                        if (newret && !o) {
@@ -2694,7 +2791,7 @@ int fio_options_parse(struct thread_data *td, char **opts, int num_opts)
 
 int fio_cmd_option_parse(struct thread_data *td, const char *opt, char *val)
 {
-       return parse_cmd_option(opt, val, options, td);
+       return parse_cmd_option(opt, val, fio_options, td);
 }
 
 int fio_cmd_ioengine_option_parse(struct thread_data *td, const char *opt,
@@ -2705,12 +2802,12 @@ int fio_cmd_ioengine_option_parse(struct thread_data *td, const char *opt,
 
 void fio_fill_default_options(struct thread_data *td)
 {
-       fill_default_options(td, options);
+       fill_default_options(td, fio_options);
 }
 
 int fio_show_option_help(const char *opt)
 {
-       return show_cmd_help(options, opt);
+       return show_cmd_help(fio_options, opt);
 }
 
 void options_mem_dupe(void *data, struct fio_option *options)
@@ -2733,7 +2830,7 @@ void options_mem_dupe(void *data, struct fio_option *options)
  */
 void fio_options_mem_dupe(struct thread_data *td)
 {
-       options_mem_dupe(&td->o, options);
+       options_mem_dupe(&td->o, fio_options);
 
        if (td->eo && td->io_ops) {
                void *oldeo = td->eo;
@@ -2762,13 +2859,13 @@ int add_option(struct fio_option *o)
        struct fio_option *__o;
        int opt_index = 0;
 
-       __o = options;
+       __o = fio_options;
        while (__o->name) {
                opt_index++;
                __o++;
        }
 
-       memcpy(&options[opt_index], o, sizeof(*o));
+       memcpy(&fio_options[opt_index], o, sizeof(*o));
        return 0;
 }
 
@@ -2776,7 +2873,7 @@ void invalidate_profile_options(const char *prof_name)
 {
        struct fio_option *o;
 
-       o = options;
+       o = fio_options;
        while (o->name) {
                if (o->prof_name && !strcmp(o->prof_name, prof_name)) {
                        o->type = FIO_OPT_INVALID;
@@ -2791,7 +2888,7 @@ void add_opt_posval(const char *optname, const char *ival, const char *help)
        struct fio_option *o;
        unsigned int i;
 
-       o = find_option(options, optname);
+       o = find_option(fio_options, optname);
        if (!o)
                return;
 
@@ -2810,7 +2907,7 @@ void del_opt_posval(const char *optname, const char *ival)
        struct fio_option *o;
        unsigned int i;
 
-       o = find_option(options, optname);
+       o = find_option(fio_options, optname);
        if (!o)
                return;
 
@@ -2827,7 +2924,7 @@ void del_opt_posval(const char *optname, const char *ival)
 
 void fio_options_free(struct thread_data *td)
 {
-       options_free(options, td);
+       options_free(fio_options, td);
        if (td->eo && td->io_ops && td->io_ops->options) {
                options_free(td->io_ops->options, td->eo);
                free(td->eo);
index ed6b9c2da47a5699cb9b4d3f1808eba4b8ede019..0b93c05a7a1c3def92508168e5470332e05680aa 100644 (file)
--- a/options.h
+++ b/options.h
@@ -18,6 +18,8 @@ void del_opt_posval(const char *, const char *);
 struct thread_data;
 void fio_options_free(struct thread_data *);
 
+extern struct fio_option fio_options[FIO_MAX_OPTS];
+
 static inline int o_match(struct fio_option *o, const char *opt)
 {
        if (!strcmp(o->name, opt))
@@ -40,4 +42,51 @@ static inline struct fio_option *find_option(struct fio_option *options,
        return NULL;
 }
 
+struct opt_group {
+       const char *name;
+       unsigned int mask;
+};
+
+enum opt_category {
+       __FIO_OPT_G_DESC        = 0,
+       __FIO_OPT_G_FILE        = 1,
+       __FIO_OPT_G_MISC        = 2,
+       __FIO_OPT_G_IO          = 3,
+       __FIO_OPT_G_IO_DDIR     = 4,
+       __FIO_OPT_G_IO_BUF      = 5,
+       __FIO_OPT_G_RAND        = 6,
+       __FIO_OPT_G_OS          = 7,
+       __FIO_OPT_G_MEM         = 8,
+       __FIO_OPT_G_VERIFY      = 9,
+       __FIO_OPT_G_CPU         = 10,
+       __FIO_OPT_G_LOG         = 11,
+       __FIO_OPT_G_ZONE        = 12,
+       __FIO_OPT_G_CACHE       = 13,
+       __FIO_OPT_G_STAT        = 14,
+       __FIO_OPT_G_ERR         = 15,
+       __FIO_OPT_G_JOB         = 16,
+       __FIO_OPT_G_NR          = 17,
+
+       FIO_OPT_G_DESC          = (1U << __FIO_OPT_G_DESC),
+       FIO_OPT_G_FILE          = (1U << __FIO_OPT_G_FILE),
+       FIO_OPT_G_MISC          = (1U << __FIO_OPT_G_MISC),
+       FIO_OPT_G_IO            = (1U << __FIO_OPT_G_IO),
+       FIO_OPT_G_IO_DDIR       = (1U << __FIO_OPT_G_IO_DDIR),
+       FIO_OPT_G_IO_BUF        = (1U << __FIO_OPT_G_IO_BUF),
+       FIO_OPT_G_RAND          = (1U << __FIO_OPT_G_RAND),
+       FIO_OPT_G_OS            = (1U << __FIO_OPT_G_OS),
+       FIO_OPT_G_MEM           = (1U << __FIO_OPT_G_MEM),
+       FIO_OPT_G_VERIFY        = (1U << __FIO_OPT_G_VERIFY),
+       FIO_OPT_G_CPU           = (1U << __FIO_OPT_G_CPU),
+       FIO_OPT_G_LOG           = (1U << __FIO_OPT_G_LOG),
+       FIO_OPT_G_ZONE          = (1U << __FIO_OPT_G_ZONE),
+       FIO_OPT_G_CACHE         = (1U << __FIO_OPT_G_CACHE),
+       FIO_OPT_G_STAT          = (1U << __FIO_OPT_G_STAT),
+       FIO_OPT_G_ERR           = (1U << __FIO_OPT_G_ERR),
+       FIO_OPT_G_JOB           = (1U << __FIO_OPT_G_JOB),
+       FIO_OPT_G_INVALID       = (1U << __FIO_OPT_G_NR),
+};
+
+extern struct opt_group *opt_group_from_mask(unsigned int *mask);
+
 #endif
diff --git a/parse.c b/parse.c
index cdd9ac7e3cf0cb9e81a25d2fd43aba205c90ce88..9891974d57bca8bd62752f78e421a8b6978d62f3 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -15,7 +15,7 @@
 #include "debug.h"
 #include "options.h"
 
-static struct fio_option *fio_options;
+static struct fio_option *__fio_options;
 extern unsigned int fio_get_kb_base(void *);
 
 static int vp_cmp(const void *p1, const void *p2)
@@ -260,7 +260,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);
 }
@@ -770,14 +770,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);
@@ -788,9 +788,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,
diff --git a/parse.h b/parse.h
index 68a7338e32d34ed929cb5173c18df43273e2920f..b3d86138f25a4474a65cf67bd63d1dab5a35e871 100644 (file)
--- a/parse.h
+++ b/parse.h
@@ -35,26 +35,6 @@ struct value_pair {
 #define OPT_LEN_MAX    4096
 #define PARSE_MAX_VP   16
 
-enum opt_category {
-       FIO_OPT_G_DESC          = 1UL << 0,
-       FIO_OPT_G_FILE          = 1UL << 1,
-       FIO_OPT_G_MISC          = 1UL << 2,
-       FIO_OPT_G_IO            = 1UL << 3,
-       FIO_OPT_G_IO_DDIR       = 1UL << 4,
-       FIO_OPT_G_IO_BUF        = 1UL << 5,
-       FIO_OPT_G_RAND          = 1UL << 6,
-       FIO_OPT_G_OS            = 1UL << 7,
-       FIO_OPT_G_MEM           = 1UL << 8,
-       FIO_OPT_G_VERIFY        = 1UL << 9,
-       FIO_OPT_G_CPU           = 1UL << 10,
-       FIO_OPT_G_LOG           = 1UL << 11,
-       FIO_OPT_G_ZONE          = 1UL << 12,
-       FIO_OPT_G_CACHE         = 1UL << 13,
-       FIO_OPT_G_STAT          = 1UL << 14,
-       FIO_OPT_G_ERR           = 1UL << 15,
-       FIO_OPT_G_JOB           = 1UL << 16,
-};
-
 /*
  * Option define
  */
@@ -98,6 +78,7 @@ extern void options_free(struct fio_option *, void *);
 extern void strip_blank_front(char **);
 extern void strip_blank_end(char *);
 extern int str_to_decimal(const char *, long long *, int, void *);
+extern int check_str_bytes(const char *p, long long *val, void *data);
 
 /*
  * Handlers for the options