/*
 * This file contains the ini and command liner parser main.
 */
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
#include <float.h>

#include "compiler/compiler.h"
#include "parse.h"
#include "debug.h"
#include "log.h"
#include "options.h"
#include "optgroup.h"
#include "minmax.h"
#include "lib/ieee754.h"
#include "lib/pow2.h"

#ifdef CONFIG_ARITHMETIC
#include "y.tab.h"
#endif

static const char *opt_type_names[] = {
	"OPT_INVALID",
	"OPT_STR",
	"OPT_STR_ULL",
	"OPT_STR_MULTI",
	"OPT_STR_VAL",
	"OPT_STR_VAL_TIME",
	"OPT_STR_STORE",
	"OPT_RANGE",
	"OPT_INT",
	"OPT_ULL",
	"OPT_BOOL",
	"OPT_FLOAT_LIST",
	"OPT_STR_SET",
	"OPT_DEPRECATED",
	"OPT_SOFT_DEPRECATED",
	"OPT_UNSUPPORTED",
};

static const struct fio_option *__fio_options;

static int vp_cmp(const void *p1, const void *p2)
{
	const struct value_pair *vp1 = p1;
	const struct value_pair *vp2 = p2;

	return strlen(vp2->ival) - strlen(vp1->ival);
}

static void posval_sort(const struct fio_option *o, struct value_pair *vpmap)
{
	const struct value_pair *vp;
	int entries;

	memset(vpmap, 0, PARSE_MAX_VP * sizeof(struct value_pair));

	for (entries = 0; entries < PARSE_MAX_VP; entries++) {
		vp = &o->posval[entries];
		if (!vp->ival || vp->ival[0] == '\0')
			break;

		memcpy(&vpmap[entries], vp, sizeof(*vp));
	}

	qsort(vpmap, entries, sizeof(struct value_pair), vp_cmp);
}

static void show_option_range(const struct fio_option *o,
			      ssize_t (*logger)(const char *format, ...))
{
	if (o->type == FIO_OPT_FLOAT_LIST) {
		const char *sep = "";
		if (!o->minfp && !o->maxfp)
			return;

		logger("%20s: ", "range");
		if (o->minfp != DBL_MIN) {
			logger("min=%f", o->minfp);
			sep = ", ";
		}
		if (o->maxfp != DBL_MAX)
			logger("%smax=%f", sep, o->maxfp);
		logger("\n");
	} else if (!o->posval[0].ival) {
		if (!o->minval && !o->maxval)
			return;

		logger("%20s: min=%d", "range", o->minval);
		if (o->maxval)
			logger(", max=%d", o->maxval);
		logger("\n");
	}
}

static void show_option_values(const struct fio_option *o)
{
	int i;

	for (i = 0; i < PARSE_MAX_VP; i++) {
		const struct value_pair *vp = &o->posval[i];

		if (!vp->ival)
			continue;

		log_info("%20s: %-10s", i == 0 ? "valid values" : "", vp->ival);
		if (vp->help)
			log_info(" %s", vp->help);
		log_info("\n");
	}

	if (i)
		log_info("\n");
}

static void show_option_help(const struct fio_option *o, int is_err)
{
	const char *typehelp[] = {
		[FIO_OPT_INVALID]	  = "invalid",
		[FIO_OPT_STR]		  = "string (opt=bla)",
		[FIO_OPT_STR_ULL]	  = "string (opt=bla)",
		[FIO_OPT_STR_MULTI]	  = "string with possible k/m/g postfix (opt=4k)",
		[FIO_OPT_STR_VAL]	  = "string (opt=bla)",
		[FIO_OPT_STR_VAL_TIME]	  = "string with time postfix (opt=10s)",
		[FIO_OPT_STR_STORE]	  = "string (opt=bla)",
		[FIO_OPT_RANGE]		  = "one to three ranges (opt=1k-4k[,4k-8k[,1k-8k]])",
		[FIO_OPT_INT]		  = "integer value (opt=100)",
		[FIO_OPT_ULL]		  = "integer value (opt=100)",
		[FIO_OPT_BOOL]		  = "boolean value (opt=1)",
		[FIO_OPT_FLOAT_LIST]	  = "list of floating point values separated by ':' (opt=5.9:7.8)",
		[FIO_OPT_STR_SET]	  = "empty or boolean value ([0|1])",
		[FIO_OPT_DEPRECATED]	  = "deprecated",
		[FIO_OPT_SOFT_DEPRECATED] = "deprecated",
		[FIO_OPT_UNSUPPORTED]	  = "unsupported",
	};
	ssize_t (*logger)(const char *format, ...);

	if (is_err)
		logger = log_err;
	else
		logger = log_info;

	if (o->alias)
		logger("%20s: %s\n", "alias", o->alias);

	logger("%20s: %s\n", "type", typehelp[o->type]);
	logger("%20s: %s\n", "default", o->def ? o->def : "no default");
	if (o->prof_name)
		logger("%20s: only for profile '%s'\n", "valid", o->prof_name);
	show_option_range(o, logger);
	show_option_values(o);
}

