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