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