Commit 59e89e3ddf8523be39a8e0a66bacbbdd6a72d069

Authored by Sam Ravnborg
Committed by Michal Marek
1 parent 861b4ea4cc

kconfig: save location of config symbols

When we add a new config symbol save the file/line
so we later can refer to their location.

The information is saved as a property to a config symbol
because we may have multiple definitions of the same symbol.

This has the side-effect that a symbol always has
at least one property.

Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
Cc: Roman Zippel <zippel@linux-m68k.org>
Signed-off-by: Michal Marek <mmarek@suse.cz>

Showing 3 changed files with 5 additions and 0 deletions Inline Diff

scripts/kconfig/expr.h
1 /* 1 /*
2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> 2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0. 3 * Released under the terms of the GNU GPL v2.0.
4 */ 4 */
5 5
6 #ifndef EXPR_H 6 #ifndef EXPR_H
7 #define EXPR_H 7 #define EXPR_H
8 8
9 #ifdef __cplusplus 9 #ifdef __cplusplus
10 extern "C" { 10 extern "C" {
11 #endif 11 #endif
12 12
13 #include <stdio.h> 13 #include <stdio.h>
14 #ifndef __cplusplus 14 #ifndef __cplusplus
15 #include <stdbool.h> 15 #include <stdbool.h>
16 #endif 16 #endif
17 17
18 struct file { 18 struct file {
19 struct file *next; 19 struct file *next;
20 struct file *parent; 20 struct file *parent;
21 char *name; 21 char *name;
22 int lineno; 22 int lineno;
23 int flags; 23 int flags;
24 }; 24 };
25 25
26 #define FILE_BUSY 0x0001 26 #define FILE_BUSY 0x0001
27 #define FILE_SCANNED 0x0002 27 #define FILE_SCANNED 0x0002
28 28
29 typedef enum tristate { 29 typedef enum tristate {
30 no, mod, yes 30 no, mod, yes
31 } tristate; 31 } tristate;
32 32
33 enum expr_type { 33 enum expr_type {
34 E_NONE, E_OR, E_AND, E_NOT, E_EQUAL, E_UNEQUAL, E_LIST, E_SYMBOL, E_RANGE 34 E_NONE, E_OR, E_AND, E_NOT, E_EQUAL, E_UNEQUAL, E_LIST, E_SYMBOL, E_RANGE
35 }; 35 };
36 36
37 union expr_data { 37 union expr_data {
38 struct expr *expr; 38 struct expr *expr;
39 struct symbol *sym; 39 struct symbol *sym;
40 }; 40 };
41 41
42 struct expr { 42 struct expr {
43 enum expr_type type; 43 enum expr_type type;
44 union expr_data left, right; 44 union expr_data left, right;
45 }; 45 };
46 46
47 #define EXPR_OR(dep1, dep2) (((dep1)>(dep2))?(dep1):(dep2)) 47 #define EXPR_OR(dep1, dep2) (((dep1)>(dep2))?(dep1):(dep2))
48 #define EXPR_AND(dep1, dep2) (((dep1)<(dep2))?(dep1):(dep2)) 48 #define EXPR_AND(dep1, dep2) (((dep1)<(dep2))?(dep1):(dep2))
49 #define EXPR_NOT(dep) (2-(dep)) 49 #define EXPR_NOT(dep) (2-(dep))
50 50
51 #define expr_list_for_each_sym(l, e, s) \ 51 #define expr_list_for_each_sym(l, e, s) \
52 for (e = (l); e && (s = e->right.sym); e = e->left.expr) 52 for (e = (l); e && (s = e->right.sym); e = e->left.expr)
53 53
54 struct expr_value { 54 struct expr_value {
55 struct expr *expr; 55 struct expr *expr;
56 tristate tri; 56 tristate tri;
57 }; 57 };
58 58
59 struct symbol_value { 59 struct symbol_value {
60 void *val; 60 void *val;
61 tristate tri; 61 tristate tri;
62 }; 62 };
63 63
64 enum symbol_type { 64 enum symbol_type {
65 S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING, S_OTHER 65 S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING, S_OTHER
66 }; 66 };
67 67
68 /* enum values are used as index to symbol.def[] */ 68 /* enum values are used as index to symbol.def[] */
69 enum { 69 enum {
70 S_DEF_USER, /* main user value */ 70 S_DEF_USER, /* main user value */
71 S_DEF_AUTO, /* values read from auto.conf */ 71 S_DEF_AUTO, /* values read from auto.conf */
72 S_DEF_DEF3, /* Reserved for UI usage */ 72 S_DEF_DEF3, /* Reserved for UI usage */
73 S_DEF_DEF4, /* Reserved for UI usage */ 73 S_DEF_DEF4, /* Reserved for UI usage */
74 S_DEF_COUNT 74 S_DEF_COUNT
75 }; 75 };
76 76
77 struct symbol { 77 struct symbol {
78 struct symbol *next; 78 struct symbol *next;
79 char *name; 79 char *name;
80 enum symbol_type type; 80 enum symbol_type type;
81 struct symbol_value curr; 81 struct symbol_value curr;
82 struct symbol_value def[S_DEF_COUNT]; 82 struct symbol_value def[S_DEF_COUNT];
83 tristate visible; 83 tristate visible;
84 int flags; 84 int flags;
85 struct property *prop; 85 struct property *prop;
86 struct expr_value dir_dep; 86 struct expr_value dir_dep;
87 struct expr_value rev_dep; 87 struct expr_value rev_dep;
88 }; 88 };
89 89
90 #define for_all_symbols(i, sym) for (i = 0; i < SYMBOL_HASHSIZE; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER) 90 #define for_all_symbols(i, sym) for (i = 0; i < SYMBOL_HASHSIZE; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER)
91 91
92 #define SYMBOL_CONST 0x0001 /* symbol is const */ 92 #define SYMBOL_CONST 0x0001 /* symbol is const */
93 #define SYMBOL_CHECK 0x0008 /* used during dependency checking */ 93 #define SYMBOL_CHECK 0x0008 /* used during dependency checking */
94 #define SYMBOL_CHOICE 0x0010 /* start of a choice block (null name) */ 94 #define SYMBOL_CHOICE 0x0010 /* start of a choice block (null name) */
95 #define SYMBOL_CHOICEVAL 0x0020 /* used as a value in a choice block */ 95 #define SYMBOL_CHOICEVAL 0x0020 /* used as a value in a choice block */
96 #define SYMBOL_VALID 0x0080 /* set when symbol.curr is calculated */ 96 #define SYMBOL_VALID 0x0080 /* set when symbol.curr is calculated */
97 #define SYMBOL_OPTIONAL 0x0100 /* choice is optional - values can be 'n' */ 97 #define SYMBOL_OPTIONAL 0x0100 /* choice is optional - values can be 'n' */
98 #define SYMBOL_WRITE 0x0200 /* ? */ 98 #define SYMBOL_WRITE 0x0200 /* ? */
99 #define SYMBOL_CHANGED 0x0400 /* ? */ 99 #define SYMBOL_CHANGED 0x0400 /* ? */
100 #define SYMBOL_AUTO 0x1000 /* value from environment variable */ 100 #define SYMBOL_AUTO 0x1000 /* value from environment variable */
101 #define SYMBOL_CHECKED 0x2000 /* used during dependency checking */ 101 #define SYMBOL_CHECKED 0x2000 /* used during dependency checking */
102 #define SYMBOL_WARNED 0x8000 /* warning has been issued */ 102 #define SYMBOL_WARNED 0x8000 /* warning has been issued */
103 103
104 /* Set when symbol.def[] is used */ 104 /* Set when symbol.def[] is used */
105 #define SYMBOL_DEF 0x10000 /* First bit of SYMBOL_DEF */ 105 #define SYMBOL_DEF 0x10000 /* First bit of SYMBOL_DEF */
106 #define SYMBOL_DEF_USER 0x10000 /* symbol.def[S_DEF_USER] is valid */ 106 #define SYMBOL_DEF_USER 0x10000 /* symbol.def[S_DEF_USER] is valid */
107 #define SYMBOL_DEF_AUTO 0x20000 /* symbol.def[S_DEF_AUTO] is valid */ 107 #define SYMBOL_DEF_AUTO 0x20000 /* symbol.def[S_DEF_AUTO] is valid */
108 #define SYMBOL_DEF3 0x40000 /* symbol.def[S_DEF_3] is valid */ 108 #define SYMBOL_DEF3 0x40000 /* symbol.def[S_DEF_3] is valid */
109 #define SYMBOL_DEF4 0x80000 /* symbol.def[S_DEF_4] is valid */ 109 #define SYMBOL_DEF4 0x80000 /* symbol.def[S_DEF_4] is valid */
110 110
111 #define SYMBOL_MAXLENGTH 256 111 #define SYMBOL_MAXLENGTH 256
112 #define SYMBOL_HASHSIZE 9973 112 #define SYMBOL_HASHSIZE 9973
113 113
114 /* A property represent the config options that can be associated 114 /* A property represent the config options that can be associated
115 * with a config "symbol". 115 * with a config "symbol".
116 * Sample: 116 * Sample:
117 * config FOO 117 * config FOO
118 * default y 118 * default y
119 * prompt "foo prompt" 119 * prompt "foo prompt"
120 * select BAR 120 * select BAR
121 * config BAZ 121 * config BAZ
122 * int "BAZ Value" 122 * int "BAZ Value"
123 * range 1..255 123 * range 1..255
124 */ 124 */
125 enum prop_type { 125 enum prop_type {
126 P_UNKNOWN, 126 P_UNKNOWN,
127 P_PROMPT, /* prompt "foo prompt" or "BAZ Value" */ 127 P_PROMPT, /* prompt "foo prompt" or "BAZ Value" */
128 P_COMMENT, /* text associated with a comment */ 128 P_COMMENT, /* text associated with a comment */
129 P_MENU, /* prompt associated with a menuconfig option */ 129 P_MENU, /* prompt associated with a menuconfig option */
130 P_DEFAULT, /* default y */ 130 P_DEFAULT, /* default y */
131 P_CHOICE, /* choice value */ 131 P_CHOICE, /* choice value */
132 P_SELECT, /* select BAR */ 132 P_SELECT, /* select BAR */
133 P_RANGE, /* range 7..100 (for a symbol) */ 133 P_RANGE, /* range 7..100 (for a symbol) */
134 P_ENV, /* value from environment variable */ 134 P_ENV, /* value from environment variable */
135 P_SYMBOL, /* where a symbol is defined */
135 }; 136 };
136 137
137 struct property { 138 struct property {
138 struct property *next; /* next property - null if last */ 139 struct property *next; /* next property - null if last */
139 struct symbol *sym; /* the symbol for which the property is associated */ 140 struct symbol *sym; /* the symbol for which the property is associated */
140 enum prop_type type; /* type of property */ 141 enum prop_type type; /* type of property */
141 const char *text; /* the prompt value - P_PROMPT, P_MENU, P_COMMENT */ 142 const char *text; /* the prompt value - P_PROMPT, P_MENU, P_COMMENT */
142 struct expr_value visible; 143 struct expr_value visible;
143 struct expr *expr; /* the optional conditional part of the property */ 144 struct expr *expr; /* the optional conditional part of the property */
144 struct menu *menu; /* the menu the property are associated with 145 struct menu *menu; /* the menu the property are associated with
145 * valid for: P_SELECT, P_RANGE, P_CHOICE, 146 * valid for: P_SELECT, P_RANGE, P_CHOICE,
146 * P_PROMPT, P_DEFAULT, P_MENU, P_COMMENT */ 147 * P_PROMPT, P_DEFAULT, P_MENU, P_COMMENT */
147 struct file *file; /* what file was this property defined */ 148 struct file *file; /* what file was this property defined */
148 int lineno; /* what lineno was this property defined */ 149 int lineno; /* what lineno was this property defined */
149 }; 150 };
150 151
151 #define for_all_properties(sym, st, tok) \ 152 #define for_all_properties(sym, st, tok) \
152 for (st = sym->prop; st; st = st->next) \ 153 for (st = sym->prop; st; st = st->next) \
153 if (st->type == (tok)) 154 if (st->type == (tok))
154 #define for_all_defaults(sym, st) for_all_properties(sym, st, P_DEFAULT) 155 #define for_all_defaults(sym, st) for_all_properties(sym, st, P_DEFAULT)
155 #define for_all_choices(sym, st) for_all_properties(sym, st, P_CHOICE) 156 #define for_all_choices(sym, st) for_all_properties(sym, st, P_CHOICE)
156 #define for_all_prompts(sym, st) \ 157 #define for_all_prompts(sym, st) \
157 for (st = sym->prop; st; st = st->next) \ 158 for (st = sym->prop; st; st = st->next) \
158 if (st->text) 159 if (st->text)
159 160
160 struct menu { 161 struct menu {
161 struct menu *next; 162 struct menu *next;
162 struct menu *parent; 163 struct menu *parent;
163 struct menu *list; 164 struct menu *list;
164 struct symbol *sym; 165 struct symbol *sym;
165 struct property *prompt; 166 struct property *prompt;
166 struct expr *dep; 167 struct expr *dep;
167 struct expr *dir_dep; 168 struct expr *dir_dep;
168 unsigned int flags; 169 unsigned int flags;
169 char *help; 170 char *help;
170 struct file *file; 171 struct file *file;
171 int lineno; 172 int lineno;
172 void *data; 173 void *data;
173 }; 174 };
174 175
175 #define MENU_CHANGED 0x0001 176 #define MENU_CHANGED 0x0001
176 #define MENU_ROOT 0x0002 177 #define MENU_ROOT 0x0002
177 178
178 #ifndef SWIG 179 #ifndef SWIG
179 180
180 extern struct file *file_list; 181 extern struct file *file_list;
181 extern struct file *current_file; 182 extern struct file *current_file;
182 struct file *lookup_file(const char *name); 183 struct file *lookup_file(const char *name);
183 184
184 extern struct symbol symbol_yes, symbol_no, symbol_mod; 185 extern struct symbol symbol_yes, symbol_no, symbol_mod;
185 extern struct symbol *modules_sym; 186 extern struct symbol *modules_sym;
186 extern struct symbol *sym_defconfig_list; 187 extern struct symbol *sym_defconfig_list;
187 extern int cdebug; 188 extern int cdebug;
188 struct expr *expr_alloc_symbol(struct symbol *sym); 189 struct expr *expr_alloc_symbol(struct symbol *sym);
189 struct expr *expr_alloc_one(enum expr_type type, struct expr *ce); 190 struct expr *expr_alloc_one(enum expr_type type, struct expr *ce);
190 struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2); 191 struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2);
191 struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2); 192 struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2);
192 struct expr *expr_alloc_and(struct expr *e1, struct expr *e2); 193 struct expr *expr_alloc_and(struct expr *e1, struct expr *e2);
193 struct expr *expr_alloc_or(struct expr *e1, struct expr *e2); 194 struct expr *expr_alloc_or(struct expr *e1, struct expr *e2);
194 struct expr *expr_copy(struct expr *org); 195 struct expr *expr_copy(struct expr *org);
195 void expr_free(struct expr *e); 196 void expr_free(struct expr *e);
196 int expr_eq(struct expr *e1, struct expr *e2); 197 int expr_eq(struct expr *e1, struct expr *e2);
197 void expr_eliminate_eq(struct expr **ep1, struct expr **ep2); 198 void expr_eliminate_eq(struct expr **ep1, struct expr **ep2);
198 tristate expr_calc_value(struct expr *e); 199 tristate expr_calc_value(struct expr *e);
199 struct expr *expr_eliminate_yn(struct expr *e); 200 struct expr *expr_eliminate_yn(struct expr *e);
200 struct expr *expr_trans_bool(struct expr *e); 201 struct expr *expr_trans_bool(struct expr *e);
201 struct expr *expr_eliminate_dups(struct expr *e); 202 struct expr *expr_eliminate_dups(struct expr *e);
202 struct expr *expr_transform(struct expr *e); 203 struct expr *expr_transform(struct expr *e);
203 int expr_contains_symbol(struct expr *dep, struct symbol *sym); 204 int expr_contains_symbol(struct expr *dep, struct symbol *sym);
204 bool expr_depends_symbol(struct expr *dep, struct symbol *sym); 205 bool expr_depends_symbol(struct expr *dep, struct symbol *sym);
205 struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2); 206 struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2);
206 struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2); 207 struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2);
207 void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2); 208 void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2);
208 struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym); 209 struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym);
209 210
210 void expr_fprint(struct expr *e, FILE *out); 211 void expr_fprint(struct expr *e, FILE *out);
211 struct gstr; /* forward */ 212 struct gstr; /* forward */
212 void expr_gstr_print(struct expr *e, struct gstr *gs); 213 void expr_gstr_print(struct expr *e, struct gstr *gs);
213 214
214 static inline int expr_is_yes(struct expr *e) 215 static inline int expr_is_yes(struct expr *e)
215 { 216 {
216 return !e || (e->type == E_SYMBOL && e->left.sym == &symbol_yes); 217 return !e || (e->type == E_SYMBOL && e->left.sym == &symbol_yes);
217 } 218 }
218 219
219 static inline int expr_is_no(struct expr *e) 220 static inline int expr_is_no(struct expr *e)
220 { 221 {
221 return e && (e->type == E_SYMBOL && e->left.sym == &symbol_no); 222 return e && (e->type == E_SYMBOL && e->left.sym == &symbol_no);
222 } 223 }
223 #endif 224 #endif
224 225
225 #ifdef __cplusplus 226 #ifdef __cplusplus
226 } 227 }
227 #endif 228 #endif
228 229
229 #endif /* EXPR_H */ 230 #endif /* EXPR_H */
230 231
scripts/kconfig/menu.c
1 /* 1 /*
2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> 2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0. 3 * Released under the terms of the GNU GPL v2.0.
4 */ 4 */
5 5
6 #include <stdlib.h> 6 #include <stdlib.h>
7 #include <string.h> 7 #include <string.h>
8 8
9 #define LKC_DIRECT_LINK 9 #define LKC_DIRECT_LINK
10 #include "lkc.h" 10 #include "lkc.h"
11 11
12 static const char nohelp_text[] = N_( 12 static const char nohelp_text[] = N_(
13 "There is no help available for this kernel option.\n"); 13 "There is no help available for this kernel option.\n");
14 14
15 struct menu rootmenu; 15 struct menu rootmenu;
16 static struct menu **last_entry_ptr; 16 static struct menu **last_entry_ptr;
17 17
18 struct file *file_list; 18 struct file *file_list;
19 struct file *current_file; 19 struct file *current_file;
20 20
21 void menu_warn(struct menu *menu, const char *fmt, ...) 21 void menu_warn(struct menu *menu, const char *fmt, ...)
22 { 22 {
23 va_list ap; 23 va_list ap;
24 va_start(ap, fmt); 24 va_start(ap, fmt);
25 fprintf(stderr, "%s:%d:warning: ", menu->file->name, menu->lineno); 25 fprintf(stderr, "%s:%d:warning: ", menu->file->name, menu->lineno);
26 vfprintf(stderr, fmt, ap); 26 vfprintf(stderr, fmt, ap);
27 fprintf(stderr, "\n"); 27 fprintf(stderr, "\n");
28 va_end(ap); 28 va_end(ap);
29 } 29 }
30 30
31 static void prop_warn(struct property *prop, const char *fmt, ...) 31 static void prop_warn(struct property *prop, const char *fmt, ...)
32 { 32 {
33 va_list ap; 33 va_list ap;
34 va_start(ap, fmt); 34 va_start(ap, fmt);
35 fprintf(stderr, "%s:%d:warning: ", prop->file->name, prop->lineno); 35 fprintf(stderr, "%s:%d:warning: ", prop->file->name, prop->lineno);
36 vfprintf(stderr, fmt, ap); 36 vfprintf(stderr, fmt, ap);
37 fprintf(stderr, "\n"); 37 fprintf(stderr, "\n");
38 va_end(ap); 38 va_end(ap);
39 } 39 }
40 40
41 void _menu_init(void) 41 void _menu_init(void)
42 { 42 {
43 current_entry = current_menu = &rootmenu; 43 current_entry = current_menu = &rootmenu;
44 last_entry_ptr = &rootmenu.list; 44 last_entry_ptr = &rootmenu.list;
45 } 45 }
46 46
47 void menu_add_entry(struct symbol *sym) 47 void menu_add_entry(struct symbol *sym)
48 { 48 {
49 struct menu *menu; 49 struct menu *menu;
50 50
51 menu = malloc(sizeof(*menu)); 51 menu = malloc(sizeof(*menu));
52 memset(menu, 0, sizeof(*menu)); 52 memset(menu, 0, sizeof(*menu));
53 menu->sym = sym; 53 menu->sym = sym;
54 menu->parent = current_menu; 54 menu->parent = current_menu;
55 menu->file = current_file; 55 menu->file = current_file;
56 menu->lineno = zconf_lineno(); 56 menu->lineno = zconf_lineno();
57 57
58 *last_entry_ptr = menu; 58 *last_entry_ptr = menu;
59 last_entry_ptr = &menu->next; 59 last_entry_ptr = &menu->next;
60 current_entry = menu; 60 current_entry = menu;
61 if (sym)
62 menu_add_symbol(P_SYMBOL, sym, NULL);
61 } 63 }
62 64
63 void menu_end_entry(void) 65 void menu_end_entry(void)
64 { 66 {
65 } 67 }
66 68
67 struct menu *menu_add_menu(void) 69 struct menu *menu_add_menu(void)
68 { 70 {
69 menu_end_entry(); 71 menu_end_entry();
70 last_entry_ptr = &current_entry->list; 72 last_entry_ptr = &current_entry->list;
71 return current_menu = current_entry; 73 return current_menu = current_entry;
72 } 74 }
73 75
74 void menu_end_menu(void) 76 void menu_end_menu(void)
75 { 77 {
76 last_entry_ptr = &current_menu->next; 78 last_entry_ptr = &current_menu->next;
77 current_menu = current_menu->parent; 79 current_menu = current_menu->parent;
78 } 80 }
79 81
80 static struct expr *menu_check_dep(struct expr *e) 82 static struct expr *menu_check_dep(struct expr *e)
81 { 83 {
82 if (!e) 84 if (!e)
83 return e; 85 return e;
84 86
85 switch (e->type) { 87 switch (e->type) {
86 case E_NOT: 88 case E_NOT:
87 e->left.expr = menu_check_dep(e->left.expr); 89 e->left.expr = menu_check_dep(e->left.expr);
88 break; 90 break;
89 case E_OR: 91 case E_OR:
90 case E_AND: 92 case E_AND:
91 e->left.expr = menu_check_dep(e->left.expr); 93 e->left.expr = menu_check_dep(e->left.expr);
92 e->right.expr = menu_check_dep(e->right.expr); 94 e->right.expr = menu_check_dep(e->right.expr);
93 break; 95 break;
94 case E_SYMBOL: 96 case E_SYMBOL:
95 /* change 'm' into 'm' && MODULES */ 97 /* change 'm' into 'm' && MODULES */
96 if (e->left.sym == &symbol_mod) 98 if (e->left.sym == &symbol_mod)
97 return expr_alloc_and(e, expr_alloc_symbol(modules_sym)); 99 return expr_alloc_and(e, expr_alloc_symbol(modules_sym));
98 break; 100 break;
99 default: 101 default:
100 break; 102 break;
101 } 103 }
102 return e; 104 return e;
103 } 105 }
104 106
105 void menu_add_dep(struct expr *dep) 107 void menu_add_dep(struct expr *dep)
106 { 108 {
107 current_entry->dep = expr_alloc_and(current_entry->dep, menu_check_dep(dep)); 109 current_entry->dep = expr_alloc_and(current_entry->dep, menu_check_dep(dep));
108 current_entry->dir_dep = current_entry->dep; 110 current_entry->dir_dep = current_entry->dep;
109 } 111 }
110 112
111 void menu_set_type(int type) 113 void menu_set_type(int type)
112 { 114 {
113 struct symbol *sym = current_entry->sym; 115 struct symbol *sym = current_entry->sym;
114 116
115 if (sym->type == type) 117 if (sym->type == type)
116 return; 118 return;
117 if (sym->type == S_UNKNOWN) { 119 if (sym->type == S_UNKNOWN) {
118 sym->type = type; 120 sym->type = type;
119 return; 121 return;
120 } 122 }
121 menu_warn(current_entry, "type of '%s' redefined from '%s' to '%s'", 123 menu_warn(current_entry, "type of '%s' redefined from '%s' to '%s'",
122 sym->name ? sym->name : "<choice>", 124 sym->name ? sym->name : "<choice>",
123 sym_type_name(sym->type), sym_type_name(type)); 125 sym_type_name(sym->type), sym_type_name(type));
124 } 126 }
125 127
126 struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep) 128 struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep)
127 { 129 {
128 struct property *prop = prop_alloc(type, current_entry->sym); 130 struct property *prop = prop_alloc(type, current_entry->sym);
129 131
130 prop->menu = current_entry; 132 prop->menu = current_entry;
131 prop->expr = expr; 133 prop->expr = expr;
132 prop->visible.expr = menu_check_dep(dep); 134 prop->visible.expr = menu_check_dep(dep);
133 135
134 if (prompt) { 136 if (prompt) {
135 if (isspace(*prompt)) { 137 if (isspace(*prompt)) {
136 prop_warn(prop, "leading whitespace ignored"); 138 prop_warn(prop, "leading whitespace ignored");
137 while (isspace(*prompt)) 139 while (isspace(*prompt))
138 prompt++; 140 prompt++;
139 } 141 }
140 if (current_entry->prompt) 142 if (current_entry->prompt)
141 prop_warn(prop, "prompt redefined"); 143 prop_warn(prop, "prompt redefined");
142 current_entry->prompt = prop; 144 current_entry->prompt = prop;
143 } 145 }
144 prop->text = prompt; 146 prop->text = prompt;
145 147
146 return prop; 148 return prop;
147 } 149 }
148 150
149 struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep) 151 struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep)
150 { 152 {
151 return menu_add_prop(type, prompt, NULL, dep); 153 return menu_add_prop(type, prompt, NULL, dep);
152 } 154 }
153 155
154 void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep) 156 void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep)
155 { 157 {
156 menu_add_prop(type, NULL, expr, dep); 158 menu_add_prop(type, NULL, expr, dep);
157 } 159 }
158 160
159 void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep) 161 void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep)
160 { 162 {
161 menu_add_prop(type, NULL, expr_alloc_symbol(sym), dep); 163 menu_add_prop(type, NULL, expr_alloc_symbol(sym), dep);
162 } 164 }
163 165
164 void menu_add_option(int token, char *arg) 166 void menu_add_option(int token, char *arg)
165 { 167 {
166 struct property *prop; 168 struct property *prop;
167 169
168 switch (token) { 170 switch (token) {
169 case T_OPT_MODULES: 171 case T_OPT_MODULES:
170 prop = prop_alloc(P_DEFAULT, modules_sym); 172 prop = prop_alloc(P_DEFAULT, modules_sym);
171 prop->expr = expr_alloc_symbol(current_entry->sym); 173 prop->expr = expr_alloc_symbol(current_entry->sym);
172 break; 174 break;
173 case T_OPT_DEFCONFIG_LIST: 175 case T_OPT_DEFCONFIG_LIST:
174 if (!sym_defconfig_list) 176 if (!sym_defconfig_list)
175 sym_defconfig_list = current_entry->sym; 177 sym_defconfig_list = current_entry->sym;
176 else if (sym_defconfig_list != current_entry->sym) 178 else if (sym_defconfig_list != current_entry->sym)
177 zconf_error("trying to redefine defconfig symbol"); 179 zconf_error("trying to redefine defconfig symbol");
178 break; 180 break;
179 case T_OPT_ENV: 181 case T_OPT_ENV:
180 prop_add_env(arg); 182 prop_add_env(arg);
181 break; 183 break;
182 } 184 }
183 } 185 }
184 186
185 static int menu_range_valid_sym(struct symbol *sym, struct symbol *sym2) 187 static int menu_range_valid_sym(struct symbol *sym, struct symbol *sym2)
186 { 188 {
187 return sym2->type == S_INT || sym2->type == S_HEX || 189 return sym2->type == S_INT || sym2->type == S_HEX ||
188 (sym2->type == S_UNKNOWN && sym_string_valid(sym, sym2->name)); 190 (sym2->type == S_UNKNOWN && sym_string_valid(sym, sym2->name));
189 } 191 }
190 192
191 static void sym_check_prop(struct symbol *sym) 193 static void sym_check_prop(struct symbol *sym)
192 { 194 {
193 struct property *prop; 195 struct property *prop;
194 struct symbol *sym2; 196 struct symbol *sym2;
195 for (prop = sym->prop; prop; prop = prop->next) { 197 for (prop = sym->prop; prop; prop = prop->next) {
196 switch (prop->type) { 198 switch (prop->type) {
197 case P_DEFAULT: 199 case P_DEFAULT:
198 if ((sym->type == S_STRING || sym->type == S_INT || sym->type == S_HEX) && 200 if ((sym->type == S_STRING || sym->type == S_INT || sym->type == S_HEX) &&
199 prop->expr->type != E_SYMBOL) 201 prop->expr->type != E_SYMBOL)
200 prop_warn(prop, 202 prop_warn(prop,
201 "default for config symbol '%s'" 203 "default for config symbol '%s'"
202 " must be a single symbol", sym->name); 204 " must be a single symbol", sym->name);
203 break; 205 break;
204 case P_SELECT: 206 case P_SELECT:
205 sym2 = prop_get_symbol(prop); 207 sym2 = prop_get_symbol(prop);
206 if (sym->type != S_BOOLEAN && sym->type != S_TRISTATE) 208 if (sym->type != S_BOOLEAN && sym->type != S_TRISTATE)
207 prop_warn(prop, 209 prop_warn(prop,
208 "config symbol '%s' uses select, but is " 210 "config symbol '%s' uses select, but is "
209 "not boolean or tristate", sym->name); 211 "not boolean or tristate", sym->name);
210 else if (sym2->type != S_UNKNOWN && 212 else if (sym2->type != S_UNKNOWN &&
211 sym2->type != S_BOOLEAN && 213 sym2->type != S_BOOLEAN &&
212 sym2->type != S_TRISTATE) 214 sym2->type != S_TRISTATE)
213 prop_warn(prop, 215 prop_warn(prop,
214 "'%s' has wrong type. 'select' only " 216 "'%s' has wrong type. 'select' only "
215 "accept arguments of boolean and " 217 "accept arguments of boolean and "
216 "tristate type", sym2->name); 218 "tristate type", sym2->name);
217 break; 219 break;
218 case P_RANGE: 220 case P_RANGE:
219 if (sym->type != S_INT && sym->type != S_HEX) 221 if (sym->type != S_INT && sym->type != S_HEX)
220 prop_warn(prop, "range is only allowed " 222 prop_warn(prop, "range is only allowed "
221 "for int or hex symbols"); 223 "for int or hex symbols");
222 if (!menu_range_valid_sym(sym, prop->expr->left.sym) || 224 if (!menu_range_valid_sym(sym, prop->expr->left.sym) ||
223 !menu_range_valid_sym(sym, prop->expr->right.sym)) 225 !menu_range_valid_sym(sym, prop->expr->right.sym))
224 prop_warn(prop, "range is invalid"); 226 prop_warn(prop, "range is invalid");
225 break; 227 break;
226 default: 228 default:
227 ; 229 ;
228 } 230 }
229 } 231 }
230 } 232 }
231 233
232 void menu_finalize(struct menu *parent) 234 void menu_finalize(struct menu *parent)
233 { 235 {
234 struct menu *menu, *last_menu; 236 struct menu *menu, *last_menu;
235 struct symbol *sym; 237 struct symbol *sym;
236 struct property *prop; 238 struct property *prop;
237 struct expr *parentdep, *basedep, *dep, *dep2, **ep; 239 struct expr *parentdep, *basedep, *dep, *dep2, **ep;
238 240
239 sym = parent->sym; 241 sym = parent->sym;
240 if (parent->list) { 242 if (parent->list) {
241 if (sym && sym_is_choice(sym)) { 243 if (sym && sym_is_choice(sym)) {
242 if (sym->type == S_UNKNOWN) { 244 if (sym->type == S_UNKNOWN) {
243 /* find the first choice value to find out choice type */ 245 /* find the first choice value to find out choice type */
244 current_entry = parent; 246 current_entry = parent;
245 for (menu = parent->list; menu; menu = menu->next) { 247 for (menu = parent->list; menu; menu = menu->next) {
246 if (menu->sym && menu->sym->type != S_UNKNOWN) { 248 if (menu->sym && menu->sym->type != S_UNKNOWN) {
247 menu_set_type(menu->sym->type); 249 menu_set_type(menu->sym->type);
248 break; 250 break;
249 } 251 }
250 } 252 }
251 } 253 }
252 /* set the type of the remaining choice values */ 254 /* set the type of the remaining choice values */
253 for (menu = parent->list; menu; menu = menu->next) { 255 for (menu = parent->list; menu; menu = menu->next) {
254 current_entry = menu; 256 current_entry = menu;
255 if (menu->sym && menu->sym->type == S_UNKNOWN) 257 if (menu->sym && menu->sym->type == S_UNKNOWN)
256 menu_set_type(sym->type); 258 menu_set_type(sym->type);
257 } 259 }
258 parentdep = expr_alloc_symbol(sym); 260 parentdep = expr_alloc_symbol(sym);
259 } else if (parent->prompt) 261 } else if (parent->prompt)
260 parentdep = parent->prompt->visible.expr; 262 parentdep = parent->prompt->visible.expr;
261 else 263 else
262 parentdep = parent->dep; 264 parentdep = parent->dep;
263 265
264 for (menu = parent->list; menu; menu = menu->next) { 266 for (menu = parent->list; menu; menu = menu->next) {
265 basedep = expr_transform(menu->dep); 267 basedep = expr_transform(menu->dep);
266 basedep = expr_alloc_and(expr_copy(parentdep), basedep); 268 basedep = expr_alloc_and(expr_copy(parentdep), basedep);
267 basedep = expr_eliminate_dups(basedep); 269 basedep = expr_eliminate_dups(basedep);
268 menu->dep = basedep; 270 menu->dep = basedep;
269 if (menu->sym) 271 if (menu->sym)
270 prop = menu->sym->prop; 272 prop = menu->sym->prop;
271 else 273 else
272 prop = menu->prompt; 274 prop = menu->prompt;
273 for (; prop; prop = prop->next) { 275 for (; prop; prop = prop->next) {
274 if (prop->menu != menu) 276 if (prop->menu != menu)
275 continue; 277 continue;
276 dep = expr_transform(prop->visible.expr); 278 dep = expr_transform(prop->visible.expr);
277 dep = expr_alloc_and(expr_copy(basedep), dep); 279 dep = expr_alloc_and(expr_copy(basedep), dep);
278 dep = expr_eliminate_dups(dep); 280 dep = expr_eliminate_dups(dep);
279 if (menu->sym && menu->sym->type != S_TRISTATE) 281 if (menu->sym && menu->sym->type != S_TRISTATE)
280 dep = expr_trans_bool(dep); 282 dep = expr_trans_bool(dep);
281 prop->visible.expr = dep; 283 prop->visible.expr = dep;
282 if (prop->type == P_SELECT) { 284 if (prop->type == P_SELECT) {
283 struct symbol *es = prop_get_symbol(prop); 285 struct symbol *es = prop_get_symbol(prop);
284 es->rev_dep.expr = expr_alloc_or(es->rev_dep.expr, 286 es->rev_dep.expr = expr_alloc_or(es->rev_dep.expr,
285 expr_alloc_and(expr_alloc_symbol(menu->sym), expr_copy(dep))); 287 expr_alloc_and(expr_alloc_symbol(menu->sym), expr_copy(dep)));
286 } 288 }
287 } 289 }
288 } 290 }
289 for (menu = parent->list; menu; menu = menu->next) 291 for (menu = parent->list; menu; menu = menu->next)
290 menu_finalize(menu); 292 menu_finalize(menu);
291 } else if (sym) { 293 } else if (sym) {
292 /* ignore inherited dependencies for dir_dep */ 294 /* ignore inherited dependencies for dir_dep */
293 sym->dir_dep.expr = expr_transform(expr_copy(parent->dir_dep)); 295 sym->dir_dep.expr = expr_transform(expr_copy(parent->dir_dep));
294 sym->dir_dep.expr = expr_eliminate_dups(sym->dir_dep.expr); 296 sym->dir_dep.expr = expr_eliminate_dups(sym->dir_dep.expr);
295 297
296 basedep = parent->prompt ? parent->prompt->visible.expr : NULL; 298 basedep = parent->prompt ? parent->prompt->visible.expr : NULL;
297 basedep = expr_trans_compare(basedep, E_UNEQUAL, &symbol_no); 299 basedep = expr_trans_compare(basedep, E_UNEQUAL, &symbol_no);
298 basedep = expr_eliminate_dups(expr_transform(basedep)); 300 basedep = expr_eliminate_dups(expr_transform(basedep));
299 last_menu = NULL; 301 last_menu = NULL;
300 for (menu = parent->next; menu; menu = menu->next) { 302 for (menu = parent->next; menu; menu = menu->next) {
301 dep = menu->prompt ? menu->prompt->visible.expr : menu->dep; 303 dep = menu->prompt ? menu->prompt->visible.expr : menu->dep;
302 if (!expr_contains_symbol(dep, sym)) 304 if (!expr_contains_symbol(dep, sym))
303 break; 305 break;
304 if (expr_depends_symbol(dep, sym)) 306 if (expr_depends_symbol(dep, sym))
305 goto next; 307 goto next;
306 dep = expr_trans_compare(dep, E_UNEQUAL, &symbol_no); 308 dep = expr_trans_compare(dep, E_UNEQUAL, &symbol_no);
307 dep = expr_eliminate_dups(expr_transform(dep)); 309 dep = expr_eliminate_dups(expr_transform(dep));
308 dep2 = expr_copy(basedep); 310 dep2 = expr_copy(basedep);
309 expr_eliminate_eq(&dep, &dep2); 311 expr_eliminate_eq(&dep, &dep2);
310 expr_free(dep); 312 expr_free(dep);
311 if (!expr_is_yes(dep2)) { 313 if (!expr_is_yes(dep2)) {
312 expr_free(dep2); 314 expr_free(dep2);
313 break; 315 break;
314 } 316 }
315 expr_free(dep2); 317 expr_free(dep2);
316 next: 318 next:
317 menu_finalize(menu); 319 menu_finalize(menu);
318 menu->parent = parent; 320 menu->parent = parent;
319 last_menu = menu; 321 last_menu = menu;
320 } 322 }
321 if (last_menu) { 323 if (last_menu) {
322 parent->list = parent->next; 324 parent->list = parent->next;
323 parent->next = last_menu->next; 325 parent->next = last_menu->next;
324 last_menu->next = NULL; 326 last_menu->next = NULL;
325 } 327 }
326 } 328 }
327 for (menu = parent->list; menu; menu = menu->next) { 329 for (menu = parent->list; menu; menu = menu->next) {
328 if (sym && sym_is_choice(sym) && 330 if (sym && sym_is_choice(sym) &&
329 menu->sym && !sym_is_choice_value(menu->sym)) { 331 menu->sym && !sym_is_choice_value(menu->sym)) {
330 current_entry = menu; 332 current_entry = menu;
331 menu->sym->flags |= SYMBOL_CHOICEVAL; 333 menu->sym->flags |= SYMBOL_CHOICEVAL;
332 if (!menu->prompt) 334 if (!menu->prompt)
333 menu_warn(menu, "choice value must have a prompt"); 335 menu_warn(menu, "choice value must have a prompt");
334 for (prop = menu->sym->prop; prop; prop = prop->next) { 336 for (prop = menu->sym->prop; prop; prop = prop->next) {
335 if (prop->type == P_DEFAULT) 337 if (prop->type == P_DEFAULT)
336 prop_warn(prop, "defaults for choice " 338 prop_warn(prop, "defaults for choice "
337 "values not supported"); 339 "values not supported");
338 if (prop->menu == menu) 340 if (prop->menu == menu)
339 continue; 341 continue;
340 if (prop->type == P_PROMPT && 342 if (prop->type == P_PROMPT &&
341 prop->menu->parent->sym != sym) 343 prop->menu->parent->sym != sym)
342 prop_warn(prop, "choice value used outside its choice group"); 344 prop_warn(prop, "choice value used outside its choice group");
343 } 345 }
344 /* Non-tristate choice values of tristate choices must 346 /* Non-tristate choice values of tristate choices must
345 * depend on the choice being set to Y. The choice 347 * depend on the choice being set to Y. The choice
346 * values' dependencies were propagated to their 348 * values' dependencies were propagated to their
347 * properties above, so the change here must be re- 349 * properties above, so the change here must be re-
348 * propagated. 350 * propagated.
349 */ 351 */
350 if (sym->type == S_TRISTATE && menu->sym->type != S_TRISTATE) { 352 if (sym->type == S_TRISTATE && menu->sym->type != S_TRISTATE) {
351 basedep = expr_alloc_comp(E_EQUAL, sym, &symbol_yes); 353 basedep = expr_alloc_comp(E_EQUAL, sym, &symbol_yes);
352 menu->dep = expr_alloc_and(basedep, menu->dep); 354 menu->dep = expr_alloc_and(basedep, menu->dep);
353 for (prop = menu->sym->prop; prop; prop = prop->next) { 355 for (prop = menu->sym->prop; prop; prop = prop->next) {
354 if (prop->menu != menu) 356 if (prop->menu != menu)
355 continue; 357 continue;
356 prop->visible.expr = expr_alloc_and(expr_copy(basedep), 358 prop->visible.expr = expr_alloc_and(expr_copy(basedep),
357 prop->visible.expr); 359 prop->visible.expr);
358 } 360 }
359 } 361 }
360 menu_add_symbol(P_CHOICE, sym, NULL); 362 menu_add_symbol(P_CHOICE, sym, NULL);
361 prop = sym_get_choice_prop(sym); 363 prop = sym_get_choice_prop(sym);
362 for (ep = &prop->expr; *ep; ep = &(*ep)->left.expr) 364 for (ep = &prop->expr; *ep; ep = &(*ep)->left.expr)
363 ; 365 ;
364 *ep = expr_alloc_one(E_LIST, NULL); 366 *ep = expr_alloc_one(E_LIST, NULL);
365 (*ep)->right.sym = menu->sym; 367 (*ep)->right.sym = menu->sym;
366 } 368 }
367 if (menu->list && (!menu->prompt || !menu->prompt->text)) { 369 if (menu->list && (!menu->prompt || !menu->prompt->text)) {
368 for (last_menu = menu->list; ; last_menu = last_menu->next) { 370 for (last_menu = menu->list; ; last_menu = last_menu->next) {
369 last_menu->parent = parent; 371 last_menu->parent = parent;
370 if (!last_menu->next) 372 if (!last_menu->next)
371 break; 373 break;
372 } 374 }
373 last_menu->next = menu->next; 375 last_menu->next = menu->next;
374 menu->next = menu->list; 376 menu->next = menu->list;
375 menu->list = NULL; 377 menu->list = NULL;
376 } 378 }
377 } 379 }
378 380
379 if (sym && !(sym->flags & SYMBOL_WARNED)) { 381 if (sym && !(sym->flags & SYMBOL_WARNED)) {
380 if (sym->type == S_UNKNOWN) 382 if (sym->type == S_UNKNOWN)
381 menu_warn(parent, "config symbol defined without type"); 383 menu_warn(parent, "config symbol defined without type");
382 384
383 if (sym_is_choice(sym) && !parent->prompt) 385 if (sym_is_choice(sym) && !parent->prompt)
384 menu_warn(parent, "choice must have a prompt"); 386 menu_warn(parent, "choice must have a prompt");
385 387
386 /* Check properties connected to this symbol */ 388 /* Check properties connected to this symbol */
387 sym_check_prop(sym); 389 sym_check_prop(sym);
388 sym->flags |= SYMBOL_WARNED; 390 sym->flags |= SYMBOL_WARNED;
389 } 391 }
390 392
391 if (sym && !sym_is_optional(sym) && parent->prompt) { 393 if (sym && !sym_is_optional(sym) && parent->prompt) {
392 sym->rev_dep.expr = expr_alloc_or(sym->rev_dep.expr, 394 sym->rev_dep.expr = expr_alloc_or(sym->rev_dep.expr,
393 expr_alloc_and(parent->prompt->visible.expr, 395 expr_alloc_and(parent->prompt->visible.expr,
394 expr_alloc_symbol(&symbol_mod))); 396 expr_alloc_symbol(&symbol_mod)));
395 } 397 }
396 } 398 }
397 399
398 bool menu_has_prompt(struct menu *menu) 400 bool menu_has_prompt(struct menu *menu)
399 { 401 {
400 if (!menu->prompt) 402 if (!menu->prompt)
401 return false; 403 return false;
402 return true; 404 return true;
403 } 405 }
404 406
405 bool menu_is_visible(struct menu *menu) 407 bool menu_is_visible(struct menu *menu)
406 { 408 {
407 struct menu *child; 409 struct menu *child;
408 struct symbol *sym; 410 struct symbol *sym;
409 tristate visible; 411 tristate visible;
410 412
411 if (!menu->prompt) 413 if (!menu->prompt)
412 return false; 414 return false;
413 415
414 sym = menu->sym; 416 sym = menu->sym;
415 if (sym) { 417 if (sym) {
416 sym_calc_value(sym); 418 sym_calc_value(sym);
417 visible = menu->prompt->visible.tri; 419 visible = menu->prompt->visible.tri;
418 } else 420 } else
419 visible = menu->prompt->visible.tri = expr_calc_value(menu->prompt->visible.expr); 421 visible = menu->prompt->visible.tri = expr_calc_value(menu->prompt->visible.expr);
420 422
421 if (visible != no) 423 if (visible != no)
422 return true; 424 return true;
423 425
424 if (!sym || sym_get_tristate_value(menu->sym) == no) 426 if (!sym || sym_get_tristate_value(menu->sym) == no)
425 return false; 427 return false;
426 428
427 for (child = menu->list; child; child = child->next) { 429 for (child = menu->list; child; child = child->next) {
428 if (menu_is_visible(child)) { 430 if (menu_is_visible(child)) {
429 if (sym) 431 if (sym)
430 sym->flags |= SYMBOL_DEF_USER; 432 sym->flags |= SYMBOL_DEF_USER;
431 return true; 433 return true;
432 } 434 }
433 } 435 }
434 436
435 return false; 437 return false;
436 } 438 }
437 439
438 const char *menu_get_prompt(struct menu *menu) 440 const char *menu_get_prompt(struct menu *menu)
439 { 441 {
440 if (menu->prompt) 442 if (menu->prompt)
441 return menu->prompt->text; 443 return menu->prompt->text;
442 else if (menu->sym) 444 else if (menu->sym)
443 return menu->sym->name; 445 return menu->sym->name;
444 return NULL; 446 return NULL;
445 } 447 }
446 448
447 struct menu *menu_get_root_menu(struct menu *menu) 449 struct menu *menu_get_root_menu(struct menu *menu)
448 { 450 {
449 return &rootmenu; 451 return &rootmenu;
450 } 452 }
451 453
452 struct menu *menu_get_parent_menu(struct menu *menu) 454 struct menu *menu_get_parent_menu(struct menu *menu)
453 { 455 {
454 enum prop_type type; 456 enum prop_type type;
455 457
456 for (; menu != &rootmenu; menu = menu->parent) { 458 for (; menu != &rootmenu; menu = menu->parent) {
457 type = menu->prompt ? menu->prompt->type : 0; 459 type = menu->prompt ? menu->prompt->type : 0;
458 if (type == P_MENU) 460 if (type == P_MENU)
459 break; 461 break;
460 } 462 }
461 return menu; 463 return menu;
462 } 464 }
463 465
464 bool menu_has_help(struct menu *menu) 466 bool menu_has_help(struct menu *menu)
465 { 467 {
466 return menu->help != NULL; 468 return menu->help != NULL;
467 } 469 }
468 470
469 const char *menu_get_help(struct menu *menu) 471 const char *menu_get_help(struct menu *menu)
470 { 472 {
471 if (menu->help) 473 if (menu->help)
472 return menu->help; 474 return menu->help;
473 else 475 else
474 return ""; 476 return "";
475 } 477 }
476 478
477 static void get_prompt_str(struct gstr *r, struct property *prop) 479 static void get_prompt_str(struct gstr *r, struct property *prop)
478 { 480 {
479 int i, j; 481 int i, j;
480 struct menu *submenu[8], *menu; 482 struct menu *submenu[8], *menu;
481 483
482 str_printf(r, _("Prompt: %s\n"), _(prop->text)); 484 str_printf(r, _("Prompt: %s\n"), _(prop->text));
483 str_printf(r, _(" Defined at %s:%d\n"), prop->menu->file->name, 485 str_printf(r, _(" Defined at %s:%d\n"), prop->menu->file->name,
484 prop->menu->lineno); 486 prop->menu->lineno);
485 if (!expr_is_yes(prop->visible.expr)) { 487 if (!expr_is_yes(prop->visible.expr)) {
486 str_append(r, _(" Depends on: ")); 488 str_append(r, _(" Depends on: "));
487 expr_gstr_print(prop->visible.expr, r); 489 expr_gstr_print(prop->visible.expr, r);
488 str_append(r, "\n"); 490 str_append(r, "\n");
489 } 491 }
490 menu = prop->menu->parent; 492 menu = prop->menu->parent;
491 for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent) 493 for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent)
492 submenu[i++] = menu; 494 submenu[i++] = menu;
493 if (i > 0) { 495 if (i > 0) {
494 str_printf(r, _(" Location:\n")); 496 str_printf(r, _(" Location:\n"));
495 for (j = 4; --i >= 0; j += 2) { 497 for (j = 4; --i >= 0; j += 2) {
496 menu = submenu[i]; 498 menu = submenu[i];
497 str_printf(r, "%*c-> %s", j, ' ', _(menu_get_prompt(menu))); 499 str_printf(r, "%*c-> %s", j, ' ', _(menu_get_prompt(menu)));
498 if (menu->sym) { 500 if (menu->sym) {
499 str_printf(r, " (%s [=%s])", menu->sym->name ? 501 str_printf(r, " (%s [=%s])", menu->sym->name ?
500 menu->sym->name : _("<choice>"), 502 menu->sym->name : _("<choice>"),
501 sym_get_string_value(menu->sym)); 503 sym_get_string_value(menu->sym));
502 } 504 }
503 str_append(r, "\n"); 505 str_append(r, "\n");
504 } 506 }
505 } 507 }
506 } 508 }
507 509
508 void get_symbol_str(struct gstr *r, struct symbol *sym) 510 void get_symbol_str(struct gstr *r, struct symbol *sym)
509 { 511 {
510 bool hit; 512 bool hit;
511 struct property *prop; 513 struct property *prop;
512 514
513 if (sym && sym->name) { 515 if (sym && sym->name) {
514 str_printf(r, "Symbol: %s [=%s]\n", sym->name, 516 str_printf(r, "Symbol: %s [=%s]\n", sym->name,
515 sym_get_string_value(sym)); 517 sym_get_string_value(sym));
516 str_printf(r, "Type : %s\n", sym_type_name(sym->type)); 518 str_printf(r, "Type : %s\n", sym_type_name(sym->type));
517 if (sym->type == S_INT || sym->type == S_HEX) { 519 if (sym->type == S_INT || sym->type == S_HEX) {
518 prop = sym_get_range_prop(sym); 520 prop = sym_get_range_prop(sym);
519 if (prop) { 521 if (prop) {
520 str_printf(r, "Range : "); 522 str_printf(r, "Range : ");
521 expr_gstr_print(prop->expr, r); 523 expr_gstr_print(prop->expr, r);
522 str_append(r, "\n"); 524 str_append(r, "\n");
523 } 525 }
524 } 526 }
525 } 527 }
526 for_all_prompts(sym, prop) 528 for_all_prompts(sym, prop)
527 get_prompt_str(r, prop); 529 get_prompt_str(r, prop);
528 hit = false; 530 hit = false;
529 for_all_properties(sym, prop, P_SELECT) { 531 for_all_properties(sym, prop, P_SELECT) {
530 if (!hit) { 532 if (!hit) {
531 str_append(r, " Selects: "); 533 str_append(r, " Selects: ");
532 hit = true; 534 hit = true;
533 } else 535 } else
534 str_printf(r, " && "); 536 str_printf(r, " && ");
535 expr_gstr_print(prop->expr, r); 537 expr_gstr_print(prop->expr, r);
536 } 538 }
537 if (hit) 539 if (hit)
538 str_append(r, "\n"); 540 str_append(r, "\n");
539 if (sym->rev_dep.expr) { 541 if (sym->rev_dep.expr) {
540 str_append(r, _(" Selected by: ")); 542 str_append(r, _(" Selected by: "));
541 expr_gstr_print(sym->rev_dep.expr, r); 543 expr_gstr_print(sym->rev_dep.expr, r);
542 str_append(r, "\n"); 544 str_append(r, "\n");
543 } 545 }
544 str_append(r, "\n\n"); 546 str_append(r, "\n\n");
545 } 547 }
546 548
547 struct gstr get_relations_str(struct symbol **sym_arr) 549 struct gstr get_relations_str(struct symbol **sym_arr)
548 { 550 {
549 struct symbol *sym; 551 struct symbol *sym;
550 struct gstr res = str_new(); 552 struct gstr res = str_new();
551 int i; 553 int i;
552 554
553 for (i = 0; sym_arr && (sym = sym_arr[i]); i++) 555 for (i = 0; sym_arr && (sym = sym_arr[i]); i++)
554 get_symbol_str(&res, sym); 556 get_symbol_str(&res, sym);
555 if (!i) 557 if (!i)
556 str_append(&res, _("No matches found.\n")); 558 str_append(&res, _("No matches found.\n"));
557 return res; 559 return res;
558 } 560 }
559 561
560 562
561 void menu_get_ext_help(struct menu *menu, struct gstr *help) 563 void menu_get_ext_help(struct menu *menu, struct gstr *help)
562 { 564 {
563 struct symbol *sym = menu->sym; 565 struct symbol *sym = menu->sym;
564 566
565 if (menu_has_help(menu)) { 567 if (menu_has_help(menu)) {
566 if (sym->name) { 568 if (sym->name) {
567 str_printf(help, "CONFIG_%s:\n\n", sym->name); 569 str_printf(help, "CONFIG_%s:\n\n", sym->name);
568 str_append(help, _(menu_get_help(menu))); 570 str_append(help, _(menu_get_help(menu)));
569 str_append(help, "\n"); 571 str_append(help, "\n");
570 } 572 }
571 } else { 573 } else {
572 str_append(help, nohelp_text); 574 str_append(help, nohelp_text);
573 } 575 }
574 if (sym) 576 if (sym)
575 get_symbol_str(help, sym); 577 get_symbol_str(help, sym);
576 } 578 }
577 579
scripts/kconfig/symbol.c
1 /* 1 /*
2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> 2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0. 3 * Released under the terms of the GNU GPL v2.0.
4 */ 4 */
5 5
6 #include <ctype.h> 6 #include <ctype.h>
7 #include <stdlib.h> 7 #include <stdlib.h>
8 #include <string.h> 8 #include <string.h>
9 #include <regex.h> 9 #include <regex.h>
10 #include <sys/utsname.h> 10 #include <sys/utsname.h>
11 11
12 #define LKC_DIRECT_LINK 12 #define LKC_DIRECT_LINK
13 #include "lkc.h" 13 #include "lkc.h"
14 14
15 struct symbol symbol_yes = { 15 struct symbol symbol_yes = {
16 .name = "y", 16 .name = "y",
17 .curr = { "y", yes }, 17 .curr = { "y", yes },
18 .flags = SYMBOL_CONST|SYMBOL_VALID, 18 .flags = SYMBOL_CONST|SYMBOL_VALID,
19 }, symbol_mod = { 19 }, symbol_mod = {
20 .name = "m", 20 .name = "m",
21 .curr = { "m", mod }, 21 .curr = { "m", mod },
22 .flags = SYMBOL_CONST|SYMBOL_VALID, 22 .flags = SYMBOL_CONST|SYMBOL_VALID,
23 }, symbol_no = { 23 }, symbol_no = {
24 .name = "n", 24 .name = "n",
25 .curr = { "n", no }, 25 .curr = { "n", no },
26 .flags = SYMBOL_CONST|SYMBOL_VALID, 26 .flags = SYMBOL_CONST|SYMBOL_VALID,
27 }, symbol_empty = { 27 }, symbol_empty = {
28 .name = "", 28 .name = "",
29 .curr = { "", no }, 29 .curr = { "", no },
30 .flags = SYMBOL_VALID, 30 .flags = SYMBOL_VALID,
31 }; 31 };
32 32
33 struct symbol *sym_defconfig_list; 33 struct symbol *sym_defconfig_list;
34 struct symbol *modules_sym; 34 struct symbol *modules_sym;
35 tristate modules_val; 35 tristate modules_val;
36 36
37 struct expr *sym_env_list; 37 struct expr *sym_env_list;
38 38
39 static void sym_add_default(struct symbol *sym, const char *def) 39 static void sym_add_default(struct symbol *sym, const char *def)
40 { 40 {
41 struct property *prop = prop_alloc(P_DEFAULT, sym); 41 struct property *prop = prop_alloc(P_DEFAULT, sym);
42 42
43 prop->expr = expr_alloc_symbol(sym_lookup(def, SYMBOL_CONST)); 43 prop->expr = expr_alloc_symbol(sym_lookup(def, SYMBOL_CONST));
44 } 44 }
45 45
46 void sym_init(void) 46 void sym_init(void)
47 { 47 {
48 struct symbol *sym; 48 struct symbol *sym;
49 struct utsname uts; 49 struct utsname uts;
50 static bool inited = false; 50 static bool inited = false;
51 51
52 if (inited) 52 if (inited)
53 return; 53 return;
54 inited = true; 54 inited = true;
55 55
56 uname(&uts); 56 uname(&uts);
57 57
58 sym = sym_lookup("UNAME_RELEASE", 0); 58 sym = sym_lookup("UNAME_RELEASE", 0);
59 sym->type = S_STRING; 59 sym->type = S_STRING;
60 sym->flags |= SYMBOL_AUTO; 60 sym->flags |= SYMBOL_AUTO;
61 sym_add_default(sym, uts.release); 61 sym_add_default(sym, uts.release);
62 } 62 }
63 63
64 enum symbol_type sym_get_type(struct symbol *sym) 64 enum symbol_type sym_get_type(struct symbol *sym)
65 { 65 {
66 enum symbol_type type = sym->type; 66 enum symbol_type type = sym->type;
67 67
68 if (type == S_TRISTATE) { 68 if (type == S_TRISTATE) {
69 if (sym_is_choice_value(sym) && sym->visible == yes) 69 if (sym_is_choice_value(sym) && sym->visible == yes)
70 type = S_BOOLEAN; 70 type = S_BOOLEAN;
71 else if (modules_val == no) 71 else if (modules_val == no)
72 type = S_BOOLEAN; 72 type = S_BOOLEAN;
73 } 73 }
74 return type; 74 return type;
75 } 75 }
76 76
77 const char *sym_type_name(enum symbol_type type) 77 const char *sym_type_name(enum symbol_type type)
78 { 78 {
79 switch (type) { 79 switch (type) {
80 case S_BOOLEAN: 80 case S_BOOLEAN:
81 return "boolean"; 81 return "boolean";
82 case S_TRISTATE: 82 case S_TRISTATE:
83 return "tristate"; 83 return "tristate";
84 case S_INT: 84 case S_INT:
85 return "integer"; 85 return "integer";
86 case S_HEX: 86 case S_HEX:
87 return "hex"; 87 return "hex";
88 case S_STRING: 88 case S_STRING:
89 return "string"; 89 return "string";
90 case S_UNKNOWN: 90 case S_UNKNOWN:
91 return "unknown"; 91 return "unknown";
92 case S_OTHER: 92 case S_OTHER:
93 break; 93 break;
94 } 94 }
95 return "???"; 95 return "???";
96 } 96 }
97 97
98 struct property *sym_get_choice_prop(struct symbol *sym) 98 struct property *sym_get_choice_prop(struct symbol *sym)
99 { 99 {
100 struct property *prop; 100 struct property *prop;
101 101
102 for_all_choices(sym, prop) 102 for_all_choices(sym, prop)
103 return prop; 103 return prop;
104 return NULL; 104 return NULL;
105 } 105 }
106 106
107 struct property *sym_get_env_prop(struct symbol *sym) 107 struct property *sym_get_env_prop(struct symbol *sym)
108 { 108 {
109 struct property *prop; 109 struct property *prop;
110 110
111 for_all_properties(sym, prop, P_ENV) 111 for_all_properties(sym, prop, P_ENV)
112 return prop; 112 return prop;
113 return NULL; 113 return NULL;
114 } 114 }
115 115
116 struct property *sym_get_default_prop(struct symbol *sym) 116 struct property *sym_get_default_prop(struct symbol *sym)
117 { 117 {
118 struct property *prop; 118 struct property *prop;
119 119
120 for_all_defaults(sym, prop) { 120 for_all_defaults(sym, prop) {
121 prop->visible.tri = expr_calc_value(prop->visible.expr); 121 prop->visible.tri = expr_calc_value(prop->visible.expr);
122 if (prop->visible.tri != no) 122 if (prop->visible.tri != no)
123 return prop; 123 return prop;
124 } 124 }
125 return NULL; 125 return NULL;
126 } 126 }
127 127
128 static struct property *sym_get_range_prop(struct symbol *sym) 128 static struct property *sym_get_range_prop(struct symbol *sym)
129 { 129 {
130 struct property *prop; 130 struct property *prop;
131 131
132 for_all_properties(sym, prop, P_RANGE) { 132 for_all_properties(sym, prop, P_RANGE) {
133 prop->visible.tri = expr_calc_value(prop->visible.expr); 133 prop->visible.tri = expr_calc_value(prop->visible.expr);
134 if (prop->visible.tri != no) 134 if (prop->visible.tri != no)
135 return prop; 135 return prop;
136 } 136 }
137 return NULL; 137 return NULL;
138 } 138 }
139 139
140 static int sym_get_range_val(struct symbol *sym, int base) 140 static int sym_get_range_val(struct symbol *sym, int base)
141 { 141 {
142 sym_calc_value(sym); 142 sym_calc_value(sym);
143 switch (sym->type) { 143 switch (sym->type) {
144 case S_INT: 144 case S_INT:
145 base = 10; 145 base = 10;
146 break; 146 break;
147 case S_HEX: 147 case S_HEX:
148 base = 16; 148 base = 16;
149 break; 149 break;
150 default: 150 default:
151 break; 151 break;
152 } 152 }
153 return strtol(sym->curr.val, NULL, base); 153 return strtol(sym->curr.val, NULL, base);
154 } 154 }
155 155
156 static void sym_validate_range(struct symbol *sym) 156 static void sym_validate_range(struct symbol *sym)
157 { 157 {
158 struct property *prop; 158 struct property *prop;
159 int base, val, val2; 159 int base, val, val2;
160 char str[64]; 160 char str[64];
161 161
162 switch (sym->type) { 162 switch (sym->type) {
163 case S_INT: 163 case S_INT:
164 base = 10; 164 base = 10;
165 break; 165 break;
166 case S_HEX: 166 case S_HEX:
167 base = 16; 167 base = 16;
168 break; 168 break;
169 default: 169 default:
170 return; 170 return;
171 } 171 }
172 prop = sym_get_range_prop(sym); 172 prop = sym_get_range_prop(sym);
173 if (!prop) 173 if (!prop)
174 return; 174 return;
175 val = strtol(sym->curr.val, NULL, base); 175 val = strtol(sym->curr.val, NULL, base);
176 val2 = sym_get_range_val(prop->expr->left.sym, base); 176 val2 = sym_get_range_val(prop->expr->left.sym, base);
177 if (val >= val2) { 177 if (val >= val2) {
178 val2 = sym_get_range_val(prop->expr->right.sym, base); 178 val2 = sym_get_range_val(prop->expr->right.sym, base);
179 if (val <= val2) 179 if (val <= val2)
180 return; 180 return;
181 } 181 }
182 if (sym->type == S_INT) 182 if (sym->type == S_INT)
183 sprintf(str, "%d", val2); 183 sprintf(str, "%d", val2);
184 else 184 else
185 sprintf(str, "0x%x", val2); 185 sprintf(str, "0x%x", val2);
186 sym->curr.val = strdup(str); 186 sym->curr.val = strdup(str);
187 } 187 }
188 188
189 static void sym_calc_visibility(struct symbol *sym) 189 static void sym_calc_visibility(struct symbol *sym)
190 { 190 {
191 struct property *prop; 191 struct property *prop;
192 tristate tri; 192 tristate tri;
193 193
194 /* any prompt visible? */ 194 /* any prompt visible? */
195 tri = no; 195 tri = no;
196 for_all_prompts(sym, prop) { 196 for_all_prompts(sym, prop) {
197 prop->visible.tri = expr_calc_value(prop->visible.expr); 197 prop->visible.tri = expr_calc_value(prop->visible.expr);
198 tri = EXPR_OR(tri, prop->visible.tri); 198 tri = EXPR_OR(tri, prop->visible.tri);
199 } 199 }
200 if (tri == mod && (sym->type != S_TRISTATE || modules_val == no)) 200 if (tri == mod && (sym->type != S_TRISTATE || modules_val == no))
201 tri = yes; 201 tri = yes;
202 if (sym->visible != tri) { 202 if (sym->visible != tri) {
203 sym->visible = tri; 203 sym->visible = tri;
204 sym_set_changed(sym); 204 sym_set_changed(sym);
205 } 205 }
206 if (sym_is_choice_value(sym)) 206 if (sym_is_choice_value(sym))
207 return; 207 return;
208 /* defaulting to "yes" if no explicit "depends on" are given */ 208 /* defaulting to "yes" if no explicit "depends on" are given */
209 tri = yes; 209 tri = yes;
210 if (sym->dir_dep.expr) 210 if (sym->dir_dep.expr)
211 tri = expr_calc_value(sym->dir_dep.expr); 211 tri = expr_calc_value(sym->dir_dep.expr);
212 if (tri == mod) 212 if (tri == mod)
213 tri = yes; 213 tri = yes;
214 if (sym->dir_dep.tri != tri) { 214 if (sym->dir_dep.tri != tri) {
215 sym->dir_dep.tri = tri; 215 sym->dir_dep.tri = tri;
216 sym_set_changed(sym); 216 sym_set_changed(sym);
217 } 217 }
218 tri = no; 218 tri = no;
219 if (sym->rev_dep.expr) 219 if (sym->rev_dep.expr)
220 tri = expr_calc_value(sym->rev_dep.expr); 220 tri = expr_calc_value(sym->rev_dep.expr);
221 if (tri == mod && sym_get_type(sym) == S_BOOLEAN) 221 if (tri == mod && sym_get_type(sym) == S_BOOLEAN)
222 tri = yes; 222 tri = yes;
223 if (sym->rev_dep.tri != tri) { 223 if (sym->rev_dep.tri != tri) {
224 sym->rev_dep.tri = tri; 224 sym->rev_dep.tri = tri;
225 sym_set_changed(sym); 225 sym_set_changed(sym);
226 } 226 }
227 } 227 }
228 228
229 static struct symbol *sym_calc_choice(struct symbol *sym) 229 static struct symbol *sym_calc_choice(struct symbol *sym)
230 { 230 {
231 struct symbol *def_sym; 231 struct symbol *def_sym;
232 struct property *prop; 232 struct property *prop;
233 struct expr *e; 233 struct expr *e;
234 234
235 /* first calculate all choice values' visibilities */ 235 /* first calculate all choice values' visibilities */
236 prop = sym_get_choice_prop(sym); 236 prop = sym_get_choice_prop(sym);
237 expr_list_for_each_sym(prop->expr, e, def_sym) 237 expr_list_for_each_sym(prop->expr, e, def_sym)
238 sym_calc_visibility(def_sym); 238 sym_calc_visibility(def_sym);
239 239
240 /* is the user choice visible? */ 240 /* is the user choice visible? */
241 def_sym = sym->def[S_DEF_USER].val; 241 def_sym = sym->def[S_DEF_USER].val;
242 if (def_sym && def_sym->visible != no) 242 if (def_sym && def_sym->visible != no)
243 return def_sym; 243 return def_sym;
244 244
245 /* any of the defaults visible? */ 245 /* any of the defaults visible? */
246 for_all_defaults(sym, prop) { 246 for_all_defaults(sym, prop) {
247 prop->visible.tri = expr_calc_value(prop->visible.expr); 247 prop->visible.tri = expr_calc_value(prop->visible.expr);
248 if (prop->visible.tri == no) 248 if (prop->visible.tri == no)
249 continue; 249 continue;
250 def_sym = prop_get_symbol(prop); 250 def_sym = prop_get_symbol(prop);
251 if (def_sym->visible != no) 251 if (def_sym->visible != no)
252 return def_sym; 252 return def_sym;
253 } 253 }
254 254
255 /* just get the first visible value */ 255 /* just get the first visible value */
256 prop = sym_get_choice_prop(sym); 256 prop = sym_get_choice_prop(sym);
257 expr_list_for_each_sym(prop->expr, e, def_sym) 257 expr_list_for_each_sym(prop->expr, e, def_sym)
258 if (def_sym->visible != no) 258 if (def_sym->visible != no)
259 return def_sym; 259 return def_sym;
260 260
261 /* no choice? reset tristate value */ 261 /* no choice? reset tristate value */
262 sym->curr.tri = no; 262 sym->curr.tri = no;
263 return NULL; 263 return NULL;
264 } 264 }
265 265
266 void sym_calc_value(struct symbol *sym) 266 void sym_calc_value(struct symbol *sym)
267 { 267 {
268 struct symbol_value newval, oldval; 268 struct symbol_value newval, oldval;
269 struct property *prop; 269 struct property *prop;
270 struct expr *e; 270 struct expr *e;
271 271
272 if (!sym) 272 if (!sym)
273 return; 273 return;
274 274
275 if (sym->flags & SYMBOL_VALID) 275 if (sym->flags & SYMBOL_VALID)
276 return; 276 return;
277 sym->flags |= SYMBOL_VALID; 277 sym->flags |= SYMBOL_VALID;
278 278
279 oldval = sym->curr; 279 oldval = sym->curr;
280 280
281 switch (sym->type) { 281 switch (sym->type) {
282 case S_INT: 282 case S_INT:
283 case S_HEX: 283 case S_HEX:
284 case S_STRING: 284 case S_STRING:
285 newval = symbol_empty.curr; 285 newval = symbol_empty.curr;
286 break; 286 break;
287 case S_BOOLEAN: 287 case S_BOOLEAN:
288 case S_TRISTATE: 288 case S_TRISTATE:
289 newval = symbol_no.curr; 289 newval = symbol_no.curr;
290 break; 290 break;
291 default: 291 default:
292 sym->curr.val = sym->name; 292 sym->curr.val = sym->name;
293 sym->curr.tri = no; 293 sym->curr.tri = no;
294 return; 294 return;
295 } 295 }
296 if (!sym_is_choice_value(sym)) 296 if (!sym_is_choice_value(sym))
297 sym->flags &= ~SYMBOL_WRITE; 297 sym->flags &= ~SYMBOL_WRITE;
298 298
299 sym_calc_visibility(sym); 299 sym_calc_visibility(sym);
300 300
301 /* set default if recursively called */ 301 /* set default if recursively called */
302 sym->curr = newval; 302 sym->curr = newval;
303 303
304 switch (sym_get_type(sym)) { 304 switch (sym_get_type(sym)) {
305 case S_BOOLEAN: 305 case S_BOOLEAN:
306 case S_TRISTATE: 306 case S_TRISTATE:
307 if (sym_is_choice_value(sym) && sym->visible == yes) { 307 if (sym_is_choice_value(sym) && sym->visible == yes) {
308 prop = sym_get_choice_prop(sym); 308 prop = sym_get_choice_prop(sym);
309 newval.tri = (prop_get_symbol(prop)->curr.val == sym) ? yes : no; 309 newval.tri = (prop_get_symbol(prop)->curr.val == sym) ? yes : no;
310 } else { 310 } else {
311 if (sym->visible != no) { 311 if (sym->visible != no) {
312 /* if the symbol is visible use the user value 312 /* if the symbol is visible use the user value
313 * if available, otherwise try the default value 313 * if available, otherwise try the default value
314 */ 314 */
315 sym->flags |= SYMBOL_WRITE; 315 sym->flags |= SYMBOL_WRITE;
316 if (sym_has_value(sym)) { 316 if (sym_has_value(sym)) {
317 newval.tri = EXPR_AND(sym->def[S_DEF_USER].tri, 317 newval.tri = EXPR_AND(sym->def[S_DEF_USER].tri,
318 sym->visible); 318 sym->visible);
319 goto calc_newval; 319 goto calc_newval;
320 } 320 }
321 } 321 }
322 if (sym->rev_dep.tri != no) 322 if (sym->rev_dep.tri != no)
323 sym->flags |= SYMBOL_WRITE; 323 sym->flags |= SYMBOL_WRITE;
324 if (!sym_is_choice(sym)) { 324 if (!sym_is_choice(sym)) {
325 prop = sym_get_default_prop(sym); 325 prop = sym_get_default_prop(sym);
326 if (prop) { 326 if (prop) {
327 sym->flags |= SYMBOL_WRITE; 327 sym->flags |= SYMBOL_WRITE;
328 newval.tri = EXPR_AND(expr_calc_value(prop->expr), 328 newval.tri = EXPR_AND(expr_calc_value(prop->expr),
329 prop->visible.tri); 329 prop->visible.tri);
330 } 330 }
331 } 331 }
332 calc_newval: 332 calc_newval:
333 if (sym->dir_dep.tri == no && sym->rev_dep.tri != no) { 333 if (sym->dir_dep.tri == no && sym->rev_dep.tri != no) {
334 fprintf(stderr, "warning: ("); 334 fprintf(stderr, "warning: (");
335 expr_fprint(sym->rev_dep.expr, stderr); 335 expr_fprint(sym->rev_dep.expr, stderr);
336 fprintf(stderr, ") selects %s which has unmet direct dependencies (", 336 fprintf(stderr, ") selects %s which has unmet direct dependencies (",
337 sym->name); 337 sym->name);
338 expr_fprint(sym->dir_dep.expr, stderr); 338 expr_fprint(sym->dir_dep.expr, stderr);
339 fprintf(stderr, ")\n"); 339 fprintf(stderr, ")\n");
340 } 340 }
341 newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri); 341 newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri);
342 } 342 }
343 if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN) 343 if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN)
344 newval.tri = yes; 344 newval.tri = yes;
345 break; 345 break;
346 case S_STRING: 346 case S_STRING:
347 case S_HEX: 347 case S_HEX:
348 case S_INT: 348 case S_INT:
349 if (sym->visible != no) { 349 if (sym->visible != no) {
350 sym->flags |= SYMBOL_WRITE; 350 sym->flags |= SYMBOL_WRITE;
351 if (sym_has_value(sym)) { 351 if (sym_has_value(sym)) {
352 newval.val = sym->def[S_DEF_USER].val; 352 newval.val = sym->def[S_DEF_USER].val;
353 break; 353 break;
354 } 354 }
355 } 355 }
356 prop = sym_get_default_prop(sym); 356 prop = sym_get_default_prop(sym);
357 if (prop) { 357 if (prop) {
358 struct symbol *ds = prop_get_symbol(prop); 358 struct symbol *ds = prop_get_symbol(prop);
359 if (ds) { 359 if (ds) {
360 sym->flags |= SYMBOL_WRITE; 360 sym->flags |= SYMBOL_WRITE;
361 sym_calc_value(ds); 361 sym_calc_value(ds);
362 newval.val = ds->curr.val; 362 newval.val = ds->curr.val;
363 } 363 }
364 } 364 }
365 break; 365 break;
366 default: 366 default:
367 ; 367 ;
368 } 368 }
369 369
370 sym->curr = newval; 370 sym->curr = newval;
371 if (sym_is_choice(sym) && newval.tri == yes) 371 if (sym_is_choice(sym) && newval.tri == yes)
372 sym->curr.val = sym_calc_choice(sym); 372 sym->curr.val = sym_calc_choice(sym);
373 sym_validate_range(sym); 373 sym_validate_range(sym);
374 374
375 if (memcmp(&oldval, &sym->curr, sizeof(oldval))) { 375 if (memcmp(&oldval, &sym->curr, sizeof(oldval))) {
376 sym_set_changed(sym); 376 sym_set_changed(sym);
377 if (modules_sym == sym) { 377 if (modules_sym == sym) {
378 sym_set_all_changed(); 378 sym_set_all_changed();
379 modules_val = modules_sym->curr.tri; 379 modules_val = modules_sym->curr.tri;
380 } 380 }
381 } 381 }
382 382
383 if (sym_is_choice(sym)) { 383 if (sym_is_choice(sym)) {
384 struct symbol *choice_sym; 384 struct symbol *choice_sym;
385 385
386 prop = sym_get_choice_prop(sym); 386 prop = sym_get_choice_prop(sym);
387 expr_list_for_each_sym(prop->expr, e, choice_sym) { 387 expr_list_for_each_sym(prop->expr, e, choice_sym) {
388 if ((sym->flags & SYMBOL_WRITE) && 388 if ((sym->flags & SYMBOL_WRITE) &&
389 choice_sym->visible != no) 389 choice_sym->visible != no)
390 choice_sym->flags |= SYMBOL_WRITE; 390 choice_sym->flags |= SYMBOL_WRITE;
391 if (sym->flags & SYMBOL_CHANGED) 391 if (sym->flags & SYMBOL_CHANGED)
392 sym_set_changed(choice_sym); 392 sym_set_changed(choice_sym);
393 } 393 }
394 } 394 }
395 395
396 if (sym->flags & SYMBOL_AUTO) 396 if (sym->flags & SYMBOL_AUTO)
397 sym->flags &= ~SYMBOL_WRITE; 397 sym->flags &= ~SYMBOL_WRITE;
398 } 398 }
399 399
400 void sym_clear_all_valid(void) 400 void sym_clear_all_valid(void)
401 { 401 {
402 struct symbol *sym; 402 struct symbol *sym;
403 int i; 403 int i;
404 404
405 for_all_symbols(i, sym) 405 for_all_symbols(i, sym)
406 sym->flags &= ~SYMBOL_VALID; 406 sym->flags &= ~SYMBOL_VALID;
407 sym_add_change_count(1); 407 sym_add_change_count(1);
408 if (modules_sym) 408 if (modules_sym)
409 sym_calc_value(modules_sym); 409 sym_calc_value(modules_sym);
410 } 410 }
411 411
412 void sym_set_changed(struct symbol *sym) 412 void sym_set_changed(struct symbol *sym)
413 { 413 {
414 struct property *prop; 414 struct property *prop;
415 415
416 sym->flags |= SYMBOL_CHANGED; 416 sym->flags |= SYMBOL_CHANGED;
417 for (prop = sym->prop; prop; prop = prop->next) { 417 for (prop = sym->prop; prop; prop = prop->next) {
418 if (prop->menu) 418 if (prop->menu)
419 prop->menu->flags |= MENU_CHANGED; 419 prop->menu->flags |= MENU_CHANGED;
420 } 420 }
421 } 421 }
422 422
423 void sym_set_all_changed(void) 423 void sym_set_all_changed(void)
424 { 424 {
425 struct symbol *sym; 425 struct symbol *sym;
426 int i; 426 int i;
427 427
428 for_all_symbols(i, sym) 428 for_all_symbols(i, sym)
429 sym_set_changed(sym); 429 sym_set_changed(sym);
430 } 430 }
431 431
432 bool sym_tristate_within_range(struct symbol *sym, tristate val) 432 bool sym_tristate_within_range(struct symbol *sym, tristate val)
433 { 433 {
434 int type = sym_get_type(sym); 434 int type = sym_get_type(sym);
435 435
436 if (sym->visible == no) 436 if (sym->visible == no)
437 return false; 437 return false;
438 438
439 if (type != S_BOOLEAN && type != S_TRISTATE) 439 if (type != S_BOOLEAN && type != S_TRISTATE)
440 return false; 440 return false;
441 441
442 if (type == S_BOOLEAN && val == mod) 442 if (type == S_BOOLEAN && val == mod)
443 return false; 443 return false;
444 if (sym->visible <= sym->rev_dep.tri) 444 if (sym->visible <= sym->rev_dep.tri)
445 return false; 445 return false;
446 if (sym_is_choice_value(sym) && sym->visible == yes) 446 if (sym_is_choice_value(sym) && sym->visible == yes)
447 return val == yes; 447 return val == yes;
448 return val >= sym->rev_dep.tri && val <= sym->visible; 448 return val >= sym->rev_dep.tri && val <= sym->visible;
449 } 449 }
450 450
451 bool sym_set_tristate_value(struct symbol *sym, tristate val) 451 bool sym_set_tristate_value(struct symbol *sym, tristate val)
452 { 452 {
453 tristate oldval = sym_get_tristate_value(sym); 453 tristate oldval = sym_get_tristate_value(sym);
454 454
455 if (oldval != val && !sym_tristate_within_range(sym, val)) 455 if (oldval != val && !sym_tristate_within_range(sym, val))
456 return false; 456 return false;
457 457
458 if (!(sym->flags & SYMBOL_DEF_USER)) { 458 if (!(sym->flags & SYMBOL_DEF_USER)) {
459 sym->flags |= SYMBOL_DEF_USER; 459 sym->flags |= SYMBOL_DEF_USER;
460 sym_set_changed(sym); 460 sym_set_changed(sym);
461 } 461 }
462 /* 462 /*
463 * setting a choice value also resets the new flag of the choice 463 * setting a choice value also resets the new flag of the choice
464 * symbol and all other choice values. 464 * symbol and all other choice values.
465 */ 465 */
466 if (sym_is_choice_value(sym) && val == yes) { 466 if (sym_is_choice_value(sym) && val == yes) {
467 struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); 467 struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
468 struct property *prop; 468 struct property *prop;
469 struct expr *e; 469 struct expr *e;
470 470
471 cs->def[S_DEF_USER].val = sym; 471 cs->def[S_DEF_USER].val = sym;
472 cs->flags |= SYMBOL_DEF_USER; 472 cs->flags |= SYMBOL_DEF_USER;
473 prop = sym_get_choice_prop(cs); 473 prop = sym_get_choice_prop(cs);
474 for (e = prop->expr; e; e = e->left.expr) { 474 for (e = prop->expr; e; e = e->left.expr) {
475 if (e->right.sym->visible != no) 475 if (e->right.sym->visible != no)
476 e->right.sym->flags |= SYMBOL_DEF_USER; 476 e->right.sym->flags |= SYMBOL_DEF_USER;
477 } 477 }
478 } 478 }
479 479
480 sym->def[S_DEF_USER].tri = val; 480 sym->def[S_DEF_USER].tri = val;
481 if (oldval != val) 481 if (oldval != val)
482 sym_clear_all_valid(); 482 sym_clear_all_valid();
483 483
484 return true; 484 return true;
485 } 485 }
486 486
487 tristate sym_toggle_tristate_value(struct symbol *sym) 487 tristate sym_toggle_tristate_value(struct symbol *sym)
488 { 488 {
489 tristate oldval, newval; 489 tristate oldval, newval;
490 490
491 oldval = newval = sym_get_tristate_value(sym); 491 oldval = newval = sym_get_tristate_value(sym);
492 do { 492 do {
493 switch (newval) { 493 switch (newval) {
494 case no: 494 case no:
495 newval = mod; 495 newval = mod;
496 break; 496 break;
497 case mod: 497 case mod:
498 newval = yes; 498 newval = yes;
499 break; 499 break;
500 case yes: 500 case yes:
501 newval = no; 501 newval = no;
502 break; 502 break;
503 } 503 }
504 if (sym_set_tristate_value(sym, newval)) 504 if (sym_set_tristate_value(sym, newval))
505 break; 505 break;
506 } while (oldval != newval); 506 } while (oldval != newval);
507 return newval; 507 return newval;
508 } 508 }
509 509
510 bool sym_string_valid(struct symbol *sym, const char *str) 510 bool sym_string_valid(struct symbol *sym, const char *str)
511 { 511 {
512 signed char ch; 512 signed char ch;
513 513
514 switch (sym->type) { 514 switch (sym->type) {
515 case S_STRING: 515 case S_STRING:
516 return true; 516 return true;
517 case S_INT: 517 case S_INT:
518 ch = *str++; 518 ch = *str++;
519 if (ch == '-') 519 if (ch == '-')
520 ch = *str++; 520 ch = *str++;
521 if (!isdigit(ch)) 521 if (!isdigit(ch))
522 return false; 522 return false;
523 if (ch == '0' && *str != 0) 523 if (ch == '0' && *str != 0)
524 return false; 524 return false;
525 while ((ch = *str++)) { 525 while ((ch = *str++)) {
526 if (!isdigit(ch)) 526 if (!isdigit(ch))
527 return false; 527 return false;
528 } 528 }
529 return true; 529 return true;
530 case S_HEX: 530 case S_HEX:
531 if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) 531 if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
532 str += 2; 532 str += 2;
533 ch = *str++; 533 ch = *str++;
534 do { 534 do {
535 if (!isxdigit(ch)) 535 if (!isxdigit(ch))
536 return false; 536 return false;
537 } while ((ch = *str++)); 537 } while ((ch = *str++));
538 return true; 538 return true;
539 case S_BOOLEAN: 539 case S_BOOLEAN:
540 case S_TRISTATE: 540 case S_TRISTATE:
541 switch (str[0]) { 541 switch (str[0]) {
542 case 'y': case 'Y': 542 case 'y': case 'Y':
543 case 'm': case 'M': 543 case 'm': case 'M':
544 case 'n': case 'N': 544 case 'n': case 'N':
545 return true; 545 return true;
546 } 546 }
547 return false; 547 return false;
548 default: 548 default:
549 return false; 549 return false;
550 } 550 }
551 } 551 }
552 552
553 bool sym_string_within_range(struct symbol *sym, const char *str) 553 bool sym_string_within_range(struct symbol *sym, const char *str)
554 { 554 {
555 struct property *prop; 555 struct property *prop;
556 int val; 556 int val;
557 557
558 switch (sym->type) { 558 switch (sym->type) {
559 case S_STRING: 559 case S_STRING:
560 return sym_string_valid(sym, str); 560 return sym_string_valid(sym, str);
561 case S_INT: 561 case S_INT:
562 if (!sym_string_valid(sym, str)) 562 if (!sym_string_valid(sym, str))
563 return false; 563 return false;
564 prop = sym_get_range_prop(sym); 564 prop = sym_get_range_prop(sym);
565 if (!prop) 565 if (!prop)
566 return true; 566 return true;
567 val = strtol(str, NULL, 10); 567 val = strtol(str, NULL, 10);
568 return val >= sym_get_range_val(prop->expr->left.sym, 10) && 568 return val >= sym_get_range_val(prop->expr->left.sym, 10) &&
569 val <= sym_get_range_val(prop->expr->right.sym, 10); 569 val <= sym_get_range_val(prop->expr->right.sym, 10);
570 case S_HEX: 570 case S_HEX:
571 if (!sym_string_valid(sym, str)) 571 if (!sym_string_valid(sym, str))
572 return false; 572 return false;
573 prop = sym_get_range_prop(sym); 573 prop = sym_get_range_prop(sym);
574 if (!prop) 574 if (!prop)
575 return true; 575 return true;
576 val = strtol(str, NULL, 16); 576 val = strtol(str, NULL, 16);
577 return val >= sym_get_range_val(prop->expr->left.sym, 16) && 577 return val >= sym_get_range_val(prop->expr->left.sym, 16) &&
578 val <= sym_get_range_val(prop->expr->right.sym, 16); 578 val <= sym_get_range_val(prop->expr->right.sym, 16);
579 case S_BOOLEAN: 579 case S_BOOLEAN:
580 case S_TRISTATE: 580 case S_TRISTATE:
581 switch (str[0]) { 581 switch (str[0]) {
582 case 'y': case 'Y': 582 case 'y': case 'Y':
583 return sym_tristate_within_range(sym, yes); 583 return sym_tristate_within_range(sym, yes);
584 case 'm': case 'M': 584 case 'm': case 'M':
585 return sym_tristate_within_range(sym, mod); 585 return sym_tristate_within_range(sym, mod);
586 case 'n': case 'N': 586 case 'n': case 'N':
587 return sym_tristate_within_range(sym, no); 587 return sym_tristate_within_range(sym, no);
588 } 588 }
589 return false; 589 return false;
590 default: 590 default:
591 return false; 591 return false;
592 } 592 }
593 } 593 }
594 594
595 bool sym_set_string_value(struct symbol *sym, const char *newval) 595 bool sym_set_string_value(struct symbol *sym, const char *newval)
596 { 596 {
597 const char *oldval; 597 const char *oldval;
598 char *val; 598 char *val;
599 int size; 599 int size;
600 600
601 switch (sym->type) { 601 switch (sym->type) {
602 case S_BOOLEAN: 602 case S_BOOLEAN:
603 case S_TRISTATE: 603 case S_TRISTATE:
604 switch (newval[0]) { 604 switch (newval[0]) {
605 case 'y': case 'Y': 605 case 'y': case 'Y':
606 return sym_set_tristate_value(sym, yes); 606 return sym_set_tristate_value(sym, yes);
607 case 'm': case 'M': 607 case 'm': case 'M':
608 return sym_set_tristate_value(sym, mod); 608 return sym_set_tristate_value(sym, mod);
609 case 'n': case 'N': 609 case 'n': case 'N':
610 return sym_set_tristate_value(sym, no); 610 return sym_set_tristate_value(sym, no);
611 } 611 }
612 return false; 612 return false;
613 default: 613 default:
614 ; 614 ;
615 } 615 }
616 616
617 if (!sym_string_within_range(sym, newval)) 617 if (!sym_string_within_range(sym, newval))
618 return false; 618 return false;
619 619
620 if (!(sym->flags & SYMBOL_DEF_USER)) { 620 if (!(sym->flags & SYMBOL_DEF_USER)) {
621 sym->flags |= SYMBOL_DEF_USER; 621 sym->flags |= SYMBOL_DEF_USER;
622 sym_set_changed(sym); 622 sym_set_changed(sym);
623 } 623 }
624 624
625 oldval = sym->def[S_DEF_USER].val; 625 oldval = sym->def[S_DEF_USER].val;
626 size = strlen(newval) + 1; 626 size = strlen(newval) + 1;
627 if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) { 627 if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) {
628 size += 2; 628 size += 2;
629 sym->def[S_DEF_USER].val = val = malloc(size); 629 sym->def[S_DEF_USER].val = val = malloc(size);
630 *val++ = '0'; 630 *val++ = '0';
631 *val++ = 'x'; 631 *val++ = 'x';
632 } else if (!oldval || strcmp(oldval, newval)) 632 } else if (!oldval || strcmp(oldval, newval))
633 sym->def[S_DEF_USER].val = val = malloc(size); 633 sym->def[S_DEF_USER].val = val = malloc(size);
634 else 634 else
635 return true; 635 return true;
636 636
637 strcpy(val, newval); 637 strcpy(val, newval);
638 free((void *)oldval); 638 free((void *)oldval);
639 sym_clear_all_valid(); 639 sym_clear_all_valid();
640 640
641 return true; 641 return true;
642 } 642 }
643 643
644 const char *sym_get_string_value(struct symbol *sym) 644 const char *sym_get_string_value(struct symbol *sym)
645 { 645 {
646 tristate val; 646 tristate val;
647 647
648 switch (sym->type) { 648 switch (sym->type) {
649 case S_BOOLEAN: 649 case S_BOOLEAN:
650 case S_TRISTATE: 650 case S_TRISTATE:
651 val = sym_get_tristate_value(sym); 651 val = sym_get_tristate_value(sym);
652 switch (val) { 652 switch (val) {
653 case no: 653 case no:
654 return "n"; 654 return "n";
655 case mod: 655 case mod:
656 return "m"; 656 return "m";
657 case yes: 657 case yes:
658 return "y"; 658 return "y";
659 } 659 }
660 break; 660 break;
661 default: 661 default:
662 ; 662 ;
663 } 663 }
664 return (const char *)sym->curr.val; 664 return (const char *)sym->curr.val;
665 } 665 }
666 666
667 bool sym_is_changable(struct symbol *sym) 667 bool sym_is_changable(struct symbol *sym)
668 { 668 {
669 return sym->visible > sym->rev_dep.tri; 669 return sym->visible > sym->rev_dep.tri;
670 } 670 }
671 671
672 static unsigned strhash(const char *s) 672 static unsigned strhash(const char *s)
673 { 673 {
674 /* fnv32 hash */ 674 /* fnv32 hash */
675 unsigned hash = 2166136261U; 675 unsigned hash = 2166136261U;
676 for (; *s; s++) 676 for (; *s; s++)
677 hash = (hash ^ *s) * 0x01000193; 677 hash = (hash ^ *s) * 0x01000193;
678 return hash; 678 return hash;
679 } 679 }
680 680
681 struct symbol *sym_lookup(const char *name, int flags) 681 struct symbol *sym_lookup(const char *name, int flags)
682 { 682 {
683 struct symbol *symbol; 683 struct symbol *symbol;
684 char *new_name; 684 char *new_name;
685 int hash; 685 int hash;
686 686
687 if (name) { 687 if (name) {
688 if (name[0] && !name[1]) { 688 if (name[0] && !name[1]) {
689 switch (name[0]) { 689 switch (name[0]) {
690 case 'y': return &symbol_yes; 690 case 'y': return &symbol_yes;
691 case 'm': return &symbol_mod; 691 case 'm': return &symbol_mod;
692 case 'n': return &symbol_no; 692 case 'n': return &symbol_no;
693 } 693 }
694 } 694 }
695 hash = strhash(name) % SYMBOL_HASHSIZE; 695 hash = strhash(name) % SYMBOL_HASHSIZE;
696 696
697 for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) { 697 for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
698 if (symbol->name && 698 if (symbol->name &&
699 !strcmp(symbol->name, name) && 699 !strcmp(symbol->name, name) &&
700 (flags ? symbol->flags & flags 700 (flags ? symbol->flags & flags
701 : !(symbol->flags & (SYMBOL_CONST|SYMBOL_CHOICE)))) 701 : !(symbol->flags & (SYMBOL_CONST|SYMBOL_CHOICE))))
702 return symbol; 702 return symbol;
703 } 703 }
704 new_name = strdup(name); 704 new_name = strdup(name);
705 } else { 705 } else {
706 new_name = NULL; 706 new_name = NULL;
707 hash = 0; 707 hash = 0;
708 } 708 }
709 709
710 symbol = malloc(sizeof(*symbol)); 710 symbol = malloc(sizeof(*symbol));
711 memset(symbol, 0, sizeof(*symbol)); 711 memset(symbol, 0, sizeof(*symbol));
712 symbol->name = new_name; 712 symbol->name = new_name;
713 symbol->type = S_UNKNOWN; 713 symbol->type = S_UNKNOWN;
714 symbol->flags |= flags; 714 symbol->flags |= flags;
715 715
716 symbol->next = symbol_hash[hash]; 716 symbol->next = symbol_hash[hash];
717 symbol_hash[hash] = symbol; 717 symbol_hash[hash] = symbol;
718 718
719 return symbol; 719 return symbol;
720 } 720 }
721 721
722 struct symbol *sym_find(const char *name) 722 struct symbol *sym_find(const char *name)
723 { 723 {
724 struct symbol *symbol = NULL; 724 struct symbol *symbol = NULL;
725 int hash = 0; 725 int hash = 0;
726 726
727 if (!name) 727 if (!name)
728 return NULL; 728 return NULL;
729 729
730 if (name[0] && !name[1]) { 730 if (name[0] && !name[1]) {
731 switch (name[0]) { 731 switch (name[0]) {
732 case 'y': return &symbol_yes; 732 case 'y': return &symbol_yes;
733 case 'm': return &symbol_mod; 733 case 'm': return &symbol_mod;
734 case 'n': return &symbol_no; 734 case 'n': return &symbol_no;
735 } 735 }
736 } 736 }
737 hash = strhash(name) % SYMBOL_HASHSIZE; 737 hash = strhash(name) % SYMBOL_HASHSIZE;
738 738
739 for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) { 739 for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
740 if (symbol->name && 740 if (symbol->name &&
741 !strcmp(symbol->name, name) && 741 !strcmp(symbol->name, name) &&
742 !(symbol->flags & SYMBOL_CONST)) 742 !(symbol->flags & SYMBOL_CONST))
743 break; 743 break;
744 } 744 }
745 745
746 return symbol; 746 return symbol;
747 } 747 }
748 748
749 struct symbol **sym_re_search(const char *pattern) 749 struct symbol **sym_re_search(const char *pattern)
750 { 750 {
751 struct symbol *sym, **sym_arr = NULL; 751 struct symbol *sym, **sym_arr = NULL;
752 int i, cnt, size; 752 int i, cnt, size;
753 regex_t re; 753 regex_t re;
754 754
755 cnt = size = 0; 755 cnt = size = 0;
756 /* Skip if empty */ 756 /* Skip if empty */
757 if (strlen(pattern) == 0) 757 if (strlen(pattern) == 0)
758 return NULL; 758 return NULL;
759 if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB|REG_ICASE)) 759 if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB|REG_ICASE))
760 return NULL; 760 return NULL;
761 761
762 for_all_symbols(i, sym) { 762 for_all_symbols(i, sym) {
763 if (sym->flags & SYMBOL_CONST || !sym->name) 763 if (sym->flags & SYMBOL_CONST || !sym->name)
764 continue; 764 continue;
765 if (regexec(&re, sym->name, 0, NULL, 0)) 765 if (regexec(&re, sym->name, 0, NULL, 0))
766 continue; 766 continue;
767 if (cnt + 1 >= size) { 767 if (cnt + 1 >= size) {
768 void *tmp = sym_arr; 768 void *tmp = sym_arr;
769 size += 16; 769 size += 16;
770 sym_arr = realloc(sym_arr, size * sizeof(struct symbol *)); 770 sym_arr = realloc(sym_arr, size * sizeof(struct symbol *));
771 if (!sym_arr) { 771 if (!sym_arr) {
772 free(tmp); 772 free(tmp);
773 return NULL; 773 return NULL;
774 } 774 }
775 } 775 }
776 sym_calc_value(sym); 776 sym_calc_value(sym);
777 sym_arr[cnt++] = sym; 777 sym_arr[cnt++] = sym;
778 } 778 }
779 if (sym_arr) 779 if (sym_arr)
780 sym_arr[cnt] = NULL; 780 sym_arr[cnt] = NULL;
781 regfree(&re); 781 regfree(&re);
782 782
783 return sym_arr; 783 return sym_arr;
784 } 784 }
785 785
786 786
787 static struct symbol *sym_check_expr_deps(struct expr *e) 787 static struct symbol *sym_check_expr_deps(struct expr *e)
788 { 788 {
789 struct symbol *sym; 789 struct symbol *sym;
790 790
791 if (!e) 791 if (!e)
792 return NULL; 792 return NULL;
793 switch (e->type) { 793 switch (e->type) {
794 case E_OR: 794 case E_OR:
795 case E_AND: 795 case E_AND:
796 sym = sym_check_expr_deps(e->left.expr); 796 sym = sym_check_expr_deps(e->left.expr);
797 if (sym) 797 if (sym)
798 return sym; 798 return sym;
799 return sym_check_expr_deps(e->right.expr); 799 return sym_check_expr_deps(e->right.expr);
800 case E_NOT: 800 case E_NOT:
801 return sym_check_expr_deps(e->left.expr); 801 return sym_check_expr_deps(e->left.expr);
802 case E_EQUAL: 802 case E_EQUAL:
803 case E_UNEQUAL: 803 case E_UNEQUAL:
804 sym = sym_check_deps(e->left.sym); 804 sym = sym_check_deps(e->left.sym);
805 if (sym) 805 if (sym)
806 return sym; 806 return sym;
807 return sym_check_deps(e->right.sym); 807 return sym_check_deps(e->right.sym);
808 case E_SYMBOL: 808 case E_SYMBOL:
809 return sym_check_deps(e->left.sym); 809 return sym_check_deps(e->left.sym);
810 default: 810 default:
811 break; 811 break;
812 } 812 }
813 printf("Oops! How to check %d?\n", e->type); 813 printf("Oops! How to check %d?\n", e->type);
814 return NULL; 814 return NULL;
815 } 815 }
816 816
817 /* return NULL when dependencies are OK */ 817 /* return NULL when dependencies are OK */
818 static struct symbol *sym_check_sym_deps(struct symbol *sym) 818 static struct symbol *sym_check_sym_deps(struct symbol *sym)
819 { 819 {
820 struct symbol *sym2; 820 struct symbol *sym2;
821 struct property *prop; 821 struct property *prop;
822 822
823 sym2 = sym_check_expr_deps(sym->rev_dep.expr); 823 sym2 = sym_check_expr_deps(sym->rev_dep.expr);
824 if (sym2) 824 if (sym2)
825 return sym2; 825 return sym2;
826 826
827 for (prop = sym->prop; prop; prop = prop->next) { 827 for (prop = sym->prop; prop; prop = prop->next) {
828 if (prop->type == P_CHOICE || prop->type == P_SELECT) 828 if (prop->type == P_CHOICE || prop->type == P_SELECT)
829 continue; 829 continue;
830 sym2 = sym_check_expr_deps(prop->visible.expr); 830 sym2 = sym_check_expr_deps(prop->visible.expr);
831 if (sym2) 831 if (sym2)
832 break; 832 break;
833 if (prop->type != P_DEFAULT || sym_is_choice(sym)) 833 if (prop->type != P_DEFAULT || sym_is_choice(sym))
834 continue; 834 continue;
835 sym2 = sym_check_expr_deps(prop->expr); 835 sym2 = sym_check_expr_deps(prop->expr);
836 if (sym2) 836 if (sym2)
837 break; 837 break;
838 } 838 }
839 839
840 return sym2; 840 return sym2;
841 } 841 }
842 842
843 static struct symbol *sym_check_choice_deps(struct symbol *choice) 843 static struct symbol *sym_check_choice_deps(struct symbol *choice)
844 { 844 {
845 struct symbol *sym, *sym2; 845 struct symbol *sym, *sym2;
846 struct property *prop; 846 struct property *prop;
847 struct expr *e; 847 struct expr *e;
848 848
849 prop = sym_get_choice_prop(choice); 849 prop = sym_get_choice_prop(choice);
850 expr_list_for_each_sym(prop->expr, e, sym) 850 expr_list_for_each_sym(prop->expr, e, sym)
851 sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED); 851 sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
852 852
853 choice->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED); 853 choice->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
854 sym2 = sym_check_sym_deps(choice); 854 sym2 = sym_check_sym_deps(choice);
855 choice->flags &= ~SYMBOL_CHECK; 855 choice->flags &= ~SYMBOL_CHECK;
856 if (sym2) 856 if (sym2)
857 goto out; 857 goto out;
858 858
859 expr_list_for_each_sym(prop->expr, e, sym) { 859 expr_list_for_each_sym(prop->expr, e, sym) {
860 sym2 = sym_check_sym_deps(sym); 860 sym2 = sym_check_sym_deps(sym);
861 if (sym2) { 861 if (sym2) {
862 fprintf(stderr, " -> %s", sym->name); 862 fprintf(stderr, " -> %s", sym->name);
863 break; 863 break;
864 } 864 }
865 } 865 }
866 out: 866 out:
867 expr_list_for_each_sym(prop->expr, e, sym) 867 expr_list_for_each_sym(prop->expr, e, sym)
868 sym->flags &= ~SYMBOL_CHECK; 868 sym->flags &= ~SYMBOL_CHECK;
869 869
870 if (sym2 && sym_is_choice_value(sym2) && 870 if (sym2 && sym_is_choice_value(sym2) &&
871 prop_get_symbol(sym_get_choice_prop(sym2)) == choice) 871 prop_get_symbol(sym_get_choice_prop(sym2)) == choice)
872 sym2 = choice; 872 sym2 = choice;
873 873
874 return sym2; 874 return sym2;
875 } 875 }
876 876
877 struct symbol *sym_check_deps(struct symbol *sym) 877 struct symbol *sym_check_deps(struct symbol *sym)
878 { 878 {
879 struct symbol *sym2; 879 struct symbol *sym2;
880 struct property *prop; 880 struct property *prop;
881 881
882 if (sym->flags & SYMBOL_CHECK) { 882 if (sym->flags & SYMBOL_CHECK) {
883 fprintf(stderr, "%s:%d:error: found recursive dependency: %s", 883 fprintf(stderr, "%s:%d:error: found recursive dependency: %s",
884 sym->prop->file->name, sym->prop->lineno, 884 sym->prop->file->name, sym->prop->lineno,
885 sym->name ? sym->name : "<choice>"); 885 sym->name ? sym->name : "<choice>");
886 return sym; 886 return sym;
887 } 887 }
888 if (sym->flags & SYMBOL_CHECKED) 888 if (sym->flags & SYMBOL_CHECKED)
889 return NULL; 889 return NULL;
890 890
891 if (sym_is_choice_value(sym)) { 891 if (sym_is_choice_value(sym)) {
892 /* for choice groups start the check with main choice symbol */ 892 /* for choice groups start the check with main choice symbol */
893 prop = sym_get_choice_prop(sym); 893 prop = sym_get_choice_prop(sym);
894 sym2 = sym_check_deps(prop_get_symbol(prop)); 894 sym2 = sym_check_deps(prop_get_symbol(prop));
895 } else if (sym_is_choice(sym)) { 895 } else if (sym_is_choice(sym)) {
896 sym2 = sym_check_choice_deps(sym); 896 sym2 = sym_check_choice_deps(sym);
897 } else { 897 } else {
898 sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED); 898 sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
899 sym2 = sym_check_sym_deps(sym); 899 sym2 = sym_check_sym_deps(sym);
900 sym->flags &= ~SYMBOL_CHECK; 900 sym->flags &= ~SYMBOL_CHECK;
901 } 901 }
902 902
903 if (sym2) { 903 if (sym2) {
904 fprintf(stderr, " -> %s", sym->name ? sym->name : "<choice>"); 904 fprintf(stderr, " -> %s", sym->name ? sym->name : "<choice>");
905 if (sym2 == sym) { 905 if (sym2 == sym) {
906 fprintf(stderr, "\n"); 906 fprintf(stderr, "\n");
907 zconfnerrs++; 907 zconfnerrs++;
908 sym2 = NULL; 908 sym2 = NULL;
909 } 909 }
910 } 910 }
911 911
912 return sym2; 912 return sym2;
913 } 913 }
914 914
915 struct property *prop_alloc(enum prop_type type, struct symbol *sym) 915 struct property *prop_alloc(enum prop_type type, struct symbol *sym)
916 { 916 {
917 struct property *prop; 917 struct property *prop;
918 struct property **propp; 918 struct property **propp;
919 919
920 prop = malloc(sizeof(*prop)); 920 prop = malloc(sizeof(*prop));
921 memset(prop, 0, sizeof(*prop)); 921 memset(prop, 0, sizeof(*prop));
922 prop->type = type; 922 prop->type = type;
923 prop->sym = sym; 923 prop->sym = sym;
924 prop->file = current_file; 924 prop->file = current_file;
925 prop->lineno = zconf_lineno(); 925 prop->lineno = zconf_lineno();
926 926
927 /* append property to the prop list of symbol */ 927 /* append property to the prop list of symbol */
928 if (sym) { 928 if (sym) {
929 for (propp = &sym->prop; *propp; propp = &(*propp)->next) 929 for (propp = &sym->prop; *propp; propp = &(*propp)->next)
930 ; 930 ;
931 *propp = prop; 931 *propp = prop;
932 } 932 }
933 933
934 return prop; 934 return prop;
935 } 935 }
936 936
937 struct symbol *prop_get_symbol(struct property *prop) 937 struct symbol *prop_get_symbol(struct property *prop)
938 { 938 {
939 if (prop->expr && (prop->expr->type == E_SYMBOL || 939 if (prop->expr && (prop->expr->type == E_SYMBOL ||
940 prop->expr->type == E_LIST)) 940 prop->expr->type == E_LIST))
941 return prop->expr->left.sym; 941 return prop->expr->left.sym;
942 return NULL; 942 return NULL;
943 } 943 }
944 944
945 const char *prop_get_type_name(enum prop_type type) 945 const char *prop_get_type_name(enum prop_type type)
946 { 946 {
947 switch (type) { 947 switch (type) {
948 case P_PROMPT: 948 case P_PROMPT:
949 return "prompt"; 949 return "prompt";
950 case P_ENV: 950 case P_ENV:
951 return "env"; 951 return "env";
952 case P_COMMENT: 952 case P_COMMENT:
953 return "comment"; 953 return "comment";
954 case P_MENU: 954 case P_MENU:
955 return "menu"; 955 return "menu";
956 case P_DEFAULT: 956 case P_DEFAULT:
957 return "default"; 957 return "default";
958 case P_CHOICE: 958 case P_CHOICE:
959 return "choice"; 959 return "choice";
960 case P_SELECT: 960 case P_SELECT:
961 return "select"; 961 return "select";
962 case P_RANGE: 962 case P_RANGE:
963 return "range"; 963 return "range";
964 case P_SYMBOL:
965 return "symbol";
964 case P_UNKNOWN: 966 case P_UNKNOWN:
965 break; 967 break;
966 } 968 }
967 return "unknown"; 969 return "unknown";
968 } 970 }
969 971
970 static void prop_add_env(const char *env) 972 static void prop_add_env(const char *env)
971 { 973 {
972 struct symbol *sym, *sym2; 974 struct symbol *sym, *sym2;
973 struct property *prop; 975 struct property *prop;
974 char *p; 976 char *p;
975 977
976 sym = current_entry->sym; 978 sym = current_entry->sym;
977 sym->flags |= SYMBOL_AUTO; 979 sym->flags |= SYMBOL_AUTO;
978 for_all_properties(sym, prop, P_ENV) { 980 for_all_properties(sym, prop, P_ENV) {
979 sym2 = prop_get_symbol(prop); 981 sym2 = prop_get_symbol(prop);
980 if (strcmp(sym2->name, env)) 982 if (strcmp(sym2->name, env))
981 menu_warn(current_entry, "redefining environment symbol from %s", 983 menu_warn(current_entry, "redefining environment symbol from %s",
982 sym2->name); 984 sym2->name);
983 return; 985 return;
984 } 986 }
985 987
986 prop = prop_alloc(P_ENV, sym); 988 prop = prop_alloc(P_ENV, sym);
987 prop->expr = expr_alloc_symbol(sym_lookup(env, SYMBOL_CONST)); 989 prop->expr = expr_alloc_symbol(sym_lookup(env, SYMBOL_CONST));
988 990
989 sym_env_list = expr_alloc_one(E_LIST, sym_env_list); 991 sym_env_list = expr_alloc_one(E_LIST, sym_env_list);
990 sym_env_list->right.sym = sym; 992 sym_env_list->right.sym = sym;
991 993
992 p = getenv(env); 994 p = getenv(env);
993 if (p) 995 if (p)
994 sym_add_default(sym, p); 996 sym_add_default(sym, p);
995 else 997 else
996 menu_warn(current_entry, "environment variable %s undefined", env); 998 menu_warn(current_entry, "environment variable %s undefined", env);
997 } 999 }
998 1000