aboutsummaryrefslogtreecommitdiff
path: root/scripts/config/symbol.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2006-10-06 13:51:04 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2006-10-06 13:51:04 +0000
commit4fa499a17b52b299abc3a6ddd289bb6ca74bb84b (patch)
tree17df4dd427d85319857d9b7882585b3db9ad6994 /scripts/config/symbol.c
parentc12f53090bd41dbb87279083bc442769cb0610f0 (diff)
downloadbusybox-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.c810
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
16struct 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
34int sym_change_count;
35struct symbol *modules_sym;
36tristate modules_val;
37
38void 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
45void 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
71enum 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
84const 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
105struct 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
114struct 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
126struct 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
138static 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
168static 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
207void 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
315void 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
327void 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
338void 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
347bool 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
366bool 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
394tristate 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
417bool 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
460bool 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
502bool 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
551const 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
574bool sym_is_changable(struct symbol *sym)
575{
576 return sym->visible > sym->rev_dep.tri;
577}
578
579struct 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
625struct 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
654struct 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
691struct symbol *sym_check_deps(struct symbol *sym);
692
693static 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
723struct 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 }
752out:
753 if (sym2)
754 printf(" %s", sym->name);
755 sym->flags &= ~SYMBOL_CHECK;
756 return sym2;
757}
758
759struct 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
781struct 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
789const 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}