// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
 */

#include <sys/types.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <regex.h>

#include "internal.h"
#include "lkc.h"

struct symbol symbol_yes = {
	.name = "y",
	.type = S_TRISTATE,
	.curr = { "y", yes },
	.menus = LIST_HEAD_INIT(symbol_yes.menus),
	.flags = SYMBOL_CONST|SYMBOL_VALID,
};

struct symbol symbol_mod = {
	.name = "m",
	.type = S_TRISTATE,
	.curr = { "m", mod },
	.menus = LIST_HEAD_INIT(symbol_mod.menus),
	.flags = SYMBOL_CONST|SYMBOL_VALID,
};

struct symbol symbol_no = {
	.name = "n",
	.type = S_TRISTATE,
	.curr = { "n", no },
	.menus = LIST_HEAD_INIT(symbol_no.menus),
	.flags = SYMBOL_CONST|SYMBOL_VALID,
};

struct symbol *modules_sym;
static tristate modules_val;
static int sym_warnings;

enum symbol_type sym_get_type(const struct symbol *sym)
{
	enum symbol_type type = sym->type;

	if (type == S_TRISTATE && modules_val == no)
		type = S_BOOLEAN;
	return type;
}

const char *sym_type_name(enum symbol_type type)
{
	switch (type) {
	case S_BOOLEAN:
		return "bool";
	case S_TRISTATE:
		return "tristate";
	case S_INT:
		return "integer";
	case S_HEX:
		return "hex";
	case S_STRING:
		return "string";
	case S_UNKNOWN:
		return "unknown";
	}
	return "???";
}

/**
 * sym_get_choice_menu - get the parent choice menu if present
 *
 * @sym: a symbol pointer
 *
 * Return: a choice menu if this function is called against a choice member.
 */
struct menu *sym_get_choice_menu(const struct symbol *sym)
{
	struct menu *menu = NULL;
	struct menu *m;

	/*
	 * Choice members must have a prompt. Find a menu entry with a prompt,
	 * and assume it resides inside a choice block.
	 */
	list_for_each_entry(m, &sym->menus, link)
		if (m->prompt) {
			menu = m;
			break;
		}

	if (!menu)
		return NULL;

	do {
		menu = menu->parent;
	} while (menu && !menu->sym);

	if (menu && menu->sym && sym_is_choice(menu->sym))
		return menu;

	return NULL;
}

static struct property *sym_get_default_prop(struct symbol *sym)
{
	struct property *prop;

	for_all_defaults(sym, prop) {
		prop->visible.tri = expr_calc_value(prop->visible.expr);
		if (prop->visible.tri != no)
			return prop;
	}
	return NULL;
}

struct property *sym_get_range_prop(struct symbol *sym)
{
	struct property *prop;

	for_all_properties(sym, prop, P_RANGE) {
		prop->visible.tri = expr_calc_value(prop->visible.expr);
		if (prop->visible.tri != no)
			return prop;
	}
	return NULL;
}

static long long sym_get_range_val(struct symbol *sym, int base)
{
	sym_calc_value(sym);
	switch (sym->type) {
	case S_INT:
		base = 10;
		break;
	case S_HEX:
		base = 16;
		break;
	default:
		break;
	}
	return strtoll(sym->curr.val, NULL, base);
}

static void sym_validate_range(struct symbol *sym)
{
	struct property *prop;
	struct symbol *range_sym;
	int base;
	long long val, val2;

	switch (sym->type) {
	case S_INT:
		base = 10;
		break;
	case S_HEX:
		base = 16;
		break;
	default:
		return;
	}
	prop = sym_get_range_prop(sym);
	if (!prop)
		return;
	val = strtoll(sym->curr.val, NULL, base);
	range_sym = prop->expr->left.sym;
	val2 = sym_get_range_val(range_sym, base);
	if (val >= val2) {
		range_sym = prop->expr->right.sym;
		val2 = sym_get_range_val(range_sym, base);
		if (val <= val2)
			return;
	}
	sym->curr.val = range_sym->curr.val;
}

static void sym_set_changed(struct symbol *sym)
{
	struct menu *menu;

	list_for_each_entry(menu, &sym->menus, link)
		menu->flags |= MENU_CHANGED;
}

static void sym_set_all_changed(void)
{
	struct symbol *sym;

	for_all_symbols(sym)
		sym_set_changed(sym);
}