static unsigned long long get_mult_time(const char *str, int len,
					int is_seconds)
{
	const char *p = str;
	char *c;
	unsigned long long mult = 1;
	int i;

	/*
         * Go forward until we hit a non-digit, or +/- sign
         */
	while ((p - str) <= len) {
		if (!isdigit((int) *p) && (*p != '+') && (*p != '-'))
			break;
		p++;
	}

	if (!isalpha((int) *p)) {
		if (is_seconds)
			return 1000000UL;
		else
			return 1;
	}

	c = strdup(p);
	for (i = 0; i < strlen(c); i++)
		c[i] = tolower((unsigned char)c[i]);

	if (!strncmp("us", c, 2) || !strncmp("usec", c, 4))
		mult = 1;
	else if (!strncmp("ms", c, 2) || !strncmp("msec", c, 4))
		mult = 1000;
	else if (!strcmp("s", c))
		mult = 1000000;
	else if (!strcmp("m", c))
		mult = 60 * 1000000UL;
	else if (!strcmp("h", c))
		mult = 60 * 60 * 1000000UL;
	else if (!strcmp("d", c))
		mult = 24 * 60 * 60 * 1000000ULL;

	free(c);
	return mult;
}

static int is_separator(char c)
{
	switch (c) {
	case ':':
	case '-':
	case ',':
	case '/':
		return 1;
	default:
		return 0;
	}
}

static unsigned long long __get_mult_bytes(const char *p, void *data,
					   int *percent)
{
	unsigned int kb_base = fio_get_kb_base(data);
	unsigned long long ret = 1;
	unsigned int i, pow = 0, mult = kb_base;
	char *c;

	if (!p)
		return 1;

	c = strdup(p);

	for (i = 0; i < strlen(c); i++) {
		c[i] = tolower((unsigned char)c[i]);
		if (is_separator(c[i])) {
			c[i] = '\0';
			break;
		}
	}

	/* If kb_base is 1000, use true units.
	 * If kb_base is 1024, use opposite units.
	 */
	if (!strncmp("pib", c, 3)) {
		pow = 5;
		if (kb_base == 1000)
			mult = 1024;
		else if (kb_base == 1024)
			mult = 1000;
	} else if (!strncmp("tib", c, 3)) {
		pow = 4;
		if (kb_base == 1000)
			mult = 1024;
		else if (kb_base == 1024)
			mult = 1000;
	} else if (!strncmp("gib", c, 3)) {
		pow = 3;
		if (kb_base == 1000)
			mult = 1024;
		else if (kb_base == 1024)
			mult = 1000;
	} else if (!strncmp("mib", c, 3)) {
		pow = 2;
		if (kb_base == 1000)
			mult = 1024;
		else if (kb_base == 1024)
			mult = 1000;
	} else if (!strncmp("kib", c, 3)) {
		pow = 1;
		if (kb_base == 1000)
			mult = 1024;
		else if (kb_base == 1024)
			mult = 1000;
	} else if (!strncmp("p", c, 1) || !strncmp("pb", c, 2)) {
		pow = 5;
	} else if (!strncmp("t", c, 1) || !strncmp("tb", c, 2)) {
		pow = 4;
	} else if (!strncmp("g", c, 1) || !strncmp("gb", c, 2)) {
		pow = 3;
	} else if (!strncmp("m", c, 1) || !strncmp("mb", c, 2)) {
		pow = 2;
	} else if (!strncmp("k", c, 1) || !strncmp("kb", c, 2)) {
		pow = 1;
	} else if (!strncmp("%", c, 1)) {
		*percent = 1;
		free(c);
		return ret;
	}

	while (pow--)
		ret *= (unsigned long long) mult;

	free(c);
	return ret;
}

static unsigned long long get_mult_bytes(const char *str, int len, void *data,
					 int *percent)
{
	const char *p = str;
	int digit_seen = 0;

	if (len < 2)
		return __get_mult_bytes(str, data, percent);

	/*
	 * Go forward until we hit a non-digit, or +/- sign
	 */
	while ((p - str) <= len) {
		if (!isdigit((int) *p) &&
		    (((*p != '+') && (*p != '-')) || digit_seen))
			break;
		digit_seen |= isdigit((int) *p);
		p++;
	}

	if (!isalpha((int) *p) && (*p != '%'))
		p = NULL;

	return __get_mult_bytes(p, data, percent);
}

extern int evaluate_arithmetic_expression(const char *buffer, long long *ival,
					  double *dval, double implied_units,
					  int is_time);

/*
 * Convert string into a floating number. Return 1 for success and 0 otherwise.
 */
