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