static void sym_calc_visibility(struct symbol *sym)
{
	struct property *prop;
	tristate tri;

	/* any prompt visible? */
	tri = no;
	for_all_prompts(sym, prop) {
		prop->visible.tri = expr_calc_value(prop->visible.expr);
		tri = EXPR_OR(tri, prop->visible.tri);
	}
	if (tri == mod && (sym->type != S_TRISTATE || modules_val == no))
		tri = yes;
	if (sym->visible != tri) {
		sym->visible = tri;
		sym_set_changed(sym);
	}
	if (sym_is_choice_value(sym))
		return;
	/* defaulting to "yes" if no explicit "depends on" are given */
	tri = yes;
	if (sym->dir_dep.expr)
		tri = expr_calc_value(sym->dir_dep.expr);
	if (tri == mod && sym_get_type(sym) == S_BOOLEAN)
		tri = yes;
	if (sym->dir_dep.tri != tri) {
		sym->dir_dep.tri = tri;
		sym_set_changed(sym);
	}
	tri = no;
	if (sym->rev_dep.expr)
		tri = expr_calc_value(sym->rev_dep.expr);
	if (tri == mod && sym_get_type(sym) == S_BOOLEAN)
		tri = yes;
	if (sym->rev_dep.tri != tri) {
		sym->rev_dep.tri = tri;
		sym_set_changed(sym);
	}
	tri = no;
	if (sym->implied.expr)
		tri = expr_calc_value(sym->implied.expr);
	if (tri == mod && sym_get_type(sym) == S_BOOLEAN)
		tri = yes;
	if (sym->implied.tri != tri) {
		sym->implied.tri = tri;
		sym_set_changed(sym);
	}
}

/*
 * Find the default symbol for a choice.
 * First try the default values for the choice symbol
 * Next locate the first visible choice value
 * Return NULL if none was found
 */
struct symbol *sym_choice_default(struct menu *choice)
{
	struct menu *menu;
	struct symbol *def_sym;
	struct property *prop;

	/* any of the defaults visible? */
	for_all_defaults(choice->sym, prop) {
		prop->visible.tri = expr_calc_value(prop->visible.expr);
		if (prop->visible.tri == no)
			continue;
		def_sym = prop_get_symbol(prop);
		if (def_sym->visible != no)
			return def_sym;
	}

	/* just get the first visible value */
	menu_for_each_sub_entry(menu, choice)
		if (menu->sym && menu->sym->visible != no)
			return menu->sym;

	/* failed to locate any defaults */
	return NULL;
}

/*
 * sym_calc_choice - calculate symbol values in a choice
 *
 * @choice: a menu of the choice
 *
 * Return: a chosen symbol
 */
struct symbol *sym_calc_choice(struct menu *choice)
{
	struct symbol *res = NULL;
	struct symbol *sym;
	struct menu *menu;

	/* Traverse the list of choice members in the priority order. */
	list_for_each_entry(sym, &choice->choice_members, choice_link) {
		sym_calc_visibility(sym);
		if (sym->visible == no)
			continue;

		/* The first visible symble with the user value 'y'. */
		if (sym_has_value(sym) && sym->def[S_DEF_USER].tri == yes) {
			res = sym;
			break;
		}
	}

	/*
	 * If 'y' is not found in the user input, use the default, unless it is
	 * explicitly set to 'n'.
	 */
	if (!res) {
		res = sym_choice_default(choice);
		if (res && sym_has_value(res) && res->def[S_DEF_USER].tri == no)
			res = NULL;
	}

	/* Still not found. Pick up the first visible, user-unspecified symbol. */
	if (!res) {
		menu_for_each_sub_entry(menu, choice) {
			sym = menu->sym;

			if (!sym || sym->visible == no || sym_has_value(sym))
				continue;

			res = sym;
			break;
		}
	}

	/*
	 * Still not found. Traverse the linked list in the _reverse_ order to
	 * pick up the least prioritized 'n'.
	 */
	if (!res) {
		list_for_each_entry_reverse(sym, &choice->choice_members,
					    choice_link) {
			if (sym->visible == no)
				continue;

			res = sym;
			break;
		}
	}

	menu_for_each_sub_entry(menu, choice) {
		tristate val;

		sym = menu->sym;

		if (!sym || sym->visible == no)
			continue;

		val = sym == res ? yes : no;

		if (sym->curr.tri != val)
			sym_set_changed(sym);

		sym->curr.tri = val;
		sym->flags |= SYMBOL_VALID | SYMBOL_WRITE;
	}

	return res;
}

