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