Blame view

scripts/kconfig/conf.c 15.7 KB
0c8741001   Masahiro Yamada   kconfig: convert ...
1
  // SPDX-License-Identifier: GPL-2.0
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
3
  /*
   * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4
5
6
   */
  
  #include <ctype.h>
74dba8091   Markus Mayer   kconfig: allow kc...
7
  #include <limits.h>
9dfb563b0   Randy Dunlap   [PATCH] config: u...
8
  #include <stdio.h>
75ff4309c   Ladislav Michl   kconfig: fix whit...
9
  #include <stdlib.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
10
  #include <string.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
11
  #include <time.h>
75ff4309c   Ladislav Michl   kconfig: fix whit...
12
  #include <unistd.h>
4062f1a4c   Sam Ravnborg   kconfig: use long...
13
  #include <getopt.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
14
  #include <sys/stat.h>
b0fe55100   Ingo Molnar   kconfig: improve ...
15
  #include <sys/time.h>
0d8024c6e   Yann E. MORIN   kconfig: allow sp...
16
  #include <errno.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
17

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
18
19
20
21
  #include "lkc.h"
  
  static void conf(struct menu *menu);
  static void check_conf(struct menu *menu);
4062f1a4c   Sam Ravnborg   kconfig: use long...
22
23
  enum input_mode {
  	oldaskconfig,
911a91c39   Masahiro Yamada   kconfig: rename s...
24
  	syncconfig,
4062f1a4c   Sam Ravnborg   kconfig: use long...
25
26
27
28
  	oldconfig,
  	allnoconfig,
  	allyesconfig,
  	allmodconfig,
0748cb3e1   Sam Ravnborg   kconfig: add alld...
29
  	alldefconfig,
4062f1a4c   Sam Ravnborg   kconfig: use long...
30
31
  	randconfig,
  	defconfig,
7cf3d73b4   Sam Ravnborg   kconfig: add save...
32
  	savedefconfig,
861b4ea4c   Sam Ravnborg   kconfig: change n...
33
  	listnewconfig,
5d8b42aa7   Laura Abbott   kconfig: Add opti...
34
  	helpnewconfig,
fb16d8912   Adam Lee   kconfig: replace ...
35
  	olddefconfig,
89b906098   Tetsuo Handa   kconfig: Add yes2...
36
37
  	yes2modconfig,
  	mod2yesconfig,
52e58a3ca   Masahiro Yamada   kconfig: make inp...
38
39
  };
  static enum input_mode input_mode = oldaskconfig;
4062f1a4c   Sam Ravnborg   kconfig: use long...
40

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
41
  static int indent = 1;
62dc98992   Ben Hutchings   kbuild: Fix missi...
42
  static int tty_stdio;
204c96f60   zippel@linux-m68k.org   kconfig: fix sile...
43
  static int sync_kconfig;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
44
  static int conf_cnt;
74dba8091   Markus Mayer   kconfig: allow kc...
45
  static char line[PATH_MAX];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
46
  static struct menu *rootEntry;
66c4bd808   Cheng Renquan   kconfig: make use...
47
  static void print_help(struct menu *menu)
