Root/scripts/kconfig/mconf.c

1/*
2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0.
4 *
5 * Introduced single menu mode (show all sub-menus in one large tree).
6 * 2002-11-06 Petr Baudis <pasky@ucw.cz>
7 *
8 * i18n, 2005, Arnaldo Carvalho de Melo <acme@conectiva.com.br>
9 */
10
11#include <ctype.h>
12#include <errno.h>
13#include <fcntl.h>
14#include <limits.h>
15#include <stdarg.h>
16#include <stdlib.h>
17#include <string.h>
18#include <unistd.h>
19#include <locale.h>
20
21#define LKC_DIRECT_LINK
22#include "lkc.h"
23#include "lxdialog/dialog.h"
24
25static const char mconf_readme[] = N_(
26"Overview\n"
27"--------\n"
28"This interface let you select features and parameters for the build.\n"
29"Features can either be built-in, modularized, or ignored. Parameters\n"
30"must be entered in as decimal or hexadecimal numbers or text.\n"
31"\n"
32"Menu items beginning with following braces represent features that\n"
33" [ ] can be built in or removed\n"
34" < > can be built in, modularized or removed\n"
35" { } can be built in or modularized (selected by other feature)\n"
36" - - are selected by other feature,\n"
37"while *, M or whitespace inside braces means to build in, build as\n"
38"a module or to exclude the feature respectively.\n"
39"\n"
40"To change any of these features, highlight it with the cursor\n"
41"keys and press <Y> to build it in, <M> to make it a module or\n"
42"<N> to removed it. You may also press the <Space Bar> to cycle\n"
43"through the available options (ie. Y->N->M->Y).\n"
44"\n"
45"Some additional keyboard hints:\n"
46"\n"
47"Menus\n"
48"----------\n"
49"o Use the Up/Down arrow keys (cursor keys) to highlight the item\n"
50" you wish to change or submenu wish to select and press <Enter>.\n"
51" Submenus are designated by \"--->\".\n"
52"\n"
53" Shortcut: Press the option's highlighted letter (hotkey).\n"
54" Pressing a hotkey more than once will sequence\n"
55" through all visible items which use that hotkey.\n"
56"\n"
57" You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll\n"
58" unseen options into view.\n"
59"\n"
60"o To exit a menu use the cursor keys to highlight the <Exit> button\n"
61" and press <ENTER>.\n"
62"\n"
63" Shortcut: Press <ESC><ESC> or <E> or <X> if there is no hotkey\n"
64" using those letters. You may press a single <ESC>, but\n"
65" there is a delayed response which you may find annoying.\n"
66"\n"
67" Also, the <TAB> and cursor keys will cycle between <Select>,\n"
68" <Exit> and <Help>.\n"
69"\n"
70"o To get help with an item, use the cursor keys to highlight <Help>\n"
71" and press <ENTER>.\n"
72"\n"
73" Shortcut: Press <H> or <?>.\n"
74"\n"
75"o To toggle the display of hidden options, press <Z>.\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 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 options listed in a single menu, rather\n"
152"than the default multimenu hierarchy, run the menuconfig with\n"
153"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"),
177menu_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"),
184radiolist_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."),
189inputbox_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."),
193inputbox_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."),
196inputbox_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."),
199setmod_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."),
202load_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."),
206load_config_help[] = N_(
207    "\n"
208    "For various reasons, one may wish to keep several different\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    "default one, entering its name here will allow you to modify that\n"
213    "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"),
217save_config_text[] = N_(
218    "Enter a filename to which this configuration should be saved "
219    "as an alternate. Leave blank to abort."),
220save_config_help[] = N_(
221    "\n"
222    "For various reasons, one may wish to keep different configurations\n"
223    "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"),
231search_help[] = N_(
232    "\n"
233    "Search for 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 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 symbols containing USB\n"
267    " ^USB => find all symbols starting with USB\n"
268    " USB$ => find all symbols ending with USB\n"
269    "\n");
270
271static int indent;
272static struct menu *current_menu;
273static int child_count;
274static int single_menu_mode;
275static int show_all_options;
276
277static void conf(struct menu *menu);
278static void conf_choice(struct menu *menu);
279static void conf_string(struct menu *menu);
280static void conf_load(void);
281static void conf_save(void);
282static void show_textbox(const char *title, const char *text, int r, int c);
283static void show_helptext(const char *title, const char *text);
284static void show_help(struct menu *menu);
285
286static char filename[PATH_MAX+1];
287static void set_config_filename(const char *config_filename)
288{
289    static char menu_backtitle[PATH_MAX+128];
290    int size;
291
292    size = snprintf(menu_backtitle, sizeof(menu_backtitle),
293                    "%s - %s", config_filename, rootmenu.prompt->text);
294    if (size >= sizeof(menu_backtitle))
295        menu_backtitle[sizeof(menu_backtitle)-1] = '\0';
296    set_dialog_backtitle(menu_backtitle);
297
298    size = snprintf(filename, sizeof(filename), "%s", config_filename);
299    if (size >= sizeof(filename))
300        filename[sizeof(filename)-1] = '\0';
301}
302
303
304static void search_conf(void)
305{
306    struct symbol **sym_arr;
307    struct gstr res;
308    char *dialog_input;
309    int dres;
310again:
311    dialog_clear();
312    dres = dialog_inputbox(_("Search Configuration Parameter"),
313                  _("Enter " CONFIG_ " (sub)string to search for "
314                "(with or without \"" CONFIG_ "\")"),
315                  10, 75, "");
316    switch (dres) {
317    case 0:
318        break;
319    case 1:
320        show_helptext(_("Search Configuration"), search_help);
321        goto again;
322    default:
323        return;
324    }
325
326    /* strip the prefix if necessary */
327    dialog_input = dialog_input_result;
328    if (strncasecmp(dialog_input_result, CONFIG_, strlen(CONFIG_)) == 0)
329        dialog_input += strlen(CONFIG_);
330
331    sym_arr = sym_re_search(dialog_input);
332    res = get_relations_str(sym_arr);
333    free(sym_arr);
334    show_textbox(_("Search Results"), str_get(&res), 0, 0);
335    str_free(&res);
336}
337
338static void build_conf(struct menu *menu)
339{
340    struct symbol *sym;
341    struct property *prop;
342    struct menu *child;
343    int type, tmp, doint = 2;
344    tristate val;
345    char ch;
346    bool visible;
347
348    /*
349     * note: menu_is_visible() has side effect that it will
350     * recalc the value of the symbol.
351     */
352    visible = menu_is_visible(menu);
353    if (show_all_options && !menu_has_prompt(menu))
354        return;
355    else if (!show_all_options && !visible)
356        return;
357
358    sym = menu->sym;
359    prop = menu->prompt;
360    if (!sym) {
361        if (prop && menu != current_menu) {
362            const char *prompt = menu_get_prompt(menu);
363            switch (prop->type) {
364            case P_MENU:
365                child_count++;
366                prompt = _(prompt);
367                if (single_menu_mode) {
368                    item_make("%s%*c%s",
369                          menu->data ? "-->" : "++>",
370                          indent + 1, ' ', prompt);
371                } else
372                    item_make(" %*c%s --->", indent + 1, ' ', prompt);
373
374                item_set_tag('m');
375                item_set_data(menu);
376                if (single_menu_mode && menu->data)
377                    goto conf_childs;
378                return;
379            case P_COMMENT:
380                if (prompt) {
381                    child_count++;
382                    item_make(" %*c*** %s ***", indent + 1, ' ', _(prompt));
383                    item_set_tag(':');
384                    item_set_data(menu);
385                }
386                break;
387            default:
388                if (prompt) {
389                    child_count++;
390                    item_make("---%*c%s", indent + 1, ' ', _(prompt));
391                    item_set_tag(':');
392                    item_set_data(menu);
393                }
394            }
395        } else
396            doint = 0;
397        goto conf_childs;
398    }
399
400    type = sym_get_type(sym);
401    if (sym_is_choice(sym)) {
402        struct symbol *def_sym = sym_get_choice_value(sym);
403        struct menu *def_menu = NULL;
404
405        child_count++;
406        for (child = menu->list; child; child = child->next) {
407            if (menu_is_visible(child) && child->sym == def_sym)
408                def_menu = child;
409        }
410
411        val = sym_get_tristate_value(sym);
412        if (sym_is_changable(sym)) {
413            switch (type) {
414            case S_BOOLEAN:
415                item_make("[%c]", val == no ? ' ' : '*');
416                break;
417            case S_TRISTATE:
418                switch (val) {
419                case yes: ch = '*'; break;
420                case mod: ch = 'M'; break;
421                default: ch = ' '; break;
422                }
423                item_make("<%c>", ch);
424                break;
425            }
426            item_set_tag('t');
427            item_set_data(menu);
428        } else {
429            item_make(" ");
430            item_set_tag(def_menu ? 't' : ':');
431            item_set_data(menu);
432        }
433
434        item_add_str("%*c%s", indent + 1, ' ', _(menu_get_prompt(menu)));
435        if (val == yes) {
436            if (def_menu) {
437                item_add_str(" (%s)", _(menu_get_prompt(def_menu)));
438                item_add_str(" --->");
439                if (def_menu->list) {
440                    indent += 2;
441                    build_conf(def_menu);
442                    indent -= 2;
443                }
444            }
445            return;
446        }
447    } else {
448        if (menu == current_menu) {
449            item_make("---%*c%s", indent + 1, ' ', _(menu_get_prompt(menu)));
450            item_set_tag(':');
451            item_set_data(menu);
452            goto conf_childs;
453        }
454        child_count++;
455        val = sym_get_tristate_value(sym);
456        if (sym_is_choice_value(sym) && val == yes) {
457            item_make(" ");
458            item_set_tag(':');
459            item_set_data(menu);
460        } else {
461            switch (type) {
462            case S_BOOLEAN:
463                if (sym_is_changable(sym))
464                    item_make("[%c]", val == no ? ' ' : '*');
465                else
466                    item_make("-%c-", val == no ? ' ' : '*');
467                item_set_tag('t');
468                item_set_data(menu);
469                break;
470            case S_TRISTATE:
471                switch (val) {
472                case yes: ch = '*'; break;
473                case mod: ch = 'M'; break;
474                default: ch = ' '; break;
475                }
476                if (sym_is_changable(sym)) {
477                    if (sym->rev_dep.tri == mod)
478                        item_make("{%c}", ch);
479                    else
480                        item_make("<%c>", ch);
481                } else
482                    item_make("-%c-", ch);
483                item_set_tag('t');
484                item_set_data(menu);
485                break;
486            default:
487                tmp = 2 + strlen(sym_get_string_value(sym)); /* () = 2 */
488                item_make("(%s)", sym_get_string_value(sym));
489                tmp = indent - tmp + 4;
490                if (tmp < 0)
491                    tmp = 0;
492                item_add_str("%*c%s%s", tmp, ' ', _(menu_get_prompt(menu)),
493                         (sym_has_value(sym) || !sym_is_changable(sym)) ?
494                         "" : _(" (NEW)"));
495                item_set_tag('s');
496                item_set_data(menu);
497                goto conf_childs;
498            }
499        }
500        item_add_str("%*c%s%s", indent + 1, ' ', _(menu_get_prompt(menu)),
501              (sym_has_value(sym) || !sym_is_changable(sym)) ?
502              "" : _(" (NEW)"));
503        if (menu->prompt->type == P_MENU) {
504            item_add_str(" --->");
505            return;
506        }
507    }
508
509conf_childs:
510    indent += doint;
511    for (child = menu->list; child; child = child->next)
512        build_conf(child);
513    indent -= doint;
514}
515
516static void conf(struct menu *menu)
517{
518    struct menu *submenu;
519    const char *prompt = menu_get_prompt(menu);
520    struct symbol *sym;
521    struct menu *active_menu = NULL;
522    int res;
523    int s_scroll = 0;
524
525    while (1) {
526        item_reset();
527        current_menu = menu;
528        build_conf(menu);
529        if (!child_count)
530            break;
531        if (menu == &rootmenu) {
532            item_make("--- ");
533            item_set_tag(':');
534            item_make(_(" Load an Alternate Configuration File"));
535            item_set_tag('L');
536            item_make(_(" Save an Alternate Configuration File"));
537            item_set_tag('S');
538        }
539        dialog_clear();
540        res = dialog_menu(prompt ? _(prompt) : _("Main Menu"),
541                  _(menu_instructions),
542                  active_menu, &s_scroll);
543        if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL)
544            break;
545        if (!item_activate_selected())
546            continue;
547        if (!item_tag())
548            continue;
549
550        submenu = item_data();
551        active_menu = item_data();
552        if (submenu)
553            sym = submenu->sym;
554        else
555            sym = NULL;
556
557        switch (res) {
558        case 0:
559            switch (item_tag()) {
560            case 'm':
561                if (single_menu_mode)
562                    submenu->data = (void *) (long) !submenu->data;
563                else
564                    conf(submenu);
565                break;
566            case 't':
567                if (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)
568                    conf_choice(submenu);
569                else if (submenu->prompt->type == P_MENU)
570                    conf(submenu);
571                break;
572            case 's':
573                conf_string(submenu);
574                break;
575            case 'L':
576                conf_load();
577                break;
578            case 'S':
579                conf_save();
580                break;
581            }
582            break;
583        case 2:
584            if (sym)
585                show_help(submenu);
586            else
587                show_helptext(_("README"), _(mconf_readme));
588            break;
589        case 3:
590            if (item_is_tag('t')) {
591                if (sym_set_tristate_value(sym, yes))
592                    break;
593                if (sym_set_tristate_value(sym, mod))
594                    show_textbox(NULL, setmod_text, 6, 74);
595            }
596            break;
597        case 4:
598            if (item_is_tag('t'))
599                sym_set_tristate_value(sym, no);
600            break;
601        case 5:
602            if (item_is_tag('t'))
603                sym_set_tristate_value(sym, mod);
604            break;
605        case 6:
606            if (item_is_tag('t'))
607                sym_toggle_tristate_value(sym);
608            else if (item_is_tag('m'))
609                conf(submenu);
610            break;
611        case 7:
612            search_conf();
613            break;
614        case 8:
615            show_all_options = !show_all_options;
616            break;
617        }
618    }
619}
620
621static void show_textbox(const char *title, const char *text, int r, int c)
622{
623    dialog_clear();
624    dialog_textbox(title, text, r, c);
625}
626
627static void show_helptext(const char *title, const char *text)
628{
629    show_textbox(title, text, 0, 0);
630}
631
632static void show_help(struct menu *menu)
633{
634    struct gstr help = str_new();
635
636    help.max_width = getmaxx(stdscr) - 10;
637    menu_get_ext_help(menu, &help);
638
639    show_helptext(_(menu_get_prompt(menu)), str_get(&help));
640    str_free(&help);
641}
642
643static void conf_choice(struct menu *menu)
644{
645    const char *prompt = _(menu_get_prompt(menu));
646    struct menu *child;
647    struct symbol *active;
648
649    active = sym_get_choice_value(menu->sym);
650    while (1) {
651        int res;
652        int selected;
653        item_reset();
654
655        current_menu = menu;
656        for (child = menu->list; child; child = child->next) {
657            if (!menu_is_visible(child))
658                continue;
659            if (child->sym)
660                item_make("%s", _(menu_get_prompt(child)));
661            else {
662                item_make("*** %s ***", _(menu_get_prompt(child)));
663                item_set_tag(':');
664            }
665            item_set_data(child);
666            if (child->sym == active)
667                item_set_selected(1);
668            if (child->sym == sym_get_choice_value(menu->sym))
669                item_set_tag('X');
670        }
671        dialog_clear();
672        res = dialog_checklist(prompt ? _(prompt) : _("Main Menu"),
673                    _(radiolist_instructions),
674                     15, 70, 6);
675        selected = item_activate_selected();
676        switch (res) {
677        case 0:
678            if (selected) {
679                child = item_data();
680                if (!child->sym)
681                    break;
682
683                sym_set_tristate_value(child->sym, yes);
684            }
685            return;
686        case 1:
687            if (selected) {
688                child = item_data();
689                show_help(child);
690                active = child->sym;
691            } else
692                show_help(menu);
693            break;
694        case KEY_ESC:
695            return;
696        case -ERRDISPLAYTOOSMALL:
697            return;
698        }
699    }
700}
701
702static void conf_string(struct menu *menu)
703{
704    const char *prompt = menu_get_prompt(menu);
705
706    while (1) {
707        int res;
708        const char *heading;
709
710        switch (sym_get_type(menu->sym)) {
711        case S_INT:
712            heading = _(inputbox_instructions_int);
713            break;
714        case S_HEX:
715            heading = _(inputbox_instructions_hex);
716            break;
717        case S_STRING:
718            heading = _(inputbox_instructions_string);
719            break;
720        default:
721            heading = _("Internal mconf error!");
722        }
723        dialog_clear();
724        res = dialog_inputbox(prompt ? _(prompt) : _("Main Menu"),
725                      heading, 10, 75,
726                      sym_get_string_value(menu->sym));
727        switch (res) {
728        case 0:
729            if (sym_set_string_value(menu->sym, dialog_input_result))
730                return;
731            show_textbox(NULL, _("You have made an invalid entry."), 5, 43);
732            break;
733        case 1:
734            show_help(menu);
735            break;
736        case KEY_ESC:
737            return;
738        }
739    }
740}
741
742static void conf_load(void)
743{
744
745    while (1) {
746        int res;
747        dialog_clear();
748        res = dialog_inputbox(NULL, load_config_text,
749                      11, 55, filename);
750        switch(res) {
751        case 0:
752            if (!dialog_input_result[0])
753                return;
754            if (!conf_read(dialog_input_result)) {
755                set_config_filename(dialog_input_result);
756                sym_set_change_count(1);
757                return;
758            }
759            show_textbox(NULL, _("File does not exist!"), 5, 38);
760            break;
761        case 1:
762            show_helptext(_("Load Alternate Configuration"), load_config_help);
763            break;
764        case KEY_ESC:
765            return;
766        }
767    }
768}
769
770static void conf_save(void)
771{
772    while (1) {
773        int res;
774        dialog_clear();
775        res = dialog_inputbox(NULL, save_config_text,
776                      11, 55, filename);
777        switch(res) {
778        case 0:
779            if (!dialog_input_result[0])
780                return;
781            if (!conf_write(dialog_input_result)) {
782                set_config_filename(dialog_input_result);
783                return;
784            }
785            show_textbox(NULL, _("Can't create file! Probably a nonexistent directory."), 5, 60);
786            break;
787        case 1:
788            show_helptext(_("Save Alternate Configuration"), save_config_help);
789            break;
790        case KEY_ESC:
791            return;
792        }
793    }
794}
795
796int main(int ac, char **av)
797{
798    int saved_x, saved_y;
799    char *mode;
800    int res;
801
802    setlocale(LC_ALL, "");
803    bindtextdomain(PACKAGE, LOCALEDIR);
804    textdomain(PACKAGE);
805
806    conf_parse(av[1]);
807    conf_read(NULL);
808
809    mode = getenv("MENUCONFIG_MODE");
810    if (mode) {
811        if (!strcasecmp(mode, "single_menu"))
812            single_menu_mode = 1;
813    }
814
815    initscr();
816
817    getyx(stdscr, saved_y, saved_x);
818    if (init_dialog(NULL)) {
819        fprintf(stderr, N_("Your display is too small to run Menuconfig!\n"));
820        fprintf(stderr, N_("It must be at least 19 lines by 80 columns.\n"));
821        return 1;
822    }
823
824    set_config_filename(conf_get_configname());
825    do {
826        conf(&rootmenu);
827        dialog_clear();
828        if (conf_get_changed())
829            res = dialog_yesno(NULL,
830                       _("Do you wish to save your "
831                         "new configuration?\n"
832                         "<ESC><ESC> to continue."),
833                       6, 60);
834        else
835            res = -1;
836    } while (res == KEY_ESC);
837    end_dialog(saved_x, saved_y);
838
839    switch (res) {
840    case 0:
841        if (conf_write(filename)) {
842            fprintf(stderr, _("\n\n"
843                "Error while writing of the configuration.\n"
844                "Your configuration changes were NOT saved."
845                "\n\n"));
846            return 1;
847        }
848    case -1:
849        printf(_("\n\n"
850            "*** End of the configuration.\n"
851            "*** Execute 'make' to start the build or try 'make help'."
852            "\n\n"));
853        break;
854    default:
855        fprintf(stderr, _("\n\n"
856            "Your configuration changes were NOT saved."
857            "\n\n"));
858    }
859
860    return 0;
861}
862
863

Archive Download this file



interactive