int str_to_float(const char *str, double *val, int is_time)
{
#ifdef CONFIG_ARITHMETIC
	int rc;
	long long ival;
	double dval;

	if (str[0] == '(') {
		rc = evaluate_arithmetic_expression(str, &ival, &dval, 1.0, is_time);
		if (!rc) {
			*val = dval;
			return 1;
		}
	}
#endif
	return 1 == sscanf(str, "%lf", val);
}

/*
 * convert string into decimal value, noting any size suffix
 */
int str_to_decimal(const char *str, long long *val, int kilo, void *data,
		   int is_seconds, int is_time)
{
	int len, base;
	int rc = 1;
#ifdef CONFIG_ARITHMETIC
	long long ival;
	double dval;
	double implied_units = 1.0;
#endif

	len = strlen(str);
	if (!len)
		return 1;

#ifdef CONFIG_ARITHMETIC
	if (is_seconds)
		implied_units = 1000000.0;
	if (str[0] == '(')
		rc = evaluate_arithmetic_expression(str, &ival, &dval, implied_units, is_time);
	if (str[0] == '(' && !rc) {
		if (!kilo && is_seconds)
			*val = ival / 1000000LL;
		else
			*val = ival;
	}
#endif

	if (rc == 1) {
		if (strstr(str, "0x") || strstr(str, "0X"))
			base = 16;
		else
			base = 10;

		*val = strtoll(str, NULL, base);
		if (*val == LONG_MAX && errno == ERANGE)
			return 1;
	}

	if (kilo) {
		unsigned long long mult;
		int perc = 0;

		mult = get_mult_bytes(str, len, data, &perc);
		if (perc)
			*val = -1ULL - *val;
		else
			*val *= mult;
	} else
		*val *= get_mult_time(str, len, is_seconds);

	return 0;
}

int check_str_bytes(const char *p, long long *val, void *data)
{
	return str_to_decimal(p, val, 1, data, 0, 0);
}

int check_str_time(const char *p, long long *val, int is_seconds)
{
	return str_to_decimal(p, val, 0, NULL, is_seconds, 1);
}

void strip_blank_front(char **p)
{
	char *s = *p;

	if (!strlen(s))
		return;
	while (isspace((int) *s))
		s++;

	*p = s;
}

void strip_blank_end(char *p)
{
	char *start = p, *s;

	if (!strlen(p))
		return;

	s = strchr(p, ';');
	if (s)
		*s = '\0';
	s = strchr(p, '#');
	if (s)
		*s = '\0';
	if (s)
		p = s;

	s = p + strlen(p);
	while ((isspace((int) *s) || iscntrl((int) *s)) && (s > start))
		s--;

	*(s + 1) = '\0';
}

static int check_range_bytes(const char *str, long long *val, void *data)
{
	long long __val;

	if (!str_to_decimal(str, &__val, 1, data, 0, 0)) {
		*val = __val;
		return 0;
	}

	return 1;
}

static int check_int(const char *p, int *val)
{
	if (!strlen(p))
		return 1;
	if (strstr(p, "0x") || strstr(p, "0X")) {
		if (sscanf(p, "%x", val) == 1)
			return 0;
	} else {
		if (sscanf(p, "%u", val) == 1)
			return 0;
	}

	return 1;
}

static size_t opt_len(const char *str)
{
	char *postfix;

	postfix = strchr(str, ':');
	if (!postfix)
		return strlen(str);

	return (int)(postfix - str);
}

static int str_match_len(const struct value_pair *vp, const char *str)
{
	return max(strlen(vp->ival), opt_len(str));
}

#define val_store(ptr, val, off, or, data, o)		\
	do {						\
		ptr = td_var((data), (o), (off));	\
		if ((or))				\
			*ptr |= (val);			\
		else					\
			*ptr = (val);			\
	} while (0)

static const char *opt_type_name(const struct fio_option *o)
{
	compiletime_assert(ARRAY_SIZE(opt_type_names) - 1 == FIO_OPT_UNSUPPORTED,
				"opt_type_names[] index");

	if (o->type <= FIO_OPT_UNSUPPORTED)
		return opt_type_names[o->type];

	return "OPT_UNKNOWN?";
}

static bool val_too_large(const struct fio_option *o, unsigned long long val,
			  bool is_uint)
{
	if (!o->maxval)
		return false;

	if (is_uint) {
		if ((int) val < 0)
			return (int) val > (int) o->maxval;
		return (unsigned int) val > o->maxval;
	}

	return val > o->maxval;
}

static bool val_too_small(const struct fio_option *o, unsigned long long val,
			  bool is_uint)
{
	if (!o->minval)
		return false;

	if (is_uint)
		return (int) val < o->minval;

	return val < o->minval;
}

