X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=parse.c;h=8cd427a9f3ce2b6cf7547ce4822d8da614e7b82e;hp=6e935f31069f3cf0076fb5806c8a595d82b6ff65;hb=02bcaa8c31feb93c61b701d143a7eea3efd2124d;hpb=f90eff5a414f6e8c16a51c3a7d9b5e077ab49aac diff --git a/parse.c b/parse.c index 6e935f31..8cd427a9 100644 --- a/parse.c +++ b/parse.c @@ -64,6 +64,7 @@ static int str_to_decimal(const char *str, unsigned long long *val, int kilo) *val *= get_mult_bytes(str[len - 1]); else *val *= get_mult_time(str[len - 1]); + return 0; } @@ -99,6 +100,9 @@ static int check_range_bytes(const char *str, unsigned long *val) { char suffix; + if (!strlen(str)) + return 1; + if (sscanf(str, "%lu%c", val, &suffix) == 2) { *val *= get_mult_bytes(suffix); return 0; @@ -112,6 +116,8 @@ static int check_range_bytes(const char *str, unsigned long *val) static int check_int(const char *p, unsigned int *val) { + if (!strlen(p)) + return 1; if (sscanf(p, "%u", val) == 1) return 0; @@ -133,15 +139,26 @@ static struct fio_option *find_option(struct fio_option *options, return NULL; } +#define val_store(ptr, val, off, data) \ + do { \ + ptr = td_var((data), (off)); \ + *ptr = (val); \ + } while (0) + static int __handle_option(struct fio_option *o, const char *ptr, void *data, - int first) + int first, int more) { - unsigned int il, *ilp1, *ilp2; + unsigned int il, *ilp; unsigned long long ull, *ullp; unsigned long ul1, ul2; char **cp; int ret = 0, is_time = 0; + if (!ptr && o->type != FIO_OPT_STR_SET) { + fprintf(stderr, "Option %s requires an argument\n", o->name); + return 1; + } + switch (o->type) { case FIO_OPT_STR: { fio_opt_str_fn *fn = o->cb; @@ -170,29 +187,15 @@ static int __handle_option(struct fio_option *o, const char *ptr, void *data, ret = fn(data, &ull); else { if (o->type == FIO_OPT_STR_VAL_INT) { - if (first) { - ilp1 = td_var(data, o->off1); - *ilp1 = ull; - if (o->off2) { - ilp1 = td_var(data, o->off2); - *ilp1 = ull; - } - } else if (o->off2) { - ilp1 = td_var(data, o->off2); - *ilp1 = ull; - } + if (first) + val_store(ilp, ull, o->off1, data); + if (!more && o->off2) + val_store(ilp, ull, o->off2, data); } else { - if (first) { - ullp = td_var(data, o->off1); - *ullp = ull; - if (o->off2) { - ullp = td_var(data, o->off2); - *ullp = ull; - } - } else if (o->off2) { - ullp = td_var(data, o->off2); - *ullp = ull; - } + if (first) + val_store(ullp, ull, o->off1, data); + if (!more && o->off2) + val_store(ullp, ull, o->off2, data); } } break; @@ -228,24 +231,15 @@ static int __handle_option(struct fio_option *o, const char *ptr, void *data, } if (first) { - ilp1 = td_var(data, o->off1); - ilp2 = td_var(data, o->off2); - *ilp1 = ul1; - *ilp2 = ul2; - if (o->off3 && o->off4) { - ilp1 = td_var(data, o->off3); - ilp2 = td_var(data, o->off4); - *ilp1 = ul1; - *ilp2 = ul2; - } - } else if (o->off3 && o->off4) { - ilp1 = td_var(data, o->off3); - ilp2 = td_var(data, o->off4); - *ilp1 = ul1; - *ilp2 = ul2; + val_store(ilp, ul1, o->off1, data); + val_store(ilp, ul2, o->off2, data); + } + if (!more && o->off3 && o->off4) { + val_store(ilp, ul1, o->off3, data); + val_store(ilp, ul2, o->off4, data); } - } - + } + break; } case FIO_OPT_INT: { @@ -261,12 +255,10 @@ static int __handle_option(struct fio_option *o, const char *ptr, void *data, if (fn) ret = fn(data, &il); else { - if (first || !o->off2) - ilp1 = td_var(data, o->off1); - else - ilp1 = td_var(data, o->off2); - - *ilp1 = il; + if (first) + val_store(ilp, il, o->off1, data); + if (!more && o->off2) + val_store(ilp, il, o->off2, data); } break; } @@ -276,12 +268,10 @@ static int __handle_option(struct fio_option *o, const char *ptr, void *data, if (fn) ret = fn(data); else { - if (first || !o->off2) - ilp1 = td_var(data, o->off1); - else - ilp1 = td_var(data, o->off2); - - *ilp1 = 1; + if (first) + val_store(ilp, 1, o->off1, data); + if (!more && o->off2) + val_store(ilp, 1, o->off2, data); } break; } @@ -295,22 +285,31 @@ static int __handle_option(struct fio_option *o, const char *ptr, void *data, static int handle_option(struct fio_option *o, const char *ptr, void *data) { - const char *ptr2; - int ret; + const char *ptr2 = NULL; + int r1, r2; - ret = __handle_option(o, ptr, data, 1); - if (ret) - return ret; + /* + * 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 + * copy set 1 options to set 2. + */ + if (ptr) + ptr2 = strchr(ptr, ','); /* - * See if we have a second set of parameters, hidden after a comma + * Don't return early if parsing the first option fails - if + * we are doing multiple arguments, we can allow the first one + * being empty. */ - ptr2 = strchr(ptr, ','); + r1 = __handle_option(o, ptr, data, 1, !!ptr2); + if (!ptr2) - return 0; + return r1; ptr2++; - return __handle_option(o, ptr2, data, 0); + r2 = __handle_option(o, ptr2, data, 0, 0); + + return r1 && r2; } int parse_cmd_option(const char *opt, const char *val,