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 <sys/stat.h> 7 #include <ctype.h> 8 #include <fcntl.h> 9 #include <stdio.h> 10 #include <stdlib.h> 11 #include <string.h> 12 #include <time.h> 13 #include <unistd.h> 14 15 #define LKC_DIRECT_LINK 16 #include "lkc.h" 17 18 static void conf_warning(const char *fmt, ...) 19 __attribute__ ((format (printf, 1, 2))); 20 21 static const char *conf_filename; 22 static int conf_lineno, conf_warnings, conf_unsaved; 23 24 const char conf_defname[] = "arch/$ARCH/defconfig"; 25 26 static void conf_warning(const char *fmt, ...) 27 { 28 va_list ap; 29 va_start(ap, fmt); 30 fprintf(stderr, "%s:%d:warning: ", conf_filename, conf_lineno); 31 vfprintf(stderr, fmt, ap); 32 fprintf(stderr, "\n"); 33 va_end(ap); 34 conf_warnings++; 35 } 36 37 const char *conf_get_configname(void) 38 { 39 char *name = getenv("KCONFIG_CONFIG"); 40 41 return name ? name : ".config"; 42 } 43 44 static char *conf_expand_value(const char *in) 45 { 46 struct symbol *sym; 47 const char *src; 48 static char res_value[SYMBOL_MAXLENGTH]; 49 char *dst, name[SYMBOL_MAXLENGTH]; 50 51 res_value[0] = 0; 52 dst = name; 53 while ((src = strchr(in, '$'))) { 54 strncat(res_value, in, src - in); 55 src++; 56 dst = name; 57 while (isalnum(*src) || *src == '_') 58 *dst++ = *src++; 59 *dst = 0; 60 sym = sym_lookup(name, 0); 61 sym_calc_value(sym); 62 strcat(res_value, sym_get_string_value(sym)); 63 in = src; 64 } 65 strcat(res_value, in); 66 67 return res_value; 68 } 69 70 char *conf_get_default_confname(void) 71 { 72 struct stat buf; 73 static char fullname[PATH_MAX+1]; 74 char *env, *name; 75 76 name = conf_expand_value(conf_defname); 77 env = getenv(SRCTREE); 78 if (env) { 79 sprintf(fullname, "%s/%s", env, name); 80 if (!stat(fullname, &buf)) 81 return fullname; 82 } 83 return name; 84 } 85 86 static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p) 87 { 88 char *p2; 89 90 switch (sym->type) { 91 case S_TRISTATE: 92 if (p[0] == 'm') { 93 sym->def[def].tri = mod; 94 sym->flags |= def_flags; 95 break; 96 } 97 case S_BOOLEAN: 98 if (p[0] == 'y') { 99 sym->def[def].tri = yes; 100 sym->flags |= def_flags; 101 break; 102 } 103 if (p[0] == 'n') { 104 sym->def[def].tri = no; 105 sym->flags |= def_flags; 106 break; 107 } 108 conf_warning("symbol value '%s' invalid for %s", p, sym->name); 109 break; 110 case S_OTHER: 111 if (*p != '"') { 112 for (p2 = p; *p2 && !isspace(*p2); p2++) 113 ; 114 sym->type = S_STRING; 115 goto done; 116 } 117 case S_STRING: 118 if (*p++ != '"') 119 break; 120 for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) { 121 if (*p2 == '"') { 122 *p2 = 0; 123 break; 124 } 125 memmove(p2, p2 + 1, strlen(p2)); 126 } 127 if (!p2) { 128 conf_warning("invalid string found"); 129 return 1; 130 } 131 case S_INT: 132 case S_HEX: 133 done: 134 if (sym_string_valid(sym, p)) { 135 sym->def[def].val = strdup(p); 136 sym->flags |= def_flags; 137 } else { 138 conf_warning("symbol value '%s' invalid for %s", p, sym->name); 139 return 1; 140 } 141 break; 142 default: 143 ; 144 } 145 return 0; 146 } 147 148 int conf_read_simple(const char *name, int def) 149 { 150 FILE *in = NULL; 151 char line[1024]; 152 char *p, *p2; 153 struct symbol *sym; 154 int i, def_flags; 155 156 if (name) { 157 in = zconf_fopen(name); 158 } else { 159 struct property *prop; 160 161 name = conf_get_configname(); 162 in = zconf_fopen(name); 163 if (in) 164 goto load; 165 sym_add_change_count(1); 166 if (!sym_defconfig_list) 167 return 1; 168 169 for_all_defaults(sym_defconfig_list, prop) { 170 if (expr_calc_value(prop->visible.expr) == no || 171 prop->expr->type != E_SYMBOL) 172 continue; 173 name = conf_expand_value(prop->expr->left.sym->name); 174 in = zconf_fopen(name); 175 if (in) { 176 printf(_("#\n" 177 "# using defaults found in %s\n" 178 "#\n"), name); 179 goto load; 180 } 181 } 182 } 183 if (!in) 184 return 1; 185 186 load: 187 conf_filename = name; 188 conf_lineno = 0; 189 conf_warnings = 0; 190 conf_unsaved = 0; 191 192 def_flags = SYMBOL_DEF << def; 193 for_all_symbols(i, sym) { 194 sym->flags |= SYMBOL_CHANGED; 195 sym->flags &= ~(def_flags|SYMBOL_VALID); 196 if (sym_is_choice(sym)) 197 sym->flags |= def_flags; 198 switch (sym->type) { 199 case S_INT: 200 case S_HEX: 201 case S_STRING: 202 if (sym->def[def].val) 203 free(sym->def[def].val); 204 default: 205 sym->def[def].val = NULL; 206 sym->def[def].tri = no; 207 } 208 } 209 210 while (fgets(line, sizeof(line), in)) { 211 conf_lineno++; 212 sym = NULL; 213 switch (line[0]) { 214 case '#': 215 if (memcmp(line + 2, "CONFIG_", 7)) 216 continue; 217 p = strchr(line + 9, ' '); 218 if (!p) 219 continue; 220 *p++ = 0; 221 if (strncmp(p, "is not set", 10)) 222 continue; 223 if (def == S_DEF_USER) { 224 sym = sym_find(line + 9); 225 if (!sym) 226 break; 227 } else { 228 sym = sym_lookup(line + 9, 0); 229 if (sym->type == S_UNKNOWN) 230 sym->type = S_BOOLEAN; 231 } 232 if (sym->flags & def_flags) { 233 conf_warning("override: reassigning to symbol %s", sym->name); 234 } 235 switch (sym->type) { 236 case S_BOOLEAN: 237 case S_TRISTATE: 238 sym->def[def].tri = no; 239 sym->flags |= def_flags; 240 break; 241 default: 242 ; 243 } 244 break; 245 case 'C': 246 if (memcmp(line, "CONFIG_", 7)) { 247 conf_warning("unexpected data"); 248 continue; 249 } 250 p = strchr(line + 7, '='); 251 if (!p) 252 continue; 253 *p++ = 0; 254 p2 = strchr(p, '\n'); 255 if (p2) { 256 *p2-- = 0; 257 if (*p2 == '\r') 258 *p2 = 0; 259 } 260 if (def == S_DEF_USER) { 261 sym = sym_find(line + 7); 262 if (!sym) 263 break; 264 } else { 265 sym = sym_lookup(line + 7, 0); 266 if (sym->type == S_UNKNOWN) 267 sym->type = S_OTHER; 268 } 269 if (sym->flags & def_flags) { 270 conf_warning("override: reassigning to symbol %s", sym->name); 271 } 272 if (conf_set_sym_val(sym, def, def_flags, p)) 273 continue; 274 break; 275 case '\r': 276 case '\n': 277 break; 278 default: 279 conf_warning("unexpected data"); 280 continue; 281 } 282 if (sym && sym_is_choice_value(sym)) { 283 struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); 284 switch (sym->def[def].tri) { 285 case no: 286 break; 287 case mod: 288 if (cs->def[def].tri == yes) { 289 conf_warning("%s creates inconsistent choice state", sym->name); 290 cs->flags &= ~def_flags; 291 } 292 break; 293 case yes: 294 if (cs->def[def].tri != no) 295 conf_warning("override: %s changes choice state", sym->name); 296 cs->def[def].val = sym; 297 break; 298 } 299 cs->def[def].tri = EXPR_OR(cs->def[def].tri, sym->def[def].tri); 300 } 301 } 302 fclose(in); 303 304 if (modules_sym) 305 sym_calc_value(modules_sym); 306 return 0; 307 } 308 309 int conf_read(const char *name) 310 { 311 struct symbol *sym, *choice_sym; 312 struct property *prop; 313 struct expr *e; 314 int i, flags; 315 316 sym_set_change_count(0); 317 318 if (conf_read_simple(name, S_DEF_USER)) 319 return 1; 320 321 for_all_symbols(i, sym) { 322 sym_calc_value(sym); 323 if (sym_is_choice(sym) || (sym->flags & SYMBOL_AUTO)) 324 goto sym_ok; 325 if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) { 326 /* check that calculated value agrees with saved value */ 327 switch (sym->type) { 328 case S_BOOLEAN: 329 case S_TRISTATE: 330 if (sym->def[S_DEF_USER].tri != sym_get_tristate_value(sym)) 331 break; 332 if (!sym_is_choice(sym)) 333 goto sym_ok; 334 default: 335 if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val)) 336 goto sym_ok; 337 break; 338 } 339 } else if (!sym_has_value(sym) && !(sym->flags & SYMBOL_WRITE)) 340 /* no previous value and not saved */ 341 goto sym_ok; 342 conf_unsaved++; 343 /* maybe print value in verbose mode... */ 344 sym_ok: 345 if (!sym_is_choice(sym)) 346 continue; 347 /* The choice symbol only has a set value (and thus is not new) 348 * if all its visible childs have values. 349 */ 350 prop = sym_get_choice_prop(sym); 351 flags = sym->flags; 352 expr_list_for_each_sym(prop->expr, e, choice_sym) 353 if (choice_sym->visible != no) 354 flags &= choice_sym->flags; 355 sym->flags &= flags | ~SYMBOL_DEF_USER; 356 } 357 358 for_all_symbols(i, sym) { 359 if (sym_has_value(sym) && !sym_is_choice_value(sym)) { 360 /* Reset values of generates values, so they'll appear 361 * as new, if they should become visible, but that 362 * doesn't quite work if the Kconfig and the saved 363 * configuration disagree. 364 */ 365 if (sym->visible == no && !conf_unsaved) 366 sym->flags &= ~SYMBOL_DEF_USER; 367 switch (sym->type) { 368 case S_STRING: 369 case S_INT: 370 case S_HEX: 371 /* Reset a string value if it's out of range */ 372 if (sym_string_within_range(sym, sym->def[S_DEF_USER].val)) 373 break; 374 sym->flags &= ~(SYMBOL_VALID|SYMBOL_DEF_USER); 375 conf_unsaved++; 376 break; 377 default: 378 break; 379 } 380 } 381 } 382 383 sym_add_change_count(conf_warnings || conf_unsaved); 384 385 return 0; 386 } 387 388 int conf_write(const char *name) 389 { 390 FILE *out; 391 struct symbol *sym; 392 struct menu *menu; 393 const char *basename; 394 char dirname[128], tmpname[128], newname[128]; 395 int type, l; 396 const char *str; 397 time_t now; 398 int use_timestamp = 1; 399 char *env; 400 401 dirname[0] = 0; 402 if (name && name[0]) { 403 struct stat st; 404 char *slash; 405 406 if (!stat(name, &st) && S_ISDIR(st.st_mode)) { 407 strcpy(dirname, name); 408 strcat(dirname, "/"); 409 basename = conf_get_configname(); 410 } else if ((slash = strrchr(name, '/'))) { 411 int size = slash - name + 1; 412 memcpy(dirname, name, size); 413 dirname[size] = 0; 414 if (slash[1]) 415 basename = slash + 1; 416 else 417 basename = conf_get_configname(); 418 } else 419 basename = name; 420 } else 421 basename = conf_get_configname(); 422 423 sprintf(newname, "%s%s", dirname, basename); 424 env = getenv("KCONFIG_OVERWRITECONFIG"); 425 if (!env || !*env) { 426 sprintf(tmpname, "%s.tmpconfig.%d", dirname, (int)getpid()); 427 out = fopen(tmpname, "w"); 428 } else { 429 *tmpname = 0; 430 out = fopen(newname, "w"); 431 } 432 if (!out) 433 return 1; 434 435 sym = sym_lookup("KERNELVERSION", 0); 436 sym_calc_value(sym); 437 time(&now); 438 env = getenv("KCONFIG_NOTIMESTAMP"); 439 if (env && *env) 440 use_timestamp = 0; 441 442 fprintf(out, _("#\n" 443 "# Automatically generated make config: don't edit\n" 444 "# Linux kernel version: %s\n" 445 "%s%s" 446 "#\n"), 447 sym_get_string_value(sym), 448 use_timestamp ? "# " : "", 449 use_timestamp ? ctime(&now) : ""); 450 451 if (!conf_get_changed()) 452 sym_clear_all_valid(); 453 454 menu = rootmenu.list; 455 while (menu) { 456 sym = menu->sym; 457 if (!sym) { 458 if (!menu_is_visible(menu)) 459 goto next; 460 str = menu_get_prompt(menu); 461 fprintf(out, "\n" 462 "#\n" 463 "# %s\n" 464 "#\n", str); 465 } else if (!(sym->flags & SYMBOL_CHOICE)) { 466 sym_calc_value(sym); 467 if (!(sym->flags & SYMBOL_WRITE)) 468 goto next; 469 sym->flags &= ~SYMBOL_WRITE; 470 type = sym->type; 471 if (type == S_TRISTATE) { 472 sym_calc_value(modules_sym); 473 if (modules_sym->curr.tri == no) 474 type = S_BOOLEAN; 475 } 476 switch (type) { 477 case S_BOOLEAN: 478 case S_TRISTATE: 479 switch (sym_get_tristate_value(sym)) { 480 case no: 481 fprintf(out, "# CONFIG_%s is not set\n", sym->name); 482 break; 483 case mod: 484 fprintf(out, "CONFIG_%s=m\n", sym->name); 485 break; 486 case yes: 487 fprintf(out, "CONFIG_%s=y\n", sym->name); 488 break; 489 } 490 break; 491 case S_STRING: 492 str = sym_get_string_value(sym); 493 fprintf(out, "CONFIG_%s=\"", sym->name); 494 while (1) { 495 l = strcspn(str, "\"\\"); 496 if (l) { 497 fwrite(str, l, 1, out); 498 str += l; 499 } 500 if (!*str) 501 break; 502 fprintf(out, "\\%c", *str++); 503 } 504 fputs("\"\n", out); 505 break; 506 case S_HEX: 507 str = sym_get_string_value(sym); 508 if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) { 509 fprintf(out, "CONFIG_%s=%s\n", sym->name, str); 510 break; 511 } 512 case S_INT: 513 str = sym_get_string_value(sym); 514 fprintf(out, "CONFIG_%s=%s\n", sym->name, str); 515 break; 516 } 517 } 518 519 next: 520 if (menu->list) { 521 menu = menu->list; 522 continue; 523 } 524 if (menu->next) 525 menu = menu->next; 526 else while ((menu = menu->parent)) { 527 if (menu->next) { 528 menu = menu->next; 529 break; 530 } 531 } 532 } 533 fclose(out); 534 535 if (*tmpname) { 536 strcat(dirname, basename); 537 strcat(dirname, ".old"); 538 rename(newname, dirname); 539 if (rename(tmpname, newname)) 540 return 1; 541 } 542 543 printf(_("#\n" 544 "# configuration written to %s\n" 545 "#\n"), newname); 546 547 sym_set_change_count(0); 548 549 return 0; 550 } 551 552 int conf_split_config(void) 553 { 554 char *name, path[128]; 555 char *s, *d, c; 556 struct symbol *sym; 557 struct stat sb; 558 int res, i, fd; 559 560 name = getenv("KCONFIG_AUTOCONFIG"); 561 if (!name) 562 name = "include/config/auto.conf"; 563 conf_read_simple(name, S_DEF_AUTO); 564 565 if (chdir("include/config")) 566 return 1; 567 568 res = 0; 569 for_all_symbols(i, sym) { 570 sym_calc_value(sym); 571 if ((sym->flags & SYMBOL_AUTO) || !sym->name) 572 continue; 573 if (sym->flags & SYMBOL_WRITE) { 574 if (sym->flags & SYMBOL_DEF_AUTO) { 575 /* 576 * symbol has old and new value, 577 * so compare them... 578 */ 579 switch (sym->type) { 580 case S_BOOLEAN: 581 case S_TRISTATE: 582 if (sym_get_tristate_value(sym) == 583 sym->def[S_DEF_AUTO].tri) 584 continue; 585 break; 586 case S_STRING: 587 case S_HEX: 588 case S_INT: 589 if (!strcmp(sym_get_string_value(sym), 590 sym->def[S_DEF_AUTO].val)) 591 continue; 592 break; 593 default: 594 break; 595 } 596 } else { 597 /* 598 * If there is no old value, only 'no' (unset) 599 * is allowed as new value. 600 */ 601 switch (sym->type) { 602 case S_BOOLEAN: 603 case S_TRISTATE: 604 if (sym_get_tristate_value(sym) == no) 605 continue; 606 break; 607 default: 608 break; 609 } 610 } 611 } else if (!(sym->flags & SYMBOL_DEF_AUTO)) 612 /* There is neither an old nor a new value. */ 613 continue; 614 /* else 615 * There is an old value, but no new value ('no' (unset) 616 * isn't saved in auto.conf, so the old value is always 617 * different from 'no'). 618 */ 619 620 /* Replace all '_' and append ".h" */ 621 s = sym->name; 622 d = path; 623 while ((c = *s++)) { 624 c = tolower(c); 625 *d++ = (c == '_') ? '/' : c; 626 } 627 strcpy(d, ".h"); 628 629 /* Assume directory path already exists. */ 630 fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644); 631 if (fd == -1) { 632 if (errno != ENOENT) { 633 res = 1; 634 break; 635 } 636 /* 637 * Create directory components, 638 * unless they exist already. 639 */ 640 d = path; 641 while ((d = strchr(d, '/'))) { 642 *d = 0; 643 if (stat(path, &sb) && mkdir(path, 0755)) { 644 res = 1; 645 goto out; 646 } 647 *d++ = '/'; 648 } 649 /* Try it again. */ 650 fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644); 651 if (fd == -1) { 652 res = 1; 653 break; 654 } 655 } 656 close(fd); 657 } 658 out: 659 if (chdir("../..")) 660 return 1; 661 662 return res; 663 } 664 665 int conf_write_autoconf(void) 666 { 667 struct symbol *sym; 668 const char *str; 669 char *name; 670 FILE *out, *out_h; 671 time_t now; 672 int i, l; 673 674 sym_clear_all_valid(); 675 676 file_write_dep("include/config/auto.conf.cmd"); 677 678 if (conf_split_config()) 679 return 1; 680 681 out = fopen(".tmpconfig", "w"); 682 if (!out) 683 return 1; 684 685 out_h = fopen(".tmpconfig.h", "w"); 686 if (!out_h) { 687 fclose(out); 688 return 1; 689 } 690 691 sym = sym_lookup("KERNELVERSION", 0); 692 sym_calc_value(sym); 693 time(&now); 694 fprintf(out, "#\n" 695 "# Automatically generated make config: don't edit\n" 696 "# Linux kernel version: %s\n" 697 "# %s" 698 "#\n", 699 sym_get_string_value(sym), ctime(&now)); 700 fprintf(out_h, "/*\n" 701 " * Automatically generated C config: don't edit\n" 702 " * Linux kernel version: %s\n" 703 " * %s" 704 " */\n" 705 "#define AUTOCONF_INCLUDED\n", 706 sym_get_string_value(sym), ctime(&now)); 707 708 for_all_symbols(i, sym) { 709 sym_calc_value(sym); 710 if (!(sym->flags & SYMBOL_WRITE) || !sym->name) 711 continue; 712 switch (sym->type) { 713 case S_BOOLEAN: 714 case S_TRISTATE: 715 switch (sym_get_tristate_value(sym)) { 716 case no: 717 break; 718 case mod: 719 fprintf(out, "CONFIG_%s=m\n", sym->name); 720 fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name); 721 break; 722 case yes: 723 fprintf(out, "CONFIG_%s=y\n", sym->name); 724 fprintf(out_h, "#define CONFIG_%s 1\n", sym->name); 725 break; 726 } 727 break; 728 case S_STRING: 729 str = sym_get_string_value(sym); 730 fprintf(out, "CONFIG_%s=\"", sym->name); 731 fprintf(out_h, "#define CONFIG_%s \"", sym->name); 732 while (1) { 733 l = strcspn(str, "\"\\"); 734 if (l) { 735 fwrite(str, l, 1, out); 736 fwrite(str, l, 1, out_h); 737 str += l; 738 } 739 if (!*str) 740 break; 741 fprintf(out, "\\%c", *str); 742 fprintf(out_h, "\\%c", *str); 743 str++; 744 } 745 fputs("\"\n", out); 746 fputs("\"\n", out_h); 747 break; 748 case S_HEX: 749 str = sym_get_string_value(sym); 750 if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) { 751 fprintf(out, "CONFIG_%s=%s\n", sym->name, str); 752 fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str); 753 break; 754 } 755 case S_INT: 756 str = sym_get_string_value(sym); 757 fprintf(out, "CONFIG_%s=%s\n", sym->name, str); 758 fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str); 759 break; 760 default: 761 break; 762 } 763 } 764 fclose(out); 765 fclose(out_h); 766 767 name = getenv("KCONFIG_AUTOHEADER"); 768 if (!name) 769 name = "include/linux/autoconf.h"; 770 if (rename(".tmpconfig.h", name)) 771 return 1; 772 name = getenv("KCONFIG_AUTOCONFIG"); 773 if (!name) 774 name = "include/config/auto.conf"; 775 /* 776 * This must be the last step, kbuild has a dependency on auto.conf 777 * and this marks the successful completion of the previous steps. 778 */ 779 if (rename(".tmpconfig", name)) 780 return 1; 781 782 return 0; 783 } 784 785 static int sym_change_count; 786 static void (*conf_changed_callback)(void); 787 788 void sym_set_change_count(int count) 789 { 790 int _sym_change_count = sym_change_count; 791 sym_change_count = count; 792 if (conf_changed_callback && 793 (bool)_sym_change_count != (bool)count) 794 conf_changed_callback(); 795 } 796 797 void sym_add_change_count(int count) 798 { 799 sym_set_change_count(count + sym_change_count); 800 } 801 802 bool conf_get_changed(void) 803 { 804 return sym_change_count; 805 } 806 807 void conf_set_changed_callback(void (*fn)(void)) 808 { 809 conf_changed_callback = fn; 810 } 811 812 813 void conf_set_all_new_symbols(enum conf_def_mode mode) 814 { 815 struct symbol *sym, *csym; 816 struct property *prop; 817 struct expr *e; 818 int i, cnt, def; 819 820 for_all_symbols(i, sym) { 821 if (sym_has_value(sym)) 822 continue; 823 switch (sym_get_type(sym)) { 824 case S_BOOLEAN: 825 case S_TRISTATE: 826 switch (mode) { 827 case def_yes: 828 sym->def[S_DEF_USER].tri = yes; 829 break; 830 case def_mod: 831 sym->def[S_DEF_USER].tri = mod; 832 break; 833 case def_no: 834 sym->def[S_DEF_USER].tri = no; 835 break; 836 case def_random: 837 sym->def[S_DEF_USER].tri = (tristate)(rand() % 3); 838 break; 839 default: 840 continue; 841 } 842 if (!sym_is_choice(sym) || mode != def_random) 843 sym->flags |= SYMBOL_DEF_USER; 844 break; 845 default: 846 break; 847 } 848 849 } 850 851 if (modules_sym) 852 sym_calc_value(modules_sym); 853 854 if (mode != def_random) 855 return; 856 857 for_all_symbols(i, csym) { 858 if (sym_has_value(csym) || !sym_is_choice(csym)) 859 continue; 860 861 sym_calc_value(csym); 862 prop = sym_get_choice_prop(csym); 863 def = -1; 864 while (1) { 865 cnt = 0; 866 expr_list_for_each_sym(prop->expr, e, sym) { 867 if (sym->visible == no) 868 continue; 869 if (def == cnt++) { 870 csym->def[S_DEF_USER].val = sym; 871 break; 872 } 873 } 874 if (def >= 0 || cnt < 2) 875 break; 876 def = (rand() % cnt) + 1; 877 } 878 csym->flags |= SYMBOL_DEF_USER; 879 } 880 } 881