kconfig: m/nconf: remove dead code to display children of choice members
[linux-block.git] / scripts / kconfig / mconf.c
CommitLineData
0c874100 1// SPDX-License-Identifier: GPL-2.0
1da177e4
LT
2/*
3 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
1da177e4
LT
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>
ba82f52e 18#include <strings.h>
564899f9 19#include <signal.h>
1da177e4
LT
20#include <unistd.h>
21
4dae9cf5 22#include "list.h"
1da177e4 23#include "lkc.h"
2982de69 24#include "lxdialog/dialog.h"
6c07fd84 25#include "mnconf-common.h"
1da177e4 26
694c49a7 27static const char mconf_readme[] =
1da177e4
LT
28"Overview\n"
29"--------\n"
8d9dfe82 30"This interface lets you select features and parameters for the build.\n"
652cf982
AL
31"Features can either be built-in, modularized, or ignored. Parameters\n"
32"must be entered in as decimal or hexadecimal numbers or text.\n"
1da177e4 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"
8d9dfe82
MW
44"<N> to remove it. You may also press the <Space Bar> to cycle\n"
45"through the available options (i.e. Y->N->M->Y).\n"
1da177e4
LT
46"\n"
47"Some additional keyboard hints:\n"
48"\n"
49"Menus\n"
50"----------\n"
8d9dfe82
MW
51"o Use the Up/Down arrow keys (cursor keys) to highlight the item you\n"
52" wish to change or the submenu you wish to select and press <Enter>.\n"
1278ebdb 53" Submenus are designated by \"--->\", empty ones by \"----\".\n"
1da177e4
LT
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"
8d9dfe82 70" <Exit>, <Help>, <Save>, and <Load>.\n"
1da177e4
LT
71"\n"
72"o To get help with an item, use the cursor keys to highlight <Help>\n"
22c7eca6 73" and press <ENTER>.\n"
1da177e4
LT
74"\n"
75" Shortcut: Press <H> or <?>.\n"
76"\n"
f9447c49 77"o To toggle the display of hidden options, press <Z>.\n"
22c7eca6 78"\n"
1da177e4
LT
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"
8d9dfe82 110" keys h,j,k,l function here as do <u>, <d>, <SPACE BAR> and <B> for\n"
9d4792c9 111" those who are familiar with less and lynx.\n"
1da177e4 112"\n"
9d4792c9 113"o Press <E>, <X>, <q>, <Enter> or <Esc><Esc> to exit.\n"
1da177e4
LT
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"
652cf982 120"between different configurations.\n"
1da177e4 121"\n"
8d9dfe82
MW
122"The <Save> button will let you save the current configuration to\n"
123"a file of your choosing. Use the <Load> button to load a previously\n"
124"saved alternate configuration.\n"
1da177e4 125"\n"
8d9dfe82
MW
126"Even if you don't use alternate configuration files, but you find\n"
127"during a Menuconfig session that you have completely messed up your\n"
128"settings, you may use the <Load> button to restore your previously\n"
129"saved settings from \".config\" without restarting Menuconfig.\n"
1da177e4
LT
130"\n"
131"Other information\n"
132"-----------------\n"
8d9dfe82
MW
133"If you use Menuconfig in an XTERM window, make sure you have your\n"
134"$TERM variable set to point to an xterm definition which supports\n"
135"color. Otherwise, Menuconfig will look rather bad. Menuconfig will\n"
136"not display correctly in an RXVT window because rxvt displays only one\n"
1da177e4
LT
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"
8d9dfe82
MW
151"If you prefer to have all of the options listed in a single menu,\n"
152"rather than the default multimenu hierarchy, run the menuconfig with\n"
652cf982 153"MENUCONFIG_MODE environment variable set to single_menu. Example:\n"
1da177e4
LT
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"
da8daff9
BC
164
165"Search\n"
166"-------\n"
167"Pressing the forward-slash (/) anywhere brings up a search dialog box.\n"
168"\n"
169
45897213
SR
170"Different color themes available\n"
171"--------------------------------\n"
172"It is possible to select different color themes using the variable\n"
173"MENUCONFIG_COLOR. To select a theme use:\n"
174"\n"
175"make MENUCONFIG_COLOR=<theme> menuconfig\n"
176"\n"
177"Available themes are\n"
178" mono => selects colors suitable for monochrome displays\n"
179" blackbg => selects a color scheme with black background\n"
350b5b76 180" classic => theme with blue background. The classic look\n"
8d9dfe82 181" bluetitle => an LCD friendly version of classic. (default)\n"
694c49a7
SR
182"\n",
183menu_instructions[] =
1da177e4 184 "Arrow keys navigate the menu. "
1278ebdb 185 "<Enter> selects submenus ---> (or empty submenus ----). "
1da177e4
LT
186 "Highlighted letters are hotkeys. "
187 "Pressing <Y> includes, <N> excludes, <M> modularizes features. "
188 "Press <Esc><Esc> to exit, <?> for Help, </> for Search. "
694c49a7
SR
189 "Legend: [*] built-in [ ] excluded <M> module < > module capable",
190radiolist_instructions[] =
1da177e4
LT
191 "Use the arrow keys to navigate this window or "
192 "press the hotkey of the item you wish to select "
193 "followed by the <SPACE BAR>. "
694c49a7
SR
194 "Press <?> for additional information about this option.",
195inputbox_instructions_int[] =
1da177e4
LT
196 "Please enter a decimal value. "
197 "Fractions will not be accepted. "
694c49a7
SR
198 "Use the <TAB> key to move from the input field to the buttons below it.",
199inputbox_instructions_hex[] =
1da177e4 200 "Please enter a hexadecimal value. "
694c49a7
SR
201 "Use the <TAB> key to move from the input field to the buttons below it.",
202inputbox_instructions_string[] =
1da177e4 203 "Please enter a string value. "
694c49a7
SR
204 "Use the <TAB> key to move from the input field to the buttons below it.",
205setmod_text[] =
1da177e4 206 "This feature depends on another which has been configured as a module.\n"
694c49a7
SR
207 "As a result, this feature will be built as a module.",
208load_config_text[] =
1da177e4
LT
209 "Enter the name of the configuration file you wish to load. "
210 "Accept the name shown to restore the configuration you "
694c49a7
SR
211 "last retrieved. Leave blank to abort.",
212load_config_help[] =
1da177e4 213 "\n"
652cf982 214 "For various reasons, one may wish to keep several different\n"
1da177e4
LT
215 "configurations available on a single machine.\n"
216 "\n"
217 "If you have saved a previous configuration in a file other than the\n"
652cf982
AL
218 "default one, entering its name here will allow you to modify that\n"
219 "configuration.\n"
1da177e4
LT
220 "\n"
221 "If you are uncertain, then you have probably never used alternate\n"
694c49a7
SR
222 "configuration files. You should therefore leave this blank to abort.\n",
223save_config_text[] =
1da177e4 224 "Enter a filename to which this configuration should be saved "
694c49a7
SR
225 "as an alternate. Leave blank to abort.",
226save_config_help[] =
1da177e4 227 "\n"
652cf982
AL
228 "For various reasons, one may wish to keep different configurations\n"
229 "available on a single machine.\n"
1da177e4
LT
230 "\n"
231 "Entering a file name here will allow you to later retrieve, modify\n"
232 "and use the current configuration as an alternate to whatever\n"
233 "configuration options you have selected at that time.\n"
234 "\n"
235 "If you are uncertain what all this means then you should probably\n"
694c49a7
SR
236 "leave this blank.\n",
237search_help[] =
1da177e4 238 "\n"
59dfa24d 239 "Search for symbols and display their relations.\n"
503af334 240 "Regular expressions are allowed.\n"
1da177e4
LT
241 "Example: search for \"^FOO\"\n"
242 "Result:\n"
243 "-----------------------------------------------------------------\n"
244 "Symbol: FOO [=m]\n"
5e609add 245 "Type : tristate\n"
1da177e4 246 "Prompt: Foo bus is used to drive the bar HW\n"
5e609add
BP
247 " Location:\n"
248 " -> Bus options (PCI, PCMCIA, EISA, ISA)\n"
249 " -> PCI support (PCI [=y])\n"
250 "(1) -> PCI access mode (<choice> [=y])\n"
8d9dfe82 251 " Defined at drivers/pci/Kconfig:47\n"
0df8e970 252 " Depends on: X86_LOCAL_APIC && X86_IO_APIC\n"
5e609add 253 " Selects: LIBCRC32\n"
8d9dfe82 254 " Selected by: BAR [=n]\n"
1da177e4 255 "-----------------------------------------------------------------\n"
5e609add 256 "o The line 'Type:' shows the type of the configuration option for\n"
b92d804a 257 " this symbol (bool, tristate, string, ...)\n"
1da177e4 258 "o The line 'Prompt:' shows the text used in the menu structure for\n"
59dfa24d 259 " this symbol\n"
8d9dfe82 260 "o The 'Defined at' line tells at what file / line number the symbol\n"
1da177e4 261 " is defined\n"
8d9dfe82 262 "o The 'Depends on:' line tells what symbols need to be defined for\n"
1da177e4 263 " this symbol to be visible in the menu (selectable)\n"
8d9dfe82 264 "o The 'Location:' lines tells where in the menu structure this symbol\n"
1da177e4 265 " is located\n"
5e609add
BP
266 " A location followed by a [=y] indicates that this is a\n"
267 " selectable menu item - and the current value is displayed inside\n"
268 " brackets.\n"
269 " Press the key in the (#) prefix to jump directly to that\n"
270 " location. You will be returned to the current search results\n"
271 " after exiting this new menu.\n"
8d9dfe82 272 "o The 'Selects:' line tells what symbols will be automatically\n"
1da177e4 273 " selected if this symbol is selected (y or m)\n"
8d9dfe82 274 "o The 'Selected by' line tells what symbol has selected this symbol\n"
1da177e4
LT
275 "\n"
276 "Only relevant lines are shown.\n"
277 "\n\n"
278 "Search examples:\n"
59dfa24d
AL
279 "Examples: USB => find all symbols containing USB\n"
280 " ^USB => find all symbols starting with USB\n"
281 " USB$ => find all symbols ending with USB\n"
694c49a7 282 "\n";
1da177e4 283
1da177e4 284static int indent;
1da177e4
LT
285static struct menu *current_menu;
286static int child_count;
1da177e4 287static int single_menu_mode;
22c7eca6 288static int show_all_options;
6364fd0c 289static int save_and_exit;
0a1f00a1 290static int silent;
1da177e4 291
5e609add 292static void conf(struct menu *menu, struct menu *active_menu);
1da177e4 293
95e30f95
SR
294static char filename[PATH_MAX+1];
295static void set_config_filename(const char *config_filename)
296{
297 static char menu_backtitle[PATH_MAX+128];
95e30f95 298
68876c38
MY
299 snprintf(menu_backtitle, sizeof(menu_backtitle), "%s - %s",
300 config_filename, rootmenu.prompt->text);
95e30f95
SR
301 set_dialog_backtitle(menu_backtitle);
302
68876c38 303 snprintf(filename, sizeof(filename), "%s", config_filename);
95e30f95
SR
304}
305
9a69abf8
BP
306struct subtitle_part {
307 struct list_head entries;
308 const char *text;
309};
310static LIST_HEAD(trail);
311
312static struct subtitle_list *subtitles;
313static void set_subtitle(void)
314{
315 struct subtitle_part *sp;
316 struct subtitle_list *pos, *tmp;
317
318 for (pos = subtitles; pos != NULL; pos = tmp) {
319 tmp = pos->next;
320 free(pos);
321 }
322
323 subtitles = NULL;
324 list_for_each_entry(sp, &trail, entries) {
325 if (sp->text) {
326 if (pos) {
e4e458b4 327 pos->next = xcalloc(1, sizeof(*pos));
9a69abf8
BP
328 pos = pos->next;
329 } else {
e4e458b4 330 subtitles = pos = xcalloc(1, sizeof(*pos));
9a69abf8
BP
331 }
332 pos->text = sp->text;
333 }
334 }
335
336 set_dialog_subtitles(subtitles);
337}
338
339static void reset_subtitle(void)
340{
341 struct subtitle_list *pos, *tmp;
342
343 for (pos = subtitles; pos != NULL; pos = tmp) {
344 tmp = pos->next;
345 free(pos);
346 }
347 subtitles = NULL;
348 set_dialog_subtitles(subtitles);
349}
95e30f95 350
e14f1242
MY
351static int show_textbox_ext(const char *title, const char *text, int r, int c,
352 int *vscroll, int *hscroll,
353 int (*extra_key_cb)(int, size_t, size_t, void *),
354 void *data)
fb318e54
MY
355{
356 dialog_clear();
e14f1242
MY
357 return dialog_textbox(title, text, r, c, vscroll, hscroll,
358 extra_key_cb, data);
fb318e54
MY
359}
360
361static void show_textbox(const char *title, const char *text, int r, int c)
362{
e14f1242 363 show_textbox_ext(title, text, r, c, NULL, NULL, NULL, NULL);
fb318e54
MY
364}
365
366static void show_helptext(const char *title, const char *text)
367{
368 show_textbox(title, text, 0, 0);
369}
370
371static void show_help(struct menu *menu)
372{
373 struct gstr help = str_new();
374
375 help.max_width = getmaxx(stdscr) - 10;
376 menu_get_ext_help(menu, &help);
377
378 show_helptext(menu_get_prompt(menu), str_get(&help));
379 str_free(&help);
380}
381
1da177e4
LT
382static void search_conf(void)
383{
384 struct symbol **sym_arr;
1da177e4 385 struct gstr res;
337a275d 386 struct gstr title;
0584f9f9 387 char *dialog_input;
5e609add
BP
388 int dres, vscroll = 0, hscroll = 0;
389 bool again;
9a69abf8
BP
390 struct gstr sttext;
391 struct subtitle_part stpart;
5e609add 392
337a275d 393 title = str_new();
694c49a7
SR
394 str_printf( &title, "Enter (sub)string or regexp to search for "
395 "(with or without \"%s\")", CONFIG_);
337a275d 396
1da177e4 397again:
e94c5bde 398 dialog_clear();
694c49a7 399 dres = dialog_inputbox("Search Configuration Parameter",
337a275d 400 str_get(&title),
2982de69
SR
401 10, 75, "");
402 switch (dres) {
1da177e4
LT
403 case 0:
404 break;
405 case 1:
694c49a7 406 show_helptext("Search Configuration", search_help);
1da177e4
LT
407 goto again;
408 default:
337a275d 409 str_free(&title);
1da177e4
LT
410 return;
411 }
412
ffb5957b 413 /* strip the prefix if necessary */
0584f9f9 414 dialog_input = dialog_input_result;
ffb5957b
AL
415 if (strncasecmp(dialog_input_result, CONFIG_, strlen(CONFIG_)) == 0)
416 dialog_input += strlen(CONFIG_);
0584f9f9 417
9a69abf8
BP
418 sttext = str_new();
419 str_printf(&sttext, "Search (%s)", dialog_input_result);
420 stpart.text = str_get(&sttext);
421 list_add_tail(&stpart.entries, &trail);
422
0584f9f9 423 sym_arr = sym_re_search(dialog_input);
5e609add 424 do {
bad9955d 425 LIST_HEAD(head);
95ac9b3b
BP
426 struct search_data data = {
427 .head = &head,
95ac9b3b 428 };
edb749f4 429 struct jump_key *pos, *tmp;
95ac9b3b 430
e14f1242 431 jump_key_char = 0;
95ac9b3b 432 res = get_relations_str(sym_arr, &head);
9a69abf8 433 set_subtitle();
4d980fd1 434 dres = show_textbox_ext("Search Results", str_get(&res), 0, 0,
e14f1242
MY
435 &vscroll, &hscroll,
436 handle_search_keys, &data);
5e609add 437 again = false;
e14f1242
MY
438 if (dres >= '1' && dres <= '9') {
439 assert(data.target != NULL);
440 conf(data.target->parent, data.target);
441 again = true;
442 }
5e609add 443 str_free(&res);
edb749f4
BP
444 list_for_each_entry_safe(pos, tmp, &head, entries)
445 free(pos);
5e609add 446 } while (again);
1da177e4 447 free(sym_arr);
337a275d 448 str_free(&title);
9a69abf8
BP
449 list_del(trail.prev);
450 str_free(&sttext);
1da177e4
LT
451}
452
453static void build_conf(struct menu *menu)
454{
455 struct symbol *sym;
456 struct property *prop;
457 struct menu *child;
458 int type, tmp, doint = 2;
459 tristate val;
460 char ch;
22c7eca6
LZ
461 bool visible;
462
463 /*
464 * note: menu_is_visible() has side effect that it will
465 * recalc the value of the symbol.
466 */
467 visible = menu_is_visible(menu);
468 if (show_all_options && !menu_has_prompt(menu))
469 return;
470 else if (!show_all_options && !visible)
1da177e4
LT
471 return;
472
473 sym = menu->sym;
474 prop = menu->prompt;
475 if (!sym) {
476 if (prop && menu != current_menu) {
477 const char *prompt = menu_get_prompt(menu);
478 switch (prop->type) {
479 case P_MENU:
480 child_count++;
1da177e4 481 if (single_menu_mode) {
2982de69
SR
482 item_make("%s%*c%s",
483 menu->data ? "-->" : "++>",
484 indent + 1, ' ', prompt);
1da177e4 485 } else
1278ebdb
DG
486 item_make(" %*c%s %s",
487 indent + 1, ' ', prompt,
488 menu_is_empty(menu) ? "----" : "--->");
2982de69
SR
489 item_set_tag('m');
490 item_set_data(menu);
1da177e4
LT
491 if (single_menu_mode && menu->data)
492 goto conf_childs;
493 return;
48874077
SR
494 case P_COMMENT:
495 if (prompt) {
496 child_count++;
694c49a7 497 item_make(" %*c*** %s ***", indent + 1, ' ', prompt);
48874077
SR
498 item_set_tag(':');
499 item_set_data(menu);
500 }
501 break;
1da177e4
LT
502 default:
503 if (prompt) {
504 child_count++;
694c49a7 505 item_make("---%*c%s", indent + 1, ' ', prompt);
2982de69
SR
506 item_set_tag(':');
507 item_set_data(menu);
1da177e4
LT
508 }
509 }
510 } else
511 doint = 0;
512 goto conf_childs;
513 }
514
515 type = sym_get_type(sym);
516 if (sym_is_choice(sym)) {
517 struct symbol *def_sym = sym_get_choice_value(sym);
518 struct menu *def_menu = NULL;
519
520 child_count++;
521 for (child = menu->list; child; child = child->next) {
522 if (menu_is_visible(child) && child->sym == def_sym)
523 def_menu = child;
524 }
525
526 val = sym_get_tristate_value(sym);
baa23ec8 527 if (sym_is_changeable(sym)) {
1da177e4
LT
528 switch (type) {
529 case S_BOOLEAN:
2982de69 530 item_make("[%c]", val == no ? ' ' : '*');
1da177e4
LT
531 break;
532 case S_TRISTATE:
533 switch (val) {
534 case yes: ch = '*'; break;
535 case mod: ch = 'M'; break;
536 default: ch = ' '; break;
537 }
2982de69 538 item_make("<%c>", ch);
1da177e4
LT
539 break;
540 }
2982de69
SR
541 item_set_tag('t');
542 item_set_data(menu);
1da177e4 543 } else {
2982de69
SR
544 item_make(" ");
545 item_set_tag(def_menu ? 't' : ':');
546 item_set_data(menu);
1da177e4
LT
547 }
548
694c49a7 549 item_add_str("%*c%s", indent + 1, ' ', menu_get_prompt(menu));
1da177e4
LT
550 if (val == yes) {
551 if (def_menu) {
694c49a7 552 item_add_str(" (%s)", menu_get_prompt(def_menu));
2982de69 553 item_add_str(" --->");
2982de69 554 }
1da177e4
LT
555 return;
556 }
1da177e4
LT
557 } else {
558 if (menu == current_menu) {
694c49a7 559 item_make("---%*c%s", indent + 1, ' ', menu_get_prompt(menu));
2982de69
SR
560 item_set_tag(':');
561 item_set_data(menu);
1da177e4
LT
562 goto conf_childs;
563 }
564 child_count++;
565 val = sym_get_tristate_value(sym);
e89b4615
MY
566 switch (type) {
567 case S_BOOLEAN:
568 if (sym_is_changeable(sym))
569 item_make("[%c]", val == no ? ' ' : '*');
570 else
571 item_make("-%c-", val == no ? ' ' : '*');
572 item_set_tag('t');
2982de69 573 item_set_data(menu);
e89b4615
MY
574 break;
575 case S_TRISTATE:
576 switch (val) {
577 case yes: ch = '*'; break;
578 case mod: ch = 'M'; break;
579 default: ch = ' '; break;
1da177e4 580 }
e89b4615
MY
581 if (sym_is_changeable(sym)) {
582 if (sym->rev_dep.tri == mod)
583 item_make("{%c}", ch);
584 else
585 item_make("<%c>", ch);
586 } else
587 item_make("-%c-", ch);
588 item_set_tag('t');
589 item_set_data(menu);
590 break;
591 default:
592 tmp = 2 + strlen(sym_get_string_value(sym)); /* () = 2 */
593 item_make("(%s)", sym_get_string_value(sym));
594 tmp = indent - tmp + 4;
595 if (tmp < 0)
596 tmp = 0;
597 item_add_str("%*c%s%s", tmp, ' ', menu_get_prompt(menu),
598 (sym_has_value(sym) || !sym_is_changeable(sym)) ?
599 "" : " (NEW)");
600 item_set_tag('s');
601 item_set_data(menu);
602 goto conf_childs;
1da177e4 603 }
694c49a7 604 item_add_str("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu),
baa23ec8 605 (sym_has_value(sym) || !sym_is_changeable(sym)) ?
694c49a7 606 "" : " (NEW)");
1da177e4 607 if (menu->prompt->type == P_MENU) {
1278ebdb 608 item_add_str(" %s", menu_is_empty(menu) ? "----" : "--->");
1da177e4
LT
609 return;
610 }
1da177e4
LT
611 }
612
613conf_childs:
614 indent += doint;
615 for (child = menu->list; child; child = child->next)
616 build_conf(child);
617 indent -= doint;
618}
619
1da177e4
LT
620static void conf_choice(struct menu *menu)
621{
694c49a7 622 const char *prompt = menu_get_prompt(menu);
1da177e4
LT
623 struct menu *child;
624 struct symbol *active;
1da177e4
LT
625
626 active = sym_get_choice_value(menu->sym);
627 while (1) {
2982de69
SR
628 int res;
629 int selected;
630 item_reset();
1da177e4
LT
631
632 current_menu = menu;
633 for (child = menu->list; child; child = child->next) {
634 if (!menu_is_visible(child))
635 continue;
af6c1598 636 if (child->sym)
694c49a7 637 item_make("%s", menu_get_prompt(child));
af6c1598 638 else {
694c49a7 639 item_make("*** %s ***", menu_get_prompt(child));
af6c1598
PK
640 item_set_tag(':');
641 }
2982de69
SR
642 item_set_data(child);
643 if (child->sym == active)
644 item_set_selected(1);
1da177e4 645 if (child->sym == sym_get_choice_value(menu->sym))
2982de69 646 item_set_tag('X');
1da177e4 647 }
e94c5bde 648 dialog_clear();
694c49a7
SR
649 res = dialog_checklist(prompt ? prompt : "Main Menu",
650 radiolist_instructions,
89e5462b 651 MENUBOX_HEIGHT_MIN,
ff7b0c2c 652 MENUBOX_WIDTH_MIN,
89e5462b 653 CHECKLIST_HEIGHT_MIN);
2982de69
SR
654 selected = item_activate_selected();
655 switch (res) {
1da177e4 656 case 0:
2982de69
SR
657 if (selected) {
658 child = item_data();
af6c1598
PK
659 if (!child->sym)
660 break;
661
2982de69
SR
662 sym_set_tristate_value(child->sym, yes);
663 }
1da177e4
LT
664 return;
665 case 1:
2982de69
SR
666 if (selected) {
667 child = item_data();
1da177e4
LT
668 show_help(child);
669 active = child->sym;
670 } else
671 show_help(menu);
672 break;
f3cbcdc9 673 case KEY_ESC:
1da177e4 674 return;
c8dc68ad
SR
675 case -ERRDISPLAYTOOSMALL:
676 return;
1da177e4
LT
677 }
678 }
679}
680
681static void conf_string(struct menu *menu)
682{
683 const char *prompt = menu_get_prompt(menu);
1da177e4
LT
684
685 while (1) {
2982de69 686 int res;
c4143a83 687 const char *heading;
2982de69 688
1da177e4
LT
689 switch (sym_get_type(menu->sym)) {
690 case S_INT:
694c49a7 691 heading = inputbox_instructions_int;
1da177e4
LT
692 break;
693 case S_HEX:
694c49a7 694 heading = inputbox_instructions_hex;
1da177e4
LT
695 break;
696 case S_STRING:
694c49a7 697 heading = inputbox_instructions_string;
1da177e4
LT
698 break;
699 default:
694c49a7 700 heading = "Internal mconf error!";
1da177e4 701 }
e94c5bde 702 dialog_clear();
694c49a7 703 res = dialog_inputbox(prompt ? prompt : "Main Menu",
2982de69
SR
704 heading, 10, 75,
705 sym_get_string_value(menu->sym));
706 switch (res) {
1da177e4 707 case 0:
2982de69 708 if (sym_set_string_value(menu->sym, dialog_input_result))
1da177e4 709 return;
694c49a7 710 show_textbox(NULL, "You have made an invalid entry.", 5, 43);
1da177e4
LT
711 break;
712 case 1:
713 show_help(menu);
714 break;
f3cbcdc9 715 case KEY_ESC:
1da177e4
LT
716 return;
717 }
718 }
719}
720
721static void conf_load(void)
722{
1da177e4
LT
723
724 while (1) {
2982de69 725 int res;
e94c5bde 726 dialog_clear();
2982de69
SR
727 res = dialog_inputbox(NULL, load_config_text,
728 11, 55, filename);
729 switch(res) {
1da177e4 730 case 0:
2982de69 731 if (!dialog_input_result[0])
1da177e4 732 return;
95e30f95
SR
733 if (!conf_read(dialog_input_result)) {
734 set_config_filename(dialog_input_result);
5ee54659 735 conf_set_changed(true);
1da177e4 736 return;
95e30f95 737 }
694c49a7 738 show_textbox(NULL, "File does not exist!", 5, 38);
1da177e4
LT
739 break;
740 case 1:
694c49a7 741 show_helptext("Load Alternate Configuration", load_config_help);
1da177e4 742 break;
f3cbcdc9 743 case KEY_ESC:
1da177e4
LT
744 return;
745 }
746 }
747}
748
749static void conf_save(void)
750{
1da177e4 751 while (1) {
2982de69 752 int res;
e94c5bde 753 dialog_clear();
2982de69
SR
754 res = dialog_inputbox(NULL, save_config_text,
755 11, 55, filename);
756 switch(res) {
1da177e4 757 case 0:
2982de69 758 if (!dialog_input_result[0])
1da177e4 759 return;
95e30f95
SR
760 if (!conf_write(dialog_input_result)) {
761 set_config_filename(dialog_input_result);
1da177e4 762 return;
95e30f95 763 }
580c5b3e 764 show_textbox(NULL, "Can't create file!", 5, 60);
1da177e4
LT
765 break;
766 case 1:
694c49a7 767 show_helptext("Save Alternate Configuration", save_config_help);
1da177e4 768 break;
f3cbcdc9 769 case KEY_ESC:
1da177e4
LT
770 return;
771 }
772 }
773}
774
fb318e54
MY
775static void conf(struct menu *menu, struct menu *active_menu)
776{
777 struct menu *submenu;
778 const char *prompt = menu_get_prompt(menu);
779 struct subtitle_part stpart;
780 struct symbol *sym;
781 int res;
782 int s_scroll = 0;
783
784 if (menu != &rootmenu)
785 stpart.text = menu_get_prompt(menu);
786 else
787 stpart.text = NULL;
788 list_add_tail(&stpart.entries, &trail);
789
790 while (1) {
791 item_reset();
792 current_menu = menu;
793 build_conf(menu);
794 if (!child_count)
795 break;
796 set_subtitle();
797 dialog_clear();
798 res = dialog_menu(prompt ? prompt : "Main Menu",
799 menu_instructions,
800 active_menu, &s_scroll);
801 if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL)
802 break;
803 if (item_count() != 0) {
804 if (!item_activate_selected())
805 continue;
806 if (!item_tag())
807 continue;
808 }
809 submenu = item_data();
810 active_menu = item_data();
811 if (submenu)
812 sym = submenu->sym;
813 else
814 sym = NULL;
815
816 switch (res) {
817 case 0:
818 switch (item_tag()) {
819 case 'm':
820 if (single_menu_mode)
821 submenu->data = (void *) (long) !submenu->data;
822 else
823 conf(submenu, NULL);
824 break;
825 case 't':
826 if (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)
827 conf_choice(submenu);
828 else if (submenu->prompt->type == P_MENU)
829 conf(submenu, NULL);
830 break;
831 case 's':
832 conf_string(submenu);
833 break;
834 }
835 break;
836 case 2:
837 if (sym)
838 show_help(submenu);
839 else {
840 reset_subtitle();
841 show_helptext("README", mconf_readme);
842 }
843 break;
844 case 3:
845 reset_subtitle();
846 conf_save();
847 break;
848 case 4:
849 reset_subtitle();
850 conf_load();
851 break;
852 case 5:
853 if (item_is_tag('t')) {
854 if (sym_set_tristate_value(sym, yes))
855 break;
856 if (sym_set_tristate_value(sym, mod))
857 show_textbox(NULL, setmod_text, 6, 74);
858 }
859 break;
860 case 6:
861 if (item_is_tag('t'))
862 sym_set_tristate_value(sym, no);
863 break;
864 case 7:
865 if (item_is_tag('t'))
866 sym_set_tristate_value(sym, mod);
867 break;
868 case 8:
869 if (item_is_tag('t'))
870 sym_toggle_tristate_value(sym);
871 else if (item_is_tag('m'))
872 conf(submenu, NULL);
873 break;
874 case 9:
875 search_conf();
876 break;
877 case 10:
878 show_all_options = !show_all_options;
879 break;
880 }
881 }
882
883 list_del(trail.prev);
884}
885
886static void conf_message_callback(const char *s)
887{
888 if (save_and_exit) {
889 if (!silent)
890 printf("%s", s);
891 } else {
892 show_textbox(NULL, s, 6, 60);
893 }
894}
895
564899f9
DB
896static int handle_exit(void)
897{
898 int res;
899
6364fd0c 900 save_and_exit = 1;
9a69abf8 901 reset_subtitle();
564899f9
DB
902 dialog_clear();
903 if (conf_get_changed())
904 res = dialog_yesno(NULL,
694c49a7
SR
905 "Do you wish to save your new configuration?\n"
906 "(Press <ESC><ESC> to continue kernel configuration.)",
564899f9
DB
907 6, 60);
908 else
909 res = -1;
910
911 end_dialog(saved_x, saved_y);
912
913 switch (res) {
914 case 0:
915 if (conf_write(filename)) {
694c49a7 916 fprintf(stderr, "\n\n"
564899f9
DB
917 "Error while writing of the configuration.\n"
918 "Your configuration changes were NOT saved."
694c49a7 919 "\n\n");
564899f9
DB
920 return 1;
921 }
00c864f8 922 conf_write_autoconf(0);
564899f9
DB
923 /* fall through */
924 case -1:
0a1f00a1 925 if (!silent)
694c49a7 926 printf("\n\n"
0a1f00a1
MM
927 "*** End of the configuration.\n"
928 "*** Execute 'make' to start the build or try 'make help'."
694c49a7 929 "\n\n");
564899f9
DB
930 res = 0;
931 break;
932 default:
0a1f00a1 933 if (!silent)
694c49a7 934 fprintf(stderr, "\n\n"
0a1f00a1 935 "Your configuration changes were NOT saved."
694c49a7 936 "\n\n");
30c4eaaf
LZ
937 if (res != KEY_ESC)
938 res = 0;
564899f9
DB
939 }
940
941 return res;
942}
943
944static void sig_handler(int signo)
945{
946 exit(handle_exit());
947}
948
1da177e4
LT
949int main(int ac, char **av)
950{
1da177e4 951 char *mode;
2982de69 952 int res;
1da177e4 953
564899f9
DB
954 signal(SIGINT, sig_handler);
955
0a1f00a1
MM
956 if (ac > 1 && strcmp(av[1], "-s") == 0) {
957 silent = 1;
958 /* Silence conf_read() until the real callback is set up */
959 conf_set_message_callback(NULL);
960 av++;
961 }
1da177e4
LT
962 conf_parse(av[1]);
963 conf_read(NULL);
964
1da177e4
LT
965 mode = getenv("MENUCONFIG_MODE");
966 if (mode) {
967 if (!strcasecmp(mode, "single_menu"))
968 single_menu_mode = 1;
969 }
970
09af091f 971 if (init_dialog(NULL)) {
694c49a7
SR
972 fprintf(stderr, "Your display is too small to run Menuconfig!\n");
973 fprintf(stderr, "It must be at least 19 lines by 80 columns.\n");
09af091f
LM
974 return 1;
975 }
976
d802b50f 977 set_config_filename(conf_get_configname());
6364fd0c 978 conf_set_message_callback(conf_message_callback);
f3cbcdc9 979 do {
5e609add 980 conf(&rootmenu, NULL);
564899f9 981 res = handle_exit();
f3cbcdc9 982 } while (res == KEY_ESC);
1da177e4 983
564899f9 984 return res;
1da177e4 985}