static int __handle_option(const struct fio_option *o, const char *ptr,
			   void *data, int first, int more, int curr)
{
	int il=0, *ilp;
	fio_fp64_t *flp;
	long long ull, *ullp;
	long ul2;
	long long ull1, ull2;
	double uf;
	char **cp = NULL;
	int ret = 0, is_time = 0;
	const struct value_pair *vp;
	struct value_pair posval[PARSE_MAX_VP];
	int i, all_skipped = 1;

	dprint(FD_PARSE, "__handle_option=%s, type=%s, ptr=%s\n", o->name,
							opt_type_name(o), ptr);

	if (!ptr && o->type != FIO_OPT_STR_SET && o->type != FIO_OPT_STR) {
		log_err("Option %s requires an argument\n", o->name);
		return 1;
	}

	switch (o->type) {
	case FIO_OPT_STR:
	case FIO_OPT_STR_ULL:
	case FIO_OPT_STR_MULTI: {
		fio_opt_str_fn *fn = o->cb;

		posval_sort(o, posval);

		ret = 1;
		for (i = 0; i < PARSE_MAX_VP; i++) {
			vp = &posval[i];
			if (!vp->ival || vp->ival[0] == '\0')
				continue;
			all_skipped = 0;
			if (!ptr)
				break;
			if (!strncmp(vp->ival, ptr, str_match_len(vp, ptr))) {
				ret = 0;
				if (!o->off1)
					continue;
				if (o->type == FIO_OPT_STR_ULL)
					val_store(ullp, vp->oval, o->off1, vp->orval, data, o);
				else
					val_store(ilp, vp->oval, o->off1, vp->orval, data, o);
				continue;
			}
		}

		if (ret && !all_skipped)
			show_option_values(o);
		else if (fn)
			ret = fn(data, ptr);
		break;
	}
	case FIO_OPT_STR_VAL_TIME:
		is_time = 1;
		/* fall through */
	case FIO_OPT_ULL:
	case FIO_OPT_INT:
	case FIO_OPT_STR_VAL: {
		fio_opt_str_val_fn *fn = o->cb;
		char tmp[128], *p;

		if (!is_time && o->is_time)
			is_time = o->is_time;

		tmp[sizeof(tmp) - 1] = '\0';
		strncpy(tmp, ptr, sizeof(tmp) - 1);
		p = strchr(tmp, ',');
		if (p)
			*p = '\0';

		if (is_time)
			ret = check_str_time(tmp, &ull, o->is_seconds);
		else
			ret = check_str_bytes(tmp, &ull, data);

		dprint(FD_PARSE, "  ret=%d, out=%llu\n", ret, ull);

		if (ret)
			break;
		if (o->pow2 && !is_power_of_2(ull)) {
			log_err("%s: must be a power-of-2\n", o->name);
			return 1;
		}

		if (val_too_large(o, ull, o->type == FIO_OPT_INT)) {
			log_err("%s: max value out of range: %llu"
				" (%llu max)\n", o->name, ull, o->maxval);
			return 1;
		}
		if (val_too_small(o, ull, o->type == FIO_OPT_INT)) {
			log_err("%s: min value out of range: %lld"
				" (%d min)\n", o->name, ull, o->minval);
			return 1;
		}
		if (o->posval[0].ival) {
			posval_sort(o, posval);

			ret = 1;
			for (i = 0; i < PARSE_MAX_VP; i++) {
				vp = &posval[i];
				if (!vp->ival || vp->ival[0] == '\0')
					continue;
				if (vp->oval == ull) {
					ret = 0;
					break;
				}
			}
			if (ret) {
				log_err("fio: value %llu not allowed:\n", ull);
				show_option_values(o);
				return 1;
			}
		}

		if (fn)
			ret = fn(data, &ull);
		else {
			if (o->type == FIO_OPT_INT) {
				if (first)
					val_store(ilp, ull, o->off1, 0, data, o);
				if (curr == 1) {
					if (o->off2)
						val_store(ilp, ull, o->off2, 0, data, o);
				}
				if (curr == 2) {
					if (o->off3)
						val_store(ilp, ull, o->off3, 0, data, o);
				}
				if (!more) {
					if (curr < 1) {
						if (o->off2)
							val_store(ilp, ull, o->off2, 0, data, o);
					}
					if (curr < 2) {
						if (o->off3)
							val_store(ilp, ull, o->off3, 0, data, o);
					}
				}
			} else if (o->type == FIO_OPT_ULL) {
				if (first)
					val_store(ullp, ull, o->off1, 0, data, o);
				if (curr == 1) {
					if (o->off2)
						val_store(ullp, ull, o->off2, 0, data, o);
				}
				if (curr == 2) {
					if (o->off3)
						val_store(ullp, ull, o->off3, 0, data, o);
				}
				if (!more) {
					if (curr < 1) {
						if (o->off2)
							val_store(ullp, ull, o->off2, 0, data, o);
					}
					if (curr < 2) {
						if (o->off3)
							val_store(ullp, ull, o->off3, 0, data, o);
					}
				}
			} else {
				if (first)
					val_store(ullp, ull, o->off1, 0, data, o);
				if (!more) {
					if (o->off2)
						val_store(ullp, ull, o->off2, 0, data, o);
				}
			}
		}
		break;
	}
	case FIO_OPT_FLOAT_LIST: {
		char *cp2;

		if (first) {
			/*
			** Initialize precision to 0 and zero out list
			** in case specified list is shorter than default
			*/
			if (o->off2) {
				ul2 = 0;
				ilp = td_var(data, o, o->off2);
				*ilp = ul2;
			}

			flp = td_var(data, o, o->off1);
			for(i = 0; i < o->maxlen; i++)
				flp[i].u.f = 0.0;
		}
		if (curr >= o->maxlen) {
			log_err("the list exceeding max length %d\n",
					o->maxlen);
			return 1;
		}
		if (!str_to_float(ptr, &uf, 0)) { /* this breaks if we ever have lists of times */
			log_err("not a floating point value: %s\n", ptr);
			return 1;
		}
		if (o->minfp || o->maxfp) {
			if (uf > o->maxfp) {
				log_err("value out of range: %f"
					" (range max: %f)\n", uf, o->maxfp);
				return 1;
			}
			if (uf < o->minfp) {
				log_err("value out of range: %f"
					" (range min: %f)\n", uf, o->minfp);
				return 1;
			}
		}

		flp = td_var(data, o, o->off1);
		flp[curr].u.f = uf;

		dprint(FD_PARSE, "  out=%f\n", uf);

		/*
		** Calculate precision for output by counting
		** number of digits after period. Find first
		** period in entire remaining list each time
		*/
		cp2 = strchr(ptr, '.');
		if (cp2 != NULL) {
			int len = 0;

			while (*++cp2 != '\0' && *cp2 >= '0' && *cp2 <= '9')
				len++;

			if (o->off2) {
				ilp = td_var(data, o, o->off2);
				if (len > *ilp)
					*ilp = len;
			}
		}

		break;
	}
	case FIO_OPT_STR_STORE: {
		fio_opt_str_fn *fn = o->cb;

		if (!strlen(ptr))
			return 1;

		if (o->off1) {
			cp = td_var(data, o, o->off1);
			*cp = strdup(ptr);
		}

		if (fn)
			ret = fn(data, ptr);
		else if (o->posval[0].ival) {
			posval_sort(o, posval);

			ret = 1;
			for (i = 0; i < PARSE_MAX_VP; i++) {
				vp = &posval[i];
				if (!vp->ival || vp->ival[0] == '\0' || !cp)
					continue;
				all_skipped = 0;
				if (!strncmp(vp->ival, ptr, str_match_len(vp, ptr))) {
					char *rest;

					ret = 0;
					if (vp->cb)
						fn = vp->cb;
					rest = strstr(*cp ?: ptr, ":");
					if (rest) {
						if (*cp)
							*rest = '\0';
						ptr = rest + 1;
					} else
						ptr = NULL;
					break;
				}
			}
		}

		if (!all_skipped) {
			if (ret && !*cp)
				show_option_values(o);
			else if (ret && *cp)
				ret = 0;
			else if (fn && ptr)
				ret = fn(data, ptr);
		}

		break;
	}
	case FIO_OPT_RANGE: {
		char tmp[128];
		char *p1, *p2;

		tmp[sizeof(tmp) - 1] = '\0';
		strncpy(tmp, ptr, sizeof(tmp) - 1);

		/* Handle bsrange with separate read,write values: */
		p1 = strchr(tmp, ',');
		if (p1)
			*p1 = '\0';

		p1 = strchr(tmp, '-');
		if (!p1) {
			p1 = strchr(tmp, ':');
			if (!p1) {
				ret = 1;
				break;
			}
		}

		p2 = p1 + 1;
		*p1 = '\0';
		p1 = tmp;

		ret = 1;
		if (!check_range_bytes(p1, &ull1, data) &&
			!check_range_bytes(p2, &ull2, data)) {
			ret = 0;
			if (ull1 > ull2) {
				unsigned long long foo = ull1;

				ull1 = ull2;
				ull2 = foo;
			}

			if (first) {
				val_store(ullp, ull1, o->off1, 0, data, o);
				val_store(ullp, ull2, o->off2, 0, data, o);
			}
			if (curr == 1) {
				if (o->off3 && o->off4) {
					val_store(ullp, ull1, o->off3, 0, data, o);
					val_store(ullp, ull2, o->off4, 0, data, o);
				}
			}
			if (curr == 2) {
				if (o->off5 && o->off6) {
					val_store(ullp, ull1, o->off5, 0, data, o);
					val_store(ullp, ull2, o->off6, 0, data, o);
				}
			}
			if (!more) {
				if (curr < 1) {
					if (o->off3 && o->off4) {
						val_store(ullp, ull1, o->off3, 0, data, o);
						val_store(ullp, ull2, o->off4, 0, data, o);
					}
				}
				if (curr < 2) {
					if (o->off5 && o->off6) {
						val_store(ullp, ull1, o->off5, 0, data, o);
						val_store(ullp, ull2, o->off6, 0, data, o);
					}
				}
			}
		}

		break;
	}
	case FIO_OPT_BOOL:
	case FIO_OPT_STR_SET: {
		fio_opt_int_fn *fn = o->cb;

		if (ptr)
			ret = check_int(ptr, &il);
		else if (o->type == FIO_OPT_BOOL)
			ret = 1;
		else
			il = 1;

		dprint(FD_PARSE, "  ret=%d, out=%d\n", ret, il);

		if (ret)
			break;

		if (o->maxval && il > (int) o->maxval) {
			log_err("max value out of range: %d (%llu max)\n",
								il, o->maxval);
			return 1;
		}
		if (o->minval && il < o->minval) {
			log_err("min value out of range: %d (%d min)\n",
								il, o->minval);
			return 1;
		}

		if (o->neg)
			il = !il;

		if (fn)
			ret = fn(data, &il);
		else {
			if (first)
				val_store(ilp, il, o->off1, 0, data, o);
			if (!more) {
				if (o->off2)
					val_store(ilp, il, o->off2, 0, data, o);
			}
		}
		break;
	}
	case FIO_OPT_DEPRECATED:
		ret = 1;
		/* fall through */
	case FIO_OPT_SOFT_DEPRECATED:
		log_info("Option %s is deprecated\n", o->name);
		break;
	default:
		log_err("Bad option type %u\n", o->type);
		ret = 1;
	}

	if (ret)
		return ret;

	if (o->verify) {
		ret = o->verify(o, data);
		if (ret) {
			log_err("Correct format for offending option\n");
			log_err("%20s: %s\n", o->name, o->help);
			show_option_help(o, 1);
		}
	}

	return ret;
}

