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