blob: fc446acbf6d6fb9f31d52116b09a0475f069bb09 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0.
4 */
5
EGRY Gabor534a4502008-01-11 23:44:39 +01006#include <locale.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -07007#include <ctype.h>
Markus Mayer74dba802015-12-09 14:56:12 -08008#include <limits.h>
Randy Dunlap9dfb5632006-04-18 22:21:53 -07009#include <stdio.h>
Ladislav Michl75ff4302008-01-09 16:36:19 +010010#include <stdlib.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070011#include <string.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070012#include <time.h>
Ladislav Michl75ff4302008-01-09 16:36:19 +010013#include <unistd.h>
Sam Ravnborg4062f1a2010-07-31 23:35:26 +020014#include <getopt.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070015#include <sys/stat.h>
Ingo Molnarb0fe5512009-03-12 15:15:31 +010016#include <sys/time.h>
Yann E. MORIN0d8024c2013-04-13 22:49:13 +020017#include <errno.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070018
Linus Torvalds1da177e2005-04-16 15:20:36 -070019#include "lkc.h"
20
21static void conf(struct menu *menu);
22static void check_conf(struct menu *menu);
23
Sam Ravnborg4062f1a2010-07-31 23:35:26 +020024enum input_mode {
25 oldaskconfig,
26 silentoldconfig,
27 oldconfig,
28 allnoconfig,
29 allyesconfig,
30 allmodconfig,
Sam Ravnborg0748cb32010-07-31 23:35:31 +020031 alldefconfig,
Sam Ravnborg4062f1a2010-07-31 23:35:26 +020032 randconfig,
33 defconfig,
Sam Ravnborg7cf3d732010-07-31 23:35:34 +020034 savedefconfig,
Sam Ravnborg861b4ea2010-07-31 23:35:28 +020035 listnewconfig,
Adam Leefb16d892012-09-01 01:05:17 +080036 olddefconfig,
Masahiro Yamada52e58a32018-01-11 22:39:39 +090037};
38static enum input_mode input_mode = oldaskconfig;
Sam Ravnborg4062f1a2010-07-31 23:35:26 +020039
Linus Torvalds1da177e2005-04-16 15:20:36 -070040static int indent = 1;
Ben Hutchings62dc9892013-02-19 02:24:26 +020041static int tty_stdio;
Linus Torvalds1da177e2005-04-16 15:20:36 -070042static int valid_stdin = 1;
zippel@linux-m68k.org204c96f2008-09-29 05:27:10 +020043static int sync_kconfig;
Linus Torvalds1da177e2005-04-16 15:20:36 -070044static int conf_cnt;
Markus Mayer74dba802015-12-09 14:56:12 -080045static char line[PATH_MAX];
Linus Torvalds1da177e2005-04-16 15:20:36 -070046static struct menu *rootEntry;
47
Cheng Renquan66c4bd82009-07-12 16:11:48 +080048static void print_help(struct menu *menu)
Sam Ravnborg03d29122007-07-21 00:00:36 +020049{
Cheng Renquan66c4bd82009-07-12 16:11:48 +080050 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);
Sam Ravnborg03d29122007-07-21 00:00:36 +020056}
57
J.A. Magallon48b9d032005-06-25 14:59:22 -070058static void strip(char *str)
Linus Torvalds1da177e2005-04-16 15:20:36 -070059{
J.A. Magallon48b9d032005-06-25 14:59:22 -070060 char *p = str;
Linus Torvalds1da177e2005-04-16 15:20:36 -070061 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
75static void check_stdin(void)
76{
zippel@linux-m68k.org204c96f2008-09-29 05:27:10 +020077 if (!valid_stdin) {
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -070078 printf(_("aborted!\n\n"));
79 printf(_("Console input/output is redirected. "));
80 printf(_("Run 'make oldconfig' to update configuration.\n\n"));
Linus Torvalds1da177e2005-04-16 15:20:36 -070081 exit(1);
82 }
83}
84
Masahiro Yamada5a3dc712018-01-11 22:39:40 +090085/* Helper function to facilitate fgets() by Jean Sacren. */
86static void xfgets(char *str, int size, FILE *in)
87{
88 if (!fgets(str, size, in))
89 fprintf(stderr, "\nError in reading or end of file.\n");
90}
91
Roman Zippelf82f3f92007-08-30 05:06:17 +020092static int conf_askvalue(struct symbol *sym, const char *def)
Linus Torvalds1da177e2005-04-16 15:20:36 -070093{
94 enum symbol_type type = sym_get_type(sym);
Linus Torvalds1da177e2005-04-16 15:20:36 -070095
96 if (!sym_has_value(sym))
EGRY Gabor534a4502008-01-11 23:44:39 +010097 printf(_("(NEW) "));
Linus Torvalds1da177e2005-04-16 15:20:36 -070098
99 line[0] = '\n';
100 line[1] = 0;
101
102 if (!sym_is_changable(sym)) {
103 printf("%s\n", def);
104 line[0] = '\n';
105 line[1] = 0;
Roman Zippelf82f3f92007-08-30 05:06:17 +0200106 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700107 }
108
109 switch (input_mode) {
Sam Ravnborg4062f1a2010-07-31 23:35:26 +0200110 case oldconfig:
111 case silentoldconfig:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700112 if (sym_has_value(sym)) {
113 printf("%s\n", def);
Roman Zippelf82f3f92007-08-30 05:06:17 +0200114 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700115 }
116 check_stdin();
Arnaud Lacombed8fc3202011-05-31 12:30:26 -0400117 /* fall through */
Sam Ravnborg4062f1a2010-07-31 23:35:26 +0200118 case oldaskconfig:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700119 fflush(stdout);
Markus Mayer74dba802015-12-09 14:56:12 -0800120 xfgets(line, sizeof(line), stdin);
Ben Hutchings62dc9892013-02-19 02:24:26 +0200121 if (!tty_stdio)
122 printf("\n");
Roman Zippelf82f3f92007-08-30 05:06:17 +0200123 return 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124 default:
125 break;
126 }
127
128 switch (type) {
129 case S_INT:
130 case S_HEX:
131 case S_STRING:
132 printf("%s\n", def);
Roman Zippelf82f3f92007-08-30 05:06:17 +0200133 return 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700134 default:
135 ;
136 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700137 printf("%s", line);
Roman Zippelf82f3f92007-08-30 05:06:17 +0200138 return 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700139}
140
Trevor Keith4356f482009-09-18 12:49:23 -0700141static int conf_string(struct menu *menu)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700142{
143 struct symbol *sym = menu->sym;
Sam Ravnborg03d29122007-07-21 00:00:36 +0200144 const char *def;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700145
146 while (1) {
EGRY Gabor534a4502008-01-11 23:44:39 +0100147 printf("%*s%s ", indent - 1, "", _(menu->prompt->text));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700148 printf("(%s) ", sym->name);
149 def = sym_get_string_value(sym);
150 if (sym_get_string_value(sym))
151 printf("[%s] ", def);
Roman Zippelf82f3f92007-08-30 05:06:17 +0200152 if (!conf_askvalue(sym, def))
153 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700154 switch (line[0]) {
155 case '\n':
156 break;
157 case '?':
158 /* print help */
159 if (line[1] == '\n') {
Cheng Renquan66c4bd82009-07-12 16:11:48 +0800160 print_help(menu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700161 def = NULL;
162 break;
163 }
Arnaud Lacombed8fc3202011-05-31 12:30:26 -0400164 /* fall through */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700165 default:
166 line[strlen(line)-1] = 0;
167 def = line;
168 }
169 if (def && sym_set_string_value(sym, def))
170 return 0;
171 }
172}
173
174static int conf_sym(struct menu *menu)
175{
176 struct symbol *sym = menu->sym;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700177 tristate oldval, newval;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700178
179 while (1) {
EGRY Gabor534a4502008-01-11 23:44:39 +0100180 printf("%*s%s ", indent - 1, "", _(menu->prompt->text));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700181 if (sym->name)
182 printf("(%s) ", sym->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700183 putchar('[');
184 oldval = sym_get_tristate_value(sym);
185 switch (oldval) {
186 case no:
187 putchar('N');
188 break;
189 case mod:
190 putchar('M');
191 break;
192 case yes:
193 putchar('Y');
194 break;
195 }
196 if (oldval != no && sym_tristate_within_range(sym, no))
197 printf("/n");
198 if (oldval != mod && sym_tristate_within_range(sym, mod))
199 printf("/m");
200 if (oldval != yes && sym_tristate_within_range(sym, yes))
201 printf("/y");
Masahiro Yamada4f208f32018-02-06 09:34:43 +0900202 printf("/?] ");
Roman Zippelf82f3f92007-08-30 05:06:17 +0200203 if (!conf_askvalue(sym, sym_get_string_value(sym)))
204 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700205 strip(line);
206
207 switch (line[0]) {
208 case 'n':
209 case 'N':
210 newval = no;
211 if (!line[1] || !strcmp(&line[1], "o"))
212 break;
213 continue;
214 case 'm':
215 case 'M':
216 newval = mod;
217 if (!line[1])
218 break;
219 continue;
220 case 'y':
221 case 'Y':
222 newval = yes;
223 if (!line[1] || !strcmp(&line[1], "es"))
224 break;
225 continue;
226 case 0:
227 newval = oldval;
228 break;
229 case '?':
230 goto help;
231 default:
232 continue;
233 }
234 if (sym_set_tristate_value(sym, newval))
235 return 0;
236help:
Cheng Renquan66c4bd82009-07-12 16:11:48 +0800237 print_help(menu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700238 }
239}
240
241static int conf_choice(struct menu *menu)
242{
243 struct symbol *sym, *def_sym;
244 struct menu *child;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700245 bool is_new;
246
247 sym = menu->sym;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700248 is_new = !sym_has_value(sym);
249 if (sym_is_changable(sym)) {
250 conf_sym(menu);
251 sym_calc_value(sym);
252 switch (sym_get_tristate_value(sym)) {
253 case no:
254 return 1;
255 case mod:
256 return 0;
257 case yes:
258 break;
259 }
260 } else {
261 switch (sym_get_tristate_value(sym)) {
262 case no:
263 return 1;
264 case mod:
EGRY Gabor534a4502008-01-11 23:44:39 +0100265 printf("%*s%s\n", indent - 1, "", _(menu_get_prompt(menu)));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700266 return 0;
267 case yes:
268 break;
269 }
270 }
271
272 while (1) {
273 int cnt, def;
274
EGRY Gabor534a4502008-01-11 23:44:39 +0100275 printf("%*s%s\n", indent - 1, "", _(menu_get_prompt(menu)));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700276 def_sym = sym_get_choice_value(sym);
277 cnt = def = 0;
Roman Zippel40aee722006-04-09 17:26:39 +0200278 line[0] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700279 for (child = menu->list; child; child = child->next) {
280 if (!menu_is_visible(child))
281 continue;
282 if (!child->sym) {
EGRY Gabor534a4502008-01-11 23:44:39 +0100283 printf("%*c %s\n", indent, '*', _(menu_get_prompt(child)));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700284 continue;
285 }
286 cnt++;
287 if (child->sym == def_sym) {
288 def = cnt;
289 printf("%*c", indent, '>');
290 } else
291 printf("%*c", indent, ' ');
EGRY Gabor534a4502008-01-11 23:44:39 +0100292 printf(" %d. %s", cnt, _(menu_get_prompt(child)));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700293 if (child->sym->name)
294 printf(" (%s)", child->sym->name);
295 if (!sym_has_value(child->sym))
EGRY Gabor534a4502008-01-11 23:44:39 +0100296 printf(_(" (NEW)"));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700297 printf("\n");
298 }
EGRY Gabor534a4502008-01-11 23:44:39 +0100299 printf(_("%*schoice"), indent - 1, "");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700300 if (cnt == 1) {
301 printf("[1]: 1\n");
302 goto conf_childs;
303 }
Masahiro Yamada4f208f32018-02-06 09:34:43 +0900304 printf("[1-%d?]: ", cnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700305 switch (input_mode) {
Sam Ravnborg4062f1a2010-07-31 23:35:26 +0200306 case oldconfig:
307 case silentoldconfig:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700308 if (!is_new) {
309 cnt = def;
310 printf("%d\n", cnt);
311 break;
312 }
313 check_stdin();
Arnaud Lacombed8fc3202011-05-31 12:30:26 -0400314 /* fall through */
Sam Ravnborg4062f1a2010-07-31 23:35:26 +0200315 case oldaskconfig:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700316 fflush(stdout);
Markus Mayer74dba802015-12-09 14:56:12 -0800317 xfgets(line, sizeof(line), stdin);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700318 strip(line);
319 if (line[0] == '?') {
Cheng Renquan66c4bd82009-07-12 16:11:48 +0800320 print_help(menu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700321 continue;
322 }
323 if (!line[0])
324 cnt = def;
325 else if (isdigit(line[0]))
326 cnt = atoi(line);
327 else
328 continue;
329 break;
Sam Ravnborgf443d2e2008-06-30 22:45:38 +0200330 default:
331 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700332 }
333
334 conf_childs:
335 for (child = menu->list; child; child = child->next) {
336 if (!child->sym || !menu_is_visible(child))
337 continue;
338 if (!--cnt)
339 break;
340 }
341 if (!child)
342 continue;
Ben Hutchings3ba41622011-04-23 18:42:56 +0100343 if (line[0] && line[strlen(line) - 1] == '?') {
Cheng Renquan66c4bd82009-07-12 16:11:48 +0800344 print_help(child);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700345 continue;
346 }
347 sym_set_choice_value(sym, child->sym);
Jan Beulichf5eaa322008-01-24 11:54:23 +0000348 for (child = child->list; child; child = child->next) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700349 indent += 2;
Jan Beulichf5eaa322008-01-24 11:54:23 +0000350 conf(child);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700351 indent -= 2;
352 }
353 return 1;
354 }
355}
356
357static void conf(struct menu *menu)
358{
359 struct symbol *sym;
360 struct property *prop;
361 struct menu *child;
362
363 if (!menu_is_visible(menu))
364 return;
365
366 sym = menu->sym;
367 prop = menu->prompt;
368 if (prop) {
369 const char *prompt;
370
371 switch (prop->type) {
372 case P_MENU:
Sam Ravnborg4062f1a2010-07-31 23:35:26 +0200373 if ((input_mode == silentoldconfig ||
Sam Ravnborg861b4ea2010-07-31 23:35:28 +0200374 input_mode == listnewconfig ||
Adam Leefb16d892012-09-01 01:05:17 +0800375 input_mode == olddefconfig) &&
Aristeu Rozanskif0778c82010-05-06 12:48:34 -0400376 rootEntry != menu) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377 check_conf(menu);
378 return;
379 }
Arnaud Lacombed8fc3202011-05-31 12:30:26 -0400380 /* fall through */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700381 case P_COMMENT:
382 prompt = menu_get_prompt(menu);
383 if (prompt)
384 printf("%*c\n%*c %s\n%*c\n",
385 indent, '*',
EGRY Gabor534a4502008-01-11 23:44:39 +0100386 indent, '*', _(prompt),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700387 indent, '*');
388 default:
389 ;
390 }
391 }
392
393 if (!sym)
394 goto conf_childs;
395
396 if (sym_is_choice(sym)) {
397 conf_choice(menu);
398 if (sym->curr.tri != mod)
399 return;
400 goto conf_childs;
401 }
402
403 switch (sym->type) {
404 case S_INT:
405 case S_HEX:
406 case S_STRING:
407 conf_string(menu);
408 break;
409 default:
410 conf_sym(menu);
411 break;
412 }
413
414conf_childs:
415 if (sym)
416 indent += 2;
417 for (child = menu->list; child; child = child->next)
418 conf(child);
419 if (sym)
420 indent -= 2;
421}
422
423static void check_conf(struct menu *menu)
424{
425 struct symbol *sym;
426 struct menu *child;
427
428 if (!menu_is_visible(menu))
429 return;
430
431 sym = menu->sym;
Roman Zippel3f23ca22005-11-08 21:34:48 -0800432 if (sym && !sym_has_value(sym)) {
433 if (sym_is_changable(sym) ||
434 (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) {
Sam Ravnborg861b4ea2010-07-31 23:35:28 +0200435 if (input_mode == listnewconfig) {
436 if (sym->name && !sym_is_choice_value(sym)) {
Arnaud Lacombeffb59572010-08-14 23:57:43 -0400437 printf("%s%s\n", CONFIG_, sym->name);
Aristeu Rozanskif0778c82010-05-06 12:48:34 -0400438 }
Adam Leefb16d892012-09-01 01:05:17 +0800439 } else if (input_mode != olddefconfig) {
Aristeu Rozanskif0778c82010-05-06 12:48:34 -0400440 if (!conf_cnt++)
441 printf(_("*\n* Restart config...\n*\n"));
442 rootEntry = menu_get_parent_menu(menu);
443 conf(rootEntry);
444 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700445 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700446 }
447
448 for (child = menu->list; child; child = child->next)
449 check_conf(child);
450}
451
Sam Ravnborg4062f1a2010-07-31 23:35:26 +0200452static struct option long_opts[] = {
453 {"oldaskconfig", no_argument, NULL, oldaskconfig},
454 {"oldconfig", no_argument, NULL, oldconfig},
455 {"silentoldconfig", no_argument, NULL, silentoldconfig},
456 {"defconfig", optional_argument, NULL, defconfig},
Sam Ravnborg7cf3d732010-07-31 23:35:34 +0200457 {"savedefconfig", required_argument, NULL, savedefconfig},
Sam Ravnborg4062f1a2010-07-31 23:35:26 +0200458 {"allnoconfig", no_argument, NULL, allnoconfig},
459 {"allyesconfig", no_argument, NULL, allyesconfig},
460 {"allmodconfig", no_argument, NULL, allmodconfig},
Sam Ravnborg0748cb32010-07-31 23:35:31 +0200461 {"alldefconfig", no_argument, NULL, alldefconfig},
Sam Ravnborg4062f1a2010-07-31 23:35:26 +0200462 {"randconfig", no_argument, NULL, randconfig},
Sam Ravnborg861b4ea2010-07-31 23:35:28 +0200463 {"listnewconfig", no_argument, NULL, listnewconfig},
Adam Leefb16d892012-09-01 01:05:17 +0800464 {"olddefconfig", no_argument, NULL, olddefconfig},
465 /*
466 * oldnoconfig is an alias of olddefconfig, because people already
467 * are dependent on its behavior(sets new symbols to their default
468 * value but not 'n') with the counter-intuitive name.
469 */
470 {"oldnoconfig", no_argument, NULL, olddefconfig},
Sam Ravnborg4062f1a2010-07-31 23:35:26 +0200471 {NULL, 0, NULL, 0}
472};
473
Arnaud Lacombe32543992010-11-02 00:26:33 -0400474static void conf_usage(const char *progname)
475{
476
Michal Marek0a1f00a2015-04-08 13:30:42 +0200477 printf("Usage: %s [-s] [option] <kconfig-file>\n", progname);
Arnaud Lacombe32543992010-11-02 00:26:33 -0400478 printf("[option] is _one_ of the following:\n");
479 printf(" --listnewconfig List new options\n");
480 printf(" --oldaskconfig Start a new configuration using a line-oriented program\n");
481 printf(" --oldconfig Update a configuration using a provided .config as base\n");
Marc Herbertcedd55d2018-01-26 14:59:00 -0800482 printf(" --silentoldconfig Similar to oldconfig but generates configuration in\n"
483 " include/{generated/,config/} (oldconfig used to be more verbose)\n");
484 printf(" --olddefconfig Same as oldconfig but sets new symbols to their default value\n");
Adam Leefb16d892012-09-01 01:05:17 +0800485 printf(" --oldnoconfig An alias of olddefconfig\n");
Arnaud Lacombe32543992010-11-02 00:26:33 -0400486 printf(" --defconfig <file> New config with default defined in <file>\n");
487 printf(" --savedefconfig <file> Save the minimal current configuration to <file>\n");
488 printf(" --allnoconfig New config where all options are answered with no\n");
489 printf(" --allyesconfig New config where all options are answered with yes\n");
490 printf(" --allmodconfig New config where all options are answered with mod\n");
491 printf(" --alldefconfig New config with all symbols set to default\n");
492 printf(" --randconfig New config with random answer to all options\n");
493}
494
Linus Torvalds1da177e2005-04-16 15:20:36 -0700495int main(int ac, char **av)
496{
Arnaud Lacombe32543992010-11-02 00:26:33 -0400497 const char *progname = av[0];
Andres Salomon2f4b4892007-12-17 01:34:58 -0500498 int opt;
Arnaud Lacombe275744c2010-10-13 20:43:28 -0400499 const char *name, *defconfig_file = NULL /* gcc uninit */;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700500 struct stat tmpstat;
501
EGRY Gabor534a4502008-01-11 23:44:39 +0100502 setlocale(LC_ALL, "");
503 bindtextdomain(PACKAGE, LOCALEDIR);
504 textdomain(PACKAGE);
505
Ben Hutchings62dc9892013-02-19 02:24:26 +0200506 tty_stdio = isatty(0) && isatty(1) && isatty(2);
507
Michal Marek0a1f00a2015-04-08 13:30:42 +0200508 while ((opt = getopt_long(ac, av, "s", long_opts, NULL)) != -1) {
509 if (opt == 's') {
510 conf_set_message_callback(NULL);
511 continue;
512 }
Sam Ravnborg4062f1a2010-07-31 23:35:26 +0200513 input_mode = (enum input_mode)opt;
Andres Salomon2f4b4892007-12-17 01:34:58 -0500514 switch (opt) {
Sam Ravnborg4062f1a2010-07-31 23:35:26 +0200515 case silentoldconfig:
zippel@linux-m68k.org204c96f2008-09-29 05:27:10 +0200516 sync_kconfig = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700517 break;
Sam Ravnborg4062f1a2010-07-31 23:35:26 +0200518 case defconfig:
Sam Ravnborg7cf3d732010-07-31 23:35:34 +0200519 case savedefconfig:
Andres Salomon2f4b4892007-12-17 01:34:58 -0500520 defconfig_file = optarg;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700521 break;
Sam Ravnborg4062f1a2010-07-31 23:35:26 +0200522 case randconfig:
Ingo Molnarb0fe5512009-03-12 15:15:31 +0100523 {
524 struct timeval now;
525 unsigned int seed;
Yann E. MORIN0d8024c2013-04-13 22:49:13 +0200526 char *seed_env;
Ingo Molnarb0fe5512009-03-12 15:15:31 +0100527
528 /*
529 * Use microseconds derived seed,
530 * compensate for systems where it may be zero
531 */
532 gettimeofday(&now, NULL);
Ingo Molnarb0fe5512009-03-12 15:15:31 +0100533 seed = (unsigned int)((now.tv_sec + 1) * (now.tv_usec + 1));
Yann E. MORIN0d8024c2013-04-13 22:49:13 +0200534
535 seed_env = getenv("KCONFIG_SEED");
536 if( seed_env && *seed_env ) {
537 char *endp;
Yann E. MORINe85ac122013-05-20 23:17:34 +0200538 int tmp = (int)strtol(seed_env, &endp, 0);
Yann E. MORIN0d8024c2013-04-13 22:49:13 +0200539 if (*endp == '\0') {
540 seed = tmp;
541 }
542 }
Yann E. MORINa5f6d792013-05-20 23:09:03 +0200543 fprintf( stderr, "KCONFIG_SEED=0x%X\n", seed );
Ingo Molnarb0fe5512009-03-12 15:15:31 +0100544 srand(seed);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700545 break;
Ingo Molnarb0fe5512009-03-12 15:15:31 +0100546 }
Arnaud Lacombe32543992010-11-02 00:26:33 -0400547 case oldaskconfig:
548 case oldconfig:
549 case allnoconfig:
550 case allyesconfig:
551 case allmodconfig:
552 case alldefconfig:
553 case listnewconfig:
Adam Leefb16d892012-09-01 01:05:17 +0800554 case olddefconfig:
Arnaud Lacombe32543992010-11-02 00:26:33 -0400555 break;
Sam Ravnborg4062f1a2010-07-31 23:35:26 +0200556 case '?':
Arnaud Lacombe32543992010-11-02 00:26:33 -0400557 conf_usage(progname);
Andres Salomon2f4b4892007-12-17 01:34:58 -0500558 exit(1);
Sam Ravnborg4062f1a2010-07-31 23:35:26 +0200559 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700560 }
561 }
Andres Salomon2f4b4892007-12-17 01:34:58 -0500562 if (ac == optind) {
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -0700563 printf(_("%s: Kconfig file missing\n"), av[0]);
Arnaud Lacombe32543992010-11-02 00:26:33 -0400564 conf_usage(progname);
Randy Dunlap250725a2006-06-08 22:12:50 -0700565 exit(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700566 }
Andres Salomon2f4b4892007-12-17 01:34:58 -0500567 name = av[optind];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700568 conf_parse(name);
569 //zconfdump(stdout);
zippel@linux-m68k.org204c96f2008-09-29 05:27:10 +0200570 if (sync_kconfig) {
Markus Heidelberg284026c2009-05-18 01:36:53 +0200571 name = conf_get_configname();
572 if (stat(name, &tmpstat)) {
zippel@linux-m68k.org204c96f2008-09-29 05:27:10 +0200573 fprintf(stderr, _("***\n"
Arnaud Lacombe652cf982010-08-14 23:51:40 -0400574 "*** Configuration file \"%s\" not found!\n"
zippel@linux-m68k.org204c96f2008-09-29 05:27:10 +0200575 "***\n"
576 "*** Please run some configurator (e.g. \"make oldconfig\" or\n"
577 "*** \"make menuconfig\" or \"make xconfig\").\n"
Markus Heidelberg284026c2009-05-18 01:36:53 +0200578 "***\n"), name);
zippel@linux-m68k.org204c96f2008-09-29 05:27:10 +0200579 exit(1);
580 }
581 }
582
Linus Torvalds1da177e2005-04-16 15:20:36 -0700583 switch (input_mode) {
Sam Ravnborg4062f1a2010-07-31 23:35:26 +0200584 case defconfig:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700585 if (!defconfig_file)
586 defconfig_file = conf_get_default_confname();
587 if (conf_read(defconfig_file)) {
EGRY Gabor534a4502008-01-11 23:44:39 +0100588 printf(_("***\n"
Linus Torvalds1da177e2005-04-16 15:20:36 -0700589 "*** Can't find default configuration \"%s\"!\n"
EGRY Gabor534a4502008-01-11 23:44:39 +0100590 "***\n"), defconfig_file);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700591 exit(1);
592 }
593 break;
Sam Ravnborg7cf3d732010-07-31 23:35:34 +0200594 case savedefconfig:
Sam Ravnborg4062f1a2010-07-31 23:35:26 +0200595 case silentoldconfig:
596 case oldaskconfig:
597 case oldconfig:
Sam Ravnborg861b4ea2010-07-31 23:35:28 +0200598 case listnewconfig:
Adam Leefb16d892012-09-01 01:05:17 +0800599 case olddefconfig:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700600 conf_read(NULL);
601 break;
Sam Ravnborg4062f1a2010-07-31 23:35:26 +0200602 case allnoconfig:
603 case allyesconfig:
604 case allmodconfig:
Sam Ravnborg0748cb32010-07-31 23:35:31 +0200605 case alldefconfig:
Sam Ravnborg4062f1a2010-07-31 23:35:26 +0200606 case randconfig:
Roman Zippel90389162005-11-08 21:34:49 -0800607 name = getenv("KCONFIG_ALLCONFIG");
Eric W. Biederman9f420bf2012-05-07 05:37:45 -0700608 if (!name)
609 break;
610 if ((strcmp(name, "") != 0) && (strcmp(name, "1") != 0)) {
Eric W. Biederman5efe2412012-04-26 01:51:32 -0700611 if (conf_read_simple(name, S_DEF_USER)) {
612 fprintf(stderr,
613 _("*** Can't read seed configuration \"%s\"!\n"),
614 name);
615 exit(1);
616 }
Roman Zippel90389162005-11-08 21:34:49 -0800617 break;
618 }
619 switch (input_mode) {
Sam Ravnborg4062f1a2010-07-31 23:35:26 +0200620 case allnoconfig: name = "allno.config"; break;
621 case allyesconfig: name = "allyes.config"; break;
622 case allmodconfig: name = "allmod.config"; break;
Sam Ravnborg0748cb32010-07-31 23:35:31 +0200623 case alldefconfig: name = "alldef.config"; break;
Sam Ravnborg4062f1a2010-07-31 23:35:26 +0200624 case randconfig: name = "allrandom.config"; break;
Roman Zippel90389162005-11-08 21:34:49 -0800625 default: break;
626 }
Eric W. Biederman5efe2412012-04-26 01:51:32 -0700627 if (conf_read_simple(name, S_DEF_USER) &&
628 conf_read_simple("all.config", S_DEF_USER)) {
629 fprintf(stderr,
630 _("*** KCONFIG_ALLCONFIG set, but no \"%s\" or \"all.config\" file found\n"),
631 name);
632 exit(1);
633 }
Roman Zippel90389162005-11-08 21:34:49 -0800634 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700635 default:
636 break;
637 }
zippel@linux-m68k.org204c96f2008-09-29 05:27:10 +0200638
639 if (sync_kconfig) {
640 if (conf_get_changed()) {
641 name = getenv("KCONFIG_NOSILENTUPDATE");
642 if (name && *name) {
643 fprintf(stderr,
Arnaud Lacombe652cf982010-08-14 23:51:40 -0400644 _("\n*** The configuration requires explicit update.\n\n"));
zippel@linux-m68k.org204c96f2008-09-29 05:27:10 +0200645 return 1;
646 }
647 }
Ben Hutchings62dc9892013-02-19 02:24:26 +0200648 valid_stdin = tty_stdio;
zippel@linux-m68k.org204c96f2008-09-29 05:27:10 +0200649 }
650
Sam Ravnborgf443d2e2008-06-30 22:45:38 +0200651 switch (input_mode) {
Sam Ravnborg4062f1a2010-07-31 23:35:26 +0200652 case allnoconfig:
Sam Ravnborgf443d2e2008-06-30 22:45:38 +0200653 conf_set_all_new_symbols(def_no);
654 break;
Sam Ravnborg4062f1a2010-07-31 23:35:26 +0200655 case allyesconfig:
Sam Ravnborgf443d2e2008-06-30 22:45:38 +0200656 conf_set_all_new_symbols(def_yes);
657 break;
Sam Ravnborg4062f1a2010-07-31 23:35:26 +0200658 case allmodconfig:
Sam Ravnborgf443d2e2008-06-30 22:45:38 +0200659 conf_set_all_new_symbols(def_mod);
660 break;
Sam Ravnborg0748cb32010-07-31 23:35:31 +0200661 case alldefconfig:
662 conf_set_all_new_symbols(def_default);
663 break;
Sam Ravnborg4062f1a2010-07-31 23:35:26 +0200664 case randconfig:
Yann E. MORIN3b9a19e2013-04-28 22:36:38 +0200665 /* Really nothing to do in this loop */
666 while (conf_set_all_new_symbols(def_random)) ;
Sam Ravnborgf443d2e2008-06-30 22:45:38 +0200667 break;
Sam Ravnborg4062f1a2010-07-31 23:35:26 +0200668 case defconfig:
Sam Ravnborg09748e12008-06-30 23:02:59 +0200669 conf_set_all_new_symbols(def_default);
670 break;
Sam Ravnborg7cf3d732010-07-31 23:35:34 +0200671 case savedefconfig:
672 break;
Sam Ravnborg4062f1a2010-07-31 23:35:26 +0200673 case oldaskconfig:
zippel@linux-m68k.org204c96f2008-09-29 05:27:10 +0200674 rootEntry = &rootmenu;
675 conf(&rootmenu);
Sam Ravnborg4062f1a2010-07-31 23:35:26 +0200676 input_mode = silentoldconfig;
zippel@linux-m68k.org204c96f2008-09-29 05:27:10 +0200677 /* fall through */
Sam Ravnborg14828342010-08-06 07:13:54 +0200678 case oldconfig:
Sam Ravnborg861b4ea2010-07-31 23:35:28 +0200679 case listnewconfig:
Adam Leefb16d892012-09-01 01:05:17 +0800680 case olddefconfig:
Sam Ravnborg4062f1a2010-07-31 23:35:26 +0200681 case silentoldconfig:
zippel@linux-m68k.org204c96f2008-09-29 05:27:10 +0200682 /* Update until a loop caused no more changes */
683 do {
684 conf_cnt = 0;
685 check_conf(&rootmenu);
Aristeu Rozanskif0778c82010-05-06 12:48:34 -0400686 } while (conf_cnt &&
Sam Ravnborg861b4ea2010-07-31 23:35:28 +0200687 (input_mode != listnewconfig &&
Adam Leefb16d892012-09-01 01:05:17 +0800688 input_mode != olddefconfig));
Sam Ravnborgf443d2e2008-06-30 22:45:38 +0200689 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700690 }
Sam Ravnborgf443d2e2008-06-30 22:45:38 +0200691
zippel@linux-m68k.org204c96f2008-09-29 05:27:10 +0200692 if (sync_kconfig) {
693 /* silentoldconfig is used during the build so we shall update autoconf.
694 * All other commands are only used to generate a config.
695 */
696 if (conf_get_changed() && conf_write(NULL)) {
Arnaud Lacombe652cf982010-08-14 23:51:40 -0400697 fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n"));
zippel@linux-m68k.org204c96f2008-09-29 05:27:10 +0200698 exit(1);
699 }
700 if (conf_write_autoconf()) {
Arnaud Lacombe652cf982010-08-14 23:51:40 -0400701 fprintf(stderr, _("\n*** Error during update of the configuration.\n\n"));
zippel@linux-m68k.org204c96f2008-09-29 05:27:10 +0200702 return 1;
703 }
Sam Ravnborg7cf3d732010-07-31 23:35:34 +0200704 } else if (input_mode == savedefconfig) {
705 if (conf_write_defconfig(defconfig_file)) {
706 fprintf(stderr, _("n*** Error while saving defconfig to: %s\n\n"),
Masahiro Yamadabb66fc62014-06-10 19:08:13 +0900707 defconfig_file);
Sam Ravnborg7cf3d732010-07-31 23:35:34 +0200708 return 1;
709 }
Sam Ravnborg861b4ea2010-07-31 23:35:28 +0200710 } else if (input_mode != listnewconfig) {
zippel@linux-m68k.org204c96f2008-09-29 05:27:10 +0200711 if (conf_write(NULL)) {
Arnaud Lacombe652cf982010-08-14 23:51:40 -0400712 fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n"));
zippel@linux-m68k.org204c96f2008-09-29 05:27:10 +0200713 exit(1);
714 }
Roman Zippelc955cca2006-06-08 22:12:39 -0700715 }
Sam Ravnborg861b4ea2010-07-31 23:35:28 +0200716 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700717}