X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=parse.c;h=78218615b79246a50c02107b7907ef747dd95476;hp=c2d744b3088f5a4d74f1e94e9ea9631f9b2859e4;hb=783500ad13ededece6c8912af1c937f990880e1f;hpb=7c8f1a5ce2ecde0ef8372e983895855ac838c76c diff --git a/parse.c b/parse.c index c2d744b3..78218615 100644 --- a/parse.c +++ b/parse.c @@ -14,6 +14,7 @@ #include "debug.h" static struct fio_option *fio_options; +extern unsigned int fio_get_kb_base(void *); static int vp_cmp(const void *p1, const void *p2) { @@ -41,12 +42,15 @@ static void posval_sort(struct fio_option *o, struct value_pair *vpmap) qsort(vpmap, entries, sizeof(struct value_pair), vp_cmp); } -static void show_option_range(struct fio_option *o) +static void show_option_range(struct fio_option *o, FILE *out) { if (!o->minval && !o->maxval) return; - printf("%20s: min=%d, max=%d\n", "range", o->minval, o->maxval); + fprintf(out, "%20s: min=%d", "range", o->minval); + if (o->maxval) + fprintf(out, ", max=%d", o->maxval); + fprintf(out, "\n"); } static void show_option_values(struct fio_option *o) @@ -70,6 +74,28 @@ static void show_option_values(struct fio_option *o) printf("\n"); } +static void show_option_help(struct fio_option *o, FILE *out) +{ + const char *typehelp[] = { + "string (opt=bla)", + "string with possible k/m/g postfix (opt=4k)", + "string with time postfix (opt=10s)", + "string (opt=bla)", + "string with dual range (opt=1k-4k,4k-8k)", + "integer value (opt=100)", + "boolean value (opt=1)", + "no argument (opt)", + }; + + if (o->alias) + fprintf(out, "%20s: %s\n", "alias", o->alias); + + fprintf(out, "%20s: %s\n", "type", typehelp[o->type]); + fprintf(out, "%20s: %s\n", "default", o->def ? o->def : "no default"); + show_option_range(o, stdout); + show_option_values(o); +} + static unsigned long get_mult_time(char c) { switch (c) { @@ -87,30 +113,39 @@ static unsigned long get_mult_time(char c) } } -static unsigned long get_mult_bytes(char c) +static unsigned long long get_mult_bytes(char c, void *data) { + unsigned int kb_base = fio_get_kb_base(data); + unsigned long long ret = 1; + switch (c) { - case 'k': - case 'K': - return 1024; - case 'm': - case 'M': - return 1024 * 1024; + default: + break; + case 'p': + case 'P': + ret *= (unsigned long long) kb_base; + case 't': + case 'T': + ret *= (unsigned long long) kb_base; case 'g': case 'G': - return 1024 * 1024 * 1024; - case 'e': - case 'E': - return 1024 * 1024 * 1024 * 1024UL; - default: - return 1; + ret *= (unsigned long long) kb_base; + case 'm': + case 'M': + ret *= (unsigned long long) kb_base; + case 'k': + case 'K': + ret *= (unsigned long long) kb_base; + break; } + + return ret; } /* * convert string into decimal value, noting any size suffix */ -int str_to_decimal(const char *str, long long *val, int kilo) +int str_to_decimal(const char *str, long long *val, int kilo, void *data) { int len, base; @@ -128,21 +163,21 @@ int str_to_decimal(const char *str, long long *val, int kilo) return 1; if (kilo) - *val *= get_mult_bytes(str[len - 1]); + *val *= get_mult_bytes(str[len - 1], data); else *val *= get_mult_time(str[len - 1]); return 0; } -static int check_str_bytes(const char *p, long long *val) +static int check_str_bytes(const char *p, long long *val, void *data) { - return str_to_decimal(p, val, 1); + return str_to_decimal(p, val, 1, data); } static int check_str_time(const char *p, long long *val) { - return str_to_decimal(p, val, 0); + return str_to_decimal(p, val, 0, NULL); } void strip_blank_front(char **p) @@ -175,7 +210,7 @@ void strip_blank_end(char *p) *(s + 1) = '\0'; } -static int check_range_bytes(const char *str, long *val) +static int check_range_bytes(const char *str, long *val, void *data) { char suffix; @@ -183,7 +218,7 @@ static int check_range_bytes(const char *str, long *val) return 1; if (sscanf(str, "%lu%c", val, &suffix) == 2) { - *val *= get_mult_bytes(suffix); + *val *= get_mult_bytes(suffix, data); return 0; } @@ -278,14 +313,13 @@ static int __handle_option(struct fio_option *o, const char *ptr, void *data, case FIO_OPT_STR_VAL_TIME: is_time = 1; case FIO_OPT_INT: - case FIO_OPT_STR_VAL: - case FIO_OPT_STR_VAL_INT: { + case FIO_OPT_STR_VAL: { fio_opt_str_val_fn *fn = o->cb; if (is_time) ret = check_str_time(ptr, &ull); else - ret = check_str_bytes(ptr, &ull); + ret = check_str_bytes(ptr, &ull, data); if (ret) break; @@ -304,8 +338,7 @@ static int __handle_option(struct fio_option *o, const char *ptr, void *data, if (fn) ret = fn(data, &ull); else { - if (o->type == FIO_OPT_STR_VAL_INT || - o->type == FIO_OPT_INT) { + if (o->type == FIO_OPT_INT) { if (first) val_store(ilp, ull, o->off1, data); if (!more && o->off2) @@ -353,8 +386,8 @@ static int __handle_option(struct fio_option *o, const char *ptr, void *data, p1 = tmp; ret = 1; - if (!check_range_bytes(p1, &ul1) && - !check_range_bytes(p2, &ul2)) { + if (!check_range_bytes(p1, &ul1, data) && + !check_range_bytes(p2, &ul2, data)) { ret = 0; if (ul1 > ul2) { unsigned long foo = ul1; @@ -427,6 +460,18 @@ static int __handle_option(struct fio_option *o, const char *ptr, void *data, ret = 1; } + if (ret) + return ret; + + if (o->verify) { + ret = o->verify(o, data); + if (ret) { + fprintf(stderr,"Correct format for offending option\n"); + fprintf(stderr, "%20s: %s\n", o->name, o->help); + show_option_help(o, stderr); + } + } + return ret; } @@ -512,7 +557,7 @@ static int opt_cmp(const void *p1, const void *p2) o1 = get_option(s1, fio_options, &foo); o2 = get_option(s2, fio_options, &foo); - + prio1 = prio2 = 0; if (o1) prio1 = o1->prio; @@ -661,29 +706,6 @@ static int string_distance(const char *s1, const char *s2) return i; } -static void show_option_help(struct fio_option *o) -{ - const char *typehelp[] = { - "string (opt=bla)", - "string with possible k/m/g postfix (opt=4k)", - "string with range and postfix (opt=1k-4k)", - "string with time postfix (opt=10s)", - "string (opt=bla)", - "string with dual range (opt=1k-4k,4k-8k)", - "integer value (opt=100)", - "boolean value (opt=1)", - "no argument (opt)", - }; - - if (o->alias) - printf("%20s: %s\n", "alias", o->alias); - - printf("%20s: %s\n", "type", typehelp[o->type]); - printf("%20s: %s\n", "default", o->def ? o->def : "no default"); - show_option_range(o); - show_option_values(o); -} - static struct fio_option *find_child(struct fio_option *options, struct fio_option *o) { @@ -788,7 +810,7 @@ int show_cmd_help(struct fio_option *options, const char *name) if (!match) continue; - show_option_help(o); + show_option_help(o, stdout); } if (found) @@ -798,7 +820,7 @@ int show_cmd_help(struct fio_option *options, const char *name) if (closest) { printf(" - showing closest match\n"); printf("%20s: %s\n", closest->name, closest->help); - show_option_help(closest); + show_option_help(closest, stdout); } else printf("\n");