kconfig/conf.c
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Sun Jul 13 10:32:38 2008 +0000 (2008-07-13)
changeset 645 8e58024f8e37
parent 39 af42eec9d383
child 860 3ff8038f904c
permissions -rw-r--r--
Ioannis E. VENETIS <venetis@mail.capsl.udel.edu> pointed out that GMP and MPFR were not used by gcc.
Turned out that none could use GMP and MPFR as the config option changed its name, but the change was not propagated to all users.

/trunk/scripts/build/binutils.sh | 2 1 1 0 +-
/trunk/scripts/build/debug/300-gdb.sh | 2 1 1 0 +-
/trunk/scripts/build/cc_gcc.sh | 6 3 3 0 +++---
3 files changed, 5 insertions(+), 5 deletions(-)
     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 <ctype.h>
     7 #include <stdlib.h>
     8 #include <stdio.h>
     9 #include <string.h>
    10 #include <unistd.h>
    11 #include <time.h>
    12 #include <sys/stat.h>
    13 
    14 #define LKC_DIRECT_LINK
    15 #include "lkc.h"
    16 
    17 static void conf(struct menu *menu);
    18 static void check_conf(struct menu *menu);
    19 
    20 enum {
    21 	ask_all,
    22 	ask_new,
    23 	ask_silent,
    24 	set_default,
    25 	set_yes,
    26 	set_mod,
    27 	set_no,
    28 	set_random
    29 } input_mode = ask_all;
    30 char *defconfig_file;
    31 
    32 static int indent = 1;
    33 static int valid_stdin = 1;
    34 static int conf_cnt;
    35 static char line[128];
    36 static struct menu *rootEntry;
    37 
    38 static char nohelp_text[] = N_("Sorry, no help available for this option yet.\n");
    39 
    40 static void strip(char *str)
    41 {
    42 	char *p = str;
    43 	int l;
    44 
    45 	while ((isspace(*p)))
    46 		p++;
    47 	l = strlen(p);
    48 	if (p != str)
    49 		memmove(str, p, l + 1);
    50 	if (!l)
    51 		return;
    52 	p = str + l - 1;
    53 	while ((isspace(*p)))
    54 		*p-- = 0;
    55 }
    56 
    57 static void check_stdin(void)
    58 {
    59 	if (!valid_stdin && input_mode == ask_silent) {
    60 		printf(_("aborted!\n\n"));
    61 		printf(_("Console input/output is redirected. "));
    62 		printf(_("Run 'make oldconfig' to update configuration.\n\n"));
    63 		exit(1);
    64 	}
    65 }
    66 
    67 static void conf_askvalue(struct symbol *sym, const char *def)
    68 {
    69 	enum symbol_type type = sym_get_type(sym);
    70 	tristate val;
    71 
    72 	if (!sym_has_value(sym))
    73 		printf("(NEW) ");
    74 
    75 	line[0] = '\n';
    76 	line[1] = 0;
    77 
    78 	if (!sym_is_changable(sym)) {
    79 		printf("%s\n", def);
    80 		line[0] = '\n';
    81 		line[1] = 0;
    82 		return;
    83 	}
    84 
    85 	switch (input_mode) {
    86 	case set_no:
    87 	case set_mod:
    88 	case set_yes:
    89 	case set_random:
    90 		if (sym_has_value(sym)) {
    91 			printf("%s\n", def);
    92 			return;
    93 		}
    94 		break;
    95 	case ask_new:
    96 	case ask_silent:
    97 		if (sym_has_value(sym)) {
    98 			printf("%s\n", def);
    99 			return;
   100 		}
   101 		check_stdin();
   102 	case ask_all:
   103 		fflush(stdout);
   104 		fgets(line, 128, stdin);
   105 		return;
   106 	case set_default:
   107 		printf("%s\n", def);
   108 		return;
   109 	default:
   110 		break;
   111 	}
   112 
   113 	switch (type) {
   114 	case S_INT:
   115 	case S_HEX:
   116 	case S_STRING:
   117 		printf("%s\n", def);
   118 		return;
   119 	default:
   120 		;
   121 	}
   122 	switch (input_mode) {
   123 	case set_yes:
   124 		if (sym_tristate_within_range(sym, yes)) {
   125 			line[0] = 'y';
   126 			line[1] = '\n';
   127 			line[2] = 0;
   128 			break;
   129 		}
   130 	case set_mod:
   131 		if (type == S_TRISTATE) {
   132 			if (sym_tristate_within_range(sym, mod)) {
   133 				line[0] = 'm';
   134 				line[1] = '\n';
   135 				line[2] = 0;
   136 				break;
   137 			}
   138 		} else {
   139 			if (sym_tristate_within_range(sym, yes)) {
   140 				line[0] = 'y';
   141 				line[1] = '\n';
   142 				line[2] = 0;
   143 				break;
   144 			}
   145 		}
   146 	case set_no:
   147 		if (sym_tristate_within_range(sym, no)) {
   148 			line[0] = 'n';
   149 			line[1] = '\n';
   150 			line[2] = 0;
   151 			break;
   152 		}
   153 	case set_random:
   154 		do {
   155 			val = (tristate)(random() % 3);
   156 		} while (!sym_tristate_within_range(sym, val));
   157 		switch (val) {
   158 		case no: line[0] = 'n'; break;
   159 		case mod: line[0] = 'm'; break;
   160 		case yes: line[0] = 'y'; break;
   161 		}
   162 		line[1] = '\n';
   163 		line[2] = 0;
   164 		break;
   165 	default:
   166 		break;
   167 	}
   168 	printf("%s", line);
   169 }
   170 
   171 int conf_string(struct menu *menu)
   172 {
   173 	struct symbol *sym = menu->sym;
   174 	const char *def, *help;
   175 
   176 	while (1) {
   177 		printf("%*s%s ", indent - 1, "", menu->prompt->text);
   178 		printf("(%s) ", sym->name);
   179 		def = sym_get_string_value(sym);
   180 		if (sym_get_string_value(sym))
   181 			printf("[%s] ", def);
   182 		conf_askvalue(sym, def);
   183 		switch (line[0]) {
   184 		case '\n':
   185 			break;
   186 		case '?':
   187 			/* print help */
   188 			if (line[1] == '\n') {
   189 				help = nohelp_text;
   190 				if (menu->sym->help)
   191 					help = menu->sym->help;
   192 				printf("\n%s\n", menu->sym->help);
   193 				def = NULL;
   194 				break;
   195 			}
   196 		default:
   197 			line[strlen(line)-1] = 0;
   198 			def = line;
   199 		}
   200 		if (def && sym_set_string_value(sym, def))
   201 			return 0;
   202 	}
   203 }
   204 
   205 static int conf_sym(struct menu *menu)
   206 {
   207 	struct symbol *sym = menu->sym;
   208 	int type;
   209 	tristate oldval, newval;
   210 	const char *help;
   211 
   212 	while (1) {
   213 		printf("%*s%s ", indent - 1, "", menu->prompt->text);
   214 		if (sym->name)
   215 			printf("(%s) ", sym->name);
   216 		type = sym_get_type(sym);
   217 		putchar('[');
   218 		oldval = sym_get_tristate_value(sym);
   219 		switch (oldval) {
   220 		case no:
   221 			putchar('N');
   222 			break;
   223 		case mod:
   224 			putchar('M');
   225 			break;
   226 		case yes:
   227 			putchar('Y');
   228 			break;
   229 		}
   230 		if (oldval != no && sym_tristate_within_range(sym, no))
   231 			printf("/n");
   232 		if (oldval != mod && sym_tristate_within_range(sym, mod))
   233 			printf("/m");
   234 		if (oldval != yes && sym_tristate_within_range(sym, yes))
   235 			printf("/y");
   236 		if (sym->help)
   237 			printf("/?");
   238 		printf("] ");
   239 		conf_askvalue(sym, sym_get_string_value(sym));
   240 		strip(line);
   241 
   242 		switch (line[0]) {
   243 		case 'n':
   244 		case 'N':
   245 			newval = no;
   246 			if (!line[1] || !strcmp(&line[1], "o"))
   247 				break;
   248 			continue;
   249 		case 'm':
   250 		case 'M':
   251 			newval = mod;
   252 			if (!line[1])
   253 				break;
   254 			continue;
   255 		case 'y':
   256 		case 'Y':
   257 			newval = yes;
   258 			if (!line[1] || !strcmp(&line[1], "es"))
   259 				break;
   260 			continue;
   261 		case 0:
   262 			newval = oldval;
   263 			break;
   264 		case '?':
   265 			goto help;
   266 		default:
   267 			continue;
   268 		}
   269 		if (sym_set_tristate_value(sym, newval))
   270 			return 0;
   271 help:
   272 		help = nohelp_text;
   273 		if (sym->help)
   274 			help = sym->help;
   275 		printf("\n%s\n", help);
   276 	}
   277 }
   278 
   279 static int conf_choice(struct menu *menu)
   280 {
   281 	struct symbol *sym, *def_sym;
   282 	struct menu *child;
   283 	int type;
   284 	bool is_new;
   285 
   286 	sym = menu->sym;
   287 	type = sym_get_type(sym);
   288 	is_new = !sym_has_value(sym);
   289 	if (sym_is_changable(sym)) {
   290 		conf_sym(menu);
   291 		sym_calc_value(sym);
   292 		switch (sym_get_tristate_value(sym)) {
   293 		case no:
   294 			return 1;
   295 		case mod:
   296 			return 0;
   297 		case yes:
   298 			break;
   299 		}
   300 	} else {
   301 		switch (sym_get_tristate_value(sym)) {
   302 		case no:
   303 			return 1;
   304 		case mod:
   305 			printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
   306 			return 0;
   307 		case yes:
   308 			break;
   309 		}
   310 	}
   311 
   312 	while (1) {
   313 		int cnt, def;
   314 
   315 		printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
   316 		def_sym = sym_get_choice_value(sym);
   317 		cnt = def = 0;
   318 		line[0] = 0;
   319 		for (child = menu->list; child; child = child->next) {
   320 			if (!menu_is_visible(child))
   321 				continue;
   322 			if (!child->sym) {
   323 				printf("%*c %s\n", indent, '*', menu_get_prompt(child));
   324 				continue;
   325 			}
   326 			cnt++;
   327 			if (child->sym == def_sym) {
   328 				def = cnt;
   329 				printf("%*c", indent, '>');
   330 			} else
   331 				printf("%*c", indent, ' ');
   332 			printf(" %d. %s", cnt, menu_get_prompt(child));
   333 			if (child->sym->name)
   334 				printf(" (%s)", child->sym->name);
   335 			if (!sym_has_value(child->sym))
   336 				printf(" (NEW)");
   337 			printf("\n");
   338 		}
   339 		printf("%*schoice", indent - 1, "");
   340 		if (cnt == 1) {
   341 			printf("[1]: 1\n");
   342 			goto conf_childs;
   343 		}
   344 		printf("[1-%d", cnt);
   345 		if (sym->help)
   346 			printf("?");
   347 		printf("]: ");
   348 		switch (input_mode) {
   349 		case ask_new:
   350 		case ask_silent:
   351 			if (!is_new) {
   352 				cnt = def;
   353 				printf("%d\n", cnt);
   354 				break;
   355 			}
   356 			check_stdin();
   357 		case ask_all:
   358 			fflush(stdout);
   359 			fgets(line, 128, stdin);
   360 			strip(line);
   361 			if (line[0] == '?') {
   362 				printf("\n%s\n", menu->sym->help ?
   363 					menu->sym->help : nohelp_text);
   364 				continue;
   365 			}
   366 			if (!line[0])
   367 				cnt = def;
   368 			else if (isdigit(line[0]))
   369 				cnt = atoi(line);
   370 			else
   371 				continue;
   372 			break;
   373 		case set_random:
   374 			def = (random() % cnt) + 1;
   375 		case set_default:
   376 		case set_yes:
   377 		case set_mod:
   378 		case set_no:
   379 			cnt = def;
   380 			printf("%d\n", cnt);
   381 			break;
   382 		}
   383 
   384 	conf_childs:
   385 		for (child = menu->list; child; child = child->next) {
   386 			if (!child->sym || !menu_is_visible(child))
   387 				continue;
   388 			if (!--cnt)
   389 				break;
   390 		}
   391 		if (!child)
   392 			continue;
   393 		if (line[strlen(line) - 1] == '?') {
   394 			printf("\n%s\n", child->sym->help ?
   395 				child->sym->help : nohelp_text);
   396 			continue;
   397 		}
   398 		sym_set_choice_value(sym, child->sym);
   399 		if (child->list) {
   400 			indent += 2;
   401 			conf(child->list);
   402 			indent -= 2;
   403 		}
   404 		return 1;
   405 	}
   406 }
   407 
   408 static void conf(struct menu *menu)
   409 {
   410 	struct symbol *sym;
   411 	struct property *prop;
   412 	struct menu *child;
   413 
   414 	if (!menu_is_visible(menu))
   415 		return;
   416 
   417 	sym = menu->sym;
   418 	prop = menu->prompt;
   419 	if (prop) {
   420 		const char *prompt;
   421 
   422 		switch (prop->type) {
   423 		case P_MENU:
   424 			if (input_mode == ask_silent && rootEntry != menu) {
   425 				check_conf(menu);
   426 				return;
   427 			}
   428 		case P_COMMENT:
   429 			prompt = menu_get_prompt(menu);
   430 			if (prompt)
   431 				printf("%*c\n%*c %s\n%*c\n",
   432 					indent, '*',
   433 					indent, '*', prompt,
   434 					indent, '*');
   435 		default:
   436 			;
   437 		}
   438 	}
   439 
   440 	if (!sym)
   441 		goto conf_childs;
   442 
   443 	if (sym_is_choice(sym)) {
   444 		conf_choice(menu);
   445 		if (sym->curr.tri != mod)
   446 			return;
   447 		goto conf_childs;
   448 	}
   449 
   450 	switch (sym->type) {
   451 	case S_INT:
   452 	case S_HEX:
   453 	case S_STRING:
   454 		conf_string(menu);
   455 		break;
   456 	default:
   457 		conf_sym(menu);
   458 		break;
   459 	}
   460 
   461 conf_childs:
   462 	if (sym)
   463 		indent += 2;
   464 	for (child = menu->list; child; child = child->next)
   465 		conf(child);
   466 	if (sym)
   467 		indent -= 2;
   468 }
   469 
   470 static void check_conf(struct menu *menu)
   471 {
   472 	struct symbol *sym;
   473 	struct menu *child;
   474 
   475 	if (!menu_is_visible(menu))
   476 		return;
   477 
   478 	sym = menu->sym;
   479 	if (sym && !sym_has_value(sym)) {
   480 		if (sym_is_changable(sym) ||
   481 		    (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) {
   482 			if (!conf_cnt++)
   483 				printf(_("*\n* Restart config...\n*\n"));
   484 			rootEntry = menu_get_parent_menu(menu);
   485 			conf(rootEntry);
   486 		}
   487 	}
   488 
   489 	for (child = menu->list; child; child = child->next)
   490 		check_conf(child);
   491 }
   492 
   493 int main(int ac, char **av)
   494 {
   495 	int i = 1;
   496 	const char *name;
   497 	struct stat tmpstat;
   498 
   499 	if (ac > i && av[i][0] == '-') {
   500 		switch (av[i++][1]) {
   501 		case 'o':
   502 			input_mode = ask_new;
   503 			break;
   504 		case 's':
   505 			input_mode = ask_silent;
   506 			break;
   507 		case 'd':
   508 			input_mode = set_default;
   509 			break;
   510 		case 'D':
   511 			input_mode = set_default;
   512 			defconfig_file = av[i++];
   513 			if (!defconfig_file) {
   514 				printf(_("%s: No default config file specified\n"),
   515 					av[0]);
   516 				exit(1);
   517 			}
   518 			break;
   519 		case 'n':
   520 			input_mode = set_no;
   521 			break;
   522 		case 'm':
   523 			input_mode = set_mod;
   524 			break;
   525 		case 'y':
   526 			input_mode = set_yes;
   527 			break;
   528 		case 'r':
   529 			input_mode = set_random;
   530 			srandom(time(NULL));
   531 			break;
   532 		case 'h':
   533 		case '?':
   534 			fprintf(stderr, "See README for usage info\n");
   535 			exit(0);
   536 		}
   537 	}
   538   	name = av[i];
   539 	if (!name) {
   540 		printf(_("%s: Kconfig file missing\n"), av[0]);
   541 		exit(1);
   542 	}
   543 	conf_parse(name);
   544 	//zconfdump(stdout);
   545 	switch (input_mode) {
   546 	case set_default:
   547 		if (!defconfig_file)
   548 			defconfig_file = conf_get_default_confname();
   549 		if (conf_read(defconfig_file)) {
   550 			printf("***\n"
   551 				"*** Can't find default configuration \"%s\"!\n"
   552 				"***\n", defconfig_file);
   553 			exit(1);
   554 		}
   555 		break;
   556 	case ask_silent:
   557 		if (stat(".config", &tmpstat)) {
   558 			printf(_("***\n"
   559 				"*** You have not yet configured "PROJECT_NAME"!\n"
   560 				"***\n"
   561 				"*** Please run some configurator (e.g. \"make oldconfig\" or\n"
   562 				"*** \"make menuconfig\" or \"make xconfig\").\n"
   563 				"***\n"));
   564 			exit(1);
   565 		}
   566 	case ask_all:
   567 	case ask_new:
   568 		conf_read(NULL);
   569 		break;
   570 	case set_no:
   571 	case set_mod:
   572 	case set_yes:
   573 	case set_random:
   574 		name = getenv("KCONFIG_ALLCONFIG");
   575 		if (name && !stat(name, &tmpstat)) {
   576 			conf_read_simple(name, S_DEF_USER);
   577 			break;
   578 		}
   579 		switch (input_mode) {
   580 		case set_no:	 name = "allno.config"; break;
   581 		case set_mod:	 name = "allmod.config"; break;
   582 		case set_yes:	 name = "allyes.config"; break;
   583 		case set_random: name = "allrandom.config"; break;
   584 		default: break;
   585 		}
   586 		if (!stat(name, &tmpstat))
   587 			conf_read_simple(name, S_DEF_USER);
   588 		else if (!stat("all.config", &tmpstat))
   589 			conf_read_simple("all.config", S_DEF_USER);
   590 		break;
   591 	default:
   592 		break;
   593 	}
   594 
   595 	if (input_mode != ask_silent) {
   596 		rootEntry = &rootmenu;
   597 		conf(&rootmenu);
   598 		if (input_mode == ask_all) {
   599 			input_mode = ask_silent;
   600 			valid_stdin = 1;
   601 		}
   602 	} else if (conf_get_changed()) {
   603 		name = getenv("KCONFIG_NOSILENTUPDATE");
   604 		if (name && *name) {
   605 			fprintf(stderr, _("\n*** "PROJECT_NAME" configuration requires explicit update.\n\n"));
   606 			return 1;
   607 		}
   608 	} else
   609 		goto skip_check;
   610 
   611 	do {
   612 		conf_cnt = 0;
   613 		check_conf(&rootmenu);
   614 	} while (conf_cnt);
   615 	if (conf_write(NULL)) {
   616 		fprintf(stderr, _("\n*** Error during writing of "PROJECT_NAME" configuration.\n\n"));
   617 		return 1;
   618 	}
   619 skip_check:
   620 
   621 	return 0;
   622 }