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 <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, 26 }, symbol_empty = { 27 .name = "", 28 .curr = { "", no }, 29 .flags = SYMBOL_VALID, 30 }; 31 32 struct symbol *sym_defconfig_list; 33 struct symbol *modules_sym; 34 tristate modules_val; 35 36 struct expr *sym_env_list; 37 38 static void sym_add_default(struct symbol *sym, const char *def) 39 { 40 struct property *prop = prop_alloc(P_DEFAULT, sym); 41 42 prop->expr = expr_alloc_symbol(sym_lookup(def, SYMBOL_CONST)); 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 97 struct property *sym_get_choice_prop(struct symbol *sym) 98 { 99 struct property *prop; 100 101 for_all_choices(sym, prop) 102 return prop; 103 return NULL; 104 } 105 106 struct property *sym_get_env_prop(struct symbol *sym) 107 { 108 struct property *prop; 109 110 for_all_properties(sym, prop, P_ENV) 111 return prop; 112 return NULL; 113 } 114 115 struct property *sym_get_default_prop(struct symbol *sym) 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 266 /* first calculate all choice values' visibilities */ 267 prop = sym_get_choice_prop(sym); 268 expr_list_for_each_sym(prop->expr, e, def_sym) 269 sym_calc_visibility(def_sym); 270 271 /* is the user choice visible? */ 272 def_sym = sym->def[S_DEF_USER].val; 273 if (def_sym && def_sym->visible != no) 274 return def_sym; 275 276 def_sym = sym_choice_default(sym); 277 278 if (def_sym == NULL) 279 /* no choice? reset tristate value */ 280 sym->curr.tri = no; 281 282 return def_sym; 283 } 284 285 void sym_calc_value(struct symbol *sym) 286 { 287 struct symbol_value newval, oldval; 288 struct property *prop; 289 struct expr *e; 290 291 if (!sym) 292 return; 293 294 if (sym->flags & SYMBOL_VALID) 295 return; 296 sym->flags |= SYMBOL_VALID; 297 298 oldval = sym->curr; 299 300 switch (sym->type) { 301 case S_INT: 302 case S_HEX: 303 case S_STRING: 304 newval = symbol_empty.curr; 305 break; 306 case S_BOOLEAN: 307 case S_TRISTATE: 308 newval = symbol_no.curr; 309 break; 310 default: 311 sym->curr.val = sym->name; 312 sym->curr.tri = no; 313 return; 314 } 315 if (!sym_is_choice_value(sym)) 316 sym->flags &= ~SYMBOL_WRITE; 317 318 sym_calc_visibility(sym); 319 320 /* set default if recursively called */ 321 sym->curr = newval; 322 323 switch (sym_get_type(sym)) { 324 case S_BOOLEAN: 325 case S_TRISTATE: 326 if (sym_is_choice_value(sym) && sym->visible == yes) { 327 prop = sym_get_choice_prop(sym); 328 newval.tri = (prop_get_symbol(prop)->curr.val == sym) ? yes : no; 329 } else { 330 if (sym->visible != no) { 331 /* if the symbol is visible use the user value 332 * if available, otherwise try the default value 333 */ 334 sym->flags |= SYMBOL_WRITE; 335 if (sym_has_value(sym)) { 336 newval.tri = EXPR_AND(sym->def[S_DEF_USER].tri, 337 sym->visible); 338 goto calc_newval; 339 } 340 } 341 if (sym->rev_dep.tri != no) 342 sym->flags |= SYMBOL_WRITE; 343 if (!sym_is_choice(sym)) { 344 prop = sym_get_default_prop(sym); 345 if (prop) { 346 sym->flags |= SYMBOL_WRITE; 347 newval.tri = EXPR_AND(expr_calc_value(prop->expr), 348 prop->visible.tri); 349 } 350 } 351 calc_newval: 352 if (sym->dir_dep.tri == no && sym->rev_dep.tri != no) { 353 struct expr *e; 354 e = expr_simplify_unmet_dep(sym->rev_dep.expr, 355 sym->dir_dep.expr); 356 fprintf(stderr, "warning: ("); 357 expr_fprint(e, stderr); 358 fprintf(stderr, ") selects %s which has unmet direct dependencies (", 359 sym->name); 360 expr_fprint(sym->dir_dep.expr, stderr); 361 fprintf(stderr, ")\n"); 362 expr_free(e); 363 } 364 newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri); 365 } 366 if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN) 367 newval.tri = yes; 368 break; 369 case S_STRING: 370 case S_HEX: 371 case S_INT: 372 if (sym->visible != no) { 373 sym->flags |= SYMBOL_WRITE; 374 if (sym_has_value(sym)) { 375 newval.val = sym->def[S_DEF_USER].val; 376 break; 377 } 378 } 379 prop = sym_get_default_prop(sym); 380 if (prop) { 381 struct symbol *ds = prop_get_symbol(prop); 382 if (ds) { 383 sym->flags |= SYMBOL_WRITE; 384 sym_calc_value(ds); 385 newval.val = ds->curr.val; 386 } 387 } 388 break; 389 default: 390 ; 391 } 392 393 sym->curr = newval; 394 if (sym_is_choice(sym) && newval.tri == yes) 395 sym->curr.val = sym_calc_choice(sym); 396 sym_validate_range(sym); 397 398 if (memcmp(&oldval, &sym->curr, sizeof(oldval))) { 399 sym_set_changed(sym); 400 if (modules_sym == sym) { 401 sym_set_all_changed(); 402 modules_val = modules_sym->curr.tri; 403 } 404 } 405 406 if (sym_is_choice(sym)) { 407 struct symbol *choice_sym; 408 409 prop = sym_get_choice_prop(sym); 410 expr_list_for_each_sym(prop->expr, e, choice_sym) { 411 if ((sym->flags & SYMBOL_WRITE) && 412 choice_sym->visible != no) 413 choice_sym->flags |= SYMBOL_WRITE; 414 if (sym->flags & SYMBOL_CHANGED) 415 sym_set_changed(choice_sym); 416 } 417 } 418 419 if (sym->flags & SYMBOL_AUTO) 420 sym->flags &= ~SYMBOL_WRITE; 421 } 422 423 void sym_clear_all_valid(void) 424 { 425 struct symbol *sym; 426 int i; 427 428 for_all_symbols(i, sym) 429 sym->flags &= ~SYMBOL_VALID; 430 sym_add_change_count(1); 431 if (modules_sym) 432 sym_calc_value(modules_sym); 433 } 434 435 void sym_set_changed(struct symbol *sym) 436 { 437 struct property *prop; 438 439 sym->flags |= SYMBOL_CHANGED; 440 for (prop = sym->prop; prop; prop = prop->next) { 441 if (prop->menu) 442 prop->menu->flags |= MENU_CHANGED; 443 } 444 } 445 446 void sym_set_all_changed(void) 447 { 448 struct symbol *sym; 449 int i; 450 451 for_all_symbols(i, sym) 452 sym_set_changed(sym); 453 } 454 455 bool sym_tristate_within_range(struct symbol *sym, tristate val) 456 { 457 int type = sym_get_type(sym); 458 459 if (sym->visible == no) 460 return false; 461 462 if (type != S_BOOLEAN && type != S_TRISTATE) 463 return false; 464 465 if (type == S_BOOLEAN && val == mod) 466 return false; 467 if (sym->visible <= sym->rev_dep.tri) 468 return false; 469 if (sym_is_choice_value(sym) && sym->visible == yes) 470 return val == yes; 471 return val >= sym->rev_dep.tri && val <= sym->visible; 472 } 473 474 bool sym_set_tristate_value(struct symbol *sym, tristate val) 475 { 476 tristate oldval = sym_get_tristate_value(sym); 477 478 if (oldval != val && !sym_tristate_within_range(sym, val)) 479 return false; 480 481 if (!(sym->flags & SYMBOL_DEF_USER)) { 482 sym->flags |= SYMBOL_DEF_USER; 483 sym_set_changed(sym); 484 } 485 /* 486 * setting a choice value also resets the new flag of the choice 487 * symbol and all other choice values. 488 */ 489 if (sym_is_choice_value(sym) && val == yes) { 490 struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); 491 struct property *prop; 492 struct expr *e; 493 494 cs->def[S_DEF_USER].val = sym; 495 cs->flags |= SYMBOL_DEF_USER; 496 prop = sym_get_choice_prop(cs); 497 for (e = prop->expr; e; e = e->left.expr) { 498 if (e->right.sym->visible != no) 499 e->right.sym->flags |= SYMBOL_DEF_USER; 500 } 501 } 502 503 sym->def[S_DEF_USER].tri = val; 504 if (oldval != val) 505 sym_clear_all_valid(); 506 507 return true; 508 } 509 510 tristate sym_toggle_tristate_value(struct symbol *sym) 511 { 512 tristate oldval, newval; 513 514 oldval = newval = sym_get_tristate_value(sym); 515 do { 516 switch (newval) { 517 case no: 518 newval = mod; 519 break; 520 case mod: 521 newval = yes; 522 break; 523 case yes: 524 newval = no; 525 break; 526 } 527 if (sym_set_tristate_value(sym, newval)) 528 break; 529 } while (oldval != newval); 530 return newval; 531 } 532 533 bool sym_string_valid(struct symbol *sym, const char *str) 534 { 535 signed char ch; 536 537 switch (sym->type) { 538 case S_STRING: 539 return true; 540 case S_INT: 541 ch = *str++; 542 if (ch == '-') 543 ch = *str++; 544 if (!isdigit(ch)) 545 return false; 546 if (ch == '0' && *str != 0) 547 return false; 548 while ((ch = *str++)) { 549 if (!isdigit(ch)) 550 return false; 551 } 552 return true; 553 case S_HEX: 554 if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) 555 str += 2; 556 ch = *str++; 557 do { 558 if (!isxdigit(ch)) 559 return false; 560 } while ((ch = *str++)); 561 return true; 562 case S_BOOLEAN: 563 case S_TRISTATE: 564 switch (str[0]) { 565 case 'y': case 'Y': 566 case 'm': case 'M': 567 case 'n': case 'N': 568 return true; 569 } 570 return false; 571 default: 572 return false; 573 } 574 } 575 576 bool sym_string_within_range(struct symbol *sym, const char *str) 577 { 578 struct property *prop; 579 int val; 580 581 switch (sym->type) { 582 case S_STRING: 583 return sym_string_valid(sym, str); 584 case S_INT: 585 if (!sym_string_valid(sym, str)) 586 return false; 587 prop = sym_get_range_prop(sym); 588 if (!prop) 589 return true; 590 val = strtol(str, NULL, 10); 591 return val >= sym_get_range_val(prop->expr->left.sym, 10) && 592 val <= sym_get_range_val(prop->expr->right.sym, 10); 593 case S_HEX: 594 if (!sym_string_valid(sym, str)) 595 return false; 596 prop = sym_get_range_prop(sym); 597 if (!prop) 598 return true; 599 val = strtol(str, NULL, 16); 600 return val >= sym_get_range_val(prop->expr->left.sym, 16) && 601 val <= sym_get_range_val(prop->expr->right.sym, 16); 602 case S_BOOLEAN: 603 case S_TRISTATE: 604 switch (str[0]) { 605 case 'y': case 'Y': 606 return sym_tristate_within_range(sym, yes); 607 case 'm': case 'M': 608 return sym_tristate_within_range(sym, mod); 609 case 'n': case 'N': 610 return sym_tristate_within_range(sym, no); 611 } 612 return false; 613 default: 614 return false; 615 } 616 } 617 618 bool sym_set_string_value(struct symbol *sym, const char *newval) 619 { 620 const char *oldval; 621 char *val; 622 int size; 623 624 switch (sym->type) { 625 case S_BOOLEAN: 626 case S_TRISTATE: 627 switch (newval[0]) { 628 case 'y': case 'Y': 629 return sym_set_tristate_value(sym, yes); 630 case 'm': case 'M': 631 return sym_set_tristate_value(sym, mod); 632 case 'n': case 'N': 633 return sym_set_tristate_value(sym, no); 634 } 635 return false; 636 default: 637 ; 638 } 639 640 if (!sym_string_within_range(sym, newval)) 641 return false; 642 643 if (!(sym->flags & SYMBOL_DEF_USER)) { 644 sym->flags |= SYMBOL_DEF_USER; 645 sym_set_changed(sym); 646 } 647 648 oldval = sym->def[S_DEF_USER].val; 649 size = strlen(newval) + 1; 650 if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) { 651 size += 2; 652 sym->def[S_DEF_USER].val = val = malloc(size); 653 *val++ = '0'; 654 *val++ = 'x'; 655 } else if (!oldval || strcmp(oldval, newval)) 656 sym->def[S_DEF_USER].val = val = malloc(size); 657 else 658 return true; 659 660 strcpy(val, newval); 661 free((void *)oldval); 662 sym_clear_all_valid(); 663 664 return true; 665 } 666 667 /* 668 * Find the default value associated to a symbol. 669 * For tristate symbol handle the modules=n case 670 * in which case "m" becomes "y". 671 * If the symbol does not have any default then fallback 672 * to the fixed default values. 673 */ 674 const char *sym_get_string_default(struct symbol *sym) 675 { 676 struct property *prop; 677 struct symbol *ds; 678 const char *str; 679 tristate val; 680 681 sym_calc_visibility(sym); 682 sym_calc_value(modules_sym); 683 val = symbol_no.curr.tri; 684 str = symbol_empty.curr.val; 685 686 /* If symbol has a default value look it up */ 687 prop = sym_get_default_prop(sym); 688 if (prop != NULL) { 689 switch (sym->type) { 690 case S_BOOLEAN: 691 case S_TRISTATE: 692 /* The visibility may limit the value from yes => mod */ 693 val = EXPR_AND(expr_calc_value(prop->expr), prop->visible.tri); 694 break; 695 default: 696 /* 697 * The following fails to handle the situation 698 * where a default value is further limited by 699 * the valid range. 700 */ 701 ds = prop_get_symbol(prop); 702 if (ds != NULL) { 703 sym_calc_value(ds); 704 str = (const char *)ds->curr.val; 705 } 706 } 707 } 708 709 /* Handle select statements */ 710 val = EXPR_OR(val, sym->rev_dep.tri); 711 712 /* transpose mod to yes if modules are not enabled */ 713 if (val == mod) 714 if (!sym_is_choice_value(sym) && modules_sym->curr.tri == no) 715 val = yes; 716 717 /* transpose mod to yes if type is bool */ 718 if (sym->type == S_BOOLEAN && val == mod) 719 val = yes; 720 721 switch (sym->type) { 722 case S_BOOLEAN: 723 case S_TRISTATE: 724 switch (val) { 725 case no: return "n"; 726 case mod: return "m"; 727 case yes: return "y"; 728 } 729 case S_INT: 730 case S_HEX: 731 return str; 732 case S_STRING: 733 return str; 734 case S_OTHER: 735 case S_UNKNOWN: 736 break; 737 } 738 return ""; 739 } 740 741 const char *sym_get_string_value(struct symbol *sym) 742 { 743 tristate val; 744 745 switch (sym->type) { 746 case S_BOOLEAN: 747 case S_TRISTATE: 748 val = sym_get_tristate_value(sym); 749 switch (val) { 750 case no: 751 return "n"; 752 case mod: 753 return "m"; 754 case yes: 755 return "y"; 756 } 757 break; 758 default: 759 ; 760 } 761 return (const char *)sym->curr.val; 762 } 763 764 bool sym_is_changable(struct symbol *sym) 765 { 766 return sym->visible > sym->rev_dep.tri; 767 } 768 769 static unsigned strhash(const char *s) 770 { 771 /* fnv32 hash */ 772 unsigned hash = 2166136261U; 773 for (; *s; s++) 774 hash = (hash ^ *s) * 0x01000193; 775 return hash; 776 } 777 778 struct symbol *sym_lookup(const char *name, int flags) 779 { 780 struct symbol *symbol; 781 char *new_name; 782 int hash; 783 784 if (name) { 785 if (name[0] && !name[1]) { 786 switch (name[0]) { 787 case 'y': return &symbol_yes; 788 case 'm': return &symbol_mod; 789 case 'n': return &symbol_no; 790 } 791 } 792 hash = strhash(name) % SYMBOL_HASHSIZE; 793 794 for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) { 795 if (symbol->name && 796 !strcmp(symbol->name, name) && 797 (flags ? symbol->flags & flags 798 : !(symbol->flags & (SYMBOL_CONST|SYMBOL_CHOICE)))) 799 return symbol; 800 } 801 new_name = strdup(name); 802 } else { 803 new_name = NULL; 804 hash = 0; 805 } 806 807 symbol = malloc(sizeof(*symbol)); 808 memset(symbol, 0, sizeof(*symbol)); 809 symbol->name = new_name; 810 symbol->type = S_UNKNOWN; 811 symbol->flags |= flags; 812 813 symbol->next = symbol_hash[hash]; 814 symbol_hash[hash] = symbol; 815 816 return symbol; 817 } 818 819 struct symbol *sym_find(const char *name) 820 { 821 struct symbol *symbol = NULL; 822 int hash = 0; 823 824 if (!name) 825 return NULL; 826 827 if (name[0] && !name[1]) { 828 switch (name[0]) { 829 case 'y': return &symbol_yes; 830 case 'm': return &symbol_mod; 831 case 'n': return &symbol_no; 832 } 833 } 834 hash = strhash(name) % SYMBOL_HASHSIZE; 835 836 for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) { 837 if (symbol->name && 838 !strcmp(symbol->name, name) && 839 !(symbol->flags & SYMBOL_CONST)) 840 break; 841 } 842 843 return symbol; 844 } 845 846 /* 847 * Expand symbol's names embedded in the string given in argument. Symbols' 848 * name to be expanded shall be prefixed by a '$'. Unknown symbol expands to 849 * the empty string. 850 */ 851 const char *sym_expand_string_value(const char *in) 852 { 853 const char *src; 854 char *res; 855 size_t reslen; 856 857 reslen = strlen(in) + 1; 858 res = malloc(reslen); 859 res[0] = '\0'; 860 861 while ((src = strchr(in, '$'))) { 862 char *p, name[SYMBOL_MAXLENGTH]; 863 const char *symval = ""; 864 struct symbol *sym; 865 size_t newlen; 866 867 strncat(res, in, src - in); 868 src++; 869 870 p = name; 871 while (isalnum(*src) || *src == '_') 872 *p++ = *src++; 873 *p = '\0'; 874 875 sym = sym_find(name); 876 if (sym != NULL) { 877 sym_calc_value(sym); 878 symval = sym_get_string_value(sym); 879 } 880 881 newlen = strlen(res) + strlen(symval) + strlen(src) + 1; 882 if (newlen > reslen) { 883 reslen = newlen; 884 res = realloc(res, reslen); 885 } 886 887 strcat(res, symval); 888 in = src; 889 } 890 strcat(res, in); 891 892 return res; 893 } 894 895 struct symbol **sym_re_search(const char *pattern) 896 { 897 struct symbol *sym, **sym_arr = NULL; 898 int i, cnt, size; 899 regex_t re; 900 901 cnt = size = 0; 902 /* Skip if empty */ 903 if (strlen(pattern) == 0) 904 return NULL; 905 if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB|REG_ICASE)) 906 return NULL; 907 908 for_all_symbols(i, sym) { 909 if (sym->flags & SYMBOL_CONST || !sym->name) 910 continue; 911 if (regexec(&re, sym->name, 0, NULL, 0)) 912 continue; 913 if (cnt + 1 >= size) { 914 void *tmp = sym_arr; 915 size += 16; 916 sym_arr = realloc(sym_arr, size * sizeof(struct symbol *)); 917 if (!sym_arr) { 918 free(tmp); 919 return NULL; 920 } 921 } 922 sym_calc_value(sym); 923 sym_arr[cnt++] = sym; 924 } 925 if (sym_arr) 926 sym_arr[cnt] = NULL; 927 regfree(&re); 928 929 return sym_arr; 930 } 931 932 /* 933 * When we check for recursive dependencies we use a stack to save 934 * current state so we can print out relevant info to user. 935 * The entries are located on the call stack so no need to free memory. 936 * Note inser() remove() must always match to properly clear the stack. 937 */ 938 static struct dep_stack { 939 struct dep_stack *prev, *next; 940 struct symbol *sym; 941 struct property *prop; 942 struct expr *expr; 943 } *check_top; 944 945 static void dep_stack_insert(struct dep_stack *stack, struct symbol *sym) 946 { 947 memset(stack, 0, sizeof(*stack)); 948 if (check_top) 949 check_top->next = stack; 950 stack->prev = check_top; 951 stack->sym = sym; 952 check_top = stack; 953 } 954 955 static void dep_stack_remove(void) 956 { 957 check_top = check_top->prev; 958 if (check_top) 959 check_top->next = NULL; 960 } 961 962 /* 963 * Called when we have detected a recursive dependency. 964 * check_top point to the top of the stact so we use 965 * the ->prev pointer to locate the bottom of the stack. 966 */ 967 static void sym_check_print_recursive(struct symbol *last_sym) 968 { 969 struct dep_stack *stack; 970 struct symbol *sym, *next_sym; 971 struct menu *menu = NULL; 972 struct property *prop; 973 struct dep_stack cv_stack; 974 975 if (sym_is_choice_value(last_sym)) { 976 dep_stack_insert(&cv_stack, last_sym); 977 last_sym = prop_get_symbol(sym_get_choice_prop(last_sym)); 978 } 979 980 for (stack = check_top; stack != NULL; stack = stack->prev) 981 if (stack->sym == last_sym) 982 break; 983 if (!stack) { 984 fprintf(stderr, "unexpected recursive dependency error\n"); 985 return; 986 } 987 988 for (; stack; stack = stack->next) { 989 sym = stack->sym; 990 next_sym = stack->next ? stack->next->sym : last_sym; 991 prop = stack->prop; 992 if (prop == NULL) 993 prop = stack->sym->prop; 994 995 /* for choice values find the menu entry (used below) */ 996 if (sym_is_choice(sym) || sym_is_choice_value(sym)) { 997 for (prop = sym->prop; prop; prop = prop->next) { 998 menu = prop->menu; 999 if (prop->menu) 1000 break; 1001 } 1002 } 1003 if (stack->sym == last_sym) 1004 fprintf(stderr, "%s:%d:error: recursive dependency detected!\n", 1005 prop->file->name, prop->lineno); 1006 if (stack->expr) { 1007 fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n", 1008 prop->file->name, prop->lineno, 1009 sym->name ? sym->name : "<choice>", 1010 prop_get_type_name(prop->type), 1011 next_sym->name ? next_sym->name : "<choice>"); 1012 } else if (stack->prop) { 1013 fprintf(stderr, "%s:%d:\tsymbol %s depends on %s\n", 1014 prop->file->name, prop->lineno, 1015 sym->name ? sym->name : "<choice>", 1016 next_sym->name ? next_sym->name : "<choice>"); 1017 } else if (sym_is_choice(sym)) { 1018 fprintf(stderr, "%s:%d:\tchoice %s contains symbol %s\n", 1019 menu->file->name, menu->lineno, 1020 sym->name ? sym->name : "<choice>", 1021 next_sym->name ? next_sym->name : "<choice>"); 1022 } else if (sym_is_choice_value(sym)) { 1023 fprintf(stderr, "%s:%d:\tsymbol %s is part of choice %s\n", 1024 menu->file->name, menu->lineno, 1025 sym->name ? sym->name : "<choice>", 1026 next_sym->name ? next_sym->name : "<choice>"); 1027 } else { 1028 fprintf(stderr, "%s:%d:\tsymbol %s is selected by %s\n", 1029 prop->file->name, prop->lineno, 1030 sym->name ? sym->name : "<choice>", 1031 next_sym->name ? next_sym->name : "<choice>"); 1032 } 1033 } 1034 1035 if (check_top == &cv_stack) 1036 dep_stack_remove(); 1037 } 1038 1039 static struct symbol *sym_check_expr_deps(struct expr *e) 1040 { 1041 struct symbol *sym; 1042 1043 if (!e) 1044 return NULL; 1045 switch (e->type) { 1046 case E_OR: 1047 case E_AND: 1048 sym = sym_check_expr_deps(e->left.expr); 1049 if (sym) 1050 return sym; 1051 return sym_check_expr_deps(e->right.expr); 1052 case E_NOT: 1053 return sym_check_expr_deps(e->left.expr); 1054 case E_EQUAL: 1055 case E_UNEQUAL: 1056 sym = sym_check_deps(e->left.sym); 1057 if (sym) 1058 return sym; 1059 return sym_check_deps(e->right.sym); 1060 case E_SYMBOL: 1061 return sym_check_deps(e->left.sym); 1062 default: 1063 break; 1064 } 1065 printf("Oops! How to check %d?\n", e->type); 1066 return NULL; 1067 } 1068 1069 /* return NULL when dependencies are OK */ 1070 static struct symbol *sym_check_sym_deps(struct symbol *sym) 1071 { 1072 struct symbol *sym2; 1073 struct property *prop; 1074 struct dep_stack stack; 1075 1076 dep_stack_insert(&stack, sym); 1077 1078 sym2 = sym_check_expr_deps(sym->rev_dep.expr); 1079 if (sym2) 1080 goto out; 1081 1082 for (prop = sym->prop; prop; prop = prop->next) { 1083 if (prop->type == P_CHOICE || prop->type == P_SELECT) 1084 continue; 1085 stack.prop = prop; 1086 sym2 = sym_check_expr_deps(prop->visible.expr); 1087 if (sym2) 1088 break; 1089 if (prop->type != P_DEFAULT || sym_is_choice(sym)) 1090 continue; 1091 stack.expr = prop->expr; 1092 sym2 = sym_check_expr_deps(prop->expr); 1093 if (sym2) 1094 break; 1095 stack.expr = NULL; 1096 } 1097 1098 out: 1099 dep_stack_remove(); 1100 1101 return sym2; 1102 } 1103 1104 static struct symbol *sym_check_choice_deps(struct symbol *choice) 1105 { 1106 struct symbol *sym, *sym2; 1107 struct property *prop; 1108 struct expr *e; 1109 struct dep_stack stack; 1110 1111 dep_stack_insert(&stack, choice); 1112 1113 prop = sym_get_choice_prop(choice); 1114 expr_list_for_each_sym(prop->expr, e, sym) 1115 sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED); 1116 1117 choice->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED); 1118 sym2 = sym_check_sym_deps(choice); 1119 choice->flags &= ~SYMBOL_CHECK; 1120 if (sym2) 1121 goto out; 1122 1123 expr_list_for_each_sym(prop->expr, e, sym) { 1124 sym2 = sym_check_sym_deps(sym); 1125 if (sym2) 1126 break; 1127 } 1128 out: 1129 expr_list_for_each_sym(prop->expr, e, sym) 1130 sym->flags &= ~SYMBOL_CHECK; 1131 1132 if (sym2 && sym_is_choice_value(sym2) && 1133 prop_get_symbol(sym_get_choice_prop(sym2)) == choice) 1134 sym2 = choice; 1135 1136 dep_stack_remove(); 1137 1138 return sym2; 1139 } 1140 1141 struct symbol *sym_check_deps(struct symbol *sym) 1142 { 1143 struct symbol *sym2; 1144 struct property *prop; 1145 1146 if (sym->flags & SYMBOL_CHECK) { 1147 sym_check_print_recursive(sym); 1148 return sym; 1149 } 1150 if (sym->flags & SYMBOL_CHECKED) 1151 return NULL; 1152 1153 if (sym_is_choice_value(sym)) { 1154 struct dep_stack stack; 1155 1156 /* for choice groups start the check with main choice symbol */ 1157 dep_stack_insert(&stack, sym); 1158 prop = sym_get_choice_prop(sym); 1159 sym2 = sym_check_deps(prop_get_symbol(prop)); 1160 dep_stack_remove(); 1161 } else if (sym_is_choice(sym)) { 1162 sym2 = sym_check_choice_deps(sym); 1163 } else { 1164 sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED); 1165 sym2 = sym_check_sym_deps(sym); 1166 sym->flags &= ~SYMBOL_CHECK; 1167 } 1168 1169 if (sym2 && sym2 == sym) 1170 sym2 = NULL; 1171 1172 return sym2; 1173 } 1174 1175 struct property *prop_alloc(enum prop_type type, struct symbol *sym) 1176 { 1177 struct property *prop; 1178 struct property **propp; 1179 1180 prop = malloc(sizeof(*prop)); 1181 memset(prop, 0, sizeof(*prop)); 1182 prop->type = type; 1183 prop->sym = sym; 1184 prop->file = current_file; 1185 prop->lineno = zconf_lineno(); 1186 1187 /* append property to the prop list of symbol */ 1188 if (sym) { 1189 for (propp = &sym->prop; *propp; propp = &(*propp)->next) 1190 ; 1191 *propp = prop; 1192 } 1193 1194 return prop; 1195 } 1196 1197 struct symbol *prop_get_symbol(struct property *prop) 1198 { 1199 if (prop->expr && (prop->expr->type == E_SYMBOL || 1200 prop->expr->type == E_LIST)) 1201 return prop->expr->left.sym; 1202 return NULL; 1203 } 1204 1205 const char *prop_get_type_name(enum prop_type type) 1206 { 1207 switch (type) { 1208 case P_PROMPT: 1209 return "prompt"; 1210 case P_ENV: 1211 return "env"; 1212 case P_COMMENT: 1213 return "comment"; 1214 case P_MENU: 1215 return "menu"; 1216 case P_DEFAULT: 1217 return "default"; 1218 case P_CHOICE: 1219 return "choice"; 1220 case P_SELECT: 1221 return "select"; 1222 case P_RANGE: 1223 return "range"; 1224 case P_SYMBOL: 1225 return "symbol"; 1226 case P_UNKNOWN: 1227 break; 1228 } 1229 return "unknown"; 1230 } 1231 1232 static void prop_add_env(const char *env) 1233 { 1234 struct symbol *sym, *sym2; 1235 struct property *prop; 1236 char *p; 1237 1238 sym = current_entry->sym; 1239 sym->flags |= SYMBOL_AUTO; 1240 for_all_properties(sym, prop, P_ENV) { 1241 sym2 = prop_get_symbol(prop); 1242 if (strcmp(sym2->name, env)) 1243 menu_warn(current_entry, "redefining environment symbol from %s", 1244 sym2->name); 1245 return; 1246 } 1247 1248 prop = prop_alloc(P_ENV, sym); 1249 prop->expr = expr_alloc_symbol(sym_lookup(env, SYMBOL_CONST)); 1250 1251 sym_env_list = expr_alloc_one(E_LIST, sym_env_list); 1252 sym_env_list->right.sym = sym; 1253 1254 p = getenv(env); 1255 if (p) 1256 sym_add_default(sym, p); 1257 else 1258 menu_warn(current_entry, "environment variable %s undefined", env); 1259 } 1260