kconfig: new configuration interface (nconfig)
[linux-2.6/libata-dev.git] / scripts / kconfig / mconf.c
bloba4a75190457cf988ef1df4b18a9cd7120b4636a9
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 char filename[PATH_MAX+1];
286 static void set_config_filename(const char *config_filename)
288 static char menu_backtitle[PATH_MAX+128];
289 int size;
290 struct symbol *sym;
292 sym = sym_lookup("KERNELVERSION", 0);
293 sym_calc_value(sym);
294 size = snprintf(menu_backtitle, sizeof(menu_backtitle),
295 _("%s - Linux Kernel v%s Configuration"),
296 config_filename, sym_get_string_value(sym));
297 if (size >= sizeof(menu_backtitle))
298 menu_backtitle[sizeof(menu_backtitle)-1] = '\0';
299 set_dialog_backtitle(menu_backtitle);
301 size = snprintf(filename, sizeof(filename), "%s", config_filename);
302 if (size >= sizeof(filename))
303 filename[sizeof(filename)-1] = '\0';
307 static void search_conf(void)
309 struct symbol **sym_arr;
310 struct gstr res;
311 char *dialog_input;
312 int dres;
313 again:
314 dialog_clear();
315 dres = dialog_inputbox(_("Search Configuration Parameter"),
316 _("Enter CONFIG_ (sub)string to search for "
317 "(with or without \"CONFIG\")"),
318 10, 75, "");
319 switch (dres) {
320 case 0:
321 break;
322 case 1:
323 show_helptext(_("Search Configuration"), search_help);
324 goto again;
325 default:
326 return;
329 /* strip CONFIG_ if necessary */
330 dialog_input = dialog_input_result;
331 if (strncasecmp(dialog_input_result, "CONFIG_", 7) == 0)
332 dialog_input += 7;
334 sym_arr = sym_re_search(dialog_input);
335 res = get_relations_str(sym_arr);
336 free(sym_arr);
337 show_textbox(_("Search Results"), str_get(&res), 0, 0);
338 str_free(&res);
341 static void build_conf(struct menu *menu)
343 struct symbol *sym;
344 struct property *prop;
345 struct menu *child;
346 int type, tmp, doint = 2;
347 tristate val;
348 char ch;
350 if (!menu_is_visible(menu))
351 return;
353 sym = menu->sym;
354 prop = menu->prompt;
355 if (!sym) {
356 if (prop && menu != current_menu) {
357 const char *prompt = menu_get_prompt(menu);
358 switch (prop->type) {
359 case P_MENU:
360 child_count++;
361 prompt = _(prompt);
362 if (single_menu_mode) {
363 item_make("%s%*c%s",
364 menu->data ? "-->" : "++>",
365 indent + 1, ' ', prompt);
366 } else
367 item_make(" %*c%s --->", indent + 1, ' ', prompt);
369 item_set_tag('m');
370 item_set_data(menu);
371 if (single_menu_mode && menu->data)
372 goto conf_childs;
373 return;
374 case P_COMMENT:
375 if (prompt) {
376 child_count++;
377 item_make(" %*c*** %s ***", indent + 1, ' ', _(prompt));
378 item_set_tag(':');
379 item_set_data(menu);
381 break;
382 default:
383 if (prompt) {
384 child_count++;
385 item_make("---%*c%s", indent + 1, ' ', _(prompt));
386 item_set_tag(':');
387 item_set_data(menu);
390 } else
391 doint = 0;
392 goto conf_childs;
395 type = sym_get_type(sym);
396 if (sym_is_choice(sym)) {
397 struct symbol *def_sym = sym_get_choice_value(sym);
398 struct menu *def_menu = NULL;
400 child_count++;
401 for (child = menu->list; child; child = child->next) {
402 if (menu_is_visible(child) && child->sym == def_sym)
403 def_menu = child;
406 val = sym_get_tristate_value(sym);
407 if (sym_is_changable(sym)) {
408 switch (type) {
409 case S_BOOLEAN:
410 item_make("[%c]", val == no ? ' ' : '*');
411 break;
412 case S_TRISTATE:
413 switch (val) {
414 case yes: ch = '*'; break;
415 case mod: ch = 'M'; break;
416 default: ch = ' '; break;
418 item_make("<%c>", ch);
419 break;
421 item_set_tag('t');
422 item_set_data(menu);
423 } else {
424 item_make(" ");
425 item_set_tag(def_menu ? 't' : ':');
426 item_set_data(menu);
429 item_add_str("%*c%s", indent + 1, ' ', _(menu_get_prompt(menu)));
430 if (val == yes) {
431 if (def_menu) {
432 item_add_str(" (%s)", _(menu_get_prompt(def_menu)));
433 item_add_str(" --->");
434 if (def_menu->list) {
435 indent += 2;
436 build_conf(def_menu);
437 indent -= 2;
440 return;
442 } else {
443 if (menu == current_menu) {
444 item_make("---%*c%s", indent + 1, ' ', _(menu_get_prompt(menu)));
445 item_set_tag(':');
446 item_set_data(menu);
447 goto conf_childs;
449 child_count++;
450 val = sym_get_tristate_value(sym);
451 if (sym_is_choice_value(sym) && val == yes) {
452 item_make(" ");
453 item_set_tag(':');
454 item_set_data(menu);
455 } else {
456 switch (type) {
457 case S_BOOLEAN:
458 if (sym_is_changable(sym))
459 item_make("[%c]", val == no ? ' ' : '*');
460 else
461 item_make("-%c-", val == no ? ' ' : '*');
462 item_set_tag('t');
463 item_set_data(menu);
464 break;
465 case S_TRISTATE:
466 switch (val) {
467 case yes: ch = '*'; break;
468 case mod: ch = 'M'; break;
469 default: ch = ' '; break;
471 if (sym_is_changable(sym)) {
472 if (sym->rev_dep.tri == mod)
473 item_make("{%c}", ch);
474 else
475 item_make("<%c>", ch);
476 } else
477 item_make("-%c-", ch);
478 item_set_tag('t');
479 item_set_data(menu);
480 break;
481 default:
482 tmp = 2 + strlen(sym_get_string_value(sym)); /* () = 2 */
483 item_make("(%s)", sym_get_string_value(sym));
484 tmp = indent - tmp + 4;
485 if (tmp < 0)
486 tmp = 0;
487 item_add_str("%*c%s%s", tmp, ' ', _(menu_get_prompt(menu)),
488 (sym_has_value(sym) || !sym_is_changable(sym)) ?
489 "" : _(" (NEW)"));
490 item_set_tag('s');
491 item_set_data(menu);
492 goto conf_childs;
495 item_add_str("%*c%s%s", indent + 1, ' ', _(menu_get_prompt(menu)),
496 (sym_has_value(sym) || !sym_is_changable(sym)) ?
497 "" : _(" (NEW)"));
498 if (menu->prompt->type == P_MENU) {
499 item_add_str(" --->");
500 return;
504 conf_childs:
505 indent += doint;
506 for (child = menu->list; child; child = child->next)
507 build_conf(child);
508 indent -= doint;
511 static void conf(struct menu *menu)
513 struct menu *submenu;
514 const char *prompt = menu_get_prompt(menu);
515 struct symbol *sym;
516 struct menu *active_menu = NULL;
517 int res;
518 int s_scroll = 0;
520 while (1) {
521 item_reset();
522 current_menu = menu;
523 build_conf(menu);
524 if (!child_count)
525 break;
526 if (menu == &rootmenu) {
527 item_make("--- ");
528 item_set_tag(':');
529 item_make(_(" Load an Alternate Configuration File"));
530 item_set_tag('L');
531 item_make(_(" Save an Alternate Configuration File"));
532 item_set_tag('S');
534 dialog_clear();
535 res = dialog_menu(prompt ? _(prompt) : _("Main Menu"),
536 _(menu_instructions),
537 active_menu, &s_scroll);
538 if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL)
539 break;
540 if (!item_activate_selected())
541 continue;
542 if (!item_tag())
543 continue;
545 submenu = item_data();
546 active_menu = item_data();
547 if (submenu)
548 sym = submenu->sym;
549 else
550 sym = NULL;
552 switch (res) {
553 case 0:
554 switch (item_tag()) {
555 case 'm':
556 if (single_menu_mode)
557 submenu->data = (void *) (long) !submenu->data;
558 else
559 conf(submenu);
560 break;
561 case 't':
562 if (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)
563 conf_choice(submenu);
564 else if (submenu->prompt->type == P_MENU)
565 conf(submenu);
566 break;
567 case 's':
568 conf_string(submenu);
569 break;
570 case 'L':
571 conf_load();
572 break;
573 case 'S':
574 conf_save();
575 break;
577 break;
578 case 2:
579 if (sym)
580 show_help(submenu);
581 else
582 show_helptext(_("README"), _(mconf_readme));
583 break;
584 case 3:
585 if (item_is_tag('t')) {
586 if (sym_set_tristate_value(sym, yes))
587 break;
588 if (sym_set_tristate_value(sym, mod))
589 show_textbox(NULL, setmod_text, 6, 74);
591 break;
592 case 4:
593 if (item_is_tag('t'))
594 sym_set_tristate_value(sym, no);
595 break;
596 case 5:
597 if (item_is_tag('t'))
598 sym_set_tristate_value(sym, mod);
599 break;
600 case 6:
601 if (item_is_tag('t'))
602 sym_toggle_tristate_value(sym);
603 else if (item_is_tag('m'))
604 conf(submenu);
605 break;
606 case 7:
607 search_conf();
608 break;
613 static void show_textbox(const char *title, const char *text, int r, int c)
615 dialog_clear();
616 dialog_textbox(title, text, r, c);
619 static void show_helptext(const char *title, const char *text)
621 show_textbox(title, text, 0, 0);
624 static void show_help(struct menu *menu)
626 struct gstr help = str_new();
628 help.max_width = getmaxx(stdscr) - 10;
629 menu_get_ext_help(menu, &help);
631 show_helptext(_(menu_get_prompt(menu)), str_get(&help));
632 str_free(&help);
635 static void conf_choice(struct menu *menu)
637 const char *prompt = _(menu_get_prompt(menu));
638 struct menu *child;
639 struct symbol *active;
641 active = sym_get_choice_value(menu->sym);
642 while (1) {
643 int res;
644 int selected;
645 item_reset();
647 current_menu = menu;
648 for (child = menu->list; child; child = child->next) {
649 if (!menu_is_visible(child))
650 continue;
651 if (child->sym)
652 item_make("%s", _(menu_get_prompt(child)));
653 else {
654 item_make("*** %s ***", _(menu_get_prompt(child)));
655 item_set_tag(':');
657 item_set_data(child);
658 if (child->sym == active)
659 item_set_selected(1);
660 if (child->sym == sym_get_choice_value(menu->sym))
661 item_set_tag('X');
663 dialog_clear();
664 res = dialog_checklist(prompt ? _(prompt) : _("Main Menu"),
665 _(radiolist_instructions),
666 15, 70, 6);
667 selected = item_activate_selected();
668 switch (res) {
669 case 0:
670 if (selected) {
671 child = item_data();
672 if (!child->sym)
673 break;
675 sym_set_tristate_value(child->sym, yes);
677 return;
678 case 1:
679 if (selected) {
680 child = item_data();
681 show_help(child);
682 active = child->sym;
683 } else
684 show_help(menu);
685 break;
686 case KEY_ESC:
687 return;
688 case -ERRDISPLAYTOOSMALL:
689 return;
694 static void conf_string(struct menu *menu)
696 const char *prompt = menu_get_prompt(menu);
698 while (1) {
699 int res;
700 const char *heading;
702 switch (sym_get_type(menu->sym)) {
703 case S_INT:
704 heading = _(inputbox_instructions_int);
705 break;
706 case S_HEX:
707 heading = _(inputbox_instructions_hex);
708 break;
709 case S_STRING:
710 heading = _(inputbox_instructions_string);
711 break;
712 default:
713 heading = _("Internal mconf error!");
715 dialog_clear();
716 res = dialog_inputbox(prompt ? _(prompt) : _("Main Menu"),
717 heading, 10, 75,
718 sym_get_string_value(menu->sym));
719 switch (res) {
720 case 0:
721 if (sym_set_string_value(menu->sym, dialog_input_result))
722 return;
723 show_textbox(NULL, _("You have made an invalid entry."), 5, 43);
724 break;
725 case 1:
726 show_help(menu);
727 break;
728 case KEY_ESC:
729 return;
734 static void conf_load(void)
737 while (1) {
738 int res;
739 dialog_clear();
740 res = dialog_inputbox(NULL, load_config_text,
741 11, 55, filename);
742 switch(res) {
743 case 0:
744 if (!dialog_input_result[0])
745 return;
746 if (!conf_read(dialog_input_result)) {
747 set_config_filename(dialog_input_result);
748 sym_set_change_count(1);
749 return;
751 show_textbox(NULL, _("File does not exist!"), 5, 38);
752 break;
753 case 1:
754 show_helptext(_("Load Alternate Configuration"), load_config_help);
755 break;
756 case KEY_ESC:
757 return;
762 static void conf_save(void)
764 while (1) {
765 int res;
766 dialog_clear();
767 res = dialog_inputbox(NULL, save_config_text,
768 11, 55, filename);
769 switch(res) {
770 case 0:
771 if (!dialog_input_result[0])
772 return;
773 if (!conf_write(dialog_input_result)) {
774 set_config_filename(dialog_input_result);
775 return;
777 show_textbox(NULL, _("Can't create file! Probably a nonexistent directory."), 5, 60);
778 break;
779 case 1:
780 show_helptext(_("Save Alternate Configuration"), save_config_help);
781 break;
782 case KEY_ESC:
783 return;
788 int main(int ac, char **av)
790 int saved_x, saved_y;
791 char *mode;
792 int res;
794 setlocale(LC_ALL, "");
795 bindtextdomain(PACKAGE, LOCALEDIR);
796 textdomain(PACKAGE);
798 conf_parse(av[1]);
799 conf_read(NULL);
801 mode = getenv("MENUCONFIG_MODE");
802 if (mode) {
803 if (!strcasecmp(mode, "single_menu"))
804 single_menu_mode = 1;
807 initscr();
809 getyx(stdscr, saved_y, saved_x);
810 if (init_dialog(NULL)) {
811 fprintf(stderr, N_("Your display is too small to run Menuconfig!\n"));
812 fprintf(stderr, N_("It must be at least 19 lines by 80 columns.\n"));
813 return 1;
816 set_config_filename(conf_get_configname());
817 do {
818 conf(&rootmenu);
819 dialog_clear();
820 if (conf_get_changed())
821 res = dialog_yesno(NULL,
822 _("Do you wish to save your "
823 "new kernel configuration?\n"
824 "<ESC><ESC> to continue."),
825 6, 60);
826 else
827 res = -1;
828 } while (res == KEY_ESC);
829 end_dialog(saved_x, saved_y);
831 switch (res) {
832 case 0:
833 if (conf_write(filename)) {
834 fprintf(stderr, _("\n\n"
835 "Error during writing of the kernel configuration.\n"
836 "Your kernel configuration changes were NOT saved."
837 "\n\n"));
838 return 1;
840 case -1:
841 printf(_("\n\n"
842 "*** End of Linux kernel configuration.\n"
843 "*** Execute 'make' to build the kernel or try 'make help'."
844 "\n\n"));
845 break;
846 default:
847 fprintf(stderr, _("\n\n"
848 "Your kernel configuration changes were NOT saved."
849 "\n\n"));
852 return 0;