diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2006-10-06 13:51:04 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2006-10-06 13:51:04 +0000 |
commit | 4fa499a17b52b299abc3a6ddd289bb6ca74bb84b (patch) | |
tree | 17df4dd427d85319857d9b7882585b3db9ad6994 /scripts/config/symbol.c | |
parent | c12f53090bd41dbb87279083bc442769cb0610f0 (diff) | |
download | busybox-w32-4fa499a17b52b299abc3a6ddd289bb6ca74bb84b.tar.gz busybox-w32-4fa499a17b52b299abc3a6ddd289bb6ca74bb84b.tar.bz2 busybox-w32-4fa499a17b52b299abc3a6ddd289bb6ca74bb84b.zip |
build system: remove loeftover (two empty dirs)
Diffstat (limited to 'scripts/config/symbol.c')
-rw-r--r-- | scripts/config/symbol.c | 810 |
1 files changed, 0 insertions, 810 deletions
diff --git a/scripts/config/symbol.c b/scripts/config/symbol.c deleted file mode 100644 index aeea4cc9f..000000000 --- a/scripts/config/symbol.c +++ /dev/null | |||
@@ -1,810 +0,0 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> | ||
4 | * Released under the terms of the GNU GPL v2.0. | ||
5 | */ | ||
6 | |||
7 | #include <ctype.h> | ||
8 | #include <stdlib.h> | ||
9 | #include <string.h> | ||
10 | #include <regex.h> | ||
11 | #include <sys/utsname.h> | ||
12 | |||
13 | #define LKC_DIRECT_LINK | ||
14 | #include "lkc.h" | ||
15 | |||
16 | struct symbol symbol_yes = { | ||
17 | .name = "y", | ||
18 | .curr = { "y", yes }, | ||
19 | .flags = SYMBOL_YES|SYMBOL_VALID, | ||
20 | }, symbol_mod = { | ||
21 | .name = "m", | ||
22 | .curr = { "m", mod }, | ||
23 | .flags = SYMBOL_MOD|SYMBOL_VALID, | ||
24 | }, symbol_no = { | ||
25 | .name = "n", | ||
26 | .curr = { "n", no }, | ||
27 | .flags = SYMBOL_NO|SYMBOL_VALID, | ||
28 | }, symbol_empty = { | ||
29 | .name = "", | ||
30 | .curr = { "", no }, | ||
31 | .flags = SYMBOL_VALID, | ||
32 | }; | ||
33 | |||
34 | int sym_change_count; | ||
35 | struct symbol *modules_sym; | ||
36 | tristate modules_val; | ||
37 | |||
38 | void sym_add_default(struct symbol *sym, const char *def) | ||
39 | { | ||
40 | struct property *prop = prop_alloc(P_DEFAULT, sym); | ||
41 | |||
42 | prop->expr = expr_alloc_symbol(sym_lookup(def, 1)); | ||
43 | } | ||
44 | |||
45 | void sym_init(void) | ||
46 | { | ||
47 | struct symbol *sym; | ||
48 | char *p; | ||
49 | static bool inited = false; | ||
50 | |||
51 | if (inited) | ||
52 | return; | ||
53 | inited = true; | ||
54 | |||
55 | sym = sym_lookup("VERSION", 0); | ||
56 | sym->type = S_STRING; | ||
57 | sym->flags |= SYMBOL_AUTO; | ||
58 | p = getenv("VERSION"); | ||
59 | if (p) | ||
60 | sym_add_default(sym, p); | ||
61 | |||
62 | sym = sym_lookup("TARGET_ARCH", 0); | ||
63 | sym->type = S_STRING; | ||
64 | sym->flags |= SYMBOL_AUTO; | ||
65 | p = getenv("TARGET_ARCH"); | ||
66 | if (p) | ||
67 | sym_add_default(sym, p); | ||
68 | |||
69 | } | ||
70 | |||
71 | enum symbol_type sym_get_type(struct symbol *sym) | ||
72 | { | ||
73 | enum symbol_type type = sym->type; | ||
74 | |||
75 | if (type == S_TRISTATE) { | ||
76 | if (sym_is_choice_value(sym) && sym->visible == yes) | ||
77 | type = S_BOOLEAN; | ||
78 | else if (modules_val == no) | ||
79 | type = S_BOOLEAN; | ||
80 | } | ||
81 | return type; | ||
82 | } | ||
83 | |||
84 | const char *sym_type_name(enum symbol_type type) | ||
85 | { | ||
86 | switch (type) { | ||
87 | case S_BOOLEAN: | ||
88 | return "boolean"; | ||
89 | case S_TRISTATE: | ||
90 | return "tristate"; | ||
91 | case S_INT: | ||
92 | return "integer"; | ||
93 | case S_HEX: | ||
94 | return "hex"; | ||
95 | case S_STRING: | ||
96 | return "string"; | ||
97 | case S_UNKNOWN: | ||
98 | return "unknown"; | ||
99 | case S_OTHER: | ||
100 | break; | ||
101 | } | ||
102 | return "???"; | ||
103 | } | ||
104 | |||
105 | struct property *sym_get_choice_prop(struct symbol *sym) | ||
106 | { | ||
107 | struct property *prop; | ||
108 | |||
109 | for_all_choices(sym, prop) | ||
110 | return prop; | ||
111 | return NULL; | ||
112 | } | ||
113 | |||
114 | struct property *sym_get_default_prop(struct symbol *sym) | ||
115 | { | ||
116 | struct property *prop; | ||
117 | |||
118 | for_all_defaults(sym, prop) { | ||
119 | prop->visible.tri = expr_calc_value(prop->visible.expr); | ||
120 | if (prop->visible.tri != no) | ||
121 | return prop; | ||
122 | } | ||
123 | return NULL; | ||
124 | } | ||
125 | |||
126 | struct property *sym_get_range_prop(struct symbol *sym) | ||
127 | { | ||
128 | struct property *prop; | ||
129 | |||
130 | for_all_properties(sym, prop, P_RANGE) { | ||
131 | prop->visible.tri = expr_calc_value(prop->visible.expr); | ||
132 | if (prop->visible.tri != no) | ||
133 | return prop; | ||
134 | } | ||
135 | return NULL; | ||
136 | } | ||
137 | |||
138 | static void sym_calc_visibility(struct symbol *sym) | ||
139 | { | ||
140 | struct property *prop; | ||
141 | tristate tri; | ||
142 | |||
143 | /* any prompt visible? */ | ||
144 | tri = no; | ||
145 | for_all_prompts(sym, prop) { | ||
146 | prop->visible.tri = expr_calc_value(prop->visible.expr); | ||
147 | tri = E_OR(tri, prop->visible.tri); | ||
148 | } | ||
149 | if (tri == mod && (sym->type != S_TRISTATE || modules_val == no)) | ||
150 | tri = yes; | ||
151 | if (sym->visible != tri) { | ||
152 | sym->visible = tri; | ||
153 | sym_set_changed(sym); | ||
154 | } | ||
155 | if (sym_is_choice_value(sym)) | ||
156 | return; | ||
157 | tri = no; | ||
158 | if (sym->rev_dep.expr) | ||
159 | tri = expr_calc_value(sym->rev_dep.expr); | ||
160 | if (tri == mod && sym_get_type(sym) == S_BOOLEAN) | ||
161 | tri = yes; | ||
162 | if (sym->rev_dep.tri != tri) { | ||
163 | sym->rev_dep.tri = tri; | ||
164 | sym_set_changed(sym); | ||
165 | } | ||
166 | } | ||
167 | |||
168 | static struct symbol *sym_calc_choice(struct symbol *sym) | ||
169 | { | ||
170 | struct symbol *def_sym; | ||
171 | struct property *prop; | ||
172 | struct expr *e; | ||
173 | |||
174 | /* is the user choice visible? */ | ||
175 | def_sym = sym->user.val; | ||
176 | if (def_sym) { | ||
177 | sym_calc_visibility(def_sym); | ||
178 | if (def_sym->visible != no) | ||
179 | return def_sym; | ||
180 | } | ||
181 | |||
182 | /* any of the defaults visible? */ | ||
183 | for_all_defaults(sym, prop) { | ||
184 | prop->visible.tri = expr_calc_value(prop->visible.expr); | ||
185 | if (prop->visible.tri == no) | ||
186 | continue; | ||
187 | def_sym = prop_get_symbol(prop); | ||
188 | sym_calc_visibility(def_sym); | ||
189 | if (def_sym->visible != no) | ||
190 | return def_sym; | ||
191 | } | ||
192 | |||
193 | /* just get the first visible value */ | ||
194 | prop = sym_get_choice_prop(sym); | ||
195 | for (e = prop->expr; e; e = e->left.expr) { | ||
196 | def_sym = e->right.sym; | ||
197 | sym_calc_visibility(def_sym); | ||
198 | if (def_sym->visible != no) | ||
199 | return def_sym; | ||
200 | } | ||
201 | |||
202 | /* no choice? reset tristate value */ | ||
203 | sym->curr.tri = no; | ||
204 | return NULL; | ||
205 | } | ||
206 | |||
207 | void sym_calc_value(struct symbol *sym) | ||
208 | { | ||
209 | struct symbol_value newval, oldval; | ||
210 | struct property *prop; | ||
211 | struct expr *e; | ||
212 | |||
213 | if (!sym) | ||
214 | return; | ||
215 | |||
216 | if (sym->flags & SYMBOL_VALID) | ||
217 | return; | ||
218 | sym->flags |= SYMBOL_VALID; | ||
219 | |||
220 | oldval = sym->curr; | ||
221 | |||
222 | switch (sym->type) { | ||
223 | case S_INT: | ||
224 | case S_HEX: | ||
225 | case S_STRING: | ||
226 | newval = symbol_empty.curr; | ||
227 | break; | ||
228 | case S_BOOLEAN: | ||
229 | case S_TRISTATE: | ||
230 | newval = symbol_no.curr; | ||
231 | break; | ||
232 | default: | ||
233 | sym->curr.val = sym->name; | ||
234 | sym->curr.tri = no; | ||
235 | return; | ||
236 | } | ||
237 | if (!sym_is_choice_value(sym)) | ||
238 | sym->flags &= ~SYMBOL_WRITE; | ||
239 | |||
240 | sym_calc_visibility(sym); | ||
241 | |||
242 | /* set default if recursively called */ | ||
243 | sym->curr = newval; | ||
244 | |||
245 | switch (sym_get_type(sym)) { | ||
246 | case S_BOOLEAN: | ||
247 | case S_TRISTATE: | ||
248 | if (sym_is_choice_value(sym) && sym->visible == yes) { | ||
249 | prop = sym_get_choice_prop(sym); | ||
250 | newval.tri = (prop_get_symbol(prop)->curr.val == sym) ? yes : no; | ||
251 | } else if (E_OR(sym->visible, sym->rev_dep.tri) != no) { | ||
252 | sym->flags |= SYMBOL_WRITE; | ||
253 | if (sym_has_value(sym)) | ||
254 | newval.tri = sym->user.tri; | ||
255 | else if (!sym_is_choice(sym)) { | ||
256 | prop = sym_get_default_prop(sym); | ||
257 | if (prop) | ||
258 | newval.tri = expr_calc_value(prop->expr); | ||
259 | } | ||
260 | newval.tri = E_OR(E_AND(newval.tri, sym->visible), sym->rev_dep.tri); | ||
261 | } else if (!sym_is_choice(sym)) { | ||
262 | prop = sym_get_default_prop(sym); | ||
263 | if (prop) { | ||
264 | sym->flags |= SYMBOL_WRITE; | ||
265 | newval.tri = expr_calc_value(prop->expr); | ||
266 | } | ||
267 | } | ||
268 | if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN) | ||
269 | newval.tri = yes; | ||
270 | break; | ||
271 | case S_STRING: | ||
272 | case S_HEX: | ||
273 | case S_INT: | ||
274 | if (sym->visible != no) { | ||
275 | sym->flags |= SYMBOL_WRITE; | ||
276 | if (sym_has_value(sym)) { | ||
277 | newval.val = sym->user.val; | ||
278 | break; | ||
279 | } | ||
280 | } | ||
281 | prop = sym_get_default_prop(sym); | ||
282 | if (prop) { | ||
283 | struct symbol *ds = prop_get_symbol(prop); | ||
284 | if (ds) { | ||
285 | sym->flags |= SYMBOL_WRITE; | ||
286 | sym_calc_value(ds); | ||
287 | newval.val = ds->curr.val; | ||
288 | } | ||
289 | } | ||
290 | break; | ||
291 | default: | ||
292 | ; | ||
293 | } | ||
294 | |||
295 | sym->curr = newval; | ||
296 | if (sym_is_choice(sym) && newval.tri == yes) | ||
297 | sym->curr.val = sym_calc_choice(sym); | ||
298 | |||
299 | if (memcmp(&oldval, &sym->curr, sizeof(oldval))) | ||
300 | sym_set_changed(sym); | ||
301 | if (modules_sym == sym) | ||
302 | modules_val = modules_sym->curr.tri; | ||
303 | |||
304 | if (sym_is_choice(sym)) { | ||
305 | int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE); | ||
306 | prop = sym_get_choice_prop(sym); | ||
307 | for (e = prop->expr; e; e = e->left.expr) { | ||
308 | e->right.sym->flags |= flags; | ||
309 | if (flags & SYMBOL_CHANGED) | ||
310 | sym_set_changed(e->right.sym); | ||
311 | } | ||
312 | } | ||
313 | } | ||
314 | |||
315 | void sym_clear_all_valid(void) | ||
316 | { | ||
317 | struct symbol *sym; | ||
318 | int i; | ||
319 | |||
320 | for_all_symbols(i, sym) | ||
321 | sym->flags &= ~SYMBOL_VALID; | ||
322 | sym_change_count++; | ||
323 | if (modules_sym) | ||
324 | sym_calc_value(modules_sym); | ||
325 | } | ||
326 | |||
327 | void sym_set_changed(struct symbol *sym) | ||
328 | { | ||
329 | struct property *prop; | ||
330 | |||
331 | sym->flags |= SYMBOL_CHANGED; | ||
332 | for (prop = sym->prop; prop; prop = prop->next) { | ||
333 | if (prop->menu) | ||
334 | prop->menu->flags |= MENU_CHANGED; | ||
335 | } | ||
336 | } | ||
337 | |||
338 | void sym_set_all_changed(void) | ||
339 | { | ||
340 | struct symbol *sym; | ||
341 | int i; | ||
342 | |||
343 | for_all_symbols(i, sym) | ||
344 | sym_set_changed(sym); | ||
345 | } | ||
346 | |||
347 | bool sym_tristate_within_range(struct symbol *sym, tristate val) | ||
348 | { | ||
349 | int type = sym_get_type(sym); | ||
350 | |||
351 | if (sym->visible == no) | ||
352 | return false; | ||
353 | |||
354 | if (type != S_BOOLEAN && type != S_TRISTATE) | ||
355 | return false; | ||
356 | |||
357 | if (type == S_BOOLEAN && val == mod) | ||
358 | return false; | ||
359 | if (sym->visible <= sym->rev_dep.tri) | ||
360 | return false; | ||
361 | if (sym_is_choice_value(sym) && sym->visible == yes) | ||
362 | return val == yes; | ||
363 | return val >= sym->rev_dep.tri && val <= sym->visible; | ||
364 | } | ||
365 | |||
366 | bool sym_set_tristate_value(struct symbol *sym, tristate val) | ||
367 | { | ||
368 | tristate oldval = sym_get_tristate_value(sym); | ||
369 | |||
370 | if (oldval != val && !sym_tristate_within_range(sym, val)) | ||
371 | return false; | ||
372 | |||
373 | if (sym->flags & SYMBOL_NEW) { | ||
374 | sym->flags &= ~SYMBOL_NEW; | ||
375 | sym_set_changed(sym); | ||
376 | } | ||
377 | if (sym_is_choice_value(sym) && val == yes) { | ||
378 | struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); | ||
379 | |||
380 | cs->user.val = sym; | ||
381 | cs->flags &= ~SYMBOL_NEW; | ||
382 | } | ||
383 | |||
384 | sym->user.tri = val; | ||
385 | if (oldval != val) { | ||
386 | sym_clear_all_valid(); | ||
387 | if (sym == modules_sym) | ||
388 | sym_set_all_changed(); | ||
389 | } | ||
390 | |||
391 | return true; | ||
392 | } | ||
393 | |||
394 | tristate sym_toggle_tristate_value(struct symbol *sym) | ||
395 | { | ||
396 | tristate oldval, newval; | ||
397 | |||
398 | oldval = newval = sym_get_tristate_value(sym); | ||
399 | do { | ||
400 | switch (newval) { | ||
401 | case no: | ||
402 | newval = mod; | ||
403 | break; | ||
404 | case mod: | ||
405 | newval = yes; | ||
406 | break; | ||
407 | case yes: | ||
408 | newval = no; | ||
409 | break; | ||
410 | } | ||
411 | if (sym_set_tristate_value(sym, newval)) | ||
412 | break; | ||
413 | } while (oldval != newval); | ||
414 | return newval; | ||
415 | } | ||
416 | |||
417 | bool sym_string_valid(struct symbol *sym, const char *str) | ||
418 | { | ||
419 | signed char ch; | ||
420 | |||
421 | switch (sym->type) { | ||
422 | case S_STRING: | ||
423 | return true; | ||
424 | case S_INT: | ||
425 | ch = *str++; | ||
426 | if (ch == '-') | ||
427 | ch = *str++; | ||
428 | if (!isdigit(ch)) | ||
429 | return false; | ||
430 | if (ch == '0' && *str != 0) | ||
431 | return false; | ||
432 | while ((ch = *str++)) { | ||
433 | if (!isdigit(ch)) | ||
434 | return false; | ||
435 | } | ||
436 | return true; | ||
437 | case S_HEX: | ||
438 | if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) | ||
439 | str += 2; | ||
440 | ch = *str++; | ||
441 | do { | ||
442 | if (!isxdigit(ch)) | ||
443 | return false; | ||
444 | } while ((ch = *str++)); | ||
445 | return true; | ||
446 | case S_BOOLEAN: | ||
447 | case S_TRISTATE: | ||
448 | switch (str[0]) { | ||
449 | case 'y': case 'Y': | ||
450 | case 'm': case 'M': | ||
451 | case 'n': case 'N': | ||
452 | return true; | ||
453 | } | ||
454 | return false; | ||
455 | default: | ||
456 | return false; | ||
457 | } | ||
458 | } | ||
459 | |||
460 | bool sym_string_within_range(struct symbol *sym, const char *str) | ||
461 | { | ||
462 | struct property *prop; | ||
463 | int val; | ||
464 | |||
465 | switch (sym->type) { | ||
466 | case S_STRING: | ||
467 | return sym_string_valid(sym, str); | ||
468 | case S_INT: | ||
469 | if (!sym_string_valid(sym, str)) | ||
470 | return false; | ||
471 | prop = sym_get_range_prop(sym); | ||
472 | if (!prop) | ||
473 | return true; | ||
474 | val = strtol(str, NULL, 10); | ||
475 | return val >= strtol(prop->expr->left.sym->name, NULL, 10) && | ||
476 | val <= strtol(prop->expr->right.sym->name, NULL, 10); | ||
477 | case S_HEX: | ||
478 | if (!sym_string_valid(sym, str)) | ||
479 | return false; | ||
480 | prop = sym_get_range_prop(sym); | ||
481 | if (!prop) | ||
482 | return true; | ||
483 | val = strtol(str, NULL, 16); | ||
484 | return val >= strtol(prop->expr->left.sym->name, NULL, 16) && | ||
485 | val <= strtol(prop->expr->right.sym->name, NULL, 16); | ||
486 | case S_BOOLEAN: | ||
487 | case S_TRISTATE: | ||
488 | switch (str[0]) { | ||
489 | case 'y': case 'Y': | ||
490 | return sym_tristate_within_range(sym, yes); | ||
491 | case 'm': case 'M': | ||
492 | return sym_tristate_within_range(sym, mod); | ||
493 | case 'n': case 'N': | ||
494 | return sym_tristate_within_range(sym, no); | ||
495 | } | ||
496 | return false; | ||
497 | default: | ||
498 | return false; | ||
499 | } | ||
500 | } | ||
501 | |||
502 | bool sym_set_string_value(struct symbol *sym, const char *newval) | ||
503 | { | ||
504 | const char *oldval; | ||
505 | char *val; | ||
506 | int size; | ||
507 | |||
508 | switch (sym->type) { | ||
509 | case S_BOOLEAN: | ||
510 | case S_TRISTATE: | ||
511 | switch (newval[0]) { | ||
512 | case 'y': case 'Y': | ||
513 | return sym_set_tristate_value(sym, yes); | ||
514 | case 'm': case 'M': | ||
515 | return sym_set_tristate_value(sym, mod); | ||
516 | case 'n': case 'N': | ||
517 | return sym_set_tristate_value(sym, no); | ||
518 | } | ||
519 | return false; | ||
520 | default: | ||
521 | ; | ||
522 | } | ||
523 | |||
524 | if (!sym_string_within_range(sym, newval)) | ||
525 | return false; | ||
526 | |||
527 | if (sym->flags & SYMBOL_NEW) { | ||
528 | sym->flags &= ~SYMBOL_NEW; | ||
529 | sym_set_changed(sym); | ||
530 | } | ||
531 | |||
532 | oldval = sym->user.val; | ||
533 | size = strlen(newval) + 1; | ||
534 | if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) { | ||
535 | size += 2; | ||
536 | sym->user.val = val = malloc(size); | ||
537 | *val++ = '0'; | ||
538 | *val++ = 'x'; | ||
539 | } else if (!oldval || strcmp(oldval, newval)) | ||
540 | sym->user.val = val = malloc(size); | ||
541 | else | ||
542 | return true; | ||
543 | |||
544 | strcpy(val, newval); | ||
545 | free((void *)oldval); | ||
546 | sym_clear_all_valid(); | ||
547 | |||
548 | return true; | ||
549 | } | ||
550 | |||
551 | const char *sym_get_string_value(struct symbol *sym) | ||
552 | { | ||
553 | tristate val; | ||
554 | |||
555 | switch (sym->type) { | ||
556 | case S_BOOLEAN: | ||
557 | case S_TRISTATE: | ||
558 | val = sym_get_tristate_value(sym); | ||
559 | switch (val) { | ||
560 | case no: | ||
561 | return "n"; | ||
562 | case mod: | ||
563 | return "m"; | ||
564 | case yes: | ||
565 | return "y"; | ||
566 | } | ||
567 | break; | ||
568 | default: | ||
569 | ; | ||
570 | } | ||
571 | return (const char *)sym->curr.val; | ||
572 | } | ||
573 | |||
574 | bool sym_is_changable(struct symbol *sym) | ||
575 | { | ||
576 | return sym->visible > sym->rev_dep.tri; | ||
577 | } | ||
578 | |||
579 | struct symbol *sym_lookup(const char *name, int isconst) | ||
580 | { | ||
581 | struct symbol *symbol; | ||
582 | const char *ptr; | ||
583 | char *new_name; | ||
584 | int hash = 0; | ||
585 | |||
586 | if (name) { | ||
587 | if (name[0] && !name[1]) { | ||
588 | switch (name[0]) { | ||
589 | case 'y': return &symbol_yes; | ||
590 | case 'm': return &symbol_mod; | ||
591 | case 'n': return &symbol_no; | ||
592 | } | ||
593 | } | ||
594 | for (ptr = name; *ptr; ptr++) | ||
595 | hash += *ptr; | ||
596 | hash &= 0xff; | ||
597 | |||
598 | for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) { | ||
599 | if (!strcmp(symbol->name, name)) { | ||
600 | if ((isconst && symbol->flags & SYMBOL_CONST) || | ||
601 | (!isconst && !(symbol->flags & SYMBOL_CONST))) | ||
602 | return symbol; | ||
603 | } | ||
604 | } | ||
605 | new_name = strdup(name); | ||
606 | } else { | ||
607 | new_name = NULL; | ||
608 | hash = 256; | ||
609 | } | ||
610 | |||
611 | symbol = malloc(sizeof(*symbol)); | ||
612 | memset(symbol, 0, sizeof(*symbol)); | ||
613 | symbol->name = new_name; | ||
614 | symbol->type = S_UNKNOWN; | ||
615 | symbol->flags = SYMBOL_NEW; | ||
616 | if (isconst) | ||
617 | symbol->flags |= SYMBOL_CONST; | ||
618 | |||
619 | symbol->next = symbol_hash[hash]; | ||
620 | symbol_hash[hash] = symbol; | ||
621 | |||
622 | return symbol; | ||
623 | } | ||
624 | |||
625 | struct symbol *sym_find(const char *name) | ||
626 | { | ||
627 | struct symbol *symbol = NULL; | ||
628 | const char *ptr; | ||
629 | int hash = 0; | ||
630 | |||
631 | if (!name) | ||
632 | return NULL; | ||
633 | |||
634 | if (name[0] && !name[1]) { | ||
635 | switch (name[0]) { | ||
636 | case 'y': return &symbol_yes; | ||
637 | case 'm': return &symbol_mod; | ||
638 | case 'n': return &symbol_no; | ||
639 | } | ||
640 | } | ||
641 | for (ptr = name; *ptr; ptr++) | ||
642 | hash += *ptr; | ||
643 | hash &= 0xff; | ||
644 | |||
645 | for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) { | ||
646 | if (!strcmp(symbol->name, name) && | ||
647 | !(symbol->flags & SYMBOL_CONST)) | ||
648 | break; | ||
649 | } | ||
650 | |||
651 | return symbol; | ||
652 | } | ||
653 | |||
654 | struct symbol **sym_re_search(const char *pattern) | ||
655 | { | ||
656 | struct symbol *sym, **sym_arr = NULL; | ||
657 | int i, cnt, size; | ||
658 | regex_t re; | ||
659 | |||
660 | cnt = size = 0; | ||
661 | /* Skip if empty */ | ||
662 | if (strlen(pattern) == 0) | ||
663 | return NULL; | ||
664 | if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB|REG_ICASE)) | ||
665 | return NULL; | ||
666 | |||
667 | for_all_symbols(i, sym) { | ||
668 | if (sym->flags & SYMBOL_CONST || !sym->name) | ||
669 | continue; | ||
670 | if (regexec(&re, sym->name, 0, NULL, 0)) | ||
671 | continue; | ||
672 | if (cnt + 1 >= size) { | ||
673 | void *tmp = sym_arr; | ||
674 | size += 16; | ||
675 | sym_arr = realloc(sym_arr, size * sizeof(struct symbol *)); | ||
676 | if (!sym_arr) { | ||
677 | free(tmp); | ||
678 | return NULL; | ||
679 | } | ||
680 | } | ||
681 | sym_arr[cnt++] = sym; | ||
682 | } | ||
683 | if (sym_arr) | ||
684 | sym_arr[cnt] = NULL; | ||
685 | regfree(&re); | ||
686 | |||
687 | return sym_arr; | ||
688 | } | ||
689 | |||
690 | |||
691 | struct symbol *sym_check_deps(struct symbol *sym); | ||
692 | |||
693 | static struct symbol *sym_check_expr_deps(struct expr *e) | ||
694 | { | ||
695 | struct symbol *sym; | ||
696 | |||
697 | if (!e) | ||
698 | return NULL; | ||
699 | switch (e->type) { | ||
700 | case E_OR: | ||
701 | case E_AND: | ||
702 | sym = sym_check_expr_deps(e->left.expr); | ||
703 | if (sym) | ||
704 | return sym; | ||
705 | return sym_check_expr_deps(e->right.expr); | ||
706 | case E_NOT: | ||
707 | return sym_check_expr_deps(e->left.expr); | ||
708 | case E_EQUAL: | ||
709 | case E_UNEQUAL: | ||
710 | sym = sym_check_deps(e->left.sym); | ||
711 | if (sym) | ||
712 | return sym; | ||
713 | return sym_check_deps(e->right.sym); | ||
714 | case E_SYMBOL: | ||
715 | return sym_check_deps(e->left.sym); | ||
716 | default: | ||
717 | break; | ||
718 | } | ||
719 | printf("Oops! How to check %d?\n", e->type); | ||
720 | return NULL; | ||
721 | } | ||
722 | |||
723 | struct symbol *sym_check_deps(struct symbol *sym) | ||
724 | { | ||
725 | struct symbol *sym2; | ||
726 | struct property *prop; | ||
727 | |||
728 | if (sym->flags & SYMBOL_CHECK_DONE) | ||
729 | return NULL; | ||
730 | if (sym->flags & SYMBOL_CHECK) { | ||
731 | printf("Warning! Found recursive dependency: %s", sym->name); | ||
732 | return sym; | ||
733 | } | ||
734 | |||
735 | sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED); | ||
736 | sym2 = sym_check_expr_deps(sym->rev_dep.expr); | ||
737 | if (sym2) | ||
738 | goto out; | ||
739 | |||
740 | for (prop = sym->prop; prop; prop = prop->next) { | ||
741 | if (prop->type == P_CHOICE || prop->type == P_SELECT) | ||
742 | continue; | ||
743 | sym2 = sym_check_expr_deps(prop->visible.expr); | ||
744 | if (sym2) | ||
745 | goto out; | ||
746 | if (prop->type != P_DEFAULT || sym_is_choice(sym)) | ||
747 | continue; | ||
748 | sym2 = sym_check_expr_deps(prop->expr); | ||
749 | if (sym2) | ||
750 | goto out; | ||
751 | } | ||
752 | out: | ||
753 | if (sym2) | ||
754 | printf(" %s", sym->name); | ||
755 | sym->flags &= ~SYMBOL_CHECK; | ||
756 | return sym2; | ||
757 | } | ||
758 | |||
759 | struct property *prop_alloc(enum prop_type type, struct symbol *sym) | ||
760 | { | ||
761 | struct property *prop; | ||
762 | struct property **propp; | ||
763 | |||
764 | prop = malloc(sizeof(*prop)); | ||
765 | memset(prop, 0, sizeof(*prop)); | ||
766 | prop->type = type; | ||
767 | prop->sym = sym; | ||
768 | prop->file = current_file; | ||
769 | prop->lineno = zconf_lineno(); | ||
770 | |||
771 | /* append property to the prop list of symbol */ | ||
772 | if (sym) { | ||
773 | for (propp = &sym->prop; *propp; propp = &(*propp)->next) | ||
774 | ; | ||
775 | *propp = prop; | ||
776 | } | ||
777 | |||
778 | return prop; | ||
779 | } | ||
780 | |||
781 | struct symbol *prop_get_symbol(struct property *prop) | ||
782 | { | ||
783 | if (prop->expr && (prop->expr->type == E_SYMBOL || | ||
784 | prop->expr->type == E_CHOICE)) | ||
785 | return prop->expr->left.sym; | ||
786 | return NULL; | ||
787 | } | ||
788 | |||
789 | const char *prop_get_type_name(enum prop_type type) | ||
790 | { | ||
791 | switch (type) { | ||
792 | case P_PROMPT: | ||
793 | return "prompt"; | ||
794 | case P_COMMENT: | ||
795 | return "comment"; | ||
796 | case P_MENU: | ||
797 | return "menu"; | ||
798 | case P_DEFAULT: | ||
799 | return "default"; | ||
800 | case P_CHOICE: | ||
801 | return "choice"; | ||
802 | case P_SELECT: | ||
803 | return "select"; | ||
804 | case P_RANGE: | ||
805 | return "range"; | ||
806 | case P_UNKNOWN: | ||
807 | break; | ||
808 | } | ||
809 | return "unknown"; | ||
810 | } | ||