Merge patches sent by Robert P. J. Day <rpjday@mindspring.com>.
Warning: the buildroot folks purposedly removed the skip-comment patch but didn't really said why. Keeping it for the sake of having it in svn just in case (removing it will be easier thant not having it at all).
2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0.
10 #include <sys/utsname.h>
12 #define LKC_DIRECT_LINK
15 struct symbol symbol_yes = {
18 .flags = SYMBOL_CONST|SYMBOL_VALID,
22 .flags = SYMBOL_CONST|SYMBOL_VALID,
26 .flags = SYMBOL_CONST|SYMBOL_VALID,
30 .flags = SYMBOL_VALID,
33 struct symbol *sym_defconfig_list;
34 struct symbol *modules_sym;
37 void sym_add_default(struct symbol *sym, const char *def)
39 struct property *prop = prop_alloc(P_DEFAULT, sym);
41 prop->expr = expr_alloc_symbol(sym_lookup(def, 1));
49 static bool inited = false;
57 sym = sym_lookup("ARCH", 0);
59 sym->flags |= SYMBOL_AUTO;
62 sym_add_default(sym, p);
64 sym = sym_lookup("PROJECTVERSION", 0);
66 sym->flags |= SYMBOL_AUTO;
67 p = getenv("PROJECTVERSION");
69 sym_add_default(sym, p);
71 sym = sym_lookup("UNAME_RELEASE", 0);
73 sym->flags |= SYMBOL_AUTO;
74 sym_add_default(sym, uts.release);
77 enum symbol_type sym_get_type(struct symbol *sym)
79 enum symbol_type type = sym->type;
81 if (type == S_TRISTATE) {
82 if (sym_is_choice_value(sym) && sym->visible == yes)
84 else if (modules_val == no)
90 const char *sym_type_name(enum symbol_type type)
111 struct property *sym_get_choice_prop(struct symbol *sym)
113 struct property *prop;
115 for_all_choices(sym, prop)
120 struct property *sym_get_default_prop(struct symbol *sym)
122 struct property *prop;
124 for_all_defaults(sym, prop) {
125 prop->visible.tri = expr_calc_value(prop->visible.expr);
126 if (prop->visible.tri != no)
132 struct property *sym_get_range_prop(struct symbol *sym)
134 struct property *prop;
136 for_all_properties(sym, prop, P_RANGE) {
137 prop->visible.tri = expr_calc_value(prop->visible.expr);
138 if (prop->visible.tri != no)
144 static int sym_get_range_val(struct symbol *sym, int base)
157 return strtol(sym->curr.val, NULL, base);
160 static void sym_validate_range(struct symbol *sym)
162 struct property *prop;
176 prop = sym_get_range_prop(sym);
179 val = strtol(sym->curr.val, NULL, base);
180 val2 = sym_get_range_val(prop->expr->left.sym, base);
182 val2 = sym_get_range_val(prop->expr->right.sym, base);
186 if (sym->type == S_INT)
187 sprintf(str, "%d", val2);
189 sprintf(str, "0x%x", val2);
190 sym->curr.val = strdup(str);
193 static void sym_calc_visibility(struct symbol *sym)
195 struct property *prop;
198 /* any prompt visible? */
200 for_all_prompts(sym, prop) {
201 prop->visible.tri = expr_calc_value(prop->visible.expr);
202 tri = E_OR(tri, prop->visible.tri);
204 if (tri == mod && (sym->type != S_TRISTATE || modules_val == no))
206 if (sym->visible != tri) {
208 sym_set_changed(sym);
210 if (sym_is_choice_value(sym))
213 if (sym->rev_dep.expr)
214 tri = expr_calc_value(sym->rev_dep.expr);
215 if (tri == mod && sym_get_type(sym) == S_BOOLEAN)
217 if (sym->rev_dep.tri != tri) {
218 sym->rev_dep.tri = tri;
219 sym_set_changed(sym);
223 static struct symbol *sym_calc_choice(struct symbol *sym)
225 struct symbol *def_sym;
226 struct property *prop;
229 /* is the user choice visible? */
230 def_sym = sym->def[S_DEF_USER].val;
232 sym_calc_visibility(def_sym);
233 if (def_sym->visible != no)
237 /* any of the defaults visible? */
238 for_all_defaults(sym, prop) {
239 prop->visible.tri = expr_calc_value(prop->visible.expr);
240 if (prop->visible.tri == no)
242 def_sym = prop_get_symbol(prop);
243 sym_calc_visibility(def_sym);
244 if (def_sym->visible != no)
248 /* just get the first visible value */
249 prop = sym_get_choice_prop(sym);
250 for (e = prop->expr; e; e = e->left.expr) {
251 def_sym = e->right.sym;
252 sym_calc_visibility(def_sym);
253 if (def_sym->visible != no)
257 /* no choice? reset tristate value */
262 void sym_calc_value(struct symbol *sym)
264 struct symbol_value newval, oldval;
265 struct property *prop;
271 if (sym->flags & SYMBOL_VALID)
273 sym->flags |= SYMBOL_VALID;
281 newval = symbol_empty.curr;
285 newval = symbol_no.curr;
288 sym->curr.val = sym->name;
292 if (!sym_is_choice_value(sym))
293 sym->flags &= ~SYMBOL_WRITE;
295 sym_calc_visibility(sym);
297 /* set default if recursively called */
300 switch (sym_get_type(sym)) {
303 if (sym_is_choice_value(sym) && sym->visible == yes) {
304 prop = sym_get_choice_prop(sym);
305 newval.tri = (prop_get_symbol(prop)->curr.val == sym) ? yes : no;
306 } else if (E_OR(sym->visible, sym->rev_dep.tri) != no) {
307 sym->flags |= SYMBOL_WRITE;
308 if (sym_has_value(sym))
309 newval.tri = sym->def[S_DEF_USER].tri;
310 else if (!sym_is_choice(sym)) {
311 prop = sym_get_default_prop(sym);
313 newval.tri = expr_calc_value(prop->expr);
315 newval.tri = E_OR(E_AND(newval.tri, sym->visible), sym->rev_dep.tri);
316 } else if (!sym_is_choice(sym)) {
317 prop = sym_get_default_prop(sym);
319 sym->flags |= SYMBOL_WRITE;
320 newval.tri = expr_calc_value(prop->expr);
323 if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN)
329 if (sym->visible != no) {
330 sym->flags |= SYMBOL_WRITE;
331 if (sym_has_value(sym)) {
332 newval.val = sym->def[S_DEF_USER].val;
336 prop = sym_get_default_prop(sym);
338 struct symbol *ds = prop_get_symbol(prop);
340 sym->flags |= SYMBOL_WRITE;
342 newval.val = ds->curr.val;
351 if (sym_is_choice(sym) && newval.tri == yes)
352 sym->curr.val = sym_calc_choice(sym);
353 sym_validate_range(sym);
355 if (memcmp(&oldval, &sym->curr, sizeof(oldval))) {
356 sym_set_changed(sym);
357 if (modules_sym == sym) {
358 sym_set_all_changed();
359 modules_val = modules_sym->curr.tri;
363 if (sym_is_choice(sym)) {
364 int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE);
365 prop = sym_get_choice_prop(sym);
366 for (e = prop->expr; e; e = e->left.expr) {
367 e->right.sym->flags |= flags;
368 if (flags & SYMBOL_CHANGED)
369 sym_set_changed(e->right.sym);
374 void sym_clear_all_valid(void)
379 for_all_symbols(i, sym)
380 sym->flags &= ~SYMBOL_VALID;
381 sym_add_change_count(1);
383 sym_calc_value(modules_sym);
386 void sym_set_changed(struct symbol *sym)
388 struct property *prop;
390 sym->flags |= SYMBOL_CHANGED;
391 for (prop = sym->prop; prop; prop = prop->next) {
393 prop->menu->flags |= MENU_CHANGED;
397 void sym_set_all_changed(void)
402 for_all_symbols(i, sym)
403 sym_set_changed(sym);
406 bool sym_tristate_within_range(struct symbol *sym, tristate val)
408 int type = sym_get_type(sym);
410 if (sym->visible == no)
413 if (type != S_BOOLEAN && type != S_TRISTATE)
416 if (type == S_BOOLEAN && val == mod)
418 if (sym->visible <= sym->rev_dep.tri)
420 if (sym_is_choice_value(sym) && sym->visible == yes)
422 return val >= sym->rev_dep.tri && val <= sym->visible;
425 bool sym_set_tristate_value(struct symbol *sym, tristate val)
427 tristate oldval = sym_get_tristate_value(sym);
429 if (oldval != val && !sym_tristate_within_range(sym, val))
432 if (!(sym->flags & SYMBOL_DEF_USER)) {
433 sym->flags |= SYMBOL_DEF_USER;
434 sym_set_changed(sym);
437 * setting a choice value also resets the new flag of the choice
438 * symbol and all other choice values.
440 if (sym_is_choice_value(sym) && val == yes) {
441 struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
442 struct property *prop;
445 cs->def[S_DEF_USER].val = sym;
446 cs->flags |= SYMBOL_DEF_USER;
447 prop = sym_get_choice_prop(cs);
448 for (e = prop->expr; e; e = e->left.expr) {
449 if (e->right.sym->visible != no)
450 e->right.sym->flags |= SYMBOL_DEF_USER;
454 sym->def[S_DEF_USER].tri = val;
456 sym_clear_all_valid();
461 tristate sym_toggle_tristate_value(struct symbol *sym)
463 tristate oldval, newval;
465 oldval = newval = sym_get_tristate_value(sym);
478 if (sym_set_tristate_value(sym, newval))
480 } while (oldval != newval);
484 bool sym_string_valid(struct symbol *sym, const char *str)
497 if (ch == '0' && *str != 0)
499 while ((ch = *str++)) {
505 if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
511 } while ((ch = *str++));
527 bool sym_string_within_range(struct symbol *sym, const char *str)
529 struct property *prop;
534 return sym_string_valid(sym, str);
536 if (!sym_string_valid(sym, str))
538 prop = sym_get_range_prop(sym);
541 val = strtol(str, NULL, 10);
542 return val >= sym_get_range_val(prop->expr->left.sym, 10) &&
543 val <= sym_get_range_val(prop->expr->right.sym, 10);
545 if (!sym_string_valid(sym, str))
547 prop = sym_get_range_prop(sym);
550 val = strtol(str, NULL, 16);
551 return val >= sym_get_range_val(prop->expr->left.sym, 16) &&
552 val <= sym_get_range_val(prop->expr->right.sym, 16);
557 return sym_tristate_within_range(sym, yes);
559 return sym_tristate_within_range(sym, mod);
561 return sym_tristate_within_range(sym, no);
569 bool sym_set_string_value(struct symbol *sym, const char *newval)
580 return sym_set_tristate_value(sym, yes);
582 return sym_set_tristate_value(sym, mod);
584 return sym_set_tristate_value(sym, no);
591 if (!sym_string_within_range(sym, newval))
594 if (!(sym->flags & SYMBOL_DEF_USER)) {
595 sym->flags |= SYMBOL_DEF_USER;
596 sym_set_changed(sym);
599 oldval = sym->def[S_DEF_USER].val;
600 size = strlen(newval) + 1;
601 if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) {
603 sym->def[S_DEF_USER].val = val = malloc(size);
606 } else if (!oldval || strcmp(oldval, newval))
607 sym->def[S_DEF_USER].val = val = malloc(size);
612 free((void *)oldval);
613 sym_clear_all_valid();
618 const char *sym_get_string_value(struct symbol *sym)
625 val = sym_get_tristate_value(sym);
638 return (const char *)sym->curr.val;
641 bool sym_is_changable(struct symbol *sym)
643 return sym->visible > sym->rev_dep.tri;
646 struct symbol *sym_lookup(const char *name, int isconst)
648 struct symbol *symbol;
654 if (name[0] && !name[1]) {
656 case 'y': return &symbol_yes;
657 case 'm': return &symbol_mod;
658 case 'n': return &symbol_no;
661 for (ptr = name; *ptr; ptr++)
665 for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
666 if (!strcmp(symbol->name, name)) {
667 if ((isconst && symbol->flags & SYMBOL_CONST) ||
668 (!isconst && !(symbol->flags & SYMBOL_CONST)))
672 new_name = strdup(name);
678 symbol = malloc(sizeof(*symbol));
679 memset(symbol, 0, sizeof(*symbol));
680 symbol->name = new_name;
681 symbol->type = S_UNKNOWN;
683 symbol->flags |= SYMBOL_CONST;
685 symbol->next = symbol_hash[hash];
686 symbol_hash[hash] = symbol;
691 struct symbol *sym_find(const char *name)
693 struct symbol *symbol = NULL;
700 if (name[0] && !name[1]) {
702 case 'y': return &symbol_yes;
703 case 'm': return &symbol_mod;
704 case 'n': return &symbol_no;
707 for (ptr = name; *ptr; ptr++)
711 for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
712 if (!strcmp(symbol->name, name) &&
713 !(symbol->flags & SYMBOL_CONST))
720 struct symbol **sym_re_search(const char *pattern)
722 struct symbol *sym, **sym_arr = NULL;
728 if (strlen(pattern) == 0)
730 if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB|REG_ICASE))
733 for_all_symbols(i, sym) {
734 if (sym->flags & SYMBOL_CONST || !sym->name)
736 if (regexec(&re, sym->name, 0, NULL, 0))
738 if (cnt + 1 >= size) {
741 sym_arr = realloc(sym_arr, size * sizeof(struct symbol *));
747 sym_arr[cnt++] = sym;
757 struct symbol *sym_check_deps(struct symbol *sym);
759 static struct symbol *sym_check_expr_deps(struct expr *e)
768 sym = sym_check_expr_deps(e->left.expr);
771 return sym_check_expr_deps(e->right.expr);
773 return sym_check_expr_deps(e->left.expr);
776 sym = sym_check_deps(e->left.sym);
779 return sym_check_deps(e->right.sym);
781 return sym_check_deps(e->left.sym);
785 printf("Oops! How to check %d?\n", e->type);
789 struct symbol *sym_check_deps(struct symbol *sym)
792 struct property *prop;
794 if (sym->flags & SYMBOL_CHECK) {
795 printf("Warning! Found recursive dependency: %s", sym->name);
798 if (sym->flags & SYMBOL_CHECKED)
801 sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
802 sym2 = sym_check_expr_deps(sym->rev_dep.expr);
806 for (prop = sym->prop; prop; prop = prop->next) {
807 if (prop->type == P_CHOICE || prop->type == P_SELECT)
809 sym2 = sym_check_expr_deps(prop->visible.expr);
812 if (prop->type != P_DEFAULT || sym_is_choice(sym))
814 sym2 = sym_check_expr_deps(prop->expr);
820 printf(" %s", sym->name);
826 sym->flags &= ~SYMBOL_CHECK;
830 struct property *prop_alloc(enum prop_type type, struct symbol *sym)
832 struct property *prop;
833 struct property **propp;
835 prop = malloc(sizeof(*prop));
836 memset(prop, 0, sizeof(*prop));
839 prop->file = current_file;
840 prop->lineno = zconf_lineno();
842 /* append property to the prop list of symbol */
844 for (propp = &sym->prop; *propp; propp = &(*propp)->next)
852 struct symbol *prop_get_symbol(struct property *prop)
854 if (prop->expr && (prop->expr->type == E_SYMBOL ||
855 prop->expr->type == E_CHOICE))
856 return prop->expr->left.sym;
860 const char *prop_get_type_name(enum prop_type type)