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