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