static opt_type check_for_long_option()

in util/windows/getopt/getopt.cpp [223:304]


static opt_type check_for_long_option(const struct option *longopts, int *longindex,
	const char* str, const char*& arg)
{
	assert(longindex);
	assert(str);

	arg = 0;

	if (!longopts)
		return opt_not_found;

	// looking for '=' in string...
	int i;
	for (i = 0; str[i] && str[i] != '='; i++);
	assert(str[i] == '=' || !str[i]);

	int len = i; // len used for detecting length of option name in string

	if (str[i] == '=' && str[i + 1]) // ok, symbol '=' detected...
		arg = str + i + 1; // set potential option name substring length

	// detecting the nearest option name to string
	int index = 1;
	const char* opt = longopts->name;

	if (!opt)
		return opt_not_found;

	int diff = string_diff(opt, str, len);
	int selected = diff >= 0 ? 0 : -1;
	bool ambiguous = false;

	while (longopts[index].name) {
		opt = longopts[index].name;

		int _diff = string_diff(opt, str, len);
		if (!_diff) {
			diff = 0;
			selected = index;
			break;
		}

		if (_diff > 0 && diff > 0)
			ambiguous = true; // detected 2 or more options which are confirms string

		else if (_diff > 0 && (_diff < diff || diff < 0)) {
			diff = _diff;
			selected = index;
		}
		index++;
	}

	if (ambiguous && diff > 0) // if detected multiple confirms and no exact match - return error
		return opt_err_ambiguous;

	if (selected >= 0) {
		if (longopts[selected].has_arg == no_argument && arg) {
			return opt_err_no_arg; // argument is not required but specified
		}
		else if (longopts[selected].has_arg == no_argument /*&& !arg*/) {
			*longindex = index;
			return opt_single; // option without argument
		}
		else if (longopts[selected].has_arg == required_argument && arg) {
			*longindex = index;
			return opt_inplace_arg;
		}
		else if (longopts[selected].has_arg == required_argument) {
			*longindex = index;
			return opt_has_arg;
		}
		else if (longopts[selected].has_arg == optional_argument && arg) {
			*longindex = index;
			return opt_inplace_arg;
		}
		else if (longopts[selected].has_arg == optional_argument) {
			*longindex = index;
			return opt_single; // option without argument
		}
	}
	return opt_not_found;
}