static void sym_warn_unmet_dep(const struct symbol *sym)
{
	struct gstr gs = str_new();

	str_printf(&gs,
		   "\nWARNING: unmet direct dependencies detected for %s\n",
		   sym->name);
	str_printf(&gs,
		   "  Depends on [%c]: ",
		   sym->dir_dep.tri == mod ? 'm' : 'n');
	expr_gstr_print(sym->dir_dep.expr, &gs);
	str_printf(&gs, "\n");

	expr_gstr_print_revdep(sym->rev_dep.expr, &gs, yes,
			       "  Selected by [y]:\n");
	expr_gstr_print_revdep(sym->rev_dep.expr, &gs, mod,
			       "  Selected by [m]:\n");

	fputs(str_get(&gs), stderr);
	sym_warnings++;
}

bool sym_dep_errors(void)
{
	if (sym_warnings)
		return getenv("KCONFIG_WERROR");
	return false;
}

void sym_calc_value(struct symbol *sym)
{
	struct symbol_value newval, oldval;
	struct property *prop;
	struct menu *choice_menu;

	if (!sym)
		return;

	if (sym->flags & SYMBOL_VALID)
		return;

	sym->flags |= SYMBOL_VALID;

	oldval = sym->curr;

	newval.tri = no;

	switch (sym->type) {
	case S_INT:
		newval.val = "0";
		break;
	case S_HEX:
		newval.val = "0x0";
		break;
	case S_STRING:
		newval.val = "";
		break;
	case S_BOOLEAN:
	case S_TRISTATE:
		newval.val = "n";
		break;
	default:
		sym->curr.val = sym->name;
		sym->curr.tri = no;
		return;
	}
	sym->flags &= ~SYMBOL_WRITE;

	sym_calc_visibility(sym);

	if (sym->visible != no)
		sym->flags |= SYMBOL_WRITE;

	/* set default if recursively called */
	sym->curr = newval;

	switch (sym_get_type(sym)) {
	case S_BOOLEAN:
	case S_TRISTATE:
		choice_menu = sym_get_choice_menu(sym);

		if (choice_menu) {
			sym_calc_choice(choice_menu);
			newval.tri = sym->curr.tri;
		} else {
			if (sym->visible != no) {
				/* if the symbol is visible use the user value
				 * if available, otherwise try the default value
				 */
				if (sym_has_value(sym)) {
					newval.tri = EXPR_AND(sym->def[S_DEF_USER].tri,
							      sym->visible);
					goto calc_newval;
				}
			}
			if (sym->rev_dep.tri != no)
				sym->flags |= SYMBOL_WRITE;
			if (!sym_is_choice(sym)) {
				prop = sym_get_default_prop(sym);
				if (prop) {
					newval.tri = EXPR_AND(expr_calc_value(prop->expr),
							      prop->visible.tri);
					if (newval.tri != no)
						sym->flags |= SYMBOL_WRITE;
				}
				if (sym->implied.tri != no) {
					sym->flags |= SYMBOL_WRITE;
					newval.tri = EXPR_OR(newval.tri, sym->implied.tri);
					newval.tri = EXPR_AND(newval.tri,
							      sym->dir_dep.tri);
				}
			}
		calc_newval:
			if (sym->dir_dep.tri < sym->rev_dep.tri)
				sym_warn_unmet_dep(sym);
			newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri);
		}
		if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN)
			newval.tri = yes;
		break;
	case S_STRING:
	case S_HEX:
	case S_INT:
		if (sym->visible != no && sym_has_value(sym)) {
			newval.val = sym->def[S_DEF_USER].val;
			break;
		}
		prop = sym_get_default_prop(sym);
		if (prop) {
			struct symbol *ds = prop_get_symbol(prop);
			if (ds) {
				sym->flags |= SYMBOL_WRITE;
				sym_calc_value(ds);
				newval.val = ds->curr.val;
			}
		}
		break;
	default:
		;
	}

	sym->curr = newval;
	sym_validate_range(sym);

	if (memcmp(&oldval, &sym->curr, sizeof(oldval))) {
		sym_set_changed(sym);
		if (modules_sym == sym) {
			sym_set_all_changed();
			modules_val = modules_sym->curr.tri;
		}
	}

	if (sym_is_choice(sym))
		sym->flags &= ~SYMBOL_WRITE;
}

void sym_clear_all_valid(void)
{
	struct symbol *sym;

	for_all_symbols(sym)
		sym->flags &= ~SYMBOL_VALID;
	conf_set_changed(true);
	sym_calc_value(modules_sym);
}