static int handle_option(const struct fio_option *o, const char *__ptr,
			 void *data)
{
	char *o_ptr, *ptr, *ptr2;
	int ret, done;

	dprint(FD_PARSE, "handle_option=%s, ptr=%s\n", o->name, __ptr);

	o_ptr = ptr = NULL;
	if (__ptr)
		o_ptr = ptr = strdup(__ptr);

	/*
	 * See if we have another set of parameters, hidden after a comma.
	 * Do this before parsing this round, to check if we should
	 * copy set 1 options to set 2.
	 */
	done = 0;
	ret = 1;
	do {
		int __ret;

		ptr2 = NULL;
		if (ptr &&
		    (o->type != FIO_OPT_STR_STORE) &&
		    (o->type != FIO_OPT_STR) &&
		    (o->type != FIO_OPT_STR_ULL) &&
		    (o->type != FIO_OPT_FLOAT_LIST)) {
			ptr2 = strchr(ptr, ',');
			if (ptr2 && *(ptr2 + 1) == '\0')
				*ptr2 = '\0';
			if (o->type != FIO_OPT_STR_MULTI && o->type != FIO_OPT_RANGE) {
				if (!ptr2)
					ptr2 = strchr(ptr, ':');
				if (!ptr2)
					ptr2 = strchr(ptr, '-');
			}
		} else if (ptr && o->type == FIO_OPT_FLOAT_LIST) {
			ptr2 = strchr(ptr, ':');
		}

		/*
		 * Don't return early if parsing the first option fails - if
		 * we are doing multiple arguments, we can allow the first one
		 * being empty.
		 */
		__ret = __handle_option(o, ptr, data, !done, !!ptr2, done);
		if (ret)
			ret = __ret;

		if (!ptr2)
			break;

		ptr = ptr2 + 1;
		done++;
	} while (1);

	if (o_ptr)
		free(o_ptr);
	return ret;
}

