• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/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 * Introduced single menu mode (show all sub-menus in one large tree).
6 * 2002-11-06 Petr Baudis <pasky@ucw.cz>
7 *
8 * i18n, 2005, Arnaldo Carvalho de Melo <acme@conectiva.com.br>
9 */
10
11#include <ctype.h>
12#include <errno.h>
13#include <fcntl.h>
14#include <limits.h>
15#include <stdarg.h>
16#include <stdlib.h>
17#include <string.h>
18#include <unistd.h>
19#include <locale.h>
20
21#define LKC_DIRECT_LINK
22#include "lkc.h"
23#include "lxdialog/dialog.h"
24
25static const char mconf_readme[] = N_(
26"Overview\n"
27"--------\n"
28"Some kernel features may be built directly into the kernel.\n"
29"Some may be made into loadable runtime modules.  Some features\n"
30"may be completely removed altogether.  There are also certain\n"
31"kernel parameters which are not really features, but must be\n"
32"entered in as decimal or hexadecimal numbers or possibly text.\n"
33"\n"
34"Menu items beginning with following braces represent features that\n"
35"  [ ] can be built in or removed\n"
36"  < > can be built in, modularized or removed\n"
37"  { } can be built in or modularized (selected by other feature)\n"
38"  - - are selected by other feature,\n"
39"while *, M or whitespace inside braces means to build in, build as\n"
40"a module or to exclude the feature respectively.\n"
41"\n"
42"To change any of these features, highlight it with the cursor\n"
43"keys and press <Y> to build it in, <M> to make it a module or\n"
44"<N> to removed it.  You may also press the <Space Bar> to cycle\n"
45"through the available options (ie. Y->N->M->Y).\n"
46"\n"
47"Some additional keyboard hints:\n"
48"\n"
49"Menus\n"
50"----------\n"
51"o  Use the Up/Down arrow keys (cursor keys) to highlight the item\n"
52"   you wish to change or submenu wish to select and press <Enter>.\n"
53"   Submenus are designated by \"--->\".\n"
54"\n"
55"   Shortcut: Press the option's highlighted letter (hotkey).\n"
56"             Pressing a hotkey more than once will sequence\n"
57"             through all visible items which use that hotkey.\n"
58"\n"
59"   You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll\n"
60"   unseen options into view.\n"
61"\n"
62"o  To exit a menu use the cursor keys to highlight the <Exit> button\n"
63"   and press <ENTER>.\n"
64"\n"
65"   Shortcut: Press <ESC><ESC> or <E> or <X> if there is no hotkey\n"
66"             using those letters.  You may press a single <ESC>, but\n"
67"             there is a delayed response which you may find annoying.\n"
68"\n"
69"   Also, the <TAB> and cursor keys will cycle between <Select>,\n"
70"   <Exit> and <Help>.\n"
71"\n"
72"o  To get help with an item, use the cursor keys to highlight <Help>\n"
73"   and press <ENTER>.\n"
74"\n"
75"   Shortcut: Press <H> or <?>.\n"
76"\n"
77"o  To toggle the display of hidden options, press <Z>.\n"
78"\n"
79"\n"
80"Radiolists  (Choice lists)\n"
81"-----------\n"
82"o  Use the cursor keys to select the option you wish to set and press\n"
83"   <S> or the <SPACE BAR>.\n"
84"\n"
85"   Shortcut: Press the first letter of the option you wish to set then\n"
86"             press <S> or <SPACE BAR>.\n"
87"\n"
88"o  To see available help for the item, use the cursor keys to highlight\n"
89"   <Help> and Press <ENTER>.\n"
90"\n"
91"   Shortcut: Press <H> or <?>.\n"
92"\n"
93"   Also, the <TAB> and cursor keys will cycle between <Select> and\n"
94"   <Help>\n"
95"\n"
96"\n"
97"Data Entry\n"
98"-----------\n"
99"o  Enter the requested information and press <ENTER>\n"
100"   If you are entering hexadecimal values, it is not necessary to\n"
101"   add the '0x' prefix to the entry.\n"
102"\n"
103"o  For help, use the <TAB> or cursor keys to highlight the help option\n"
104"   and press <ENTER>.  You can try <TAB><H> as well.\n"
105"\n"
106"\n"
107"Text Box    (Help Window)\n"
108"--------\n"
109"o  Use the cursor keys to scroll up/down/left/right.  The VI editor\n"
110"   keys h,j,k,l function here as do <SPACE BAR> and <B> for those\n"
111"   who are familiar with less and lynx.\n"
112"\n"
113"o  Press <E>, <X>, <Enter> or <Esc><Esc> to exit.\n"
114"\n"
115"\n"
116"Alternate Configuration Files\n"
117"-----------------------------\n"
118"Menuconfig supports the use of alternate configuration files for\n"
119"those who, for various reasons, find it necessary to switch\n"
120"between different kernel configurations.\n"
121"\n"
122"At the end of the main menu you will find two options.  One is\n"
123"for saving the current configuration to a file of your choosing.\n"
124"The other option is for loading a previously saved alternate\n"
125"configuration.\n"
126"\n"
127"Even if you don't use alternate configuration files, but you\n"
128"find during a Menuconfig session that you have completely messed\n"
129"up your settings, you may use the \"Load Alternate...\" option to\n"
130"restore your previously saved settings from \".config\" without\n"
131"restarting Menuconfig.\n"
132"\n"
133"Other information\n"
134"-----------------\n"
135"If you use Menuconfig in an XTERM window make sure you have your\n"
136"$TERM variable set to point to a xterm definition which supports color.\n"
137"Otherwise, Menuconfig will look rather bad.  Menuconfig will not\n"
138"display correctly in a RXVT window because rxvt displays only one\n"
139"intensity of color, bright.\n"
140"\n"
141"Menuconfig will display larger menus on screens or xterms which are\n"
142"set to display more than the standard 25 row by 80 column geometry.\n"
143"In order for this to work, the \"stty size\" command must be able to\n"
144"display the screen's current row and column geometry.  I STRONGLY\n"
145"RECOMMEND that you make sure you do NOT have the shell variables\n"
146"LINES and COLUMNS exported into your environment.  Some distributions\n"
147"export those variables via /etc/profile.  Some ncurses programs can\n"
148"become confused when those variables (LINES & COLUMNS) don't reflect\n"
149"the true screen size.\n"
150"\n"
151"Optional personality available\n"
152"------------------------------\n"
153"If you prefer to have all of the kernel options listed in a single\n"
154"menu, rather than the default multimenu hierarchy, run the menuconfig\n"
155"with MENUCONFIG_MODE environment variable set to single_menu. Example:\n"
156"\n"
157"make MENUCONFIG_MODE=single_menu menuconfig\n"
158"\n"
159"<Enter> will then unroll the appropriate category, or enfold it if it\n"
160"is already unrolled.\n"
161"\n"
162"Note that this mode can eventually be a little more CPU expensive\n"
163"(especially with a larger number of unrolled categories) than the\n"
164"default mode.\n"
165"\n"
166"Different color themes available\n"
167"--------------------------------\n"
168"It is possible to select different color themes using the variable\n"
169"MENUCONFIG_COLOR. To select a theme use:\n"
170"\n"
171"make MENUCONFIG_COLOR=<theme> menuconfig\n"
172"\n"
173"Available themes are\n"
174" mono       => selects colors suitable for monochrome displays\n"
175" blackbg    => selects a color scheme with black background\n"
176" classic    => theme with blue background. The classic look\n"
177" bluetitle  => a LCD friendly version of classic. (default)\n"
178"\n"),
179menu_instructions[] = N_(
180	"Arrow keys navigate the menu.  "
181	"<Enter> selects submenus --->.  "
182	"Highlighted letters are hotkeys.  "
183	"Pressing <Y> includes, <N> excludes, <M> modularizes features.  "
184	"Press <Esc><Esc> to exit, <?> for Help, </> for Search.  "
185	"Legend: [*] built-in  [ ] excluded  <M> module  < > module capable"),
186radiolist_instructions[] = N_(
187	"Use the arrow keys to navigate this window or "
188	"press the hotkey of the item you wish to select "
189	"followed by the <SPACE BAR>. "
190	"Press <?> for additional information about this option."),
191inputbox_instructions_int[] = N_(
192	"Please enter a decimal value. "
193	"Fractions will not be accepted.  "
194	"Use the <TAB> key to move from the input field to the buttons below it."),
195inputbox_instructions_hex[] = N_(
196	"Please enter a hexadecimal value. "
197	"Use the <TAB> key to move from the input field to the buttons below it."),
198inputbox_instructions_string[] = N_(
199	"Please enter a string value. "
200	"Use the <TAB> key to move from the input field to the buttons below it."),
201setmod_text[] = N_(
202	"This feature depends on another which has been configured as a module.\n"
203	"As a result, this feature will be built as a module."),
204load_config_text[] = N_(
205	"Enter the name of the configuration file you wish to load.  "
206	"Accept the name shown to restore the configuration you "
207	"last retrieved.  Leave blank to abort."),
208load_config_help[] = N_(
209	"\n"
210	"For various reasons, one may wish to keep several different kernel\n"
211	"configurations available on a single machine.\n"
212	"\n"
213	"If you have saved a previous configuration in a file other than the\n"
214	"kernel's default, entering the name of the file here will allow you\n"
215	"to modify that configuration.\n"
216	"\n"
217	"If you are uncertain, then you have probably never used alternate\n"
218	"configuration files. You should therefore leave this blank to abort.\n"),
219save_config_text[] = N_(
220	"Enter a filename to which this configuration should be saved "
221	"as an alternate.  Leave blank to abort."),
222save_config_help[] = N_(
223	"\n"
224	"For various reasons, one may wish to keep different kernel\n"
225	"configurations available on a single machine.\n"
226	"\n"
227	"Entering a file name here will allow you to later retrieve, modify\n"
228	"and use the current configuration as an alternate to whatever\n"
229	"configuration options you have selected at that time.\n"
230	"\n"
231	"If you are uncertain what all this means then you should probably\n"
232	"leave this blank.\n"),
233search_help[] = N_(
234	"\n"
235	"Search for CONFIG_ symbols and display their relations.\n"
236	"Regular expressions are allowed.\n"
237	"Example: search for \"^FOO\"\n"
238	"Result:\n"
239	"-----------------------------------------------------------------\n"
240	"Symbol: FOO [=m]\n"
241	"Prompt: Foo bus is used to drive the bar HW\n"
242	"Defined at drivers/pci/Kconfig:47\n"
243	"Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n"
244	"Location:\n"
245	"  -> Bus options (PCI, PCMCIA, EISA, MCA, ISA)\n"
246	"    -> PCI support (PCI [=y])\n"
247	"      -> PCI access mode (<choice> [=y])\n"
248	"Selects: LIBCRC32\n"
249	"Selected by: BAR\n"
250	"-----------------------------------------------------------------\n"
251	"o The line 'Prompt:' shows the text used in the menu structure for\n"
252	"  this CONFIG_ symbol\n"
253	"o The 'Defined at' line tell at what file / line number the symbol\n"
254	"  is defined\n"
255	"o The 'Depends on:' line tell what symbols needs to be defined for\n"
256	"  this symbol to be visible in the menu (selectable)\n"
257	"o The 'Location:' lines tell where in the menu structure this symbol\n"
258	"  is located\n"
259	"    A location followed by a [=y] indicate that this is a selectable\n"
260	"    menu item - and current value is displayed inside brackets.\n"
261	"o The 'Selects:' line tell what symbol will be automatically\n"
262	"  selected if this symbol is selected (y or m)\n"
263	"o The 'Selected by' line tell what symbol has selected this symbol\n"
264	"\n"
265	"Only relevant lines are shown.\n"
266	"\n\n"
267	"Search examples:\n"
268	"Examples: USB	=> find all CONFIG_ symbols containing USB\n"
269	"          ^USB => find all CONFIG_ symbols starting with USB\n"
270	"          USB$ => find all CONFIG_ symbols ending with USB\n"
271	"\n");
272
273static int indent;
274static struct menu *current_menu;
275static int child_count;
276static int single_menu_mode;
277static int show_all_options;
278
279static void conf(struct menu *menu);
280static void conf_choice(struct menu *menu);
281static void conf_string(struct menu *menu);
282static void conf_load(void);
283static void conf_save(void);
284static void show_textbox(const char *title, const char *text, int r, int c);
285static void show_helptext(const char *title, const char *text);
286static void show_help(struct menu *menu);
287
288static char filename[PATH_MAX+1];
289static void set_config_filename(const char *config_filename)
290{
291	static char menu_backtitle[PATH_MAX+128];
292	int size;
293	struct symbol *sym;
294
295	sym = sym_lookup("KERNELVERSION", 0);
296	sym_calc_value(sym);
297	size = snprintf(menu_backtitle, sizeof(menu_backtitle),
298	                _("%s - Linux Kernel v%s Configuration"),
299		        config_filename, sym_get_string_value(sym));
300	if (size >= sizeof(menu_backtitle))
301		menu_backtitle[sizeof(menu_backtitle)-1] = '\0';
302	set_dialog_backtitle(menu_backtitle);
303
304	size = snprintf(filename, sizeof(filename), "%s", config_filename);
305	if (size >= sizeof(filename))
306		filename[sizeof(filename)-1] = '\0';
307}
308
309
310static void search_conf(void)
311{
312	struct symbol **sym_arr;
313	struct gstr res;
314	char *dialog_input;
315	int dres;
316again:
317	dialog_clear();
318	dres = dialog_inputbox(_("Search Configuration Parameter"),
319			      _("Enter CONFIG_ (sub)string to search for "
320				"(with or without \"CONFIG\")"),
321			      10, 75, "");
322	switch (dres) {
323	case 0:
324		break;
325	case 1:
326		show_helptext(_("Search Configuration"), search_help);
327		goto again;
328	default:
329		return;
330	}
331
332	/* strip CONFIG_ if necessary */
333	dialog_input = dialog_input_result;
334	if (strncasecmp(dialog_input_result, "CONFIG_", 7) == 0)
335		dialog_input += 7;
336
337	sym_arr = sym_re_search(dialog_input);
338	res = get_relations_str(sym_arr);
339	free(sym_arr);
340	show_textbox(_("Search Results"), str_get(&res), 0, 0);
341	str_free(&res);
342}
343
344static void build_conf(struct menu *menu)
345{
346	struct symbol *sym;
347	struct property *prop;
348	struct menu *child;
349	int type, tmp, doint = 2;
350	tristate val;
351	char ch;
352	bool visible;
353
354	/*
355	 * note: menu_is_visible() has side effect that it will
356	 * recalc the value of the symbol.
357	 */
358	visible = menu_is_visible(menu);
359	if (show_all_options && !menu_has_prompt(menu))
360		return;
361	else if (!show_all_options && !visible)
362		return;
363
364	sym = menu->sym;
365	prop = menu->prompt;
366	if (!sym) {
367		if (prop && menu != current_menu) {
368			const char *prompt = menu_get_prompt(menu);
369			switch (prop->type) {
370			case P_MENU:
371				child_count++;
372				prompt = _(prompt);
373				if (single_menu_mode) {
374					item_make("%s%*c%s",
375						  menu->data ? "-->" : "++>",
376						  indent + 1, ' ', prompt);
377				} else
378					item_make("   %*c%s  --->", indent + 1, ' ', prompt);
379
380				item_set_tag('m');
381				item_set_data(menu);
382				if (single_menu_mode && menu->data)
383					goto conf_childs;
384				return;
385			case P_COMMENT:
386				if (prompt) {
387					child_count++;
388					item_make("   %*c*** %s ***", indent + 1, ' ', _(prompt));
389					item_set_tag(':');
390					item_set_data(menu);
391				}
392				break;
393			default:
394				if (prompt) {
395					child_count++;
396					item_make("---%*c%s", indent + 1, ' ', _(prompt));
397					item_set_tag(':');
398					item_set_data(menu);
399				}
400			}
401		} else
402			doint = 0;
403		goto conf_childs;
404	}
405
406	type = sym_get_type(sym);
407	if (sym_is_choice(sym)) {
408		struct symbol *def_sym = sym_get_choice_value(sym);
409		struct menu *def_menu = NULL;
410
411		child_count++;
412		for (child = menu->list; child; child = child->next) {
413			if (menu_is_visible(child) && child->sym == def_sym)
414				def_menu = child;
415		}
416
417		val = sym_get_tristate_value(sym);
418		if (sym_is_changable(sym)) {
419			switch (type) {
420			case S_BOOLEAN:
421				item_make("[%c]", val == no ? ' ' : '*');
422				break;
423			case S_TRISTATE:
424				switch (val) {
425				case yes: ch = '*'; break;
426				case mod: ch = 'M'; break;
427				default:  ch = ' '; break;
428				}
429				item_make("<%c>", ch);
430				break;
431			}
432			item_set_tag('t');
433			item_set_data(menu);
434		} else {
435			item_make("   ");
436			item_set_tag(def_menu ? 't' : ':');
437			item_set_data(menu);
438		}
439
440		item_add_str("%*c%s", indent + 1, ' ', _(menu_get_prompt(menu)));
441		if (val == yes) {
442			if (def_menu) {
443				item_add_str(" (%s)", _(menu_get_prompt(def_menu)));
444				item_add_str("  --->");
445				if (def_menu->list) {
446					indent += 2;
447					build_conf(def_menu);
448					indent -= 2;
449				}
450			}
451			return;
452		}
453	} else {
454		if (menu == current_menu) {
455			item_make("---%*c%s", indent + 1, ' ', _(menu_get_prompt(menu)));
456			item_set_tag(':');
457			item_set_data(menu);
458			goto conf_childs;
459		}
460		child_count++;
461		val = sym_get_tristate_value(sym);
462		if (sym_is_choice_value(sym) && val == yes) {
463			item_make("   ");
464			item_set_tag(':');
465			item_set_data(menu);
466		} else {
467			switch (type) {
468			case S_BOOLEAN:
469				if (sym_is_changable(sym))
470					item_make("[%c]", val == no ? ' ' : '*');
471				else
472					item_make("-%c-", val == no ? ' ' : '*');
473				item_set_tag('t');
474				item_set_data(menu);
475				break;
476			case S_TRISTATE:
477				switch (val) {
478				case yes: ch = '*'; break;
479				case mod: ch = 'M'; break;
480				default:  ch = ' '; break;
481				}
482				if (sym_is_changable(sym)) {
483					if (sym->rev_dep.tri == mod)
484						item_make("{%c}", ch);
485					else
486						item_make("<%c>", ch);
487				} else
488					item_make("-%c-", ch);
489				item_set_tag('t');
490				item_set_data(menu);
491				break;
492			default:
493				tmp = 2 + strlen(sym_get_string_value(sym)); /* () = 2 */
494				item_make("(%s)", sym_get_string_value(sym));
495				tmp = indent - tmp + 4;
496				if (tmp < 0)
497					tmp = 0;
498				item_add_str("%*c%s%s", tmp, ' ', _(menu_get_prompt(menu)),
499					     (sym_has_value(sym) || !sym_is_changable(sym)) ?
500					     "" : _(" (NEW)"));
501				item_set_tag('s');
502				item_set_data(menu);
503				goto conf_childs;
504			}
505		}
506		item_add_str("%*c%s%s", indent + 1, ' ', _(menu_get_prompt(menu)),
507			  (sym_has_value(sym) || !sym_is_changable(sym)) ?
508			  "" : _(" (NEW)"));
509		if (menu->prompt->type == P_MENU) {
510			item_add_str("  --->");
511			return;
512		}
513	}
514
515conf_childs:
516	indent += doint;
517	for (child = menu->list; child; child = child->next)
518		build_conf(child);
519	indent -= doint;
520}
521
522static void conf(struct menu *menu)
523{
524	struct menu *submenu;
525	const char *prompt = menu_get_prompt(menu);
526	struct symbol *sym;
527	struct menu *active_menu = NULL;
528	int res;
529	int s_scroll = 0;
530
531	while (1) {
532		item_reset();
533		current_menu = menu;
534		build_conf(menu);
535		if (!child_count)
536			break;
537		if (menu == &rootmenu) {
538			item_make("--- ");
539			item_set_tag(':');
540			item_make(_("    Load an Alternate Configuration File"));
541			item_set_tag('L');
542			item_make(_("    Save an Alternate Configuration File"));
543			item_set_tag('S');
544		}
545		dialog_clear();
546		res = dialog_menu(prompt ? _(prompt) : _("Main Menu"),
547				  _(menu_instructions),
548				  active_menu, &s_scroll);
549		if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL)
550			break;
551		if (!item_activate_selected())
552			continue;
553		if (!item_tag())
554			continue;
555
556		submenu = item_data();
557		active_menu = item_data();
558		if (submenu)
559			sym = submenu->sym;
560		else
561			sym = NULL;
562
563		switch (res) {
564		case 0:
565			switch (item_tag()) {
566			case 'm':
567				if (single_menu_mode)
568					submenu->data = (void *) (long) !submenu->data;
569				else
570					conf(submenu);
571				break;
572			case 't':
573				if (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)
574					conf_choice(submenu);
575				else if (submenu->prompt->type == P_MENU)
576					conf(submenu);
577				break;
578			case 's':
579				conf_string(submenu);
580				break;
581			case 'L':
582				conf_load();
583				break;
584			case 'S':
585				conf_save();
586				break;
587			}
588			break;
589		case 2:
590			if (sym)
591				show_help(submenu);
592			else
593				show_helptext(_("README"), _(mconf_readme));
594			break;
595		case 3:
596			if (item_is_tag('t')) {
597				if (sym_set_tristate_value(sym, yes))
598					break;
599				if (sym_set_tristate_value(sym, mod))
600					show_textbox(NULL, setmod_text, 6, 74);
601			}
602			break;
603		case 4:
604			if (item_is_tag('t'))
605				sym_set_tristate_value(sym, no);
606			break;
607		case 5:
608			if (item_is_tag('t'))
609				sym_set_tristate_value(sym, mod);
610			break;
611		case 6:
612			if (item_is_tag('t'))
613				sym_toggle_tristate_value(sym);
614			else if (item_is_tag('m'))
615				conf(submenu);
616			break;
617		case 7:
618			search_conf();
619			break;
620		case 8:
621			show_all_options = !show_all_options;
622			break;
623		}
624	}
625}
626
627static void show_textbox(const char *title, const char *text, int r, int c)
628{
629	dialog_clear();
630	dialog_textbox(title, text, r, c);
631}
632
633static void show_helptext(const char *title, const char *text)
634{
635	show_textbox(title, text, 0, 0);
636}
637
638static void show_help(struct menu *menu)
639{
640	struct gstr help = str_new();
641
642	help.max_width = getmaxx(stdscr) - 10;
643	menu_get_ext_help(menu, &help);
644
645	show_helptext(_(menu_get_prompt(menu)), str_get(&help));
646	str_free(&help);
647}
648
649static void conf_choice(struct menu *menu)
650{
651	const char *prompt = _(menu_get_prompt(menu));
652	struct menu *child;
653	struct symbol *active;
654
655	active = sym_get_choice_value(menu->sym);
656	while (1) {
657		int res;
658		int selected;
659		item_reset();
660
661		current_menu = menu;
662		for (child = menu->list; child; child = child->next) {
663			if (!menu_is_visible(child))
664				continue;
665			if (child->sym)
666				item_make("%s", _(menu_get_prompt(child)));
667			else {
668				item_make("*** %s ***", _(menu_get_prompt(child)));
669				item_set_tag(':');
670			}
671			item_set_data(child);
672			if (child->sym == active)
673				item_set_selected(1);
674			if (child->sym == sym_get_choice_value(menu->sym))
675				item_set_tag('X');
676		}
677		dialog_clear();
678		res = dialog_checklist(prompt ? _(prompt) : _("Main Menu"),
679					_(radiolist_instructions),
680					 15, 70, 6);
681		selected = item_activate_selected();
682		switch (res) {
683		case 0:
684			if (selected) {
685				child = item_data();
686				if (!child->sym)
687					break;
688
689				sym_set_tristate_value(child->sym, yes);
690			}
691			return;
692		case 1:
693			if (selected) {
694				child = item_data();
695				show_help(child);
696				active = child->sym;
697			} else
698				show_help(menu);
699			break;
700		case KEY_ESC:
701			return;
702		case -ERRDISPLAYTOOSMALL:
703			return;
704		}
705	}
706}
707
708static void conf_string(struct menu *menu)
709{
710	const char *prompt = menu_get_prompt(menu);
711
712	while (1) {
713		int res;
714		const char *heading;
715
716		switch (sym_get_type(menu->sym)) {
717		case S_INT:
718			heading = _(inputbox_instructions_int);
719			break;
720		case S_HEX:
721			heading = _(inputbox_instructions_hex);
722			break;
723		case S_STRING:
724			heading = _(inputbox_instructions_string);
725			break;
726		default:
727			heading = _("Internal mconf error!");
728		}
729		dialog_clear();
730		res = dialog_inputbox(prompt ? _(prompt) : _("Main Menu"),
731				      heading, 10, 75,
732				      sym_get_string_value(menu->sym));
733		switch (res) {
734		case 0:
735			if (sym_set_string_value(menu->sym, dialog_input_result))
736				return;
737			show_textbox(NULL, _("You have made an invalid entry."), 5, 43);
738			break;
739		case 1:
740			show_help(menu);
741			break;
742		case KEY_ESC:
743			return;
744		}
745	}
746}
747
748static void conf_load(void)
749{
750
751	while (1) {
752		int res;
753		dialog_clear();
754		res = dialog_inputbox(NULL, load_config_text,
755				      11, 55, filename);
756		switch(res) {
757		case 0:
758			if (!dialog_input_result[0])
759				return;
760			if (!conf_read(dialog_input_result)) {
761				set_config_filename(dialog_input_result);
762				sym_set_change_count(1);
763				return;
764			}
765			show_textbox(NULL, _("File does not exist!"), 5, 38);
766			break;
767		case 1:
768			show_helptext(_("Load Alternate Configuration"), load_config_help);
769			break;
770		case KEY_ESC:
771			return;
772		}
773	}
774}
775
776static void conf_save(void)
777{
778	while (1) {
779		int res;
780		dialog_clear();
781		res = dialog_inputbox(NULL, save_config_text,
782				      11, 55, filename);
783		switch(res) {
784		case 0:
785			if (!dialog_input_result[0])
786				return;
787			if (!conf_write(dialog_input_result)) {
788				set_config_filename(dialog_input_result);
789				return;
790			}
791			show_textbox(NULL, _("Can't create file!  Probably a nonexistent directory."), 5, 60);
792			break;
793		case 1:
794			show_helptext(_("Save Alternate Configuration"), save_config_help);
795			break;
796		case KEY_ESC:
797			return;
798		}
799	}
800}
801
802int main(int ac, char **av)
803{
804	int saved_x, saved_y;
805	char *mode;
806	int res;
807
808	setlocale(LC_ALL, "");
809	bindtextdomain(PACKAGE, LOCALEDIR);
810	textdomain(PACKAGE);
811
812	conf_parse(av[1]);
813	conf_read(NULL);
814
815	mode = getenv("MENUCONFIG_MODE");
816	if (mode) {
817		if (!strcasecmp(mode, "single_menu"))
818			single_menu_mode = 1;
819	}
820
821	initscr();
822
823	getyx(stdscr, saved_y, saved_x);
824	if (init_dialog(NULL)) {
825		fprintf(stderr, N_("Your display is too small to run Menuconfig!\n"));
826		fprintf(stderr, N_("It must be at least 19 lines by 80 columns.\n"));
827		return 1;
828	}
829
830	set_config_filename(conf_get_configname());
831	do {
832		conf(&rootmenu);
833		dialog_clear();
834		if (conf_get_changed())
835			res = dialog_yesno(NULL,
836					   _("Do you wish to save your "
837					     "new kernel configuration?\n"
838					     "<ESC><ESC> to continue."),
839					   6, 60);
840		else
841			res = -1;
842	} while (res == KEY_ESC);
843	end_dialog(saved_x, saved_y);
844
845	switch (res) {
846	case 0:
847		if (conf_write(filename)) {
848			fprintf(stderr, _("\n\n"
849				"Error during writing of the kernel configuration.\n"
850				"Your kernel configuration changes were NOT saved."
851				"\n\n"));
852			return 1;
853		}
854	case -1:
855		printf(_("\n\n"
856			"*** End of Linux kernel configuration.\n"
857			"*** Execute 'make' to build the kernel or try 'make help'."
858			"\n\n"));
859		break;
860	default:
861		fprintf(stderr, _("\n\n"
862			"Your kernel configuration changes were NOT saved."
863			"\n\n"));
864	}
865
866	return 0;
867}
868