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

#include "parse.h"
#include "debug.h"
#include "options.h"
#include "minmax.h"

static struct fio_option *fio_options;
extern unsigned int fio_get_kb_base(void *);

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(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(struct fio_option *o,
				int (*logger)(const char *format, ...))
{
	if (o->type == FIO_OPT_FLOAT_LIST){
		if (isnan(o->minfp) && isnan(o->maxfp))
			return;

		logger("%20s: min=%f", "range", o->minfp);
		if (!isnan(o->maxfp))
			logger(", max=%f", o->maxfp);
		logger("\n");
	} else {
		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(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(struct fio_option *o, int is_err)
{
	const char *typehelp[] = {
		"invalid",
		"string (opt=bla)",
		"string (opt=bla)",
		"string with possible k/m/g postfix (opt=4k)",
		"string with time postfix (opt=10s)",
		"string (opt=bla)",
		"string with dual range (opt=1k-4k,4k-8k)",
		"integer value (opt=100)",
		"boolean value (opt=1)",
		"list of floating point values separated by ':' (opt=5.9:7.8)",
		"no argument (opt)",
		"deprecated",
	};
	int (*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 get_mult_time(char c)
{
	switch (c) {
	case 'm':
	case 'M':
		return 60;
	case 'h':
	case 'H':
		return 60 * 60;
	case 'd':
	case 'D':
		return 24 * 60 * 60;
	default:
		return 1;
	}
}

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(c[i]);

	if (!strcmp("pib", c)) {
		pow = 5;
		mult = 1000;
	} else if (!strcmp("tib", c)) {
		pow = 4;
		mult = 1000;
	} else if (!strcmp("gib", c)) {
		pow = 3;
		mult = 1000;
	} else if (!strcmp("mib", c)) {
		pow = 2;
		mult = 1000;
	} else if (!strcmp("kib", c)) {
		pow = 1;
		mult = 1000;
	} else if (!strcmp("p", c) || !strcmp("pb", c))
		pow = 5;
	else if (!strcmp("t", c) || !strcmp("tb", c))
		pow = 4;
	else if (!strcmp("g", c) || !strcmp("gb", c))
		pow = 3;
	else if (!strcmp("m", c) || !strcmp("mb", c))
		pow = 2;
	else if (!strcmp("k", c) || !strcmp("kb", c))
		pow = 1;
	else if (!strcmp("%", c)) {
		*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);
}

/*
 * Convert string into a floating number. Return 1 for success and 0 otherwise.
 */
int str_to_float(const char *str, double *val)
{
	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 len, base;

	len = strlen(str);
	if (!len)
		return 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 - 1]);

	return 0;
}

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

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

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 *val, void *data)
{
	long long __val;

	if (!str_to_decimal(str, &__val, 1, data)) {
		*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 int opt_len(const char *str)
{
	char *postfix;

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

	return (int)(postfix - str);
}

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

static int __handle_option(struct fio_option *o, const char *ptr, void *data,
			   int first, int more, int curr)
{
	int il, *ilp;
	double* flp;
	long long ull, *ullp;
	long ul1, ul2;
	double uf;
	char **cp;
	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=%d, ptr=%s\n", o->name,
							o->type, 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_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 (!strncmp(vp->ival, ptr, opt_len(ptr))) {
				ret = 0;
				if (o->roff1) {
					if (vp->or)
						*(unsigned int *) o->roff1 |= vp->oval;
					else
						*(unsigned int *) o->roff1 = vp->oval;
				} else {
					if (!o->off1)
						continue;
					val_store(ilp, vp->oval, o->off1, vp->or, data);
				}
				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;
	case FIO_OPT_INT:
	case FIO_OPT_STR_VAL: {
		fio_opt_str_val_fn *fn = o->cb;
		char tmp[128], *p;

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

		if (is_time)
			ret = check_str_time(tmp, &ull);
		else
			ret = check_str_bytes(tmp, &ull, data);

		if (ret)
			break;

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

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

		if (first) {
			ul2 = 1;
			ilp = td_var(data, o->off2);
			*ilp = ul2;
		}
		if (curr >= o->maxlen) {
			log_err("the list exceeding max length %d\n",
					o->maxlen);
			return 1;
		}
		if (!str_to_float(ptr, &uf)){
			log_err("not a floating point value: %s\n", ptr);
			return 1;
		}
		if (!isnan(o->maxfp) && uf > o->maxfp) {
			log_err("value out of range: %f"
				" (range max: %f)\n", uf, o->maxfp);
			return 1;
		}
		if (!isnan(o->minfp) && uf < o->minfp) {
			log_err("value out of range: %f"
				" (range min: %f)\n", uf, o->minfp);
			return 1;
		}

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

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

		if (o->roff1 || o->off1) {
			if (o->roff1)
				cp = (char **) o->roff1;
			else if (o->off1)
				cp = td_var(data, o->off1);

			*cp = strdup(ptr);
		} else {
			cp = NULL;
		}

		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')
					continue;
				all_skipped = 0;
				if (!strncmp(vp->ival, ptr, opt_len(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;

		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, &ul1, data) &&
		    !check_range_bytes(p2, &ul2, data)) {
			ret = 0;
			if (ul1 > ul2) {
				unsigned long foo = ul1;

				ul1 = ul2;
				ul2 = foo;
			}

			if (first) {
				if (o->roff1)
					*(unsigned int *) o->roff1 = ul1;
				else
					val_store(ilp, ul1, o->off1, 0, data);
				if (o->roff2)
					*(unsigned int *) o->roff2 = ul2;
				else
					val_store(ilp, ul2, o->off2, 0, data);
			}
			if (curr == 1) {
				if (o->roff3 && o->roff4) {
					*(unsigned int *) o->roff3 = ul1;
					*(unsigned int *) o->roff4 = ul2;
				} else if (o->off3 && o->off4) {
					val_store(ilp, ul1, o->off3, 0, data);
					val_store(ilp, ul2, o->off4, 0, data);
				}
			}
			if (curr == 2) {
				if (o->roff5 && o->roff6) {
					*(unsigned int *) o->roff5 = ul1;
					*(unsigned int *) o->roff6 = ul2;
				} else if (o->off5 && o->off6) {
					val_store(ilp, ul1, o->off5, 0, data);
					val_store(ilp, ul2, o->off6, 0, data);
				}
			}
			if (!more) {
				if (curr < 1) {
					if (o->roff3 && o->roff4) {
						*(unsigned int *) o->roff3 = ul1;
						*(unsigned int *) o->roff4 = ul2;
					} else if (o->off3 && o->off4) {
						val_store(ilp, ul1, o->off3, 0, data);
						val_store(ilp, ul2, o->off4, 0, data);
					}
				}
				if (curr < 2) {
					if (o->roff5 && o->roff6) {
						*(unsigned int *) o->roff5 = ul1;
						*(unsigned int *) o->roff6 = ul2;
					} else if (o->off5 && o->off6) {
						val_store(ilp, ul1, o->off5, 0, data);
						val_store(ilp, ul2, o->off6, 0, data);
					}
				}
			}
		}

		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;

		if (ret)
			break;

		if (o->maxval && il > (int) o->maxval) {
			log_err("max value out of range: %d (%d 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) {
				if (o->roff1)
					*(unsigned int *)o->roff1 = il;
				else
					val_store(ilp, il, o->off1, 0, data);
			}
			if (!more) {
				if (o->roff2)
					*(unsigned int *) o->roff2 = il;
				else if (o->off2)
					val_store(ilp, il, o->off2, 0, data);
			}
		}
		break;
	}
	case FIO_OPT_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(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_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;
}

static struct fio_option *get_option(char *opt,
				     struct fio_option *options, char **post)
{
	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(options, ret);
	} else {
		o = find_option(options, opt);
		*post = NULL;
	}

	return o;
}

static int opt_cmp(const void *p1, const void *p2)
{
	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, struct fio_option *options, int num_opts)
{
	fio_options = options;
	qsort(opts, num_opts, sizeof(char *), opt_cmp);
	fio_options = NULL;
}

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

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

	if (!handle_option(o, val, data))
		return 0;

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

int parse_option(char *opt, const char *input,
		 struct fio_option *options, struct fio_option **o, void *data)
{
	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)) {
		return 0;
	}

	log_err("fio: failed parsing %s\n", input);
	return 1;
}

/*
 * Option match, levenshtein distance. Handy for not quite remembering what
 * the option name is.
 */
static 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];

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

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

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

static struct fio_option *find_child(struct fio_option *options,
				     struct fio_option *o)
{
	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(struct fio_option *o, struct fio_option *org,
			   int level)
{
	char name[256], *p;
	int depth;

	if (!o)
		return;
	if (!org)
		org = o;

	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(struct fio_option *o)
{
	struct fio_option *parent;
	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(struct fio_option *options, const char *name)
{
	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)
			continue;
		if (!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, struct fio_option *options)
{
	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);
}

void option_init(struct fio_option *o)
{
	if (o->type == FIO_OPT_DEPRECATED)
		return;
	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_FLOAT_LIST) {
		o->minfp = NAN;
		o->maxfp = NAN;
	}
	if (o->type == FIO_OPT_STR_SET && o->def) {
		log_err("Option %s: string set option with"
				" default will always be true\n", o->name);
	}
	if (!o->cb && (!o->off1 && !o->roff1))
		log_err("Option %s: neither cb nor offset given\n", o->name);
	if (o->type == FIO_OPT_STR || o->type == FIO_OPT_STR_STORE ||
	    o->type == FIO_OPT_STR_MULTI)
		return;
	if (o->cb && ((o->off1 || o->off2 || o->off3 || o->off4) ||
		      (o->roff1 || o->roff2 || o->roff3 || o->roff4))) {
		log_err("Option %s: both cb and offset given\n", o->name);
	}
}

/*
 * 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);
}

void options_free(struct fio_option *options, void *data)
{
	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)
			continue;

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