bool sym_tristate_within_range(const struct symbol *sym, tristate val)
{
	int type = sym_get_type(sym);

	if (sym->visible == no)
		return false;

	if (type != S_BOOLEAN && type != S_TRISTATE)
		return false;

	if (type == S_BOOLEAN && val == mod)
		return false;
	if (sym->visible <= sym->rev_dep.tri)
		return false;
	return val >= sym->rev_dep.tri && val <= sym->visible;
}

bool sym_set_tristate_value(struct symbol *sym, tristate val)
{
	tristate oldval = sym_get_tristate_value(sym);

	if (!sym_tristate_within_range(sym, val))
		return false;

	if (!(sym->flags & SYMBOL_DEF_USER) || sym->def[S_DEF_USER].tri != val) {
		sym->def[S_DEF_USER].tri = val;
		sym->flags |= SYMBOL_DEF_USER;
		sym_set_changed(sym);
	}

	if (oldval != val)
		sym_clear_all_valid();

	return true;
}

/**
 * choice_set_value - set the user input to a choice
 *
 * @choice: menu entry for the choice
 * @sym: selected symbol
 */
void choice_set_value(struct menu *choice, struct symbol *sym)
{
	struct menu *menu;
	bool changed = false;

	menu_for_each_sub_entry(menu, choice) {
		tristate val;

		if (!menu->sym)
			continue;

		if (menu->sym->visible == no)
			continue;

		val = menu->sym == sym ? yes : no;

		if (menu->sym->curr.tri != val)
			changed = true;

		menu->sym->def[S_DEF_USER].tri = val;
		menu->sym->flags |= SYMBOL_DEF_USER;

		/*
		 * Now, the user has explicitly enabled or disabled this symbol,
		 * it should be given the highest priority. We are possibly
		 * setting multiple symbols to 'n', where the first symbol is
		 * given the least prioritized 'n'. This works well when the
		 * choice block ends up with selecting 'n' symbol.
		 * (see sym_calc_choice())
		 */
		list_move(&menu->sym->choice_link, &choice->choice_members);
	}

	if (changed)
		sym_clear_all_valid();
}

tristate sym_toggle_tristate_value(struct symbol *sym)
{
	struct menu *choice;
	tristate oldval, newval;

	choice = sym_get_choice_menu(sym);
	if (choice) {
		choice_set_value(choice, sym);
		return yes;
	}

	oldval = newval = sym_get_tristate_value(sym);
	do {
		switch (newval) {
		case no:
			newval = mod;
			break;
		case mod:
			newval = yes;
			break;
		case yes:
			newval = no;
			break;
		}
		if (sym_set_tristate_value(sym, newval))
			break;
	} while (oldval != newval);
	return newval;
}

bool sym_string_valid(struct symbol *sym, const char *str)
{
	signed char ch;

	switch (sym->type) {
	case S_STRING:
		return true;
	case S_INT:
		ch = *str++;
		if (ch == '-')
			ch = *str++;
		if (!isdigit(ch))
			return false;
		if (ch == '0' && *str != 0)
			return false;
		while ((ch = *str++)) {
			if (!isdigit(ch))
				return false;
		}
		return true;
	case S_HEX:
		if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
			str += 2;
		ch = *str++;
		do {
			if (!isxdigit(ch))
				return false;
		} while ((ch = *str++));
		return true;
	case S_BOOLEAN:
	case S_TRISTATE:
		switch (str[0]) {
		case 'y': case 'Y':
		case 'm': case 'M':
		case 'n': case 'N':
			return true;
		}
		return false;
	default:
		return false;
	}
}

bool sym_string_within_range(struct symbol *sym, const char *str)
{
	struct property *prop;
	long long val;

	switch (sym->type) {
	case S_STRING:
		return sym_string_valid(sym, str);
	case S_INT:
		if (!sym_string_valid(sym, str))
			return false;
		prop = sym_get_range_prop(sym);
		if (!prop)
			return true;
		val = strtoll(str, NULL, 10);
		return val >= sym_get_range_val(prop->expr->left.sym, 10) &&
		       val <= sym_get_range_val(prop->expr->right.sym, 10);
	case S_HEX:
		if (!sym_string_valid(sym, str))
			return false;
		prop = sym_get_range_prop(sym);
		if (!prop)
			return true;
		val = strtoll(str, NULL, 16);
		return val >= sym_get_range_val(prop->expr->left.sym, 16) &&
		       val <= sym_get_range_val(prop->expr->right.sym, 16);
	case S_BOOLEAN:
	case S_TRISTATE:
		switch (str[0]) {
		case 'y': case 'Y':
			return sym_tristate_within_range(sym, yes);
		case 'm': case 'M':
			return sym_tristate_within_range(sym, mod);
		case 'n': case 'N':
			return sym_tristate_within_range(sym, no);
		}
		return false;
	default:
		return false;
	}
}

