Merge tag 'filelock-v5.4-1' of git://git.kernel.org/pub/scm/linux/kernel/git/jlayton...
[linux-2.6-block.git] / scripts / kconfig / conf.c
CommitLineData
0c874100 1// SPDX-License-Identifier: GPL-2.0
1da177e4
LT
2/*
3 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
1da177e4
LT
4 */
5
6#include <ctype.h>
74dba809 7#include <limits.h>
9dfb563b 8#include <stdio.h>
75ff4309 9#include <stdlib.h>
1da177e4 10#include <string.h>
1da177e4 11#include <time.h>
75ff4309 12#include <unistd.h>
4062f1a4 13#include <getopt.h>
1da177e4 14#include <sys/stat.h>
b0fe5510 15#include <sys/time.h>
0d8024c6 16#include <errno.h>
1da177e4 17
1da177e4
LT
18#include "lkc.h"
19
20static void conf(struct menu *menu);
21static void check_conf(struct menu *menu);
22
4062f1a4
SR
23enum input_mode {
24 oldaskconfig,
911a91c3 25 syncconfig,
4062f1a4
SR
26 oldconfig,
27 allnoconfig,
28 allyesconfig,
29 allmodconfig,
0748cb3e 30 alldefconfig,
4062f1a4
SR
31 randconfig,
32 defconfig,
7cf3d73b 33 savedefconfig,
861b4ea4 34 listnewconfig,
fb16d891 35 olddefconfig,
52e58a3c
MY
36};
37static enum input_mode input_mode = oldaskconfig;
4062f1a4 38
1da177e4 39static int indent = 1;
62dc9899 40static int tty_stdio;
204c96f6 41static int sync_kconfig;
1da177e4 42static int conf_cnt;
74dba809 43static char line[PATH_MAX];
1da177e4
LT
44static struct menu *rootEntry;
45
66c4bd80 46static void print_help(struct menu *menu)
03d29122 47{
66c4bd80
CR
48 struct gstr help = str_new();
49
50 menu_get_ext_help(menu, &help);
51
52 printf("\n%s\n", str_get(&help));
53 str_free(&help);
03d29122
SR
54}
55
48b9d03c 56static void strip(char *str)
1da177e4 57{
48b9d03c 58 char *p = str;
1da177e4
LT
59 int l;
60
61 while ((isspace(*p)))
62 p++;
63 l = strlen(p);
64 if (p != str)
65 memmove(str, p, l + 1);
66 if (!l)
67 return;
68 p = str + l - 1;
69 while ((isspace(*p)))
70 *p-- = 0;
71}
72
5a3dc717
MY
73/* Helper function to facilitate fgets() by Jean Sacren. */
74static void xfgets(char *str, int size, FILE *in)
75{
76 if (!fgets(str, size, in))
77 fprintf(stderr, "\nError in reading or end of file.\n");
f3ff6fb5
MY
78
79 if (!tty_stdio)
80 printf("%s", str);
5a3dc717
MY
81}
82
f82f3f94 83static int conf_askvalue(struct symbol *sym, const char *def)
1da177e4
LT
84{
85 enum symbol_type type = sym_get_type(sym);
1da177e4
LT
86
87 if (!sym_has_value(sym))
694c49a7 88 printf("(NEW) ");
1da177e4
LT
89
90 line[0] = '\n';
91 line[1] = 0;
92
baa23ec8 93 if (!sym_is_changeable(sym)) {
1da177e4
LT
94 printf("%s\n", def);
95 line[0] = '\n';
96 line[1] = 0;
f82f3f94 97 return 0;
1da177e4
LT
98 }
99
100 switch (input_mode) {
4062f1a4 101 case oldconfig:
911a91c3 102 case syncconfig:
1da177e4
LT
103 if (sym_has_value(sym)) {
104 printf("%s\n", def);
f82f3f94 105 return 0;
1da177e4 106 }
d8fc3200 107 /* fall through */
4062f1a4 108 case oldaskconfig:
1da177e4 109 fflush(stdout);
74dba809 110 xfgets(line, sizeof(line), stdin);
f82f3f94 111 return 1;
1da177e4
LT
112 default:
113 break;
114 }
115
116 switch (type) {
117 case S_INT:
118 case S_HEX:
119 case S_STRING:
120 printf("%s\n", def);
f82f3f94 121 return 1;
1da177e4
LT
122 default:
123 ;
124 }
1da177e4 125 printf("%s", line);
f82f3f94 126 return 1;
1da177e4
LT
127}
128
4356f489 129static int conf_string(struct menu *menu)
1da177e4
LT
130{
131 struct symbol *sym = menu->sym;
03d29122 132 const char *def;
1da177e4
LT
133
134 while (1) {
694c49a7 135 printf("%*s%s ", indent - 1, "", menu->prompt->text);
1da177e4
LT
136 printf("(%s) ", sym->name);
137 def = sym_get_string_value(sym);
138 if (sym_get_string_value(sym))
139 printf("[%s] ", def);
f82f3f94
RZ
140 if (!conf_askvalue(sym, def))
141 return 0;
1da177e4
LT
142 switch (line[0]) {
143 case '\n':
144 break;
145 case '?':
146 /* print help */
147 if (line[1] == '\n') {
66c4bd80 148 print_help(menu);
1da177e4
LT
149 def = NULL;
150 break;
151 }
d8fc3200 152 /* fall through */
1da177e4
LT
153 default:
154 line[strlen(line)-1] = 0;
155 def = line;
156 }
157 if (def && sym_set_string_value(sym, def))
158 return 0;
159 }
160}
161
162static int conf_sym(struct menu *menu)
163{
164 struct symbol *sym = menu->sym;
1da177e4 165 tristate oldval, newval;
1da177e4
LT
166
167 while (1) {
694c49a7 168 printf("%*s%s ", indent - 1, "", menu->prompt->text);
1da177e4
LT
169 if (sym->name)
170 printf("(%s) ", sym->name);
1da177e4
LT
171 putchar('[');
172 oldval = sym_get_tristate_value(sym);
173 switch (oldval) {
174 case no:
175 putchar('N');
176 break;
177 case mod:
178 putchar('M');
179 break;
180 case yes:
181 putchar('Y');
182 break;
183 }
184 if (oldval != no && sym_tristate_within_range(sym, no))
185 printf("/n");
186 if (oldval != mod && sym_tristate_within_range(sym, mod))
187 printf("/m");
188 if (oldval != yes && sym_tristate_within_range(sym, yes))
189 printf("/y");
4f208f39 190 printf("/?] ");
f82f3f94
RZ
191 if (!conf_askvalue(sym, sym_get_string_value(sym)))
192 return 0;
1da177e4
LT
193 strip(line);
194
195 switch (line[0]) {
196 case 'n':
197 case 'N':
198 newval = no;
199 if (!line[1] || !strcmp(&line[1], "o"))
200 break;
201 continue;
202 case 'm':
203 case 'M':
204 newval = mod;
205 if (!line[1])
206 break;
207 continue;
208 case 'y':
209 case 'Y':
210 newval = yes;
211 if (!line[1] || !strcmp(&line[1], "es"))
212 break;
213 continue;
214 case 0:
215 newval = oldval;
216 break;
217 case '?':
218 goto help;
219 default:
220 continue;
221 }
222 if (sym_set_tristate_value(sym, newval))
223 return 0;
224help:
66c4bd80 225 print_help(menu);
1da177e4
LT
226 }
227}
228
229static int conf_choice(struct menu *menu)
230{
231 struct symbol *sym, *def_sym;
232 struct menu *child;
1da177e4
LT
233 bool is_new;
234
235 sym = menu->sym;
1da177e4 236 is_new = !sym_has_value(sym);
baa23ec8 237 if (sym_is_changeable(sym)) {
1da177e4
LT
238 conf_sym(menu);
239 sym_calc_value(sym);
240 switch (sym_get_tristate_value(sym)) {
241 case no:
242 return 1;
243 case mod:
244 return 0;
245 case yes:
246 break;
247 }
248 } else {
249 switch (sym_get_tristate_value(sym)) {
250 case no:
251 return 1;
252 case mod:
694c49a7 253 printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
1da177e4
LT
254 return 0;
255 case yes:
256 break;
257 }
258 }
259
260 while (1) {
261 int cnt, def;
262
694c49a7 263 printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
1da177e4
LT
264 def_sym = sym_get_choice_value(sym);
265 cnt = def = 0;
40aee729 266 line[0] = 0;
1da177e4
LT
267 for (child = menu->list; child; child = child->next) {
268 if (!menu_is_visible(child))
269 continue;
270 if (!child->sym) {
694c49a7 271 printf("%*c %s\n", indent, '*', menu_get_prompt(child));
1da177e4
LT
272 continue;
273 }
274 cnt++;
275 if (child->sym == def_sym) {
276 def = cnt;
277 printf("%*c", indent, '>');
278 } else
279 printf("%*c", indent, ' ');
694c49a7 280 printf(" %d. %s", cnt, menu_get_prompt(child));
1da177e4
LT
281 if (child->sym->name)
282 printf(" (%s)", child->sym->name);
283 if (!sym_has_value(child->sym))
694c49a7 284 printf(" (NEW)");
1da177e4
LT
285 printf("\n");
286 }
694c49a7 287 printf("%*schoice", indent - 1, "");
1da177e4
LT
288 if (cnt == 1) {
289 printf("[1]: 1\n");
290 goto conf_childs;
291 }
4f208f39 292 printf("[1-%d?]: ", cnt);
1da177e4 293 switch (input_mode) {
4062f1a4 294 case oldconfig:
911a91c3 295 case syncconfig:
1da177e4
LT
296 if (!is_new) {
297 cnt = def;
298 printf("%d\n", cnt);
299 break;
300 }
d8fc3200 301 /* fall through */
4062f1a4 302 case oldaskconfig:
1da177e4 303 fflush(stdout);
74dba809 304 xfgets(line, sizeof(line), stdin);
1da177e4
LT
305 strip(line);
306 if (line[0] == '?') {
66c4bd80 307 print_help(menu);
1da177e4
LT
308 continue;
309 }
310 if (!line[0])
311 cnt = def;
312 else if (isdigit(line[0]))
313 cnt = atoi(line);
314 else
315 continue;
316 break;
f443d2ec
SR
317 default:
318 break;
1da177e4
LT
319 }
320
321 conf_childs:
322 for (child = menu->list; child; child = child->next) {
323 if (!child->sym || !menu_is_visible(child))
324 continue;
325 if (!--cnt)
326 break;
327 }
328 if (!child)
329 continue;
3ba41621 330 if (line[0] && line[strlen(line) - 1] == '?') {
66c4bd80 331 print_help(child);
1da177e4
LT
332 continue;
333 }
334 sym_set_choice_value(sym, child->sym);
f5eaa323 335 for (child = child->list; child; child = child->next) {
1da177e4 336 indent += 2;
f5eaa323 337 conf(child);
1da177e4
LT
338 indent -= 2;
339 }
340 return 1;
341 }
342}
343
344static void conf(struct menu *menu)
345{
346 struct symbol *sym;
347 struct property *prop;
348 struct menu *child;
349
350 if (!menu_is_visible(menu))
351 return;
352
353 sym = menu->sym;
354 prop = menu->prompt;
355 if (prop) {
356 const char *prompt;
357
358 switch (prop->type) {
359 case P_MENU:
2aad9b89
MY
360 /*
361 * Except in oldaskconfig mode, we show only menus that
362 * contain new symbols.
363 */
364 if (input_mode != oldaskconfig && rootEntry != menu) {
1da177e4
LT
365 check_conf(menu);
366 return;
367 }
d8fc3200 368 /* fall through */
1da177e4
LT
369 case P_COMMENT:
370 prompt = menu_get_prompt(menu);
371 if (prompt)
372 printf("%*c\n%*c %s\n%*c\n",
373 indent, '*',
694c49a7 374 indent, '*', prompt,
1da177e4
LT
375 indent, '*');
376 default:
377 ;
378 }
379 }
380
381 if (!sym)
382 goto conf_childs;
383
384 if (sym_is_choice(sym)) {
385 conf_choice(menu);
386 if (sym->curr.tri != mod)
387 return;
388 goto conf_childs;
389 }
390
391 switch (sym->type) {
392 case S_INT:
393 case S_HEX:
394 case S_STRING:
395 conf_string(menu);
396 break;
397 default:
398 conf_sym(menu);
399 break;
400 }
401
402conf_childs:
403 if (sym)
404 indent += 2;
405 for (child = menu->list; child; child = child->next)
406 conf(child);
407 if (sym)
408 indent -= 2;
409}
410
411static void check_conf(struct menu *menu)
412{
413 struct symbol *sym;
414 struct menu *child;
415
416 if (!menu_is_visible(menu))
417 return;
418
419 sym = menu->sym;
3f23ca2b 420 if (sym && !sym_has_value(sym)) {
baa23ec8 421 if (sym_is_changeable(sym) ||
3f23ca2b 422 (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) {
861b4ea4 423 if (input_mode == listnewconfig) {
17baab68
DZ
424 if (sym->name) {
425 const char *str;
426
427 if (sym->type == S_STRING) {
428 str = sym_get_string_value(sym);
429 str = sym_escape_string_value(str);
430 printf("%s%s=%s\n", CONFIG_, sym->name, str);
431 free((void *)str);
432 } else {
433 str = sym_get_string_value(sym);
434 printf("%s%s=%s\n", CONFIG_, sym->name, str);
435 }
f0778c8c 436 }
59a80b5e 437 } else {
f0778c8c 438 if (!conf_cnt++)
694c49a7 439 printf("*\n* Restart config...\n*\n");
f0778c8c
AR
440 rootEntry = menu_get_parent_menu(menu);
441 conf(rootEntry);
442 }
1da177e4 443 }
1da177e4
LT
444 }
445
446 for (child = menu->list; child; child = child->next)
447 check_conf(child);
448}
449
4062f1a4
SR
450static struct option long_opts[] = {
451 {"oldaskconfig", no_argument, NULL, oldaskconfig},
452 {"oldconfig", no_argument, NULL, oldconfig},
911a91c3 453 {"syncconfig", no_argument, NULL, syncconfig},
b6f7e9f7 454 {"defconfig", required_argument, NULL, defconfig},
7cf3d73b 455 {"savedefconfig", required_argument, NULL, savedefconfig},
4062f1a4
SR
456 {"allnoconfig", no_argument, NULL, allnoconfig},
457 {"allyesconfig", no_argument, NULL, allyesconfig},
458 {"allmodconfig", no_argument, NULL, allmodconfig},
0748cb3e 459 {"alldefconfig", no_argument, NULL, alldefconfig},
4062f1a4 460 {"randconfig", no_argument, NULL, randconfig},
861b4ea4 461 {"listnewconfig", no_argument, NULL, listnewconfig},
fb16d891 462 {"olddefconfig", no_argument, NULL, olddefconfig},
4062f1a4
SR
463 {NULL, 0, NULL, 0}
464};
465
32543999
AL
466static void conf_usage(const char *progname)
467{
468
0a1f00a1 469 printf("Usage: %s [-s] [option] <kconfig-file>\n", progname);
32543999
AL
470 printf("[option] is _one_ of the following:\n");
471 printf(" --listnewconfig List new options\n");
472 printf(" --oldaskconfig Start a new configuration using a line-oriented program\n");
473 printf(" --oldconfig Update a configuration using a provided .config as base\n");
911a91c3
MY
474 printf(" --syncconfig Similar to oldconfig but generates configuration in\n"
475 " include/{generated/,config/}\n");
cedd55d4 476 printf(" --olddefconfig Same as oldconfig but sets new symbols to their default value\n");
32543999
AL
477 printf(" --defconfig <file> New config with default defined in <file>\n");
478 printf(" --savedefconfig <file> Save the minimal current configuration to <file>\n");
479 printf(" --allnoconfig New config where all options are answered with no\n");
480 printf(" --allyesconfig New config where all options are answered with yes\n");
481 printf(" --allmodconfig New config where all options are answered with mod\n");
482 printf(" --alldefconfig New config with all symbols set to default\n");
483 printf(" --randconfig New config with random answer to all options\n");
484}
485
1da177e4
LT
486int main(int ac, char **av)
487{
32543999 488 const char *progname = av[0];
2f4b489b 489 int opt;
275744cc 490 const char *name, *defconfig_file = NULL /* gcc uninit */;
16952b77 491 int no_conf_write = 0;
1da177e4 492
f3ff6fb5 493 tty_stdio = isatty(0) && isatty(1);
62dc9899 494
0a1f00a1
MM
495 while ((opt = getopt_long(ac, av, "s", long_opts, NULL)) != -1) {
496 if (opt == 's') {
497 conf_set_message_callback(NULL);
498 continue;
499 }
4062f1a4 500 input_mode = (enum input_mode)opt;
2f4b489b 501 switch (opt) {
911a91c3 502 case syncconfig:
9a9ddcf4
MY
503 /*
504 * syncconfig is invoked during the build stage.
505 * Suppress distracting "configuration written to ..."
506 */
507 conf_set_message_callback(NULL);
204c96f6 508 sync_kconfig = 1;
1da177e4 509 break;
4062f1a4 510 case defconfig:
7cf3d73b 511 case savedefconfig:
2f4b489b 512 defconfig_file = optarg;
1da177e4 513 break;
4062f1a4 514 case randconfig:
b0fe5510
IM
515 {
516 struct timeval now;
517 unsigned int seed;
0d8024c6 518 char *seed_env;
b0fe5510
IM
519
520 /*
521 * Use microseconds derived seed,
522 * compensate for systems where it may be zero
523 */
524 gettimeofday(&now, NULL);
b0fe5510 525 seed = (unsigned int)((now.tv_sec + 1) * (now.tv_usec + 1));
0d8024c6
YM
526
527 seed_env = getenv("KCONFIG_SEED");
528 if( seed_env && *seed_env ) {
529 char *endp;
e85ac124 530 int tmp = (int)strtol(seed_env, &endp, 0);
0d8024c6
YM
531 if (*endp == '\0') {
532 seed = tmp;
533 }
534 }
a5f6d795 535 fprintf( stderr, "KCONFIG_SEED=0x%X\n", seed );
b0fe5510 536 srand(seed);
1da177e4 537 break;
b0fe5510 538 }
32543999
AL
539 case oldaskconfig:
540 case oldconfig:
541 case allnoconfig:
542 case allyesconfig:
543 case allmodconfig:
544 case alldefconfig:
545 case listnewconfig:
fb16d891 546 case olddefconfig:
32543999 547 break;
4062f1a4 548 case '?':
32543999 549 conf_usage(progname);
2f4b489b 550 exit(1);
4062f1a4 551 break;
1da177e4
LT
552 }
553 }
2f4b489b 554 if (ac == optind) {
694c49a7 555 fprintf(stderr, "%s: Kconfig file missing\n", av[0]);
32543999 556 conf_usage(progname);
250725aa 557 exit(1);
1da177e4 558 }
2f4b489b 559 name = av[optind];
1da177e4
LT
560 conf_parse(name);
561 //zconfdump(stdout);
204c96f6 562
1da177e4 563 switch (input_mode) {
4062f1a4 564 case defconfig:
1da177e4 565 if (conf_read(defconfig_file)) {
9e3e10c7 566 fprintf(stderr,
694c49a7 567 "***\n"
9e3e10c7 568 "*** Can't find default configuration \"%s\"!\n"
694c49a7 569 "***\n",
9e3e10c7 570 defconfig_file);
1da177e4
LT
571 exit(1);
572 }
573 break;
7cf3d73b 574 case savedefconfig:
911a91c3 575 case syncconfig:
4062f1a4
SR
576 case oldaskconfig:
577 case oldconfig:
861b4ea4 578 case listnewconfig:
fb16d891 579 case olddefconfig:
1da177e4
LT
580 conf_read(NULL);
581 break;
4062f1a4
SR
582 case allnoconfig:
583 case allyesconfig:
584 case allmodconfig:
0748cb3e 585 case alldefconfig:
4062f1a4 586 case randconfig:
90389160 587 name = getenv("KCONFIG_ALLCONFIG");
9f420bf0
EB
588 if (!name)
589 break;
590 if ((strcmp(name, "") != 0) && (strcmp(name, "1") != 0)) {
5efe241e
EB
591 if (conf_read_simple(name, S_DEF_USER)) {
592 fprintf(stderr,
694c49a7 593 "*** Can't read seed configuration \"%s\"!\n",
5efe241e
EB
594 name);
595 exit(1);
596 }
90389160
RZ
597 break;
598 }
599 switch (input_mode) {
4062f1a4
SR
600 case allnoconfig: name = "allno.config"; break;
601 case allyesconfig: name = "allyes.config"; break;
602 case allmodconfig: name = "allmod.config"; break;
0748cb3e 603 case alldefconfig: name = "alldef.config"; break;
4062f1a4 604 case randconfig: name = "allrandom.config"; break;
90389160
RZ
605 default: break;
606 }
5efe241e
EB
607 if (conf_read_simple(name, S_DEF_USER) &&
608 conf_read_simple("all.config", S_DEF_USER)) {
609 fprintf(stderr,
694c49a7 610 "*** KCONFIG_ALLCONFIG set, but no \"%s\" or \"all.config\" file found\n",
5efe241e
EB
611 name);
612 exit(1);
613 }
90389160 614 break;
1da177e4
LT
615 default:
616 break;
617 }
204c96f6 618
619 if (sync_kconfig) {
16952b77
MY
620 name = getenv("KCONFIG_NOSILENTUPDATE");
621 if (name && *name) {
622 if (conf_get_changed()) {
204c96f6 623 fprintf(stderr,
694c49a7 624 "\n*** The configuration requires explicit update.\n\n");
204c96f6 625 return 1;
626 }
16952b77 627 no_conf_write = 1;
204c96f6 628 }
204c96f6 629 }
630
f443d2ec 631 switch (input_mode) {
4062f1a4 632 case allnoconfig:
f443d2ec
SR
633 conf_set_all_new_symbols(def_no);
634 break;
4062f1a4 635 case allyesconfig:
f443d2ec
SR
636 conf_set_all_new_symbols(def_yes);
637 break;
4062f1a4 638 case allmodconfig:
f443d2ec
SR
639 conf_set_all_new_symbols(def_mod);
640 break;
0748cb3e
SR
641 case alldefconfig:
642 conf_set_all_new_symbols(def_default);
643 break;
4062f1a4 644 case randconfig:
3b9a19e0
YM
645 /* Really nothing to do in this loop */
646 while (conf_set_all_new_symbols(def_random)) ;
f443d2ec 647 break;
4062f1a4 648 case defconfig:
09748e17
SR
649 conf_set_all_new_symbols(def_default);
650 break;
7cf3d73b
SR
651 case savedefconfig:
652 break;
4062f1a4 653 case oldaskconfig:
204c96f6 654 rootEntry = &rootmenu;
655 conf(&rootmenu);
2aad9b89 656 input_mode = oldconfig;
204c96f6 657 /* fall through */
14828349 658 case oldconfig:
861b4ea4 659 case listnewconfig:
911a91c3 660 case syncconfig:
204c96f6 661 /* Update until a loop caused no more changes */
662 do {
663 conf_cnt = 0;
664 check_conf(&rootmenu);
99f0b657 665 } while (conf_cnt);
59a80b5e
MY
666 break;
667 case olddefconfig:
668 default:
f443d2ec
SR
669 break;
670 }
1da177e4 671
00c864f8 672 if (input_mode == savedefconfig) {
7cf3d73b 673 if (conf_write_defconfig(defconfig_file)) {
694c49a7 674 fprintf(stderr, "n*** Error while saving defconfig to: %s\n\n",
bb66fc67 675 defconfig_file);
7cf3d73b
SR
676 return 1;
677 }
861b4ea4 678 } else if (input_mode != listnewconfig) {
00c864f8 679 if (!no_conf_write && conf_write(NULL)) {
694c49a7 680 fprintf(stderr, "\n*** Error during writing of the configuration.\n\n");
204c96f6 681 exit(1);
682 }
00c864f8
MY
683
684 /*
685 * Create auto.conf if it does not exist.
686 * This prevents GNU Make 4.1 or older from emitting
687 * "include/config/auto.conf: No such file or directory"
688 * in the top-level Makefile
689 *
690 * syncconfig always creates or updates auto.conf because it is
691 * used during the build.
692 */
693 if (conf_write_autoconf(sync_kconfig) && sync_kconfig) {
694 fprintf(stderr,
695 "\n*** Error during sync of the configuration.\n\n");
696 return 1;
697 }
c955ccaf 698 }
861b4ea4 699 return 0;
1da177e4 700}