xref: /rk3399_rockchip-uboot/scripts/kconfig/conf.c (revision 9b5f0b1da9ba7019316ed8c9698fe25e8c7fc33e)
10a9064fbSMasahiro Yamada /*
20a9064fbSMasahiro Yamada  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
30a9064fbSMasahiro Yamada  * Released under the terms of the GNU GPL v2.0.
40a9064fbSMasahiro Yamada  */
50a9064fbSMasahiro Yamada 
60a9064fbSMasahiro Yamada #include <locale.h>
70a9064fbSMasahiro Yamada #include <ctype.h>
80a9064fbSMasahiro Yamada #include <stdio.h>
90a9064fbSMasahiro Yamada #include <stdlib.h>
100a9064fbSMasahiro Yamada #include <string.h>
110a9064fbSMasahiro Yamada #include <time.h>
120a9064fbSMasahiro Yamada #include <unistd.h>
130a9064fbSMasahiro Yamada #include <getopt.h>
140a9064fbSMasahiro Yamada #include <sys/stat.h>
150a9064fbSMasahiro Yamada #include <sys/time.h>
160a9064fbSMasahiro Yamada #include <errno.h>
170a9064fbSMasahiro Yamada 
180a9064fbSMasahiro Yamada #include "lkc.h"
190a9064fbSMasahiro Yamada 
200a9064fbSMasahiro Yamada static void conf(struct menu *menu);
210a9064fbSMasahiro Yamada static void check_conf(struct menu *menu);
220a9064fbSMasahiro Yamada static void xfgets(char *str, int size, FILE *in);
230a9064fbSMasahiro Yamada 
240a9064fbSMasahiro Yamada enum input_mode {
250a9064fbSMasahiro Yamada 	oldaskconfig,
260a9064fbSMasahiro Yamada 	silentoldconfig,
270a9064fbSMasahiro Yamada 	oldconfig,
280a9064fbSMasahiro Yamada 	allnoconfig,
290a9064fbSMasahiro Yamada 	allyesconfig,
300a9064fbSMasahiro Yamada 	allmodconfig,
310a9064fbSMasahiro Yamada 	alldefconfig,
320a9064fbSMasahiro Yamada 	randconfig,
330a9064fbSMasahiro Yamada 	defconfig,
340a9064fbSMasahiro Yamada 	savedefconfig,
350a9064fbSMasahiro Yamada 	listnewconfig,
360a9064fbSMasahiro Yamada 	olddefconfig,
370a9064fbSMasahiro Yamada } input_mode = oldaskconfig;
380a9064fbSMasahiro Yamada 
390a9064fbSMasahiro Yamada static int indent = 1;
400a9064fbSMasahiro Yamada static int tty_stdio;
410a9064fbSMasahiro Yamada static int valid_stdin = 1;
420a9064fbSMasahiro Yamada static int sync_kconfig;
430a9064fbSMasahiro Yamada static int conf_cnt;
440a9064fbSMasahiro Yamada static char line[128];
450a9064fbSMasahiro Yamada static struct menu *rootEntry;
460a9064fbSMasahiro Yamada 
470a9064fbSMasahiro Yamada static void print_help(struct menu *menu)
480a9064fbSMasahiro Yamada {
490a9064fbSMasahiro Yamada 	struct gstr help = str_new();
500a9064fbSMasahiro Yamada 
510a9064fbSMasahiro Yamada 	menu_get_ext_help(menu, &help);
520a9064fbSMasahiro Yamada 
530a9064fbSMasahiro Yamada 	printf("\n%s\n", str_get(&help));
540a9064fbSMasahiro Yamada 	str_free(&help);
550a9064fbSMasahiro Yamada }
560a9064fbSMasahiro Yamada 
570a9064fbSMasahiro Yamada static void strip(char *str)
580a9064fbSMasahiro Yamada {
590a9064fbSMasahiro Yamada 	char *p = str;
600a9064fbSMasahiro Yamada 	int l;
610a9064fbSMasahiro Yamada 
620a9064fbSMasahiro Yamada 	while ((isspace(*p)))
630a9064fbSMasahiro Yamada 		p++;
640a9064fbSMasahiro Yamada 	l = strlen(p);
650a9064fbSMasahiro Yamada 	if (p != str)
660a9064fbSMasahiro Yamada 		memmove(str, p, l + 1);
670a9064fbSMasahiro Yamada 	if (!l)
680a9064fbSMasahiro Yamada 		return;
690a9064fbSMasahiro Yamada 	p = str + l - 1;
700a9064fbSMasahiro Yamada 	while ((isspace(*p)))
710a9064fbSMasahiro Yamada 		*p-- = 0;
720a9064fbSMasahiro Yamada }
730a9064fbSMasahiro Yamada 
740a9064fbSMasahiro Yamada static void check_stdin(void)
750a9064fbSMasahiro Yamada {
760a9064fbSMasahiro Yamada 	if (!valid_stdin) {
770a9064fbSMasahiro Yamada 		printf(_("aborted!\n\n"));
780a9064fbSMasahiro Yamada 		printf(_("Console input/output is redirected. "));
790a9064fbSMasahiro Yamada 		printf(_("Run 'make oldconfig' to update configuration.\n\n"));
800a9064fbSMasahiro Yamada 		exit(1);
810a9064fbSMasahiro Yamada 	}
820a9064fbSMasahiro Yamada }
830a9064fbSMasahiro Yamada 
840a9064fbSMasahiro Yamada static int conf_askvalue(struct symbol *sym, const char *def)
850a9064fbSMasahiro Yamada {
860a9064fbSMasahiro Yamada 	enum symbol_type type = sym_get_type(sym);
870a9064fbSMasahiro Yamada 
880a9064fbSMasahiro Yamada 	if (!sym_has_value(sym))
890a9064fbSMasahiro Yamada 		printf(_("(NEW) "));
900a9064fbSMasahiro Yamada 
910a9064fbSMasahiro Yamada 	line[0] = '\n';
920a9064fbSMasahiro Yamada 	line[1] = 0;
930a9064fbSMasahiro Yamada 
940a9064fbSMasahiro Yamada 	if (!sym_is_changable(sym)) {
950a9064fbSMasahiro Yamada 		printf("%s\n", def);
960a9064fbSMasahiro Yamada 		line[0] = '\n';
970a9064fbSMasahiro Yamada 		line[1] = 0;
980a9064fbSMasahiro Yamada 		return 0;
990a9064fbSMasahiro Yamada 	}
1000a9064fbSMasahiro Yamada 
1010a9064fbSMasahiro Yamada 	switch (input_mode) {
1020a9064fbSMasahiro Yamada 	case oldconfig:
1030a9064fbSMasahiro Yamada 	case silentoldconfig:
1040a9064fbSMasahiro Yamada 		if (sym_has_value(sym)) {
1050a9064fbSMasahiro Yamada 			printf("%s\n", def);
1060a9064fbSMasahiro Yamada 			return 0;
1070a9064fbSMasahiro Yamada 		}
1080a9064fbSMasahiro Yamada 		check_stdin();
1090a9064fbSMasahiro Yamada 		/* fall through */
1100a9064fbSMasahiro Yamada 	case oldaskconfig:
1110a9064fbSMasahiro Yamada 		fflush(stdout);
1120a9064fbSMasahiro Yamada 		xfgets(line, 128, stdin);
1130a9064fbSMasahiro Yamada 		if (!tty_stdio)
1140a9064fbSMasahiro Yamada 			printf("\n");
1150a9064fbSMasahiro Yamada 		return 1;
1160a9064fbSMasahiro Yamada 	default:
1170a9064fbSMasahiro Yamada 		break;
1180a9064fbSMasahiro Yamada 	}
1190a9064fbSMasahiro Yamada 
1200a9064fbSMasahiro Yamada 	switch (type) {
1210a9064fbSMasahiro Yamada 	case S_INT:
1220a9064fbSMasahiro Yamada 	case S_HEX:
1230a9064fbSMasahiro Yamada 	case S_STRING:
1240a9064fbSMasahiro Yamada 		printf("%s\n", def);
1250a9064fbSMasahiro Yamada 		return 1;
1260a9064fbSMasahiro Yamada 	default:
1270a9064fbSMasahiro Yamada 		;
1280a9064fbSMasahiro Yamada 	}
1290a9064fbSMasahiro Yamada 	printf("%s", line);
1300a9064fbSMasahiro Yamada 	return 1;
1310a9064fbSMasahiro Yamada }
1320a9064fbSMasahiro Yamada 
1330a9064fbSMasahiro Yamada static int conf_string(struct menu *menu)
1340a9064fbSMasahiro Yamada {
1350a9064fbSMasahiro Yamada 	struct symbol *sym = menu->sym;
1360a9064fbSMasahiro Yamada 	const char *def;
1370a9064fbSMasahiro Yamada 
1380a9064fbSMasahiro Yamada 	while (1) {
1390a9064fbSMasahiro Yamada 		printf("%*s%s ", indent - 1, "", _(menu->prompt->text));
1400a9064fbSMasahiro Yamada 		printf("(%s) ", sym->name);
1410a9064fbSMasahiro Yamada 		def = sym_get_string_value(sym);
1420a9064fbSMasahiro Yamada 		if (sym_get_string_value(sym))
1430a9064fbSMasahiro Yamada 			printf("[%s] ", def);
1440a9064fbSMasahiro Yamada 		if (!conf_askvalue(sym, def))
1450a9064fbSMasahiro Yamada 			return 0;
1460a9064fbSMasahiro Yamada 		switch (line[0]) {
1470a9064fbSMasahiro Yamada 		case '\n':
1480a9064fbSMasahiro Yamada 			break;
1490a9064fbSMasahiro Yamada 		case '?':
1500a9064fbSMasahiro Yamada 			/* print help */
1510a9064fbSMasahiro Yamada 			if (line[1] == '\n') {
1520a9064fbSMasahiro Yamada 				print_help(menu);
1530a9064fbSMasahiro Yamada 				def = NULL;
1540a9064fbSMasahiro Yamada 				break;
1550a9064fbSMasahiro Yamada 			}
1560a9064fbSMasahiro Yamada 			/* fall through */
1570a9064fbSMasahiro Yamada 		default:
1580a9064fbSMasahiro Yamada 			line[strlen(line)-1] = 0;
1590a9064fbSMasahiro Yamada 			def = line;
1600a9064fbSMasahiro Yamada 		}
1610a9064fbSMasahiro Yamada 		if (def && sym_set_string_value(sym, def))
1620a9064fbSMasahiro Yamada 			return 0;
1630a9064fbSMasahiro Yamada 	}
1640a9064fbSMasahiro Yamada }
1650a9064fbSMasahiro Yamada 
1660a9064fbSMasahiro Yamada static int conf_sym(struct menu *menu)
1670a9064fbSMasahiro Yamada {
1680a9064fbSMasahiro Yamada 	struct symbol *sym = menu->sym;
1690a9064fbSMasahiro Yamada 	tristate oldval, newval;
1700a9064fbSMasahiro Yamada 
1710a9064fbSMasahiro Yamada 	while (1) {
1720a9064fbSMasahiro Yamada 		printf("%*s%s ", indent - 1, "", _(menu->prompt->text));
1730a9064fbSMasahiro Yamada 		if (sym->name)
1740a9064fbSMasahiro Yamada 			printf("(%s) ", sym->name);
1750a9064fbSMasahiro Yamada 		putchar('[');
1760a9064fbSMasahiro Yamada 		oldval = sym_get_tristate_value(sym);
1770a9064fbSMasahiro Yamada 		switch (oldval) {
1780a9064fbSMasahiro Yamada 		case no:
1790a9064fbSMasahiro Yamada 			putchar('N');
1800a9064fbSMasahiro Yamada 			break;
1810a9064fbSMasahiro Yamada 		case mod:
1820a9064fbSMasahiro Yamada 			putchar('M');
1830a9064fbSMasahiro Yamada 			break;
1840a9064fbSMasahiro Yamada 		case yes:
1850a9064fbSMasahiro Yamada 			putchar('Y');
1860a9064fbSMasahiro Yamada 			break;
1870a9064fbSMasahiro Yamada 		}
1880a9064fbSMasahiro Yamada 		if (oldval != no && sym_tristate_within_range(sym, no))
1890a9064fbSMasahiro Yamada 			printf("/n");
1900a9064fbSMasahiro Yamada 		if (oldval != mod && sym_tristate_within_range(sym, mod))
1910a9064fbSMasahiro Yamada 			printf("/m");
1920a9064fbSMasahiro Yamada 		if (oldval != yes && sym_tristate_within_range(sym, yes))
1930a9064fbSMasahiro Yamada 			printf("/y");
1940a9064fbSMasahiro Yamada 		if (menu_has_help(menu))
1950a9064fbSMasahiro Yamada 			printf("/?");
1960a9064fbSMasahiro Yamada 		printf("] ");
1970a9064fbSMasahiro Yamada 		if (!conf_askvalue(sym, sym_get_string_value(sym)))
1980a9064fbSMasahiro Yamada 			return 0;
1990a9064fbSMasahiro Yamada 		strip(line);
2000a9064fbSMasahiro Yamada 
2010a9064fbSMasahiro Yamada 		switch (line[0]) {
2020a9064fbSMasahiro Yamada 		case 'n':
2030a9064fbSMasahiro Yamada 		case 'N':
2040a9064fbSMasahiro Yamada 			newval = no;
2050a9064fbSMasahiro Yamada 			if (!line[1] || !strcmp(&line[1], "o"))
2060a9064fbSMasahiro Yamada 				break;
2070a9064fbSMasahiro Yamada 			continue;
2080a9064fbSMasahiro Yamada 		case 'm':
2090a9064fbSMasahiro Yamada 		case 'M':
2100a9064fbSMasahiro Yamada 			newval = mod;
2110a9064fbSMasahiro Yamada 			if (!line[1])
2120a9064fbSMasahiro Yamada 				break;
2130a9064fbSMasahiro Yamada 			continue;
2140a9064fbSMasahiro Yamada 		case 'y':
2150a9064fbSMasahiro Yamada 		case 'Y':
2160a9064fbSMasahiro Yamada 			newval = yes;
2170a9064fbSMasahiro Yamada 			if (!line[1] || !strcmp(&line[1], "es"))
2180a9064fbSMasahiro Yamada 				break;
2190a9064fbSMasahiro Yamada 			continue;
2200a9064fbSMasahiro Yamada 		case 0:
2210a9064fbSMasahiro Yamada 			newval = oldval;
2220a9064fbSMasahiro Yamada 			break;
2230a9064fbSMasahiro Yamada 		case '?':
2240a9064fbSMasahiro Yamada 			goto help;
2250a9064fbSMasahiro Yamada 		default:
2260a9064fbSMasahiro Yamada 			continue;
2270a9064fbSMasahiro Yamada 		}
2280a9064fbSMasahiro Yamada 		if (sym_set_tristate_value(sym, newval))
2290a9064fbSMasahiro Yamada 			return 0;
2300a9064fbSMasahiro Yamada help:
2310a9064fbSMasahiro Yamada 		print_help(menu);
2320a9064fbSMasahiro Yamada 	}
2330a9064fbSMasahiro Yamada }
2340a9064fbSMasahiro Yamada 
2350a9064fbSMasahiro Yamada static int conf_choice(struct menu *menu)
2360a9064fbSMasahiro Yamada {
2370a9064fbSMasahiro Yamada 	struct symbol *sym, *def_sym;
2380a9064fbSMasahiro Yamada 	struct menu *child;
2390a9064fbSMasahiro Yamada 	bool is_new;
2400a9064fbSMasahiro Yamada 
2410a9064fbSMasahiro Yamada 	sym = menu->sym;
2420a9064fbSMasahiro Yamada 	is_new = !sym_has_value(sym);
2430a9064fbSMasahiro Yamada 	if (sym_is_changable(sym)) {
2440a9064fbSMasahiro Yamada 		conf_sym(menu);
2450a9064fbSMasahiro Yamada 		sym_calc_value(sym);
2460a9064fbSMasahiro Yamada 		switch (sym_get_tristate_value(sym)) {
2470a9064fbSMasahiro Yamada 		case no:
2480a9064fbSMasahiro Yamada 			return 1;
2490a9064fbSMasahiro Yamada 		case mod:
2500a9064fbSMasahiro Yamada 			return 0;
2510a9064fbSMasahiro Yamada 		case yes:
2520a9064fbSMasahiro Yamada 			break;
2530a9064fbSMasahiro Yamada 		}
2540a9064fbSMasahiro Yamada 	} else {
2550a9064fbSMasahiro Yamada 		switch (sym_get_tristate_value(sym)) {
2560a9064fbSMasahiro Yamada 		case no:
2570a9064fbSMasahiro Yamada 			return 1;
2580a9064fbSMasahiro Yamada 		case mod:
2590a9064fbSMasahiro Yamada 			printf("%*s%s\n", indent - 1, "", _(menu_get_prompt(menu)));
2600a9064fbSMasahiro Yamada 			return 0;
2610a9064fbSMasahiro Yamada 		case yes:
2620a9064fbSMasahiro Yamada 			break;
2630a9064fbSMasahiro Yamada 		}
2640a9064fbSMasahiro Yamada 	}
2650a9064fbSMasahiro Yamada 
2660a9064fbSMasahiro Yamada 	while (1) {
2670a9064fbSMasahiro Yamada 		int cnt, def;
2680a9064fbSMasahiro Yamada 
2690a9064fbSMasahiro Yamada 		printf("%*s%s\n", indent - 1, "", _(menu_get_prompt(menu)));
2700a9064fbSMasahiro Yamada 		def_sym = sym_get_choice_value(sym);
2710a9064fbSMasahiro Yamada 		cnt = def = 0;
2720a9064fbSMasahiro Yamada 		line[0] = 0;
2730a9064fbSMasahiro Yamada 		for (child = menu->list; child; child = child->next) {
2740a9064fbSMasahiro Yamada 			if (!menu_is_visible(child))
2750a9064fbSMasahiro Yamada 				continue;
2760a9064fbSMasahiro Yamada 			if (!child->sym) {
2770a9064fbSMasahiro Yamada 				printf("%*c %s\n", indent, '*', _(menu_get_prompt(child)));
2780a9064fbSMasahiro Yamada 				continue;
2790a9064fbSMasahiro Yamada 			}
2800a9064fbSMasahiro Yamada 			cnt++;
2810a9064fbSMasahiro Yamada 			if (child->sym == def_sym) {
2820a9064fbSMasahiro Yamada 				def = cnt;
2830a9064fbSMasahiro Yamada 				printf("%*c", indent, '>');
2840a9064fbSMasahiro Yamada 			} else
2850a9064fbSMasahiro Yamada 				printf("%*c", indent, ' ');
2860a9064fbSMasahiro Yamada 			printf(" %d. %s", cnt, _(menu_get_prompt(child)));
2870a9064fbSMasahiro Yamada 			if (child->sym->name)
2880a9064fbSMasahiro Yamada 				printf(" (%s)", child->sym->name);
2890a9064fbSMasahiro Yamada 			if (!sym_has_value(child->sym))
2900a9064fbSMasahiro Yamada 				printf(_(" (NEW)"));
2910a9064fbSMasahiro Yamada 			printf("\n");
2920a9064fbSMasahiro Yamada 		}
2930a9064fbSMasahiro Yamada 		printf(_("%*schoice"), indent - 1, "");
2940a9064fbSMasahiro Yamada 		if (cnt == 1) {
2950a9064fbSMasahiro Yamada 			printf("[1]: 1\n");
2960a9064fbSMasahiro Yamada 			goto conf_childs;
2970a9064fbSMasahiro Yamada 		}
2980a9064fbSMasahiro Yamada 		printf("[1-%d", cnt);
2990a9064fbSMasahiro Yamada 		if (menu_has_help(menu))
3000a9064fbSMasahiro Yamada 			printf("?");
3010a9064fbSMasahiro Yamada 		printf("]: ");
3020a9064fbSMasahiro Yamada 		switch (input_mode) {
3030a9064fbSMasahiro Yamada 		case oldconfig:
3040a9064fbSMasahiro Yamada 		case silentoldconfig:
3050a9064fbSMasahiro Yamada 			if (!is_new) {
3060a9064fbSMasahiro Yamada 				cnt = def;
3070a9064fbSMasahiro Yamada 				printf("%d\n", cnt);
3080a9064fbSMasahiro Yamada 				break;
3090a9064fbSMasahiro Yamada 			}
3100a9064fbSMasahiro Yamada 			check_stdin();
3110a9064fbSMasahiro Yamada 			/* fall through */
3120a9064fbSMasahiro Yamada 		case oldaskconfig:
3130a9064fbSMasahiro Yamada 			fflush(stdout);
3140a9064fbSMasahiro Yamada 			xfgets(line, 128, stdin);
3150a9064fbSMasahiro Yamada 			strip(line);
3160a9064fbSMasahiro Yamada 			if (line[0] == '?') {
3170a9064fbSMasahiro Yamada 				print_help(menu);
3180a9064fbSMasahiro Yamada 				continue;
3190a9064fbSMasahiro Yamada 			}
3200a9064fbSMasahiro Yamada 			if (!line[0])
3210a9064fbSMasahiro Yamada 				cnt = def;
3220a9064fbSMasahiro Yamada 			else if (isdigit(line[0]))
3230a9064fbSMasahiro Yamada 				cnt = atoi(line);
3240a9064fbSMasahiro Yamada 			else
3250a9064fbSMasahiro Yamada 				continue;
3260a9064fbSMasahiro Yamada 			break;
3270a9064fbSMasahiro Yamada 		default:
3280a9064fbSMasahiro Yamada 			break;
3290a9064fbSMasahiro Yamada 		}
3300a9064fbSMasahiro Yamada 
3310a9064fbSMasahiro Yamada 	conf_childs:
3320a9064fbSMasahiro Yamada 		for (child = menu->list; child; child = child->next) {
3330a9064fbSMasahiro Yamada 			if (!child->sym || !menu_is_visible(child))
3340a9064fbSMasahiro Yamada 				continue;
3350a9064fbSMasahiro Yamada 			if (!--cnt)
3360a9064fbSMasahiro Yamada 				break;
3370a9064fbSMasahiro Yamada 		}
3380a9064fbSMasahiro Yamada 		if (!child)
3390a9064fbSMasahiro Yamada 			continue;
3400a9064fbSMasahiro Yamada 		if (line[0] && line[strlen(line) - 1] == '?') {
3410a9064fbSMasahiro Yamada 			print_help(child);
3420a9064fbSMasahiro Yamada 			continue;
3430a9064fbSMasahiro Yamada 		}
3440a9064fbSMasahiro Yamada 		sym_set_choice_value(sym, child->sym);
3450a9064fbSMasahiro Yamada 		for (child = child->list; child; child = child->next) {
3460a9064fbSMasahiro Yamada 			indent += 2;
3470a9064fbSMasahiro Yamada 			conf(child);
3480a9064fbSMasahiro Yamada 			indent -= 2;
3490a9064fbSMasahiro Yamada 		}
3500a9064fbSMasahiro Yamada 		return 1;
3510a9064fbSMasahiro Yamada 	}
3520a9064fbSMasahiro Yamada }
3530a9064fbSMasahiro Yamada 
3540a9064fbSMasahiro Yamada static void conf(struct menu *menu)
3550a9064fbSMasahiro Yamada {
3560a9064fbSMasahiro Yamada 	struct symbol *sym;
3570a9064fbSMasahiro Yamada 	struct property *prop;
3580a9064fbSMasahiro Yamada 	struct menu *child;
3590a9064fbSMasahiro Yamada 
3600a9064fbSMasahiro Yamada 	if (!menu_is_visible(menu))
3610a9064fbSMasahiro Yamada 		return;
3620a9064fbSMasahiro Yamada 
3630a9064fbSMasahiro Yamada 	sym = menu->sym;
3640a9064fbSMasahiro Yamada 	prop = menu->prompt;
3650a9064fbSMasahiro Yamada 	if (prop) {
3660a9064fbSMasahiro Yamada 		const char *prompt;
3670a9064fbSMasahiro Yamada 
3680a9064fbSMasahiro Yamada 		switch (prop->type) {
3690a9064fbSMasahiro Yamada 		case P_MENU:
3700a9064fbSMasahiro Yamada 			if ((input_mode == silentoldconfig ||
3710a9064fbSMasahiro Yamada 			     input_mode == listnewconfig ||
3720a9064fbSMasahiro Yamada 			     input_mode == olddefconfig) &&
3730a9064fbSMasahiro Yamada 			    rootEntry != menu) {
3740a9064fbSMasahiro Yamada 				check_conf(menu);
3750a9064fbSMasahiro Yamada 				return;
3760a9064fbSMasahiro Yamada 			}
3770a9064fbSMasahiro Yamada 			/* fall through */
3780a9064fbSMasahiro Yamada 		case P_COMMENT:
3790a9064fbSMasahiro Yamada 			prompt = menu_get_prompt(menu);
3800a9064fbSMasahiro Yamada 			if (prompt)
3810a9064fbSMasahiro Yamada 				printf("%*c\n%*c %s\n%*c\n",
3820a9064fbSMasahiro Yamada 					indent, '*',
3830a9064fbSMasahiro Yamada 					indent, '*', _(prompt),
3840a9064fbSMasahiro Yamada 					indent, '*');
3850a9064fbSMasahiro Yamada 		default:
3860a9064fbSMasahiro Yamada 			;
3870a9064fbSMasahiro Yamada 		}
3880a9064fbSMasahiro Yamada 	}
3890a9064fbSMasahiro Yamada 
3900a9064fbSMasahiro Yamada 	if (!sym)
3910a9064fbSMasahiro Yamada 		goto conf_childs;
3920a9064fbSMasahiro Yamada 
3930a9064fbSMasahiro Yamada 	if (sym_is_choice(sym)) {
3940a9064fbSMasahiro Yamada 		conf_choice(menu);
3950a9064fbSMasahiro Yamada 		if (sym->curr.tri != mod)
3960a9064fbSMasahiro Yamada 			return;
3970a9064fbSMasahiro Yamada 		goto conf_childs;
3980a9064fbSMasahiro Yamada 	}
3990a9064fbSMasahiro Yamada 
4000a9064fbSMasahiro Yamada 	switch (sym->type) {
4010a9064fbSMasahiro Yamada 	case S_INT:
4020a9064fbSMasahiro Yamada 	case S_HEX:
4030a9064fbSMasahiro Yamada 	case S_STRING:
4040a9064fbSMasahiro Yamada 		conf_string(menu);
4050a9064fbSMasahiro Yamada 		break;
4060a9064fbSMasahiro Yamada 	default:
4070a9064fbSMasahiro Yamada 		conf_sym(menu);
4080a9064fbSMasahiro Yamada 		break;
4090a9064fbSMasahiro Yamada 	}
4100a9064fbSMasahiro Yamada 
4110a9064fbSMasahiro Yamada conf_childs:
4120a9064fbSMasahiro Yamada 	if (sym)
4130a9064fbSMasahiro Yamada 		indent += 2;
4140a9064fbSMasahiro Yamada 	for (child = menu->list; child; child = child->next)
4150a9064fbSMasahiro Yamada 		conf(child);
4160a9064fbSMasahiro Yamada 	if (sym)
4170a9064fbSMasahiro Yamada 		indent -= 2;
4180a9064fbSMasahiro Yamada }
4190a9064fbSMasahiro Yamada 
4200a9064fbSMasahiro Yamada static void check_conf(struct menu *menu)
4210a9064fbSMasahiro Yamada {
4220a9064fbSMasahiro Yamada 	struct symbol *sym;
4230a9064fbSMasahiro Yamada 	struct menu *child;
4240a9064fbSMasahiro Yamada 
4250a9064fbSMasahiro Yamada 	if (!menu_is_visible(menu))
4260a9064fbSMasahiro Yamada 		return;
4270a9064fbSMasahiro Yamada 
4280a9064fbSMasahiro Yamada 	sym = menu->sym;
4290a9064fbSMasahiro Yamada 	if (sym && !sym_has_value(sym)) {
4300a9064fbSMasahiro Yamada 		if (sym_is_changable(sym) ||
4310a9064fbSMasahiro Yamada 		    (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) {
4320a9064fbSMasahiro Yamada 			if (input_mode == listnewconfig) {
4330a9064fbSMasahiro Yamada 				if (sym->name && !sym_is_choice_value(sym)) {
4340a9064fbSMasahiro Yamada 					printf("%s%s\n", CONFIG_, sym->name);
4350a9064fbSMasahiro Yamada 				}
4360a9064fbSMasahiro Yamada 			} else if (input_mode != olddefconfig) {
4370a9064fbSMasahiro Yamada 				if (!conf_cnt++)
4380a9064fbSMasahiro Yamada 					printf(_("*\n* Restart config...\n*\n"));
4390a9064fbSMasahiro Yamada 				rootEntry = menu_get_parent_menu(menu);
4400a9064fbSMasahiro Yamada 				conf(rootEntry);
4410a9064fbSMasahiro Yamada 			}
4420a9064fbSMasahiro Yamada 		}
4430a9064fbSMasahiro Yamada 	}
4440a9064fbSMasahiro Yamada 
4450a9064fbSMasahiro Yamada 	for (child = menu->list; child; child = child->next)
4460a9064fbSMasahiro Yamada 		check_conf(child);
4470a9064fbSMasahiro Yamada }
4480a9064fbSMasahiro Yamada 
4490a9064fbSMasahiro Yamada static struct option long_opts[] = {
4500a9064fbSMasahiro Yamada 	{"oldaskconfig",    no_argument,       NULL, oldaskconfig},
4510a9064fbSMasahiro Yamada 	{"oldconfig",       no_argument,       NULL, oldconfig},
4520a9064fbSMasahiro Yamada 	{"silentoldconfig", no_argument,       NULL, silentoldconfig},
4530a9064fbSMasahiro Yamada 	{"defconfig",       optional_argument, NULL, defconfig},
4540a9064fbSMasahiro Yamada 	{"savedefconfig",   required_argument, NULL, savedefconfig},
4550a9064fbSMasahiro Yamada 	{"allnoconfig",     no_argument,       NULL, allnoconfig},
4560a9064fbSMasahiro Yamada 	{"allyesconfig",    no_argument,       NULL, allyesconfig},
4570a9064fbSMasahiro Yamada 	{"allmodconfig",    no_argument,       NULL, allmodconfig},
4580a9064fbSMasahiro Yamada 	{"alldefconfig",    no_argument,       NULL, alldefconfig},
4590a9064fbSMasahiro Yamada 	{"randconfig",      no_argument,       NULL, randconfig},
4600a9064fbSMasahiro Yamada 	{"listnewconfig",   no_argument,       NULL, listnewconfig},
4610a9064fbSMasahiro Yamada 	{"olddefconfig",    no_argument,       NULL, olddefconfig},
4620a9064fbSMasahiro Yamada 	/*
4630a9064fbSMasahiro Yamada 	 * oldnoconfig is an alias of olddefconfig, because people already
4640a9064fbSMasahiro Yamada 	 * are dependent on its behavior(sets new symbols to their default
4650a9064fbSMasahiro Yamada 	 * value but not 'n') with the counter-intuitive name.
4660a9064fbSMasahiro Yamada 	 */
4670a9064fbSMasahiro Yamada 	{"oldnoconfig",     no_argument,       NULL, olddefconfig},
4680a9064fbSMasahiro Yamada 	{NULL, 0, NULL, 0}
4690a9064fbSMasahiro Yamada };
4700a9064fbSMasahiro Yamada 
4710a9064fbSMasahiro Yamada static void conf_usage(const char *progname)
4720a9064fbSMasahiro Yamada {
4730a9064fbSMasahiro Yamada 
474*9b5f0b1dSMasahiro Yamada 	printf("Usage: %s [-s] [option] <kconfig-file>\n", progname);
4750a9064fbSMasahiro Yamada 	printf("[option] is _one_ of the following:\n");
4760a9064fbSMasahiro Yamada 	printf("  --listnewconfig         List new options\n");
4770a9064fbSMasahiro Yamada 	printf("  --oldaskconfig          Start a new configuration using a line-oriented program\n");
4780a9064fbSMasahiro Yamada 	printf("  --oldconfig             Update a configuration using a provided .config as base\n");
4790a9064fbSMasahiro Yamada 	printf("  --silentoldconfig       Same as oldconfig, but quietly, additionally update deps\n");
4800a9064fbSMasahiro Yamada 	printf("  --olddefconfig          Same as silentoldconfig but sets new symbols to their default value\n");
4810a9064fbSMasahiro Yamada 	printf("  --oldnoconfig           An alias of olddefconfig\n");
4820a9064fbSMasahiro Yamada 	printf("  --defconfig <file>      New config with default defined in <file>\n");
4830a9064fbSMasahiro Yamada 	printf("  --savedefconfig <file>  Save the minimal current configuration to <file>\n");
4840a9064fbSMasahiro Yamada 	printf("  --allnoconfig           New config where all options are answered with no\n");
4850a9064fbSMasahiro Yamada 	printf("  --allyesconfig          New config where all options are answered with yes\n");
4860a9064fbSMasahiro Yamada 	printf("  --allmodconfig          New config where all options are answered with mod\n");
4870a9064fbSMasahiro Yamada 	printf("  --alldefconfig          New config with all symbols set to default\n");
4880a9064fbSMasahiro Yamada 	printf("  --randconfig            New config with random answer to all options\n");
4890a9064fbSMasahiro Yamada }
4900a9064fbSMasahiro Yamada 
4910a9064fbSMasahiro Yamada int main(int ac, char **av)
4920a9064fbSMasahiro Yamada {
4930a9064fbSMasahiro Yamada 	const char *progname = av[0];
4940a9064fbSMasahiro Yamada 	int opt;
4950a9064fbSMasahiro Yamada 	const char *name, *defconfig_file = NULL /* gcc uninit */;
4960a9064fbSMasahiro Yamada 	struct stat tmpstat;
4970a9064fbSMasahiro Yamada 
4980a9064fbSMasahiro Yamada 	setlocale(LC_ALL, "");
4990a9064fbSMasahiro Yamada 	bindtextdomain(PACKAGE, LOCALEDIR);
5000a9064fbSMasahiro Yamada 	textdomain(PACKAGE);
5010a9064fbSMasahiro Yamada 
5020a9064fbSMasahiro Yamada 	tty_stdio = isatty(0) && isatty(1) && isatty(2);
5030a9064fbSMasahiro Yamada 
504*9b5f0b1dSMasahiro Yamada 	while ((opt = getopt_long(ac, av, "s", long_opts, NULL)) != -1) {
505*9b5f0b1dSMasahiro Yamada 		if (opt == 's') {
506*9b5f0b1dSMasahiro Yamada 			conf_set_message_callback(NULL);
507*9b5f0b1dSMasahiro Yamada 			continue;
508*9b5f0b1dSMasahiro Yamada 		}
5090a9064fbSMasahiro Yamada 		input_mode = (enum input_mode)opt;
5100a9064fbSMasahiro Yamada 		switch (opt) {
5110a9064fbSMasahiro Yamada 		case silentoldconfig:
5120a9064fbSMasahiro Yamada 			sync_kconfig = 1;
5130a9064fbSMasahiro Yamada 			break;
5140a9064fbSMasahiro Yamada 		case defconfig:
5150a9064fbSMasahiro Yamada 		case savedefconfig:
5160a9064fbSMasahiro Yamada 			defconfig_file = optarg;
5170a9064fbSMasahiro Yamada 			break;
5180a9064fbSMasahiro Yamada 		case randconfig:
5190a9064fbSMasahiro Yamada 		{
5200a9064fbSMasahiro Yamada 			struct timeval now;
5210a9064fbSMasahiro Yamada 			unsigned int seed;
5220a9064fbSMasahiro Yamada 			char *seed_env;
5230a9064fbSMasahiro Yamada 
5240a9064fbSMasahiro Yamada 			/*
5250a9064fbSMasahiro Yamada 			 * Use microseconds derived seed,
5260a9064fbSMasahiro Yamada 			 * compensate for systems where it may be zero
5270a9064fbSMasahiro Yamada 			 */
5280a9064fbSMasahiro Yamada 			gettimeofday(&now, NULL);
5290a9064fbSMasahiro Yamada 			seed = (unsigned int)((now.tv_sec + 1) * (now.tv_usec + 1));
5300a9064fbSMasahiro Yamada 
5310a9064fbSMasahiro Yamada 			seed_env = getenv("KCONFIG_SEED");
5320a9064fbSMasahiro Yamada 			if( seed_env && *seed_env ) {
5330a9064fbSMasahiro Yamada 				char *endp;
5340a9064fbSMasahiro Yamada 				int tmp = (int)strtol(seed_env, &endp, 0);
5350a9064fbSMasahiro Yamada 				if (*endp == '\0') {
5360a9064fbSMasahiro Yamada 					seed = tmp;
5370a9064fbSMasahiro Yamada 				}
5380a9064fbSMasahiro Yamada 			}
5390a9064fbSMasahiro Yamada 			fprintf( stderr, "KCONFIG_SEED=0x%X\n", seed );
5400a9064fbSMasahiro Yamada 			srand(seed);
5410a9064fbSMasahiro Yamada 			break;
5420a9064fbSMasahiro Yamada 		}
5430a9064fbSMasahiro Yamada 		case oldaskconfig:
5440a9064fbSMasahiro Yamada 		case oldconfig:
5450a9064fbSMasahiro Yamada 		case allnoconfig:
5460a9064fbSMasahiro Yamada 		case allyesconfig:
5470a9064fbSMasahiro Yamada 		case allmodconfig:
5480a9064fbSMasahiro Yamada 		case alldefconfig:
5490a9064fbSMasahiro Yamada 		case listnewconfig:
5500a9064fbSMasahiro Yamada 		case olddefconfig:
5510a9064fbSMasahiro Yamada 			break;
5520a9064fbSMasahiro Yamada 		case '?':
5530a9064fbSMasahiro Yamada 			conf_usage(progname);
5540a9064fbSMasahiro Yamada 			exit(1);
5550a9064fbSMasahiro Yamada 			break;
5560a9064fbSMasahiro Yamada 		}
5570a9064fbSMasahiro Yamada 	}
5580a9064fbSMasahiro Yamada 	if (ac == optind) {
5590a9064fbSMasahiro Yamada 		printf(_("%s: Kconfig file missing\n"), av[0]);
5600a9064fbSMasahiro Yamada 		conf_usage(progname);
5610a9064fbSMasahiro Yamada 		exit(1);
5620a9064fbSMasahiro Yamada 	}
5630a9064fbSMasahiro Yamada 	name = av[optind];
5640a9064fbSMasahiro Yamada 	conf_parse(name);
5650a9064fbSMasahiro Yamada 	//zconfdump(stdout);
5660a9064fbSMasahiro Yamada 	if (sync_kconfig) {
5670a9064fbSMasahiro Yamada 		name = conf_get_configname();
5680a9064fbSMasahiro Yamada 		if (stat(name, &tmpstat)) {
5690a9064fbSMasahiro Yamada 			fprintf(stderr, _("***\n"
5700a9064fbSMasahiro Yamada 				"*** Configuration file \"%s\" not found!\n"
5710a9064fbSMasahiro Yamada 				"***\n"
5720a9064fbSMasahiro Yamada 				"*** Please run some configurator (e.g. \"make oldconfig\" or\n"
5730a9064fbSMasahiro Yamada 				"*** \"make menuconfig\" or \"make xconfig\").\n"
5740a9064fbSMasahiro Yamada 				"***\n"), name);
5750a9064fbSMasahiro Yamada 			exit(1);
5760a9064fbSMasahiro Yamada 		}
5770a9064fbSMasahiro Yamada 	}
5780a9064fbSMasahiro Yamada 
5790a9064fbSMasahiro Yamada 	switch (input_mode) {
5800a9064fbSMasahiro Yamada 	case defconfig:
5810a9064fbSMasahiro Yamada 		if (!defconfig_file)
5820a9064fbSMasahiro Yamada 			defconfig_file = conf_get_default_confname();
5830a9064fbSMasahiro Yamada 		if (conf_read(defconfig_file)) {
5840a9064fbSMasahiro Yamada 			printf(_("***\n"
5850a9064fbSMasahiro Yamada 				"*** Can't find default configuration \"%s\"!\n"
5860a9064fbSMasahiro Yamada 				"***\n"), defconfig_file);
5870a9064fbSMasahiro Yamada 			exit(1);
5880a9064fbSMasahiro Yamada 		}
5890a9064fbSMasahiro Yamada 		break;
5900a9064fbSMasahiro Yamada 	case savedefconfig:
5910a9064fbSMasahiro Yamada 	case silentoldconfig:
5920a9064fbSMasahiro Yamada 	case oldaskconfig:
5930a9064fbSMasahiro Yamada 	case oldconfig:
5940a9064fbSMasahiro Yamada 	case listnewconfig:
5950a9064fbSMasahiro Yamada 	case olddefconfig:
5960a9064fbSMasahiro Yamada 		conf_read(NULL);
5970a9064fbSMasahiro Yamada 		break;
5980a9064fbSMasahiro Yamada 	case allnoconfig:
5990a9064fbSMasahiro Yamada 	case allyesconfig:
6000a9064fbSMasahiro Yamada 	case allmodconfig:
6010a9064fbSMasahiro Yamada 	case alldefconfig:
6020a9064fbSMasahiro Yamada 	case randconfig:
6030a9064fbSMasahiro Yamada 		name = getenv("KCONFIG_ALLCONFIG");
6040a9064fbSMasahiro Yamada 		if (!name)
6050a9064fbSMasahiro Yamada 			break;
6060a9064fbSMasahiro Yamada 		if ((strcmp(name, "") != 0) && (strcmp(name, "1") != 0)) {
6070a9064fbSMasahiro Yamada 			if (conf_read_simple(name, S_DEF_USER)) {
6080a9064fbSMasahiro Yamada 				fprintf(stderr,
6090a9064fbSMasahiro Yamada 					_("*** Can't read seed configuration \"%s\"!\n"),
6100a9064fbSMasahiro Yamada 					name);
6110a9064fbSMasahiro Yamada 				exit(1);
6120a9064fbSMasahiro Yamada 			}
6130a9064fbSMasahiro Yamada 			break;
6140a9064fbSMasahiro Yamada 		}
6150a9064fbSMasahiro Yamada 		switch (input_mode) {
6160a9064fbSMasahiro Yamada 		case allnoconfig:	name = "allno.config"; break;
6170a9064fbSMasahiro Yamada 		case allyesconfig:	name = "allyes.config"; break;
6180a9064fbSMasahiro Yamada 		case allmodconfig:	name = "allmod.config"; break;
6190a9064fbSMasahiro Yamada 		case alldefconfig:	name = "alldef.config"; break;
6200a9064fbSMasahiro Yamada 		case randconfig:	name = "allrandom.config"; break;
6210a9064fbSMasahiro Yamada 		default: break;
6220a9064fbSMasahiro Yamada 		}
6230a9064fbSMasahiro Yamada 		if (conf_read_simple(name, S_DEF_USER) &&
6240a9064fbSMasahiro Yamada 		    conf_read_simple("all.config", S_DEF_USER)) {
6250a9064fbSMasahiro Yamada 			fprintf(stderr,
6260a9064fbSMasahiro Yamada 				_("*** KCONFIG_ALLCONFIG set, but no \"%s\" or \"all.config\" file found\n"),
6270a9064fbSMasahiro Yamada 				name);
6280a9064fbSMasahiro Yamada 			exit(1);
6290a9064fbSMasahiro Yamada 		}
6300a9064fbSMasahiro Yamada 		break;
6310a9064fbSMasahiro Yamada 	default:
6320a9064fbSMasahiro Yamada 		break;
6330a9064fbSMasahiro Yamada 	}
6340a9064fbSMasahiro Yamada 
6350a9064fbSMasahiro Yamada 	if (sync_kconfig) {
6360a9064fbSMasahiro Yamada 		if (conf_get_changed()) {
6370a9064fbSMasahiro Yamada 			name = getenv("KCONFIG_NOSILENTUPDATE");
6380a9064fbSMasahiro Yamada 			if (name && *name) {
6390a9064fbSMasahiro Yamada 				fprintf(stderr,
6400a9064fbSMasahiro Yamada 					_("\n*** The configuration requires explicit update.\n\n"));
6410a9064fbSMasahiro Yamada 				return 1;
6420a9064fbSMasahiro Yamada 			}
6430a9064fbSMasahiro Yamada 		}
6440a9064fbSMasahiro Yamada 		valid_stdin = tty_stdio;
6450a9064fbSMasahiro Yamada 	}
6460a9064fbSMasahiro Yamada 
6470a9064fbSMasahiro Yamada 	switch (input_mode) {
6480a9064fbSMasahiro Yamada 	case allnoconfig:
6490a9064fbSMasahiro Yamada 		conf_set_all_new_symbols(def_no);
6500a9064fbSMasahiro Yamada 		break;
6510a9064fbSMasahiro Yamada 	case allyesconfig:
6520a9064fbSMasahiro Yamada 		conf_set_all_new_symbols(def_yes);
6530a9064fbSMasahiro Yamada 		break;
6540a9064fbSMasahiro Yamada 	case allmodconfig:
6550a9064fbSMasahiro Yamada 		conf_set_all_new_symbols(def_mod);
6560a9064fbSMasahiro Yamada 		break;
6570a9064fbSMasahiro Yamada 	case alldefconfig:
6580a9064fbSMasahiro Yamada 		conf_set_all_new_symbols(def_default);
6590a9064fbSMasahiro Yamada 		break;
6600a9064fbSMasahiro Yamada 	case randconfig:
6610a9064fbSMasahiro Yamada 		/* Really nothing to do in this loop */
6620a9064fbSMasahiro Yamada 		while (conf_set_all_new_symbols(def_random)) ;
6630a9064fbSMasahiro Yamada 		break;
6640a9064fbSMasahiro Yamada 	case defconfig:
6650a9064fbSMasahiro Yamada 		conf_set_all_new_symbols(def_default);
6660a9064fbSMasahiro Yamada 		break;
6670a9064fbSMasahiro Yamada 	case savedefconfig:
6680a9064fbSMasahiro Yamada 		break;
6690a9064fbSMasahiro Yamada 	case oldaskconfig:
6700a9064fbSMasahiro Yamada 		rootEntry = &rootmenu;
6710a9064fbSMasahiro Yamada 		conf(&rootmenu);
6720a9064fbSMasahiro Yamada 		input_mode = silentoldconfig;
6730a9064fbSMasahiro Yamada 		/* fall through */
6740a9064fbSMasahiro Yamada 	case oldconfig:
6750a9064fbSMasahiro Yamada 	case listnewconfig:
6760a9064fbSMasahiro Yamada 	case olddefconfig:
6770a9064fbSMasahiro Yamada 	case silentoldconfig:
6780a9064fbSMasahiro Yamada 		/* Update until a loop caused no more changes */
6790a9064fbSMasahiro Yamada 		do {
6800a9064fbSMasahiro Yamada 			conf_cnt = 0;
6810a9064fbSMasahiro Yamada 			check_conf(&rootmenu);
6820a9064fbSMasahiro Yamada 		} while (conf_cnt &&
6830a9064fbSMasahiro Yamada 			 (input_mode != listnewconfig &&
6840a9064fbSMasahiro Yamada 			  input_mode != olddefconfig));
6850a9064fbSMasahiro Yamada 		break;
6860a9064fbSMasahiro Yamada 	}
6870a9064fbSMasahiro Yamada 
6880a9064fbSMasahiro Yamada 	if (sync_kconfig) {
6890a9064fbSMasahiro Yamada 		/* silentoldconfig is used during the build so we shall update autoconf.
6900a9064fbSMasahiro Yamada 		 * All other commands are only used to generate a config.
6910a9064fbSMasahiro Yamada 		 */
6920a9064fbSMasahiro Yamada 		if (conf_get_changed() && conf_write(NULL)) {
6930a9064fbSMasahiro Yamada 			fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n"));
6940a9064fbSMasahiro Yamada 			exit(1);
6950a9064fbSMasahiro Yamada 		}
6960a9064fbSMasahiro Yamada 		if (conf_write_autoconf()) {
6970a9064fbSMasahiro Yamada 			fprintf(stderr, _("\n*** Error during update of the configuration.\n\n"));
6980a9064fbSMasahiro Yamada 			return 1;
6990a9064fbSMasahiro Yamada 		}
7000a9064fbSMasahiro Yamada 	} else if (input_mode == savedefconfig) {
7010a9064fbSMasahiro Yamada 		if (conf_write_defconfig(defconfig_file)) {
7020a9064fbSMasahiro Yamada 			fprintf(stderr, _("n*** Error while saving defconfig to: %s\n\n"),
7030a9064fbSMasahiro Yamada 				defconfig_file);
7040a9064fbSMasahiro Yamada 			return 1;
7050a9064fbSMasahiro Yamada 		}
7060a9064fbSMasahiro Yamada 	} else if (input_mode != listnewconfig) {
7070a9064fbSMasahiro Yamada 		if (conf_write(NULL)) {
7080a9064fbSMasahiro Yamada 			fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n"));
7090a9064fbSMasahiro Yamada 			exit(1);
7100a9064fbSMasahiro Yamada 		}
7110a9064fbSMasahiro Yamada 	}
7120a9064fbSMasahiro Yamada 	return 0;
7130a9064fbSMasahiro Yamada }
7140a9064fbSMasahiro Yamada 
7150a9064fbSMasahiro Yamada /*
7160a9064fbSMasahiro Yamada  * Helper function to facilitate fgets() by Jean Sacren.
7170a9064fbSMasahiro Yamada  */
7180a9064fbSMasahiro Yamada void xfgets(char *str, int size, FILE *in)
7190a9064fbSMasahiro Yamada {
7200a9064fbSMasahiro Yamada 	if (fgets(str, size, in) == NULL)
7210a9064fbSMasahiro Yamada 		fprintf(stderr, "\nError in reading or end of file.\n");
7220a9064fbSMasahiro Yamada }
723