1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> 4 */ 5 6 #include <sys/mman.h> 7 #include <sys/stat.h> 8 #include <sys/types.h> 9 #include <ctype.h> 10 #include <errno.h> 11 #include <fcntl.h> 12 #include <limits.h> 13 #include <stdarg.h> 14 #include <stdbool.h> 15 #include <stdio.h> 16 #include <stdlib.h> 17 #include <string.h> 18 #include <time.h> 19 #include <unistd.h> 20 21 #include "internal.h" 22 #include "lkc.h" 23 24 struct gstr autoconf_cmd; 25 26 /* return true if 'path' exists, false otherwise */ 27 static bool is_present(const char *path) 28 { 29 struct stat st; 30 31 return !stat(path, &st); 32 } 33 34 /* return true if 'path' exists and it is a directory, false otherwise */ 35 static bool is_dir(const char *path) 36 { 37 struct stat st; 38 39 if (stat(path, &st)) 40 return false; 41 42 return S_ISDIR(st.st_mode); 43 } 44 45 /* return true if the given two files are the same, false otherwise */ 46 static bool is_same(const char *file1, const char *file2) 47 { 48 int fd1, fd2; 49 struct stat st1, st2; 50 void *map1, *map2; 51 bool ret = false; 52 53 fd1 = open(file1, O_RDONLY); 54 if (fd1 < 0) 55 return ret; 56 57 fd2 = open(file2, O_RDONLY); 58 if (fd2 < 0) 59 goto close1; 60 61 ret = fstat(fd1, &st1); 62 if (ret) 63 goto close2; 64 ret = fstat(fd2, &st2); 65 if (ret) 66 goto close2; 67 68 if (st1.st_size != st2.st_size) 69 goto close2; 70 71 map1 = mmap(NULL, st1.st_size, PROT_READ, MAP_PRIVATE, fd1, 0); 72 if (map1 == MAP_FAILED) 73 goto close2; 74 75 map2 = mmap(NULL, st2.st_size, PROT_READ, MAP_PRIVATE, fd2, 0); 76 if (map2 == MAP_FAILED) 77 goto close2; 78 79 if (bcmp(map1, map2, st1.st_size)) 80 goto close2; 81 82 ret = true; 83 close2: 84 close(fd2); 85 close1: 86 close(fd1); 87 88 return ret; 89 } 90 91 /* 92 * Create the parent directory of the given path. 93 * 94 * For example, if 'include/config/auto.conf' is given, create 'include/config'. 95 */ 96 static int make_parent_dir(const char *path) 97 { 98 char tmp[PATH_MAX + 1]; 99 char *p; 100 101 strncpy(tmp, path, sizeof(tmp)); 102 tmp[sizeof(tmp) - 1] = 0; 103 104 /* Remove the base name. Just return if nothing is left */ 105 p = strrchr(tmp, '/'); 106 if (!p) 107 return 0; 108 *(p + 1) = 0; 109 110 /* Just in case it is an absolute path */ 111 p = tmp; 112 while (*p == '/') 113 p++; 114 115 while ((p = strchr(p, '/'))) { 116 *p = 0; 117 118 /* skip if the directory exists */ 119 if (!is_dir(tmp) && mkdir(tmp, 0755)) 120 return -1; 121 122 *p = '/'; 123 while (*p == '/') 124 p++; 125 } 126 127 return 0; 128 } 129 130 static char depfile_path[PATH_MAX]; 131 static size_t depfile_prefix_len; 132 133 /* touch depfile for symbol 'name' */ 134 static int conf_touch_dep(const char *name) 135 { 136 int fd; 137 138 /* check overflow: prefix + name + '\0' must fit in buffer. */ 139 if (depfile_prefix_len + strlen(name) + 1 > sizeof(depfile_path)) 140 return -1; 141 142 strcpy(depfile_path + depfile_prefix_len, name); 143 144 fd = open(depfile_path, O_WRONLY | O_CREAT | O_TRUNC, 0644); 145 if (fd == -1) 146 return -1; 147 close(fd); 148 149 return 0; 150 } 151 152 static void conf_warning(const char *fmt, ...) 153 __attribute__ ((format (printf, 1, 2))); 154 155 static void conf_message(const char *fmt, ...) 156 __attribute__ ((format (printf, 1, 2))); 157 158 static const char *conf_filename; 159 static int conf_lineno, conf_warnings; 160 161 bool conf_errors(void) 162 { 163 if (conf_warnings) 164 return getenv("KCONFIG_WERROR"); 165 return false; 166 } 167 168 static void conf_warning(const char *fmt, ...) 169 { 170 va_list ap; 171 va_start(ap, fmt); 172 fprintf(stderr, "%s:%d:warning: ", conf_filename, conf_lineno); 173 vfprintf(stderr, fmt, ap); 174 fprintf(stderr, "\n"); 175 va_end(ap); 176 conf_warnings++; 177 } 178 179 static void conf_default_message_callback(const char *s) 180 { 181 printf("#\n# "); 182 printf("%s", s); 183 printf("\n#\n"); 184 } 185 186 static void (*conf_message_callback)(const char *s) = 187 conf_default_message_callback; 188 void conf_set_message_callback(void (*fn)(const char *s)) 189 { 190 conf_message_callback = fn; 191 } 192 193 static void conf_message(const char *fmt, ...) 194 { 195 va_list ap; 196 char buf[4096]; 197 198 if (!conf_message_callback) 199 return; 200 201 va_start(ap, fmt); 202 203 vsnprintf(buf, sizeof(buf), fmt, ap); 204 conf_message_callback(buf); 205 va_end(ap); 206 } 207 208 const char *conf_get_configname(void) 209 { 210 char *name = getenv("KCONFIG_CONFIG"); 211 212 return name ? name : ".config"; 213 } 214 215 static const char *conf_get_autoconfig_name(void) 216 { 217 char *name = getenv("KCONFIG_AUTOCONFIG"); 218 219 return name ? name : "include/config/auto.conf"; 220 } 221 222 static const char *conf_get_autoheader_name(void) 223 { 224 char *name = getenv("KCONFIG_AUTOHEADER"); 225 226 return name ? name : "include/generated/autoconf.h"; 227 } 228 229 static const char *conf_get_rustccfg_name(void) 230 { 231 char *name = getenv("KCONFIG_RUSTCCFG"); 232 233 return name ? name : "include/generated/rustc_cfg"; 234 } 235 236 static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p) 237 { 238 char *p2; 239 240 switch (sym->type) { 241 case S_TRISTATE: 242 if (p[0] == 'm') { 243 sym->def[def].tri = mod; 244 sym->flags |= def_flags; 245 break; 246 } 247 /* fall through */ 248 case S_BOOLEAN: 249 if (p[0] == 'y') { 250 sym->def[def].tri = yes; 251 sym->flags |= def_flags; 252 break; 253 } 254 if (p[0] == 'n') { 255 sym->def[def].tri = no; 256 sym->flags |= def_flags; 257 break; 258 } 259 if (def != S_DEF_AUTO) 260 conf_warning("symbol value '%s' invalid for %s", 261 p, sym->name); 262 return 1; 263 case S_STRING: 264 /* No escaping for S_DEF_AUTO (include/config/auto.conf) */ 265 if (def != S_DEF_AUTO) { 266 if (*p++ != '"') 267 break; 268 for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) { 269 if (*p2 == '"') { 270 *p2 = 0; 271 break; 272 } 273 memmove(p2, p2 + 1, strlen(p2)); 274 } 275 if (!p2) { 276 conf_warning("invalid string found"); 277 return 1; 278 } 279 } 280 /* fall through */ 281 case S_INT: 282 case S_HEX: 283 if (sym_string_valid(sym, p)) { 284 sym->def[def].val = xstrdup(p); 285 sym->flags |= def_flags; 286 } else { 287 if (def != S_DEF_AUTO) 288 conf_warning("symbol value '%s' invalid for %s", 289 p, sym->name); 290 return 1; 291 } 292 break; 293 default: 294 ; 295 } 296 return 0; 297 } 298 299 /* like getline(), but the newline character is stripped away */ 300 static ssize_t getline_stripped(char **lineptr, size_t *n, FILE *stream) 301 { 302 ssize_t len; 303 304 len = getline(lineptr, n, stream); 305 306 if (len > 0 && (*lineptr)[len - 1] == '\n') { 307 len--; 308 (*lineptr)[len] = '\0'; 309 310 if (len > 0 && (*lineptr)[len - 1] == '\r') { 311 len--; 312 (*lineptr)[len] = '\0'; 313 } 314 } 315 316 return len; 317 } 318 319 int conf_read_simple(const char *name, int def) 320 { 321 FILE *in = NULL; 322 char *line = NULL; 323 size_t line_asize = 0; 324 char *p, *val; 325 struct symbol *sym; 326 int def_flags; 327 const char *warn_unknown, *sym_name; 328 329 warn_unknown = getenv("KCONFIG_WARN_UNKNOWN_SYMBOLS"); 330 if (name) { 331 in = zconf_fopen(name); 332 } else { 333 char *env; 334 335 name = conf_get_configname(); 336 in = zconf_fopen(name); 337 if (in) 338 goto load; 339 conf_set_changed(true); 340 341 env = getenv("KCONFIG_DEFCONFIG_LIST"); 342 if (!env) 343 return 1; 344 345 while (1) { 346 bool is_last; 347 348 while (isspace(*env)) 349 env++; 350 351 if (!*env) 352 break; 353 354 p = env; 355 while (*p && !isspace(*p)) 356 p++; 357 358 is_last = (*p == '\0'); 359 360 *p = '\0'; 361 362 in = zconf_fopen(env); 363 if (in) { 364 conf_message("using defaults found in %s", 365 env); 366 goto load; 367 } 368 369 if (is_last) 370 break; 371 372 env = p + 1; 373 } 374 } 375 if (!in) 376 return 1; 377 378 load: 379 conf_filename = name; 380 conf_lineno = 0; 381 conf_warnings = 0; 382 383 def_flags = SYMBOL_DEF << def; 384 for_all_symbols(sym) { 385 sym->flags |= SYMBOL_CHANGED; 386 sym->flags &= ~(def_flags|SYMBOL_VALID); 387 if (sym_is_choice(sym)) 388 sym->flags |= def_flags; 389 switch (sym->type) { 390 case S_INT: 391 case S_HEX: 392 case S_STRING: 393 free(sym->def[def].val); 394 /* fall through */ 395 default: 396 sym->def[def].val = NULL; 397 sym->def[def].tri = no; 398 } 399 } 400 401 while (getline_stripped(&line, &line_asize, in) != -1) { 402 conf_lineno++; 403 404 if (!line[0]) /* blank line */ 405 continue; 406 407 if (line[0] == '#') { 408 if (line[1] != ' ') 409 continue; 410 p = line + 2; 411 if (memcmp(p, CONFIG_, strlen(CONFIG_))) 412 continue; 413 sym_name = p + strlen(CONFIG_); 414 p = strchr(sym_name, ' '); 415 if (!p) 416 continue; 417 *p++ = 0; 418 if (strcmp(p, "is not set")) 419 continue; 420 421 val = "n"; 422 } else { 423 if (memcmp(line, CONFIG_, strlen(CONFIG_))) { 424 conf_warning("unexpected data: %s", line); 425 continue; 426 } 427 428 sym_name = line + strlen(CONFIG_); 429 p = strchr(sym_name, '='); 430 if (!p) { 431 conf_warning("unexpected data: %s", line); 432 continue; 433 } 434 *p = 0; 435 val = p + 1; 436 } 437 438 sym = sym_find(sym_name); 439 if (!sym) { 440 if (def == S_DEF_AUTO) { 441 /* 442 * Reading from include/config/auto.conf. 443 * If CONFIG_FOO previously existed in auto.conf 444 * but it is missing now, include/config/FOO 445 * must be touched. 446 */ 447 conf_touch_dep(sym_name); 448 } else { 449 if (warn_unknown) 450 conf_warning("unknown symbol: %s", sym_name); 451 452 conf_set_changed(true); 453 } 454 continue; 455 } 456 457 if (sym->flags & def_flags) 458 conf_warning("override: reassigning to symbol %s", sym->name); 459 460 if (conf_set_sym_val(sym, def, def_flags, val)) 461 continue; 462 463 if (sym && sym_is_choice_value(sym)) { 464 struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); 465 switch (sym->def[def].tri) { 466 case no: 467 break; 468 case mod: 469 if (cs->def[def].tri == yes) { 470 conf_warning("%s creates inconsistent choice state", sym->name); 471 cs->flags &= ~def_flags; 472 } 473 break; 474 case yes: 475 if (cs->def[def].tri != no) 476 conf_warning("override: %s changes choice state", sym->name); 477 cs->def[def].val = sym; 478 break; 479 } 480 cs->def[def].tri = EXPR_OR(cs->def[def].tri, sym->def[def].tri); 481 } 482 } 483 free(line); 484 fclose(in); 485 486 return 0; 487 } 488 489 int conf_read(const char *name) 490 { 491 struct symbol *sym; 492 int conf_unsaved = 0; 493 494 conf_set_changed(false); 495 496 if (conf_read_simple(name, S_DEF_USER)) { 497 sym_calc_value(modules_sym); 498 return 1; 499 } 500 501 sym_calc_value(modules_sym); 502 503 for_all_symbols(sym) { 504 sym_calc_value(sym); 505 if (sym_is_choice(sym) || (sym->flags & SYMBOL_NO_WRITE)) 506 continue; 507 if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) { 508 /* check that calculated value agrees with saved value */ 509 switch (sym->type) { 510 case S_BOOLEAN: 511 case S_TRISTATE: 512 if (sym->def[S_DEF_USER].tri == sym_get_tristate_value(sym)) 513 continue; 514 break; 515 default: 516 if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val)) 517 continue; 518 break; 519 } 520 } else if (!sym_has_value(sym) && !(sym->flags & SYMBOL_WRITE)) 521 /* no previous value and not saved */ 522 continue; 523 conf_unsaved++; 524 /* maybe print value in verbose mode... */ 525 } 526 527 for_all_symbols(sym) { 528 if (sym_has_value(sym) && !sym_is_choice_value(sym)) { 529 /* Reset values of generates values, so they'll appear 530 * as new, if they should become visible, but that 531 * doesn't quite work if the Kconfig and the saved 532 * configuration disagree. 533 */ 534 if (sym->visible == no && !conf_unsaved) 535 sym->flags &= ~SYMBOL_DEF_USER; 536 switch (sym->type) { 537 case S_STRING: 538 case S_INT: 539 case S_HEX: 540 /* Reset a string value if it's out of range */ 541 if (sym_string_within_range(sym, sym->def[S_DEF_USER].val)) 542 break; 543 sym->flags &= ~SYMBOL_VALID; 544 conf_unsaved++; 545 break; 546 default: 547 break; 548 } 549 } 550 } 551 552 if (conf_warnings || conf_unsaved) 553 conf_set_changed(true); 554 555 return 0; 556 } 557 558 struct comment_style { 559 const char *decoration; 560 const char *prefix; 561 const char *postfix; 562 }; 563 564 static const struct comment_style comment_style_pound = { 565 .decoration = "#", 566 .prefix = "#", 567 .postfix = "#", 568 }; 569 570 static const struct comment_style comment_style_c = { 571 .decoration = " *", 572 .prefix = "/*", 573 .postfix = " */", 574 }; 575 576 static void conf_write_heading(FILE *fp, const struct comment_style *cs) 577 { 578 if (!cs) 579 return; 580 581 fprintf(fp, "%s\n", cs->prefix); 582 583 fprintf(fp, "%s Automatically generated file; DO NOT EDIT.\n", 584 cs->decoration); 585 586 fprintf(fp, "%s %s\n", cs->decoration, rootmenu.prompt->text); 587 588 fprintf(fp, "%s\n", cs->postfix); 589 } 590 591 /* The returned pointer must be freed on the caller side */ 592 static char *escape_string_value(const char *in) 593 { 594 const char *p; 595 char *out; 596 size_t len; 597 598 len = strlen(in) + strlen("\"\"") + 1; 599 600 p = in; 601 while (1) { 602 p += strcspn(p, "\"\\"); 603 604 if (p[0] == '\0') 605 break; 606 607 len++; 608 p++; 609 } 610 611 out = xmalloc(len); 612 out[0] = '\0'; 613 614 strcat(out, "\""); 615 616 p = in; 617 while (1) { 618 len = strcspn(p, "\"\\"); 619 strncat(out, p, len); 620 p += len; 621 622 if (p[0] == '\0') 623 break; 624 625 strcat(out, "\\"); 626 strncat(out, p++, 1); 627 } 628 629 strcat(out, "\""); 630 631 return out; 632 } 633 634 enum output_n { OUTPUT_N, OUTPUT_N_AS_UNSET, OUTPUT_N_NONE }; 635 636 static void __print_symbol(FILE *fp, struct symbol *sym, enum output_n output_n, 637 bool escape_string) 638 { 639 const char *val; 640 char *escaped = NULL; 641 642 if (sym->type == S_UNKNOWN) 643 return; 644 645 val = sym_get_string_value(sym); 646 647 if ((sym->type == S_BOOLEAN || sym->type == S_TRISTATE) && 648 output_n != OUTPUT_N && *val == 'n') { 649 if (output_n == OUTPUT_N_AS_UNSET) 650 fprintf(fp, "# %s%s is not set\n", CONFIG_, sym->name); 651 return; 652 } 653 654 if (sym->type == S_STRING && escape_string) { 655 escaped = escape_string_value(val); 656 val = escaped; 657 } 658 659 fprintf(fp, "%s%s=%s\n", CONFIG_, sym->name, val); 660 661 free(escaped); 662 } 663 664 static void print_symbol_for_dotconfig(FILE *fp, struct symbol *sym) 665 { 666 __print_symbol(fp, sym, OUTPUT_N_AS_UNSET, true); 667 } 668 669 static void print_symbol_for_autoconf(FILE *fp, struct symbol *sym) 670 { 671 __print_symbol(fp, sym, OUTPUT_N_NONE, false); 672 } 673 674 void print_symbol_for_listconfig(struct symbol *sym) 675 { 676 __print_symbol(stdout, sym, OUTPUT_N, true); 677 } 678 679 static void print_symbol_for_c(FILE *fp, struct symbol *sym) 680 { 681 const char *val; 682 const char *sym_suffix = ""; 683 const char *val_prefix = ""; 684 char *escaped = NULL; 685 686 if (sym->type == S_UNKNOWN) 687 return; 688 689 val = sym_get_string_value(sym); 690 691 switch (sym->type) { 692 case S_BOOLEAN: 693 case S_TRISTATE: 694 switch (*val) { 695 case 'n': 696 return; 697 case 'm': 698 sym_suffix = "_MODULE"; 699 /* fall through */ 700 default: 701 val = "1"; 702 } 703 break; 704 case S_HEX: 705 if (val[0] != '0' || (val[1] != 'x' && val[1] != 'X')) 706 val_prefix = "0x"; 707 break; 708 case S_STRING: 709 escaped = escape_string_value(val); 710 val = escaped; 711 default: 712 break; 713 } 714 715 fprintf(fp, "#define %s%s%s %s%s\n", CONFIG_, sym->name, sym_suffix, 716 val_prefix, val); 717 718 free(escaped); 719 } 720 721 static void print_symbol_for_rustccfg(FILE *fp, struct symbol *sym) 722 { 723 const char *val; 724 const char *val_prefix = ""; 725 char *val_prefixed = NULL; 726 size_t val_prefixed_len; 727 char *escaped = NULL; 728 729 if (sym->type == S_UNKNOWN) 730 return; 731 732 val = sym_get_string_value(sym); 733 734 switch (sym->type) { 735 case S_BOOLEAN: 736 case S_TRISTATE: 737 /* 738 * We do not care about disabled ones, i.e. no need for 739 * what otherwise are "comments" in other printers. 740 */ 741 if (*val == 'n') 742 return; 743 744 /* 745 * To have similar functionality to the C macro `IS_ENABLED()` 746 * we provide an empty `--cfg CONFIG_X` here in both `y` 747 * and `m` cases. 748 * 749 * Then, the common `fprintf()` below will also give us 750 * a `--cfg CONFIG_X="y"` or `--cfg CONFIG_X="m"`, which can 751 * be used as the equivalent of `IS_BUILTIN()`/`IS_MODULE()`. 752 */ 753 fprintf(fp, "--cfg=%s%s\n", CONFIG_, sym->name); 754 break; 755 case S_HEX: 756 if (val[0] != '0' || (val[1] != 'x' && val[1] != 'X')) 757 val_prefix = "0x"; 758 break; 759 default: 760 break; 761 } 762 763 if (strlen(val_prefix) > 0) { 764 val_prefixed_len = strlen(val) + strlen(val_prefix) + 1; 765 val_prefixed = xmalloc(val_prefixed_len); 766 snprintf(val_prefixed, val_prefixed_len, "%s%s", val_prefix, val); 767 val = val_prefixed; 768 } 769 770 /* All values get escaped: the `--cfg` option only takes strings */ 771 escaped = escape_string_value(val); 772 val = escaped; 773 774 fprintf(fp, "--cfg=%s%s=%s\n", CONFIG_, sym->name, val); 775 776 free(escaped); 777 free(val_prefixed); 778 } 779 780 /* 781 * Write out a minimal config. 782 * All values that has default values are skipped as this is redundant. 783 */ 784 int conf_write_defconfig(const char *filename) 785 { 786 struct symbol *sym; 787 struct menu *menu; 788 FILE *out; 789 790 out = fopen(filename, "w"); 791 if (!out) 792 return 1; 793 794 sym_clear_all_valid(); 795 796 /* Traverse all menus to find all relevant symbols */ 797 menu = rootmenu.list; 798 799 while (menu != NULL) 800 { 801 sym = menu->sym; 802 if (sym && !sym_is_choice(sym)) { 803 sym_calc_value(sym); 804 if (!(sym->flags & SYMBOL_WRITE)) 805 goto next_menu; 806 sym->flags &= ~SYMBOL_WRITE; 807 /* If we cannot change the symbol - skip */ 808 if (!sym_is_changeable(sym)) 809 goto next_menu; 810 /* If symbol equals to default value - skip */ 811 if (strcmp(sym_get_string_value(sym), sym_get_string_default(sym)) == 0) 812 goto next_menu; 813 814 /* 815 * If symbol is a choice value and equals to the 816 * default for a choice - skip. 817 * But only if value is bool and equal to "y" and 818 * choice is not "optional". 819 * (If choice is "optional" then all values can be "n") 820 */ 821 if (sym_is_choice_value(sym)) { 822 struct symbol *cs; 823 struct symbol *ds; 824 825 cs = prop_get_symbol(sym_get_choice_prop(sym)); 826 ds = sym_choice_default(cs); 827 if (!sym_is_optional(cs) && sym == ds) { 828 if ((sym->type == S_BOOLEAN) && 829 sym_get_tristate_value(sym) == yes) 830 goto next_menu; 831 } 832 } 833 print_symbol_for_dotconfig(out, sym); 834 } 835 next_menu: 836 if (menu->list != NULL) { 837 menu = menu->list; 838 } 839 else if (menu->next != NULL) { 840 menu = menu->next; 841 } else { 842 while ((menu = menu->parent)) { 843 if (menu->next != NULL) { 844 menu = menu->next; 845 break; 846 } 847 } 848 } 849 } 850 fclose(out); 851 return 0; 852 } 853 854 int conf_write(const char *name) 855 { 856 FILE *out; 857 struct symbol *sym; 858 struct menu *menu; 859 const char *str; 860 char tmpname[PATH_MAX + 1], oldname[PATH_MAX + 1]; 861 char *env; 862 bool need_newline = false; 863 864 if (!name) 865 name = conf_get_configname(); 866 867 if (!*name) { 868 fprintf(stderr, "config name is empty\n"); 869 return -1; 870 } 871 872 if (is_dir(name)) { 873 fprintf(stderr, "%s: Is a directory\n", name); 874 return -1; 875 } 876 877 if (make_parent_dir(name)) 878 return -1; 879 880 env = getenv("KCONFIG_OVERWRITECONFIG"); 881 if (env && *env) { 882 *tmpname = 0; 883 out = fopen(name, "w"); 884 } else { 885 snprintf(tmpname, sizeof(tmpname), "%s.%d.tmp", 886 name, (int)getpid()); 887 out = fopen(tmpname, "w"); 888 } 889 if (!out) 890 return 1; 891 892 conf_write_heading(out, &comment_style_pound); 893 894 if (!conf_get_changed()) 895 sym_clear_all_valid(); 896 897 menu = rootmenu.list; 898 while (menu) { 899 sym = menu->sym; 900 if (!sym) { 901 if (!menu_is_visible(menu)) 902 goto next; 903 str = menu_get_prompt(menu); 904 fprintf(out, "\n" 905 "#\n" 906 "# %s\n" 907 "#\n", str); 908 need_newline = false; 909 } else if (!(sym->flags & SYMBOL_CHOICE) && 910 !(sym->flags & SYMBOL_WRITTEN)) { 911 sym_calc_value(sym); 912 if (!(sym->flags & SYMBOL_WRITE)) 913 goto next; 914 if (need_newline) { 915 fprintf(out, "\n"); 916 need_newline = false; 917 } 918 sym->flags |= SYMBOL_WRITTEN; 919 print_symbol_for_dotconfig(out, sym); 920 } 921 922 next: 923 if (menu->list) { 924 menu = menu->list; 925 continue; 926 } 927 928 end_check: 929 if (!menu->sym && menu_is_visible(menu) && menu != &rootmenu && 930 menu->prompt->type == P_MENU) { 931 fprintf(out, "# end of %s\n", menu_get_prompt(menu)); 932 need_newline = true; 933 } 934 935 if (menu->next) { 936 menu = menu->next; 937 } else { 938 menu = menu->parent; 939 if (menu) 940 goto end_check; 941 } 942 } 943 fclose(out); 944 945 for_all_symbols(sym) 946 sym->flags &= ~SYMBOL_WRITTEN; 947 948 if (*tmpname) { 949 if (is_same(name, tmpname)) { 950 conf_message("No change to %s", name); 951 unlink(tmpname); 952 conf_set_changed(false); 953 return 0; 954 } 955 956 snprintf(oldname, sizeof(oldname), "%s.old", name); 957 rename(name, oldname); 958 if (rename(tmpname, name)) 959 return 1; 960 } 961 962 conf_message("configuration written to %s", name); 963 964 conf_set_changed(false); 965 966 return 0; 967 } 968 969 /* write a dependency file as used by kbuild to track dependencies */ 970 static int conf_write_autoconf_cmd(const char *autoconf_name) 971 { 972 char name[PATH_MAX], tmp[PATH_MAX]; 973 FILE *out; 974 int ret; 975 976 ret = snprintf(name, sizeof(name), "%s.cmd", autoconf_name); 977 if (ret >= sizeof(name)) /* check truncation */ 978 return -1; 979 980 if (make_parent_dir(name)) 981 return -1; 982 983 ret = snprintf(tmp, sizeof(tmp), "%s.cmd.tmp", autoconf_name); 984 if (ret >= sizeof(tmp)) /* check truncation */ 985 return -1; 986 987 out = fopen(tmp, "w"); 988 if (!out) { 989 perror("fopen"); 990 return -1; 991 } 992 993 fprintf(out, "autoconfig := %s\n", autoconf_name); 994 995 fputs(str_get(&autoconf_cmd), out); 996 997 fflush(out); 998 ret = ferror(out); /* error check for all fprintf() calls */ 999 fclose(out); 1000 if (ret) 1001 return -1; 1002 1003 if (rename(tmp, name)) { 1004 perror("rename"); 1005 return -1; 1006 } 1007 1008 return 0; 1009 } 1010 1011 static int conf_touch_deps(void) 1012 { 1013 const char *name, *tmp; 1014 struct symbol *sym; 1015 int res; 1016 1017 name = conf_get_autoconfig_name(); 1018 tmp = strrchr(name, '/'); 1019 depfile_prefix_len = tmp ? tmp - name + 1 : 0; 1020 if (depfile_prefix_len + 1 > sizeof(depfile_path)) 1021 return -1; 1022 1023 strncpy(depfile_path, name, depfile_prefix_len); 1024 depfile_path[depfile_prefix_len] = 0; 1025 1026 conf_read_simple(name, S_DEF_AUTO); 1027 sym_calc_value(modules_sym); 1028 1029 for_all_symbols(sym) { 1030 sym_calc_value(sym); 1031 if ((sym->flags & SYMBOL_NO_WRITE) || !sym->name) 1032 continue; 1033 if (sym->flags & SYMBOL_WRITE) { 1034 if (sym->flags & SYMBOL_DEF_AUTO) { 1035 /* 1036 * symbol has old and new value, 1037 * so compare them... 1038 */ 1039 switch (sym->type) { 1040 case S_BOOLEAN: 1041 case S_TRISTATE: 1042 if (sym_get_tristate_value(sym) == 1043 sym->def[S_DEF_AUTO].tri) 1044 continue; 1045 break; 1046 case S_STRING: 1047 case S_HEX: 1048 case S_INT: 1049 if (!strcmp(sym_get_string_value(sym), 1050 sym->def[S_DEF_AUTO].val)) 1051 continue; 1052 break; 1053 default: 1054 break; 1055 } 1056 } else { 1057 /* 1058 * If there is no old value, only 'no' (unset) 1059 * is allowed as new value. 1060 */ 1061 switch (sym->type) { 1062 case S_BOOLEAN: 1063 case S_TRISTATE: 1064 if (sym_get_tristate_value(sym) == no) 1065 continue; 1066 break; 1067 default: 1068 break; 1069 } 1070 } 1071 } else if (!(sym->flags & SYMBOL_DEF_AUTO)) 1072 /* There is neither an old nor a new value. */ 1073 continue; 1074 /* else 1075 * There is an old value, but no new value ('no' (unset) 1076 * isn't saved in auto.conf, so the old value is always 1077 * different from 'no'). 1078 */ 1079 1080 res = conf_touch_dep(sym->name); 1081 if (res) 1082 return res; 1083 } 1084 1085 return 0; 1086 } 1087 1088 static int __conf_write_autoconf(const char *filename, 1089 void (*print_symbol)(FILE *, struct symbol *), 1090 const struct comment_style *comment_style) 1091 { 1092 char tmp[PATH_MAX]; 1093 FILE *file; 1094 struct symbol *sym; 1095 int ret; 1096 1097 if (make_parent_dir(filename)) 1098 return -1; 1099 1100 ret = snprintf(tmp, sizeof(tmp), "%s.tmp", filename); 1101 if (ret >= sizeof(tmp)) /* check truncation */ 1102 return -1; 1103 1104 file = fopen(tmp, "w"); 1105 if (!file) { 1106 perror("fopen"); 1107 return -1; 1108 } 1109 1110 conf_write_heading(file, comment_style); 1111 1112 for_all_symbols(sym) 1113 if ((sym->flags & SYMBOL_WRITE) && sym->name) 1114 print_symbol(file, sym); 1115 1116 fflush(file); 1117 /* check possible errors in conf_write_heading() and print_symbol() */ 1118 ret = ferror(file); 1119 fclose(file); 1120 if (ret) 1121 return -1; 1122 1123 if (rename(tmp, filename)) { 1124 perror("rename"); 1125 return -1; 1126 } 1127 1128 return 0; 1129 } 1130 1131 int conf_write_autoconf(int overwrite) 1132 { 1133 struct symbol *sym; 1134 const char *autoconf_name = conf_get_autoconfig_name(); 1135 int ret; 1136 1137 if (!overwrite && is_present(autoconf_name)) 1138 return 0; 1139 1140 ret = conf_write_autoconf_cmd(autoconf_name); 1141 if (ret) 1142 return -1; 1143 1144 if (conf_touch_deps()) 1145 return 1; 1146 1147 for_all_symbols(sym) 1148 sym_calc_value(sym); 1149 1150 ret = __conf_write_autoconf(conf_get_autoheader_name(), 1151 print_symbol_for_c, 1152 &comment_style_c); 1153 if (ret) 1154 return ret; 1155 1156 ret = __conf_write_autoconf(conf_get_rustccfg_name(), 1157 print_symbol_for_rustccfg, 1158 NULL); 1159 if (ret) 1160 return ret; 1161 1162 /* 1163 * Create include/config/auto.conf. This must be the last step because 1164 * Kbuild has a dependency on auto.conf and this marks the successful 1165 * completion of the previous steps. 1166 */ 1167 ret = __conf_write_autoconf(conf_get_autoconfig_name(), 1168 print_symbol_for_autoconf, 1169 &comment_style_pound); 1170 if (ret) 1171 return ret; 1172 1173 return 0; 1174 } 1175 1176 static bool conf_changed; 1177 static void (*conf_changed_callback)(void); 1178 1179 void conf_set_changed(bool val) 1180 { 1181 bool changed = conf_changed != val; 1182 1183 conf_changed = val; 1184 1185 if (conf_changed_callback && changed) 1186 conf_changed_callback(); 1187 } 1188 1189 bool conf_get_changed(void) 1190 { 1191 return conf_changed; 1192 } 1193 1194 void conf_set_changed_callback(void (*fn)(void)) 1195 { 1196 conf_changed_callback = fn; 1197 } 1198 1199 void set_all_choice_values(struct symbol *csym) 1200 { 1201 struct property *prop; 1202 struct symbol *sym; 1203 struct expr *e; 1204 1205 prop = sym_get_choice_prop(csym); 1206 1207 /* 1208 * Set all non-assinged choice values to no 1209 */ 1210 expr_list_for_each_sym(prop->expr, e, sym) { 1211 if (!sym_has_value(sym)) 1212 sym->def[S_DEF_USER].tri = no; 1213 } 1214 csym->flags |= SYMBOL_DEF_USER; 1215 /* clear VALID to get value calculated */ 1216 csym->flags &= ~(SYMBOL_VALID | SYMBOL_NEED_SET_CHOICE_VALUES); 1217 } 1218