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