struct fio_option *find_option(struct fio_option *options, const char *opt)
{
	struct fio_option *o;

	for (o = &options[0]; o->name; o++) {
		if (!o_match(o, opt))
			continue;
		if (o->type == FIO_OPT_UNSUPPORTED) {
			log_err("Option <%s>: %s\n", o->name, o->help);
			continue;
		}

		return o;
	}

	return NULL;
}

const struct fio_option *
find_option_c(const struct fio_option *options, const char *opt)
{
	return find_option((struct fio_option *)options, opt);
}

static const struct fio_option *
get_option(char *opt, const struct fio_option *options, char **post)
{
	const struct fio_option *o;
	char *ret;

	ret = strchr(opt, '=');
	if (ret) {
		*post = ret;
		*ret = '\0';
		ret = opt;
		(*post)++;
		strip_blank_end(ret);
		o = find_option_c(options, ret);
	} else {
		o = find_option_c(options, opt);
		*post = NULL;
	}

	return o;
}

static int opt_cmp(const void *p1, const void *p2)
{
	const struct fio_option *o;
	char *s, *foo;
	int prio1, prio2;

	prio1 = prio2 = 0;

	if (*(char **)p1) {
		s = strdup(*((char **) p1));
		o = get_option(s, __fio_options, &foo);
		if (o)
			prio1 = o->prio;
		free(s);
	}
	if (*(char **)p2) {
		s = strdup(*((char **) p2));
		o = get_option(s, __fio_options, &foo);
		if (o)
			prio2 = o->prio;
		free(s);
	}

	return prio2 - prio1;
}

