Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
symbol.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2002 Roman Zippel <[email protected]>
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 <regex.h>
10 #include <sys/utsname.h>
11 
12 #include "lkc.h"
13 
14 struct symbol symbol_yes = {
15  .name = "y",
16  .curr = { "y", yes },
17  .flags = SYMBOL_CONST|SYMBOL_VALID,
18 }, symbol_mod = {
19  .name = "m",
20  .curr = { "m", mod },
21  .flags = SYMBOL_CONST|SYMBOL_VALID,
22 }, symbol_no = {
23  .name = "n",
24  .curr = { "n", no },
25  .flags = SYMBOL_CONST|SYMBOL_VALID,
27  .name = "",
28  .curr = { "", no },
29  .flags = SYMBOL_VALID,
30 };
31 
35 
37 
38 static void sym_add_default(struct symbol *sym, const char *def)
39 {
40  struct property *prop = prop_alloc(P_DEFAULT, sym);
41 
43 }
44 
45 void sym_init(void)
46 {
47  struct symbol *sym;
48  struct utsname uts;
49  static bool inited = false;
50 
51  if (inited)
52  return;
53  inited = true;
54 
55  uname(&uts);
56 
57  sym = sym_lookup("UNAME_RELEASE", 0);
58  sym->type = S_STRING;
59  sym->flags |= SYMBOL_AUTO;
60  sym_add_default(sym, uts.release);
61 }
62 
63 enum symbol_type sym_get_type(struct symbol *sym)
64 {
65  enum symbol_type type = sym->type;
66 
67  if (type == S_TRISTATE) {
68  if (sym_is_choice_value(sym) && sym->visible == yes)
69  type = S_BOOLEAN;
70  else if (modules_val == no)
71  type = S_BOOLEAN;
72  }
73  return type;
74 }
75 
76 const char *sym_type_name(enum symbol_type type)
77 {
78  switch (type) {
79  case S_BOOLEAN:
80  return "boolean";
81  case S_TRISTATE:
82  return "tristate";
83  case S_INT:
84  return "integer";
85  case S_HEX:
86  return "hex";
87  case S_STRING:
88  return "string";
89  case S_UNKNOWN:
90  return "unknown";
91  case S_OTHER:
92  break;
93  }
94  return "???";
95 }
96 
98 {
99  struct property *prop;
100 
101  for_all_choices(sym, prop)
102  return prop;
103  return NULL;
104 }
105 
107 {
108  struct property *prop;
109 
110  for_all_properties(sym, prop, P_ENV)
111  return prop;
112  return NULL;
113 }
114 
116 {
117  struct property *prop;
118 
119  for_all_defaults(sym, prop) {
120  prop->visible.tri = expr_calc_value(prop->visible.expr);
121  if (prop->visible.tri != no)
122  return prop;
123  }
124  return NULL;
125 }
126 
127 static struct property *sym_get_range_prop(struct symbol *sym)
128 {
129  struct property *prop;
130 
131  for_all_properties(sym, prop, P_RANGE) {
132  prop->visible.tri = expr_calc_value(prop->visible.expr);
133  if (prop->visible.tri != no)
134  return prop;
135  }
136  return NULL;
137 }
138 
139 static int sym_get_range_val(struct symbol *sym, int base)
140 {
141  sym_calc_value(sym);
142  switch (sym->type) {
143  case S_INT:
144  base = 10;
145  break;
146  case S_HEX:
147  base = 16;
148  break;
149  default:
150  break;
151  }
152  return strtol(sym->curr.val, NULL, base);
153 }
154 
155 static void sym_validate_range(struct symbol *sym)
156 {
157  struct property *prop;
158  int base, val, val2;
159  char str[64];
160 
161  switch (sym->type) {
162  case S_INT:
163  base = 10;
164  break;
165  case S_HEX:
166  base = 16;
167  break;
168  default:
169  return;
170  }
171  prop = sym_get_range_prop(sym);
172  if (!prop)
173  return;
174  val = strtol(sym->curr.val, NULL, base);
175  val2 = sym_get_range_val(prop->expr->left.sym, base);
176  if (val >= val2) {
177  val2 = sym_get_range_val(prop->expr->right.sym, base);
178  if (val <= val2)
179  return;
180  }
181  if (sym->type == S_INT)
182  sprintf(str, "%d", val2);
183  else
184  sprintf(str, "0x%x", val2);
185  sym->curr.val = strdup(str);
186 }
187 
188 static void sym_calc_visibility(struct symbol *sym)
189 {
190  struct property *prop;
191  tristate tri;
192 
193  /* any prompt visible? */
194  tri = no;
195  for_all_prompts(sym, prop) {
196  prop->visible.tri = expr_calc_value(prop->visible.expr);
197  tri = EXPR_OR(tri, prop->visible.tri);
198  }
199  if (tri == mod && (sym->type != S_TRISTATE || modules_val == no))
200  tri = yes;
201  if (sym->visible != tri) {
202  sym->visible = tri;
203  sym_set_changed(sym);
204  }
205  if (sym_is_choice_value(sym))
206  return;
207  /* defaulting to "yes" if no explicit "depends on" are given */
208  tri = yes;
209  if (sym->dir_dep.expr)
210  tri = expr_calc_value(sym->dir_dep.expr);
211  if (tri == mod)
212  tri = yes;
213  if (sym->dir_dep.tri != tri) {
214  sym->dir_dep.tri = tri;
215  sym_set_changed(sym);
216  }
217  tri = no;
218  if (sym->rev_dep.expr)
219  tri = expr_calc_value(sym->rev_dep.expr);
220  if (tri == mod && sym_get_type(sym) == S_BOOLEAN)
221  tri = yes;
222  if (sym->rev_dep.tri != tri) {
223  sym->rev_dep.tri = tri;
224  sym_set_changed(sym);
225  }
226 }
227 
228 /*
229  * Find the default symbol for a choice.
230  * First try the default values for the choice symbol
231  * Next locate the first visible choice value
232  * Return NULL if none was found
233  */
234 struct symbol *sym_choice_default(struct symbol *sym)
235 {
236  struct symbol *def_sym;
237  struct property *prop;
238  struct expr *e;
239 
240  /* any of the defaults visible? */
241  for_all_defaults(sym, prop) {
242  prop->visible.tri = expr_calc_value(prop->visible.expr);
243  if (prop->visible.tri == no)
244  continue;
245  def_sym = prop_get_symbol(prop);
246  if (def_sym->visible != no)
247  return def_sym;
248  }
249 
250  /* just get the first visible value */
251  prop = sym_get_choice_prop(sym);
252  expr_list_for_each_sym(prop->expr, e, def_sym)
253  if (def_sym->visible != no)
254  return def_sym;
255 
256  /* failed to locate any defaults */
257  return NULL;
258 }
259 
260 static struct symbol *sym_calc_choice(struct symbol *sym)
261 {
262  struct symbol *def_sym;
263  struct property *prop;
264  struct expr *e;
265  int flags;
266 
267  /* first calculate all choice values' visibilities */
268  flags = sym->flags;
269  prop = sym_get_choice_prop(sym);
270  expr_list_for_each_sym(prop->expr, e, def_sym) {
271  sym_calc_visibility(def_sym);
272  if (def_sym->visible != no)
273  flags &= def_sym->flags;
274  }
275 
276  sym->flags &= flags | ~SYMBOL_DEF_USER;
277 
278  /* is the user choice visible? */
279  def_sym = sym->def[S_DEF_USER].val;
280  if (def_sym && def_sym->visible != no)
281  return def_sym;
282 
283  def_sym = sym_choice_default(sym);
284 
285  if (def_sym == NULL)
286  /* no choice? reset tristate value */
287  sym->curr.tri = no;
288 
289  return def_sym;
290 }
291 
292 void sym_calc_value(struct symbol *sym)
293 {
294  struct symbol_value newval, oldval;
295  struct property *prop;
296  struct expr *e;
297 
298  if (!sym)
299  return;
300 
301  if (sym->flags & SYMBOL_VALID)
302  return;
303  sym->flags |= SYMBOL_VALID;
304 
305  oldval = sym->curr;
306 
307  switch (sym->type) {
308  case S_INT:
309  case S_HEX:
310  case S_STRING:
311  newval = symbol_empty.curr;
312  break;
313  case S_BOOLEAN:
314  case S_TRISTATE:
315  newval = symbol_no.curr;
316  break;
317  default:
318  sym->curr.val = sym->name;
319  sym->curr.tri = no;
320  return;
321  }
322  if (!sym_is_choice_value(sym))
323  sym->flags &= ~SYMBOL_WRITE;
324 
325  sym_calc_visibility(sym);
326 
327  /* set default if recursively called */
328  sym->curr = newval;
329 
330  switch (sym_get_type(sym)) {
331  case S_BOOLEAN:
332  case S_TRISTATE:
333  if (sym_is_choice_value(sym) && sym->visible == yes) {
334  prop = sym_get_choice_prop(sym);
335  newval.tri = (prop_get_symbol(prop)->curr.val == sym) ? yes : no;
336  } else {
337  if (sym->visible != no) {
338  /* if the symbol is visible use the user value
339  * if available, otherwise try the default value
340  */
341  sym->flags |= SYMBOL_WRITE;
342  if (sym_has_value(sym)) {
343  newval.tri = EXPR_AND(sym->def[S_DEF_USER].tri,
344  sym->visible);
345  goto calc_newval;
346  }
347  }
348  if (sym->rev_dep.tri != no)
349  sym->flags |= SYMBOL_WRITE;
350  if (!sym_is_choice(sym)) {
351  prop = sym_get_default_prop(sym);
352  if (prop) {
353  sym->flags |= SYMBOL_WRITE;
354  newval.tri = EXPR_AND(expr_calc_value(prop->expr),
355  prop->visible.tri);
356  }
357  }
358  calc_newval:
359  if (sym->dir_dep.tri == no && sym->rev_dep.tri != no) {
360  struct expr *e;
361  e = expr_simplify_unmet_dep(sym->rev_dep.expr,
362  sym->dir_dep.expr);
363  fprintf(stderr, "warning: (");
364  expr_fprint(e, stderr);
365  fprintf(stderr, ") selects %s which has unmet direct dependencies (",
366  sym->name);
367  expr_fprint(sym->dir_dep.expr, stderr);
368  fprintf(stderr, ")\n");
369  expr_free(e);
370  }
371  newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri);
372  }
373  if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN)
374  newval.tri = yes;
375  break;
376  case S_STRING:
377  case S_HEX:
378  case S_INT:
379  if (sym->visible != no) {
380  sym->flags |= SYMBOL_WRITE;
381  if (sym_has_value(sym)) {
382  newval.val = sym->def[S_DEF_USER].val;
383  break;
384  }
385  }
386  prop = sym_get_default_prop(sym);
387  if (prop) {
388  struct symbol *ds = prop_get_symbol(prop);
389  if (ds) {
390  sym->flags |= SYMBOL_WRITE;
391  sym_calc_value(ds);
392  newval.val = ds->curr.val;
393  }
394  }
395  break;
396  default:
397  ;
398  }
399 
400  sym->curr = newval;
401  if (sym_is_choice(sym) && newval.tri == yes)
402  sym->curr.val = sym_calc_choice(sym);
403  sym_validate_range(sym);
404 
405  if (memcmp(&oldval, &sym->curr, sizeof(oldval))) {
406  sym_set_changed(sym);
407  if (modules_sym == sym) {
409  modules_val = modules_sym->curr.tri;
410  }
411  }
412 
413  if (sym_is_choice(sym)) {
414  struct symbol *choice_sym;
415 
416  prop = sym_get_choice_prop(sym);
417  expr_list_for_each_sym(prop->expr, e, choice_sym) {
418  if ((sym->flags & SYMBOL_WRITE) &&
419  choice_sym->visible != no)
420  choice_sym->flags |= SYMBOL_WRITE;
421  if (sym->flags & SYMBOL_CHANGED)
422  sym_set_changed(choice_sym);
423  }
424  }
425 
426  if (sym->flags & SYMBOL_AUTO)
427  sym->flags &= ~SYMBOL_WRITE;
428 }
429 
431 {
432  struct symbol *sym;
433  int i;
434 
435  for_all_symbols(i, sym)
436  sym->flags &= ~SYMBOL_VALID;
438  if (modules_sym)
439  sym_calc_value(modules_sym);
440 }
441 
442 void sym_set_changed(struct symbol *sym)
443 {
444  struct property *prop;
445 
446  sym->flags |= SYMBOL_CHANGED;
447  for (prop = sym->prop; prop; prop = prop->next) {
448  if (prop->menu)
449  prop->menu->flags |= MENU_CHANGED;
450  }
451 }
452 
454 {
455  struct symbol *sym;
456  int i;
457 
458  for_all_symbols(i, sym)
459  sym_set_changed(sym);
460 }
461 
463 {
464  int type = sym_get_type(sym);
465 
466  if (sym->visible == no)
467  return false;
468 
469  if (type != S_BOOLEAN && type != S_TRISTATE)
470  return false;
471 
472  if (type == S_BOOLEAN && val == mod)
473  return false;
474  if (sym->visible <= sym->rev_dep.tri)
475  return false;
476  if (sym_is_choice_value(sym) && sym->visible == yes)
477  return val == yes;
478  return val >= sym->rev_dep.tri && val <= sym->visible;
479 }
480 
481 bool sym_set_tristate_value(struct symbol *sym, tristate val)
482 {
483  tristate oldval = sym_get_tristate_value(sym);
484 
485  if (oldval != val && !sym_tristate_within_range(sym, val))
486  return false;
487 
488  if (!(sym->flags & SYMBOL_DEF_USER)) {
489  sym->flags |= SYMBOL_DEF_USER;
490  sym_set_changed(sym);
491  }
492  /*
493  * setting a choice value also resets the new flag of the choice
494  * symbol and all other choice values.
495  */
496  if (sym_is_choice_value(sym) && val == yes) {
498  struct property *prop;
499  struct expr *e;
500 
501  cs->def[S_DEF_USER].val = sym;
502  cs->flags |= SYMBOL_DEF_USER;
503  prop = sym_get_choice_prop(cs);
504  for (e = prop->expr; e; e = e->left.expr) {
505  if (e->right.sym->visible != no)
506  e->right.sym->flags |= SYMBOL_DEF_USER;
507  }
508  }
509 
510  sym->def[S_DEF_USER].tri = val;
511  if (oldval != val)
513 
514  return true;
515 }
516 
518 {
519  tristate oldval, newval;
520 
521  oldval = newval = sym_get_tristate_value(sym);
522  do {
523  switch (newval) {
524  case no:
525  newval = mod;
526  break;
527  case mod:
528  newval = yes;
529  break;
530  case yes:
531  newval = no;
532  break;
533  }
534  if (sym_set_tristate_value(sym, newval))
535  break;
536  } while (oldval != newval);
537  return newval;
538 }
539 
540 bool sym_string_valid(struct symbol *sym, const char *str)
541 {
542  signed char ch;
543 
544  switch (sym->type) {
545  case S_STRING:
546  return true;
547  case S_INT:
548  ch = *str++;
549  if (ch == '-')
550  ch = *str++;
551  if (!isdigit(ch))
552  return false;
553  if (ch == '0' && *str != 0)
554  return false;
555  while ((ch = *str++)) {
556  if (!isdigit(ch))
557  return false;
558  }
559  return true;
560  case S_HEX:
561  if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
562  str += 2;
563  ch = *str++;
564  do {
565  if (!isxdigit(ch))
566  return false;
567  } while ((ch = *str++));
568  return true;
569  case S_BOOLEAN:
570  case S_TRISTATE:
571  switch (str[0]) {
572  case 'y': case 'Y':
573  case 'm': case 'M':
574  case 'n': case 'N':
575  return true;
576  }
577  return false;
578  default:
579  return false;
580  }
581 }
582 
583 bool sym_string_within_range(struct symbol *sym, const char *str)
584 {
585  struct property *prop;
586  int val;
587 
588  switch (sym->type) {
589  case S_STRING:
590  return sym_string_valid(sym, str);
591  case S_INT:
592  if (!sym_string_valid(sym, str))
593  return false;
594  prop = sym_get_range_prop(sym);
595  if (!prop)
596  return true;
597  val = strtol(str, NULL, 10);
598  return val >= sym_get_range_val(prop->expr->left.sym, 10) &&
599  val <= sym_get_range_val(prop->expr->right.sym, 10);
600  case S_HEX:
601  if (!sym_string_valid(sym, str))
602  return false;
603  prop = sym_get_range_prop(sym);
604  if (!prop)
605  return true;
606  val = strtol(str, NULL, 16);
607  return val >= sym_get_range_val(prop->expr->left.sym, 16) &&
608  val <= sym_get_range_val(prop->expr->right.sym, 16);
609  case S_BOOLEAN:
610  case S_TRISTATE:
611  switch (str[0]) {
612  case 'y': case 'Y':
613  return sym_tristate_within_range(sym, yes);
614  case 'm': case 'M':
615  return sym_tristate_within_range(sym, mod);
616  case 'n': case 'N':
617  return sym_tristate_within_range(sym, no);
618  }
619  return false;
620  default:
621  return false;
622  }
623 }
624 
625 bool sym_set_string_value(struct symbol *sym, const char *newval)
626 {
627  const char *oldval;
628  char *val;
629  int size;
630 
631  switch (sym->type) {
632  case S_BOOLEAN:
633  case S_TRISTATE:
634  switch (newval[0]) {
635  case 'y': case 'Y':
636  return sym_set_tristate_value(sym, yes);
637  case 'm': case 'M':
638  return sym_set_tristate_value(sym, mod);
639  case 'n': case 'N':
640  return sym_set_tristate_value(sym, no);
641  }
642  return false;
643  default:
644  ;
645  }
646 
647  if (!sym_string_within_range(sym, newval))
648  return false;
649 
650  if (!(sym->flags & SYMBOL_DEF_USER)) {
651  sym->flags |= SYMBOL_DEF_USER;
652  sym_set_changed(sym);
653  }
654 
655  oldval = sym->def[S_DEF_USER].val;
656  size = strlen(newval) + 1;
657  if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) {
658  size += 2;
659  sym->def[S_DEF_USER].val = val = malloc(size);
660  *val++ = '0';
661  *val++ = 'x';
662  } else if (!oldval || strcmp(oldval, newval))
663  sym->def[S_DEF_USER].val = val = malloc(size);
664  else
665  return true;
666 
667  strcpy(val, newval);
668  free((void *)oldval);
670 
671  return true;
672 }
673 
674 /*
675  * Find the default value associated to a symbol.
676  * For tristate symbol handle the modules=n case
677  * in which case "m" becomes "y".
678  * If the symbol does not have any default then fallback
679  * to the fixed default values.
680  */
681 const char *sym_get_string_default(struct symbol *sym)
682 {
683  struct property *prop;
684  struct symbol *ds;
685  const char *str;
686  tristate val;
687 
688  sym_calc_visibility(sym);
689  sym_calc_value(modules_sym);
690  val = symbol_no.curr.tri;
691  str = symbol_empty.curr.val;
692 
693  /* If symbol has a default value look it up */
694  prop = sym_get_default_prop(sym);
695  if (prop != NULL) {
696  switch (sym->type) {
697  case S_BOOLEAN:
698  case S_TRISTATE:
699  /* The visibility may limit the value from yes => mod */
700  val = EXPR_AND(expr_calc_value(prop->expr), prop->visible.tri);
701  break;
702  default:
703  /*
704  * The following fails to handle the situation
705  * where a default value is further limited by
706  * the valid range.
707  */
708  ds = prop_get_symbol(prop);
709  if (ds != NULL) {
710  sym_calc_value(ds);
711  str = (const char *)ds->curr.val;
712  }
713  }
714  }
715 
716  /* Handle select statements */
717  val = EXPR_OR(val, sym->rev_dep.tri);
718 
719  /* transpose mod to yes if modules are not enabled */
720  if (val == mod)
721  if (!sym_is_choice_value(sym) && modules_sym->curr.tri == no)
722  val = yes;
723 
724  /* transpose mod to yes if type is bool */
725  if (sym->type == S_BOOLEAN && val == mod)
726  val = yes;
727 
728  switch (sym->type) {
729  case S_BOOLEAN:
730  case S_TRISTATE:
731  switch (val) {
732  case no: return "n";
733  case mod: return "m";
734  case yes: return "y";
735  }
736  case S_INT:
737  case S_HEX:
738  return str;
739  case S_STRING:
740  return str;
741  case S_OTHER:
742  case S_UNKNOWN:
743  break;
744  }
745  return "";
746 }
747 
748 const char *sym_get_string_value(struct symbol *sym)
749 {
750  tristate val;
751 
752  switch (sym->type) {
753  case S_BOOLEAN:
754  case S_TRISTATE:
755  val = sym_get_tristate_value(sym);
756  switch (val) {
757  case no:
758  return "n";
759  case mod:
760  sym_calc_value(modules_sym);
761  return (modules_sym->curr.tri == no) ? "n" : "m";
762  case yes:
763  return "y";
764  }
765  break;
766  default:
767  ;
768  }
769  return (const char *)sym->curr.val;
770 }
771 
772 bool sym_is_changable(struct symbol *sym)
773 {
774  return sym->visible > sym->rev_dep.tri;
775 }
776 
777 static unsigned strhash(const char *s)
778 {
779  /* fnv32 hash */
780  unsigned hash = 2166136261U;
781  for (; *s; s++)
782  hash = (hash ^ *s) * 0x01000193;
783  return hash;
784 }
785 
786 struct symbol *sym_lookup(const char *name, int flags)
787 {
788  struct symbol *symbol;
789  char *new_name;
790  int hash;
791 
792  if (name) {
793  if (name[0] && !name[1]) {
794  switch (name[0]) {
795  case 'y': return &symbol_yes;
796  case 'm': return &symbol_mod;
797  case 'n': return &symbol_no;
798  }
799  }
800  hash = strhash(name) % SYMBOL_HASHSIZE;
801 
802  for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
803  if (symbol->name &&
804  !strcmp(symbol->name, name) &&
805  (flags ? symbol->flags & flags
806  : !(symbol->flags & (SYMBOL_CONST|SYMBOL_CHOICE))))
807  return symbol;
808  }
809  new_name = strdup(name);
810  } else {
811  new_name = NULL;
812  hash = 0;
813  }
814 
815  symbol = malloc(sizeof(*symbol));
816  memset(symbol, 0, sizeof(*symbol));
817  symbol->name = new_name;
818  symbol->type = S_UNKNOWN;
819  symbol->flags |= flags;
820 
821  symbol->next = symbol_hash[hash];
822  symbol_hash[hash] = symbol;
823 
824  return symbol;
825 }
826 
827 struct symbol *sym_find(const char *name)
828 {
829  struct symbol *symbol = NULL;
830  int hash = 0;
831 
832  if (!name)
833  return NULL;
834 
835  if (name[0] && !name[1]) {
836  switch (name[0]) {
837  case 'y': return &symbol_yes;
838  case 'm': return &symbol_mod;
839  case 'n': return &symbol_no;
840  }
841  }
842  hash = strhash(name) % SYMBOL_HASHSIZE;
843 
844  for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
845  if (symbol->name &&
846  !strcmp(symbol->name, name) &&
847  !(symbol->flags & SYMBOL_CONST))
848  break;
849  }
850 
851  return symbol;
852 }
853 
854 /*
855  * Expand symbol's names embedded in the string given in argument. Symbols'
856  * name to be expanded shall be prefixed by a '$'. Unknown symbol expands to
857  * the empty string.
858  */
859 const char *sym_expand_string_value(const char *in)
860 {
861  const char *src;
862  char *res;
863  size_t reslen;
864 
865  reslen = strlen(in) + 1;
866  res = malloc(reslen);
867  res[0] = '\0';
868 
869  while ((src = strchr(in, '$'))) {
870  char *p, name[SYMBOL_MAXLENGTH];
871  const char *symval = "";
872  struct symbol *sym;
873  size_t newlen;
874 
875  strncat(res, in, src - in);
876  src++;
877 
878  p = name;
879  while (isalnum(*src) || *src == '_')
880  *p++ = *src++;
881  *p = '\0';
882 
883  sym = sym_find(name);
884  if (sym != NULL) {
885  sym_calc_value(sym);
886  symval = sym_get_string_value(sym);
887  }
888 
889  newlen = strlen(res) + strlen(symval) + strlen(src) + 1;
890  if (newlen > reslen) {
891  reslen = newlen;
892  res = realloc(res, reslen);
893  }
894 
895  strcat(res, symval);
896  in = src;
897  }
898  strcat(res, in);
899 
900  return res;
901 }
902 
903 const char *sym_escape_string_value(const char *in)
904 {
905  const char *p;
906  size_t reslen;
907  char *res;
908  size_t l;
909 
910  reslen = strlen(in) + strlen("\"\"") + 1;
911 
912  p = in;
913  for (;;) {
914  l = strcspn(p, "\"\\");
915  p += l;
916 
917  if (p[0] == '\0')
918  break;
919 
920  reslen++;
921  p++;
922  }
923 
924  res = malloc(reslen);
925  res[0] = '\0';
926 
927  strcat(res, "\"");
928 
929  p = in;
930  for (;;) {
931  l = strcspn(p, "\"\\");
932  strncat(res, p, l);
933  p += l;
934 
935  if (p[0] == '\0')
936  break;
937 
938  strcat(res, "\\");
939  strncat(res, p++, 1);
940  }
941 
942  strcat(res, "\"");
943  return res;
944 }
945 
946 struct symbol **sym_re_search(const char *pattern)
947 {
948  struct symbol *sym, **sym_arr = NULL;
949  int i, cnt, size;
950  regex_t re;
951 
952  cnt = size = 0;
953  /* Skip if empty */
954  if (strlen(pattern) == 0)
955  return NULL;
956  if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB|REG_ICASE))
957  return NULL;
958 
959  for_all_symbols(i, sym) {
960  if (sym->flags & SYMBOL_CONST || !sym->name)
961  continue;
962  if (regexec(&re, sym->name, 0, NULL, 0))
963  continue;
964  if (cnt + 1 >= size) {
965  void *tmp = sym_arr;
966  size += 16;
967  sym_arr = realloc(sym_arr, size * sizeof(struct symbol *));
968  if (!sym_arr) {
969  free(tmp);
970  return NULL;
971  }
972  }
973  sym_calc_value(sym);
974  sym_arr[cnt++] = sym;
975  }
976  if (sym_arr)
977  sym_arr[cnt] = NULL;
978  regfree(&re);
979 
980  return sym_arr;
981 }
982 
983 /*
984  * When we check for recursive dependencies we use a stack to save
985  * current state so we can print out relevant info to user.
986  * The entries are located on the call stack so no need to free memory.
987  * Note inser() remove() must always match to properly clear the stack.
988  */
989 static struct dep_stack {
990  struct dep_stack *prev, *next;
991  struct symbol *sym;
992  struct property *prop;
993  struct expr *expr;
994 } *check_top;
995 
996 static void dep_stack_insert(struct dep_stack *stack, struct symbol *sym)
997 {
998  memset(stack, 0, sizeof(*stack));
999  if (check_top)
1000  check_top->next = stack;
1001  stack->prev = check_top;
1002  stack->sym = sym;
1003  check_top = stack;
1004 }
1005 
1006 static void dep_stack_remove(void)
1007 {
1008  check_top = check_top->prev;
1009  if (check_top)
1010  check_top->next = NULL;
1011 }
1012 
1013 /*
1014  * Called when we have detected a recursive dependency.
1015  * check_top point to the top of the stact so we use
1016  * the ->prev pointer to locate the bottom of the stack.
1017  */
1018 static void sym_check_print_recursive(struct symbol *last_sym)
1019 {
1020  struct dep_stack *stack;
1021  struct symbol *sym, *next_sym;
1022  struct menu *menu = NULL;
1023  struct property *prop;
1024  struct dep_stack cv_stack;
1025 
1026  if (sym_is_choice_value(last_sym)) {
1027  dep_stack_insert(&cv_stack, last_sym);
1028  last_sym = prop_get_symbol(sym_get_choice_prop(last_sym));
1029  }
1030 
1031  for (stack = check_top; stack != NULL; stack = stack->prev)
1032  if (stack->sym == last_sym)
1033  break;
1034  if (!stack) {
1035  fprintf(stderr, "unexpected recursive dependency error\n");
1036  return;
1037  }
1038 
1039  for (; stack; stack = stack->next) {
1040  sym = stack->sym;
1041  next_sym = stack->next ? stack->next->sym : last_sym;
1042  prop = stack->prop;
1043  if (prop == NULL)
1044  prop = stack->sym->prop;
1045 
1046  /* for choice values find the menu entry (used below) */
1047  if (sym_is_choice(sym) || sym_is_choice_value(sym)) {
1048  for (prop = sym->prop; prop; prop = prop->next) {
1049  menu = prop->menu;
1050  if (prop->menu)
1051  break;
1052  }
1053  }
1054  if (stack->sym == last_sym)
1055  fprintf(stderr, "%s:%d:error: recursive dependency detected!\n",
1056  prop->file->name, prop->lineno);
1057  if (stack->expr) {
1058  fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n",
1059  prop->file->name, prop->lineno,
1060  sym->name ? sym->name : "<choice>",
1061  prop_get_type_name(prop->type),
1062  next_sym->name ? next_sym->name : "<choice>");
1063  } else if (stack->prop) {
1064  fprintf(stderr, "%s:%d:\tsymbol %s depends on %s\n",
1065  prop->file->name, prop->lineno,
1066  sym->name ? sym->name : "<choice>",
1067  next_sym->name ? next_sym->name : "<choice>");
1068  } else if (sym_is_choice(sym)) {
1069  fprintf(stderr, "%s:%d:\tchoice %s contains symbol %s\n",
1070  menu->file->name, menu->lineno,
1071  sym->name ? sym->name : "<choice>",
1072  next_sym->name ? next_sym->name : "<choice>");
1073  } else if (sym_is_choice_value(sym)) {
1074  fprintf(stderr, "%s:%d:\tsymbol %s is part of choice %s\n",
1075  menu->file->name, menu->lineno,
1076  sym->name ? sym->name : "<choice>",
1077  next_sym->name ? next_sym->name : "<choice>");
1078  } else {
1079  fprintf(stderr, "%s:%d:\tsymbol %s is selected by %s\n",
1080  prop->file->name, prop->lineno,
1081  sym->name ? sym->name : "<choice>",
1082  next_sym->name ? next_sym->name : "<choice>");
1083  }
1084  }
1085 
1086  if (check_top == &cv_stack)
1087  dep_stack_remove();
1088 }
1089 
1090 static struct symbol *sym_check_expr_deps(struct expr *e)
1091 {
1092  struct symbol *sym;
1093 
1094  if (!e)
1095  return NULL;
1096  switch (e->type) {
1097  case E_OR:
1098  case E_AND:
1099  sym = sym_check_expr_deps(e->left.expr);
1100  if (sym)
1101  return sym;
1102  return sym_check_expr_deps(e->right.expr);
1103  case E_NOT:
1104  return sym_check_expr_deps(e->left.expr);
1105  case E_EQUAL:
1106  case E_UNEQUAL:
1107  sym = sym_check_deps(e->left.sym);
1108  if (sym)
1109  return sym;
1110  return sym_check_deps(e->right.sym);
1111  case E_SYMBOL:
1112  return sym_check_deps(e->left.sym);
1113  default:
1114  break;
1115  }
1116  printf("Oops! How to check %d?\n", e->type);
1117  return NULL;
1118 }
1119 
1120 /* return NULL when dependencies are OK */
1121 static struct symbol *sym_check_sym_deps(struct symbol *sym)
1122 {
1123  struct symbol *sym2;
1124  struct property *prop;
1125  struct dep_stack stack;
1126 
1127  dep_stack_insert(&stack, sym);
1128 
1129  sym2 = sym_check_expr_deps(sym->rev_dep.expr);
1130  if (sym2)
1131  goto out;
1132 
1133  for (prop = sym->prop; prop; prop = prop->next) {
1134  if (prop->type == P_CHOICE || prop->type == P_SELECT)
1135  continue;
1136  stack.prop = prop;
1137  sym2 = sym_check_expr_deps(prop->visible.expr);
1138  if (sym2)
1139  break;
1140  if (prop->type != P_DEFAULT || sym_is_choice(sym))
1141  continue;
1142  stack.expr = prop->expr;
1143  sym2 = sym_check_expr_deps(prop->expr);
1144  if (sym2)
1145  break;
1146  stack.expr = NULL;
1147  }
1148 
1149 out:
1150  dep_stack_remove();
1151 
1152  return sym2;
1153 }
1154 
1155 static struct symbol *sym_check_choice_deps(struct symbol *choice)
1156 {
1157  struct symbol *sym, *sym2;
1158  struct property *prop;
1159  struct expr *e;
1160  struct dep_stack stack;
1161 
1162  dep_stack_insert(&stack, choice);
1163 
1164  prop = sym_get_choice_prop(choice);
1165  expr_list_for_each_sym(prop->expr, e, sym)
1166  sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
1167 
1168  choice->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
1169  sym2 = sym_check_sym_deps(choice);
1170  choice->flags &= ~SYMBOL_CHECK;
1171  if (sym2)
1172  goto out;
1173 
1174  expr_list_for_each_sym(prop->expr, e, sym) {
1175  sym2 = sym_check_sym_deps(sym);
1176  if (sym2)
1177  break;
1178  }
1179 out:
1180  expr_list_for_each_sym(prop->expr, e, sym)
1181  sym->flags &= ~SYMBOL_CHECK;
1182 
1183  if (sym2 && sym_is_choice_value(sym2) &&
1184  prop_get_symbol(sym_get_choice_prop(sym2)) == choice)
1185  sym2 = choice;
1186 
1187  dep_stack_remove();
1188 
1189  return sym2;
1190 }
1191 
1193 {
1194  struct symbol *sym2;
1195  struct property *prop;
1196 
1197  if (sym->flags & SYMBOL_CHECK) {
1198  sym_check_print_recursive(sym);
1199  return sym;
1200  }
1201  if (sym->flags & SYMBOL_CHECKED)
1202  return NULL;
1203 
1204  if (sym_is_choice_value(sym)) {
1205  struct dep_stack stack;
1206 
1207  /* for choice groups start the check with main choice symbol */
1208  dep_stack_insert(&stack, sym);
1209  prop = sym_get_choice_prop(sym);
1210  sym2 = sym_check_deps(prop_get_symbol(prop));
1211  dep_stack_remove();
1212  } else if (sym_is_choice(sym)) {
1213  sym2 = sym_check_choice_deps(sym);
1214  } else {
1215  sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
1216  sym2 = sym_check_sym_deps(sym);
1217  sym->flags &= ~SYMBOL_CHECK;
1218  }
1219 
1220  if (sym2 && sym2 == sym)
1221  sym2 = NULL;
1222 
1223  return sym2;
1224 }
1225 
1226 struct property *prop_alloc(enum prop_type type, struct symbol *sym)
1227 {
1228  struct property *prop;
1229  struct property **propp;
1230 
1231  prop = malloc(sizeof(*prop));
1232  memset(prop, 0, sizeof(*prop));
1233  prop->type = type;
1234  prop->sym = sym;
1235  prop->file = current_file;
1236  prop->lineno = zconf_lineno();
1237 
1238  /* append property to the prop list of symbol */
1239  if (sym) {
1240  for (propp = &sym->prop; *propp; propp = &(*propp)->next)
1241  ;
1242  *propp = prop;
1243  }
1244 
1245  return prop;
1246 }
1247 
1248 struct symbol *prop_get_symbol(struct property *prop)
1249 {
1250  if (prop->expr && (prop->expr->type == E_SYMBOL ||
1251  prop->expr->type == E_LIST))
1252  return prop->expr->left.sym;
1253  return NULL;
1254 }
1255 
1257 {
1258  switch (type) {
1259  case P_PROMPT:
1260  return "prompt";
1261  case P_ENV:
1262  return "env";
1263  case P_COMMENT:
1264  return "comment";
1265  case P_MENU:
1266  return "menu";
1267  case P_DEFAULT:
1268  return "default";
1269  case P_CHOICE:
1270  return "choice";
1271  case P_SELECT:
1272  return "select";
1273  case P_RANGE:
1274  return "range";
1275  case P_SYMBOL:
1276  return "symbol";
1277  case P_UNKNOWN:
1278  break;
1279  }
1280  return "unknown";
1281 }
1282 
1283 static void prop_add_env(const char *env)
1284 {
1285  struct symbol *sym, *sym2;
1286  struct property *prop;
1287  char *p;
1288 
1289  sym = current_entry->sym;
1290  sym->flags |= SYMBOL_AUTO;
1291  for_all_properties(sym, prop, P_ENV) {
1292  sym2 = prop_get_symbol(prop);
1293  if (strcmp(sym2->name, env))
1294  menu_warn(current_entry, "redefining environment symbol from %s",
1295  sym2->name);
1296  return;
1297  }
1298 
1299  prop = prop_alloc(P_ENV, sym);
1301 
1302  sym_env_list = expr_alloc_one(E_LIST, sym_env_list);
1303  sym_env_list->right.sym = sym;
1304 
1305  p = getenv(env);
1306  if (p)
1307  sym_add_default(sym, p);
1308  else
1309  menu_warn(current_entry, "environment variable %s undefined", env);
1310 }