bool sym_set_string_value(struct symbol *sym, const char *newval)
{
	const char *oldval;
	char *val;
	int size;

	switch (sym->type) {
	case S_BOOLEAN:
	case S_TRISTATE:
		switch (newval[0]) {
		case 'y': case 'Y':
			return sym_set_tristate_value(sym, yes);
		case 'm': case 'M':
			return sym_set_tristate_value(sym, mod);
		case 'n': case 'N':
			return sym_set_tristate_value(sym, no);
		}
		return false;
	default:
		;
	}

	if (!sym_string_within_range(sym, newval))
		return false;

	if (!(sym->flags & SYMBOL_DEF_USER)) {
		sym->flags |= SYMBOL_DEF_USER;
		sym_set_changed(sym);
	}

	oldval = sym->def[S_DEF_USER].val;
	size = strlen(newval) + 1;
	if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) {
		size += 2;
		sym->def[S_DEF_USER].val = val = xmalloc(size);
		*val++ = '0';
		*val++ = 'x';
	} else if (!oldval || strcmp(oldval, newval))
		sym->def[S_DEF_USER].val = val = xmalloc(size);
	else
		return true;

	strcpy(val, newval);
	free((void *)oldval);
	sym_clear_all_valid();

	return true;
}

/*
 * Find the default value associated to a symbol.
 * For tristate symbol handle the modules=n case
 * in which case "m" becomes "y".
 * If the symbol does not have any default then fallback
 * to the fixed default values.
 */
const char *sym_get_string_default(struct symbol *sym)
{
	struct property *prop;
	struct symbol *ds;
	const char *str = "";
	tristate val;

	sym_calc_visibility(sym);
	sym_calc_value(modules_sym);
	val = symbol_no.curr.tri;

	/* If symbol has a default value look it up */
	prop = sym_get_default_prop(sym);
	if (prop != NULL) {
		switch (sym->type) {
		case S_BOOLEAN:
		case S_TRISTATE:
			/* The visibility may limit the value from yes => mod */
			val = EXPR_AND(expr_calc_value(prop->expr), prop->visible.tri);
			break;
		default:
			/*
			 * The following fails to handle the situation
			 * where a default value is further limited by
			 * the valid range.
			 */
			ds = prop_get_symbol(prop);
			if (ds != NULL) {
				sym_calc_value(ds);
				str = (const char *)ds->curr.val;
			}
		}
	}

	/* Handle select statements */
	val = EXPR_OR(val, sym->rev_dep.tri);

	/* transpose mod to yes if modules are not enabled */
	if (val == mod)
		if (!sym_is_choice_value(sym) && modules_sym->curr.tri == no)
			val = yes;

	/* transpose mod to yes if type is bool */
	if (sym->type == S_BOOLEAN && val == mod)
		val = yes;

	/* adjust the default value if this symbol is implied by another */
	if (val < sym->implied.tri)
		val = sym->implied.tri;

	switch (sym->type) {
	case S_BOOLEAN:
	case S_TRISTATE:
		switch (val) {
		case no: return "n";
		case mod: return "m";
		case yes: return "y";
		}
	case S_INT:
		if (!str[0])
			str = "0";
		break;
	case S_HEX:
		if (!str[0])
			str = "0x0";
		break;
	default:
		break;
	}
	return str;
}

const char *sym_get_string_value(struct symbol *sym)
{
	tristate val;

	switch (sym->type) {
	case S_BOOLEAN:
	case S_TRISTATE:
		val = sym_get_tristate_value(sym);
		switch (val) {
		case no:
			return "n";
		case mod:
			return "m";
		case yes:
			return "y";
		}
		break;
	default:
		;
	}
	return (const char *)sym->curr.val;
}

bool sym_is_changeable(const struct symbol *sym)
{
	return !sym_is_choice(sym) && sym->visible > sym->rev_dep.tri;
}

bool sym_is_choice_value(const struct symbol *sym)
{
	return !list_empty(&sym->choice_link);
}