void sort_options(char **opts, const struct fio_option *options, int num_opts)
{
	__fio_options = options;
	qsort(opts, num_opts, sizeof(char *), opt_cmp);
	__fio_options = NULL;
}

static void add_to_dump_list(const struct fio_option *o,
			     struct flist_head *dump_list, const char *post)
{
	struct print_option *p;

	if (!dump_list)
		return;

	p = malloc(sizeof(*p));
	p->name = strdup(o->name);
	if (post)
		p->value = strdup(post);
	else
		p->value = NULL;

	flist_add_tail(&p->list, dump_list);
}

int parse_cmd_option(const char *opt, const char *val,
		     const struct fio_option *options, void *data,
		     struct flist_head *dump_list)
{
	const struct fio_option *o;

	o = find_option_c(options, opt);
	if (!o) {
		log_err("Bad option <%s>\n", opt);
		return 1;
	}

	if (handle_option(o, val, data)) {
		log_err("fio: failed parsing %s=%s\n", opt, val);
		return 1;
	}

	add_to_dump_list(o, dump_list, val);
	return 0;
}

int parse_option(char *opt, const char *input, const struct fio_option *options,
		 const struct fio_option **o, void *data,
		 struct flist_head *dump_list)
{
	char *post;

	if (!opt) {
		log_err("fio: failed parsing %s\n", input);
		*o = NULL;
		return 1;
	}

	*o = get_option(opt, options, &post);
	if (!*o) {
		if (post) {
			int len = strlen(opt);
			if (opt + len + 1 != post)
				memmove(opt + len + 1, post, strlen(post));
			opt[len] = '=';
		}
		return 1;
	}

	if (handle_option(*o, post, data)) {
		log_err("fio: failed parsing %s\n", input);
		return 1;
	}

	add_to_dump_list(*o, dump_list, post);
	return 0;
}

/*
 * Option match, levenshtein distance. Handy for not quite remembering what
 * the option name is.
 */
int string_distance(const char *s1, const char *s2)
{
	unsigned int s1_len = strlen(s1);
	unsigned int s2_len = strlen(s2);
	unsigned int *p, *q, *r;
	unsigned int i, j;

	p = malloc(sizeof(unsigned int) * (s2_len + 1));
	q = malloc(sizeof(unsigned int) * (s2_len + 1));

	p[0] = 0;
	for (i = 1; i <= s2_len; i++)
		p[i] = p[i - 1] + 1;

	for (i = 1; i <= s1_len; i++) {
		q[0] = p[0] + 1;
		for (j = 1; j <= s2_len; j++) {
			unsigned int sub = p[j - 1];
			unsigned int pmin;

			if (s1[i - 1] != s2[j - 1])
				sub++;

			pmin = min(q[j - 1] + 1, sub);
			q[j] = min(p[j] + 1, pmin);
		}
		r = p;
		p = q;
		q = r;
	}

	i = p[s2_len];
	free(p);
	free(q);
	return i;
}

/*
 * Make a guess of whether the distance from 's1' is significant enough
 * to warrant printing the guess. We set this to a 1/2 match.
 */
int string_distance_ok(const char *opt, int distance)
{
	size_t len;

	len = strlen(opt);
	len = (len + 1) / 2;
	return distance <= len;
}

static const struct fio_option *find_child(const struct fio_option *options,
					   const struct fio_option *o)
{
	const struct fio_option *__o;

	for (__o = options + 1; __o->name; __o++)
		if (__o->parent && !strcmp(__o->parent, o->name))
			return __o;

	return NULL;
}

static void __print_option(const struct fio_option *o,
			   const struct fio_option *org,
			   int level)
{
	char name[256], *p;
	int depth;

	if (!o)
		return;

	p = name;
	depth = level;
	while (depth--)
		p += sprintf(p, "%s", "  ");

	sprintf(p, "%s", o->name);

	log_info("%-24s: %s\n", name, o->help);
}

