1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2002 Roman Zippel <[email protected]> 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 "lkc.h" 22 23 struct gstr autoconf_cmd; 24 25 /* return true if 'path' exists, false otherwise */ 26 static bool is_present(const char *path) 27 { 28 struct stat st; 29 30 return !stat(path, &st); 31 } 32 33 /* return true if 'path' exists and it is a directory, false otherwise */ 34 static bool is_dir(const char *path) 35 { 36 struct stat st; 37 38 if (stat(path, &st)) 39 return false; 40 41 return S_ISDIR(st.st_mode); 42 } 43 44 /* return true if the given two files are the same, false otherwise */ 45 static bool is_same(const char *file1, const char *file2) 46 { 47 int fd1, fd2; 48 struct stat st1, st2; 49 void *map1, *map2; 50 bool ret = false; 51 52 fd1 = open(file1, O_RDONLY); 53 if (fd1 < 0) 54 return ret; 55 56 fd2 = open(file2, O_RDONLY); 57 if (fd2 < 0) 58 goto close1; 59 60 ret = fstat(fd1, &st1); 61 if (ret) 62 goto close2; 63 ret = fstat(fd2, &st2); 64 if (ret) 65 goto close2; 66 67 if (st1.st_size != st2.st_size) 68 goto close2; 69 70 map1 = mmap(NULL, st1.st_size, PROT_READ, MAP_PRIVATE, fd1, 0); 71 if (map1 == MAP_FAILED) 72 goto close2; 73 74 map2 = mmap(NULL, st2.st_size, PROT_READ, MAP_PRIVATE, fd2, 0); 75 if (map2 == MAP_FAILED) 76 goto close2; 77 78 if (bcmp(map1, map2, st1.st_size)) 79 goto close2; 80 81 ret = true; 82 close2: 83 close(fd2); 84 close1: 85 close(fd1); 86 87 return ret; 88 } 89 90 /* 91 * Create the parent directory of the given path. 92 * 93 * For example, if 'include/config/auto.conf' is given, create 'include/config'. 94 */ 95 static int make_parent_dir(const char *path) 96 { 97 char tmp[PATH_MAX + 1]; 98 char *p; 99 100 strncpy(tmp, path, sizeof(tmp)); 101 tmp[sizeof(tmp) - 1] = 0; 102 103 /* Remove the base name. Just return if nothing is left */ 104 p = strrchr(tmp, '/'); 105 if (!p) 106 return 0; 107 *(p + 1) = 0; 108 109 /* Just in case it is an absolute path */ 110 p = tmp; 111 while (*p == '/') 112 p++; 113 114 while ((p = strchr(p, '/'))) { 115 *p = 0; 116 117 /* skip if the directory exists */ 118 if (!is_dir(tmp) && mkdir(tmp, 0755)) 119 return -1; 120 121 *p = '/'; 122 while (*p == '/') 123 p++; 124 } 125 126 return 0; 127 } 128 129 static char depfile_path[PATH_MAX]; 130 static size_t depfile_prefix_len; 131 132 /* touch depfile for symbol 'name' */ 133 static int conf_touch_dep(const char *name) 134 { 135 int fd; 136 137 /* check overflow: prefix + name + '\0' must fit in buffer. */ 138 if (depfile_prefix_len + strlen(name) + 1 > sizeof(depfile_path)) 139 return -1; 140 141 strcpy(depfile_path + depfile_prefix_len, name); 142 143 fd = open(depfile_path, O_WRONLY | O_CREAT | O_TRUNC, 0644); 144 if (fd == -1) 145 return -1; 146 close(fd); 147 148 return 0; 149 } 150 151 static void conf_warning(const char *fmt, ...) 152 __attribute__ ((format (printf, 1, 2))); 153 154 static void conf_message(const char *fmt, ...) 155 __attribute__ ((format (printf, 1, 2))); 156 157 static const char *conf_filename; 158 static int conf_lineno, conf_warnings; 159 160 bool conf_errors(void) 161 { 162 if (conf_warnings) 163 return getenv("KCONFIG_WERROR"); 164 return false; 165 } 166 167 static void conf_warning(const char *fmt, ...) 168 { 169 va_list ap; 170 va_start(ap, fmt); 171 fprintf(stderr, "%s:%d:warning: ", conf_filename, conf_lineno); 172 vfprintf(stderr, fmt, ap); 173 fprintf(stderr, "\n"); 174 va_end(ap); 175 conf_warnings++; 176 } 177 178 static void conf_default_message_callback(const char *s) 179 { 180 printf("#\n# "); 181 printf("%s", s); 182 printf("\n#\n"); 183 } 184 185 static void (*conf_message_callback)(const char *s) = 186 conf_default_message_callback; 187 void conf_set_message_callback(void (*fn)(const char *s)) 188 { 189 conf_message_callback = fn; 190 } 191 192 static void conf_message(const char *fmt, ...) 193 { 194 va_list ap; 195 char buf[4096]; 196 197 if (!conf_message_callback) 198 return; 199 200 va_start(ap, fmt); 201 202 vsnprintf(buf, sizeof(buf), fmt, ap); 203 conf_message_callback(buf); 204 va_end(ap); 205 } 206 207 const char *conf_get_configname(void) 208 { 209 char *name = getenv("KCONFIG_CONFIG"); 210 211 return name ? name : ".config"; 212 } 213 214 static const char *conf_get_autoconfig_name(void) 215 { 216 char *name = getenv("KCONFIG_AUTOCONFIG"); 217 218 return name ? name : "include/config/auto.conf"; 219 } 220 221 static const char *conf_get_autoheader_name(void) 222 { 223 char *name = getenv("KCONFIG_AUTOHEADER"); 224 225 return name ? name : "include/generated/autoconf.h"; 226 } 227 228 static const char *conf_get_rustccfg_name(void) 229 { 230 char *name = getenv("KCONFIG_RUSTCCFG"); 231 232 return name ? name : "include/generated/rustc_cfg"; 233 } 234 235 static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p) 236 { 237 char *p2; 238 239 switch (sym->type) { 240 case S_TRISTATE: 241 if (p[0] == 'm') { 242 sym->def[def].tri = mod; 243 sym->flags |= def_flags; 244 break; 245 } 246 /* fall through */ 247 case S_BOOLEAN: 248 if (p[0] == 'y') { 249 sym->def[def].tri = yes; 250 sym->flags |= def_flags; 251 break; 252 } 253 if (p[0] == 'n') { 254 sym->def[def].tri = no; 255 sym->flags |= def_flags; 256 break; 257 } 258 if (def != S_DEF_AUTO) 259 conf_warning("symbol value '%s' invalid for %s", 260 p, sym->name); 261 return 1; 262 case S_STRING: 263 /* No escaping for S_DEF_AUTO (include/config/auto.conf) */ 264 if (def != S_DEF_AUTO) { 265 if (*p++ != '"') 266 break; 267 for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) { 268 if (*p2 == '"') { 269 *p2 = 0; 270 break; 271 } 272 memmove(p2, p2 + 1, strlen(p2)); 273 } 274 if (!p2) { 275 conf_warning("invalid string found"); 276 return 1; 277 } 278 } 279 /* fall through */ 280 case S_INT: 281 case S_HEX: 282 if (sym_string_valid(sym, p)) { 283 sym->def[def].val = xstrdup(p); 284 sym->flags |= def_flags; 285 } else { 286 if (def != S_DEF_AUTO) 287 conf_warning("symbol value '%s' invalid for %s", 288 p, sym->name); 289 return 1; 290 } 291 break; 292 default: 293 ; 294 } 295 return 0; 296 } 297 298 /* like getline(), but the newline character is stripped away */ 299 static ssize_t getline_stripped(char **lineptr, size_t *n, FILE *stream) 300 { 301 ssize_t len; 302 303 len = getline(lineptr, n, stream); 304 305 if (len > 0 && (*lineptr)[len - 1] == '\n') { 306 len--; 307 (*lineptr)[len] = '\0'; 308 309 if (len > 0 && (*lineptr)[len - 1] == '\r') { 310 len--; 311 (*lineptr)[len] = '\0'; 312 } 313 } 314 315 return len; 316 } 317 318 int conf_read_simple(const char *name, int def) 319 { 320 FILE *in = NULL; 321 char *line = NULL; 322 size_t line_asize = 0; 323 char *p, *val; 324 struct symbol *sym; 325 int i, def_flags; 326 const char *warn_unknown, *sym_name; 327 328 warn_unknown = getenv("KCONFIG_WARN_UNKNOWN_SYMBOLS"); 329 if (name) { 330 in = zconf_fopen(name); 331 } else { 332 char *env; 333 334 name = conf_get_configname(); 335 in = zconf_fopen(name); 336 if (in) 337 goto load; 338 conf_set_changed(true); 339 340 env = getenv("KCONFIG_DEFCONFIG_LIST"); 341 if (!env) 342 return 1; 343 344 while (1) { 345 bool is_last; 346 347 while (isspace(*env)) 348 env++; 349 350 if (!*env) 351 break; 352 353 p = env; 354 while (*p && !isspace(*p)) 355 p++; 356 357 is_last = (*p == '\0'); 358 359 *p = '\0'; 360 361 in = zconf_fopen(env); 362 if (in) { 363 conf_message("using defaults found in %s", 364 env); 365 goto load; 366 } 367 368 if (is_last) 369 break; 370 371 env = p + 1; 372 } 373 } 374 if (!in) 375 return 1; 376 377 load: 378 conf_filename = name; 379 conf_lineno = 0; 380 conf_warnings = 0; 381 382 def_flags = SYMBOL_DEF << def; 383 for_all_symbols(i, sym) { 384 sym->flags |= SYMBOL_CHANGED; 385 sym->flags &= ~(def_flags|SYMBOL_VALID); 386 if (sym_is_choice(sym)) 387 sym->flags |= def_flags; 388 switch (sym->type) { 389 case S_INT: 390 case S_HEX: 391 case S_STRING: 392 free(sym->def[def].val); 393 /* fall through */ 394 default: 395 sym->def[def].val = NULL; 396 sym->def[def].tri = no; 397 } 398 } 399 400 while (getline_stripped(&line, &line_asize, in) != -1) { 401 conf_lineno++; 402 403 if (!line[0]) /* blank line */ 404 continue; 405 406 if (line[0] == '#') { 407 if (line[1] != ' ') 408 continue; 409 p = line + 2; 410 if (memcmp(p, CONFIG_, strlen(CONFIG_))) 411 continue; 412 sym_name = p + strlen(CONFIG_); 413 p = strchr(sym_name, ' '); 414 if (!p) 415 continue; 416 *p++ = 0; 417 if (strcmp(p, "is not set")) 418 continue; 419 420 val = "n"; 421 } else { 422 if (memcmp(line, CONFIG_, strlen(CONFIG_))) { 423 conf_warning("unexpected data: %s", line); 424 continue; 425 } 426 427 sym_name = line + strlen(CONFIG_); 428 p = strchr(sym_name, '='); 429 if (!p) { 430 conf_warning("unexpected data: %s", line); 431 continue; 432 } 433 *p = 0; 434 val = p + 1; 435 } 436 437 sym = sym_find(sym_name); 438 if (!sym) { 439 if (def == S_DEF_AUTO) { 440 /* 441 * Reading from include/config/auto.conf. 442 * If CONFIG_FOO previously existed in auto.conf 443 * but it is missing now, include/config/FOO 444 * must be touched. 445 */ 446 conf_touch_dep(sym_name); 447 } else { 448 if (warn_unknown) 449 conf_warning("unknown symbol: %s", sym_name); 450 451 conf_set_changed(true); 452 } 453 continue; 454 } 455 456 if (sym->flags & def_flags) 457 conf_warning("override: reassigning to symbol %s", sym->name); 458 459 if (conf_set_sym_val(sym, def, def_flags, val)) 460 continue; 461 462 if (sym && sym_is_choice_value(sym)) { 463 struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); 464 switch (sym->def[def].tri) { 465 case no: 466 break; 467 case mod: 468 if (cs->def[def].tri == yes) { 469 conf_warning("%s creates inconsistent choice state", sym->name); 470 cs->flags &= ~def_flags; 471 } 472 break; 473 case yes: 474 if (cs->def[def].tri != no) 475 conf_warning("override: %s changes choice state", sym->name); 476 cs->def[def].val = sym; 477 break; 478 } 479 cs->def[def].tri = EXPR_OR(cs->def[def].tri, sym->def[def].tri); 480 } 481 } 482 free(line); 483 fclose(in); 484 485 return 0; 486 } 487 488 int conf_read(const char *name) 489 { 490 struct symbol *sym; 491 int conf_unsaved = 0; 492 int i; 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(i, 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(i, 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 == NULL) { 803 if (!menu_is_visible(menu)) 804 goto next_menu; 805 } else if (!sym_is_choice(sym)) { 806 sym_calc_value(sym); 807 if (!(sym->flags & SYMBOL_WRITE)) 808 goto next_menu; 809 sym->flags &= ~SYMBOL_WRITE; 810 /* If we cannot change the symbol - skip */ 811 if (!sym_is_changeable(sym)) 812 goto next_menu; 813 /* If symbol equals to default value - skip */ 814 if (strcmp(sym_get_string_value(sym), sym_get_string_default(sym)) == 0) 815 goto next_menu; 816 817 /* 818 * If symbol is a choice value and equals to the 819 * default for a choice - skip. 820 * But only if value is bool and equal to "y" and 821 * choice is not "optional". 822 * (If choice is "optional" then all values can be "n") 823 */ 824 if (sym_is_choice_value(sym)) { 825 struct symbol *cs; 826 struct symbol *ds; 827 828 cs = prop_get_symbol(sym_get_choice_prop(sym)); 829 ds = sym_choice_default(cs); 830 if (!sym_is_optional(cs) && sym == ds) { 831 if ((sym->type == S_BOOLEAN) && 832 sym_get_tristate_value(sym) == yes) 833 goto next_menu; 834 } 835 } 836 print_symbol_for_dotconfig(out, sym); 837 } 838 next_menu: 839 if (menu->list != NULL) { 840 menu = menu->list; 841 } 842 else if (menu->next != NULL) { 843 menu = menu->next; 844 } else { 845 while ((menu = menu->parent)) { 846 if (menu->next != NULL) { 847 menu = menu->next; 848 break; 849 } 850 } 851 } 852 } 853 fclose(out); 854 return 0; 855 } 856 857 int conf_write(const char *name) 858 { 859 FILE *out; 860 struct symbol *sym; 861 struct menu *menu; 862 const char *str; 863 char tmpname[PATH_MAX + 1], oldname[PATH_MAX + 1]; 864 char *env; 865 int i; 866 bool need_newline = false; 867 868 if (!name) 869 name = conf_get_configname(); 870 871 if (!*name) { 872 fprintf(stderr, "config name is empty\n"); 873 return -1; 874 } 875 876 if (is_dir(name)) { 877 fprintf(stderr, "%s: Is a directory\n", name); 878 return -1; 879 } 880 881 if (make_parent_dir(name)) 882 return -1; 883 884 env = getenv("KCONFIG_OVERWRITECONFIG"); 885 if (env && *env) { 886 *tmpname = 0; 887 out = fopen(name, "w"); 888 } else { 889 snprintf(tmpname, sizeof(tmpname), "%s.%d.tmp", 890 name, (int)getpid()); 891 out = fopen(tmpname, "w"); 892 } 893 if (!out) 894 return 1; 895 896 conf_write_heading(out, &comment_style_pound); 897 898 if (!conf_get_changed()) 899 sym_clear_all_valid(); 900 901 menu = rootmenu.list; 902 while (menu) { 903 sym = menu->sym; 904 if (!sym) { 905 if (!menu_is_visible(menu)) 906 goto next; 907 str = menu_get_prompt(menu); 908 fprintf(out, "\n" 909 "#\n" 910 "# %s\n" 911 "#\n", str); 912 need_newline = false; 913 } else if (!(sym->flags & SYMBOL_CHOICE) && 914 !(sym->flags & SYMBOL_WRITTEN)) { 915 sym_calc_value(sym); 916 if (!(sym->flags & SYMBOL_WRITE)) 917 goto next; 918 if (need_newline) { 919 fprintf(out, "\n"); 920 need_newline = false; 921 } 922 sym->flags |= SYMBOL_WRITTEN; 923 print_symbol_for_dotconfig(out, sym); 924 } 925 926 next: 927 if (menu->list) { 928 menu = menu->list; 929 continue; 930 } 931 932 end_check: 933 if (!menu->sym && menu_is_visible(menu) && menu != &rootmenu && 934 menu->prompt->type == P_MENU) { 935 fprintf(out, "# end of %s\n", menu_get_prompt(menu)); 936 need_newline = true; 937 } 938 939 if (menu->next) { 940 menu = menu->next; 941 } else { 942 menu = menu->parent; 943 if (menu) 944 goto end_check; 945 } 946 } 947 fclose(out); 948 949 for_all_symbols(i, sym) 950 sym->flags &= ~SYMBOL_WRITTEN; 951 952 if (*tmpname) { 953 if (is_same(name, tmpname)) { 954 conf_message("No change to %s", name); 955 unlink(tmpname); 956 conf_set_changed(false); 957 return 0; 958 } 959 960 snprintf(oldname, sizeof(oldname), "%s.old", name); 961 rename(name, oldname); 962 if (rename(tmpname, name)) 963 return 1; 964 } 965 966 conf_message("configuration written to %s", name); 967 968 conf_set_changed(false); 969 970 return 0; 971 } 972 973 /* write a dependency file as used by kbuild to track dependencies */ 974 static int conf_write_autoconf_cmd(const char *autoconf_name) 975 { 976 char name[PATH_MAX], tmp[PATH_MAX]; 977 FILE *out; 978 int ret; 979 980 ret = snprintf(name, sizeof(name), "%s.cmd", autoconf_name); 981 if (ret >= sizeof(name)) /* check truncation */ 982 return -1; 983 984 if (make_parent_dir(name)) 985 return -1; 986 987 ret = snprintf(tmp, sizeof(tmp), "%s.cmd.tmp", autoconf_name); 988 if (ret >= sizeof(tmp)) /* check truncation */ 989 return -1; 990 991 out = fopen(tmp, "w"); 992 if (!out) { 993 perror("fopen"); 994 return -1; 995 } 996 997 fprintf(out, "autoconfig := %s\n", autoconf_name); 998 999 fputs(str_get(&autoconf_cmd), out); 1000 1001 fflush(out); 1002 ret = ferror(out); /* error check for all fprintf() calls */ 1003 fclose(out); 1004 if (ret) 1005 return -1; 1006 1007 if (rename(tmp, name)) { 1008 perror("rename"); 1009 return -1; 1010 } 1011 1012 return 0; 1013 } 1014 1015 static int conf_touch_deps(void) 1016 { 1017 const char *name, *tmp; 1018 struct symbol *sym; 1019 int res, i; 1020 1021 name = conf_get_autoconfig_name(); 1022 tmp = strrchr(name, '/'); 1023 depfile_prefix_len = tmp ? tmp - name + 1 : 0; 1024 if (depfile_prefix_len + 1 > sizeof(depfile_path)) 1025 return -1; 1026 1027 strncpy(depfile_path, name, depfile_prefix_len); 1028 depfile_path[depfile_prefix_len] = 0; 1029 1030 conf_read_simple(name, S_DEF_AUTO); 1031 sym_calc_value(modules_sym); 1032 1033 for_all_symbols(i, sym) { 1034 sym_calc_value(sym); 1035 if ((sym->flags & SYMBOL_NO_WRITE) || !sym->name) 1036 continue; 1037 if (sym->flags & SYMBOL_WRITE) { 1038 if (sym->flags & SYMBOL_DEF_AUTO) { 1039 /* 1040 * symbol has old and new value, 1041 * so compare them... 1042 */ 1043 switch (sym->type) { 1044 case S_BOOLEAN: 1045 case S_TRISTATE: 1046 if (sym_get_tristate_value(sym) == 1047 sym->def[S_DEF_AUTO].tri) 1048 continue; 1049 break; 1050 case S_STRING: 1051 case S_HEX: 1052 case S_INT: 1053 if (!strcmp(sym_get_string_value(sym), 1054 sym->def[S_DEF_AUTO].val)) 1055 continue; 1056 break; 1057 default: 1058 break; 1059 } 1060 } else { 1061 /* 1062 * If there is no old value, only 'no' (unset) 1063 * is allowed as new value. 1064 */ 1065 switch (sym->type) { 1066 case S_BOOLEAN: 1067 case S_TRISTATE: 1068 if (sym_get_tristate_value(sym) == no) 1069 continue; 1070 break; 1071 default: 1072 break; 1073 } 1074 } 1075 } else if (!(sym->flags & SYMBOL_DEF_AUTO)) 1076 /* There is neither an old nor a new value. */ 1077 continue; 1078 /* else 1079 * There is an old value, but no new value ('no' (unset) 1080 * isn't saved in auto.conf, so the old value is always 1081 * different from 'no'). 1082 */ 1083 1084 res = conf_touch_dep(sym->name); 1085 if (res) 1086 return res; 1087 } 1088 1089 return 0; 1090 } 1091 1092 static int __conf_write_autoconf(const char *filename, 1093 void (*print_symbol)(FILE *, struct symbol *), 1094 const struct comment_style *comment_style) 1095 { 1096 char tmp[PATH_MAX]; 1097 FILE *file; 1098 struct symbol *sym; 1099 int ret, i; 1100 1101 if (make_parent_dir(filename)) 1102 return -1; 1103 1104 ret = snprintf(tmp, sizeof(tmp), "%s.tmp", filename); 1105 if (ret >= sizeof(tmp)) /* check truncation */ 1106 return -1; 1107 1108 file = fopen(tmp, "w"); 1109 if (!file) { 1110 perror("fopen"); 1111 return -1; 1112 } 1113 1114 conf_write_heading(file, comment_style); 1115 1116 for_all_symbols(i, sym) 1117 if ((sym->flags & SYMBOL_WRITE) && sym->name) 1118 print_symbol(file, sym); 1119 1120 fflush(file); 1121 /* check possible errors in conf_write_heading() and print_symbol() */ 1122 ret = ferror(file); 1123 fclose(file); 1124 if (ret) 1125 return -1; 1126 1127 if (rename(tmp, filename)) { 1128 perror("rename"); 1129 return -1; 1130 } 1131 1132 return 0; 1133 } 1134 1135 int conf_write_autoconf(int overwrite) 1136 { 1137 struct symbol *sym; 1138 const char *autoconf_name = conf_get_autoconfig_name(); 1139 int ret, i; 1140 1141 if (!overwrite && is_present(autoconf_name)) 1142 return 0; 1143 1144 ret = conf_write_autoconf_cmd(autoconf_name); 1145 if (ret) 1146 return -1; 1147 1148 if (conf_touch_deps()) 1149 return 1; 1150 1151 for_all_symbols(i, sym) 1152 sym_calc_value(sym); 1153 1154 ret = __conf_write_autoconf(conf_get_autoheader_name(), 1155 print_symbol_for_c, 1156 &comment_style_c); 1157 if (ret) 1158 return ret; 1159 1160 ret = __conf_write_autoconf(conf_get_rustccfg_name(), 1161 print_symbol_for_rustccfg, 1162 NULL); 1163 if (ret) 1164 return ret; 1165 1166 /* 1167 * Create include/config/auto.conf. This must be the last step because 1168 * Kbuild has a dependency on auto.conf and this marks the successful 1169 * completion of the previous steps. 1170 */ 1171 ret = __conf_write_autoconf(conf_get_autoconfig_name(), 1172 print_symbol_for_autoconf, 1173 &comment_style_pound); 1174 if (ret) 1175 return ret; 1176 1177 return 0; 1178 } 1179 1180 static bool conf_changed; 1181 static void (*conf_changed_callback)(void); 1182 1183 void conf_set_changed(bool val) 1184 { 1185 bool changed = conf_changed != val; 1186 1187 conf_changed = val; 1188 1189 if (conf_changed_callback && changed) 1190 conf_changed_callback(); 1191 } 1192 1193 bool conf_get_changed(void) 1194 { 1195 return conf_changed; 1196 } 1197 1198 void conf_set_changed_callback(void (*fn)(void)) 1199 { 1200 conf_changed_callback = fn; 1201 } 1202 1203 void set_all_choice_values(struct symbol *csym) 1204 { 1205 struct property *prop; 1206 struct symbol *sym; 1207 struct expr *e; 1208 1209 prop = sym_get_choice_prop(csym); 1210 1211 /* 1212 * Set all non-assinged choice values to no 1213 */ 1214 expr_list_for_each_sym(prop->expr, e, sym) { 1215 if (!sym_has_value(sym)) 1216 sym->def[S_DEF_USER].tri = no; 1217 } 1218 csym->flags |= SYMBOL_DEF_USER; 1219 /* clear VALID to get value calculated */ 1220 csym->flags &= ~(SYMBOL_VALID | SYMBOL_NEED_SET_CHOICE_VALUES); 1221 } 1222