X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=parse.c;h=f4cefcf6243edbd911cb4f274611912c440a5f07;hp=194ad594779a59a6de8104939fd5b7ef5dc1f69a;hb=2fbe1e195999e23c95b08d03eadac0b5f95330e7;hpb=a94aedbc11829470cce77eb52969601d618054d6 diff --git a/parse.c b/parse.c index 194ad594..f4cefcf6 100644 --- a/parse.c +++ b/parse.c @@ -120,19 +120,22 @@ static void show_option_values(const struct fio_option *o) static void show_option_help(const struct fio_option *o, int is_err) { 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)", - "string with dual range (opt=1k-4k,4k-8k)", - "integer value (opt=100)", - "boolean value (opt=1)", - "list of floating point values separated by ':' (opt=5.9:7.8)", - "no argument (opt)", - "deprecated", - "unsupported", + [FIO_OPT_INVALID] = "invalid", + [FIO_OPT_STR] = "string (opt=bla)", + [FIO_OPT_STR_ULL] = "string (opt=bla)", + [FIO_OPT_STR_MULTI] = "string with possible k/m/g postfix (opt=4k)", + [FIO_OPT_STR_VAL] = "string (opt=bla)", + [FIO_OPT_STR_VAL_TIME] = "string with time postfix (opt=10s)", + [FIO_OPT_STR_STORE] = "string (opt=bla)", + [FIO_OPT_RANGE] = "one to three ranges (opt=1k-4k[,4k-8k[,1k-8k]])", + [FIO_OPT_INT] = "integer value (opt=100)", + [FIO_OPT_ULL] = "integer value (opt=100)", + [FIO_OPT_BOOL] = "boolean value (opt=1)", + [FIO_OPT_FLOAT_LIST] = "list of floating point values separated by ':' (opt=5.9:7.8)", + [FIO_OPT_STR_SET] = "empty or boolean value ([0|1])", + [FIO_OPT_DEPRECATED] = "deprecated", + [FIO_OPT_SOFT_DEPRECATED] = "deprecated", + [FIO_OPT_UNSUPPORTED] = "unsupported", }; ssize_t (*logger)(const char *format, ...); @@ -370,12 +373,16 @@ int str_to_decimal(const char *str, long long *val, int kilo, void *data, #endif if (rc == 1) { + char *endptr; + if (strstr(str, "0x") || strstr(str, "0X")) base = 16; else base = 10; - *val = strtoll(str, NULL, base); + *val = strtoll(str, &endptr, base); + if (*val == 0 && endptr == str) + return 1; if (*val == LONG_MAX && errno == ERANGE) return 1; } @@ -503,6 +510,33 @@ static const char *opt_type_name(const struct fio_option *o) return "OPT_UNKNOWN?"; } +static bool val_too_large(const struct fio_option *o, unsigned long long val, + bool is_uint) +{ + if (!o->maxval) + return false; + + if (is_uint) { + if ((int) val < 0) + return (int) val > (int) o->maxval; + return (unsigned int) val > o->maxval; + } + + return val > o->maxval; +} + +static bool val_too_small(const struct fio_option *o, unsigned long long val, + bool is_uint) +{ + if (!o->minval) + return false; + + if (is_uint) + return (int) val < o->minval; + + return val < o->minval; +} + static int __handle_option(const struct fio_option *o, const char *ptr, void *data, int first, int more, int curr) { @@ -562,7 +596,7 @@ static int __handle_option(const struct fio_option *o, const char *ptr, } case FIO_OPT_STR_VAL_TIME: is_time = 1; - /* fall through */ + fallthrough; case FIO_OPT_ULL: case FIO_OPT_INT: case FIO_OPT_STR_VAL: { @@ -572,8 +606,7 @@ static int __handle_option(const struct fio_option *o, const char *ptr, if (!is_time && o->is_time) is_time = o->is_time; - tmp[sizeof(tmp) - 1] = '\0'; - strncpy(tmp, ptr, sizeof(tmp) - 1); + snprintf(tmp, sizeof(tmp), "%s", ptr); p = strchr(tmp, ','); if (p) *p = '\0'; @@ -592,14 +625,14 @@ static int __handle_option(const struct fio_option *o, const char *ptr, return 1; } - if (o->maxval && ull > o->maxval) { - log_err("max value out of range: %llu" - " (%llu max)\n", ull, o->maxval); + if (val_too_large(o, ull, o->type == FIO_OPT_INT)) { + log_err("%s: max value out of range: %llu" + " (%llu max)\n", o->name, ull, o->maxval); return 1; } - if (o->minval && ull < o->minval) { - log_err("min value out of range: %lld" - " (%d min)\n", ull, o->minval); + if (val_too_small(o, ull, o->type == FIO_OPT_INT)) { + log_err("%s: min value out of range: %lld" + " (%d min)\n", o->name, ull, o->minval); return 1; } if (o->posval[0].ival) { @@ -799,8 +832,7 @@ static int __handle_option(const struct fio_option *o, const char *ptr, char tmp[128]; char *p1, *p2; - tmp[sizeof(tmp) - 1] = '\0'; - strncpy(tmp, ptr, sizeof(tmp) - 1); + snprintf(tmp, sizeof(tmp), "%s", ptr); /* Handle bsrange with separate read,write values: */ p1 = strchr(tmp, ','); @@ -909,7 +941,7 @@ static int __handle_option(const struct fio_option *o, const char *ptr, } case FIO_OPT_DEPRECATED: ret = 1; - /* fall through */ + fallthrough; case FIO_OPT_SOFT_DEPRECATED: log_info("Option %s is deprecated\n", o->name); break; @@ -959,6 +991,7 @@ static int handle_option(const struct fio_option *o, const char *__ptr, if (ptr && (o->type != FIO_OPT_STR_STORE) && (o->type != FIO_OPT_STR) && + (o->type != FIO_OPT_STR_ULL) && (o->type != FIO_OPT_FLOAT_LIST)) { ptr2 = strchr(ptr, ','); if (ptr2 && *(ptr2 + 1) == '\0') @@ -1015,7 +1048,20 @@ struct fio_option *find_option(struct fio_option *options, const char *opt) const struct fio_option * find_option_c(const struct fio_option *options, const char *opt) { - return find_option((struct fio_option *)options, opt); + const struct fio_option *o; + + for (o = &options[0]; o->name; o++) { + if (!o_match(o, opt)) + continue; + if (o->type == FIO_OPT_UNSUPPORTED) { + log_err("Option <%s>: %s\n", o->name, o->help); + continue; + } + + return o; + } + + return NULL; } static const struct fio_option * @@ -1372,9 +1418,6 @@ static void option_init(struct fio_option *o) o->category = FIO_OPT_C_GENERAL; o->group = FIO_OPT_G_INVALID; } - if (o->type == FIO_OPT_STR || o->type == FIO_OPT_STR_STORE || - o->type == FIO_OPT_STR_MULTI) - return; } /*