HASHTABLE_DEFINE(sym_hashtable, SYMBOL_HASHSIZE);

struct symbol *sym_lookup(const char *name, int flags)
{
	struct symbol *symbol;
	char *new_name;
	int hash;

	if (name) {
		if (name[0] && !name[1]) {
			switch (name[0]) {
			case 'y': return &symbol_yes;
			case 'm': return &symbol_mod;
			case 'n': return &symbol_no;
			}
		}
		hash = strhash(name);

		hash_for_each_possible(sym_hashtable, symbol, node, hash) {
			if (symbol->name &&
			    !strcmp(symbol->name, name) &&
			    (flags ? symbol->flags & flags
				   : !(symbol->flags & SYMBOL_CONST)))
				return symbol;
		}
		new_name = xstrdup(name);
	} else {
		new_name = NULL;
		hash = 0;
	}

	symbol = xmalloc(sizeof(*symbol));
	memset(symbol, 0, sizeof(*symbol));
	symbol->name = new_name;
	symbol->type = S_UNKNOWN;
	symbol->flags = flags;
	INIT_LIST_HEAD(&symbol->menus);
	INIT_LIST_HEAD(&symbol->choice_link);

	hash_add(sym_hashtable, &symbol->node, hash);

	return symbol;
}

struct symbol *sym_find(const char *name)
{
	struct symbol *symbol = NULL;
	int hash = 0;

	if (!name)
		return NULL;

	if (name[0] && !name[1]) {
		switch (name[0]) {
		case 'y': return &symbol_yes;
		case 'm': return &symbol_mod;
		case 'n': return &symbol_no;
		}
	}
	hash = strhash(name);

	hash_for_each_possible(sym_hashtable, symbol, node, hash) {
		if (symbol->name &&
		    !strcmp(symbol->name, name) &&
		    !(symbol->flags & SYMBOL_CONST))
				break;
	}

	return symbol;
}

struct sym_match {
	struct symbol	*sym;
	off_t		so, eo;
};

/* Compare matched symbols as thus:
 * - first, symbols that match exactly
 * - then, alphabetical sort
 */
static int sym_rel_comp(const void *sym1, const void *sym2)
{
	const struct sym_match *s1 = sym1;
	const struct sym_match *s2 = sym2;
	int exact1, exact2;

	/* Exact match:
	 * - if matched length on symbol s1 is the length of that symbol,
	 *   then this symbol should come first;
	 * - if matched length on symbol s2 is the length of that symbol,
	 *   then this symbol should come first.
	 * Note: since the search can be a regexp, both symbols may match
	 * exactly; if this is the case, we can't decide which comes first,
	 * and we fallback to sorting alphabetically.
	 */
	exact1 = (s1->eo - s1->so) == strlen(s1->sym->name);
	exact2 = (s2->eo - s2->so) == strlen(s2->sym->name);
	if (exact1 && !exact2)
		return -1;
	if (!exact1 && exact2)
		return 1;

	/* As a fallback, sort symbols alphabetically */
	return strcmp(s1->sym->name, s2->sym->name);
}

struct symbol **sym_re_search(const char *pattern)
{
	struct symbol *sym, **sym_arr = NULL;
	struct sym_match *sym_match_arr = NULL;
	int i, cnt, size;
	regex_t re;
	regmatch_t match[1];

	cnt = size = 0;
	/* Skip if empty */
	if (strlen(pattern) == 0)
		return NULL;
	if (regcomp(&re, pattern, REG_EXTENDED|REG_ICASE))
		return NULL;

	for_all_symbols(sym) {
		if (sym->flags & SYMBOL_CONST || !sym->name)
			continue;
		if (regexec(&re, sym->name, 1, match, 0))
			continue;
		if (cnt >= size) {
			void *tmp;
			size += 16;
			tmp = realloc(sym_match_arr, size * sizeof(struct sym_match));
			if (!tmp)
				goto sym_re_search_free;
			sym_match_arr = tmp;
		}
		sym_calc_value(sym);
		/* As regexec returned 0, we know we have a match, so
		 * we can use match[0].rm_[se]o without further checks
		 */
		sym_match_arr[cnt].so = match[0].rm_so;
		sym_match_arr[cnt].eo = match[0].rm_eo;
		sym_match_arr[cnt++].sym = sym;
	}
	if (sym_match_arr) {
		qsort(sym_match_arr, cnt, sizeof(struct sym_match), sym_rel_comp);
		sym_arr = malloc((cnt+1) * sizeof(struct symbol *));
		if (!sym_arr)
			goto sym_re_search_free;
		for (i = 0; i < cnt; i++)
			sym_arr[i] = sym_match_arr[i].sym;
		sym_arr[cnt] = NULL;
	}
sym_re_search_free:
	/* sym_match_arr can be NULL if no match, but free(NULL) is OK */
	free(sym_match_arr);
	regfree(&re);

	return sym_arr;
}

/*
 * When we check for recursive dependencies we use a stack to save
 * current state so we can print out relevant info to user.
 * The entries are located on the call stack so no need to free memory.
 * Note insert() remove() must always match to properly clear the stack.
 */
static struct dep_stack {
	struct dep_stack *prev, *next;
	struct symbol *sym;
	struct property *prop;
	struct expr **expr;
} *check_top;

static void dep_stack_insert(struct dep_stack *stack, struct symbol *sym)
{
	memset(stack, 0, sizeof(*stack));
	if (check_top)
		check_top->next = stack;
	stack->prev = check_top;
	stack->sym = sym;
	check_top = stack;
}

static void dep_stack_remove(void)
{
	check_top = check_top->prev;
	if (check_top)
		check_top->next = NULL;
}

/*
 * Called when we have detected a recursive dependency.
 * check_top point to the top of the stact so we use
 * the ->prev pointer to locate the bottom of the stack.
 */
static void sym_check_print_recursive(struct symbol *last_sym)
{
	struct dep_stack *stack;
	struct symbol *sym, *next_sym;
	struct menu *choice;
	struct dep_stack cv_stack;
	enum prop_type type;

	choice = sym_get_choice_menu(last_sym);
	if (choice) {
		dep_stack_insert(&cv_stack, last_sym);
		last_sym = choice->sym;
	}

	for (stack = check_top; stack != NULL; stack = stack->prev)
		if (stack->sym == last_sym)
			break;
	if (!stack) {
		fprintf(stderr, "unexpected recursive dependency error\n");
		return;
	}

	for (; stack; stack = stack->next) {
		sym = stack->sym;
		next_sym = stack->next ? stack->next->sym : last_sym;
		type = stack->prop ? stack->prop->type : P_UNKNOWN;

		if (stack->sym == last_sym)
			fprintf(stderr, "error: recursive dependency detected!\n");

		if (sym_is_choice(next_sym)) {
			choice = list_first_entry(&next_sym->menus, struct menu, link);

			fprintf(stderr, "\tsymbol %s is part of choice block at %s:%d\n",
				sym->name ? sym->name : "<choice>",
				choice->filename, choice->lineno);
		} else if (stack->expr == &sym->dir_dep.expr) {
			fprintf(stderr, "\tsymbol %s depends on %s\n",
				sym->name ? sym->name : "<choice>",
				next_sym->name);
		} else if (stack->expr == &sym->rev_dep.expr) {
			fprintf(stderr, "\tsymbol %s is selected by %s\n",
				sym->name, next_sym->name);
		} else if (stack->expr == &sym->implied.expr) {
			fprintf(stderr, "\tsymbol %s is implied by %s\n",
				sym->name, next_sym->name);
		} else if (stack->expr) {
			fprintf(stderr, "\tsymbol %s %s value contains %s\n",
				sym->name ? sym->name : "<choice>",
				prop_get_type_name(type),
				next_sym->name);
		} else {
			fprintf(stderr, "\tsymbol %s %s is visible depending on %s\n",
				sym->name ? sym->name : "<choice>",
				prop_get_type_name(type),
				next_sym->name);
		}
	}

	fprintf(stderr,
		"For a resolution refer to Documentation/kbuild/kconfig-language.rst\n"
		"subsection \"Kconfig recursive dependency limitations\"\n"
		"\n");

	if (check_top == &cv_stack)
		dep_stack_remove();
}

static struct symbol *sym_check_expr_deps(const struct expr *e)
{
	struct symbol *sym;

	if (!e)
		return NULL;
	switch (e->type) {
	case E_OR:
	case E_AND:
		sym = sym_check_expr_deps(e->left.expr);
		if (sym)
			return sym;
		return sym_check_expr_deps(e->right.expr);
	case E_NOT:
		return sym_check_expr_deps(e->left.expr);
	case E_EQUAL:
	case E_GEQ:
	case E_GTH:
	case E_LEQ:
	case E_LTH:
	case E_UNEQUAL:
		sym = sym_check_deps(e->left.sym);
		if (sym)
			return sym;
		return sym_check_deps(e->right.sym);
	case E_SYMBOL:
		return sym_check_deps(e->left.sym);
	default:
		break;
	}
	fprintf(stderr, "Oops! How to check %d?\n", e->type);
	return NULL;
}

