kconfig/symbol.c
author "Benoît Thébaudeau" <benoit.thebaudeau@advansee.com>
Mon Apr 16 15:25:36 2012 +0200 (2012-04-16)
changeset 2941 13e40098fffc
parent 2448 a103abae1560
permissions -rw-r--r--
cc/gcc: update Linaro GCC revisions to 2012.04

Update Linaro GCC with the latest available revisions.

The 4.7 revision is also released, but the infrastructure is not yet ready for
it in CT-NG.

Signed-off-by: "Benoît Thébaudeau" <benoit.thebaudeau@advansee.com>
     1 /*
     2  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
     3  * Released under the terms of the GNU GPL v2.0.
     4  */
     5 
     6 #include <ctype.h>
     7 #include <stdlib.h>
     8 #include <string.h>
     9 #include <regex.h>
    10 #include <sys/utsname.h>
    11 
    12 #define LKC_DIRECT_LINK
    13 #include "lkc.h"
    14 
    15 struct symbol symbol_yes = {
    16 	.name = "y",
    17 	.curr = { "y", yes },
    18 	.flags = SYMBOL_CONST|SYMBOL_VALID,
    19 }, symbol_mod = {
    20 	.name = "m",
    21 	.curr = { "m", mod },
    22 	.flags = SYMBOL_CONST|SYMBOL_VALID,
    23 }, symbol_no = {
    24 	.name = "n",
    25 	.curr = { "n", no },
    26 	.flags = SYMBOL_CONST|SYMBOL_VALID,
    27 }, symbol_empty = {
    28 	.name = "",
    29 	.curr = { "", no },
    30 	.flags = SYMBOL_VALID,
    31 };
    32 
    33 struct symbol *sym_defconfig_list;
    34 struct symbol *modules_sym;
    35 tristate modules_val;
    36 
    37 struct expr *sym_env_list;
    38 
    39 static void sym_add_default(struct symbol *sym, const char *def)
    40 {
    41 	struct property *prop = prop_alloc(P_DEFAULT, sym);
    42 
    43 	prop->expr = expr_alloc_symbol(sym_lookup(def, SYMBOL_CONST));
    44 }
    45 
    46 void sym_init(void)
    47 {
    48 	struct symbol *sym;
    49 	struct utsname uts;
    50 	static bool inited = false;
    51 
    52 	if (inited)
    53 		return;
    54 	inited = true;
    55 
    56 	uname(&uts);
    57 
    58 	sym = sym_lookup("UNAME_RELEASE", 0);
    59 	sym->type = S_STRING;
    60 	sym->flags |= SYMBOL_AUTO;
    61 	sym_add_default(sym, uts.release);
    62 }
    63 
    64 enum symbol_type sym_get_type(struct symbol *sym)
    65 {
    66 	enum symbol_type type = sym->type;
    67 
    68 	if (type == S_TRISTATE) {
    69 		if (sym_is_choice_value(sym) && sym->visible == yes)
    70 			type = S_BOOLEAN;
    71 		else if (modules_val == no)
    72 			type = S_BOOLEAN;
    73 	}
    74 	return type;
    75 }
    76 
    77 const char *sym_type_name(enum symbol_type type)
    78 {
    79 	switch (type) {
    80 	case S_BOOLEAN:
    81 		return "boolean";
    82 	case S_TRISTATE:
    83 		return "tristate";
    84 	case S_INT:
    85 		return "integer";
    86 	case S_HEX:
    87 		return "hex";
    88 	case S_STRING:
    89 		return "string";
    90 	case S_UNKNOWN:
    91 		return "unknown";
    92 	case S_OTHER:
    93 		break;
    94 	}
    95 	return "???";
    96 }
    97 
    98 struct property *sym_get_choice_prop(struct symbol *sym)
    99 {
   100 	struct property *prop;
   101 
   102 	for_all_choices(sym, prop)
   103 		return prop;
   104 	return NULL;
   105 }
   106 
   107 struct property *sym_get_env_prop(struct symbol *sym)
   108 {
   109 	struct property *prop;
   110 
   111 	for_all_properties(sym, prop, P_ENV)
   112 		return prop;
   113 	return NULL;
   114 }
   115 
   116 struct property *sym_get_default_prop(struct symbol *sym)
   117 {
   118 	struct property *prop;
   119 
   120 	for_all_defaults(sym, prop) {
   121 		prop->visible.tri = expr_calc_value(prop->visible.expr);
   122 		if (prop->visible.tri != no)
   123 			return prop;
   124 	}
   125 	return NULL;
   126 }
   127 
   128 static struct property *sym_get_range_prop(struct symbol *sym)
   129 {
   130 	struct property *prop;
   131 
   132 	for_all_properties(sym, prop, P_RANGE) {
   133 		prop->visible.tri = expr_calc_value(prop->visible.expr);
   134 		if (prop->visible.tri != no)
   135 			return prop;
   136 	}
   137 	return NULL;
   138 }
   139 
   140 static int sym_get_range_val(struct symbol *sym, int base)
   141 {
   142 	sym_calc_value(sym);
   143 	switch (sym->type) {
   144 	case S_INT:
   145 		base = 10;
   146 		break;
   147 	case S_HEX:
   148 		base = 16;
   149 		break;
   150 	default:
   151 		break;
   152 	}
   153 	return strtol(sym->curr.val, NULL, base);
   154 }
   155 
   156 static void sym_validate_range(struct symbol *sym)
   157 {
   158 	struct property *prop;
   159 	int base, val, val2;
   160 	char str[64];
   161 
   162 	switch (sym->type) {
   163 	case S_INT:
   164 		base = 10;
   165 		break;
   166 	case S_HEX:
   167 		base = 16;
   168 		break;
   169 	default:
   170 		return;
   171 	}
   172 	prop = sym_get_range_prop(sym);
   173 	if (!prop)
   174 		return;
   175 	val = strtol(sym->curr.val, NULL, base);
   176 	val2 = sym_get_range_val(prop->expr->left.sym, base);
   177 	if (val >= val2) {
   178 		val2 = sym_get_range_val(prop->expr->right.sym, base);
   179 		if (val <= val2)
   180 			return;
   181 	}
   182 	if (sym->type == S_INT)
   183 		sprintf(str, "%d", val2);
   184 	else
   185 		sprintf(str, "0x%x", val2);
   186 	sym->curr.val = strdup(str);
   187 }
   188 
   189 static void sym_calc_visibility(struct symbol *sym)
   190 {
   191 	struct property *prop;
   192 	tristate tri;
   193 
   194 	/* any prompt visible? */
   195 	tri = no;
   196 	for_all_prompts(sym, prop) {
   197 		prop->visible.tri = expr_calc_value(prop->visible.expr);
   198 		tri = EXPR_OR(tri, prop->visible.tri);
   199 	}
   200 	if (tri == mod && (sym->type != S_TRISTATE || modules_val == no))
   201 		tri = yes;
   202 	if (sym->visible != tri) {
   203 		sym->visible = tri;
   204 		sym_set_changed(sym);
   205 	}
   206 	if (sym_is_choice_value(sym))
   207 		return;
   208 	/* defaulting to "yes" if no explicit "depends on" are given */
   209 	tri = yes;
   210 	if (sym->dir_dep.expr)
   211 		tri = expr_calc_value(sym->dir_dep.expr);
   212 	if (tri == mod)
   213 		tri = yes;
   214 	if (sym->dir_dep.tri != tri) {
   215 		sym->dir_dep.tri = tri;
   216 		sym_set_changed(sym);
   217 	}
   218 	tri = no;
   219 	if (sym->rev_dep.expr)
   220 		tri = expr_calc_value(sym->rev_dep.expr);
   221 	if (tri == mod && sym_get_type(sym) == S_BOOLEAN)
   222 		tri = yes;
   223 	if (sym->rev_dep.tri != tri) {
   224 		sym->rev_dep.tri = tri;
   225 		sym_set_changed(sym);
   226 	}
   227 }
   228 
   229 /*
   230  * Find the default symbol for a choice.
   231  * First try the default values for the choice symbol
   232  * Next locate the first visible choice value
   233  * Return NULL if none was found
   234  */
   235 struct symbol *sym_choice_default(struct symbol *sym)
   236 {
   237 	struct symbol *def_sym;
   238 	struct property *prop;
   239 	struct expr *e;
   240 
   241 	/* any of the defaults visible? */
   242 	for_all_defaults(sym, prop) {
   243 		prop->visible.tri = expr_calc_value(prop->visible.expr);
   244 		if (prop->visible.tri == no)
   245 			continue;
   246 		def_sym = prop_get_symbol(prop);
   247 		if (def_sym->visible != no)
   248 			return def_sym;
   249 	}
   250 
   251 	/* just get the first visible value */
   252 	prop = sym_get_choice_prop(sym);
   253 	expr_list_for_each_sym(prop->expr, e, def_sym)
   254 		if (def_sym->visible != no)
   255 			return def_sym;
   256 
   257 	/* failed to locate any defaults */
   258 	return NULL;
   259 }
   260 
   261 static struct symbol *sym_calc_choice(struct symbol *sym)
   262 {
   263 	struct symbol *def_sym;
   264 	struct property *prop;
   265 	struct expr *e;
   266 
   267 	/* first calculate all choice values' visibilities */
   268 	prop = sym_get_choice_prop(sym);
   269 	expr_list_for_each_sym(prop->expr, e, def_sym)
   270 		sym_calc_visibility(def_sym);
   271 
   272 	/* is the user choice visible? */
   273 	def_sym = sym->def[S_DEF_USER].val;
   274 	if (def_sym && def_sym->visible != no)
   275 		return def_sym;
   276 
   277 	def_sym = sym_choice_default(sym);
   278 
   279 	if (def_sym == NULL)
   280 		/* no choice? reset tristate value */
   281 		sym->curr.tri = no;
   282 
   283 	return def_sym;
   284 }
   285 
   286 void sym_calc_value(struct symbol *sym)
   287 {
   288 	struct symbol_value newval, oldval;
   289 	struct property *prop;
   290 	struct expr *e;
   291 
   292 	if (!sym)
   293 		return;
   294 
   295 	if (sym->flags & SYMBOL_VALID)
   296 		return;
   297 	sym->flags |= SYMBOL_VALID;
   298 
   299 	oldval = sym->curr;
   300 
   301 	switch (sym->type) {
   302 	case S_INT:
   303 	case S_HEX:
   304 	case S_STRING:
   305 		newval = symbol_empty.curr;
   306 		break;
   307 	case S_BOOLEAN:
   308 	case S_TRISTATE:
   309 		newval = symbol_no.curr;
   310 		break;
   311 	default:
   312 		sym->curr.val = sym->name;
   313 		sym->curr.tri = no;
   314 		return;
   315 	}
   316 	if (!sym_is_choice_value(sym))
   317 		sym->flags &= ~SYMBOL_WRITE;
   318 
   319 	sym_calc_visibility(sym);
   320 
   321 	/* set default if recursively called */
   322 	sym->curr = newval;
   323 
   324 	switch (sym_get_type(sym)) {
   325 	case S_BOOLEAN:
   326 	case S_TRISTATE:
   327 		if (sym_is_choice_value(sym) && sym->visible == yes) {
   328 			prop = sym_get_choice_prop(sym);
   329 			newval.tri = (prop_get_symbol(prop)->curr.val == sym) ? yes : no;
   330 		} else {
   331 			if (sym->visible != no) {
   332 				/* if the symbol is visible use the user value
   333 				 * if available, otherwise try the default value
   334 				 */
   335 				sym->flags |= SYMBOL_WRITE;
   336 				if (sym_has_value(sym)) {
   337 					newval.tri = EXPR_AND(sym->def[S_DEF_USER].tri,
   338 							      sym->visible);
   339 					goto calc_newval;
   340 				}
   341 			}
   342 			if (sym->rev_dep.tri != no)
   343 				sym->flags |= SYMBOL_WRITE;
   344 			if (!sym_is_choice(sym)) {
   345 				prop = sym_get_default_prop(sym);
   346 				if (prop) {
   347 					sym->flags |= SYMBOL_WRITE;
   348 					newval.tri = EXPR_AND(expr_calc_value(prop->expr),
   349 							      prop->visible.tri);
   350 				}
   351 			}
   352 		calc_newval:
   353 			if (sym->dir_dep.tri == no && sym->rev_dep.tri != no) {
   354 				struct expr *e;
   355 				e = expr_simplify_unmet_dep(sym->rev_dep.expr,
   356 				    sym->dir_dep.expr);
   357 				fprintf(stderr, "warning: (");
   358 				expr_fprint(e, stderr);
   359 				fprintf(stderr, ") selects %s which has unmet direct dependencies (",
   360 					sym->name);
   361 				expr_fprint(sym->dir_dep.expr, stderr);
   362 				fprintf(stderr, ")\n");
   363 				expr_free(e);
   364 			}
   365 			newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri);
   366 		}
   367 		if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN)
   368 			newval.tri = yes;
   369 		break;
   370 	case S_STRING:
   371 	case S_HEX:
   372 	case S_INT:
   373 		if (sym->visible != no) {
   374 			sym->flags |= SYMBOL_WRITE;
   375 			if (sym_has_value(sym)) {
   376 				newval.val = sym->def[S_DEF_USER].val;
   377 				break;
   378 			}
   379 		}
   380 		prop = sym_get_default_prop(sym);
   381 		if (prop) {
   382 			struct symbol *ds = prop_get_symbol(prop);
   383 			if (ds) {
   384 				sym->flags |= SYMBOL_WRITE;
   385 				sym_calc_value(ds);
   386 				newval.val = ds->curr.val;
   387 			}
   388 		}
   389 		break;
   390 	default:
   391 		;
   392 	}
   393 
   394 	sym->curr = newval;
   395 	if (sym_is_choice(sym) && newval.tri == yes)
   396 		sym->curr.val = sym_calc_choice(sym);
   397 	sym_validate_range(sym);
   398 
   399 	if (memcmp(&oldval, &sym->curr, sizeof(oldval))) {
   400 		sym_set_changed(sym);
   401 		if (modules_sym == sym) {
   402 			sym_set_all_changed();
   403 			modules_val = modules_sym->curr.tri;
   404 		}
   405 	}
   406 
   407 	if (sym_is_choice(sym)) {
   408 		struct symbol *choice_sym;
   409 
   410 		prop = sym_get_choice_prop(sym);
   411 		expr_list_for_each_sym(prop->expr, e, choice_sym) {
   412 			if ((sym->flags & SYMBOL_WRITE) &&
   413 			    choice_sym->visible != no)
   414 				choice_sym->flags |= SYMBOL_WRITE;
   415 			if (sym->flags & SYMBOL_CHANGED)
   416 				sym_set_changed(choice_sym);
   417 		}
   418 	}
   419 
   420 	if (sym->flags & SYMBOL_AUTO)
   421 		sym->flags &= ~SYMBOL_WRITE;
   422 }
   423 
   424 void sym_clear_all_valid(void)
   425 {
   426 	struct symbol *sym;
   427 	int i;
   428 
   429 	for_all_symbols(i, sym)
   430 		sym->flags &= ~SYMBOL_VALID;
   431 	sym_add_change_count(1);
   432 	if (modules_sym)
   433 		sym_calc_value(modules_sym);
   434 }
   435 
   436 void sym_set_changed(struct symbol *sym)
   437 {
   438 	struct property *prop;
   439 
   440 	sym->flags |= SYMBOL_CHANGED;
   441 	for (prop = sym->prop; prop; prop = prop->next) {
   442 		if (prop->menu)
   443 			prop->menu->flags |= MENU_CHANGED;
   444 	}
   445 }
   446 
   447 void sym_set_all_changed(void)
   448 {
   449 	struct symbol *sym;
   450 	int i;
   451 
   452 	for_all_symbols(i, sym)
   453 		sym_set_changed(sym);
   454 }
   455 
   456 bool sym_tristate_within_range(struct symbol *sym, tristate val)
   457 {
   458 	int type = sym_get_type(sym);
   459 
   460 	if (sym->visible == no)
   461 		return false;
   462 
   463 	if (type != S_BOOLEAN && type != S_TRISTATE)
   464 		return false;
   465 
   466 	if (type == S_BOOLEAN && val == mod)
   467 		return false;
   468 	if (sym->visible <= sym->rev_dep.tri)
   469 		return false;
   470 	if (sym_is_choice_value(sym) && sym->visible == yes)
   471 		return val == yes;
   472 	return val >= sym->rev_dep.tri && val <= sym->visible;
   473 }
   474 
   475 bool sym_set_tristate_value(struct symbol *sym, tristate val)
   476 {
   477 	tristate oldval = sym_get_tristate_value(sym);
   478 
   479 	if (oldval != val && !sym_tristate_within_range(sym, val))
   480 		return false;
   481 
   482 	if (!(sym->flags & SYMBOL_DEF_USER)) {
   483 		sym->flags |= SYMBOL_DEF_USER;
   484 		sym_set_changed(sym);
   485 	}
   486 	/*
   487 	 * setting a choice value also resets the new flag of the choice
   488 	 * symbol and all other choice values.
   489 	 */
   490 	if (sym_is_choice_value(sym) && val == yes) {
   491 		struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
   492 		struct property *prop;
   493 		struct expr *e;
   494 
   495 		cs->def[S_DEF_USER].val = sym;
   496 		cs->flags |= SYMBOL_DEF_USER;
   497 		prop = sym_get_choice_prop(cs);
   498 		for (e = prop->expr; e; e = e->left.expr) {
   499 			if (e->right.sym->visible != no)
   500 				e->right.sym->flags |= SYMBOL_DEF_USER;
   501 		}
   502 	}
   503 
   504 	sym->def[S_DEF_USER].tri = val;
   505 	if (oldval != val)
   506 		sym_clear_all_valid();
   507 
   508 	return true;
   509 }
   510 
   511 tristate sym_toggle_tristate_value(struct symbol *sym)
   512 {
   513 	tristate oldval, newval;
   514 
   515 	oldval = newval = sym_get_tristate_value(sym);
   516 	do {
   517 		switch (newval) {
   518 		case no:
   519 			newval = mod;
   520 			break;
   521 		case mod:
   522 			newval = yes;
   523 			break;
   524 		case yes:
   525 			newval = no;
   526 			break;
   527 		}
   528 		if (sym_set_tristate_value(sym, newval))
   529 			break;
   530 	} while (oldval != newval);
   531 	return newval;
   532 }
   533 
   534 bool sym_string_valid(struct symbol *sym, const char *str)
   535 {
   536 	signed char ch;
   537 
   538 	switch (sym->type) {
   539 	case S_STRING:
   540 		return true;
   541 	case S_INT:
   542 		ch = *str++;
   543 		if (ch == '-')
   544 			ch = *str++;
   545 		if (!isdigit(ch))
   546 			return false;
   547 		if (ch == '0' && *str != 0)
   548 			return false;
   549 		while ((ch = *str++)) {
   550 			if (!isdigit(ch))
   551 				return false;
   552 		}
   553 		return true;
   554 	case S_HEX:
   555 		if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
   556 			str += 2;
   557 		ch = *str++;
   558 		do {
   559 			if (!isxdigit(ch))
   560 				return false;
   561 		} while ((ch = *str++));
   562 		return true;
   563 	case S_BOOLEAN:
   564 	case S_TRISTATE:
   565 		switch (str[0]) {
   566 		case 'y': case 'Y':
   567 		case 'm': case 'M':
   568 		case 'n': case 'N':
   569 			return true;
   570 		}
   571 		return false;
   572 	default:
   573 		return false;
   574 	}
   575 }
   576 
   577 bool sym_string_within_range(struct symbol *sym, const char *str)
   578 {
   579 	struct property *prop;
   580 	int val;
   581 
   582 	switch (sym->type) {
   583 	case S_STRING:
   584 		return sym_string_valid(sym, str);
   585 	case S_INT:
   586 		if (!sym_string_valid(sym, str))
   587 			return false;
   588 		prop = sym_get_range_prop(sym);
   589 		if (!prop)
   590 			return true;
   591 		val = strtol(str, NULL, 10);
   592 		return val >= sym_get_range_val(prop->expr->left.sym, 10) &&
   593 		       val <= sym_get_range_val(prop->expr->right.sym, 10);
   594 	case S_HEX:
   595 		if (!sym_string_valid(sym, str))
   596 			return false;
   597 		prop = sym_get_range_prop(sym);
   598 		if (!prop)
   599 			return true;
   600 		val = strtol(str, NULL, 16);
   601 		return val >= sym_get_range_val(prop->expr->left.sym, 16) &&
   602 		       val <= sym_get_range_val(prop->expr->right.sym, 16);
   603 	case S_BOOLEAN:
   604 	case S_TRISTATE:
   605 		switch (str[0]) {
   606 		case 'y': case 'Y':
   607 			return sym_tristate_within_range(sym, yes);
   608 		case 'm': case 'M':
   609 			return sym_tristate_within_range(sym, mod);
   610 		case 'n': case 'N':
   611 			return sym_tristate_within_range(sym, no);
   612 		}
   613 		return false;
   614 	default:
   615 		return false;
   616 	}
   617 }
   618 
   619 bool sym_set_string_value(struct symbol *sym, const char *newval)
   620 {
   621 	const char *oldval;
   622 	char *val;
   623 	int size;
   624 
   625 	switch (sym->type) {
   626 	case S_BOOLEAN:
   627 	case S_TRISTATE:
   628 		switch (newval[0]) {
   629 		case 'y': case 'Y':
   630 			return sym_set_tristate_value(sym, yes);
   631 		case 'm': case 'M':
   632 			return sym_set_tristate_value(sym, mod);
   633 		case 'n': case 'N':
   634 			return sym_set_tristate_value(sym, no);
   635 		}
   636 		return false;
   637 	default:
   638 		;
   639 	}
   640 
   641 	if (!sym_string_within_range(sym, newval))
   642 		return false;
   643 
   644 	if (!(sym->flags & SYMBOL_DEF_USER)) {
   645 		sym->flags |= SYMBOL_DEF_USER;
   646 		sym_set_changed(sym);
   647 	}
   648 
   649 	oldval = sym->def[S_DEF_USER].val;
   650 	size = strlen(newval) + 1;
   651 	if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) {
   652 		size += 2;
   653 		sym->def[S_DEF_USER].val = val = malloc(size);
   654 		*val++ = '0';
   655 		*val++ = 'x';
   656 	} else if (!oldval || strcmp(oldval, newval))
   657 		sym->def[S_DEF_USER].val = val = malloc(size);
   658 	else
   659 		return true;
   660 
   661 	strcpy(val, newval);
   662 	free((void *)oldval);
   663 	sym_clear_all_valid();
   664 
   665 	return true;
   666 }
   667 
   668 /*
   669  * Find the default value associated to a symbol.
   670  * For tristate symbol handle the modules=n case
   671  * in which case "m" becomes "y".
   672  * If the symbol does not have any default then fallback
   673  * to the fixed default values.
   674  */
   675 const char *sym_get_string_default(struct symbol *sym)
   676 {
   677 	struct property *prop;
   678 	struct symbol *ds;
   679 	const char *str;
   680 	tristate val;
   681 
   682 	sym_calc_visibility(sym);
   683 	sym_calc_value(modules_sym);
   684 	val = symbol_no.curr.tri;
   685 	str = symbol_empty.curr.val;
   686 
   687 	/* If symbol has a default value look it up */
   688 	prop = sym_get_default_prop(sym);
   689 	if (prop != NULL) {
   690 		switch (sym->type) {
   691 		case S_BOOLEAN:
   692 		case S_TRISTATE:
   693 			/* The visibility may limit the value from yes => mod */
   694 			val = EXPR_AND(expr_calc_value(prop->expr), prop->visible.tri);
   695 			break;
   696 		default:
   697 			/*
   698 			 * The following fails to handle the situation
   699 			 * where a default value is further limited by
   700 			 * the valid range.
   701 			 */
   702 			ds = prop_get_symbol(prop);
   703 			if (ds != NULL) {
   704 				sym_calc_value(ds);
   705 				str = (const char *)ds->curr.val;
   706 			}
   707 		}
   708 	}
   709 
   710 	/* Handle select statements */
   711 	val = EXPR_OR(val, sym->rev_dep.tri);
   712 
   713 	/* transpose mod to yes if modules are not enabled */
   714 	if (val == mod)
   715 		if (!sym_is_choice_value(sym) && modules_sym->curr.tri == no)
   716 			val = yes;
   717 
   718 	/* transpose mod to yes if type is bool */
   719 	if (sym->type == S_BOOLEAN && val == mod)
   720 		val = yes;
   721 
   722 	switch (sym->type) {
   723 	case S_BOOLEAN:
   724 	case S_TRISTATE:
   725 		switch (val) {
   726 		case no: return "n";
   727 		case mod: return "m";
   728 		case yes: return "y";
   729 		}
   730 	case S_INT:
   731 	case S_HEX:
   732 		return str;
   733 	case S_STRING:
   734 		return str;
   735 	case S_OTHER:
   736 	case S_UNKNOWN:
   737 		break;
   738 	}
   739 	return "";
   740 }
   741 
   742 const char *sym_get_string_value(struct symbol *sym)
   743 {
   744 	tristate val;
   745 
   746 	switch (sym->type) {
   747 	case S_BOOLEAN:
   748 	case S_TRISTATE:
   749 		val = sym_get_tristate_value(sym);
   750 		switch (val) {
   751 		case no:
   752 			return "n";
   753 		case mod:
   754 			return "m";
   755 		case yes:
   756 			return "y";
   757 		}
   758 		break;
   759 	default:
   760 		;
   761 	}
   762 	return (const char *)sym->curr.val;
   763 }
   764 
   765 bool sym_is_changable(struct symbol *sym)
   766 {
   767 	return sym->visible > sym->rev_dep.tri;
   768 }
   769 
   770 static unsigned strhash(const char *s)
   771 {
   772 	/* fnv32 hash */
   773 	unsigned hash = 2166136261U;
   774 	for (; *s; s++)
   775 		hash = (hash ^ *s) * 0x01000193;
   776 	return hash;
   777 }
   778 
   779 struct symbol *sym_lookup(const char *name, int flags)
   780 {
   781 	struct symbol *symbol;
   782 	char *new_name;
   783 	int hash;
   784 
   785 	if (name) {
   786 		if (name[0] && !name[1]) {
   787 			switch (name[0]) {
   788 			case 'y': return &symbol_yes;
   789 			case 'm': return &symbol_mod;
   790 			case 'n': return &symbol_no;
   791 			}
   792 		}
   793 		hash = strhash(name) % SYMBOL_HASHSIZE;
   794 
   795 		for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
   796 			if (symbol->name &&
   797 			    !strcmp(symbol->name, name) &&
   798 			    (flags ? symbol->flags & flags
   799 				   : !(symbol->flags & (SYMBOL_CONST|SYMBOL_CHOICE))))
   800 				return symbol;
   801 		}
   802 		new_name = strdup(name);
   803 	} else {
   804 		new_name = NULL;
   805 		hash = 0;
   806 	}
   807 
   808 	symbol = malloc(sizeof(*symbol));
   809 	memset(symbol, 0, sizeof(*symbol));
   810 	symbol->name = new_name;
   811 	symbol->type = S_UNKNOWN;
   812 	symbol->flags |= flags;
   813 
   814 	symbol->next = symbol_hash[hash];
   815 	symbol_hash[hash] = symbol;
   816 
   817 	return symbol;
   818 }
   819 
   820 struct symbol *sym_find(const char *name)
   821 {
   822 	struct symbol *symbol = NULL;
   823 	int hash = 0;
   824 
   825 	if (!name)
   826 		return NULL;
   827 
   828 	if (name[0] && !name[1]) {
   829 		switch (name[0]) {
   830 		case 'y': return &symbol_yes;
   831 		case 'm': return &symbol_mod;
   832 		case 'n': return &symbol_no;
   833 		}
   834 	}
   835 	hash = strhash(name) % SYMBOL_HASHSIZE;
   836 
   837 	for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
   838 		if (symbol->name &&
   839 		    !strcmp(symbol->name, name) &&
   840 		    !(symbol->flags & SYMBOL_CONST))
   841 				break;
   842 	}
   843 
   844 	return symbol;
   845 }
   846 
   847 /*
   848  * Expand symbol's names embedded in the string given in argument. Symbols'
   849  * name to be expanded shall be prefixed by a '$'. Unknown symbol expands to
   850  * the empty string.
   851  */
   852 const char *sym_expand_string_value(const char *in)
   853 {
   854 	const char *src;
   855 	char *res;
   856 	size_t reslen;
   857 
   858 	reslen = strlen(in) + 1;
   859 	res = malloc(reslen);
   860 	res[0] = '\0';
   861 
   862 	while ((src = strchr(in, '$'))) {
   863 		char *p, name[SYMBOL_MAXLENGTH];
   864 		const char *symval = "";
   865 		struct symbol *sym;
   866 		size_t newlen;
   867 
   868 		strncat(res, in, src - in);
   869 		src++;
   870 
   871 		p = name;
   872 		while (isalnum(*src) || *src == '_')
   873 			*p++ = *src++;
   874 		*p = '\0';
   875 
   876 		sym = sym_find(name);
   877 		if (sym != NULL) {
   878 			sym_calc_value(sym);
   879 			symval = sym_get_string_value(sym);
   880 		}
   881 
   882 		newlen = strlen(res) + strlen(symval) + strlen(src) + 1;
   883 		if (newlen > reslen) {
   884 			reslen = newlen;
   885 			res = realloc(res, reslen);
   886 		}
   887 
   888 		strcat(res, symval);
   889 		in = src;
   890 	}
   891 	strcat(res, in);
   892 
   893 	return res;
   894 }
   895 
   896 struct symbol **sym_re_search(const char *pattern)
   897 {
   898 	struct symbol *sym, **sym_arr = NULL;
   899 	int i, cnt, size;
   900 	regex_t re;
   901 
   902 	cnt = size = 0;
   903 	/* Skip if empty */
   904 	if (strlen(pattern) == 0)
   905 		return NULL;
   906 	if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB|REG_ICASE))
   907 		return NULL;
   908 
   909 	for_all_symbols(i, sym) {
   910 		if (sym->flags & SYMBOL_CONST || !sym->name)
   911 			continue;
   912 		if (regexec(&re, sym->name, 0, NULL, 0))
   913 			continue;
   914 		if (cnt + 1 >= size) {
   915 			void *tmp = sym_arr;
   916 			size += 16;
   917 			sym_arr = realloc(sym_arr, size * sizeof(struct symbol *));
   918 			if (!sym_arr) {
   919 				free(tmp);
   920 				return NULL;
   921 			}
   922 		}
   923 		sym_calc_value(sym);
   924 		sym_arr[cnt++] = sym;
   925 	}
   926 	if (sym_arr)
   927 		sym_arr[cnt] = NULL;
   928 	regfree(&re);
   929 
   930 	return sym_arr;
   931 }
   932 
   933 /*
   934  * When we check for recursive dependencies we use a stack to save
   935  * current state so we can print out relevant info to user.
   936  * The entries are located on the call stack so no need to free memory.
   937  * Note inser() remove() must always match to properly clear the stack.
   938  */
   939 static struct dep_stack {
   940 	struct dep_stack *prev, *next;
   941 	struct symbol *sym;
   942 	struct property *prop;
   943 	struct expr *expr;
   944 } *check_top;
   945 
   946 static void dep_stack_insert(struct dep_stack *stack, struct symbol *sym)
   947 {
   948 	memset(stack, 0, sizeof(*stack));
   949 	if (check_top)
   950 		check_top->next = stack;
   951 	stack->prev = check_top;
   952 	stack->sym = sym;
   953 	check_top = stack;
   954 }
   955 
   956 static void dep_stack_remove(void)
   957 {
   958 	check_top = check_top->prev;
   959 	if (check_top)
   960 		check_top->next = NULL;
   961 }
   962 
   963 /*
   964  * Called when we have detected a recursive dependency.
   965  * check_top point to the top of the stact so we use
   966  * the ->prev pointer to locate the bottom of the stack.
   967  */
   968 static void sym_check_print_recursive(struct symbol *last_sym)
   969 {
   970 	struct dep_stack *stack;
   971 	struct symbol *sym, *next_sym;
   972 	struct menu *menu = NULL;
   973 	struct property *prop;
   974 	struct dep_stack cv_stack;
   975 
   976 	if (sym_is_choice_value(last_sym)) {
   977 		dep_stack_insert(&cv_stack, last_sym);
   978 		last_sym = prop_get_symbol(sym_get_choice_prop(last_sym));
   979 	}
   980 
   981 	for (stack = check_top; stack != NULL; stack = stack->prev)
   982 		if (stack->sym == last_sym)
   983 			break;
   984 	if (!stack) {
   985 		fprintf(stderr, "unexpected recursive dependency error\n");
   986 		return;
   987 	}
   988 
   989 	for (; stack; stack = stack->next) {
   990 		sym = stack->sym;
   991 		next_sym = stack->next ? stack->next->sym : last_sym;
   992 		prop = stack->prop;
   993 		if (prop == NULL)
   994 			prop = stack->sym->prop;
   995 
   996 		/* for choice values find the menu entry (used below) */
   997 		if (sym_is_choice(sym) || sym_is_choice_value(sym)) {
   998 			for (prop = sym->prop; prop; prop = prop->next) {
   999 				menu = prop->menu;
  1000 				if (prop->menu)
  1001 					break;
  1002 			}
  1003 		}
  1004 		if (stack->sym == last_sym)
  1005 			fprintf(stderr, "%s:%d:error: recursive dependency detected!\n",
  1006 				prop->file->name, prop->lineno);
  1007 		if (stack->expr) {
  1008 			fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n",
  1009 				prop->file->name, prop->lineno,
  1010 				sym->name ? sym->name : "<choice>",
  1011 				prop_get_type_name(prop->type),
  1012 				next_sym->name ? next_sym->name : "<choice>");
  1013 		} else if (stack->prop) {
  1014 			fprintf(stderr, "%s:%d:\tsymbol %s depends on %s\n",
  1015 				prop->file->name, prop->lineno,
  1016 				sym->name ? sym->name : "<choice>",
  1017 				next_sym->name ? next_sym->name : "<choice>");
  1018 		} else if (sym_is_choice(sym)) {
  1019 			fprintf(stderr, "%s:%d:\tchoice %s contains symbol %s\n",
  1020 				menu->file->name, menu->lineno,
  1021 				sym->name ? sym->name : "<choice>",
  1022 				next_sym->name ? next_sym->name : "<choice>");
  1023 		} else if (sym_is_choice_value(sym)) {
  1024 			fprintf(stderr, "%s:%d:\tsymbol %s is part of choice %s\n",
  1025 				menu->file->name, menu->lineno,
  1026 				sym->name ? sym->name : "<choice>",
  1027 				next_sym->name ? next_sym->name : "<choice>");
  1028 		} else {
  1029 			fprintf(stderr, "%s:%d:\tsymbol %s is selected by %s\n",
  1030 				prop->file->name, prop->lineno,
  1031 				sym->name ? sym->name : "<choice>",
  1032 				next_sym->name ? next_sym->name : "<choice>");
  1033 		}
  1034 	}
  1035 
  1036 	if (check_top == &cv_stack)
  1037 		dep_stack_remove();
  1038 }
  1039 
  1040 static struct symbol *sym_check_expr_deps(struct expr *e)
  1041 {
  1042 	struct symbol *sym;
  1043 
  1044 	if (!e)
  1045 		return NULL;
  1046 	switch (e->type) {
  1047 	case E_OR:
  1048 	case E_AND:
  1049 		sym = sym_check_expr_deps(e->left.expr);
  1050 		if (sym)
  1051 			return sym;
  1052 		return sym_check_expr_deps(e->right.expr);
  1053 	case E_NOT:
  1054 		return sym_check_expr_deps(e->left.expr);
  1055 	case E_EQUAL:
  1056 	case E_UNEQUAL:
  1057 		sym = sym_check_deps(e->left.sym);
  1058 		if (sym)
  1059 			return sym;
  1060 		return sym_check_deps(e->right.sym);
  1061 	case E_SYMBOL:
  1062 		return sym_check_deps(e->left.sym);
  1063 	default:
  1064 		break;
  1065 	}
  1066 	printf("Oops! How to check %d?\n", e->type);
  1067 	return NULL;
  1068 }
  1069 
  1070 /* return NULL when dependencies are OK */
  1071 static struct symbol *sym_check_sym_deps(struct symbol *sym)
  1072 {
  1073 	struct symbol *sym2;
  1074 	struct property *prop;
  1075 	struct dep_stack stack;
  1076 
  1077 	dep_stack_insert(&stack, sym);
  1078 
  1079 	sym2 = sym_check_expr_deps(sym->rev_dep.expr);
  1080 	if (sym2)
  1081 		goto out;
  1082 
  1083 	for (prop = sym->prop; prop; prop = prop->next) {
  1084 		if (prop->type == P_CHOICE || prop->type == P_SELECT)
  1085 			continue;
  1086 		stack.prop = prop;
  1087 		sym2 = sym_check_expr_deps(prop->visible.expr);
  1088 		if (sym2)
  1089 			break;
  1090 		if (prop->type != P_DEFAULT || sym_is_choice(sym))
  1091 			continue;
  1092 		stack.expr = prop->expr;
  1093 		sym2 = sym_check_expr_deps(prop->expr);
  1094 		if (sym2)
  1095 			break;
  1096 		stack.expr = NULL;
  1097 	}
  1098 
  1099 out:
  1100 	dep_stack_remove();
  1101 
  1102 	return sym2;
  1103 }
  1104 
  1105 static struct symbol *sym_check_choice_deps(struct symbol *choice)
  1106 {
  1107 	struct symbol *sym, *sym2;
  1108 	struct property *prop;
  1109 	struct expr *e;
  1110 	struct dep_stack stack;
  1111 
  1112 	dep_stack_insert(&stack, choice);
  1113 
  1114 	prop = sym_get_choice_prop(choice);
  1115 	expr_list_for_each_sym(prop->expr, e, sym)
  1116 		sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
  1117 
  1118 	choice->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
  1119 	sym2 = sym_check_sym_deps(choice);
  1120 	choice->flags &= ~SYMBOL_CHECK;
  1121 	if (sym2)
  1122 		goto out;
  1123 
  1124 	expr_list_for_each_sym(prop->expr, e, sym) {
  1125 		sym2 = sym_check_sym_deps(sym);
  1126 		if (sym2)
  1127 			break;
  1128 	}
  1129 out:
  1130 	expr_list_for_each_sym(prop->expr, e, sym)
  1131 		sym->flags &= ~SYMBOL_CHECK;
  1132 
  1133 	if (sym2 && sym_is_choice_value(sym2) &&
  1134 	    prop_get_symbol(sym_get_choice_prop(sym2)) == choice)
  1135 		sym2 = choice;
  1136 
  1137 	dep_stack_remove();
  1138 
  1139 	return sym2;
  1140 }
  1141 
  1142 struct symbol *sym_check_deps(struct symbol *sym)
  1143 {
  1144 	struct symbol *sym2;
  1145 	struct property *prop;
  1146 
  1147 	if (sym->flags & SYMBOL_CHECK) {
  1148 		sym_check_print_recursive(sym);
  1149 		return sym;
  1150 	}
  1151 	if (sym->flags & SYMBOL_CHECKED)
  1152 		return NULL;
  1153 
  1154 	if (sym_is_choice_value(sym)) {
  1155 		struct dep_stack stack;
  1156 
  1157 		/* for choice groups start the check with main choice symbol */
  1158 		dep_stack_insert(&stack, sym);
  1159 		prop = sym_get_choice_prop(sym);
  1160 		sym2 = sym_check_deps(prop_get_symbol(prop));
  1161 		dep_stack_remove();
  1162 	} else if (sym_is_choice(sym)) {
  1163 		sym2 = sym_check_choice_deps(sym);
  1164 	} else {
  1165 		sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
  1166 		sym2 = sym_check_sym_deps(sym);
  1167 		sym->flags &= ~SYMBOL_CHECK;
  1168 	}
  1169 
  1170 	if (sym2 && sym2 == sym)
  1171 		sym2 = NULL;
  1172 
  1173 	return sym2;
  1174 }
  1175 
  1176 struct property *prop_alloc(enum prop_type type, struct symbol *sym)
  1177 {
  1178 	struct property *prop;
  1179 	struct property **propp;
  1180 
  1181 	prop = malloc(sizeof(*prop));
  1182 	memset(prop, 0, sizeof(*prop));
  1183 	prop->type = type;
  1184 	prop->sym = sym;
  1185 	prop->file = current_file;
  1186 	prop->lineno = zconf_lineno();
  1187 
  1188 	/* append property to the prop list of symbol */
  1189 	if (sym) {
  1190 		for (propp = &sym->prop; *propp; propp = &(*propp)->next)
  1191 			;
  1192 		*propp = prop;
  1193 	}
  1194 
  1195 	return prop;
  1196 }
  1197 
  1198 struct symbol *prop_get_symbol(struct property *prop)
  1199 {
  1200 	if (prop->expr && (prop->expr->type == E_SYMBOL ||
  1201 			   prop->expr->type == E_LIST))
  1202 		return prop->expr->left.sym;
  1203 	return NULL;
  1204 }
  1205 
  1206 const char *prop_get_type_name(enum prop_type type)
  1207 {
  1208 	switch (type) {
  1209 	case P_PROMPT:
  1210 		return "prompt";
  1211 	case P_ENV:
  1212 		return "env";
  1213 	case P_COMMENT:
  1214 		return "comment";
  1215 	case P_MENU:
  1216 		return "menu";
  1217 	case P_DEFAULT:
  1218 		return "default";
  1219 	case P_CHOICE:
  1220 		return "choice";
  1221 	case P_SELECT:
  1222 		return "select";
  1223 	case P_RANGE:
  1224 		return "range";
  1225 	case P_SYMBOL:
  1226 		return "symbol";
  1227 	case P_UNKNOWN:
  1228 		break;
  1229 	}
  1230 	return "unknown";
  1231 }
  1232 
  1233 static void prop_add_env(const char *env)
  1234 {
  1235 	struct symbol *sym, *sym2;
  1236 	struct property *prop;
  1237 	char *p;
  1238 
  1239 	sym = current_entry->sym;
  1240 	sym->flags |= SYMBOL_AUTO;
  1241 	for_all_properties(sym, prop, P_ENV) {
  1242 		sym2 = prop_get_symbol(prop);
  1243 		if (strcmp(sym2->name, env))
  1244 			menu_warn(current_entry, "redefining environment symbol from %s",
  1245 				  sym2->name);
  1246 		return;
  1247 	}
  1248 
  1249 	prop = prop_alloc(P_ENV, sym);
  1250 	prop->expr = expr_alloc_symbol(sym_lookup(env, SYMBOL_CONST));
  1251 
  1252 	sym_env_list = expr_alloc_one(E_LIST, sym_env_list);
  1253 	sym_env_list->right.sym = sym;
  1254 
  1255 	p = getenv(env);
  1256 	if (p)
  1257 		sym_add_default(sym, p);
  1258 }