parse.c revision 4ac23d27a5e5dea73c4db4a4fcc46a6afe645bd0
1afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg/*
2be1b8e5d6c6692010a3ec117035d9b218929e2b3Brian * This file contains the ini and command liner parser main.
325be043940b25a5fe6eb8058070b3e8f12e92039Brian Paul */
45e3bc0c2a2bcdf59949410f94c9b705fc1281ce8Jouk Jansen#include <stdio.h>
59f6022d0567dc1288888212d7128acc48795b306Brian#include <stdlib.h>
680684649a6d01f0e0517b14f61cbcad6fa101929Brian Paul#include <unistd.h>
75e3bc0c2a2bcdf59949410f94c9b705fc1281ce8Jouk Jansen#include <ctype.h>
8afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#include <string.h>
9afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#include <errno.h>
10afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#include <limits.h>
11afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#include <stdlib.h>
12afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#include <math.h>
13afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#include <float.h>
145e3bc0c2a2bcdf59949410f94c9b705fc1281ce8Jouk Jansen
15afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#include "parse.h"
16afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#include "debug.h"
175e3bc0c2a2bcdf59949410f94c9b705fc1281ce8Jouk Jansen#include "options.h"
18afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#include "minmax.h"
19afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#include "lib/ieee754.h"
20afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
21afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtgstatic struct fio_option *__fio_options;
22afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
23afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtgstatic int vp_cmp(const void *p1, const void *p2)
24afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
25afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	const struct value_pair *vp1 = p1;
266dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell	const struct value_pair *vp2 = p2;
27add9f2168a5d6b15eb9955ee761246c4f4cf8458Brian Paul
28add9f2168a5d6b15eb9955ee761246c4f4cf8458Brian Paul	return strlen(vp2->ival) - strlen(vp1->ival);
2977ee31930a1b0cc7766939415f4f04ed6a1fa4acBrian Paul}
30add9f2168a5d6b15eb9955ee761246c4f4cf8458Brian Paul
31add9f2168a5d6b15eb9955ee761246c4f4cf8458Brian Paulstatic void posval_sort(struct fio_option *o, struct value_pair *vpmap)
32add9f2168a5d6b15eb9955ee761246c4f4cf8458Brian Paul{
33fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul	const struct value_pair *vp;
34b46712ca9d379d9c091f5543500088d82cf9776cBrian Paul	int entries;
35afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
36d100cbf721010f4eacc87507cc87c5314150d493Maciej Cencora	memset(vpmap, 0, PARSE_MAX_VP * sizeof(struct value_pair));
3734bd1233a9874fe12a822c4fcb926d48456e1f29Brian Paul
3834bd1233a9874fe12a822c4fcb926d48456e1f29Brian Paul	for (entries = 0; entries < PARSE_MAX_VP; entries++) {
392897cee99fb877e1f3cd9a881a61418c9c31867fBrian Paul		vp = &o->posval[entries];
40afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg		if (!vp->ival || vp->ival[0] == '\0')
413c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul			break;
42ebb248aa5c018dc676d389221d76ed329059789eBrian Paul
43fa4525e289b475b928a7b2c4055af9dd7fe46600Brian Paul		memcpy(&vpmap[entries], vp, sizeof(*vp));
4489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul	}
451a2bb37264b4448d33f2948fe1702c9dc936395dBrian Paul
46afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	qsort(vpmap, entries, sizeof(struct value_pair), vp_cmp);
47afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg}
487179a822628963d8cfa0817cf072c5acb70638a7Kristian Høgsberg
495e3bc0c2a2bcdf59949410f94c9b705fc1281ce8Jouk Jansenstatic void show_option_range(struct fio_option *o,
50afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg				int (*logger)(const char *format, ...))
51afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
524cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul	if (o->type == FIO_OPT_FLOAT_LIST) {
5363f01309801c5a900d8d7f5ccd63413e33ff9bffBrian Paul		if (o->minfp == DBL_MIN && o->maxfp == DBL_MAX)
5463f01309801c5a900d8d7f5ccd63413e33ff9bffBrian Paul			return;
5563f01309801c5a900d8d7f5ccd63413e33ff9bffBrian Paul
5663f01309801c5a900d8d7f5ccd63413e33ff9bffBrian Paul		logger("%20s: min=%f", "range", o->minfp);
5763f01309801c5a900d8d7f5ccd63413e33ff9bffBrian Paul		if (o->maxfp != DBL_MAX)
5863f01309801c5a900d8d7f5ccd63413e33ff9bffBrian Paul			logger(", max=%f", o->maxfp);
5963f01309801c5a900d8d7f5ccd63413e33ff9bffBrian Paul		logger("\n");
6063f01309801c5a900d8d7f5ccd63413e33ff9bffBrian Paul	} else if (!o->posval[0].ival) {
6163f01309801c5a900d8d7f5ccd63413e33ff9bffBrian Paul		if (!o->minval && !o->maxval)
6263f01309801c5a900d8d7f5ccd63413e33ff9bffBrian Paul			return;
6363f01309801c5a900d8d7f5ccd63413e33ff9bffBrian Paul
644cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul		logger("%20s: min=%d", "range", o->minval);
654cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul		if (o->maxval)
664cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul			logger(", max=%d", o->maxval);
674cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul		logger("\n");
684cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul	}
694cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul}
704cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul
714cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paulstatic void show_option_values(struct fio_option *o)
724cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul{
734cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul	int i;
744cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul
754cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul	for (i = 0; i < PARSE_MAX_VP; i++) {
764cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul		const struct value_pair *vp = &o->posval[i];
774cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul
784cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul		if (!vp->ival)
794cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul			continue;
804cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul
814cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul		log_info("%20s: %-10s", i == 0 ? "valid values" : "", vp->ival);
824cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul		if (vp->help)
834cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul			log_info(" %s", vp->help);
84f7b5707d66678f09bec652ecce024a0da6cc4a4bBrian Paul		log_info("\n");
85887e2cf01a99f7fe1b7c94320b7bdbbf0d6ad2f8Brian Paul	}
86973da83f6237b5af4a9ee77f32fdfa5c04ecabc8Brian Paul
87afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	if (i)
88fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul		log_info("\n");
89fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul}
90afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
91afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtgstatic void show_option_help(struct fio_option *o, int is_err)
92afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
93afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	const char *typehelp[] = {
94973da83f6237b5af4a9ee77f32fdfa5c04ecabc8Brian Paul		"invalid",
95afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg		"string (opt=bla)",
96973da83f6237b5af4a9ee77f32fdfa5c04ecabc8Brian Paul		"string (opt=bla)",
97973da83f6237b5af4a9ee77f32fdfa5c04ecabc8Brian Paul		"string with possible k/m/g postfix (opt=4k)",
98973da83f6237b5af4a9ee77f32fdfa5c04ecabc8Brian Paul		"string with time postfix (opt=10s)",
99afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg		"string (opt=bla)",
100afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg		"string with dual range (opt=1k-4k,4k-8k)",
101afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg		"integer value (opt=100)",
102afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg		"boolean value (opt=1)",
103afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg		"list of floating point values separated by ':' (opt=5.9:7.8)",
104afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg		"no argument (opt)",
105887e2cf01a99f7fe1b7c94320b7bdbbf0d6ad2f8Brian Paul		"deprecated",
106afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	};
107afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	int (*logger)(const char *format, ...);
108afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
109afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	if (is_err)
110afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg		logger = log_err;
111afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	else
112afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg		logger = log_info;
113afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
1146dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell	if (o->alias)
1151749a25ca889d514889b34cf6311c8014d97bf66Brian Paul		logger("%20s: %s\n", "alias", o->alias);
1161749a25ca889d514889b34cf6311c8014d97bf66Brian Paul
1176dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell	logger("%20s: %s\n", "type", typehelp[o->type]);
1186dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell	logger("%20s: %s\n", "default", o->def ? o->def : "no default");
1191749a25ca889d514889b34cf6311c8014d97bf66Brian Paul	if (o->prof_name)
1206dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell		logger("%20s: only for profile '%s'\n", "valid", o->prof_name);
1216dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell	show_option_range(o, logger);
1226dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell	show_option_values(o);
12389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul}
12489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
12589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paulstatic unsigned long get_mult_time(char c)
12673b150c816c46a88e3e5d97f9b73ab0095f2bc60Brian Paul{
12773b150c816c46a88e3e5d97f9b73ab0095f2bc60Brian Paul	switch (c) {
128afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	case 'm':
129b132e8da5e5f2b7da1f2141e0322e66bb0608e02Brian Paul	case 'M':
130f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg		return 60;
131afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	case 'h':
1321749a25ca889d514889b34cf6311c8014d97bf66Brian Paul	case 'H':
133afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg		return 60 * 60;
134afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	case 'd':
135afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	case 'D':
136afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg		return 24 * 60 * 60;
137afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	default:
138afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg		return 1;
139afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	}
140afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg}
141afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
142afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtgstatic int is_separator(char c)
143afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
144afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	switch (c) {
145afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	case ':':
146afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	case '-':
147afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	case ',':
148afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	case '/':
149afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg		return 1;
150afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	default:
151afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg		return 0;
152afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	}
153afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg}
154afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
155afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtgstatic unsigned long long __get_mult_bytes(const char *p, void *data,
156afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg					   int *percent)
157afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
158afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	unsigned int kb_base = fio_get_kb_base(data);
159afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	unsigned long long ret = 1;
160afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	unsigned int i, pow = 0, mult = kb_base;
161afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	char *c;
162afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
163afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	if (!p)
164afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg		return 1;
165afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
166afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	c = strdup(p);
167afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
168afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	for (i = 0; i < strlen(c); i++) {
169afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg		c[i] = tolower(c[i]);
170afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg		if (is_separator(c[i])) {
171afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg			c[i] = '\0';
172afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg			break;
173afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg		}
174afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	}
175afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
176afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	if (!strncmp("pib", c, 3)) {
177afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg		pow = 5;
178afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg		mult = 1000;
179afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	} else if (!strncmp("tib", c, 3)) {
180afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg		pow = 4;
181f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul		mult = 1000;
182f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul	} else if (!strncmp("gib", c, 3)) {
183f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul		pow = 3;
184f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul		mult = 1000;
185f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul	} else if (!strncmp("mib", c, 3)) {
186f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul		pow = 2;
187f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul		mult = 1000;
188f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul	} else if (!strncmp("kib", c, 3)) {
189f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul		pow = 1;
190f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul		mult = 1000;
191f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul	} else if (!strncmp("p", c, 1) || !strncmp("pb", c, 2))
192f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul		pow = 5;
193f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul	else if (!strncmp("t", c, 1) || !strncmp("tb", c, 2))
194e71654961868eac559210ced359c1af114138d8aBrian Paul		pow = 4;
195f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul	else if (!strncmp("g", c, 1) || !strncmp("gb", c, 2))
196f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul		pow = 3;
197f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul	else if (!strncmp("m", c, 1) || !strncmp("mb", c, 2))
198f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul		pow = 2;
199f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul	else if (!strncmp("k", c, 1) || !strncmp("kb", c, 2))
2004741dbcbbc2514de370a760f4b78a17491014555Ian Romanick		pow = 1;
201f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul	else if (!strncmp("%", c, 1)) {
202f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul		*percent = 1;
2034741dbcbbc2514de370a760f4b78a17491014555Ian Romanick		free(c);
2044741dbcbbc2514de370a760f4b78a17491014555Ian Romanick		return ret;
2054741dbcbbc2514de370a760f4b78a17491014555Ian Romanick	}
206f7e1dfeaefda8865252513bc4d880ea8640efe4dBrian Paul
207f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul	while (pow--)
208f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul		ret *= (unsigned long long) mult;
209f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
210f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul	free(c);
21189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul	return ret;
21233fa5e4bfad8005f09ad3c9fc92c40fa863935d1Ian Romanick}
21333fa5e4bfad8005f09ad3c9fc92c40fa863935d1Ian Romanick
21433fa5e4bfad8005f09ad3c9fc92c40fa863935d1Ian Romanickstatic unsigned long long get_mult_bytes(const char *str, int len, void *data,
21533fa5e4bfad8005f09ad3c9fc92c40fa863935d1Ian Romanick					 int *percent)
21633fa5e4bfad8005f09ad3c9fc92c40fa863935d1Ian Romanick{
21733fa5e4bfad8005f09ad3c9fc92c40fa863935d1Ian Romanick	const char *p = str;
21833fa5e4bfad8005f09ad3c9fc92c40fa863935d1Ian Romanick	int digit_seen = 0;
21933fa5e4bfad8005f09ad3c9fc92c40fa863935d1Ian Romanick
22033fa5e4bfad8005f09ad3c9fc92c40fa863935d1Ian Romanick	if (len < 2)
22133fa5e4bfad8005f09ad3c9fc92c40fa863935d1Ian Romanick		return __get_mult_bytes(str, data, percent);
22233fa5e4bfad8005f09ad3c9fc92c40fa863935d1Ian Romanick
22333fa5e4bfad8005f09ad3c9fc92c40fa863935d1Ian Romanick	/*
22433fa5e4bfad8005f09ad3c9fc92c40fa863935d1Ian Romanick	 * Go forward until we hit a non-digit, or +/- sign
22533fa5e4bfad8005f09ad3c9fc92c40fa863935d1Ian Romanick	 */
22633fa5e4bfad8005f09ad3c9fc92c40fa863935d1Ian Romanick	while ((p - str) <= len) {
227f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul		if (!isdigit((int) *p) &&
228f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul		    (((*p != '+') && (*p != '-')) || digit_seen))
229f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul			break;
230f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul		digit_seen |= isdigit((int) *p);
231f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul		p++;
23289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul	}
233f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
23489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul	if (!isalpha((int) *p) && (*p != '%'))
235f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul		p = NULL;
236f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
237f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul	return __get_mult_bytes(p, data, percent);
238f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
239f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
240f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/*
241f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Convert string into a floating number. Return 1 for success and 0 otherwise.
2428f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul */
2438f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paulint str_to_float(const char *str, double *val)
244f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
245f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul	return (1 == sscanf(str, "%lf", val));
246f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
24740bd9d0b190e11d39350d1b08d2c2b28e3040bcaDaniel Borca
248f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/*
249f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * convert string into decimal value, noting any size suffix
250f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
251f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paulint str_to_decimal(const char *str, long long *val, int kilo, void *data)
252f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
253f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul	int len, base;
254f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
255f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul	len = strlen(str);
256f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul	if (!len)
257663a9e1b7ef7b8384abe2f81e1a8749b942f6d3aDaniel Borca		return 1;
258f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
259f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul	if (strstr(str, "0x") || strstr(str, "0X"))
260663a9e1b7ef7b8384abe2f81e1a8749b942f6d3aDaniel Borca		base = 16;
261f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul	else
262f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul		base = 10;
263f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
264f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul	*val = strtoll(str, NULL, base);
26589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul	if (*val == LONG_MAX && errno == ERANGE)
266f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul		return 1;
267f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
268f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul	if (kilo) {
269f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul		unsigned long long mult;
2701749a25ca889d514889b34cf6311c8014d97bf66Brian Paul		int perc = 0;
271f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
272f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul		mult = get_mult_bytes(str, len, data, &perc);
273f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul		if (perc)
274f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul			*val = -1ULL - *val;
275f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul		else
276f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul			*val *= mult;
277f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul	} else
278f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul		*val *= get_mult_time(str[len - 1]);
279f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
280f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul	return 0;
281f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
282f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
283f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paulint check_str_bytes(const char *p, long long *val, void *data)
284f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
285f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul	return str_to_decimal(p, val, 1, data);
286f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
287f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
288f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paulint check_str_time(const char *p, long long *val)
289f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
290f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul	return str_to_decimal(p, val, 0, NULL);
291f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
2928f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul
293f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paulvoid strip_blank_front(char **p)
294afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
295f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul	char *s = *p;
296114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger
297114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger	if (!strlen(s))
298114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger		return;
299114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger	while (isspace((int) *s))
300114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger		s++;
301114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger
302114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger	*p = s;
303114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger}
304114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger
305114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheideggervoid strip_blank_end(char *p)
306c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger{
307c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger	char *start = p, *s;
308c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger
309c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger	if (!strlen(p))
310c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger		return;
311c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger
312c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger	s = strchr(p, ';');
313c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger	if (s)
314c6a6cc191813e8343a17b028146a34f193a6ce44Roland Scheidegger		*s = '\0';
315114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger	s = strchr(p, '#');
3161ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul	if (s)
3171ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul		*s = '\0';
3181ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul	if (s)
3191ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul		p = s;
3201ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul
3211ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul	s = p + strlen(p);
3221ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul	while ((isspace((int) *s) || iscntrl((int) *s)) && (s > start))
3231ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul		s--;
3241ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul
3251ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul	*(s + 1) = '\0';
3260a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul}
3270a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul
3280a4be7036864efa6b30d78e0aac449d34b812c13Brian Paulstatic int check_range_bytes(const char *str, long *val, void *data)
3290a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul{
3300a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul	long long __val;
3310a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul
3320a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul	if (!str_to_decimal(str, &__val, 1, data)) {
3330a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul		*val = __val;
3340a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul		return 0;
3350a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul	}
3360a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul
3370a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul	return 1;
3380a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul}
3390a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul
3400a4be7036864efa6b30d78e0aac449d34b812c13Brian Paulstatic int check_int(const char *p, int *val)
3410a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul{
3420a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul	if (!strlen(p))
3430a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul		return 1;
3440a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul	if (strstr(p, "0x") || strstr(p, "0X")) {
3450a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul		if (sscanf(p, "%x", val) == 1)
3460a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul			return 0;
3470a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul	} else {
3480a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul		if (sscanf(p, "%u", val) == 1)
3490a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul			return 0;
350abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul	}
3510a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul
3520a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul	return 1;
3530a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul}
3540a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul
355abd5627a6a034885b0b01b995c73870da1361bb0Brian Paulstatic int opt_len(const char *str)
356abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul{
357abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul	char *postfix;
358abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul
359abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul	postfix = strchr(str, ':');
360abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul	if (!postfix)
361abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul		return strlen(str);
362abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul
363abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul	return (int)(postfix - str);
364abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul}
365abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul
366abd5627a6a034885b0b01b995c73870da1361bb0Brian Paulstatic int str_match_len(const struct value_pair *vp, const char *str)
367abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul{
368abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul	return max(strlen(vp->ival), opt_len(str));
369abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul}
370abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul
371abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul#define val_store(ptr, val, off, or, data)		\
372abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul	do {						\
373abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul		ptr = td_var((data), (off));		\
374abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul		if ((or))				\
375abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul			*ptr |= (val);			\
376abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul		else					\
377abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul			*ptr = (val);			\
378abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul	} while (0)
379abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul
380abd5627a6a034885b0b01b995c73870da1361bb0Brian Paulstatic int __handle_option(struct fio_option *o, const char *ptr, void *data,
381abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul			   int first, int more, int curr)
382abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul{
383abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul	int il, *ilp;
384abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul	fio_fp64_t *flp;
385abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul	long long ull, *ullp;
386abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul	long ul1, ul2;
387abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul	double uf;
388abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul	char **cp = NULL;
389abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul	int ret = 0, is_time = 0;
390abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul	const struct value_pair *vp;
391abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul	struct value_pair posval[PARSE_MAX_VP];
392abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul	int i, all_skipped = 1;
393abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul
394abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul	dprint(FD_PARSE, "__handle_option=%s, type=%d, ptr=%s\n", o->name,
395abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul							o->type, ptr);
396abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul
397abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul	if (!ptr && o->type != FIO_OPT_STR_SET && o->type != FIO_OPT_STR) {
398abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul		log_err("Option %s requires an argument\n", o->name);
399abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul		return 1;
400abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul	}
401abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul
4026988f65e43297ae63bbce30bf882f870b370096cBrian Paul	switch (o->type) {
4036988f65e43297ae63bbce30bf882f870b370096cBrian Paul	case FIO_OPT_STR:
4046988f65e43297ae63bbce30bf882f870b370096cBrian Paul	case FIO_OPT_STR_MULTI: {
4056988f65e43297ae63bbce30bf882f870b370096cBrian Paul		fio_opt_str_fn *fn = o->cb;
4066988f65e43297ae63bbce30bf882f870b370096cBrian Paul
4073ebbc176f9200ac954d461758937e755220ac551Ian Romanick		posval_sort(o, posval);
4083ebbc176f9200ac954d461758937e755220ac551Ian Romanick
4093ebbc176f9200ac954d461758937e755220ac551Ian Romanick		ret = 1;
4103ebbc176f9200ac954d461758937e755220ac551Ian Romanick		for (i = 0; i < PARSE_MAX_VP; i++) {
4113ebbc176f9200ac954d461758937e755220ac551Ian Romanick			vp = &posval[i];
4126988f65e43297ae63bbce30bf882f870b370096cBrian Paul			if (!vp->ival || vp->ival[0] == '\0')
4133ebbc176f9200ac954d461758937e755220ac551Ian Romanick				continue;
4143ebbc176f9200ac954d461758937e755220ac551Ian Romanick			all_skipped = 0;
4153ebbc176f9200ac954d461758937e755220ac551Ian Romanick			if (!strncmp(vp->ival, ptr, str_match_len(vp, ptr))) {
4166988f65e43297ae63bbce30bf882f870b370096cBrian Paul				ret = 0;
4176988f65e43297ae63bbce30bf882f870b370096cBrian Paul				if (o->roff1) {
4186988f65e43297ae63bbce30bf882f870b370096cBrian Paul					if (vp->or)
4196988f65e43297ae63bbce30bf882f870b370096cBrian Paul						*(unsigned int *) o->roff1 |= vp->oval;
4206988f65e43297ae63bbce30bf882f870b370096cBrian Paul					else
4216988f65e43297ae63bbce30bf882f870b370096cBrian Paul						*(unsigned int *) o->roff1 = vp->oval;
4223ebbc176f9200ac954d461758937e755220ac551Ian Romanick				} else {
4233ebbc176f9200ac954d461758937e755220ac551Ian Romanick					if (!o->off1)
4243ebbc176f9200ac954d461758937e755220ac551Ian Romanick						continue;
4253ebbc176f9200ac954d461758937e755220ac551Ian Romanick					val_store(ilp, vp->oval, o->off1, vp->or, data);
4263ebbc176f9200ac954d461758937e755220ac551Ian Romanick				}
4273ebbc176f9200ac954d461758937e755220ac551Ian Romanick				continue;
4283ebbc176f9200ac954d461758937e755220ac551Ian Romanick			}
4293ebbc176f9200ac954d461758937e755220ac551Ian Romanick		}
4303ebbc176f9200ac954d461758937e755220ac551Ian Romanick
4316988f65e43297ae63bbce30bf882f870b370096cBrian Paul		if (ret && !all_skipped)
4323ebbc176f9200ac954d461758937e755220ac551Ian Romanick			show_option_values(o);
4333ebbc176f9200ac954d461758937e755220ac551Ian Romanick		else if (fn)
4343ebbc176f9200ac954d461758937e755220ac551Ian Romanick			ret = fn(data, ptr);
4353ebbc176f9200ac954d461758937e755220ac551Ian Romanick		break;
4363ebbc176f9200ac954d461758937e755220ac551Ian Romanick	}
4376988f65e43297ae63bbce30bf882f870b370096cBrian Paul	case FIO_OPT_STR_VAL_TIME:
4383ebbc176f9200ac954d461758937e755220ac551Ian Romanick		is_time = 1;
4393ebbc176f9200ac954d461758937e755220ac551Ian Romanick	case FIO_OPT_INT:
4403ebbc176f9200ac954d461758937e755220ac551Ian Romanick	case FIO_OPT_STR_VAL: {
4416988f65e43297ae63bbce30bf882f870b370096cBrian Paul		fio_opt_str_val_fn *fn = o->cb;
4426988f65e43297ae63bbce30bf882f870b370096cBrian Paul		char tmp[128], *p;
4436988f65e43297ae63bbce30bf882f870b370096cBrian Paul
4446988f65e43297ae63bbce30bf882f870b370096cBrian Paul		strncpy(tmp, ptr, sizeof(tmp) - 1);
4456988f65e43297ae63bbce30bf882f870b370096cBrian Paul		p = strchr(tmp, ',');
4466988f65e43297ae63bbce30bf882f870b370096cBrian Paul		if (p)
4473ebbc176f9200ac954d461758937e755220ac551Ian Romanick			*p = '\0';
4483ebbc176f9200ac954d461758937e755220ac551Ian Romanick
4493ebbc176f9200ac954d461758937e755220ac551Ian Romanick		if (is_time)
4503ebbc176f9200ac954d461758937e755220ac551Ian Romanick			ret = check_str_time(tmp, &ull);
4513ebbc176f9200ac954d461758937e755220ac551Ian Romanick		else
4523ebbc176f9200ac954d461758937e755220ac551Ian Romanick			ret = check_str_bytes(tmp, &ull, data);
4533ebbc176f9200ac954d461758937e755220ac551Ian Romanick
4546988f65e43297ae63bbce30bf882f870b370096cBrian Paul		dprint(FD_PARSE, "  ret=%d, out=%llu\n", ret, ull);
4556988f65e43297ae63bbce30bf882f870b370096cBrian Paul
4566988f65e43297ae63bbce30bf882f870b370096cBrian Paul		if (ret)
4576988f65e43297ae63bbce30bf882f870b370096cBrian Paul			break;
4586988f65e43297ae63bbce30bf882f870b370096cBrian Paul
4596988f65e43297ae63bbce30bf882f870b370096cBrian Paul		if (o->maxval && ull > o->maxval) {
4606988f65e43297ae63bbce30bf882f870b370096cBrian Paul			log_err("max value out of range: %llu"
4616988f65e43297ae63bbce30bf882f870b370096cBrian Paul					" (%u max)\n", ull, o->maxval);
4626988f65e43297ae63bbce30bf882f870b370096cBrian Paul			return 1;
4636988f65e43297ae63bbce30bf882f870b370096cBrian Paul		}
4646988f65e43297ae63bbce30bf882f870b370096cBrian Paul		if (o->minval && ull < o->minval) {
4656988f65e43297ae63bbce30bf882f870b370096cBrian Paul			log_err("min value out of range: %llu"
4666988f65e43297ae63bbce30bf882f870b370096cBrian Paul					" (%u min)\n", ull, o->minval);
4676988f65e43297ae63bbce30bf882f870b370096cBrian Paul			return 1;
4686988f65e43297ae63bbce30bf882f870b370096cBrian Paul		}
4696988f65e43297ae63bbce30bf882f870b370096cBrian Paul		if (o->posval[0].ival) {
4706988f65e43297ae63bbce30bf882f870b370096cBrian Paul			posval_sort(o, posval);
4716988f65e43297ae63bbce30bf882f870b370096cBrian Paul
4726988f65e43297ae63bbce30bf882f870b370096cBrian Paul			ret = 1;
4736988f65e43297ae63bbce30bf882f870b370096cBrian Paul			for (i = 0; i < PARSE_MAX_VP; i++) {
4746988f65e43297ae63bbce30bf882f870b370096cBrian Paul				vp = &posval[i];
4756988f65e43297ae63bbce30bf882f870b370096cBrian Paul				if (!vp->ival || vp->ival[0] == '\0')
4766988f65e43297ae63bbce30bf882f870b370096cBrian Paul					continue;
4776988f65e43297ae63bbce30bf882f870b370096cBrian Paul				if (vp->oval == ull) {
4786988f65e43297ae63bbce30bf882f870b370096cBrian Paul					ret = 0;
4796988f65e43297ae63bbce30bf882f870b370096cBrian Paul					break;
4806988f65e43297ae63bbce30bf882f870b370096cBrian Paul				}
4816988f65e43297ae63bbce30bf882f870b370096cBrian Paul			}
4826988f65e43297ae63bbce30bf882f870b370096cBrian Paul			if (ret) {
4836988f65e43297ae63bbce30bf882f870b370096cBrian Paul				log_err("fio: value %llu not allowed:\n", ull);
4846988f65e43297ae63bbce30bf882f870b370096cBrian Paul				show_option_values(o);
4856988f65e43297ae63bbce30bf882f870b370096cBrian Paul				return 1;
4866988f65e43297ae63bbce30bf882f870b370096cBrian Paul			}
4876988f65e43297ae63bbce30bf882f870b370096cBrian Paul		}
4886988f65e43297ae63bbce30bf882f870b370096cBrian Paul
489e2a054b70cb5dace40fc1426cbf936366dc72fb9Ian Romanick		if (fn)
4906988f65e43297ae63bbce30bf882f870b370096cBrian Paul			ret = fn(data, &ull);
491e2a054b70cb5dace40fc1426cbf936366dc72fb9Ian Romanick		else {
492e2a054b70cb5dace40fc1426cbf936366dc72fb9Ian Romanick			if (o->type == FIO_OPT_INT) {
4936988f65e43297ae63bbce30bf882f870b370096cBrian Paul				if (first) {
494e2a054b70cb5dace40fc1426cbf936366dc72fb9Ian Romanick					if (o->roff1)
495e2a054b70cb5dace40fc1426cbf936366dc72fb9Ian Romanick						*(unsigned int *) o->roff1 = ull;
4966988f65e43297ae63bbce30bf882f870b370096cBrian Paul					else
4976988f65e43297ae63bbce30bf882f870b370096cBrian Paul						val_store(ilp, ull, o->off1, 0, data);
4986988f65e43297ae63bbce30bf882f870b370096cBrian Paul				}
4996988f65e43297ae63bbce30bf882f870b370096cBrian Paul				if (curr == 1) {
500abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul					if (o->roff2)
501abd5627a6a034885b0b01b995c73870da1361bb0Brian Paul						*(unsigned int *) o->roff2 = ull;
502f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul					else if (o->off2)
503afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg						val_store(ilp, ull, o->off2, 0, data);
504afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg				}
505afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg				if (curr == 2) {
5066dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell					if (o->roff3)
507e93243f8b7d43695654a36334c8cc5cea140d23cBrian						*(unsigned int *) o->roff3 = ull;
508e93243f8b7d43695654a36334c8cc5cea140d23cBrian					else if (o->off3)
509e93243f8b7d43695654a36334c8cc5cea140d23cBrian						val_store(ilp, ull, o->off3, 0, data);
510e93243f8b7d43695654a36334c8cc5cea140d23cBrian				}
511e93243f8b7d43695654a36334c8cc5cea140d23cBrian				if (!more) {
512519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul					if (curr < 1) {
513519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul						if (o->roff2)
514519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul							*(unsigned int *) o->roff2 = ull;
515519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul						else if (o->off2)
516519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul							val_store(ilp, ull, o->off2, 0, data);
517519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul					}
518519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul					if (curr < 2) {
519519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul						if (o->roff3)
520519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul							*(unsigned int *) o->roff3 = ull;
521519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul						else if (o->off3)
5226dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell							val_store(ilp, ull, o->off3, 0, data);
5238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul					}
5248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul				}
5256dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell			} else {
5266dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell				if (first) {
5276dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell					if (o->roff1)
5286dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell						*(unsigned long long *) o->roff1 = ull;
5296dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell					else
5306dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell						val_store(ullp, ull, o->off1, 0, data);
5318e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul				}
532afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg				if (!more) {
5333893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul					if (o->roff2)
5343893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul						*(unsigned long long *) o->roff2 =  ull;
5353893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul					else if (o->off2)
5363893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul						val_store(ullp, ull, o->off2, 0, data);
537fc4b44399a07a7a7559f20ceab8a791209b4d875Brian Paul				}
5389c9a9abd7b953ec9b6cfc52c2f6981c5d38b1691Brian Paul			}
5399c9a9abd7b953ec9b6cfc52c2f6981c5d38b1691Brian Paul		}
540fc4b44399a07a7a7559f20ceab8a791209b4d875Brian Paul		break;
541fc4b44399a07a7a7559f20ceab8a791209b4d875Brian Paul	}
5429c9a9abd7b953ec9b6cfc52c2f6981c5d38b1691Brian Paul	case FIO_OPT_FLOAT_LIST: {
5439c9a9abd7b953ec9b6cfc52c2f6981c5d38b1691Brian Paul		char *cp2;
5449c9a9abd7b953ec9b6cfc52c2f6981c5d38b1691Brian Paul
5459c9a9abd7b953ec9b6cfc52c2f6981c5d38b1691Brian Paul		if (first) {
546a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul			/*
547a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul			** Initialize precision to 0 and zero out list
548fc4b44399a07a7a7559f20ceab8a791209b4d875Brian Paul			** in case specified list is shorter than default
549fc4b44399a07a7a7559f20ceab8a791209b4d875Brian Paul			*/
550fc4b44399a07a7a7559f20ceab8a791209b4d875Brian Paul			ul2 = 0;
551a3f137094cd965d27e1b088499dd609b81a91906Brian Paul			ilp = td_var(data, o->off2);
5526dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell			*ilp = ul2;
5536dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell
554a3f137094cd965d27e1b088499dd609b81a91906Brian Paul			flp = td_var(data, o->off1);
555a3f137094cd965d27e1b088499dd609b81a91906Brian Paul			for(i = 0; i < o->maxlen; i++)
5566dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell				flp[i].u.f = 0.0;
5576dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell		}
5586dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell		if (curr >= o->maxlen) {
55977ce6da028589efc2f3f16cece287f56fd98ce8eBrian Paul			log_err("the list exceeding max length %d\n",
56077ce6da028589efc2f3f16cece287f56fd98ce8eBrian Paul					o->maxlen);
561f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg			return 1;
56277ce6da028589efc2f3f16cece287f56fd98ce8eBrian Paul		}
563a3f137094cd965d27e1b088499dd609b81a91906Brian Paul		if (!str_to_float(ptr, &uf)) {
56477ce6da028589efc2f3f16cece287f56fd98ce8eBrian Paul			log_err("not a floating point value: %s\n", ptr);
56577ce6da028589efc2f3f16cece287f56fd98ce8eBrian Paul			return 1;
56677ce6da028589efc2f3f16cece287f56fd98ce8eBrian Paul		}
56777ce6da028589efc2f3f16cece287f56fd98ce8eBrian Paul		if (uf > o->maxfp) {
568a3f137094cd965d27e1b088499dd609b81a91906Brian Paul			log_err("value out of range: %f"
5693e62d3a8d88b48d4ed19e00ea2bbc3d0a2b6acf7Keith Whitwell				" (range max: %f)\n", uf, o->maxfp);
5704cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul			return 1;
5713e62d3a8d88b48d4ed19e00ea2bbc3d0a2b6acf7Keith Whitwell		}
5721eee1bac1f6d911e6124daafc9b9291666d91cefVinson Lee		if (uf < o->minfp) {
5733e62d3a8d88b48d4ed19e00ea2bbc3d0a2b6acf7Keith Whitwell			log_err("value out of range: %f"
5743e62d3a8d88b48d4ed19e00ea2bbc3d0a2b6acf7Keith Whitwell				" (range min: %f)\n", uf, o->minfp);
5753e62d3a8d88b48d4ed19e00ea2bbc3d0a2b6acf7Keith Whitwell			return 1;
5763e62d3a8d88b48d4ed19e00ea2bbc3d0a2b6acf7Keith Whitwell		}
577f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg
5784cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul		flp = td_var(data, o->off1);
5793e62d3a8d88b48d4ed19e00ea2bbc3d0a2b6acf7Keith Whitwell		flp[curr].u.f = uf;
580c3c19be8e0d0b13916cc128cf3c8e839935c912aBrian Paul
581c3c19be8e0d0b13916cc128cf3c8e839935c912aBrian Paul		dprint(FD_PARSE, "  out=%f\n", uf);
5823e62d3a8d88b48d4ed19e00ea2bbc3d0a2b6acf7Keith Whitwell
5833e62d3a8d88b48d4ed19e00ea2bbc3d0a2b6acf7Keith Whitwell		/*
5844cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul		** Calculate precision for output by counting
5853e62d3a8d88b48d4ed19e00ea2bbc3d0a2b6acf7Keith Whitwell		** number of digits after period. Find first
5863e62d3a8d88b48d4ed19e00ea2bbc3d0a2b6acf7Keith Whitwell		** period in entire remaining list each time
5873e62d3a8d88b48d4ed19e00ea2bbc3d0a2b6acf7Keith Whitwell		*/
5883e62d3a8d88b48d4ed19e00ea2bbc3d0a2b6acf7Keith Whitwell		cp2 = strchr(ptr, '.');
5893e62d3a8d88b48d4ed19e00ea2bbc3d0a2b6acf7Keith Whitwell		if (cp2 != NULL) {
5903e62d3a8d88b48d4ed19e00ea2bbc3d0a2b6acf7Keith Whitwell			int len = 0;
5913e62d3a8d88b48d4ed19e00ea2bbc3d0a2b6acf7Keith Whitwell
5926dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell			while (*++cp2 != '\0' && *cp2 >= '0' && *cp2 <= '9')
5936dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell				len++;
5941eee1bac1f6d911e6124daafc9b9291666d91cefVinson Lee
5956dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell			ilp = td_var(data, o->off2);
5963e62d3a8d88b48d4ed19e00ea2bbc3d0a2b6acf7Keith Whitwell			if (len > *ilp)
597a3f137094cd965d27e1b088499dd609b81a91906Brian Paul				*ilp = len;
59877ce6da028589efc2f3f16cece287f56fd98ce8eBrian Paul		}
5993c59febf05e6af80d63e5b9a478a11b275ac429cBrian Paul
6003c59febf05e6af80d63e5b9a478a11b275ac429cBrian Paul		break;
60177ce6da028589efc2f3f16cece287f56fd98ce8eBrian Paul	}
6025ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell	case FIO_OPT_STR_STORE: {
6035ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell		fio_opt_str_fn *fn = o->cb;
6045ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell
6055ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell		if (o->roff1 || o->off1) {
6065ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell			if (o->roff1)
6075ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell				cp = (char **) o->roff1;
6083e62d3a8d88b48d4ed19e00ea2bbc3d0a2b6acf7Keith Whitwell			else if (o->off1)
609b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul				cp = td_var(data, o->off1);
61032f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg
61132f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg			*cp = strdup(ptr);
61277ce6da028589efc2f3f16cece287f56fd98ce8eBrian Paul		}
61377ce6da028589efc2f3f16cece287f56fd98ce8eBrian Paul
61477ce6da028589efc2f3f16cece287f56fd98ce8eBrian Paul		if (fn)
6156dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell			ret = fn(data, ptr);
6166dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell		else if (o->posval[0].ival) {
6176dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell			posval_sort(o, posval);
6186dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell
6196dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell			ret = 1;
6206dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell			for (i = 0; i < PARSE_MAX_VP; i++) {
621aea66b135eaa5a5f2bc8c652fa7a1a42cca2fe83Brian Paul				vp = &posval[i];
62277ee31930a1b0cc7766939415f4f04ed6a1fa4acBrian Paul				if (!vp->ival || vp->ival[0] == '\0')
62377ee31930a1b0cc7766939415f4f04ed6a1fa4acBrian Paul					continue;
624aea66b135eaa5a5f2bc8c652fa7a1a42cca2fe83Brian Paul				all_skipped = 0;
6252465c4fa9cabe8c40e526b9e081de3b70c851455Brian Paul				if (!strncmp(vp->ival, ptr, str_match_len(vp, ptr))) {
6262465c4fa9cabe8c40e526b9e081de3b70c851455Brian Paul					char *rest;
6272465c4fa9cabe8c40e526b9e081de3b70c851455Brian Paul
6288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul					ret = 0;
6298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul					if (vp->cb)
6308e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul						fn = vp->cb;
63127f4484fb73ac7bf4f790ca2d3efd50b6bea25c3Brian Paul					rest = strstr(*cp ?: ptr, ":");
632bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick					if (rest) {
633bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick						if (*cp)
634bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick							*rest = '\0';
635aea66b135eaa5a5f2bc8c652fa7a1a42cca2fe83Brian Paul						ptr = rest + 1;
636aea66b135eaa5a5f2bc8c652fa7a1a42cca2fe83Brian Paul					} else
637aea66b135eaa5a5f2bc8c652fa7a1a42cca2fe83Brian Paul						ptr = NULL;
6386dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell					break;
6393c59febf05e6af80d63e5b9a478a11b275ac429cBrian Paul				}
6403c59febf05e6af80d63e5b9a478a11b275ac429cBrian Paul			}
6416dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell		}
6426dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell
6436dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell		if (!all_skipped) {
6446dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell			if (ret && !*cp)
6456dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell				show_option_values(o);
6466dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell			else if (ret && *cp)
6476dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell				ret = 0;
6486dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell			else if (fn && ptr)
64935d5301a54153930ee6fd60dff1010ce9f901397Brian Paul				ret = fn(data, ptr);
65035d5301a54153930ee6fd60dff1010ce9f901397Brian Paul		}
6513c59febf05e6af80d63e5b9a478a11b275ac429cBrian Paul
6523c59febf05e6af80d63e5b9a478a11b275ac429cBrian Paul		break;
65335d5301a54153930ee6fd60dff1010ce9f901397Brian Paul	}
65435d5301a54153930ee6fd60dff1010ce9f901397Brian Paul	case FIO_OPT_RANGE: {
65535d5301a54153930ee6fd60dff1010ce9f901397Brian Paul		char tmp[128];
65635d5301a54153930ee6fd60dff1010ce9f901397Brian Paul		char *p1, *p2;
6579818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul
65835d5301a54153930ee6fd60dff1010ce9f901397Brian Paul		strncpy(tmp, ptr, sizeof(tmp) - 1);
659fe469007037d9d5cdbe1677d8ff7368b276e9e7cBrian
66035d5301a54153930ee6fd60dff1010ce9f901397Brian Paul		/* Handle bsrange with separate read,write values: */
6619818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul		p1 = strchr(tmp, ',');
66235d5301a54153930ee6fd60dff1010ce9f901397Brian Paul		if (p1)
663fe469007037d9d5cdbe1677d8ff7368b276e9e7cBrian			*p1 = '\0';
66435d5301a54153930ee6fd60dff1010ce9f901397Brian Paul
6659818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul		p1 = strchr(tmp, '-');
66635d5301a54153930ee6fd60dff1010ce9f901397Brian Paul		if (!p1) {
667fe469007037d9d5cdbe1677d8ff7368b276e9e7cBrian			p1 = strchr(tmp, ':');
66835d5301a54153930ee6fd60dff1010ce9f901397Brian Paul			if (!p1) {
66935d5301a54153930ee6fd60dff1010ce9f901397Brian Paul				ret = 1;
67035d5301a54153930ee6fd60dff1010ce9f901397Brian Paul				break;
67135d5301a54153930ee6fd60dff1010ce9f901397Brian Paul			}
67235d5301a54153930ee6fd60dff1010ce9f901397Brian Paul		}
67335d5301a54153930ee6fd60dff1010ce9f901397Brian Paul
6745ff4075a6961b26042dc2d7f4adcf333439823f4Brian Paul		p2 = p1 + 1;
675a96308c37db0bc0086a017d318bc3504aa5f0b1aKeith Whitwell		*p1 = '\0';
6769818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul		p1 = tmp;
67735d5301a54153930ee6fd60dff1010ce9f901397Brian Paul
678a96308c37db0bc0086a017d318bc3504aa5f0b1aKeith Whitwell		ret = 1;
679fe469007037d9d5cdbe1677d8ff7368b276e9e7cBrian		if (!check_range_bytes(p1, &ul1, data) &&
6808afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul		    !check_range_bytes(p2, &ul2, data)) {
6818afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul			ret = 0;
6829818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul			if (ul1 > ul2) {
6838afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul				unsigned long foo = ul1;
6848afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul
685fe469007037d9d5cdbe1677d8ff7368b276e9e7cBrian				ul1 = ul2;
686bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick				ul2 = foo;
687bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick			}
6889818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul
689bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick			if (first) {
690bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick				if (o->roff1)
691fe469007037d9d5cdbe1677d8ff7368b276e9e7cBrian					*(unsigned int *) o->roff1 = ul1;
692bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick				else
693bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick					val_store(ilp, ul1, o->off1, 0, data);
6949818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul				if (o->roff2)
695bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick					*(unsigned int *) o->roff2 = ul2;
696bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick				else
697fe469007037d9d5cdbe1677d8ff7368b276e9e7cBrian					val_store(ilp, ul2, o->off2, 0, data);
69835d5301a54153930ee6fd60dff1010ce9f901397Brian Paul			}
69908836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul			if (curr == 1) {
70035d5301a54153930ee6fd60dff1010ce9f901397Brian Paul				if (o->roff3 && o->roff4) {
70135d5301a54153930ee6fd60dff1010ce9f901397Brian Paul					*(unsigned int *) o->roff3 = ul1;
70235d5301a54153930ee6fd60dff1010ce9f901397Brian Paul					*(unsigned int *) o->roff4 = ul2;
70335d5301a54153930ee6fd60dff1010ce9f901397Brian Paul				} else if (o->off3 && o->off4) {
70435d5301a54153930ee6fd60dff1010ce9f901397Brian Paul					val_store(ilp, ul1, o->off3, 0, data);
7056dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell					val_store(ilp, ul2, o->off4, 0, data);
706b8fdb900fb9b1c8b1e9ec88509624237307a869aBrian Paul				}
707b8fdb900fb9b1c8b1e9ec88509624237307a869aBrian Paul			}
708b8fdb900fb9b1c8b1e9ec88509624237307a869aBrian Paul			if (curr == 2) {
709f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg				if (o->roff5 && o->roff6) {
710b8fdb900fb9b1c8b1e9ec88509624237307a869aBrian Paul					*(unsigned int *) o->roff5 = ul1;
711b8fdb900fb9b1c8b1e9ec88509624237307a869aBrian Paul					*(unsigned int *) o->roff6 = ul2;
712b8fdb900fb9b1c8b1e9ec88509624237307a869aBrian Paul				} else if (o->off5 && o->off6) {
713b8fdb900fb9b1c8b1e9ec88509624237307a869aBrian Paul					val_store(ilp, ul1, o->off5, 0, data);
714b8fdb900fb9b1c8b1e9ec88509624237307a869aBrian Paul					val_store(ilp, ul2, o->off6, 0, data);
715b8fdb900fb9b1c8b1e9ec88509624237307a869aBrian Paul				}
716b8fdb900fb9b1c8b1e9ec88509624237307a869aBrian Paul			}
717c156eeb682d673e571c1798ff21e183ad4114feaBrian Paul			if (!more) {
718c156eeb682d673e571c1798ff21e183ad4114feaBrian Paul				if (curr < 1) {
719c156eeb682d673e571c1798ff21e183ad4114feaBrian Paul					if (o->roff3 && o->roff4) {
7206dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell						*(unsigned int *) o->roff3 = ul1;
7216dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell						*(unsigned int *) o->roff4 = ul2;
7221eee1bac1f6d911e6124daafc9b9291666d91cefVinson Lee					} else if (o->off3 && o->off4) {
7236dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell						val_store(ilp, ul1, o->off3, 0, data);
7246dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell						val_store(ilp, ul2, o->off4, 0, data);
7256dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell					}
726c156eeb682d673e571c1798ff21e183ad4114feaBrian Paul				}
727fc4b44399a07a7a7559f20ceab8a791209b4d875Brian Paul				if (curr < 2) {
728fc4b44399a07a7a7559f20ceab8a791209b4d875Brian Paul					if (o->roff5 && o->roff6) {
7293c59febf05e6af80d63e5b9a478a11b275ac429cBrian Paul						*(unsigned int *) o->roff5 = ul1;
7303c59febf05e6af80d63e5b9a478a11b275ac429cBrian Paul						*(unsigned int *) o->roff6 = ul2;
7315ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell					} else if (o->off5 && o->off6) {
732fc4b44399a07a7a7559f20ceab8a791209b4d875Brian Paul						val_store(ilp, ul1, o->off5, 0, data);
733c156eeb682d673e571c1798ff21e183ad4114feaBrian Paul						val_store(ilp, ul2, o->off6, 0, data);
7345ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell					}
735c156eeb682d673e571c1798ff21e183ad4114feaBrian Paul				}
736c156eeb682d673e571c1798ff21e183ad4114feaBrian Paul			}
737c156eeb682d673e571c1798ff21e183ad4114feaBrian Paul		}
738bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
739c156eeb682d673e571c1798ff21e183ad4114feaBrian Paul		break;
740fc4b44399a07a7a7559f20ceab8a791209b4d875Brian Paul	}
741fc4b44399a07a7a7559f20ceab8a791209b4d875Brian Paul	case FIO_OPT_BOOL:
742fc4b44399a07a7a7559f20ceab8a791209b4d875Brian Paul	case FIO_OPT_STR_SET: {
743a3f137094cd965d27e1b088499dd609b81a91906Brian Paul		fio_opt_int_fn *fn = o->cb;
744a3f137094cd965d27e1b088499dd609b81a91906Brian Paul
745a3f137094cd965d27e1b088499dd609b81a91906Brian Paul		if (ptr)
746a3f137094cd965d27e1b088499dd609b81a91906Brian Paul			ret = check_int(ptr, &il);
747a3f137094cd965d27e1b088499dd609b81a91906Brian Paul		else if (o->type == FIO_OPT_BOOL)
748a3f137094cd965d27e1b088499dd609b81a91906Brian Paul			ret = 1;
749f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg		else
750a3f137094cd965d27e1b088499dd609b81a91906Brian Paul			il = 1;
751a3f137094cd965d27e1b088499dd609b81a91906Brian Paul
752a3f137094cd965d27e1b088499dd609b81a91906Brian Paul		dprint(FD_PARSE, "  ret=%d, out=%d\n", ret, il);
7535ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell
7545ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell		if (ret)
7555ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell			break;
7565ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell
7575ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell		if (o->maxval && il > (int) o->maxval) {
758a3f137094cd965d27e1b088499dd609b81a91906Brian Paul			log_err("max value out of range: %d (%d max)\n",
759a3f137094cd965d27e1b088499dd609b81a91906Brian Paul								il, o->maxval);
760a3f137094cd965d27e1b088499dd609b81a91906Brian Paul			return 1;
761a3f137094cd965d27e1b088499dd609b81a91906Brian Paul		}
762a3f137094cd965d27e1b088499dd609b81a91906Brian Paul		if (o->minval && il < o->minval) {
763a3f137094cd965d27e1b088499dd609b81a91906Brian Paul			log_err("min value out of range: %d (%d min)\n",
7645ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell								il, o->minval);
765a3f137094cd965d27e1b088499dd609b81a91906Brian Paul			return 1;
766a3f137094cd965d27e1b088499dd609b81a91906Brian Paul		}
7675ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell
768a3f137094cd965d27e1b088499dd609b81a91906Brian Paul		if (o->neg)
769a3f137094cd965d27e1b088499dd609b81a91906Brian Paul			il = !il;
770a3f137094cd965d27e1b088499dd609b81a91906Brian Paul
771a3f137094cd965d27e1b088499dd609b81a91906Brian Paul		if (fn)
772a3f137094cd965d27e1b088499dd609b81a91906Brian Paul			ret = fn(data, &il);
773a3f137094cd965d27e1b088499dd609b81a91906Brian Paul		else {
774a3f137094cd965d27e1b088499dd609b81a91906Brian Paul			if (first) {
775a3f137094cd965d27e1b088499dd609b81a91906Brian Paul				if (o->roff1)
776a3f137094cd965d27e1b088499dd609b81a91906Brian Paul					*(unsigned int *)o->roff1 = il;
777a3f137094cd965d27e1b088499dd609b81a91906Brian Paul				else
778a3f137094cd965d27e1b088499dd609b81a91906Brian Paul					val_store(ilp, il, o->off1, 0, data);
779f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg			}
780a3f137094cd965d27e1b088499dd609b81a91906Brian Paul			if (!more) {
781a3f137094cd965d27e1b088499dd609b81a91906Brian Paul				if (o->roff2)
78280684649a6d01f0e0517b14f61cbcad6fa101929Brian Paul					*(unsigned int *) o->roff2 = il;
783a3f137094cd965d27e1b088499dd609b81a91906Brian Paul				else if (o->off2)
784a3f137094cd965d27e1b088499dd609b81a91906Brian Paul					val_store(ilp, il, o->off2, 0, data);
785a3f137094cd965d27e1b088499dd609b81a91906Brian Paul			}
786a3f137094cd965d27e1b088499dd609b81a91906Brian Paul		}
787a3f137094cd965d27e1b088499dd609b81a91906Brian Paul		break;
788a3f137094cd965d27e1b088499dd609b81a91906Brian Paul	}
789a3f137094cd965d27e1b088499dd609b81a91906Brian Paul	case FIO_OPT_DEPRECATED:
790a3f137094cd965d27e1b088499dd609b81a91906Brian Paul		log_info("Option %s is deprecated\n", o->name);
79180684649a6d01f0e0517b14f61cbcad6fa101929Brian Paul		break;
79280684649a6d01f0e0517b14f61cbcad6fa101929Brian Paul	default:
793a3f137094cd965d27e1b088499dd609b81a91906Brian Paul		log_err("Bad option type %u\n", o->type);
794a3f137094cd965d27e1b088499dd609b81a91906Brian Paul		ret = 1;
795a3f137094cd965d27e1b088499dd609b81a91906Brian Paul	}
79680684649a6d01f0e0517b14f61cbcad6fa101929Brian Paul
79780684649a6d01f0e0517b14f61cbcad6fa101929Brian Paul	if (ret)
798a3f137094cd965d27e1b088499dd609b81a91906Brian Paul		return ret;
799a3f137094cd965d27e1b088499dd609b81a91906Brian Paul
800a3f137094cd965d27e1b088499dd609b81a91906Brian Paul	if (o->verify) {
80180684649a6d01f0e0517b14f61cbcad6fa101929Brian Paul		ret = o->verify(o, data);
80280684649a6d01f0e0517b14f61cbcad6fa101929Brian Paul		if (ret) {
803a3f137094cd965d27e1b088499dd609b81a91906Brian Paul			log_err("Correct format for offending option\n");
804a3f137094cd965d27e1b088499dd609b81a91906Brian Paul			log_err("%20s: %s\n", o->name, o->help);
805a3f137094cd965d27e1b088499dd609b81a91906Brian Paul			show_option_help(o, 1);
80680684649a6d01f0e0517b14f61cbcad6fa101929Brian Paul		}
80780684649a6d01f0e0517b14f61cbcad6fa101929Brian Paul	}
808a3f137094cd965d27e1b088499dd609b81a91906Brian Paul
809a3f137094cd965d27e1b088499dd609b81a91906Brian Paul	return ret;
810a3f137094cd965d27e1b088499dd609b81a91906Brian Paul}
81180684649a6d01f0e0517b14f61cbcad6fa101929Brian Paul
81280684649a6d01f0e0517b14f61cbcad6fa101929Brian Paulstatic int handle_option(struct fio_option *o, const char *__ptr, void *data)
813bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick{
814bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick	char *o_ptr, *ptr, *ptr2;
815bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick	int ret, done;
81680684649a6d01f0e0517b14f61cbcad6fa101929Brian Paul
81780684649a6d01f0e0517b14f61cbcad6fa101929Brian Paul	dprint(FD_PARSE, "handle_option=%s, ptr=%s\n", o->name, __ptr);
818bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick
819bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick	o_ptr = ptr = NULL;
820bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick	if (__ptr)
82180684649a6d01f0e0517b14f61cbcad6fa101929Brian Paul		o_ptr = ptr = strdup(__ptr);
82280684649a6d01f0e0517b14f61cbcad6fa101929Brian Paul
823a3f137094cd965d27e1b088499dd609b81a91906Brian Paul	/*
824a3f137094cd965d27e1b088499dd609b81a91906Brian Paul	 * See if we have another set of parameters, hidden after a comma.
825a3f137094cd965d27e1b088499dd609b81a91906Brian Paul	 * Do this before parsing this round, to check if we should
82680684649a6d01f0e0517b14f61cbcad6fa101929Brian Paul	 * copy set 1 options to set 2.
82780684649a6d01f0e0517b14f61cbcad6fa101929Brian Paul	 */
82880684649a6d01f0e0517b14f61cbcad6fa101929Brian Paul	done = 0;
82980684649a6d01f0e0517b14f61cbcad6fa101929Brian Paul	ret = 1;
83080684649a6d01f0e0517b14f61cbcad6fa101929Brian Paul	do {
83180684649a6d01f0e0517b14f61cbcad6fa101929Brian Paul		int __ret;
83280684649a6d01f0e0517b14f61cbcad6fa101929Brian Paul
83380684649a6d01f0e0517b14f61cbcad6fa101929Brian Paul		ptr2 = NULL;
83480684649a6d01f0e0517b14f61cbcad6fa101929Brian Paul		if (ptr &&
83580684649a6d01f0e0517b14f61cbcad6fa101929Brian Paul		    (o->type != FIO_OPT_STR_STORE) &&
83680684649a6d01f0e0517b14f61cbcad6fa101929Brian Paul		    (o->type != FIO_OPT_STR) &&
83780684649a6d01f0e0517b14f61cbcad6fa101929Brian Paul		    (o->type != FIO_OPT_FLOAT_LIST)) {
83880684649a6d01f0e0517b14f61cbcad6fa101929Brian Paul			ptr2 = strchr(ptr, ',');
839a3f137094cd965d27e1b088499dd609b81a91906Brian Paul			if (ptr2 && *(ptr2 + 1) == '\0')
840a3f137094cd965d27e1b088499dd609b81a91906Brian Paul				*ptr2 = '\0';
841a3f137094cd965d27e1b088499dd609b81a91906Brian Paul			if (o->type != FIO_OPT_STR_MULTI && o->type != FIO_OPT_RANGE) {
8426dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell				if (!ptr2)
8436dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell					ptr2 = strchr(ptr, ':');
8446dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell				if (!ptr2)
8456dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell					ptr2 = strchr(ptr, '-');
8466dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell			}
8476dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell		} else if (ptr && o->type == FIO_OPT_FLOAT_LIST) {
8486dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell			ptr2 = strchr(ptr, ':');
8496dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell		}
8506dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell
8516dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell		/*
852ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul		 * Don't return early if parsing the first option fails - if
853ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul		 * we are doing multiple arguments, we can allow the first one
854f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg		 * being empty.
855ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul		 */
856ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul		__ret = __handle_option(o, ptr, data, !done, !!ptr2, done);
857ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul		if (ret)
858ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul			ret = __ret;
859ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul
860ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul		if (!ptr2)
861ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul			break;
862ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul
863ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul		ptr = ptr2 + 1;
864ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul		done++;
865ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul	} while (1);
866ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul
867ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul	if (o_ptr)
868ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul		free(o_ptr);
869ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul	return ret;
870ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul}
871add9f2168a5d6b15eb9955ee761246c4f4cf8458Brian Paul
872ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paulstatic struct fio_option *get_option(char *opt,
873fe988d786c4076bfbf410b84085d8c1115baa489Brian Paul				     struct fio_option *options, char **post)
874fe988d786c4076bfbf410b84085d8c1115baa489Brian Paul{
875ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul	struct fio_option *o;
876ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul	char *ret;
877fe988d786c4076bfbf410b84085d8c1115baa489Brian Paul
878fe988d786c4076bfbf410b84085d8c1115baa489Brian Paul	ret = strchr(opt, '=');
879fe988d786c4076bfbf410b84085d8c1115baa489Brian Paul	if (ret) {
880fe988d786c4076bfbf410b84085d8c1115baa489Brian Paul		*post = ret;
881fe988d786c4076bfbf410b84085d8c1115baa489Brian Paul		*ret = '\0';
882fe988d786c4076bfbf410b84085d8c1115baa489Brian Paul		ret = opt;
883fe988d786c4076bfbf410b84085d8c1115baa489Brian Paul		(*post)++;
884ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul		strip_blank_end(ret);
885ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul		o = find_option(options, ret);
886ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul	} else {
887ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul		o = find_option(options, opt);
888ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul		*post = NULL;
889ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul	}
89083e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul
8915e3733fadf08178fca7c9f20a0f4783f940383aaBrian Paul	return o;
89283e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul}
89383e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul
89483e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paulstatic int opt_cmp(const void *p1, const void *p2)
89583e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul{
89683e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul	struct fio_option *o;
89783e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul	char *s, *foo;
89883e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul	int prio1, prio2;
89983e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul
90083e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul	prio1 = prio2 = 0;
90183e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul
90283e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul	if (*(char **)p1) {
90383e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul		s = strdup(*((char **) p1));
90483e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul		o = get_option(s, __fio_options, &foo);
90583e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul		if (o)
90683e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul			prio1 = o->prio;
90783e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul		free(s);
90883e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul	}
90983e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul	if (*(char **)p2) {
91083e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul		s = strdup(*((char **) p2));
91183e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul		o = get_option(s, __fio_options, &foo);
9125e3733fadf08178fca7c9f20a0f4783f940383aaBrian Paul		if (o)
9135e3733fadf08178fca7c9f20a0f4783f940383aaBrian Paul			prio2 = o->prio;
91483e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul		free(s);
91583e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul	}
91683e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul
9175e3733fadf08178fca7c9f20a0f4783f940383aaBrian Paul	return prio2 - prio1;
9185e3733fadf08178fca7c9f20a0f4783f940383aaBrian Paul}
91983e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul
92083e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paulvoid sort_options(char **opts, struct fio_option *options, int num_opts)
92183e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul{
92283e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul	__fio_options = options;
92383e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul	qsort(opts, num_opts, sizeof(char *), opt_cmp);
92483e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul	__fio_options = NULL;
92583e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul}
92683e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul
92783e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paulint parse_cmd_option(const char *opt, const char *val,
92883e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul		     struct fio_option *options, void *data)
929fc4b44399a07a7a7559f20ceab8a791209b4d875Brian Paul{
93062c734f49948df7aeef55ad23a6664cbf3e11533Brian Paul	struct fio_option *o;
931f93b3dd69e744cf1dd6b102a11cdb07c2df4a967Brian Paul
932afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	o = find_option(options, opt);
933afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	if (!o) {
9348e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul		log_err("Bad option <%s>\n", opt);
935afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg		return 1;
9368e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul	}
9378e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
938afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	if (!handle_option(o, val, data))
9398e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul		return 0;
9408e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
9418e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul	log_err("fio: failed parsing %s=%s\n", opt, val);
942afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	return 1;
943a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul}
944afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
945afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtgint parse_option(char *opt, const char *input,
946afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg		 struct fio_option *options, struct fio_option **o, void *data)
947afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
948afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	char *post;
9498e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
95065d54604c387dca986c876e811362d8e8517dcacBrian Paul	if (!opt) {
951afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg		log_err("fio: failed parsing %s\n", input);
952afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg		*o = NULL;
953afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg		return 1;
954afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	}
955afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
956afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	*o = get_option(opt, options, &post);
957afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	if (!*o) {
958afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg		if (post) {
959afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg			int len = strlen(opt);
960afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg			if (opt + len + 1 != post)
9618e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul				memmove(opt + len + 1, post, strlen(post));
9628e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul			opt[len] = '=';
9638e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul		}
9648e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul		return 1;
9658e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul	}
9668e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
9678e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul	if (!handle_option(*o, post, data))
9688e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul		return 0;
9698e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
9708e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul	log_err("fio: failed parsing %s\n", input);
9718e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul	return 1;
972afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg}
973afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
974afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg/*
975afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * Option match, levenshtein distance. Handy for not quite remembering what
976a1503b00f863a48a517939a42d512f9cfe77f79cBrian Paul * the option name is.
9778e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
9788e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulstatic int string_distance(const char *s1, const char *s2)
979afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
98062c734f49948df7aeef55ad23a6664cbf3e11533Brian Paul	unsigned int s1_len = strlen(s1);
981afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	unsigned int s2_len = strlen(s2);
982afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	unsigned int *p, *q, *r;
983afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	unsigned int i, j;
984738318bb75dea8dac4465f53850987f6062a732dBrian Paul
985f378ab825c0c74aab263e7dec30194eead22c288Brian Paul	p = malloc(sizeof(unsigned int) * (s2_len + 1));
9866dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell	q = malloc(sizeof(unsigned int) * (s2_len + 1));
9876dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell
9886dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell	p[0] = 0;
9899c27278acfb786c8f2fc591eef9ed0c25135bcf0Brian Paul	for (i = 1; i <= s2_len; i++)
9909c27278acfb786c8f2fc591eef9ed0c25135bcf0Brian Paul		p[i] = p[i - 1] + 1;
991f378ab825c0c74aab263e7dec30194eead22c288Brian Paul
992f378ab825c0c74aab263e7dec30194eead22c288Brian Paul	for (i = 1; i <= s1_len; i++) {
993f378ab825c0c74aab263e7dec30194eead22c288Brian Paul		q[0] = p[0] + 1;
9949c27278acfb786c8f2fc591eef9ed0c25135bcf0Brian Paul		for (j = 1; j <= s2_len; j++) {
9959c27278acfb786c8f2fc591eef9ed0c25135bcf0Brian Paul			unsigned int sub = p[j - 1];
996f378ab825c0c74aab263e7dec30194eead22c288Brian Paul
9979c27278acfb786c8f2fc591eef9ed0c25135bcf0Brian Paul			if (s1[i - 1] != s2[j - 1])
9989c27278acfb786c8f2fc591eef9ed0c25135bcf0Brian Paul				sub++;
999a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul
1000a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul			q[j] = min(p[j] + 1, min(q[j - 1] + 1, sub));
10019c27278acfb786c8f2fc591eef9ed0c25135bcf0Brian Paul		}
10029c27278acfb786c8f2fc591eef9ed0c25135bcf0Brian Paul		r = p;
10039c27278acfb786c8f2fc591eef9ed0c25135bcf0Brian Paul		p = q;
10049c27278acfb786c8f2fc591eef9ed0c25135bcf0Brian Paul		q = r;
1005681b8c9d1ba06c8c82e687a5ced369b72e6b1eb9Brian Paul	}
1006b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul
100732f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg	i = p[s2_len];
1008b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul	free(p);
1009b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul	free(q);
10109c27278acfb786c8f2fc591eef9ed0c25135bcf0Brian Paul	return i;
10119c27278acfb786c8f2fc591eef9ed0c25135bcf0Brian Paul}
10129c27278acfb786c8f2fc591eef9ed0c25135bcf0Brian Paul
10139c27278acfb786c8f2fc591eef9ed0c25135bcf0Brian Paulstatic struct fio_option *find_child(struct fio_option *options,
10149c27278acfb786c8f2fc591eef9ed0c25135bcf0Brian Paul				     struct fio_option *o)
10159c27278acfb786c8f2fc591eef9ed0c25135bcf0Brian Paul{
10169c27278acfb786c8f2fc591eef9ed0c25135bcf0Brian Paul	struct fio_option *__o;
10171f7c914ad0beea8a29c1a171c7cd1a12f2efe0faBrian Paul
10184f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul	for (__o = options + 1; __o->name; __o++)
10194f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul		if (__o->parent && !strcmp(__o->parent, o->name))
10209c27278acfb786c8f2fc591eef9ed0c25135bcf0Brian Paul			return __o;
10219c27278acfb786c8f2fc591eef9ed0c25135bcf0Brian Paul
10229c27278acfb786c8f2fc591eef9ed0c25135bcf0Brian Paul	return NULL;
10236dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell}
10246628bc9cff74a6d524165e809f73eabc85ba34b5Brian Paul
10256dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwellstatic void __print_option(struct fio_option *o, struct fio_option *org,
10266dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell			   int level)
1027b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul{
10286dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell	char name[256], *p;
10296dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell	int depth;
10306dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell
10316dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell	if (!o)
10326dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell		return;
10336dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell	if (!org)
103483e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul		org = o;
10356dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell
10366dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell	p = name;
1037887e2cf01a99f7fe1b7c94320b7bdbbf0d6ad2f8Brian Paul	depth = level;
10386628bc9cff74a6d524165e809f73eabc85ba34b5Brian Paul	while (depth--)
10393893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul		p += sprintf(p, "%s", "  ");
1040f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg
10413893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul	sprintf(p, "%s", o->name);
10423893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
104383e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul	log_info("%-24s: %s\n", name, o->help);
104483e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul}
10456628bc9cff74a6d524165e809f73eabc85ba34b5Brian Paul
104683e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paulstatic void print_option(struct fio_option *o)
1047b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul{
10486628bc9cff74a6d524165e809f73eabc85ba34b5Brian Paul	struct fio_option *parent;
10498bc00c2047f69d8cd37d4fd70256850445b0fa1dBrian Paul	struct fio_option *__o;
10508bc00c2047f69d8cd37d4fd70256850445b0fa1dBrian Paul	unsigned int printed;
10518bc00c2047f69d8cd37d4fd70256850445b0fa1dBrian Paul	unsigned int level;
1052b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul
1053a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul	__print_option(o, NULL, 0);
1054a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul	parent = o;
1055a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul	level = 0;
10566628bc9cff74a6d524165e809f73eabc85ba34b5Brian Paul	do {
10576628bc9cff74a6d524165e809f73eabc85ba34b5Brian Paul		level++;
10586628bc9cff74a6d524165e809f73eabc85ba34b5Brian Paul		printed = 0;
10596628bc9cff74a6d524165e809f73eabc85ba34b5Brian Paul
1060c813b545ab4726fc5030f123ec6255224d64ad82Brian		while ((__o = find_child(o, parent)) != NULL) {
10614d0b7618cb3ada3b13e9e9b650ace34f5131e318Brian Paul			__print_option(__o, o, level);
10624d0b7618cb3ada3b13e9e9b650ace34f5131e318Brian Paul			o = __o;
1063c813b545ab4726fc5030f123ec6255224d64ad82Brian			printed++;
1064c813b545ab4726fc5030f123ec6255224d64ad82Brian		}
1065c813b545ab4726fc5030f123ec6255224d64ad82Brian
10666628bc9cff74a6d524165e809f73eabc85ba34b5Brian Paul		parent = o;
1067c813b545ab4726fc5030f123ec6255224d64ad82Brian	} while (printed);
1068c813b545ab4726fc5030f123ec6255224d64ad82Brian}
1069c813b545ab4726fc5030f123ec6255224d64ad82Brian
10704d0b7618cb3ada3b13e9e9b650ace34f5131e318Brian Paulint show_cmd_help(struct fio_option *options, const char *name)
1071c813b545ab4726fc5030f123ec6255224d64ad82Brian{
1072c813b545ab4726fc5030f123ec6255224d64ad82Brian	struct fio_option *o, *closest;
1073c813b545ab4726fc5030f123ec6255224d64ad82Brian	unsigned int best_dist = -1U;
1074c813b545ab4726fc5030f123ec6255224d64ad82Brian	int found = 0;
10756628bc9cff74a6d524165e809f73eabc85ba34b5Brian Paul	int show_all = 0;
1076c813b545ab4726fc5030f123ec6255224d64ad82Brian
1077c813b545ab4726fc5030f123ec6255224d64ad82Brian	if (!name || !strcmp(name, "all"))
1078c813b545ab4726fc5030f123ec6255224d64ad82Brian		show_all = 1;
10794d0b7618cb3ada3b13e9e9b650ace34f5131e318Brian Paul
1080c813b545ab4726fc5030f123ec6255224d64ad82Brian	closest = NULL;
1081c813b545ab4726fc5030f123ec6255224d64ad82Brian	best_dist = -1;
10826628bc9cff74a6d524165e809f73eabc85ba34b5Brian Paul	for (o = &options[0]; o->name; o++) {
1083c813b545ab4726fc5030f123ec6255224d64ad82Brian		int match = 0;
1084be1b8e5d6c6692010a3ec117035d9b218929e2b3Brian
1085be1b8e5d6c6692010a3ec117035d9b218929e2b3Brian		if (o->type == FIO_OPT_DEPRECATED)
1086be1b8e5d6c6692010a3ec117035d9b218929e2b3Brian			continue;
1087887e2cf01a99f7fe1b7c94320b7bdbbf0d6ad2f8Brian Paul		if (!exec_profile && o->prof_name)
1088887e2cf01a99f7fe1b7c94320b7bdbbf0d6ad2f8Brian Paul			continue;
1089887e2cf01a99f7fe1b7c94320b7bdbbf0d6ad2f8Brian Paul		if (exec_profile && !(o->prof_name && !strcmp(exec_profile, o->prof_name)))
1090887e2cf01a99f7fe1b7c94320b7bdbbf0d6ad2f8Brian Paul			continue;
1091b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul
1092b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul		if (name) {
1093b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul			if (!strcmp(name, o->name) ||
1094b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul			    (o->alias && !strcmp(name, o->alias)))
1095b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul				match = 1;
1096b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul			else {
1097a120778c72324bc56c63cd0f1873c6f2772228eaMichel Dänzer				unsigned int dist;
109832f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg
109932f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg				dist = string_distance(name, o->name);
1100b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul				if (dist < best_dist) {
1101b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul					best_dist = dist;
1102b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul					closest = o;
1103b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul				}
11048afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul			}
11058afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul		}
11068afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul
11078afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul		if (show_all || match) {
11088afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul			found = 1;
11098afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul			if (match)
11108afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul				log_info("%20s: %s\n", o->name, o->help);
11118afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul			if (show_all) {
11128afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul				if (!o->parent)
11138afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul					print_option(o);
11148afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul				continue;
11158afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul			}
11161a2bb37264b4448d33f2948fe1702c9dc936395dBrian Paul		}
111783e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul
111883e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul		if (!match)
111983e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul			continue;
112083e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul
112183e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul		show_option_help(o, 0);
11226628bc9cff74a6d524165e809f73eabc85ba34b5Brian Paul	}
11236628bc9cff74a6d524165e809f73eabc85ba34b5Brian Paul
11246628bc9cff74a6d524165e809f73eabc85ba34b5Brian Paul	if (found)
1125738318bb75dea8dac4465f53850987f6062a732dBrian Paul		return 0;
112642b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu
112742b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu	log_err("No such command: %s", name);
112842b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu
112942b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu	/*
113042b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu	 * Only print an appropriately close option, one where the edit
113142b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu	 * distance isn't too big. Otherwise we get crazy matches.
113242b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu	 */
113342b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu	if (closest && best_dist < 3) {
113442b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu		log_info(" - showing closest match\n");
11353c59febf05e6af80d63e5b9a478a11b275ac429cBrian Paul		log_info("%20s: %s\n", closest->name, closest->help);
11363c59febf05e6af80d63e5b9a478a11b275ac429cBrian Paul		show_option_help(closest, 0);
113742b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu	} else
113842b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu		log_info("\n");
113942b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu
114042b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu	return 1;
114142b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu}
114242b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu
114342b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu/*
1144738318bb75dea8dac4465f53850987f6062a732dBrian Paul * Handle parsing of default parameters.
1145738318bb75dea8dac4465f53850987f6062a732dBrian Paul */
1146738318bb75dea8dac4465f53850987f6062a732dBrian Paulvoid fill_default_options(void *data, struct fio_option *options)
1147738318bb75dea8dac4465f53850987f6062a732dBrian Paul{
1148738318bb75dea8dac4465f53850987f6062a732dBrian Paul	struct fio_option *o;
1149738318bb75dea8dac4465f53850987f6062a732dBrian Paul
1150aa328291c5b015e74ebfd9c5cdb39227265b3000Brian	dprint(FD_PARSE, "filling default options\n");
1151aa328291c5b015e74ebfd9c5cdb39227265b3000Brian
1152aa328291c5b015e74ebfd9c5cdb39227265b3000Brian	for (o = &options[0]; o->name; o++)
1153aa328291c5b015e74ebfd9c5cdb39227265b3000Brian		if (o->def)
1154738318bb75dea8dac4465f53850987f6062a732dBrian Paul			handle_option(o, o->def, data);
1155738318bb75dea8dac4465f53850987f6062a732dBrian Paul}
1156738318bb75dea8dac4465f53850987f6062a732dBrian Paul
1157738318bb75dea8dac4465f53850987f6062a732dBrian Paulvoid option_init(struct fio_option *o)
1158738318bb75dea8dac4465f53850987f6062a732dBrian Paul{
1159738318bb75dea8dac4465f53850987f6062a732dBrian Paul	if (o->type == FIO_OPT_DEPRECATED)
1160738318bb75dea8dac4465f53850987f6062a732dBrian Paul		return;
1161738318bb75dea8dac4465f53850987f6062a732dBrian Paul	if (o->type == FIO_OPT_BOOL) {
1162738318bb75dea8dac4465f53850987f6062a732dBrian Paul		o->minval = 0;
1163738318bb75dea8dac4465f53850987f6062a732dBrian Paul		o->maxval = 1;
1164738318bb75dea8dac4465f53850987f6062a732dBrian Paul	}
1165738318bb75dea8dac4465f53850987f6062a732dBrian Paul	if (o->type == FIO_OPT_INT) {
1166738318bb75dea8dac4465f53850987f6062a732dBrian Paul		if (!o->maxval)
1167738318bb75dea8dac4465f53850987f6062a732dBrian Paul			o->maxval = UINT_MAX;
1168f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg	}
1169738318bb75dea8dac4465f53850987f6062a732dBrian Paul	if (o->type == FIO_OPT_FLOAT_LIST) {
1170738318bb75dea8dac4465f53850987f6062a732dBrian Paul		o->minfp = DBL_MIN;
1171738318bb75dea8dac4465f53850987f6062a732dBrian Paul		o->maxfp = DBL_MAX;
1172738318bb75dea8dac4465f53850987f6062a732dBrian Paul	}
11739c27278acfb786c8f2fc591eef9ed0c25135bcf0Brian Paul	if (o->type == FIO_OPT_STR_SET && o->def) {
1174738318bb75dea8dac4465f53850987f6062a732dBrian Paul		log_err("Option %s: string set option with"
1175738318bb75dea8dac4465f53850987f6062a732dBrian Paul				" default will always be true\n", o->name);
1176738318bb75dea8dac4465f53850987f6062a732dBrian Paul	}
1177738318bb75dea8dac4465f53850987f6062a732dBrian Paul	if (!o->cb && (!o->off1 && !o->roff1))
1178738318bb75dea8dac4465f53850987f6062a732dBrian Paul		log_err("Option %s: neither cb nor offset given\n", o->name);
1179738318bb75dea8dac4465f53850987f6062a732dBrian Paul	if (!o->category) {
1180738318bb75dea8dac4465f53850987f6062a732dBrian Paul		log_info("Option %s: no category defined. Setting to misc\n", o->name);
1181738318bb75dea8dac4465f53850987f6062a732dBrian Paul		o->category = FIO_OPT_C_GENERAL;
1182887e2cf01a99f7fe1b7c94320b7bdbbf0d6ad2f8Brian Paul		o->group = FIO_OPT_G_INVALID;
1183be1b8e5d6c6692010a3ec117035d9b218929e2b3Brian	}
1184738318bb75dea8dac4465f53850987f6062a732dBrian Paul	if (o->type == FIO_OPT_STR || o->type == FIO_OPT_STR_STORE ||
1185738318bb75dea8dac4465f53850987f6062a732dBrian Paul	    o->type == FIO_OPT_STR_MULTI)
1186738318bb75dea8dac4465f53850987f6062a732dBrian Paul		return;
1187738318bb75dea8dac4465f53850987f6062a732dBrian Paul	if (o->cb && ((o->off1 || o->off2 || o->off3 || o->off4) ||
1188738318bb75dea8dac4465f53850987f6062a732dBrian Paul		      (o->roff1 || o->roff2 || o->roff3 || o->roff4))) {
1189738318bb75dea8dac4465f53850987f6062a732dBrian Paul		log_err("Option %s: both cb and offset given\n", o->name);
1190738318bb75dea8dac4465f53850987f6062a732dBrian Paul	}
1191738318bb75dea8dac4465f53850987f6062a732dBrian Paul}
1192887e2cf01a99f7fe1b7c94320b7bdbbf0d6ad2f8Brian Paul
1193be1b8e5d6c6692010a3ec117035d9b218929e2b3Brian/*
1194738318bb75dea8dac4465f53850987f6062a732dBrian Paul * Sanitize the options structure. For now it just sets min/max for bool
1195887e2cf01a99f7fe1b7c94320b7bdbbf0d6ad2f8Brian Paul * values and whether both callback and offsets are given.
1196be1b8e5d6c6692010a3ec117035d9b218929e2b3Brian */
1197738318bb75dea8dac4465f53850987f6062a732dBrian Paulvoid options_init(struct fio_option *options)
1198738318bb75dea8dac4465f53850987f6062a732dBrian Paul{
1199738318bb75dea8dac4465f53850987f6062a732dBrian Paul	struct fio_option *o;
1200738318bb75dea8dac4465f53850987f6062a732dBrian Paul
1201738318bb75dea8dac4465f53850987f6062a732dBrian Paul	dprint(FD_PARSE, "init options\n");
1202738318bb75dea8dac4465f53850987f6062a732dBrian Paul
1203738318bb75dea8dac4465f53850987f6062a732dBrian Paul	for (o = &options[0]; o->name; o++) {
1204738318bb75dea8dac4465f53850987f6062a732dBrian Paul		option_init(o);
1205887e2cf01a99f7fe1b7c94320b7bdbbf0d6ad2f8Brian Paul		if (o->inverse)
1206be1b8e5d6c6692010a3ec117035d9b218929e2b3Brian			o->inv_opt = find_option(options, o->inverse);
1207738318bb75dea8dac4465f53850987f6062a732dBrian Paul	}
1208887e2cf01a99f7fe1b7c94320b7bdbbf0d6ad2f8Brian Paul}
1209be1b8e5d6c6692010a3ec117035d9b218929e2b3Brian
1210738318bb75dea8dac4465f53850987f6062a732dBrian Paulvoid options_free(struct fio_option *options, void *data)
1211887e2cf01a99f7fe1b7c94320b7bdbbf0d6ad2f8Brian Paul{
1212be1b8e5d6c6692010a3ec117035d9b218929e2b3Brian	struct fio_option *o;
1213738318bb75dea8dac4465f53850987f6062a732dBrian Paul	char **ptr;
1214738318bb75dea8dac4465f53850987f6062a732dBrian Paul
1215738318bb75dea8dac4465f53850987f6062a732dBrian Paul	dprint(FD_PARSE, "free options\n");
1216738318bb75dea8dac4465f53850987f6062a732dBrian Paul
1217738318bb75dea8dac4465f53850987f6062a732dBrian Paul	for (o = &options[0]; o->name; o++) {
1218738318bb75dea8dac4465f53850987f6062a732dBrian Paul		if (o->type != FIO_OPT_STR_STORE || !o->off1)
1219aa328291c5b015e74ebfd9c5cdb39227265b3000Brian			continue;
1220aa328291c5b015e74ebfd9c5cdb39227265b3000Brian
1221738318bb75dea8dac4465f53850987f6062a732dBrian Paul		ptr = td_var(data, o->off1);
1222738318bb75dea8dac4465f53850987f6062a732dBrian Paul		if (*ptr) {
1223738318bb75dea8dac4465f53850987f6062a732dBrian Paul			free(*ptr);
1224738318bb75dea8dac4465f53850987f6062a732dBrian Paul			*ptr = NULL;
1225738318bb75dea8dac4465f53850987f6062a732dBrian Paul		}
1226738318bb75dea8dac4465f53850987f6062a732dBrian Paul	}
1227738318bb75dea8dac4465f53850987f6062a732dBrian Paul}
1228738318bb75dea8dac4465f53850987f6062a732dBrian Paul