parse.c revision eef02441621aa969f01a1a331e0215dd587d25af
13ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
23ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * This file contains the ini and command liner parser main.
33ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */
43ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include <stdio.h>
53ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include <stdlib.h>
63ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include <unistd.h>
73ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include <ctype.h>
83ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include <string.h>
93ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include <errno.h>
103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include <limits.h>
113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include <stdlib.h>
123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include <math.h>
133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include <float.h>
143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "parse.h"
163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "debug.h"
173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "options.h"
183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "minmax.h"
193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "lib/ieee754.h"
2045ef08fd6a09813e4a8f5ddadf85ba9e0ec2cdc7cristy
213ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic struct fio_option *fio_options;
223ed852eea50f9d4cd633efb8c2b054b8e33c253cristyextern unsigned int fio_get_kb_base(void *);
233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
243ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int vp_cmp(const void *p1, const void *p2)
253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	const struct value_pair *vp1 = p1;
273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	const struct value_pair *vp2 = p2;
283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	return strlen(vp2->ival) - strlen(vp1->ival);
303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
323ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void posval_sort(struct fio_option *o, struct value_pair *vpmap)
333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	const struct value_pair *vp;
353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	int entries;
363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	memset(vpmap, 0, PARSE_MAX_VP * sizeof(struct value_pair));
383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	for (entries = 0; entries < PARSE_MAX_VP; entries++) {
403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		vp = &o->posval[entries];
413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		if (!vp->ival || vp->ival[0] == '\0')
424c08aed51c5899665ade97263692328eea4af106cristy			break;
434c08aed51c5899665ade97263692328eea4af106cristy
444c08aed51c5899665ade97263692328eea4af106cristy		memcpy(&vpmap[entries], vp, sizeof(*vp));
454c08aed51c5899665ade97263692328eea4af106cristy	}
464c08aed51c5899665ade97263692328eea4af106cristy
474c08aed51c5899665ade97263692328eea4af106cristy	qsort(vpmap, entries, sizeof(struct value_pair), vp_cmp);
484c08aed51c5899665ade97263692328eea4af106cristy}
494c08aed51c5899665ade97263692328eea4af106cristy
504c08aed51c5899665ade97263692328eea4af106cristystatic void show_option_range(struct fio_option *o,
514c08aed51c5899665ade97263692328eea4af106cristy				int (*logger)(const char *format, ...))
52030436f8fc9854b6bb39f4d7593d9e70ff83a8cacristy{
534c08aed51c5899665ade97263692328eea4af106cristy	if (o->type == FIO_OPT_FLOAT_LIST){
54c53413df5789700e14e1a67e6cc2716d1716a387cristy		if (o->minfp == DBL_MIN && o->maxfp == DBL_MAX)
554c08aed51c5899665ade97263692328eea4af106cristy			return;
564c08aed51c5899665ade97263692328eea4af106cristy
574c08aed51c5899665ade97263692328eea4af106cristy		logger("%20s: min=%f", "range", o->minfp);
584c08aed51c5899665ade97263692328eea4af106cristy		if (o->maxfp != DBL_MAX)
594c08aed51c5899665ade97263692328eea4af106cristy			logger(", max=%f", o->maxfp);
604c08aed51c5899665ade97263692328eea4af106cristy		logger("\n");
614c08aed51c5899665ade97263692328eea4af106cristy	} else {
624c08aed51c5899665ade97263692328eea4af106cristy		if (!o->minval && !o->maxval)
634c08aed51c5899665ade97263692328eea4af106cristy			return;
644c08aed51c5899665ade97263692328eea4af106cristy
654c08aed51c5899665ade97263692328eea4af106cristy		logger("%20s: min=%d", "range", o->minval);
664c08aed51c5899665ade97263692328eea4af106cristy		if (o->maxval)
672c5fc27ae5b613b7fb9fd69c12a47b99c7d4d471cristy			logger(", max=%d", o->maxval);
684c08aed51c5899665ade97263692328eea4af106cristy		logger("\n");
694c08aed51c5899665ade97263692328eea4af106cristy	}
704c08aed51c5899665ade97263692328eea4af106cristy}
714c08aed51c5899665ade97263692328eea4af106cristy
724c08aed51c5899665ade97263692328eea4af106cristystatic void show_option_values(struct fio_option *o)
734c08aed51c5899665ade97263692328eea4af106cristy{
744c08aed51c5899665ade97263692328eea4af106cristy	int i;
754c08aed51c5899665ade97263692328eea4af106cristy
764c08aed51c5899665ade97263692328eea4af106cristy	for (i = 0; i < PARSE_MAX_VP; i++) {
774c08aed51c5899665ade97263692328eea4af106cristy		const struct value_pair *vp = &o->posval[i];
784c08aed51c5899665ade97263692328eea4af106cristy
794c08aed51c5899665ade97263692328eea4af106cristy		if (!vp->ival)
8063a81879d3568083e4ee4f78ebcae2bc831cb764cristy			continue;
814c08aed51c5899665ade97263692328eea4af106cristy
82d1dd6e4fefa0810b9893e6ac9418f79c97c1b39acristy		log_info("%20s: %-10s", i == 0 ? "valid values" : "", vp->ival);
834c08aed51c5899665ade97263692328eea4af106cristy		if (vp->help)
84bcbda3fd7d9f3084869f5cebabceb0324c3b2cd7cristy			log_info(" %s", vp->help);
854c08aed51c5899665ade97263692328eea4af106cristy		log_info("\n");
864c08aed51c5899665ade97263692328eea4af106cristy	}
874c08aed51c5899665ade97263692328eea4af106cristy
883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	if (i)
893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		log_info("\n");
903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
923ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void show_option_help(struct fio_option *o, int is_err)
933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	const char *typehelp[] = {
953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		"invalid",
963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		"string (opt=bla)",
973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		"string (opt=bla)",
983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		"string with possible k/m/g postfix (opt=4k)",
993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		"string with time postfix (opt=10s)",
1003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		"string (opt=bla)",
1013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		"string with dual range (opt=1k-4k,4k-8k)",
1023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		"integer value (opt=100)",
1033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		"boolean value (opt=1)",
1043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		"list of floating point values separated by ':' (opt=5.9:7.8)",
1053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		"no argument (opt)",
1063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		"deprecated",
1073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	};
1083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	int (*logger)(const char *format, ...);
1093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	if (is_err)
1113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		logger = log_err;
112ce70c17bb6433add2eb069515a4f3105989e0662cristy	else
1133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		logger = log_info;
1143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1154c08aed51c5899665ade97263692328eea4af106cristy	if (o->alias)
1167e9f233e6549b1e1856c1aa85b3f4dee8e9493facristy		logger("%20s: %s\n", "alias", o->alias);
1177e9f233e6549b1e1856c1aa85b3f4dee8e9493facristy
1187e9f233e6549b1e1856c1aa85b3f4dee8e9493facristy	logger("%20s: %s\n", "type", typehelp[o->type]);
1197e9f233e6549b1e1856c1aa85b3f4dee8e9493facristy	logger("%20s: %s\n", "default", o->def ? o->def : "no default");
1207e9f233e6549b1e1856c1aa85b3f4dee8e9493facristy	if (o->prof_name)
1217e9f233e6549b1e1856c1aa85b3f4dee8e9493facristy		logger("%20s: only for profile '%s'\n", "valid", o->prof_name);
1224c08aed51c5899665ade97263692328eea4af106cristy	show_option_range(o, logger);
1234c08aed51c5899665ade97263692328eea4af106cristy	show_option_values(o);
1244c08aed51c5899665ade97263692328eea4af106cristy}
1254c08aed51c5899665ade97263692328eea4af106cristy
1264c08aed51c5899665ade97263692328eea4af106cristystatic unsigned long get_mult_time(char c)
1274c08aed51c5899665ade97263692328eea4af106cristy{
1284c08aed51c5899665ade97263692328eea4af106cristy	switch (c) {
129ce70c17bb6433add2eb069515a4f3105989e0662cristy	case 'm':
1303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	case 'M':
1313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		return 60;
132ce70c17bb6433add2eb069515a4f3105989e0662cristy	case 'h':
1333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	case 'H':
1343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		return 60 * 60;
135bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy	case 'd':
1367e9f233e6549b1e1856c1aa85b3f4dee8e9493facristy	case 'D':
1377e9f233e6549b1e1856c1aa85b3f4dee8e9493facristy		return 24 * 60 * 60;
1387e9f233e6549b1e1856c1aa85b3f4dee8e9493facristy	default:
1393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		return 1;
1403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	}
1413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1433ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic unsigned long long __get_mult_bytes(const char *p, void *data,
1443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					   int *percent)
1453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	unsigned int kb_base = fio_get_kb_base(data);
1473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	unsigned long long ret = 1;
1483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	unsigned int i, pow = 0, mult = kb_base;
1493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	char *c;
1503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	if (!p)
1523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		return 1;
1533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	c = strdup(p);
1553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	for (i = 0; i < strlen(c); i++)
1573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		c[i] = tolower(c[i]);
1583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	if (!strcmp("pib", c)) {
1603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		pow = 5;
1613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		mult = 1000;
1623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	} else if (!strcmp("tib", c)) {
1633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		pow = 4;
1643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		mult = 1000;
1653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	} else if (!strcmp("gib", c)) {
1663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		pow = 3;
1673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		mult = 1000;
1683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	} else if (!strcmp("mib", c)) {
1693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		pow = 2;
1703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		mult = 1000;
1713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	} else if (!strcmp("kib", c)) {
1723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		pow = 1;
1733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		mult = 1000;
1743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	} else if (!strcmp("p", c) || !strcmp("pb", c))
1753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		pow = 5;
1763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	else if (!strcmp("t", c) || !strcmp("tb", c))
1773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		pow = 4;
1783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	else if (!strcmp("g", c) || !strcmp("gb", c))
1793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		pow = 3;
1803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	else if (!strcmp("m", c) || !strcmp("mb", c))
1813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		pow = 2;
1823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	else if (!strcmp("k", c) || !strcmp("kb", c))
1833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		pow = 1;
1843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	else if (!strcmp("%", c)) {
1853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		*percent = 1;
1863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		free(c);
1873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		return ret;
1883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	}
1893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	while (pow--)
1913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		ret *= (unsigned long long) mult;
1923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
193bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy	free(c);
1943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	return ret;
1953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1973ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic unsigned long long get_mult_bytes(const char *str, int len, void *data,
1983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					 int *percent)
1993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	const char *p = str;
2013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	int digit_seen = 0;
2023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	if (len < 2)
2043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		return __get_mult_bytes(str, data, percent);
2053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	/*
2073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	 * Go forward until we hit a non-digit, or +/- sign
2083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	 */
209a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy	while ((p - str) <= len) {
2103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		if (!isdigit((int) *p) &&
2113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		    (((*p != '+') && (*p != '-')) || digit_seen))
2123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			break;
2133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		digit_seen |= isdigit((int) *p);
2143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		p++;
2153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	}
2163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	if (!isalpha((int) *p) && (*p != '%'))
2183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		p = NULL;
219e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy
2203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	return __get_mult_bytes(p, data, percent);
221e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy}
2223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
2243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * Convert string into a floating number. Return 1 for success and 0 otherwise.
2253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */
2263ed852eea50f9d4cd633efb8c2b054b8e33c253cristyint str_to_float(const char *str, double *val)
2273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	return (1 == sscanf(str, "%lf", val));
2293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
2303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
2323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * convert string into decimal value, noting any size suffix
2333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */
2343ed852eea50f9d4cd633efb8c2b054b8e33c253cristyint str_to_decimal(const char *str, long long *val, int kilo, void *data)
2353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	int len, base;
2373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	len = strlen(str);
2393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	if (!len)
2403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		return 1;
2413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	if (strstr(str, "0x") || strstr(str, "0X"))
2433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		base = 16;
2443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	else
2453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		base = 10;
2463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	*val = strtoll(str, NULL, base);
2483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	if (*val == LONG_MAX && errno == ERANGE)
2493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		return 1;
2503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	if (kilo) {
2523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		unsigned long long mult;
2533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		int perc = 0;
2543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		mult = get_mult_bytes(str, len, data, &perc);
2563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		if (perc)
2573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			*val = -1ULL - *val;
2583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		else
2593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			*val *= mult;
2603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	} else
2613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		*val *= get_mult_time(str[len - 1]);
2623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	return 0;
2643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
2653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2663ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int check_str_bytes(const char *p, long long *val, void *data)
2673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	return str_to_decimal(p, val, 1, data);
2693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
2703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2713ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int check_str_time(const char *p, long long *val)
2723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	return str_to_decimal(p, val, 0, NULL);
2743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
2753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2763ed852eea50f9d4cd633efb8c2b054b8e33c253cristyvoid strip_blank_front(char **p)
2773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	char *s = *p;
2793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	if (!strlen(s))
2813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		return;
2823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	while (isspace((int) *s))
2833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		s++;
2843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	*p = s;
2863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
2873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2883ed852eea50f9d4cd633efb8c2b054b8e33c253cristyvoid strip_blank_end(char *p)
2893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	char *start = p, *s;
2913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	if (!strlen(p))
2933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		return;
2943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	s = strchr(p, ';');
2963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	if (s)
2973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		*s = '\0';
2983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	s = strchr(p, '#');
2993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	if (s)
3003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		*s = '\0';
3013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	if (s)
3023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		p = s;
3033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	s = p + strlen(p);
3053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	while ((isspace((int) *s) || iscntrl((int) *s)) && (s > start))
3063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		s--;
3073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	*(s + 1) = '\0';
3093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
3103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3113ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int check_range_bytes(const char *str, long *val, void *data)
3123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
3133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	long long __val;
3143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	if (!str_to_decimal(str, &__val, 1, data)) {
3163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		*val = __val;
3173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		return 0;
3183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	}
3193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	return 1;
3213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
3223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3233ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int check_int(const char *p, int *val)
3243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
3253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	if (!strlen(p))
3263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		return 1;
3273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	if (strstr(p, "0x") || strstr(p, "0X")) {
3283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		if (sscanf(p, "%x", val) == 1)
3293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			return 0;
3303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	} else {
3313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		if (sscanf(p, "%u", val) == 1)
3323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			return 0;
3333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	}
3343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	return 1;
3363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
3373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3383ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int opt_len(const char *str)
3393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
3403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	char *postfix;
3413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	postfix = strchr(str, ':');
3433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	if (!postfix)
3443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		return strlen(str);
3453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	return (int)(postfix - str);
3473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
3483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3493ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int str_match_len(const struct value_pair *vp, const char *str)
3503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
3513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	return max(strlen(vp->ival), opt_len(str));
3523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
3533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define val_store(ptr, val, off, or, data)		\
3553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	do {						\
3563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		ptr = td_var((data), (off));		\
3573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		if ((or))				\
3583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			*ptr |= (val);			\
3593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		else					\
3603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			*ptr = (val);			\
3613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	} while (0)
3623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3633ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int __handle_option(struct fio_option *o, const char *ptr, void *data,
3643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			   int first, int more, int curr)
3653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
366f2faecf9facdbbb14fcba373365f9f691a9658e0cristy	int il, *ilp;
367f2faecf9facdbbb14fcba373365f9f691a9658e0cristy	fio_fp64_t *flp;
3683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	long long ull, *ullp;
3693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	long ul1, ul2;
3703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	double uf;
3713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	char **cp = NULL;
3723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	int ret = 0, is_time = 0;
3733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	const struct value_pair *vp;
3743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	struct value_pair posval[PARSE_MAX_VP];
3753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	int i, all_skipped = 1;
376f2faecf9facdbbb14fcba373365f9f691a9658e0cristy
377f2faecf9facdbbb14fcba373365f9f691a9658e0cristy	dprint(FD_PARSE, "__handle_option=%s, type=%d, ptr=%s\n", o->name,
3783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy							o->type, ptr);
3793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	if (!ptr && o->type != FIO_OPT_STR_SET && o->type != FIO_OPT_STR) {
3813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		log_err("Option %s requires an argument\n", o->name);
3823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		return 1;
3833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	}
3843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	switch (o->type) {
3863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	case FIO_OPT_STR:
3873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	case FIO_OPT_STR_MULTI: {
3883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		fio_opt_str_fn *fn = o->cb;
3893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		posval_sort(o, posval);
3913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		ret = 1;
3933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		for (i = 0; i < PARSE_MAX_VP; i++) {
3943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			vp = &posval[i];
395c9cc4a7b1dd605daff0dd2e0b0e1c42f178871ddcristy			if (!vp->ival || vp->ival[0] == '\0')
396c9cc4a7b1dd605daff0dd2e0b0e1c42f178871ddcristy				continue;
397c9cc4a7b1dd605daff0dd2e0b0e1c42f178871ddcristy			all_skipped = 0;
398c9cc4a7b1dd605daff0dd2e0b0e1c42f178871ddcristy			if (!strncmp(vp->ival, ptr, str_match_len(vp, ptr))) {
399c9cc4a7b1dd605daff0dd2e0b0e1c42f178871ddcristy				ret = 0;
400c9cc4a7b1dd605daff0dd2e0b0e1c42f178871ddcristy				if (o->roff1) {
4013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					if (vp->or)
4023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy						*(unsigned int *) o->roff1 |= vp->oval;
4033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					else
4043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy						*(unsigned int *) o->roff1 = vp->oval;
4053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				} else {
4063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					if (!o->off1)
4073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy						continue;
4083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					val_store(ilp, vp->oval, o->off1, vp->or, data);
4093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				}
4103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				continue;
4113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			}
4123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		}
4133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		if (ret && !all_skipped)
4153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			show_option_values(o);
4163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		else if (fn)
4173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			ret = fn(data, ptr);
4183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		break;
4193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	}
4203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	case FIO_OPT_STR_VAL_TIME:
4213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		is_time = 1;
4223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	case FIO_OPT_INT:
4233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	case FIO_OPT_STR_VAL: {
4243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		fio_opt_str_val_fn *fn = o->cb;
4253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		char tmp[128], *p;
4263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		strncpy(tmp, ptr, sizeof(tmp) - 1);
4283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		p = strchr(tmp, ',');
4293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		if (p)
4303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			*p = '\0';
4313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		if (is_time)
4333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			ret = check_str_time(tmp, &ull);
4343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		else
4353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			ret = check_str_bytes(tmp, &ull, data);
4363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		if (ret)
4383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			break;
4393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		if (o->maxval && ull > o->maxval) {
4413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			log_err("max value out of range: %llu"
4423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					" (%u max)\n", ull, o->maxval);
4433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			return 1;
4443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		}
4453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		if (o->minval && ull < o->minval) {
4463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			log_err("min value out of range: %llu"
4473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					" (%u min)\n", ull, o->minval);
4487c3af951210f34d3f244b31f06ee291e5be8ecb7cristy			return 1;
4497c3af951210f34d3f244b31f06ee291e5be8ecb7cristy		}
4503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		if (fn)
4523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			ret = fn(data, &ull);
4533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		else {
4543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			if (o->type == FIO_OPT_INT) {
4553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				if (first) {
4563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					if (o->roff1)
4573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy						*(unsigned int *) o->roff1 = ull;
4583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					else
4593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy						val_store(ilp, ull, o->off1, 0, data);
4603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				}
4613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				if (curr == 1) {
4627c3af951210f34d3f244b31f06ee291e5be8ecb7cristy					if (o->roff2)
4637c3af951210f34d3f244b31f06ee291e5be8ecb7cristy						*(unsigned int *) o->roff2 = ull;
4643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					else if (o->off2)
465bcbda3fd7d9f3084869f5cebabceb0324c3b2cd7cristy						val_store(ilp, ull, o->off2, 0, data);
4667c3af951210f34d3f244b31f06ee291e5be8ecb7cristy				}
4677c3af951210f34d3f244b31f06ee291e5be8ecb7cristy				if (curr == 2) {
4683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					if (o->roff3)
469c57f694b2d04975a0e501613e34368c464708c19cristy						*(unsigned int *) o->roff3 = ull;
470c57f694b2d04975a0e501613e34368c464708c19cristy					else if (o->off3)
471c57f694b2d04975a0e501613e34368c464708c19cristy						val_store(ilp, ull, o->off3, 0, data);
4723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				}
4733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				if (!more) {
4743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					if (curr < 1) {
4753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy						if (o->roff2)
4763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy							*(unsigned int *) o->roff2 = ull;
4773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy						else if (o->off2)
4783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy							val_store(ilp, ull, o->off2, 0, data);
4793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					}
4803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					if (curr < 2) {
4813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy						if (o->roff3)
482b0a657e13c4aefba39c51292005427b47277869dcristy							*(unsigned int *) o->roff3 = ull;
483b0a657e13c4aefba39c51292005427b47277869dcristy						else if (o->off3)
4843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy							val_store(ilp, ull, o->off3, 0, data);
4853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					}
4863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				}
4873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			} else {
4883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				if (first) {
4893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					if (o->roff1)
4903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy						*(unsigned long long *) o->roff1 = ull;
4913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					else
4923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy						val_store(ullp, ull, o->off1, 0, data);
4933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				}
4943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				if (!more) {
4953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					if (o->roff2)
4963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy						*(unsigned long long *) o->roff2 =  ull;
4973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					else if (o->off2)
4983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy						val_store(ullp, ull, o->off2, 0, data);
4993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				}
5003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			}
5013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		}
5023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		break;
5033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	}
5043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	case FIO_OPT_FLOAT_LIST: {
5053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		char *cp2;
5063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		if (first) {
5083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			/*
5093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			** Initialize precision to 0 and zero out list
5103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			** in case specified list is shorter than default
5113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			*/
5123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			ul2 = 0;
5133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			ilp = td_var(data, o->off2);
5143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			*ilp = ul2;
5153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			flp = td_var(data, o->off1);
5173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			for(i = 0; i < o->maxlen; i++)
5183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				flp[i].u.f = 0.0;
5193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		}
5203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		if (curr >= o->maxlen) {
5213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			log_err("the list exceeding max length %d\n",
5223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					o->maxlen);
523bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy			return 1;
5243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		}
525c57f694b2d04975a0e501613e34368c464708c19cristy		if (!str_to_float(ptr, &uf)) {
526c57f694b2d04975a0e501613e34368c464708c19cristy			log_err("not a floating point value: %s\n", ptr);
5273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			return 1;
5283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		}
5293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		if (uf > o->maxfp) {
5303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			log_err("value out of range: %f"
5313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				" (range max: %f)\n", uf, o->maxfp);
5323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			return 1;
5333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		}
5343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		if (uf < o->minfp) {
5353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			log_err("value out of range: %f"
5363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				" (range min: %f)\n", uf, o->minfp);
5373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			return 1;
5383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		}
5393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		flp = td_var(data, o->off1);
5413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		flp[curr].u.f = uf;
5423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		/*
5443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		** Calculate precision for output by counting
5453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		** number of digits after period. Find first
5463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		** period in entire remaining list each time
5476710d8414f0ed06e4eaf9346366be72e2b4719efcristy		*/
5483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		cp2 = strchr(ptr, '.');
5493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		if (cp2 != NULL) {
5503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			int len = 0;
5513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			while (*++cp2 != '\0' && *cp2 >= '0' && *cp2 <= '9')
5533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				len++;
5543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			ilp = td_var(data, o->off2);
5563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			if (len > *ilp)
5573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				*ilp = len;
5583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		}
5593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
560f05d4947caf1bc27fbec041eb37c474a80c83c0bcristy		break;
561f05d4947caf1bc27fbec041eb37c474a80c83c0bcristy	}
5623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	case FIO_OPT_STR_STORE: {
5638a46d827a124555f0c48fb2368ec1bba8e079ab6cristy		fio_opt_str_fn *fn = o->cb;
5646f5395df39e037392db46729f9aab05f2a9a428fcristy
5653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		if (o->roff1 || o->off1) {
5663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			if (o->roff1)
567c57f694b2d04975a0e501613e34368c464708c19cristy				cp = (char **) o->roff1;
5683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			else if (o->off1)
5693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				cp = td_var(data, o->off1);
5704c08aed51c5899665ade97263692328eea4af106cristy
571c47d1f8ecfe7d04f0f003cca0fe175658bbf0fb2cristy			*cp = strdup(ptr);
5723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		}
573c57f694b2d04975a0e501613e34368c464708c19cristy
574c57f694b2d04975a0e501613e34368c464708c19cristy		if (fn)
575acd2ed254c18c254a0ab5aafa06d1645e5d079d8cristy			ret = fn(data, ptr);
5763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		else if (o->posval[0].ival) {
577c57f694b2d04975a0e501613e34368c464708c19cristy			posval_sort(o, posval);
5783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5794c08aed51c5899665ade97263692328eea4af106cristy			ret = 1;
5803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			for (i = 0; i < PARSE_MAX_VP; i++) {
5813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				vp = &posval[i];
5823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				if (!vp->ival || vp->ival[0] == '\0')
5833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					continue;
5843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				all_skipped = 0;
5854c08aed51c5899665ade97263692328eea4af106cristy				if (!strncmp(vp->ival, ptr, str_match_len(vp, ptr))) {
5864c08aed51c5899665ade97263692328eea4af106cristy					char *rest;
5874c08aed51c5899665ade97263692328eea4af106cristy
5884c08aed51c5899665ade97263692328eea4af106cristy					ret = 0;
5894c08aed51c5899665ade97263692328eea4af106cristy					if (vp->cb)
5904c08aed51c5899665ade97263692328eea4af106cristy						fn = vp->cb;
5913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					rest = strstr(*cp ?: ptr, ":");
5923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					if (rest) {
5934c08aed51c5899665ade97263692328eea4af106cristy						if (*cp)
5943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy							*rest = '\0';
5953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy						ptr = rest + 1;
5963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					} else
5973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy						ptr = NULL;
5983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					break;
5993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				}
6004c08aed51c5899665ade97263692328eea4af106cristy			}
6014c08aed51c5899665ade97263692328eea4af106cristy		}
6024c08aed51c5899665ade97263692328eea4af106cristy
6034c08aed51c5899665ade97263692328eea4af106cristy		if (!all_skipped) {
6044c08aed51c5899665ade97263692328eea4af106cristy			if (ret && !*cp)
6054c08aed51c5899665ade97263692328eea4af106cristy				show_option_values(o);
6063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			else if (ret && *cp)
6074c08aed51c5899665ade97263692328eea4af106cristy				ret = 0;
6083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			else if (fn && ptr)
609ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy				ret = fn(data, ptr);
6103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		}
611c57f694b2d04975a0e501613e34368c464708c19cristy
6123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		break;
6133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	}
614c57f694b2d04975a0e501613e34368c464708c19cristy	case FIO_OPT_RANGE: {
6153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		char tmp[128];
6163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		char *p1, *p2;
6173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		strncpy(tmp, ptr, sizeof(tmp) - 1);
6193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		/* Handle bsrange with separate read,write values: */
6213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		p1 = strchr(tmp, ',');
6223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		if (p1)
6233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			*p1 = '\0';
6243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		p1 = strchr(tmp, '-');
6263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		if (!p1) {
6273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			p1 = strchr(tmp, ':');
6283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			if (!p1) {
629b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy				ret = 1;
6303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				break;
631e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy			}
632e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy		}
6333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		p2 = p1 + 1;
6353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		*p1 = '\0';
6363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		p1 = tmp;
6373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		ret = 1;
6393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		if (!check_range_bytes(p1, &ul1, data) &&
6403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		    !check_range_bytes(p2, &ul2, data)) {
6413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			ret = 0;
642a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy			if (ul1 > ul2) {
6433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				unsigned long foo = ul1;
6443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				ul1 = ul2;
6463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				ul2 = foo;
6473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			}
6486710d8414f0ed06e4eaf9346366be72e2b4719efcristy
6493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			if (first) {
6503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				if (o->roff1)
6513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					*(unsigned int *) o->roff1 = ul1;
6523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				else
6533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					val_store(ilp, ul1, o->off1, 0, data);
6543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				if (o->roff2)
6553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					*(unsigned int *) o->roff2 = ul2;
6563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				else
6573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					val_store(ilp, ul2, o->off2, 0, data);
6583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			}
6593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			if (curr == 1) {
6603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				if (o->roff3 && o->roff4) {
6613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					*(unsigned int *) o->roff3 = ul1;
6623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					*(unsigned int *) o->roff4 = ul2;
6633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				} else if (o->off3 && o->off4) {
6643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					val_store(ilp, ul1, o->off3, 0, data);
6653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					val_store(ilp, ul2, o->off4, 0, data);
6663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				}
6673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			}
6683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			if (curr == 2) {
6693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				if (o->roff5 && o->roff6) {
6703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					*(unsigned int *) o->roff5 = ul1;
6713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					*(unsigned int *) o->roff6 = ul2;
6723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				} else if (o->off5 && o->off6) {
6733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					val_store(ilp, ul1, o->off5, 0, data);
6743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					val_store(ilp, ul2, o->off6, 0, data);
6753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				}
6763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			}
6773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			if (!more) {
6783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				if (curr < 1) {
6793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					if (o->roff3 && o->roff4) {
6803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy						*(unsigned int *) o->roff3 = ul1;
6813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy						*(unsigned int *) o->roff4 = ul2;
6823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					} else if (o->off3 && o->off4) {
6833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy						val_store(ilp, ul1, o->off3, 0, data);
6843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy						val_store(ilp, ul2, o->off4, 0, data);
6853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					}
6863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				}
6873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				if (curr < 2) {
6883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					if (o->roff5 && o->roff6) {
6893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy						*(unsigned int *) o->roff5 = ul1;
6903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy						*(unsigned int *) o->roff6 = ul2;
6913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					} else if (o->off5 && o->off6) {
6923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy						val_store(ilp, ul1, o->off5, 0, data);
6933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy						val_store(ilp, ul2, o->off6, 0, data);
6943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					}
6953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				}
6963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			}
6973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		}
698b0a657e13c4aefba39c51292005427b47277869dcristy
699feb3e9695150978a5d2372d3fe2f60466a7c8066cristy		break;
700b0a657e13c4aefba39c51292005427b47277869dcristy	}
701b0a657e13c4aefba39c51292005427b47277869dcristy	case FIO_OPT_BOOL:
702b0a657e13c4aefba39c51292005427b47277869dcristy	case FIO_OPT_STR_SET: {
7033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		fio_opt_int_fn *fn = o->cb;
7043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		if (ptr)
7063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			ret = check_int(ptr, &il);
7073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		else if (o->type == FIO_OPT_BOOL)
7083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			ret = 1;
7093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		else
7103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			il = 1;
7113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		if (ret)
7133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			break;
7143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		if (o->maxval && il > (int) o->maxval) {
7163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			log_err("max value out of range: %d (%d max)\n",
7173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy								il, o->maxval);
7183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			return 1;
7193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		}
7203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		if (o->minval && il < o->minval) {
7213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			log_err("min value out of range: %d (%d min)\n",
7223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy								il, o->minval);
7233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			return 1;
7243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		}
7253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		if (o->neg)
7273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			il = !il;
7283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		if (fn)
7303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			ret = fn(data, &il);
7313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		else {
7323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			if (first) {
7333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				if (o->roff1)
7343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					*(unsigned int *)o->roff1 = il;
7353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				else
7363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					val_store(ilp, il, o->off1, 0, data);
7373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			}
7383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			if (!more) {
7393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				if (o->roff2)
7403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					*(unsigned int *) o->roff2 = il;
7413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				else if (o->off2)
7423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					val_store(ilp, il, o->off2, 0, data);
7433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			}
7443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		}
7453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		break;
7463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	}
7473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	case FIO_OPT_DEPRECATED:
7483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		log_info("Option %s is deprecated\n", o->name);
7493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		break;
7503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	default:
7513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		log_err("Bad option type %u\n", o->type);
7523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		ret = 1;
7533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	}
7543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	if (ret)
7563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		return ret;
7573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	if (o->verify) {
7593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		ret = o->verify(o, data);
7603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		if (ret) {
7613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			log_err("Correct format for offending option\n");
7623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			log_err("%20s: %s\n", o->name, o->help);
7633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			show_option_help(o, 1);
7643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		}
7653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	}
7663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	return ret;
7683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
7693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7703ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int handle_option(struct fio_option *o, const char *__ptr, void *data)
7713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
7723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	char *o_ptr, *ptr, *ptr2;
7733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	int ret, done;
7743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	dprint(FD_PARSE, "handle_option=%s, ptr=%s\n", o->name, __ptr);
7763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	o_ptr = ptr = NULL;
7783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	if (__ptr)
7793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		o_ptr = ptr = strdup(__ptr);
7803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	/*
7823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	 * See if we have another set of parameters, hidden after a comma.
7833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	 * Do this before parsing this round, to check if we should
7843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	 * copy set 1 options to set 2.
7853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	 */
7863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	done = 0;
7873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	ret = 1;
7883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	do {
7893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		int __ret;
7903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		ptr2 = NULL;
792bcbda3fd7d9f3084869f5cebabceb0324c3b2cd7cristy		if (ptr &&
7933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		    (o->type != FIO_OPT_STR_STORE) &&
7943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		    (o->type != FIO_OPT_STR) &&
7953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		    (o->type != FIO_OPT_FLOAT_LIST)) {
7963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			ptr2 = strchr(ptr, ',');
7973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			if (ptr2 && *(ptr2 + 1) == '\0')
7983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				*ptr2 = '\0';
7993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			if (o->type != FIO_OPT_STR_MULTI && o->type != FIO_OPT_RANGE) {
8003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				if (!ptr2)
8013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					ptr2 = strchr(ptr, ':');
8023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				if (!ptr2)
8033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					ptr2 = strchr(ptr, '-');
8043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			}
8053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		} else if (ptr && o->type == FIO_OPT_FLOAT_LIST) {
8063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			ptr2 = strchr(ptr, ':');
8073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		}
8083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		/*
8103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		 * Don't return early if parsing the first option fails - if
8113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		 * we are doing multiple arguments, we can allow the first one
8123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		 * being empty.
8133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		 */
8143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		__ret = __handle_option(o, ptr, data, !done, !!ptr2, done);
8153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		if (ret)
8163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			ret = __ret;
8173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		if (!ptr2)
8193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			break;
8203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		ptr = ptr2 + 1;
8223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		done++;
8233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	} while (1);
8243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	if (o_ptr)
8263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		free(o_ptr);
8273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	return ret;
8283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8303ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic struct fio_option *get_option(char *opt,
8313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				     struct fio_option *options, char **post)
8323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
8333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	struct fio_option *o;
8343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	char *ret;
8353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	ret = strchr(opt, '=');
8373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	if (ret) {
8383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		*post = ret;
8393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		*ret = '\0';
8403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		ret = opt;
8413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		(*post)++;
8423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		strip_blank_end(ret);
8433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		o = find_option(options, ret);
8443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	} else {
8453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		o = find_option(options, opt);
8463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		*post = NULL;
8473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	}
8483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	return o;
8503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8523ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int opt_cmp(const void *p1, const void *p2)
8533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
8543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	struct fio_option *o;
8553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	char *s, *foo;
8563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	int prio1, prio2;
8573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	prio1 = prio2 = 0;
8593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	if (*(char **)p1) {
8613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		s = strdup(*((char **) p1));
8623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		o = get_option(s, fio_options, &foo);
8633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		if (o)
8643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			prio1 = o->prio;
8653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		free(s);
8663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	}
8673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	if (*(char **)p2) {
8683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		s = strdup(*((char **) p2));
8693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		o = get_option(s, fio_options, &foo);
8703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		if (o)
8713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			prio2 = o->prio;
8723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		free(s);
8733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	}
8743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	return prio2 - prio1;
8763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8783ed852eea50f9d4cd633efb8c2b054b8e33c253cristyvoid sort_options(char **opts, struct fio_option *options, int num_opts)
8793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
8803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	fio_options = options;
8813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	qsort(opts, num_opts, sizeof(char *), opt_cmp);
8823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	fio_options = NULL;
8833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8853ed852eea50f9d4cd633efb8c2b054b8e33c253cristyint parse_cmd_option(const char *opt, const char *val,
8863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		     struct fio_option *options, void *data)
8873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
8883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	struct fio_option *o;
8893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	o = find_option(options, opt);
8913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	if (!o) {
8923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		log_err("Bad option <%s>\n", opt);
8933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		return 1;
8943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	}
8953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	if (!handle_option(o, val, data))
8973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		return 0;
8983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	log_err("fio: failed parsing %s=%s\n", opt, val);
900bcbda3fd7d9f3084869f5cebabceb0324c3b2cd7cristy	return 1;
9013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9033ed852eea50f9d4cd633efb8c2b054b8e33c253cristyint parse_option(char *opt, const char *input,
9043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		 struct fio_option *options, struct fio_option **o, void *data)
9053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	char *post;
907a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy
9083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	if (!opt) {
9093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		log_err("fio: failed parsing %s\n", input);
9103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		*o = NULL;
9113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		return 1;
9123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	}
9133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	*o = get_option(opt, options, &post);
9153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	if (!*o) {
9163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		if (post) {
9173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			int len = strlen(opt);
9183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			if (opt + len + 1 != post)
9193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				memmove(opt + len + 1, post, strlen(post));
9203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			opt[len] = '=';
9213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		}
9223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		return 1;
9233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	}
9243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	if (!handle_option(*o, post, data)) {
9263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		return 0;
9273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	}
9283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	log_err("fio: failed parsing %s\n", input);
9303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	return 1;
9313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
9343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * Option match, levenshtein distance. Handy for not quite remembering what
9353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * the option name is.
9363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */
9373ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int string_distance(const char *s1, const char *s2)
9383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	unsigned int s1_len = strlen(s1);
9403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	unsigned int s2_len = strlen(s2);
9413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	unsigned int *p, *q, *r;
9423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	unsigned int i, j;
9433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	p = malloc(sizeof(unsigned int) * (s2_len + 1));
9453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	q = malloc(sizeof(unsigned int) * (s2_len + 1));
9463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	p[0] = 0;
9483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	for (i = 1; i <= s2_len; i++)
9493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		p[i] = p[i - 1] + 1;
9503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	for (i = 1; i <= s1_len; i++) {
9523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		q[0] = p[0] + 1;
9533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		for (j = 1; j <= s2_len; j++) {
9543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			unsigned int sub = p[j - 1];
9553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			if (s1[i - 1] != s2[j - 1])
9573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				sub++;
9583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			q[j] = min(p[j] + 1, min(q[j - 1] + 1, sub));
9603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		}
9613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		r = p;
9623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		p = q;
9633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		q = r;
9643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	}
9653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	i = p[s2_len];
9673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	free(p);
968a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy	free(q);
969a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy	return i;
970a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy}
9713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9723ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic struct fio_option *find_child(struct fio_option *options,
9733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				     struct fio_option *o)
9743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	struct fio_option *__o;
9763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	for (__o = options + 1; __o->name; __o++)
9783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		if (__o->parent && !strcmp(__o->parent, o->name))
9793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			return __o;
9803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	return NULL;
9823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9843ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void __print_option(struct fio_option *o, struct fio_option *org,
9853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			   int level)
9863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	char name[256], *p;
9883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	int depth;
9893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	if (!o)
9913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		return;
9923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	if (!org)
9933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		org = o;
9943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	p = name;
9963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	depth = level;
9973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	while (depth--)
9983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		p += sprintf(p, "%s", "  ");
9993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	sprintf(p, "%s", o->name);
10013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	log_info("%-24s: %s\n", name, o->help);
10033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10053ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void print_option(struct fio_option *o)
10063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	struct fio_option *parent;
10083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	struct fio_option *__o;
10093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	unsigned int printed;
10103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	unsigned int level;
10113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	__print_option(o, NULL, 0);
10133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	parent = o;
10143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	level = 0;
10153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	do {
10163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		level++;
10173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		printed = 0;
10183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		while ((__o = find_child(o, parent)) != NULL) {
10203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			__print_option(__o, o, level);
10213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			o = __o;
10223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			printed++;
10233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		}
10243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		parent = o;
10263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	} while (printed);
10273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1028bcbda3fd7d9f3084869f5cebabceb0324c3b2cd7cristy
10293ed852eea50f9d4cd633efb8c2b054b8e33c253cristyint show_cmd_help(struct fio_option *options, const char *name)
10303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	struct fio_option *o, *closest;
10323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	unsigned int best_dist = -1U;
10333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	int found = 0;
10344c08aed51c5899665ade97263692328eea4af106cristy	int show_all = 0;
10353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	if (!name || !strcmp(name, "all"))
1037a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy		show_all = 1;
10383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	closest = NULL;
1040a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy	best_dist = -1;
10413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	for (o = &options[0]; o->name; o++) {
10423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		int match = 0;
10433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		if (o->type == FIO_OPT_DEPRECATED)
10453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			continue;
10463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		if (!exec_profile && o->prof_name)
10473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			continue;
10483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		if (name) {
10503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			if (!strcmp(name, o->name) ||
10513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			    (o->alias && !strcmp(name, o->alias)))
10523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				match = 1;
10533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			else {
10543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				unsigned int dist;
10553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				dist = string_distance(name, o->name);
10573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				if (dist < best_dist) {
10583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					best_dist = dist;
10593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					closest = o;
10603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				}
10613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			}
10623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		}
10633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		if (show_all || match) {
10653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			found = 1;
10663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			if (match)
10673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				log_info("%20s: %s\n", o->name, o->help);
10683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			if (show_all) {
10693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				if (!o->parent)
10703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy					print_option(o);
10713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				continue;
10723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			}
1073bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy		}
10743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		if (!match)
10763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			continue;
10773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1078a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy		show_option_help(o, 0);
10793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	}
10803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	if (found)
10823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		return 0;
1083a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy
10843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	log_err("No such command: %s", name);
10853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	/*
1087a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy	 * Only print an appropriately close option, one where the edit
10883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	 * distance isn't too big. Otherwise we get crazy matches.
10893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	 */
10903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	if (closest && best_dist < 3) {
1091a19f1d70e9a9f88279c4ecafe6dfafc1f9a09599cristy		log_info(" - showing closest match\n");
10923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		log_info("%20s: %s\n", closest->name, closest->help);
10933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		show_option_help(closest, 0);
10943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	} else
10953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		log_info("\n");
10963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	return 1;
10983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
11013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * Handle parsing of default parameters.
11023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */
11033ed852eea50f9d4cd633efb8c2b054b8e33c253cristyvoid fill_default_options(void *data, struct fio_option *options)
11043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	struct fio_option *o;
11063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	dprint(FD_PARSE, "filling default options\n");
11083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	for (o = &options[0]; o->name; o++)
11103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		if (o->def)
11113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			handle_option(o, o->def, data);
11123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11143ed852eea50f9d4cd633efb8c2b054b8e33c253cristyvoid option_init(struct fio_option *o)
11153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	if (o->type == FIO_OPT_DEPRECATED)
11173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		return;
11183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	if (o->type == FIO_OPT_BOOL) {
11193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		o->minval = 0;
11203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		o->maxval = 1;
11213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	}
11223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	if (o->type == FIO_OPT_INT) {
11233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		if (!o->maxval)
11243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			o->maxval = UINT_MAX;
11253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	}
11263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	if (o->type == FIO_OPT_FLOAT_LIST) {
11273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		o->minfp = DBL_MIN;
11283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		o->maxfp = DBL_MAX;
11293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	}
11303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	if (o->type == FIO_OPT_STR_SET && o->def) {
11313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		log_err("Option %s: string set option with"
11323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy				" default will always be true\n", o->name);
11333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	}
11343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	if (!o->cb && (!o->off1 && !o->roff1))
11353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		log_err("Option %s: neither cb nor offset given\n", o->name);
11363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	if (o->type == FIO_OPT_STR || o->type == FIO_OPT_STR_STORE ||
11373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	    o->type == FIO_OPT_STR_MULTI)
11383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		return;
11393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	if (o->cb && ((o->off1 || o->off2 || o->off3 || o->off4) ||
11403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		      (o->roff1 || o->roff2 || o->roff3 || o->roff4))) {
11413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		log_err("Option %s: both cb and offset given\n", o->name);
11423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	}
11433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
11463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * Sanitize the options structure. For now it just sets min/max for bool
11473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * values and whether both callback and offsets are given.
11483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */
11493ed852eea50f9d4cd633efb8c2b054b8e33c253cristyvoid options_init(struct fio_option *options)
11503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	struct fio_option *o;
11523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	dprint(FD_PARSE, "init options\n");
11543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	for (o = &options[0]; o->name; o++)
11563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		option_init(o);
1157bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy}
11583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11593ed852eea50f9d4cd633efb8c2b054b8e33c253cristyvoid options_free(struct fio_option *options, void *data)
11603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	struct fio_option *o;
11623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	char **ptr;
11633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	dprint(FD_PARSE, "free options\n");
1165bcbda3fd7d9f3084869f5cebabceb0324c3b2cd7cristy
11663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	for (o = &options[0]; o->name; o++) {
11673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		if (o->type != FIO_OPT_STR_STORE || !o->off1)
11683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			continue;
11693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		ptr = td_var(data, o->off1);
11713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		if (*ptr) {
11723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			free(*ptr);
11733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy			*ptr = NULL;
11743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy		}
11753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy	}
11763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy