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