03d291227   Sam Ravnborg   kconfig: attach h...
48
  {
66c4bd808   Cheng Renquan   kconfig: make use...
49
50
51
52
53
54
55
56
  	struct gstr help = str_new();
  
  	menu_get_ext_help(menu, &help);
  
  	printf("
  %s
  ", str_get(&help));
  	str_free(&help);
03d291227   Sam Ravnborg   kconfig: attach h...
57
  }
48b9d03c5   J.A. Magallon   [PATCH] Kill sign...
58
  static void strip(char *str)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
59
  {
48b9d03c5   J.A. Magallon   [PATCH] Kill sign...
60
  	char *p = str;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
61
62
63
64
65
66
67
68
69
70
71
72
73
  	int l;
  
  	while ((isspace(*p)))
  		p++;
  	l = strlen(p);
  	if (p != str)
  		memmove(str, p, l + 1);
  	if (!l)
  		return;
  	p = str + l - 1;
  	while ((isspace(*p)))
  		*p-- = 0;
  }
5a3dc717b   Masahiro Yamada   kconfig: make xfg...
74
75
76
77
78
79
80
  /* Helper function to facilitate fgets() by Jean Sacren. */
  static void xfgets(char *str, int size, FILE *in)
  {
  	if (!fgets(str, size, in))
  		fprintf(stderr, "
  Error in reading or end of file.
  ");
f3ff6fb5d   Masahiro Yamada   kconfig: echo std...
81
82
83
  
  	if (!tty_stdio)
  		printf("%s", str);
5a3dc717b   Masahiro Yamada   kconfig: make xfg...
84
  }
f82f3f942   Roman Zippel   kconfig: oldconfi...
85
  static int conf_askvalue(struct symbol *sym, const char *def)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
86
87
  {
  	enum symbol_type type = sym_get_type(sym);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
88
89
  
  	if (!sym_has_value(sym))
694c49a7c   Sam Ravnborg   kconfig: drop loc...
90
  		printf("(NEW) ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
91
92
93
94
  
  	line[0] = '
  ';
  	line[1] = 0;
baa23ec86   Marco Ammon   kconfig: Fix spel...
95
  	if (!sym_is_changeable(sym)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
96
97
98
99
100
  		printf("%s
  ", def);
  		line[0] = '
  ';
  		line[1] = 0;
f82f3f942   Roman Zippel   kconfig: oldconfi...
101
  		return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
102
103
104
  	}
  
  	switch (input_mode) {
4062f1a4c   Sam Ravnborg   kconfig: use long...
105
  	case oldconfig:
911a91c39   Masahiro Yamada   kconfig: rename s...
106
  	case syncconfig:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
107
108
109
  		if (sym_has_value(sym)) {
  			printf("%s
  ", def);
f82f3f942   Roman Zippel   kconfig: oldconfi...
110
  			return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
111
  		}
d8fc32007   Arnaud Lacombe   kconfig: annotate...
112
  		/* fall through */
4062f1a4c   Sam Ravnborg   kconfig: use long...
113
  	case oldaskconfig:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
114
  		fflush(stdout);
74dba8091   Markus Mayer   kconfig: allow kc...
115
  		xfgets(line, sizeof(line), stdin);
f82f3f942   Roman Zippel   kconfig: oldconfi...
116
  		return 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
117
118
119
120
121
122
123
124
125
126
  	default:
  		break;
  	}
  
  	switch (type) {
  	case S_INT:
  	case S_HEX:
  	case S_STRING:
  		printf("%s
  ", def);
f82f3f942   Roman Zippel   kconfig: oldconfi...
127
  		return 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
128
129
130
  	default:
  		;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
131
  	printf("%s", line);
f82f3f942   Roman Zippel   kconfig: oldconfi...
132
  	return 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
133
  }
4356f4890   Trevor Keith   kbuild: add stati...
134
  static int conf_string(struct menu *menu)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
135
136
  {
  	struct symbol *sym = menu->sym;
03d291227   Sam Ravnborg   kconfig: attach h...
137
  	const char *def;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
138
139
  
  	while (1) {
694c49a7c   Sam Ravnborg   kconfig: drop loc...
140
  		printf("%*s%s ", indent - 1, "", menu->prompt->text);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
141
142
143
144
  		printf("(%s) ", sym->name);
  		def = sym_get_string_value(sym);
  		if (sym_get_string_value(sym))
  			printf("[%s] ", def);
f82f3f942   Roman Zippel   kconfig: oldconfi...
145
146
  		if (!conf_askvalue(sym, def))
  			return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
147
148
149
150
151
152
153
154
  		switch (line[0]) {
  		case '
  ':
  			break;
  		case '?':
  			/* print help */
  			if (line[1] == '
  ') {
66c4bd808   Cheng Renquan   kconfig: make use...
155
  				print_help(menu);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
156
157
158
  				def = NULL;
  				break;
  			}
d8fc32007   Arnaud Lacombe   kconfig: annotate...
159
  			/* fall through */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
160
161
162
163
164
165
166
167
168
169
170
171
  		default:
  			line[strlen(line)-1] = 0;
  			def = line;
  		}
  		if (def && sym_set_string_value(sym, def))
  			return 0;
  	}
  }
  
  static int conf_sym(struct menu *menu)
  {
  	struct symbol *sym = menu->sym;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
172
  	tristate oldval, newval;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
173
174
  
  	while (1) {
694c49a7c   Sam Ravnborg   kconfig: drop loc...
175
  		printf("%*s%s ", indent - 1, "", menu->prompt->text);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
176
177
  		if (sym->name)
  			printf("(%s) ", sym->name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
  		putchar('[');
  		oldval = sym_get_tristate_value(sym);
  		switch (oldval) {
  		case no:
  			putchar('N');
  			break;
  		case mod:
  			putchar('M');
  			break;
  		case yes:
  			putchar('Y');
  			break;
  		}
  		if (oldval != no && sym_tristate_within_range(sym, no))
  			printf("/n");
  		if (oldval != mod && sym_tristate_within_range(sym, mod))
  			printf("/m");
  		if (oldval != yes && sym_tristate_within_range(sym, yes))
  			printf("/y");
4f208f392   Masahiro Yamada   kconfig: show '?'...
197
  		printf("/?] ");
f82f3f942   Roman Zippel   kconfig: oldconfi...
198
199
  		if (!conf_askvalue(sym, sym_get_string_value(sym)))
  			return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
  		strip(line);
  
  		switch (line[0]) {
  		case 'n':
  		case 'N':
  			newval = no;
  			if (!line[1] || !strcmp(&line[1], "o"))
  				break;
  			continue;
  		case 'm':
  		case 'M':
  			newval = mod;
  			if (!line[1])
  				break;
  			continue;
  		case 'y':
  		case 'Y':
  			newval = yes;
  			if (!line[1] || !strcmp(&line[1], "es"))
  				break;
  			continue;
  		case 0:
  			newval = oldval;
  			break;
  		case '?':
  			goto help;
  		default:
  			continue;
  		}
  		if (sym_set_tristate_value(sym, newval))
  			return 0;
  help:
66c4bd808   Cheng Renquan   kconfig: make use...
232
  		print_help(menu);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
233
234
235
236
237
238
239
  	}
  }
  
  static int conf_choice(struct menu *menu)
  {
  	struct symbol *sym, *def_sym;
  	struct menu *child;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
240
241
242
  	bool is_new;
  
  	sym = menu->sym;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
243
  	is_new = !sym_has_value(sym);
baa23ec86   Marco Ammon   kconfig: Fix spel...
244
  	if (sym_is_changeable(sym)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
  		conf_sym(menu);
  		sym_calc_value(sym);
  		switch (sym_get_tristate_value(sym)) {
  		case no:
  			return 1;
  		case mod:
  			return 0;
  		case yes:
  			break;
  		}
  	} else {
  		switch (sym_get_tristate_value(sym)) {
  		case no:
  			return 1;
  		case mod:
694c49a7c   Sam Ravnborg   kconfig: drop loc...
260
261
  			printf("%*s%s
  ", indent - 1, "", menu_get_prompt(menu));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
262
263
264
265
266
267
268
269
  			return 0;
  		case yes:
  			break;
  		}
  	}
  
  	while (1) {
  		int cnt, def;
694c49a7c   Sam Ravnborg   kconfig: drop loc...
270
271
  		printf("%*s%s
  ", indent - 1, "", menu_get_prompt(menu));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
272
273
  		def_sym = sym_get_choice_value(sym);
  		cnt = def = 0;
40aee729b   Roman Zippel   kconfig: fix defa...
274
  		line[0] = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
275
276
277
278
  		for (child = menu->list; child; child = child->next) {
  			if (!menu_is_visible(child))
  				continue;
  			if (!child->sym) {
694c49a7c   Sam Ravnborg   kconfig: drop loc...
279
280
  				printf("%*c %s
  ", indent, '*', menu_get_prompt(child));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
281
282
283
284
285
286
287
288
  				continue;
  			}
  			cnt++;
  			if (child->sym == def_sym) {
  				def = cnt;
  				printf("%*c", indent, '>');
  			} else
  				printf("%*c", indent, ' ');
694c49a7c   Sam Ravnborg   kconfig: drop loc...
289
  			printf(" %d. %s", cnt, menu_get_prompt(child));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
290
291
292
  			if (child->sym->name)
  				printf(" (%s)", child->sym->name);
  			if (!sym_has_value(child->sym))
694c49a7c   Sam Ravnborg   kconfig: drop loc...
293
  				printf(" (NEW)");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
294
295
296
  			printf("
  ");
  		}
694c49a7c   Sam Ravnborg   kconfig: drop loc...
297
  		printf("%*schoice", indent - 1, "");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
298
299
300
301
302
  		if (cnt == 1) {
  			printf("[1]: 1
  ");
  			goto conf_childs;
  		}
4f208f392   Masahiro Yamada   kconfig: show '?'...
303
  		printf("[1-%d?]: ", cnt);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
304
  		switch (input_mode) {
4062f1a4c   Sam Ravnborg   kconfig: use long...
305
  		case oldconfig:
911a91c39   Masahiro Yamada   kconfig: rename s...
306
  		case syncconfig:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
307
308
309
310
311
312
  			if (!is_new) {
  				cnt = def;
  				printf("%d
  ", cnt);
  				break;
  			}
d8fc32007   Arnaud Lacombe   kconfig: annotate...
313
  			/* fall through */
4062f1a4c   Sam Ravnborg   kconfig: use long...
314
  		case oldaskconfig:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
315
  			fflush(stdout);
74dba8091   Markus Mayer   kconfig: allow kc...
316
  			xfgets(line, sizeof(line), stdin);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
317
318
  			strip(line);
  			if (line[0] == '?') {
66c4bd808   Cheng Renquan   kconfig: make use...
319
  				print_help(menu);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
320
321
322
323
324
325
326
327
328
  				continue;
  			}
  			if (!line[0])
  				cnt = def;
  			else if (isdigit(line[0]))
  				cnt = atoi(line);
  			else
  				continue;
  			break;
f443d2ecc   Sam Ravnborg   kconfig: speed up...
329
330
  		default:
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
331
332
333
334
335
336
337
338
339
340
341
  		}
  
  	conf_childs:
  		for (child = menu->list; child; child = child->next) {
  			if (!child->sym || !menu_is_visible(child))
  				continue;
  			if (!--cnt)
  				break;
  		}
  		if (!child)
  			continue;
3ba416211   Ben Hutchings   kconfig: Avoid bu...
342
  		if (line[0] && line[strlen(line) - 1] == '?') {
66c4bd808   Cheng Renquan   kconfig: make use...
343
  			print_help(child);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
344
345
346
  			continue;
  		}
  		sym_set_choice_value(sym, child->sym);
f5eaa323e   Jan Beulich   kconfig: tristate...
347
  		for (child = child->list; child; child = child->next) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
348
  			indent += 2;
f5eaa323e   Jan Beulich   kconfig: tristate...
349
  			conf(child);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
  			indent -= 2;
  		}
  		return 1;
  	}
  }
  
  static void conf(struct menu *menu)
  {
  	struct symbol *sym;
  	struct property *prop;
  	struct menu *child;
  
  	if (!menu_is_visible(menu))
  		return;
  
  	sym = menu->sym;
  	prop = menu->prompt;
  	if (prop) {
  		const char *prompt;
  
  		switch (prop->type) {
  		case P_MENU:
2aad9b896   Masahiro Yamada   kconfig: hide irr...
372
373
374
375
376
  			/*
  			 * Except in oldaskconfig mode, we show only menus that
  			 * contain new symbols.
  			 */
  			if (input_mode != oldaskconfig && rootEntry != menu) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
377
378
379
  				check_conf(menu);
  				return;
  			}
d8fc32007   Arnaud Lacombe   kconfig: annotate...
380
  			/* fall through */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
381
382
383
384
385
386
387
388
  		case P_COMMENT:
  			prompt = menu_get_prompt(menu);
  			if (prompt)
  				printf("%*c
  %*c %s
  %*c
  ",
  					indent, '*',
694c49a7c   Sam Ravnborg   kconfig: drop loc...
389
  					indent, '*', prompt,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
  					indent, '*');
  		default:
  			;
  		}
  	}
  
  	if (!sym)
  		goto conf_childs;
  
  	if (sym_is_choice(sym)) {
  		conf_choice(menu);
  		if (sym->curr.tri != mod)
  			return;
  		goto conf_childs;
  	}
  
  	switch (sym->type) {
  	case S_INT:
  	case S_HEX:
  	case S_STRING:
  		conf_string(menu);
  		break;
  	default:
  		conf_sym(menu);
  		break;
  	}
  
  conf_childs:
  	if (sym)
  		indent += 2;
  	for (child = menu->list; child; child = child->next)
  		conf(child);
  	if (sym)
  		indent -= 2;
  }
  
  static void check_conf(struct menu *menu)
  {
  	struct symbol *sym;
  	struct menu *child;
  
  	if (!menu_is_visible(menu))
  		return;
  
  	sym = menu->sym;
3f23ca2b3   Roman Zippel   [PATCH] kconfig: ...
435
  	if (sym && !sym_has_value(sym)) {
baa23ec86   Marco Ammon   kconfig: Fix spel...
436
  		if (sym_is_changeable(sym) ||
3f23ca2b3   Roman Zippel   [PATCH] kconfig: ...
437
  		    (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) {
861b4ea4c   Sam Ravnborg   kconfig: change n...
438
  			if (input_mode == listnewconfig) {
17baab68d   Don Zickus   kconfig: extend o...
439
440
441
442
443
444
445
446
447
448
449
450
451
452
  				if (sym->name) {
  					const char *str;
  
  					if (sym->type == S_STRING) {
  						str = sym_get_string_value(sym);
  						str = sym_escape_string_value(str);
  						printf("%s%s=%s
  ", CONFIG_, sym->name, str);
  						free((void *)str);
  					} else {
  						str = sym_get_string_value(sym);
  						printf("%s%s=%s
  ", CONFIG_, sym->name, str);
  					}
f0778c8c4   Aristeu Rozanski   kconfig: introduc...
453
  				}
5d8b42aa7   Laura Abbott   kconfig: Add opti...
454
455
456
457
458
459
  			} else if (input_mode == helpnewconfig) {
  				printf("-----
  ");
  				print_help(menu);
  				printf("-----
  ");
59a80b5e8   Masahiro Yamada   kconfig: do not c...
460
  			} else {
f0778c8c4   Aristeu Rozanski   kconfig: introduc...
461
  				if (!conf_cnt++)
694c49a7c   Sam Ravnborg   kconfig: drop loc...
462
463
464
465
  					printf("*
  * Restart config...
  *
  ");
f0778c8c4   Aristeu Rozanski   kconfig: introduc...
466
467
468
  				rootEntry = menu_get_parent_menu(menu);
  				conf(rootEntry);
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
469
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
470
471
472
473
474
  	}
  
  	for (child = menu->list; child; child = child->next)
  		check_conf(child);
  }
4062f1a4c   Sam Ravnborg   kconfig: use long...
475
476
477
  static struct option long_opts[] = {
  	{"oldaskconfig",    no_argument,       NULL, oldaskconfig},
  	{"oldconfig",       no_argument,       NULL, oldconfig},
911a91c39   Masahiro Yamada   kconfig: rename s...
478
  	{"syncconfig",      no_argument,       NULL, syncconfig},
b6f7e9f70   Masahiro Yamada   kconfig: require ...
479
  	{"defconfig",       required_argument, NULL, defconfig},
7cf3d73b4   Sam Ravnborg   kconfig: add save...
480
  	{"savedefconfig",   required_argument, NULL, savedefconfig},
4062f1a4c   Sam Ravnborg   kconfig: use long...
481
482
483
  	{"allnoconfig",     no_argument,       NULL, allnoconfig},
  	{"allyesconfig",    no_argument,       NULL, allyesconfig},
  	{"allmodconfig",    no_argument,       NULL, allmodconfig},
0748cb3e1   Sam Ravnborg   kconfig: add alld...
484
  	{"alldefconfig",    no_argument,       NULL, alldefconfig},
4062f1a4c   Sam Ravnborg   kconfig: use long...
485
  	{"randconfig",      no_argument,       NULL, randconfig},
861b4ea4c   Sam Ravnborg   kconfig: change n...
486
  	{"listnewconfig",   no_argument,       NULL, listnewconfig},
5d8b42aa7   Laura Abbott   kconfig: Add opti...
487
  	{"helpnewconfig",   no_argument,       NULL, helpnewconfig},
fb16d8912   Adam Lee   kconfig: replace ...
488
  	{"olddefconfig",    no_argument,       NULL, olddefconfig},
89b906098   Tetsuo Handa   kconfig: Add yes2...
489
490
  	{"yes2modconfig",   no_argument,       NULL, yes2modconfig},
  	{"mod2yesconfig",   no_argument,       NULL, mod2yesconfig},
4062f1a4c   Sam Ravnborg   kconfig: use long...
491
492
  	{NULL, 0, NULL, 0}
  };
32543999f   Arnaud Lacombe   kconfig/conf: add...
493
494
  static void conf_usage(const char *progname)
  {
0a1f00a1c   Michal Marek   kconfig: Do not p...
495
496
  	printf("Usage: %s [-s] [option] <kconfig-file>
  ", progname);
32543999f   Arnaud Lacombe   kconfig/conf: add...
497
498
499
500
  	printf("[option] is _one_ of the following:
  ");
  	printf("  --listnewconfig         List new options
  ");
5d8b42aa7   Laura Abbott   kconfig: Add opti...
501
502
  	printf("  --helpnewconfig         List new options and help text
  ");
32543999f   Arnaud Lacombe   kconfig/conf: add...
503
504
505
506
  	printf("  --oldaskconfig          Start a new configuration using a line-oriented program
  ");
  	printf("  --oldconfig             Update a configuration using a provided .config as base
  ");
911a91c39   Masahiro Yamada   kconfig: rename s...
507
508
509
510
  	printf("  --syncconfig            Similar to oldconfig but generates configuration in
  "
  	       "                          include/{generated/,config/}
  ");
cedd55d49   Marc Herbert   kconfig: Remove s...
511
512
  	printf("  --olddefconfig          Same as oldconfig but sets new symbols to their default value
  ");
32543999f   Arnaud Lacombe   kconfig/conf: add...
513
514
515
516
517
518
519
520
521
522
523
524
525
526
  	printf("  --defconfig <file>      New config with default defined in <file>
  ");
  	printf("  --savedefconfig <file>  Save the minimal current configuration to <file>
  ");
  	printf("  --allnoconfig           New config where all options are answered with no
  ");
  	printf("  --allyesconfig          New config where all options are answered with yes
  ");
  	printf("  --allmodconfig          New config where all options are answered with mod
  ");
  	printf("  --alldefconfig          New config with all symbols set to default
  ");
  	printf("  --randconfig            New config with random answer to all options
  ");
89b906098   Tetsuo Handa   kconfig: Add yes2...
527
528
529
530
  	printf("  --yes2modconfig         Change answers from yes to mod if possible
  ");
  	printf("  --mod2yesconfig         Change answers from mod to yes if possible
  ");
32543999f   Arnaud Lacombe   kconfig/conf: add...
531
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
532
533
  int main(int ac, char **av)
  {
32543999f   Arnaud Lacombe   kconfig/conf: add...
534
  	const char *progname = av[0];
2f4b489b7   Andres Salomon   kconfig: use geto...
535
  	int opt;
275744cc8   Arnaud Lacombe   kconfig/conf: red...
536
  	const char *name, *defconfig_file = NULL /* gcc uninit */;
16952b77d   Masahiro Yamada   kconfig: make syn...
537
  	int no_conf_write = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
538

f3ff6fb5d   Masahiro Yamada   kconfig: echo std...
539
  	tty_stdio = isatty(0) && isatty(1);
62dc98992   Ben Hutchings   kbuild: Fix missi...
540

0a1f00a1c   Michal Marek   kconfig: Do not p...
541
542
543
544
545
  	while ((opt = getopt_long(ac, av, "s", long_opts, NULL)) != -1) {
  		if (opt == 's') {
  			conf_set_message_callback(NULL);
  			continue;
  		}
4062f1a4c   Sam Ravnborg   kconfig: use long...
546
  		input_mode = (enum input_mode)opt;
2f4b489b7   Andres Salomon   kconfig: use geto...
547
  		switch (opt) {
911a91c39   Masahiro Yamada   kconfig: rename s...
548
  		case syncconfig:
9a9ddcf47   Masahiro Yamada   kconfig: suppress...
549
550
551
552
553
  			/*
  			 * syncconfig is invoked during the build stage.
  			 * Suppress distracting "configuration written to ..."
  			 */
  			conf_set_message_callback(NULL);
204c96f60   zippel@linux-m68k.org   kconfig: fix sile...
554
  			sync_kconfig = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
555
  			break;
4062f1a4c   Sam Ravnborg   kconfig: use long...
556
  		case defconfig:
7cf3d73b4   Sam Ravnborg   kconfig: add save...
557
  		case savedefconfig:
2f4b489b7   Andres Salomon   kconfig: use geto...
558
  			defconfig_file = optarg;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
559
  			break;
4062f1a4c   Sam Ravnborg   kconfig: use long...
560
  		case randconfig:
b0fe55100   Ingo Molnar   kconfig: improve ...
561
562
563
  		{
  			struct timeval now;
  			unsigned int seed;
0d8024c6e   Yann E. MORIN   kconfig: allow sp...
564
  			char *seed_env;
b0fe55100   Ingo Molnar   kconfig: improve ...
565
566
567
568
569
570
  
  			/*
  			 * Use microseconds derived seed,
  			 * compensate for systems where it may be zero
  			 */
  			gettimeofday(&now, NULL);
b0fe55100   Ingo Molnar   kconfig: improve ...
571
  			seed = (unsigned int)((now.tv_sec + 1) * (now.tv_usec + 1));
0d8024c6e   Yann E. MORIN   kconfig: allow sp...
572
573
574
575
  
  			seed_env = getenv("KCONFIG_SEED");
  			if( seed_env && *seed_env ) {
  				char *endp;
e85ac1244   Yann E. MORIN   kconfig/conf: acc...
576
  				int tmp = (int)strtol(seed_env, &endp, 0);
0d8024c6e   Yann E. MORIN   kconfig: allow sp...
577
578
579
580
  				if (*endp == '\0') {
  					seed = tmp;
  				}
  			}
a5f6d795f   Yann E. MORIN   kconfig/conf: pri...
581
582
  			fprintf( stderr, "KCONFIG_SEED=0x%X
  ", seed );
b0fe55100   Ingo Molnar   kconfig: improve ...
583
  			srand(seed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
584
  			break;
b0fe55100   Ingo Molnar   kconfig: improve ...
585
  		}
32543999f   Arnaud Lacombe   kconfig/conf: add...
586
587
588
589
590
591
592
  		case oldaskconfig:
  		case oldconfig:
  		case allnoconfig:
  		case allyesconfig:
  		case allmodconfig:
  		case alldefconfig:
  		case listnewconfig:
5d8b42aa7   Laura Abbott   kconfig: Add opti...
593
  		case helpnewconfig:
fb16d8912   Adam Lee   kconfig: replace ...
594
  		case olddefconfig:
89b906098   Tetsuo Handa   kconfig: Add yes2...
595
596
  		case yes2modconfig:
  		case mod2yesconfig:
32543999f   Arnaud Lacombe   kconfig/conf: add...
597
  			break;
4062f1a4c   Sam Ravnborg   kconfig: use long...
598
  		case '?':
32543999f   Arnaud Lacombe   kconfig/conf: add...
599
  			conf_usage(progname);
2f4b489b7   Andres Salomon   kconfig: use geto...
600
  			exit(1);
4062f1a4c   Sam Ravnborg   kconfig: use long...
601
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
602
603
  		}
  	}
2f4b489b7   Andres Salomon   kconfig: use geto...
604
  	if (ac == optind) {
694c49a7c   Sam Ravnborg   kconfig: drop loc...
605
606
  		fprintf(stderr, "%s: Kconfig file missing
  ", av[0]);
32543999f   Arnaud Lacombe   kconfig/conf: add...
607
  		conf_usage(progname);
250725aa1   Randy Dunlap   kconfig: exit if ...
608
  		exit(1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
609
  	}
2f4b489b7   Andres Salomon   kconfig: use geto...
610
  	name = av[optind];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
611
612
  	conf_parse(name);
  	//zconfdump(stdout);
204c96f60   zippel@linux-m68k.org   kconfig: fix sile...
613

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
614
  	switch (input_mode) {
4062f1a4c   Sam Ravnborg   kconfig: use long...
615
  	case defconfig:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
616
  		if (conf_read(defconfig_file)) {
9e3e10c72   Masahiro Yamada   kconfig: send err...
617
  			fprintf(stderr,
694c49a7c   Sam Ravnborg   kconfig: drop loc...
618
619
  				"***
  "
9e3e10c72   Masahiro Yamada   kconfig: send err...
620
621
  				  "*** Can't find default configuration \"%s\"!
  "
694c49a7c   Sam Ravnborg   kconfig: drop loc...
622
623
  				  "***
  ",
9e3e10c72   Masahiro Yamada   kconfig: send err...
624
  				defconfig_file);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
625
626
627
  			exit(1);
  		}
  		break;
7cf3d73b4   Sam Ravnborg   kconfig: add save...
628
  	case savedefconfig:
911a91c39   Masahiro Yamada   kconfig: rename s...
629
  	case syncconfig:
4062f1a4c   Sam Ravnborg   kconfig: use long...
630
631
  	case oldaskconfig:
  	case oldconfig:
861b4ea4c   Sam Ravnborg   kconfig: change n...
632
  	case listnewconfig:
5d8b42aa7   Laura Abbott   kconfig: Add opti...
633
  	case helpnewconfig:
fb16d8912   Adam Lee   kconfig: replace ...
634
  	case olddefconfig:
89b906098   Tetsuo Handa   kconfig: Add yes2...
635
636
  	case yes2modconfig:
  	case mod2yesconfig:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
637
638
  		conf_read(NULL);
  		break;
4062f1a4c   Sam Ravnborg   kconfig: use long...
639
640
641
  	case allnoconfig:
  	case allyesconfig:
  	case allmodconfig:
0748cb3e1   Sam Ravnborg   kconfig: add alld...
642
  	case alldefconfig:
4062f1a4c   Sam Ravnborg   kconfig: use long...
643
  	case randconfig:
90389160e   Roman Zippel   [PATCH] kconfig: ...
644
  		name = getenv("KCONFIG_ALLCONFIG");
9f420bf0f   Eric W. Biederman   kbuild: all{no,ye...
645
646
647
  		if (!name)
  			break;
  		if ((strcmp(name, "") != 0) && (strcmp(name, "1") != 0)) {
5efe241ea   Eric W. Biederman   kconfig: Add erro...
648
649
  			if (conf_read_simple(name, S_DEF_USER)) {
  				fprintf(stderr,
694c49a7c   Sam Ravnborg   kconfig: drop loc...
650
651
  					"*** Can't read seed configuration \"%s\"!
  ",
5efe241ea   Eric W. Biederman   kconfig: Add erro...
652
653
654
  					name);
  				exit(1);
  			}
90389160e   Roman Zippel   [PATCH] kconfig: ...
655
656
657
  			break;
  		}
  		switch (input_mode) {
4062f1a4c   Sam Ravnborg   kconfig: use long...
658
659
660
  		case allnoconfig:	name = "allno.config"; break;
  		case allyesconfig:	name = "allyes.config"; break;
  		case allmodconfig:	name = "allmod.config"; break;
0748cb3e1   Sam Ravnborg   kconfig: add alld...
661
  		case alldefconfig:	name = "alldef.config"; break;
4062f1a4c   Sam Ravnborg   kconfig: use long...
662
  		case randconfig:	name = "allrandom.config"; break;
90389160e   Roman Zippel   [PATCH] kconfig: ...
663
664
  		default: break;
  		}
5efe241ea   Eric W. Biederman   kconfig: Add erro...
665
666
667
  		if (conf_read_simple(name, S_DEF_USER) &&
  		    conf_read_simple("all.config", S_DEF_USER)) {
  			fprintf(stderr,
694c49a7c   Sam Ravnborg   kconfig: drop loc...
668
669
  				"*** KCONFIG_ALLCONFIG set, but no \"%s\" or \"all.config\" file found
  ",
5efe241ea   Eric W. Biederman   kconfig: Add erro...
670
671
672
  				name);
  			exit(1);
  		}
90389160e   Roman Zippel   [PATCH] kconfig: ...
673
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
674
675
676
  	default:
  		break;
  	}
204c96f60   zippel@linux-m68k.org   kconfig: fix sile...
677
678
  
  	if (sync_kconfig) {
16952b77d   Masahiro Yamada   kconfig: make syn...
679
680
681
  		name = getenv("KCONFIG_NOSILENTUPDATE");
  		if (name && *name) {
  			if (conf_get_changed()) {
204c96f60   zippel@linux-m68k.org   kconfig: fix sile...
682
  				fprintf(stderr,
694c49a7c   Sam Ravnborg   kconfig: drop loc...
683
684
685
686
  					"
  *** The configuration requires explicit update.
  
  ");
204c96f60   zippel@linux-m68k.org   kconfig: fix sile...
687
688
  				return 1;
  			}
16952b77d   Masahiro Yamada   kconfig: make syn...
689
  			no_conf_write = 1;
204c96f60   zippel@linux-m68k.org   kconfig: fix sile...
690
  		}
204c96f60   zippel@linux-m68k.org   kconfig: fix sile...
691
  	}
f443d2ecc   Sam Ravnborg   kconfig: speed up...
692
  	switch (input_mode) {
4062f1a4c   Sam Ravnborg   kconfig: use long...
693
  	case allnoconfig:
f443d2ecc   Sam Ravnborg   kconfig: speed up...
694
695
  		conf_set_all_new_symbols(def_no);
  		break;
4062f1a4c   Sam Ravnborg   kconfig: use long...
696
  	case allyesconfig:
f443d2ecc   Sam Ravnborg   kconfig: speed up...
697
698
  		conf_set_all_new_symbols(def_yes);
  		break;
4062f1a4c   Sam Ravnborg   kconfig: use long...
699
  	case allmodconfig:
f443d2ecc   Sam Ravnborg   kconfig: speed up...
700
701
  		conf_set_all_new_symbols(def_mod);
  		break;
0748cb3e1   Sam Ravnborg   kconfig: add alld...
702
703
704
  	case alldefconfig:
  		conf_set_all_new_symbols(def_default);
  		break;
4062f1a4c   Sam Ravnborg   kconfig: use long...
705
  	case randconfig:
3b9a19e08   Yann E. MORIN   kconfig: loop as ...
706
707
  		/* Really nothing to do in this loop */
  		while (conf_set_all_new_symbols(def_random)) ;
f443d2ecc   Sam Ravnborg   kconfig: speed up...
708
  		break;
4062f1a4c   Sam Ravnborg   kconfig: use long...
709
  	case defconfig:
09748e178   Sam Ravnborg   kconfig: make def...
710
711
  		conf_set_all_new_symbols(def_default);
  		break;
7cf3d73b4   Sam Ravnborg   kconfig: add save...
712
713
  	case savedefconfig:
  		break;
89b906098   Tetsuo Handa   kconfig: Add yes2...
714
715
716
717
718
719
  	case yes2modconfig:
  		conf_rewrite_mod_or_yes(def_y2m);
  		break;
  	case mod2yesconfig:
  		conf_rewrite_mod_or_yes(def_m2y);
  		break;
4062f1a4c   Sam Ravnborg   kconfig: use long...
720
  	case oldaskconfig:
204c96f60   zippel@linux-m68k.org   kconfig: fix sile...
721
722
  		rootEntry = &rootmenu;
  		conf(&rootmenu);
2aad9b896   Masahiro Yamada   kconfig: hide irr...
723
  		input_mode = oldconfig;
204c96f60   zippel@linux-m68k.org   kconfig: fix sile...
724
  		/* fall through */
148283497   Sam Ravnborg   kconfig: fix make...
725
  	case oldconfig:
861b4ea4c   Sam Ravnborg   kconfig: change n...
726
  	case listnewconfig:
5d8b42aa7   Laura Abbott   kconfig: Add opti...
727
  	case helpnewconfig:
911a91c39   Masahiro Yamada   kconfig: rename s...
728
  	case syncconfig:
204c96f60   zippel@linux-m68k.org   kconfig: fix sile...
729
730
731
732
  		/* Update until a loop caused no more changes */
  		do {
  			conf_cnt = 0;
  			check_conf(&rootmenu);
99f0b6578   Masahiro Yamada   kconfig: remove r...
733
  		} while (conf_cnt);
59a80b5e8   Masahiro Yamada   kconfig: do not c...
734
735
736
  		break;
  	case olddefconfig:
  	default:
f443d2ecc   Sam Ravnborg   kconfig: speed up...
737
738
  		break;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
739

00c864f89   Masahiro Yamada   kconfig: allow al...
740
  	if (input_mode == savedefconfig) {
7cf3d73b4   Sam Ravnborg   kconfig: add save...
741
  		if (conf_write_defconfig(defconfig_file)) {
694c49a7c   Sam Ravnborg   kconfig: drop loc...
742
743
744
  			fprintf(stderr, "n*** Error while saving defconfig to: %s
  
  ",
bb66fc671   Masahiro Yamada   kbuild: trivial -...
745
  				defconfig_file);
7cf3d73b4   Sam Ravnborg   kconfig: add save...
746
747
  			return 1;
  		}
5d8b42aa7   Laura Abbott   kconfig: Add opti...
748
  	} else if (input_mode != listnewconfig && input_mode != helpnewconfig) {
00c864f89   Masahiro Yamada   kconfig: allow al...
749
  		if (!no_conf_write && conf_write(NULL)) {
694c49a7c   Sam Ravnborg   kconfig: drop loc...
750
751
752
753
  			fprintf(stderr, "
  *** Error during writing of the configuration.
  
  ");
204c96f60   zippel@linux-m68k.org   kconfig: fix sile...
754
755
  			exit(1);
  		}
00c864f89   Masahiro Yamada   kconfig: allow al...
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
  
  		/*
  		 * Create auto.conf if it does not exist.
  		 * This prevents GNU Make 4.1 or older from emitting
  		 * "include/config/auto.conf: No such file or directory"
  		 * in the top-level Makefile
  		 *
  		 * syncconfig always creates or updates auto.conf because it is
  		 * used during the build.
  		 */
  		if (conf_write_autoconf(sync_kconfig) && sync_kconfig) {
  			fprintf(stderr,
  				"
  *** Error during sync of the configuration.
  
  ");
  			return 1;
  		}
c955ccafc   Roman Zippel   kconfig: fix .con...
774
  	}
861b4ea4c   Sam Ravnborg   kconfig: change n...
775
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
776
  }