X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=parse.c;h=ad2782f0fbe93c9ddc822015343390d37f967a98;hp=db2f5a42f85aa68b5c7e768f0dee5f2be14cef2a;hb=74ba1808c32e978229eefa7cf28c08bcb73b5b5d;hpb=1d1c187b36fd4ee28d72d04660b37a7c3edd64e6 diff --git a/parse.c b/parse.c index db2f5a42..ad2782f0 100644 --- a/parse.c +++ b/parse.c @@ -79,6 +79,7 @@ static void show_option_help(struct fio_option *o, FILE *out) const char *typehelp[] = { "invalid", "string (opt=bla)", + "string (opt=bla)", "string with possible k/m/g postfix (opt=4k)", "string with time postfix (opt=10s)", "string (opt=bla)", @@ -117,7 +118,8 @@ static unsigned long get_mult_time(char c) } } -static unsigned long long __get_mult_bytes(const char *p, void *data) +static unsigned long long __get_mult_bytes(const char *p, void *data, + int *percent) { unsigned int kb_base = fio_get_kb_base(data); unsigned long long ret = 1; @@ -157,6 +159,10 @@ static unsigned long long __get_mult_bytes(const char *p, void *data) pow = 2; else if (!strcmp("k", c) || !strcmp("kb", c)) pow = 1; + else if (!strcmp("%", c)) { + *percent = 1; + return ret; + } while (pow--) ret *= (unsigned long long) mult; @@ -165,25 +171,27 @@ static unsigned long long __get_mult_bytes(const char *p, void *data) return ret; } -static unsigned long long get_mult_bytes(const char *str, int len, void *data) +static unsigned long long get_mult_bytes(const char *str, int len, void *data, + int *percent) { - const char *p; + const char *p = str; if (len < 2) - return __get_mult_bytes(str, data); + return __get_mult_bytes(str, data, percent); - /* - * if the last char is 'b' or 'B', the user likely used - * "1gb" instead of just "1g". If the second to last is also - * a letter, adjust. - */ - p = str + len - 1; - while (isalpha(*(p - 1))) - p--; - if (!isalpha(*p)) + /* + * Go forward until we hit a non-digit + */ + while ((p - str) <= len) { + if (!isdigit((int) *p)) + break; + p++; + } + + if (!isalpha((int) *p) && (*p != '%')) p = NULL; - return __get_mult_bytes(p, data); + return __get_mult_bytes(p, data, percent); } /* @@ -206,9 +214,16 @@ int str_to_decimal(const char *str, long long *val, int kilo, void *data) if (*val == LONG_MAX && errno == ERANGE) return 1; - if (kilo) - *val *= get_mult_bytes(str, len, data); - else + if (kilo) { + unsigned long long mult; + int perc = 0; + + mult = get_mult_bytes(str, len, data, &perc); + if (perc) + *val = -1ULL - *val; + else + *val *= mult; + } else *val *= get_mult_time(str[len - 1]); return 0; @@ -228,7 +243,7 @@ void strip_blank_front(char **p) { char *s = *p; - while (isspace(*s)) + while (isspace((int) *s)) s++; *p = s; @@ -248,7 +263,7 @@ void strip_blank_end(char *p) p = s; s = p + strlen(p); - while ((isspace(*s) || iscntrl(*s)) && (s > start)) + while ((isspace((int) *s) || iscntrl((int) *s)) && (s > start)) s--; *(s + 1) = '\0'; @@ -483,10 +498,17 @@ static int __handle_option(struct fio_option *o, const char *ptr, void *data, break; } - case FIO_OPT_BOOL: { + case FIO_OPT_BOOL: + case FIO_OPT_STR_SET: { fio_opt_int_fn *fn = o->cb; - ret = check_int(ptr, &il); + if (ptr) + ret = check_int(ptr, &il); + else if (o->type == FIO_OPT_BOOL) + ret = 1; + else + il = 1; + if (ret) break; @@ -522,27 +544,6 @@ static int __handle_option(struct fio_option *o, const char *ptr, void *data, } break; } - case FIO_OPT_STR_SET: { - fio_opt_str_set_fn *fn = o->cb; - - if (fn) - ret = fn(data); - else { - if (first) { - if (o->roff1) - *(unsigned int *) o->roff1 = 1; - else - val_store(ilp, 1, o->off1, 0, data); - } - if (!more) { - if (o->roff2) - *(unsigned int *) o->roff2 = 1; - else if (o->off2) - val_store(ilp, 1, o->off2, 0, data); - } - } - break; - } case FIO_OPT_DEPRECATED: fprintf(stdout, "Option %s is deprecated\n", o->name); break;