X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=parse.c;h=50d8ae5e5f4fe56ea12ba5ff33ca76fe48e114a4;hp=12f769798b778102dc7175edcc35e20b7ecd7187;hb=1e97cce9f5a87a67293a05ec4533ed6968698b2e;hpb=17abbe89b8d3a4c7a4deab00a7cc98fbd215f1ef diff --git a/parse.c b/parse.c index 12f76979..50d8ae5e 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; @@ -140,7 +146,7 @@ static struct fio_option *find_option(struct fio_option *options, } while (0) static int __handle_option(struct fio_option *o, const char *ptr, void *data, - int first) + int first, int more) { unsigned int il, *ilp; unsigned long long ull, *ullp; @@ -148,6 +154,11 @@ static int __handle_option(struct fio_option *o, const char *ptr, void *data, 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; @@ -178,12 +189,12 @@ static int __handle_option(struct fio_option *o, const char *ptr, void *data, if (o->type == FIO_OPT_STR_VAL_INT) { if (first) val_store(ilp, ull, o->off1, data); - if (o->off2) + if (!more && o->off2) val_store(ilp, ull, o->off2, data); } else { if (first) val_store(ullp, ull, o->off1, data); - if (o->off2) + if (!more && o->off2) val_store(ullp, ull, o->off2, data); } } @@ -223,7 +234,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 (o->off3 && o->off4) { + if (!more && o->off3 && o->off4) { val_store(ilp, ul1, o->off3, data); val_store(ilp, ul2, o->off4, data); } @@ -246,7 +257,7 @@ static int __handle_option(struct fio_option *o, const char *ptr, void *data, else { if (first) val_store(ilp, il, o->off1, data); - if (o->off2) + if (!more && o->off2) val_store(ilp, il, o->off2, data); } break; @@ -259,13 +270,13 @@ static int __handle_option(struct fio_option *o, const char *ptr, void *data, else { if (first) val_store(ilp, 1, o->off1, data); - if (o->off2) + if (!more && o->off2) val_store(ilp, 1, o->off2, data); } break; } default: - fprintf(stderr, "Bad option type %d\n", o->type); + fprintf(stderr, "Bad option type %u\n", o->type); ret = 1; } @@ -274,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,