static void print_option(const struct fio_option *o)
{
	const struct fio_option *parent;
	const struct fio_option *__o;
	unsigned int printed;
	unsigned int level;

	__print_option(o, NULL, 0);
	parent = o;
	level = 0;
	do {
		level++;
		printed = 0;

		while ((__o = find_child(o, parent)) != NULL) {
			__print_option(__o, o, level);
			o = __o;
			printed++;
		}

		parent = o;
	} while (printed);
}

int show_cmd_help(const struct fio_option *options, const char *name)
{
	const struct fio_option *o, *closest;
	unsigned int best_dist = -1U;
	int found = 0;
	int show_all = 0;

	if (!name || !strcmp(name, "all"))
		show_all = 1;

	closest = NULL;
	best_dist = -1;
	for (o = &options[0]; o->name; o++) {
		int match = 0;

		if (o->type == FIO_OPT_DEPRECATED ||
		    o->type == FIO_OPT_SOFT_DEPRECATED)
			continue;
		if (!exec_profile && o->prof_name)
			continue;
		if (exec_profile && !(o->prof_name && !strcmp(exec_profile, o->prof_name)))
			continue;

		if (name) {
			if (!strcmp(name, o->name) ||
			    (o->alias && !strcmp(name, o->alias)))
				match = 1;
			else {
				unsigned int dist;

				dist = string_distance(name, o->name);
				if (dist < best_dist) {
					best_dist = dist;
					closest = o;
				}
			}
		}

		if (show_all || match) {
			found = 1;
			if (match)
				log_info("%20s: %s\n", o->name, o->help);
			if (show_all) {
				if (!o->parent)
					print_option(o);
				continue;
			}
		}

		if (!match)
			continue;

		show_option_help(o, 0);
	}

	if (found)
		return 0;

	log_err("No such command: %s", name);

	/*
	 * Only print an appropriately close option, one where the edit
	 * distance isn't too big. Otherwise we get crazy matches.
	 */
	if (closest && best_dist < 3) {
		log_info(" - showing closest match\n");
		log_info("%20s: %s\n", closest->name, closest->help);
		show_option_help(closest, 0);
	} else
		log_info("\n");

	return 1;
}

/*
 * Handle parsing of default parameters.
 */
void fill_default_options(void *data, const struct fio_option *options)
{
	const struct fio_option *o;

	dprint(FD_PARSE, "filling default options\n");

	for (o = &options[0]; o->name; o++)
		if (o->def)
			handle_option(o, o->def, data);
}

static void option_init(struct fio_option *o)
{
	if (o->type == FIO_OPT_DEPRECATED || o->type == FIO_OPT_UNSUPPORTED ||
	    o->type == FIO_OPT_SOFT_DEPRECATED)
		return;
	if (o->name && !o->lname)
		log_err("Option %s: missing long option name\n", o->name);
	if (o->type == FIO_OPT_BOOL) {
		o->minval = 0;
		o->maxval = 1;
	}
	if (o->type == FIO_OPT_INT) {
		if (!o->maxval)
			o->maxval = UINT_MAX;
	}
	if (o->type == FIO_OPT_ULL) {
		if (!o->maxval)
			o->maxval = ULLONG_MAX;
	}
	if (o->type == FIO_OPT_STR_SET && o->def && !o->no_warn_def) {
		log_err("Option %s: string set option with"
				" default will always be true\n", o->name);
	}
	if (!o->cb && !o->off1)
		log_err("Option %s: neither cb nor offset given\n", o->name);
	if (!o->category) {
		log_info("Option %s: no category defined. Setting to misc\n", o->name);
		o->category = FIO_OPT_C_GENERAL;
		o->group = FIO_OPT_G_INVALID;
	}
}

/*
 * Sanitize the options structure. For now it just sets min/max for bool
 * values and whether both callback and offsets are given.
 */
void options_init(struct fio_option *options)
{
	struct fio_option *o;

	dprint(FD_PARSE, "init options\n");

	for (o = &options[0]; o->name; o++) {
		option_init(o);
		if (o->inverse)
			o->inv_opt = find_option(options, o->inverse);
	}
}

void options_mem_dupe(const struct fio_option *options, void *data)
{
	const struct fio_option *o;
	char **ptr;

	dprint(FD_PARSE, "dup options\n");

	for (o = &options[0]; o->name; o++) {
		if (o->type != FIO_OPT_STR_STORE)
			continue;

		ptr = td_var(data, o, o->off1);
		if (*ptr)
			*ptr = strdup(*ptr);
	}
}

void options_free(const struct fio_option *options, void *data)
{
	const struct fio_option *o;
	char **ptr;

	dprint(FD_PARSE, "free options\n");

	for (o = &options[0]; o->name; o++) {
		if (o->type != FIO_OPT_STR_STORE || !o->off1 || o->no_free)
			continue;

		ptr = td_var(data, o, o->off1);
		if (*ptr) {
			free(*ptr);
			*ptr = NULL;
		}
	}
}
