]> bbs.cooldavid.org Git - net-next-2.6.git/blame - scripts/kconfig/conf.c
kconfig: change nonint_oldconfig to listnewconfig
[net-next-2.6.git] / scripts / kconfig / conf.c
CommitLineData
1da177e4
LT
1/*
2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0.
4 */
5
534a450c 6#include <locale.h>
1da177e4 7#include <ctype.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>
1da177e4
LT
16
17#define LKC_DIRECT_LINK
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,
25 silentoldconfig,
26 oldconfig,
27 allnoconfig,
28 allyesconfig,
29 allmodconfig,
30 randconfig,
31 defconfig,
861b4ea4 32 listnewconfig,
ef61ca88 33 oldnoconfig,
4062f1a4
SR
34} input_mode = oldaskconfig;
35
1da177e4
LT
36char *defconfig_file;
37
38static int indent = 1;
39static int valid_stdin = 1;
204c96f6 40static int sync_kconfig;
1da177e4 41static int conf_cnt;
48b9d03c 42static char line[128];
1da177e4
LT
43static struct menu *rootEntry;
44
66c4bd80 45static void print_help(struct menu *menu)
03d29122 46{
66c4bd80
CR
47 struct gstr help = str_new();
48
49 menu_get_ext_help(menu, &help);
50
51 printf("\n%s\n", str_get(&help));
52 str_free(&help);
03d29122
SR
53}
54
48b9d03c 55static void strip(char *str)
1da177e4 56{
48b9d03c 57 char *p = str;
1da177e4
LT
58 int l;
59
60 while ((isspace(*p)))
61 p++;
62 l = strlen(p);
63 if (p != str)
64 memmove(str, p, l + 1);
65 if (!l)
66 return;
67 p = str + l - 1;
68 while ((isspace(*p)))
69 *p-- = 0;
70}
71
72static void check_stdin(void)
73{
204c96f6 74 if (!valid_stdin) {
3b9fa093
ACM
75 printf(_("aborted!\n\n"));
76 printf(_("Console input/output is redirected. "));
77 printf(_("Run 'make oldconfig' to update configuration.\n\n"));
1da177e4
LT
78 exit(1);
79 }
80}
81
f82f3f94 82static int conf_askvalue(struct symbol *sym, const char *def)
1da177e4
LT
83{
84 enum symbol_type type = sym_get_type(sym);
1da177e4
LT
85
86 if (!sym_has_value(sym))
534a450c 87 printf(_("(NEW) "));
1da177e4
LT
88
89 line[0] = '\n';
90 line[1] = 0;
91
92 if (!sym_is_changable(sym)) {
93 printf("%s\n", def);
94 line[0] = '\n';
95 line[1] = 0;
f82f3f94 96 return 0;
1da177e4
LT
97 }
98
99 switch (input_mode) {
4062f1a4
SR
100 case oldconfig:
101 case silentoldconfig:
1da177e4
LT
102 if (sym_has_value(sym)) {
103 printf("%s\n", def);
f82f3f94 104 return 0;
1da177e4
LT
105 }
106 check_stdin();
4062f1a4 107 case oldaskconfig:
1da177e4 108 fflush(stdout);
59c6a3f4 109 fgets(line, 128, stdin);
f82f3f94 110 return 1;
1da177e4
LT
111 default:
112 break;
113 }
114
115 switch (type) {
116 case S_INT:
117 case S_HEX:
118 case S_STRING:
119 printf("%s\n", def);
f82f3f94 120 return 1;
1da177e4
LT
121 default:
122 ;
123 }
1da177e4 124 printf("%s", line);
f82f3f94 125 return 1;
1da177e4
LT
126}
127
4356f489 128static int conf_string(struct menu *menu)
1da177e4
LT
129{
130 struct symbol *sym = menu->sym;
03d29122 131 const char *def;
1da177e4
LT
132
133 while (1) {
534a450c 134 printf("%*s%s ", indent - 1, "", _(menu->prompt->text));
1da177e4
LT
135 printf("(%s) ", sym->name);
136 def = sym_get_string_value(sym);
137 if (sym_get_string_value(sym))
138 printf("[%s] ", def);
f82f3f94
RZ
139 if (!conf_askvalue(sym, def))
140 return 0;
1da177e4
LT
141 switch (line[0]) {
142 case '\n':
143 break;
144 case '?':
145 /* print help */
146 if (line[1] == '\n') {
66c4bd80 147 print_help(menu);
1da177e4
LT
148 def = NULL;
149 break;
150 }
151 default:
152 line[strlen(line)-1] = 0;
153 def = line;
154 }
155 if (def && sym_set_string_value(sym, def))
156 return 0;
157 }
158}
159
160static int conf_sym(struct menu *menu)
161{
162 struct symbol *sym = menu->sym;
1da177e4 163 tristate oldval, newval;
1da177e4
LT
164
165 while (1) {
534a450c 166 printf("%*s%s ", indent - 1, "", _(menu->prompt->text));
1da177e4
LT
167 if (sym->name)
168 printf("(%s) ", sym->name);
1da177e4
LT
169 putchar('[');
170 oldval = sym_get_tristate_value(sym);
171 switch (oldval) {
172 case no:
173 putchar('N');
174 break;
175 case mod:
176 putchar('M');
177 break;
178 case yes:
179 putchar('Y');
180 break;
181 }
182 if (oldval != no && sym_tristate_within_range(sym, no))
183 printf("/n");
184 if (oldval != mod && sym_tristate_within_range(sym, mod))
185 printf("/m");
186 if (oldval != yes && sym_tristate_within_range(sym, yes))
187 printf("/y");
03d29122 188 if (menu_has_help(menu))
1da177e4
LT
189 printf("/?");
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
LT
236 is_new = !sym_has_value(sym);
237 if (sym_is_changable(sym)) {
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:
534a450c 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
534a450c 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) {
534a450c 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, ' ');
534a450c 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))
534a450c 284 printf(_(" (NEW)"));
1da177e4
LT
285 printf("\n");
286 }
534a450c 287 printf(_("%*schoice"), indent - 1, "");
1da177e4
LT
288 if (cnt == 1) {
289 printf("[1]: 1\n");
290 goto conf_childs;
291 }
292 printf("[1-%d", cnt);
03d29122 293 if (menu_has_help(menu))
1da177e4
LT
294 printf("?");
295 printf("]: ");
296 switch (input_mode) {
4062f1a4
SR
297 case oldconfig:
298 case silentoldconfig:
1da177e4
LT
299 if (!is_new) {
300 cnt = def;
301 printf("%d\n", cnt);
302 break;
303 }
304 check_stdin();
4062f1a4 305 case oldaskconfig:
1da177e4 306 fflush(stdout);
59c6a3f4 307 fgets(line, 128, stdin);
1da177e4
LT
308 strip(line);
309 if (line[0] == '?') {
66c4bd80 310 print_help(menu);
1da177e4
LT
311 continue;
312 }
313 if (!line[0])
314 cnt = def;
315 else if (isdigit(line[0]))
316 cnt = atoi(line);
317 else
318 continue;
319 break;
f443d2ec
SR
320 default:
321 break;
1da177e4
LT
322 }
323
324 conf_childs:
325 for (child = menu->list; child; child = child->next) {
326 if (!child->sym || !menu_is_visible(child))
327 continue;
328 if (!--cnt)
329 break;
330 }
331 if (!child)
332 continue;
333 if (line[strlen(line) - 1] == '?') {
66c4bd80 334 print_help(child);
1da177e4
LT
335 continue;
336 }
337 sym_set_choice_value(sym, child->sym);
f5eaa323 338 for (child = child->list; child; child = child->next) {
1da177e4 339 indent += 2;
f5eaa323 340 conf(child);
1da177e4
LT
341 indent -= 2;
342 }
343 return 1;
344 }
345}
346
347static void conf(struct menu *menu)
348{
349 struct symbol *sym;
350 struct property *prop;
351 struct menu *child;
352
353 if (!menu_is_visible(menu))
354 return;
355
356 sym = menu->sym;
357 prop = menu->prompt;
358 if (prop) {
359 const char *prompt;
360
361 switch (prop->type) {
362 case P_MENU:
4062f1a4 363 if ((input_mode == silentoldconfig ||
861b4ea4 364 input_mode == listnewconfig ||
ef61ca88 365 input_mode == oldnoconfig) &&
f0778c8c 366 rootEntry != menu) {
1da177e4
LT
367 check_conf(menu);
368 return;
369 }
370 case P_COMMENT:
371 prompt = menu_get_prompt(menu);
372 if (prompt)
373 printf("%*c\n%*c %s\n%*c\n",
374 indent, '*',
534a450c 375 indent, '*', _(prompt),
1da177e4
LT
376 indent, '*');
377 default:
378 ;
379 }
380 }
381
382 if (!sym)
383 goto conf_childs;
384
385 if (sym_is_choice(sym)) {
386 conf_choice(menu);
387 if (sym->curr.tri != mod)
388 return;
389 goto conf_childs;
390 }
391
392 switch (sym->type) {
393 case S_INT:
394 case S_HEX:
395 case S_STRING:
396 conf_string(menu);
397 break;
398 default:
399 conf_sym(menu);
400 break;
401 }
402
403conf_childs:
404 if (sym)
405 indent += 2;
406 for (child = menu->list; child; child = child->next)
407 conf(child);
408 if (sym)
409 indent -= 2;
410}
411
412static void check_conf(struct menu *menu)
413{
414 struct symbol *sym;
415 struct menu *child;
416
417 if (!menu_is_visible(menu))
418 return;
419
420 sym = menu->sym;
3f23ca2b
RZ
421 if (sym && !sym_has_value(sym)) {
422 if (sym_is_changable(sym) ||
423 (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) {
861b4ea4
SR
424 if (input_mode == listnewconfig) {
425 if (sym->name && !sym_is_choice_value(sym)) {
426 printf("CONFIG_%s\n", sym->name);
f0778c8c
AR
427 }
428 } else {
429 if (!conf_cnt++)
430 printf(_("*\n* Restart config...\n*\n"));
431 rootEntry = menu_get_parent_menu(menu);
432 conf(rootEntry);
433 }
1da177e4 434 }
1da177e4
LT
435 }
436
437 for (child = menu->list; child; child = child->next)
438 check_conf(child);
439}
440
4062f1a4
SR
441static struct option long_opts[] = {
442 {"oldaskconfig", no_argument, NULL, oldaskconfig},
443 {"oldconfig", no_argument, NULL, oldconfig},
444 {"silentoldconfig", no_argument, NULL, silentoldconfig},
445 {"defconfig", optional_argument, NULL, defconfig},
446 {"allnoconfig", no_argument, NULL, allnoconfig},
447 {"allyesconfig", no_argument, NULL, allyesconfig},
448 {"allmodconfig", no_argument, NULL, allmodconfig},
449 {"randconfig", no_argument, NULL, randconfig},
861b4ea4 450 {"listnewconfig", no_argument, NULL, listnewconfig},
ef61ca88 451 {"oldnoconfig", no_argument, NULL, oldnoconfig},
4062f1a4
SR
452 {NULL, 0, NULL, 0}
453};
454
1da177e4
LT
455int main(int ac, char **av)
456{
2f4b489b 457 int opt;
1da177e4
LT
458 const char *name;
459 struct stat tmpstat;
460
534a450c
EG
461 setlocale(LC_ALL, "");
462 bindtextdomain(PACKAGE, LOCALEDIR);
463 textdomain(PACKAGE);
464
4062f1a4
SR
465 while ((opt = getopt_long_only(ac, av, "", long_opts, NULL)) != -1) {
466 input_mode = (enum input_mode)opt;
2f4b489b 467 switch (opt) {
4062f1a4 468 case silentoldconfig:
204c96f6 469 sync_kconfig = 1;
1da177e4 470 break;
4062f1a4 471 case defconfig:
2f4b489b 472 defconfig_file = optarg;
1da177e4 473 break;
4062f1a4 474 case randconfig:
b0fe5510
IM
475 {
476 struct timeval now;
477 unsigned int seed;
478
479 /*
480 * Use microseconds derived seed,
481 * compensate for systems where it may be zero
482 */
483 gettimeofday(&now, NULL);
484
485 seed = (unsigned int)((now.tv_sec + 1) * (now.tv_usec + 1));
486 srand(seed);
1da177e4 487 break;
b0fe5510 488 }
4062f1a4 489 case '?':
534a450c 490 fprintf(stderr, _("See README for usage info\n"));
2f4b489b 491 exit(1);
4062f1a4 492 break;
1da177e4
LT
493 }
494 }
2f4b489b 495 if (ac == optind) {
3b9fa093 496 printf(_("%s: Kconfig file missing\n"), av[0]);
250725aa 497 exit(1);
1da177e4 498 }
2f4b489b 499 name = av[optind];
1da177e4
LT
500 conf_parse(name);
501 //zconfdump(stdout);
204c96f6 502 if (sync_kconfig) {
284026cd
MH
503 name = conf_get_configname();
504 if (stat(name, &tmpstat)) {
204c96f6 505 fprintf(stderr, _("***\n"
506 "*** You have not yet configured your kernel!\n"
284026cd 507 "*** (missing kernel config file \"%s\")\n"
204c96f6 508 "***\n"
509 "*** Please run some configurator (e.g. \"make oldconfig\" or\n"
510 "*** \"make menuconfig\" or \"make xconfig\").\n"
284026cd 511 "***\n"), name);
204c96f6 512 exit(1);
513 }
514 }
515
1da177e4 516 switch (input_mode) {
4062f1a4 517 case defconfig:
1da177e4
LT
518 if (!defconfig_file)
519 defconfig_file = conf_get_default_confname();
520 if (conf_read(defconfig_file)) {
534a450c 521 printf(_("***\n"
1da177e4 522 "*** Can't find default configuration \"%s\"!\n"
534a450c 523 "***\n"), defconfig_file);
1da177e4
LT
524 exit(1);
525 }
526 break;
4062f1a4
SR
527 case silentoldconfig:
528 case oldaskconfig:
529 case oldconfig:
861b4ea4 530 case listnewconfig:
ef61ca88 531 case oldnoconfig:
1da177e4
LT
532 conf_read(NULL);
533 break;
4062f1a4
SR
534 case allnoconfig:
535 case allyesconfig:
536 case allmodconfig:
537 case randconfig:
90389160
RZ
538 name = getenv("KCONFIG_ALLCONFIG");
539 if (name && !stat(name, &tmpstat)) {
669bfad9 540 conf_read_simple(name, S_DEF_USER);
90389160
RZ
541 break;
542 }
543 switch (input_mode) {
4062f1a4
SR
544 case allnoconfig: name = "allno.config"; break;
545 case allyesconfig: name = "allyes.config"; break;
546 case allmodconfig: name = "allmod.config"; break;
547 case randconfig: name = "allrandom.config"; break;
90389160
RZ
548 default: break;
549 }
550 if (!stat(name, &tmpstat))
669bfad9 551 conf_read_simple(name, S_DEF_USER);
90389160 552 else if (!stat("all.config", &tmpstat))
669bfad9 553 conf_read_simple("all.config", S_DEF_USER);
90389160 554 break;
1da177e4
LT
555 default:
556 break;
557 }
204c96f6 558
559 if (sync_kconfig) {
560 if (conf_get_changed()) {
561 name = getenv("KCONFIG_NOSILENTUPDATE");
562 if (name && *name) {
563 fprintf(stderr,
564 _("\n*** Kernel configuration requires explicit update.\n\n"));
565 return 1;
566 }
567 }
568 valid_stdin = isatty(0) && isatty(1) && isatty(2);
569 }
570
f443d2ec 571 switch (input_mode) {
4062f1a4 572 case allnoconfig:
f443d2ec
SR
573 conf_set_all_new_symbols(def_no);
574 break;
4062f1a4 575 case allyesconfig:
f443d2ec
SR
576 conf_set_all_new_symbols(def_yes);
577 break;
4062f1a4 578 case allmodconfig:
f443d2ec
SR
579 conf_set_all_new_symbols(def_mod);
580 break;
4062f1a4 581 case randconfig:
f443d2ec
SR
582 conf_set_all_new_symbols(def_random);
583 break;
4062f1a4 584 case defconfig:
09748e17
SR
585 conf_set_all_new_symbols(def_default);
586 break;
4062f1a4
SR
587 case oldconfig:
588 case oldaskconfig:
204c96f6 589 rootEntry = &rootmenu;
590 conf(&rootmenu);
4062f1a4 591 input_mode = silentoldconfig;
204c96f6 592 /* fall through */
861b4ea4 593 case listnewconfig:
ef61ca88 594 case oldnoconfig:
4062f1a4 595 case silentoldconfig:
204c96f6 596 /* Update until a loop caused no more changes */
597 do {
598 conf_cnt = 0;
599 check_conf(&rootmenu);
f0778c8c 600 } while (conf_cnt &&
861b4ea4 601 (input_mode != listnewconfig &&
ef61ca88 602 input_mode != oldnoconfig));
f443d2ec
SR
603 break;
604 }
1da177e4 605
204c96f6 606 if (sync_kconfig) {
607 /* silentoldconfig is used during the build so we shall update autoconf.
608 * All other commands are only used to generate a config.
609 */
610 if (conf_get_changed() && conf_write(NULL)) {
611 fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n"));
612 exit(1);
613 }
614 if (conf_write_autoconf()) {
615 fprintf(stderr, _("\n*** Error during update of the kernel configuration.\n\n"));
616 return 1;
617 }
861b4ea4 618 } else if (input_mode != listnewconfig) {
204c96f6 619 if (conf_write(NULL)) {
620 fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n"));
621 exit(1);
622 }
c955ccaf 623 }
861b4ea4 624 return 0;
1da177e4 625}