Merge branch 'writeback' of git://git.kernel.dk/linux-2.6-block
[linux-block.git] / scripts / kconfig / mconf.c
CommitLineData
1da177e4
LT
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>
3b9fa093
ACM
7 *
8 * i18n, 2005, Arnaldo Carvalho de Melo <acme@conectiva.com.br>
1da177e4
LT
9 */
10
1da177e4
LT
11#include <ctype.h>
12#include <errno.h>
13#include <fcntl.h>
14#include <limits.h>
1da177e4
LT
15#include <stdarg.h>
16#include <stdlib.h>
17#include <string.h>
1da177e4 18#include <unistd.h>
442ff702 19#include <locale.h>
1da177e4
LT
20
21#define LKC_DIRECT_LINK
22#include "lkc.h"
2982de69 23#include "lxdialog/dialog.h"
1da177e4 24
3b9fa093 25static const char mconf_readme[] = N_(
1da177e4
LT
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"
b5d609db
ML
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"
1da177e4
LT
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"
45897213
SR
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"
350b5b76
SR
174" classic => theme with blue background. The classic look\n"
175" bluetitle => a LCD friendly version of classic. (default)\n"
45897213 176"\n"),
3b9fa093 177menu_instructions[] = N_(
1da177e4
LT
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. "
3b9fa093
ACM
183 "Legend: [*] built-in [ ] excluded <M> module < > module capable"),
184radiolist_instructions[] = N_(
1da177e4
LT
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>. "
3b9fa093
ACM
188 "Press <?> for additional information about this option."),
189inputbox_instructions_int[] = N_(
1da177e4
LT
190 "Please enter a decimal value. "
191 "Fractions will not be accepted. "
3b9fa093
ACM
192 "Use the <TAB> key to move from the input field to the buttons below it."),
193inputbox_instructions_hex[] = N_(
1da177e4 194 "Please enter a hexadecimal value. "
3b9fa093
ACM
195 "Use the <TAB> key to move from the input field to the buttons below it."),
196inputbox_instructions_string[] = N_(
1da177e4 197 "Please enter a string value. "
3b9fa093
ACM
198 "Use the <TAB> key to move from the input field to the buttons below it."),
199setmod_text[] = N_(
1da177e4 200 "This feature depends on another which has been configured as a module.\n"
3b9fa093 201 "As a result, this feature will be built as a module."),
3b9fa093 202load_config_text[] = N_(
1da177e4
LT
203 "Enter the name of the configuration file you wish to load. "
204 "Accept the name shown to restore the configuration you "
3b9fa093
ACM
205 "last retrieved. Leave blank to abort."),
206load_config_help[] = N_(
1da177e4
LT
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"
3b9fa093
ACM
216 "configuration files. You should therefor leave this blank to abort.\n"),
217save_config_text[] = N_(
1da177e4 218 "Enter a filename to which this configuration should be saved "
3b9fa093
ACM
219 "as an alternate. Leave blank to abort."),
220save_config_help[] = N_(
1da177e4
LT
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"
3b9fa093
ACM
230 "leave this blank.\n"),
231search_help[] = N_(
1da177e4
LT
232 "\n"
233 "Search for CONFIG_ symbols and display their relations.\n"
503af334 234 "Regular expressions are allowed.\n"
1da177e4
LT
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"
3b9fa093 269 "\n");
1da177e4 270
1da177e4 271static int indent;
1da177e4
LT
272static struct menu *current_menu;
273static int child_count;
1da177e4
LT
274static int single_menu_mode;
275
276static void conf(struct menu *menu);
277static void conf_choice(struct menu *menu);
278static void conf_string(struct menu *menu);
279static void conf_load(void);
280static void conf_save(void);
281static void show_textbox(const char *title, const char *text, int r, int c);
282static void show_helptext(const char *title, const char *text);
283static void show_help(struct menu *menu);
1da177e4 284
1da177e4
LT
285static struct gstr get_relations_str(struct symbol **sym_arr)
286{
287 struct symbol *sym;
288 struct gstr res = str_new();
289 int i;
290
291 for (i = 0; sym_arr && (sym = sym_arr[i]); i++)
292 get_symbol_str(&res, sym);
293 if (!i)
413f006b 294 str_append(&res, _("No matches found.\n"));
1da177e4
LT
295 return res;
296}
297
95e30f95
SR
298static char filename[PATH_MAX+1];
299static void set_config_filename(const char *config_filename)
300{
301 static char menu_backtitle[PATH_MAX+128];
302 int size;
303 struct symbol *sym;
304
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);
313
314 size = snprintf(filename, sizeof(filename), "%s", config_filename);
315 if (size >= sizeof(filename))
316 filename[sizeof(filename)-1] = '\0';
317}
318
319
1da177e4
LT
320static void search_conf(void)
321{
322 struct symbol **sym_arr;
1da177e4 323 struct gstr res;
0584f9f9 324 char *dialog_input;
2982de69 325 int dres;
1da177e4 326again:
e94c5bde 327 dialog_clear();
2982de69 328 dres = dialog_inputbox(_("Search Configuration Parameter"),
0584f9f9
BW
329 _("Enter CONFIG_ (sub)string to search for "
330 "(with or without \"CONFIG\")"),
2982de69
SR
331 10, 75, "");
332 switch (dres) {
1da177e4
LT
333 case 0:
334 break;
335 case 1:
3b9fa093 336 show_helptext(_("Search Configuration"), search_help);
1da177e4
LT
337 goto again;
338 default:
339 return;
340 }
341
0584f9f9
BW
342 /* strip CONFIG_ if necessary */
343 dialog_input = dialog_input_result;
344 if (strncasecmp(dialog_input_result, "CONFIG_", 7) == 0)
345 dialog_input += 7;
346
347 sym_arr = sym_re_search(dialog_input);
1da177e4
LT
348 res = get_relations_str(sym_arr);
349 free(sym_arr);
3b9fa093 350 show_textbox(_("Search Results"), str_get(&res), 0, 0);
1da177e4
LT
351 str_free(&res);
352}
353
354static void build_conf(struct menu *menu)
355{
356 struct symbol *sym;
357 struct property *prop;
358 struct menu *child;
359 int type, tmp, doint = 2;
360 tristate val;
361 char ch;
362
363 if (!menu_is_visible(menu))
364 return;
365
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++;
413f006b 374 prompt = _(prompt);
1da177e4 375 if (single_menu_mode) {
2982de69
SR
376 item_make("%s%*c%s",
377 menu->data ? "-->" : "++>",
378 indent + 1, ' ', prompt);
1da177e4 379 } else
2982de69 380 item_make(" %*c%s --->", indent + 1, ' ', prompt);
1da177e4 381
2982de69
SR
382 item_set_tag('m');
383 item_set_data(menu);
1da177e4
LT
384 if (single_menu_mode && menu->data)
385 goto conf_childs;
386 return;
48874077
SR
387 case P_COMMENT:
388 if (prompt) {
389 child_count++;
413f006b 390 item_make(" %*c*** %s ***", indent + 1, ' ', _(prompt));
48874077
SR
391 item_set_tag(':');
392 item_set_data(menu);
393 }
394 break;
1da177e4
LT
395 default:
396 if (prompt) {
397 child_count++;
413f006b 398 item_make("---%*c%s", indent + 1, ' ', _(prompt));
2982de69
SR
399 item_set_tag(':');
400 item_set_data(menu);
1da177e4
LT
401 }
402 }
403 } else
404 doint = 0;
405 goto conf_childs;
406 }
407
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;
412
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;
417 }
418
419 val = sym_get_tristate_value(sym);
420 if (sym_is_changable(sym)) {
1da177e4
LT
421 switch (type) {
422 case S_BOOLEAN:
2982de69 423 item_make("[%c]", val == no ? ' ' : '*');
1da177e4
LT
424 break;
425 case S_TRISTATE:
426 switch (val) {
427 case yes: ch = '*'; break;
428 case mod: ch = 'M'; break;
429 default: ch = ' '; break;
430 }
2982de69 431 item_make("<%c>", ch);
1da177e4
LT
432 break;
433 }
2982de69
SR
434 item_set_tag('t');
435 item_set_data(menu);
1da177e4 436 } else {
2982de69
SR
437 item_make(" ");
438 item_set_tag(def_menu ? 't' : ':');
439 item_set_data(menu);
1da177e4
LT
440 }
441
413f006b 442 item_add_str("%*c%s", indent + 1, ' ', _(menu_get_prompt(menu)));
1da177e4
LT
443 if (val == yes) {
444 if (def_menu) {
413f006b 445 item_add_str(" (%s)", _(menu_get_prompt(def_menu)));
2982de69 446 item_add_str(" --->");
1da177e4
LT
447 if (def_menu->list) {
448 indent += 2;
449 build_conf(def_menu);
450 indent -= 2;
451 }
2982de69 452 }
1da177e4
LT
453 return;
454 }
1da177e4
LT
455 } else {
456 if (menu == current_menu) {
413f006b 457 item_make("---%*c%s", indent + 1, ' ', _(menu_get_prompt(menu)));
2982de69
SR
458 item_set_tag(':');
459 item_set_data(menu);
1da177e4
LT
460 goto conf_childs;
461 }
462 child_count++;
463 val = sym_get_tristate_value(sym);
464 if (sym_is_choice_value(sym) && val == yes) {
2982de69
SR
465 item_make(" ");
466 item_set_tag(':');
467 item_set_data(menu);
1da177e4
LT
468 } else {
469 switch (type) {
470 case S_BOOLEAN:
1da177e4 471 if (sym_is_changable(sym))
2982de69 472 item_make("[%c]", val == no ? ' ' : '*');
1da177e4 473 else
b5d609db 474 item_make("-%c-", val == no ? ' ' : '*');
2982de69
SR
475 item_set_tag('t');
476 item_set_data(menu);
1da177e4
LT
477 break;
478 case S_TRISTATE:
1da177e4
LT
479 switch (val) {
480 case yes: ch = '*'; break;
481 case mod: ch = 'M'; break;
482 default: ch = ' '; break;
483 }
b5d609db
ML
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);
2982de69
SR
491 item_set_tag('t');
492 item_set_data(menu);
1da177e4
LT
493 break;
494 default:
2982de69
SR
495 tmp = 2 + strlen(sym_get_string_value(sym)); /* () = 2 */
496 item_make("(%s)", sym_get_string_value(sym));
1da177e4
LT
497 tmp = indent - tmp + 4;
498 if (tmp < 0)
499 tmp = 0;
413f006b 500 item_add_str("%*c%s%s", tmp, ' ', _(menu_get_prompt(menu)),
2982de69 501 (sym_has_value(sym) || !sym_is_changable(sym)) ?
413f006b 502 "" : _(" (NEW)"));
2982de69
SR
503 item_set_tag('s');
504 item_set_data(menu);
1da177e4
LT
505 goto conf_childs;
506 }
507 }
413f006b 508 item_add_str("%*c%s%s", indent + 1, ' ', _(menu_get_prompt(menu)),
2982de69 509 (sym_has_value(sym) || !sym_is_changable(sym)) ?
413f006b 510 "" : _(" (NEW)"));
1da177e4 511 if (menu->prompt->type == P_MENU) {
2982de69 512 item_add_str(" --->");
1da177e4
LT
513 return;
514 }
1da177e4
LT
515 }
516
517conf_childs:
518 indent += doint;
519 for (child = menu->list; child; child = child->next)
520 build_conf(child);
521 indent -= doint;
522}
523
524static void conf(struct menu *menu)
525{
526 struct menu *submenu;
527 const char *prompt = menu_get_prompt(menu);
528 struct symbol *sym;
2982de69
SR
529 struct menu *active_menu = NULL;
530 int res;
531 int s_scroll = 0;
1da177e4 532
1da177e4 533 while (1) {
2982de69 534 item_reset();
1da177e4
LT
535 current_menu = menu;
536 build_conf(menu);
537 if (!child_count)
538 break;
539 if (menu == &rootmenu) {
2982de69
SR
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');
1da177e4 546 }
e94c5bde 547 dialog_clear();
413f006b 548 res = dialog_menu(prompt ? _(prompt) : _("Main Menu"),
2982de69 549 _(menu_instructions),
2982de69 550 active_menu, &s_scroll);
c8dc68ad 551 if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL)
1da177e4 552 break;
2982de69
SR
553 if (!item_activate_selected())
554 continue;
555 if (!item_tag())
1da177e4
LT
556 continue;
557
2982de69
SR
558 submenu = item_data();
559 active_menu = item_data();
c8dc68ad
SR
560 if (submenu)
561 sym = submenu->sym;
562 else
563 sym = NULL;
1da177e4 564
2982de69 565 switch (res) {
1da177e4 566 case 0:
2982de69 567 switch (item_tag()) {
1da177e4
LT
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;
589 }
590 break;
591 case 2:
592 if (sym)
593 show_help(submenu);
594 else
413f006b 595 show_helptext(_("README"), _(mconf_readme));
1da177e4
LT
596 break;
597 case 3:
2982de69 598 if (item_is_tag('t')) {
1da177e4
LT
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);
603 }
604 break;
605 case 4:
2982de69 606 if (item_is_tag('t'))
1da177e4
LT
607 sym_set_tristate_value(sym, no);
608 break;
609 case 5:
2982de69 610 if (item_is_tag('t'))
1da177e4
LT
611 sym_set_tristate_value(sym, mod);
612 break;
613 case 6:
2982de69 614 if (item_is_tag('t'))
1da177e4 615 sym_toggle_tristate_value(sym);
2982de69 616 else if (item_is_tag('m'))
1da177e4
LT
617 conf(submenu);
618 break;
619 case 7:
620 search_conf();
621 break;
622 }
623 }
624}
625
626static void show_textbox(const char *title, const char *text, int r, int c)
627{
e94c5bde 628 dialog_clear();
c8dc68ad 629 dialog_textbox(title, text, r, c);
1da177e4
LT
630}
631
632static void show_helptext(const char *title, const char *text)
633{
634 show_textbox(title, text, 0, 0);
635}
636
637static void show_help(struct menu *menu)
638{
639 struct gstr help = str_new();
1d525e7c
CR
640
641 menu_get_ext_help(menu, &help);
642
413f006b 643 show_helptext(_(menu_get_prompt(menu)), str_get(&help));
1da177e4
LT
644 str_free(&help);
645}
646
1da177e4
LT
647static void conf_choice(struct menu *menu)
648{
413f006b 649 const char *prompt = _(menu_get_prompt(menu));
1da177e4
LT
650 struct menu *child;
651 struct symbol *active;
1da177e4
LT
652
653 active = sym_get_choice_value(menu->sym);
654 while (1) {
2982de69
SR
655 int res;
656 int selected;
657 item_reset();
1da177e4
LT
658
659 current_menu = menu;
660 for (child = menu->list; child; child = child->next) {
661 if (!menu_is_visible(child))
662 continue;
af6c1598
PK
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(':');
668 }
2982de69
SR
669 item_set_data(child);
670 if (child->sym == active)
671 item_set_selected(1);
1da177e4 672 if (child->sym == sym_get_choice_value(menu->sym))
2982de69 673 item_set_tag('X');
1da177e4 674 }
e94c5bde 675 dialog_clear();
413f006b 676 res = dialog_checklist(prompt ? _(prompt) : _("Main Menu"),
2982de69
SR
677 _(radiolist_instructions),
678 15, 70, 6);
679 selected = item_activate_selected();
680 switch (res) {
1da177e4 681 case 0:
2982de69
SR
682 if (selected) {
683 child = item_data();
af6c1598
PK
684 if (!child->sym)
685 break;
686
2982de69
SR
687 sym_set_tristate_value(child->sym, yes);
688 }
1da177e4
LT
689 return;
690 case 1:
2982de69
SR
691 if (selected) {
692 child = item_data();
1da177e4
LT
693 show_help(child);
694 active = child->sym;
695 } else
696 show_help(menu);
697 break;
f3cbcdc9 698 case KEY_ESC:
1da177e4 699 return;
c8dc68ad
SR
700 case -ERRDISPLAYTOOSMALL:
701 return;
1da177e4
LT
702 }
703 }
704}
705
706static void conf_string(struct menu *menu)
707{
708 const char *prompt = menu_get_prompt(menu);
1da177e4
LT
709
710 while (1) {
2982de69 711 int res;
c4143a83 712 const char *heading;
2982de69 713
1da177e4
LT
714 switch (sym_get_type(menu->sym)) {
715 case S_INT:
2982de69 716 heading = _(inputbox_instructions_int);
1da177e4
LT
717 break;
718 case S_HEX:
2982de69 719 heading = _(inputbox_instructions_hex);
1da177e4
LT
720 break;
721 case S_STRING:
2982de69 722 heading = _(inputbox_instructions_string);
1da177e4
LT
723 break;
724 default:
413f006b 725 heading = _("Internal mconf error!");
1da177e4 726 }
e94c5bde 727 dialog_clear();
413f006b 728 res = dialog_inputbox(prompt ? _(prompt) : _("Main Menu"),
2982de69
SR
729 heading, 10, 75,
730 sym_get_string_value(menu->sym));
731 switch (res) {
1da177e4 732 case 0:
2982de69 733 if (sym_set_string_value(menu->sym, dialog_input_result))
1da177e4 734 return;
3b9fa093 735 show_textbox(NULL, _("You have made an invalid entry."), 5, 43);
1da177e4
LT
736 break;
737 case 1:
738 show_help(menu);
739 break;
f3cbcdc9 740 case KEY_ESC:
1da177e4
LT
741 return;
742 }
743 }
744}
745
746static void conf_load(void)
747{
1da177e4
LT
748
749 while (1) {
2982de69 750 int res;
e94c5bde 751 dialog_clear();
2982de69
SR
752 res = dialog_inputbox(NULL, load_config_text,
753 11, 55, filename);
754 switch(res) {
1da177e4 755 case 0:
2982de69 756 if (!dialog_input_result[0])
1da177e4 757 return;
95e30f95
SR
758 if (!conf_read(dialog_input_result)) {
759 set_config_filename(dialog_input_result);
36ef805b 760 sym_set_change_count(1);
1da177e4 761 return;
95e30f95 762 }
3b9fa093 763 show_textbox(NULL, _("File does not exist!"), 5, 38);
1da177e4
LT
764 break;
765 case 1:
3b9fa093 766 show_helptext(_("Load Alternate Configuration"), load_config_help);
1da177e4 767 break;
f3cbcdc9 768 case KEY_ESC:
1da177e4
LT
769 return;
770 }
771 }
772}
773
774static void conf_save(void)
775{
1da177e4 776 while (1) {
2982de69 777 int res;
e94c5bde 778 dialog_clear();
2982de69
SR
779 res = dialog_inputbox(NULL, save_config_text,
780 11, 55, filename);
781 switch(res) {
1da177e4 782 case 0:
2982de69 783 if (!dialog_input_result[0])
1da177e4 784 return;
95e30f95
SR
785 if (!conf_write(dialog_input_result)) {
786 set_config_filename(dialog_input_result);
1da177e4 787 return;
95e30f95 788 }
3b9fa093 789 show_textbox(NULL, _("Can't create file! Probably a nonexistent directory."), 5, 60);
1da177e4
LT
790 break;
791 case 1:
3b9fa093 792 show_helptext(_("Save Alternate Configuration"), save_config_help);
1da177e4 793 break;
f3cbcdc9 794 case KEY_ESC:
1da177e4
LT
795 return;
796 }
797 }
798}
799
1da177e4
LT
800int main(int ac, char **av)
801{
09af091f 802 int saved_x, saved_y;
1da177e4 803 char *mode;
2982de69 804 int res;
1da177e4 805
3b9fa093
ACM
806 setlocale(LC_ALL, "");
807 bindtextdomain(PACKAGE, LOCALEDIR);
808 textdomain(PACKAGE);
809
1da177e4
LT
810 conf_parse(av[1]);
811 conf_read(NULL);
812
1da177e4
LT
813 mode = getenv("MENUCONFIG_MODE");
814 if (mode) {
815 if (!strcasecmp(mode, "single_menu"))
816 single_menu_mode = 1;
817 }
818
d0e1e095
AL
819 initscr();
820
09af091f
LM
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;
826 }
827
d802b50f 828 set_config_filename(conf_get_configname());
f3cbcdc9
SR
829 do {
830 conf(&rootmenu);
e94c5bde 831 dialog_clear();
b3214293
KW
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;
f3cbcdc9 840 } while (res == KEY_ESC);
09af091f 841 end_dialog(saved_x, saved_y);
b3214293
KW
842
843 switch (res) {
844 case 0:
95e30f95 845 if (conf_write(filename)) {
3b9fa093 846 fprintf(stderr, _("\n\n"
1da177e4
LT
847 "Error during writing of the kernel configuration.\n"
848 "Your kernel configuration changes were NOT saved."
3b9fa093 849 "\n\n"));
1da177e4
LT
850 return 1;
851 }
b3214293 852 case -1:
3b9fa093 853 printf(_("\n\n"
1da177e4
LT
854 "*** End of Linux kernel configuration.\n"
855 "*** Execute 'make' to build the kernel or try 'make help'."
3b9fa093 856 "\n\n"));
b3214293
KW
857 break;
858 default:
3b9fa093 859 fprintf(stderr, _("\n\n"
1da177e4 860 "Your kernel configuration changes were NOT saved."
3b9fa093 861 "\n\n"));
1da177e4
LT
862 }
863
864 return 0;
865}
c4143a83 866