/* return NULL when dependencies are OK */
static struct symbol *sym_check_sym_deps(struct symbol *sym)
{
	struct symbol *sym2;
	struct property *prop;
	struct dep_stack stack;

	dep_stack_insert(&stack, sym);

	stack.expr = &sym->dir_dep.expr;
	sym2 = sym_check_expr_deps(sym->dir_dep.expr);
	if (sym2)
		goto out;

	stack.expr = &sym->rev_dep.expr;
	sym2 = sym_check_expr_deps(sym->rev_dep.expr);
	if (sym2)
		goto out;

	stack.expr = &sym->implied.expr;
	sym2 = sym_check_expr_deps(sym->implied.expr);
	if (sym2)
		goto out;

	stack.expr = NULL;

	for (prop = sym->prop; prop; prop = prop->next) {
		if (prop->type == P_SELECT || prop->type == P_IMPLY)
			continue;
		stack.prop = prop;
		sym2 = sym_check_expr_deps(prop->visible.expr);
		if (sym2)
			break;
		if (prop->type != P_DEFAULT || sym_is_choice(sym))
			continue;
		stack.expr = &prop->expr;
		sym2 = sym_check_expr_deps(prop->expr);
		if (sym2)
			break;
		stack.expr = NULL;
	}

out:
	dep_stack_remove();

	return sym2;
}

static struct symbol *sym_check_choice_deps(struct symbol *choice)
{
	struct menu *choice_menu, *menu;
	struct symbol *sym2;
	struct dep_stack stack;

	dep_stack_insert(&stack, choice);

	choice_menu = list_first_entry(&choice->menus, struct menu, link);

	menu_for_each_sub_entry(menu, choice_menu) {
		if (menu->sym)
			menu->sym->flags |= SYMBOL_CHECK | SYMBOL_CHECKED;
	}

	choice->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
	sym2 = sym_check_sym_deps(choice);
	choice->flags &= ~SYMBOL_CHECK;
	if (sym2)
		goto out;

	menu_for_each_sub_entry(menu, choice_menu) {
		if (!menu->sym)
			continue;
		sym2 = sym_check_sym_deps(menu->sym);
		if (sym2)
			break;
	}
out:
	menu_for_each_sub_entry(menu, choice_menu)
		if (menu->sym)
			menu->sym->flags &= ~SYMBOL_CHECK;

	if (sym2) {
		struct menu *choice_menu2;

		choice_menu2 = sym_get_choice_menu(sym2);
		if (choice_menu2 == choice_menu)
			sym2 = choice;
	}

	dep_stack_remove();

	return sym2;
}

struct symbol *sym_check_deps(struct symbol *sym)
{
	struct menu *choice;
	struct symbol *sym2;

	if (sym->flags & SYMBOL_CHECK) {
		sym_check_print_recursive(sym);
		return sym;
	}
	if (sym->flags & SYMBOL_CHECKED)
		return NULL;

	choice = sym_get_choice_menu(sym);
	if (choice) {
		struct dep_stack stack;

		/* for choice groups start the check with main choice symbol */
		dep_stack_insert(&stack, sym);
		sym2 = sym_check_deps(choice->sym);
		dep_stack_remove();
	} else if (sym_is_choice(sym)) {
		sym2 = sym_check_choice_deps(sym);
	} else {
		sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
		sym2 = sym_check_sym_deps(sym);
		sym->flags &= ~SYMBOL_CHECK;
	}

	return sym2;
}

struct symbol *prop_get_symbol(const struct property *prop)
{
	if (prop->expr && prop->expr->type == E_SYMBOL)
		return prop->expr->left.sym;
	return NULL;
}

const char *prop_get_type_name(enum prop_type type)
{
	switch (type) {
	case P_PROMPT:
		return "prompt";
	case P_COMMENT:
		return "comment";
	case P_MENU:
		return "menu";
	case P_DEFAULT:
		return "default";
	case P_SELECT:
		return "select";
	case P_IMPLY:
		return "imply";
	case P_RANGE:
		return "range";
	case P_SYMBOL:
		return "symbol";
	case P_UNKNOWN:
		break;
	}
	return "unknown";
}
