18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Introduced single menu mode (show all sub-menus in one large tree). 68c2ecf20Sopenharmony_ci * 2002-11-06 Petr Baudis <pasky@ucw.cz> 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * i18n, 2005, Arnaldo Carvalho de Melo <acme@conectiva.com.br> 98c2ecf20Sopenharmony_ci */ 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#include <ctype.h> 128c2ecf20Sopenharmony_ci#include <errno.h> 138c2ecf20Sopenharmony_ci#include <fcntl.h> 148c2ecf20Sopenharmony_ci#include <limits.h> 158c2ecf20Sopenharmony_ci#include <stdarg.h> 168c2ecf20Sopenharmony_ci#include <stdlib.h> 178c2ecf20Sopenharmony_ci#include <string.h> 188c2ecf20Sopenharmony_ci#include <strings.h> 198c2ecf20Sopenharmony_ci#include <signal.h> 208c2ecf20Sopenharmony_ci#include <unistd.h> 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci#include "lkc.h" 238c2ecf20Sopenharmony_ci#include "lxdialog/dialog.h" 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_cistatic const char mconf_readme[] = 268c2ecf20Sopenharmony_ci"Overview\n" 278c2ecf20Sopenharmony_ci"--------\n" 288c2ecf20Sopenharmony_ci"This interface lets you select features and parameters for the build.\n" 298c2ecf20Sopenharmony_ci"Features can either be built-in, modularized, or ignored. Parameters\n" 308c2ecf20Sopenharmony_ci"must be entered in as decimal or hexadecimal numbers or text.\n" 318c2ecf20Sopenharmony_ci"\n" 328c2ecf20Sopenharmony_ci"Menu items beginning with following braces represent features that\n" 338c2ecf20Sopenharmony_ci" [ ] can be built in or removed\n" 348c2ecf20Sopenharmony_ci" < > can be built in, modularized or removed\n" 358c2ecf20Sopenharmony_ci" { } can be built in or modularized (selected by other feature)\n" 368c2ecf20Sopenharmony_ci" - - are selected by other feature,\n" 378c2ecf20Sopenharmony_ci"while *, M or whitespace inside braces means to build in, build as\n" 388c2ecf20Sopenharmony_ci"a module or to exclude the feature respectively.\n" 398c2ecf20Sopenharmony_ci"\n" 408c2ecf20Sopenharmony_ci"To change any of these features, highlight it with the cursor\n" 418c2ecf20Sopenharmony_ci"keys and press <Y> to build it in, <M> to make it a module or\n" 428c2ecf20Sopenharmony_ci"<N> to remove it. You may also press the <Space Bar> to cycle\n" 438c2ecf20Sopenharmony_ci"through the available options (i.e. Y->N->M->Y).\n" 448c2ecf20Sopenharmony_ci"\n" 458c2ecf20Sopenharmony_ci"Some additional keyboard hints:\n" 468c2ecf20Sopenharmony_ci"\n" 478c2ecf20Sopenharmony_ci"Menus\n" 488c2ecf20Sopenharmony_ci"----------\n" 498c2ecf20Sopenharmony_ci"o Use the Up/Down arrow keys (cursor keys) to highlight the item you\n" 508c2ecf20Sopenharmony_ci" wish to change or the submenu you wish to select and press <Enter>.\n" 518c2ecf20Sopenharmony_ci" Submenus are designated by \"--->\", empty ones by \"----\".\n" 528c2ecf20Sopenharmony_ci"\n" 538c2ecf20Sopenharmony_ci" Shortcut: Press the option's highlighted letter (hotkey).\n" 548c2ecf20Sopenharmony_ci" Pressing a hotkey more than once will sequence\n" 558c2ecf20Sopenharmony_ci" through all visible items which use that hotkey.\n" 568c2ecf20Sopenharmony_ci"\n" 578c2ecf20Sopenharmony_ci" You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll\n" 588c2ecf20Sopenharmony_ci" unseen options into view.\n" 598c2ecf20Sopenharmony_ci"\n" 608c2ecf20Sopenharmony_ci"o To exit a menu use the cursor keys to highlight the <Exit> button\n" 618c2ecf20Sopenharmony_ci" and press <ENTER>.\n" 628c2ecf20Sopenharmony_ci"\n" 638c2ecf20Sopenharmony_ci" Shortcut: Press <ESC><ESC> or <E> or <X> if there is no hotkey\n" 648c2ecf20Sopenharmony_ci" using those letters. You may press a single <ESC>, but\n" 658c2ecf20Sopenharmony_ci" there is a delayed response which you may find annoying.\n" 668c2ecf20Sopenharmony_ci"\n" 678c2ecf20Sopenharmony_ci" Also, the <TAB> and cursor keys will cycle between <Select>,\n" 688c2ecf20Sopenharmony_ci" <Exit>, <Help>, <Save>, and <Load>.\n" 698c2ecf20Sopenharmony_ci"\n" 708c2ecf20Sopenharmony_ci"o To get help with an item, use the cursor keys to highlight <Help>\n" 718c2ecf20Sopenharmony_ci" and press <ENTER>.\n" 728c2ecf20Sopenharmony_ci"\n" 738c2ecf20Sopenharmony_ci" Shortcut: Press <H> or <?>.\n" 748c2ecf20Sopenharmony_ci"\n" 758c2ecf20Sopenharmony_ci"o To toggle the display of hidden options, press <Z>.\n" 768c2ecf20Sopenharmony_ci"\n" 778c2ecf20Sopenharmony_ci"\n" 788c2ecf20Sopenharmony_ci"Radiolists (Choice lists)\n" 798c2ecf20Sopenharmony_ci"-----------\n" 808c2ecf20Sopenharmony_ci"o Use the cursor keys to select the option you wish to set and press\n" 818c2ecf20Sopenharmony_ci" <S> or the <SPACE BAR>.\n" 828c2ecf20Sopenharmony_ci"\n" 838c2ecf20Sopenharmony_ci" Shortcut: Press the first letter of the option you wish to set then\n" 848c2ecf20Sopenharmony_ci" press <S> or <SPACE BAR>.\n" 858c2ecf20Sopenharmony_ci"\n" 868c2ecf20Sopenharmony_ci"o To see available help for the item, use the cursor keys to highlight\n" 878c2ecf20Sopenharmony_ci" <Help> and Press <ENTER>.\n" 888c2ecf20Sopenharmony_ci"\n" 898c2ecf20Sopenharmony_ci" Shortcut: Press <H> or <?>.\n" 908c2ecf20Sopenharmony_ci"\n" 918c2ecf20Sopenharmony_ci" Also, the <TAB> and cursor keys will cycle between <Select> and\n" 928c2ecf20Sopenharmony_ci" <Help>\n" 938c2ecf20Sopenharmony_ci"\n" 948c2ecf20Sopenharmony_ci"\n" 958c2ecf20Sopenharmony_ci"Data Entry\n" 968c2ecf20Sopenharmony_ci"-----------\n" 978c2ecf20Sopenharmony_ci"o Enter the requested information and press <ENTER>\n" 988c2ecf20Sopenharmony_ci" If you are entering hexadecimal values, it is not necessary to\n" 998c2ecf20Sopenharmony_ci" add the '0x' prefix to the entry.\n" 1008c2ecf20Sopenharmony_ci"\n" 1018c2ecf20Sopenharmony_ci"o For help, use the <TAB> or cursor keys to highlight the help option\n" 1028c2ecf20Sopenharmony_ci" and press <ENTER>. You can try <TAB><H> as well.\n" 1038c2ecf20Sopenharmony_ci"\n" 1048c2ecf20Sopenharmony_ci"\n" 1058c2ecf20Sopenharmony_ci"Text Box (Help Window)\n" 1068c2ecf20Sopenharmony_ci"--------\n" 1078c2ecf20Sopenharmony_ci"o Use the cursor keys to scroll up/down/left/right. The VI editor\n" 1088c2ecf20Sopenharmony_ci" keys h,j,k,l function here as do <u>, <d>, <SPACE BAR> and <B> for\n" 1098c2ecf20Sopenharmony_ci" those who are familiar with less and lynx.\n" 1108c2ecf20Sopenharmony_ci"\n" 1118c2ecf20Sopenharmony_ci"o Press <E>, <X>, <q>, <Enter> or <Esc><Esc> to exit.\n" 1128c2ecf20Sopenharmony_ci"\n" 1138c2ecf20Sopenharmony_ci"\n" 1148c2ecf20Sopenharmony_ci"Alternate Configuration Files\n" 1158c2ecf20Sopenharmony_ci"-----------------------------\n" 1168c2ecf20Sopenharmony_ci"Menuconfig supports the use of alternate configuration files for\n" 1178c2ecf20Sopenharmony_ci"those who, for various reasons, find it necessary to switch\n" 1188c2ecf20Sopenharmony_ci"between different configurations.\n" 1198c2ecf20Sopenharmony_ci"\n" 1208c2ecf20Sopenharmony_ci"The <Save> button will let you save the current configuration to\n" 1218c2ecf20Sopenharmony_ci"a file of your choosing. Use the <Load> button to load a previously\n" 1228c2ecf20Sopenharmony_ci"saved alternate configuration.\n" 1238c2ecf20Sopenharmony_ci"\n" 1248c2ecf20Sopenharmony_ci"Even if you don't use alternate configuration files, but you find\n" 1258c2ecf20Sopenharmony_ci"during a Menuconfig session that you have completely messed up your\n" 1268c2ecf20Sopenharmony_ci"settings, you may use the <Load> button to restore your previously\n" 1278c2ecf20Sopenharmony_ci"saved settings from \".config\" without restarting Menuconfig.\n" 1288c2ecf20Sopenharmony_ci"\n" 1298c2ecf20Sopenharmony_ci"Other information\n" 1308c2ecf20Sopenharmony_ci"-----------------\n" 1318c2ecf20Sopenharmony_ci"If you use Menuconfig in an XTERM window, make sure you have your\n" 1328c2ecf20Sopenharmony_ci"$TERM variable set to point to an xterm definition which supports\n" 1338c2ecf20Sopenharmony_ci"color. Otherwise, Menuconfig will look rather bad. Menuconfig will\n" 1348c2ecf20Sopenharmony_ci"not display correctly in an RXVT window because rxvt displays only one\n" 1358c2ecf20Sopenharmony_ci"intensity of color, bright.\n" 1368c2ecf20Sopenharmony_ci"\n" 1378c2ecf20Sopenharmony_ci"Menuconfig will display larger menus on screens or xterms which are\n" 1388c2ecf20Sopenharmony_ci"set to display more than the standard 25 row by 80 column geometry.\n" 1398c2ecf20Sopenharmony_ci"In order for this to work, the \"stty size\" command must be able to\n" 1408c2ecf20Sopenharmony_ci"display the screen's current row and column geometry. I STRONGLY\n" 1418c2ecf20Sopenharmony_ci"RECOMMEND that you make sure you do NOT have the shell variables\n" 1428c2ecf20Sopenharmony_ci"LINES and COLUMNS exported into your environment. Some distributions\n" 1438c2ecf20Sopenharmony_ci"export those variables via /etc/profile. Some ncurses programs can\n" 1448c2ecf20Sopenharmony_ci"become confused when those variables (LINES & COLUMNS) don't reflect\n" 1458c2ecf20Sopenharmony_ci"the true screen size.\n" 1468c2ecf20Sopenharmony_ci"\n" 1478c2ecf20Sopenharmony_ci"Optional personality available\n" 1488c2ecf20Sopenharmony_ci"------------------------------\n" 1498c2ecf20Sopenharmony_ci"If you prefer to have all of the options listed in a single menu,\n" 1508c2ecf20Sopenharmony_ci"rather than the default multimenu hierarchy, run the menuconfig with\n" 1518c2ecf20Sopenharmony_ci"MENUCONFIG_MODE environment variable set to single_menu. Example:\n" 1528c2ecf20Sopenharmony_ci"\n" 1538c2ecf20Sopenharmony_ci"make MENUCONFIG_MODE=single_menu menuconfig\n" 1548c2ecf20Sopenharmony_ci"\n" 1558c2ecf20Sopenharmony_ci"<Enter> will then unroll the appropriate category, or enfold it if it\n" 1568c2ecf20Sopenharmony_ci"is already unrolled.\n" 1578c2ecf20Sopenharmony_ci"\n" 1588c2ecf20Sopenharmony_ci"Note that this mode can eventually be a little more CPU expensive\n" 1598c2ecf20Sopenharmony_ci"(especially with a larger number of unrolled categories) than the\n" 1608c2ecf20Sopenharmony_ci"default mode.\n" 1618c2ecf20Sopenharmony_ci"\n" 1628c2ecf20Sopenharmony_ci"Different color themes available\n" 1638c2ecf20Sopenharmony_ci"--------------------------------\n" 1648c2ecf20Sopenharmony_ci"It is possible to select different color themes using the variable\n" 1658c2ecf20Sopenharmony_ci"MENUCONFIG_COLOR. To select a theme use:\n" 1668c2ecf20Sopenharmony_ci"\n" 1678c2ecf20Sopenharmony_ci"make MENUCONFIG_COLOR=<theme> menuconfig\n" 1688c2ecf20Sopenharmony_ci"\n" 1698c2ecf20Sopenharmony_ci"Available themes are\n" 1708c2ecf20Sopenharmony_ci" mono => selects colors suitable for monochrome displays\n" 1718c2ecf20Sopenharmony_ci" blackbg => selects a color scheme with black background\n" 1728c2ecf20Sopenharmony_ci" classic => theme with blue background. The classic look\n" 1738c2ecf20Sopenharmony_ci" bluetitle => an LCD friendly version of classic. (default)\n" 1748c2ecf20Sopenharmony_ci"\n", 1758c2ecf20Sopenharmony_cimenu_instructions[] = 1768c2ecf20Sopenharmony_ci "Arrow keys navigate the menu. " 1778c2ecf20Sopenharmony_ci "<Enter> selects submenus ---> (or empty submenus ----). " 1788c2ecf20Sopenharmony_ci "Highlighted letters are hotkeys. " 1798c2ecf20Sopenharmony_ci "Pressing <Y> includes, <N> excludes, <M> modularizes features. " 1808c2ecf20Sopenharmony_ci "Press <Esc><Esc> to exit, <?> for Help, </> for Search. " 1818c2ecf20Sopenharmony_ci "Legend: [*] built-in [ ] excluded <M> module < > module capable", 1828c2ecf20Sopenharmony_ciradiolist_instructions[] = 1838c2ecf20Sopenharmony_ci "Use the arrow keys to navigate this window or " 1848c2ecf20Sopenharmony_ci "press the hotkey of the item you wish to select " 1858c2ecf20Sopenharmony_ci "followed by the <SPACE BAR>. " 1868c2ecf20Sopenharmony_ci "Press <?> for additional information about this option.", 1878c2ecf20Sopenharmony_ciinputbox_instructions_int[] = 1888c2ecf20Sopenharmony_ci "Please enter a decimal value. " 1898c2ecf20Sopenharmony_ci "Fractions will not be accepted. " 1908c2ecf20Sopenharmony_ci "Use the <TAB> key to move from the input field to the buttons below it.", 1918c2ecf20Sopenharmony_ciinputbox_instructions_hex[] = 1928c2ecf20Sopenharmony_ci "Please enter a hexadecimal value. " 1938c2ecf20Sopenharmony_ci "Use the <TAB> key to move from the input field to the buttons below it.", 1948c2ecf20Sopenharmony_ciinputbox_instructions_string[] = 1958c2ecf20Sopenharmony_ci "Please enter a string value. " 1968c2ecf20Sopenharmony_ci "Use the <TAB> key to move from the input field to the buttons below it.", 1978c2ecf20Sopenharmony_cisetmod_text[] = 1988c2ecf20Sopenharmony_ci "This feature depends on another which has been configured as a module.\n" 1998c2ecf20Sopenharmony_ci "As a result, this feature will be built as a module.", 2008c2ecf20Sopenharmony_ciload_config_text[] = 2018c2ecf20Sopenharmony_ci "Enter the name of the configuration file you wish to load. " 2028c2ecf20Sopenharmony_ci "Accept the name shown to restore the configuration you " 2038c2ecf20Sopenharmony_ci "last retrieved. Leave blank to abort.", 2048c2ecf20Sopenharmony_ciload_config_help[] = 2058c2ecf20Sopenharmony_ci "\n" 2068c2ecf20Sopenharmony_ci "For various reasons, one may wish to keep several different\n" 2078c2ecf20Sopenharmony_ci "configurations available on a single machine.\n" 2088c2ecf20Sopenharmony_ci "\n" 2098c2ecf20Sopenharmony_ci "If you have saved a previous configuration in a file other than the\n" 2108c2ecf20Sopenharmony_ci "default one, entering its name here will allow you to modify that\n" 2118c2ecf20Sopenharmony_ci "configuration.\n" 2128c2ecf20Sopenharmony_ci "\n" 2138c2ecf20Sopenharmony_ci "If you are uncertain, then you have probably never used alternate\n" 2148c2ecf20Sopenharmony_ci "configuration files. You should therefore leave this blank to abort.\n", 2158c2ecf20Sopenharmony_cisave_config_text[] = 2168c2ecf20Sopenharmony_ci "Enter a filename to which this configuration should be saved " 2178c2ecf20Sopenharmony_ci "as an alternate. Leave blank to abort.", 2188c2ecf20Sopenharmony_cisave_config_help[] = 2198c2ecf20Sopenharmony_ci "\n" 2208c2ecf20Sopenharmony_ci "For various reasons, one may wish to keep different configurations\n" 2218c2ecf20Sopenharmony_ci "available on a single machine.\n" 2228c2ecf20Sopenharmony_ci "\n" 2238c2ecf20Sopenharmony_ci "Entering a file name here will allow you to later retrieve, modify\n" 2248c2ecf20Sopenharmony_ci "and use the current configuration as an alternate to whatever\n" 2258c2ecf20Sopenharmony_ci "configuration options you have selected at that time.\n" 2268c2ecf20Sopenharmony_ci "\n" 2278c2ecf20Sopenharmony_ci "If you are uncertain what all this means then you should probably\n" 2288c2ecf20Sopenharmony_ci "leave this blank.\n", 2298c2ecf20Sopenharmony_cisearch_help[] = 2308c2ecf20Sopenharmony_ci "\n" 2318c2ecf20Sopenharmony_ci "Search for symbols and display their relations.\n" 2328c2ecf20Sopenharmony_ci "Regular expressions are allowed.\n" 2338c2ecf20Sopenharmony_ci "Example: search for \"^FOO\"\n" 2348c2ecf20Sopenharmony_ci "Result:\n" 2358c2ecf20Sopenharmony_ci "-----------------------------------------------------------------\n" 2368c2ecf20Sopenharmony_ci "Symbol: FOO [=m]\n" 2378c2ecf20Sopenharmony_ci "Type : tristate\n" 2388c2ecf20Sopenharmony_ci "Prompt: Foo bus is used to drive the bar HW\n" 2398c2ecf20Sopenharmony_ci " Location:\n" 2408c2ecf20Sopenharmony_ci " -> Bus options (PCI, PCMCIA, EISA, ISA)\n" 2418c2ecf20Sopenharmony_ci " -> PCI support (PCI [=y])\n" 2428c2ecf20Sopenharmony_ci "(1) -> PCI access mode (<choice> [=y])\n" 2438c2ecf20Sopenharmony_ci " Defined at drivers/pci/Kconfig:47\n" 2448c2ecf20Sopenharmony_ci " Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n" 2458c2ecf20Sopenharmony_ci " Selects: LIBCRC32\n" 2468c2ecf20Sopenharmony_ci " Selected by: BAR [=n]\n" 2478c2ecf20Sopenharmony_ci "-----------------------------------------------------------------\n" 2488c2ecf20Sopenharmony_ci "o The line 'Type:' shows the type of the configuration option for\n" 2498c2ecf20Sopenharmony_ci " this symbol (bool, tristate, string, ...)\n" 2508c2ecf20Sopenharmony_ci "o The line 'Prompt:' shows the text used in the menu structure for\n" 2518c2ecf20Sopenharmony_ci " this symbol\n" 2528c2ecf20Sopenharmony_ci "o The 'Defined at' line tells at what file / line number the symbol\n" 2538c2ecf20Sopenharmony_ci " is defined\n" 2548c2ecf20Sopenharmony_ci "o The 'Depends on:' line tells what symbols need to be defined for\n" 2558c2ecf20Sopenharmony_ci " this symbol to be visible in the menu (selectable)\n" 2568c2ecf20Sopenharmony_ci "o The 'Location:' lines tells where in the menu structure this symbol\n" 2578c2ecf20Sopenharmony_ci " is located\n" 2588c2ecf20Sopenharmony_ci " A location followed by a [=y] indicates that this is a\n" 2598c2ecf20Sopenharmony_ci " selectable menu item - and the current value is displayed inside\n" 2608c2ecf20Sopenharmony_ci " brackets.\n" 2618c2ecf20Sopenharmony_ci " Press the key in the (#) prefix to jump directly to that\n" 2628c2ecf20Sopenharmony_ci " location. You will be returned to the current search results\n" 2638c2ecf20Sopenharmony_ci " after exiting this new menu.\n" 2648c2ecf20Sopenharmony_ci "o The 'Selects:' line tells what symbols will be automatically\n" 2658c2ecf20Sopenharmony_ci " selected if this symbol is selected (y or m)\n" 2668c2ecf20Sopenharmony_ci "o The 'Selected by' line tells what symbol has selected this symbol\n" 2678c2ecf20Sopenharmony_ci "\n" 2688c2ecf20Sopenharmony_ci "Only relevant lines are shown.\n" 2698c2ecf20Sopenharmony_ci "\n\n" 2708c2ecf20Sopenharmony_ci "Search examples:\n" 2718c2ecf20Sopenharmony_ci "Examples: USB => find all symbols containing USB\n" 2728c2ecf20Sopenharmony_ci " ^USB => find all symbols starting with USB\n" 2738c2ecf20Sopenharmony_ci " USB$ => find all symbols ending with USB\n" 2748c2ecf20Sopenharmony_ci "\n"; 2758c2ecf20Sopenharmony_ci 2768c2ecf20Sopenharmony_cistatic int indent; 2778c2ecf20Sopenharmony_cistatic struct menu *current_menu; 2788c2ecf20Sopenharmony_cistatic int child_count; 2798c2ecf20Sopenharmony_cistatic int single_menu_mode; 2808c2ecf20Sopenharmony_cistatic int show_all_options; 2818c2ecf20Sopenharmony_cistatic int save_and_exit; 2828c2ecf20Sopenharmony_cistatic int silent; 2838c2ecf20Sopenharmony_ci 2848c2ecf20Sopenharmony_cistatic void conf(struct menu *menu, struct menu *active_menu); 2858c2ecf20Sopenharmony_cistatic void conf_choice(struct menu *menu); 2868c2ecf20Sopenharmony_cistatic void conf_string(struct menu *menu); 2878c2ecf20Sopenharmony_cistatic void conf_load(void); 2888c2ecf20Sopenharmony_cistatic void conf_save(void); 2898c2ecf20Sopenharmony_cistatic int show_textbox_ext(const char *title, char *text, int r, int c, 2908c2ecf20Sopenharmony_ci int *keys, int *vscroll, int *hscroll, 2918c2ecf20Sopenharmony_ci update_text_fn update_text, void *data); 2928c2ecf20Sopenharmony_cistatic void show_textbox(const char *title, const char *text, int r, int c); 2938c2ecf20Sopenharmony_cistatic void show_helptext(const char *title, const char *text); 2948c2ecf20Sopenharmony_cistatic void show_help(struct menu *menu); 2958c2ecf20Sopenharmony_ci 2968c2ecf20Sopenharmony_cistatic char filename[PATH_MAX+1]; 2978c2ecf20Sopenharmony_cistatic void set_config_filename(const char *config_filename) 2988c2ecf20Sopenharmony_ci{ 2998c2ecf20Sopenharmony_ci static char menu_backtitle[PATH_MAX+128]; 3008c2ecf20Sopenharmony_ci int size; 3018c2ecf20Sopenharmony_ci 3028c2ecf20Sopenharmony_ci size = snprintf(menu_backtitle, sizeof(menu_backtitle), 3038c2ecf20Sopenharmony_ci "%s - %s", config_filename, rootmenu.prompt->text); 3048c2ecf20Sopenharmony_ci if (size >= sizeof(menu_backtitle)) 3058c2ecf20Sopenharmony_ci menu_backtitle[sizeof(menu_backtitle)-1] = '\0'; 3068c2ecf20Sopenharmony_ci set_dialog_backtitle(menu_backtitle); 3078c2ecf20Sopenharmony_ci 3088c2ecf20Sopenharmony_ci size = snprintf(filename, sizeof(filename), "%s", config_filename); 3098c2ecf20Sopenharmony_ci if (size >= sizeof(filename)) 3108c2ecf20Sopenharmony_ci filename[sizeof(filename)-1] = '\0'; 3118c2ecf20Sopenharmony_ci} 3128c2ecf20Sopenharmony_ci 3138c2ecf20Sopenharmony_cistruct subtitle_part { 3148c2ecf20Sopenharmony_ci struct list_head entries; 3158c2ecf20Sopenharmony_ci const char *text; 3168c2ecf20Sopenharmony_ci}; 3178c2ecf20Sopenharmony_cistatic LIST_HEAD(trail); 3188c2ecf20Sopenharmony_ci 3198c2ecf20Sopenharmony_cistatic struct subtitle_list *subtitles; 3208c2ecf20Sopenharmony_cistatic void set_subtitle(void) 3218c2ecf20Sopenharmony_ci{ 3228c2ecf20Sopenharmony_ci struct subtitle_part *sp; 3238c2ecf20Sopenharmony_ci struct subtitle_list *pos, *tmp; 3248c2ecf20Sopenharmony_ci 3258c2ecf20Sopenharmony_ci for (pos = subtitles; pos != NULL; pos = tmp) { 3268c2ecf20Sopenharmony_ci tmp = pos->next; 3278c2ecf20Sopenharmony_ci free(pos); 3288c2ecf20Sopenharmony_ci } 3298c2ecf20Sopenharmony_ci 3308c2ecf20Sopenharmony_ci subtitles = NULL; 3318c2ecf20Sopenharmony_ci list_for_each_entry(sp, &trail, entries) { 3328c2ecf20Sopenharmony_ci if (sp->text) { 3338c2ecf20Sopenharmony_ci if (pos) { 3348c2ecf20Sopenharmony_ci pos->next = xcalloc(1, sizeof(*pos)); 3358c2ecf20Sopenharmony_ci pos = pos->next; 3368c2ecf20Sopenharmony_ci } else { 3378c2ecf20Sopenharmony_ci subtitles = pos = xcalloc(1, sizeof(*pos)); 3388c2ecf20Sopenharmony_ci } 3398c2ecf20Sopenharmony_ci pos->text = sp->text; 3408c2ecf20Sopenharmony_ci } 3418c2ecf20Sopenharmony_ci } 3428c2ecf20Sopenharmony_ci 3438c2ecf20Sopenharmony_ci set_dialog_subtitles(subtitles); 3448c2ecf20Sopenharmony_ci} 3458c2ecf20Sopenharmony_ci 3468c2ecf20Sopenharmony_cistatic void reset_subtitle(void) 3478c2ecf20Sopenharmony_ci{ 3488c2ecf20Sopenharmony_ci struct subtitle_list *pos, *tmp; 3498c2ecf20Sopenharmony_ci 3508c2ecf20Sopenharmony_ci for (pos = subtitles; pos != NULL; pos = tmp) { 3518c2ecf20Sopenharmony_ci tmp = pos->next; 3528c2ecf20Sopenharmony_ci free(pos); 3538c2ecf20Sopenharmony_ci } 3548c2ecf20Sopenharmony_ci subtitles = NULL; 3558c2ecf20Sopenharmony_ci set_dialog_subtitles(subtitles); 3568c2ecf20Sopenharmony_ci} 3578c2ecf20Sopenharmony_ci 3588c2ecf20Sopenharmony_cistruct search_data { 3598c2ecf20Sopenharmony_ci struct list_head *head; 3608c2ecf20Sopenharmony_ci struct menu **targets; 3618c2ecf20Sopenharmony_ci int *keys; 3628c2ecf20Sopenharmony_ci}; 3638c2ecf20Sopenharmony_ci 3648c2ecf20Sopenharmony_cistatic void update_text(char *buf, size_t start, size_t end, void *_data) 3658c2ecf20Sopenharmony_ci{ 3668c2ecf20Sopenharmony_ci struct search_data *data = _data; 3678c2ecf20Sopenharmony_ci struct jump_key *pos; 3688c2ecf20Sopenharmony_ci int k = 0; 3698c2ecf20Sopenharmony_ci 3708c2ecf20Sopenharmony_ci list_for_each_entry(pos, data->head, entries) { 3718c2ecf20Sopenharmony_ci if (pos->offset >= start && pos->offset < end) { 3728c2ecf20Sopenharmony_ci char header[4]; 3738c2ecf20Sopenharmony_ci 3748c2ecf20Sopenharmony_ci if (k < JUMP_NB) { 3758c2ecf20Sopenharmony_ci int key = '0' + (pos->index % JUMP_NB) + 1; 3768c2ecf20Sopenharmony_ci 3778c2ecf20Sopenharmony_ci sprintf(header, "(%c)", key); 3788c2ecf20Sopenharmony_ci data->keys[k] = key; 3798c2ecf20Sopenharmony_ci data->targets[k] = pos->target; 3808c2ecf20Sopenharmony_ci k++; 3818c2ecf20Sopenharmony_ci } else { 3828c2ecf20Sopenharmony_ci sprintf(header, " "); 3838c2ecf20Sopenharmony_ci } 3848c2ecf20Sopenharmony_ci 3858c2ecf20Sopenharmony_ci memcpy(buf + pos->offset, header, sizeof(header) - 1); 3868c2ecf20Sopenharmony_ci } 3878c2ecf20Sopenharmony_ci } 3888c2ecf20Sopenharmony_ci data->keys[k] = 0; 3898c2ecf20Sopenharmony_ci} 3908c2ecf20Sopenharmony_ci 3918c2ecf20Sopenharmony_cistatic void search_conf(void) 3928c2ecf20Sopenharmony_ci{ 3938c2ecf20Sopenharmony_ci struct symbol **sym_arr; 3948c2ecf20Sopenharmony_ci struct gstr res; 3958c2ecf20Sopenharmony_ci struct gstr title; 3968c2ecf20Sopenharmony_ci char *dialog_input; 3978c2ecf20Sopenharmony_ci int dres, vscroll = 0, hscroll = 0; 3988c2ecf20Sopenharmony_ci bool again; 3998c2ecf20Sopenharmony_ci struct gstr sttext; 4008c2ecf20Sopenharmony_ci struct subtitle_part stpart; 4018c2ecf20Sopenharmony_ci 4028c2ecf20Sopenharmony_ci title = str_new(); 4038c2ecf20Sopenharmony_ci str_printf( &title, "Enter (sub)string or regexp to search for " 4048c2ecf20Sopenharmony_ci "(with or without \"%s\")", CONFIG_); 4058c2ecf20Sopenharmony_ci 4068c2ecf20Sopenharmony_ciagain: 4078c2ecf20Sopenharmony_ci dialog_clear(); 4088c2ecf20Sopenharmony_ci dres = dialog_inputbox("Search Configuration Parameter", 4098c2ecf20Sopenharmony_ci str_get(&title), 4108c2ecf20Sopenharmony_ci 10, 75, ""); 4118c2ecf20Sopenharmony_ci switch (dres) { 4128c2ecf20Sopenharmony_ci case 0: 4138c2ecf20Sopenharmony_ci break; 4148c2ecf20Sopenharmony_ci case 1: 4158c2ecf20Sopenharmony_ci show_helptext("Search Configuration", search_help); 4168c2ecf20Sopenharmony_ci goto again; 4178c2ecf20Sopenharmony_ci default: 4188c2ecf20Sopenharmony_ci str_free(&title); 4198c2ecf20Sopenharmony_ci return; 4208c2ecf20Sopenharmony_ci } 4218c2ecf20Sopenharmony_ci 4228c2ecf20Sopenharmony_ci /* strip the prefix if necessary */ 4238c2ecf20Sopenharmony_ci dialog_input = dialog_input_result; 4248c2ecf20Sopenharmony_ci if (strncasecmp(dialog_input_result, CONFIG_, strlen(CONFIG_)) == 0) 4258c2ecf20Sopenharmony_ci dialog_input += strlen(CONFIG_); 4268c2ecf20Sopenharmony_ci 4278c2ecf20Sopenharmony_ci sttext = str_new(); 4288c2ecf20Sopenharmony_ci str_printf(&sttext, "Search (%s)", dialog_input_result); 4298c2ecf20Sopenharmony_ci stpart.text = str_get(&sttext); 4308c2ecf20Sopenharmony_ci list_add_tail(&stpart.entries, &trail); 4318c2ecf20Sopenharmony_ci 4328c2ecf20Sopenharmony_ci sym_arr = sym_re_search(dialog_input); 4338c2ecf20Sopenharmony_ci do { 4348c2ecf20Sopenharmony_ci LIST_HEAD(head); 4358c2ecf20Sopenharmony_ci struct menu *targets[JUMP_NB]; 4368c2ecf20Sopenharmony_ci int keys[JUMP_NB + 1], i; 4378c2ecf20Sopenharmony_ci struct search_data data = { 4388c2ecf20Sopenharmony_ci .head = &head, 4398c2ecf20Sopenharmony_ci .targets = targets, 4408c2ecf20Sopenharmony_ci .keys = keys, 4418c2ecf20Sopenharmony_ci }; 4428c2ecf20Sopenharmony_ci struct jump_key *pos, *tmp; 4438c2ecf20Sopenharmony_ci 4448c2ecf20Sopenharmony_ci res = get_relations_str(sym_arr, &head); 4458c2ecf20Sopenharmony_ci set_subtitle(); 4468c2ecf20Sopenharmony_ci dres = show_textbox_ext("Search Results", (char *) 4478c2ecf20Sopenharmony_ci str_get(&res), 0, 0, keys, &vscroll, 4488c2ecf20Sopenharmony_ci &hscroll, &update_text, (void *) 4498c2ecf20Sopenharmony_ci &data); 4508c2ecf20Sopenharmony_ci again = false; 4518c2ecf20Sopenharmony_ci for (i = 0; i < JUMP_NB && keys[i]; i++) 4528c2ecf20Sopenharmony_ci if (dres == keys[i]) { 4538c2ecf20Sopenharmony_ci conf(targets[i]->parent, targets[i]); 4548c2ecf20Sopenharmony_ci again = true; 4558c2ecf20Sopenharmony_ci } 4568c2ecf20Sopenharmony_ci str_free(&res); 4578c2ecf20Sopenharmony_ci list_for_each_entry_safe(pos, tmp, &head, entries) 4588c2ecf20Sopenharmony_ci free(pos); 4598c2ecf20Sopenharmony_ci } while (again); 4608c2ecf20Sopenharmony_ci free(sym_arr); 4618c2ecf20Sopenharmony_ci str_free(&title); 4628c2ecf20Sopenharmony_ci list_del(trail.prev); 4638c2ecf20Sopenharmony_ci str_free(&sttext); 4648c2ecf20Sopenharmony_ci} 4658c2ecf20Sopenharmony_ci 4668c2ecf20Sopenharmony_cistatic void build_conf(struct menu *menu) 4678c2ecf20Sopenharmony_ci{ 4688c2ecf20Sopenharmony_ci struct symbol *sym; 4698c2ecf20Sopenharmony_ci struct property *prop; 4708c2ecf20Sopenharmony_ci struct menu *child; 4718c2ecf20Sopenharmony_ci int type, tmp, doint = 2; 4728c2ecf20Sopenharmony_ci tristate val; 4738c2ecf20Sopenharmony_ci char ch; 4748c2ecf20Sopenharmony_ci bool visible; 4758c2ecf20Sopenharmony_ci 4768c2ecf20Sopenharmony_ci /* 4778c2ecf20Sopenharmony_ci * note: menu_is_visible() has side effect that it will 4788c2ecf20Sopenharmony_ci * recalc the value of the symbol. 4798c2ecf20Sopenharmony_ci */ 4808c2ecf20Sopenharmony_ci visible = menu_is_visible(menu); 4818c2ecf20Sopenharmony_ci if (show_all_options && !menu_has_prompt(menu)) 4828c2ecf20Sopenharmony_ci return; 4838c2ecf20Sopenharmony_ci else if (!show_all_options && !visible) 4848c2ecf20Sopenharmony_ci return; 4858c2ecf20Sopenharmony_ci 4868c2ecf20Sopenharmony_ci sym = menu->sym; 4878c2ecf20Sopenharmony_ci prop = menu->prompt; 4888c2ecf20Sopenharmony_ci if (!sym) { 4898c2ecf20Sopenharmony_ci if (prop && menu != current_menu) { 4908c2ecf20Sopenharmony_ci const char *prompt = menu_get_prompt(menu); 4918c2ecf20Sopenharmony_ci switch (prop->type) { 4928c2ecf20Sopenharmony_ci case P_MENU: 4938c2ecf20Sopenharmony_ci child_count++; 4948c2ecf20Sopenharmony_ci if (single_menu_mode) { 4958c2ecf20Sopenharmony_ci item_make("%s%*c%s", 4968c2ecf20Sopenharmony_ci menu->data ? "-->" : "++>", 4978c2ecf20Sopenharmony_ci indent + 1, ' ', prompt); 4988c2ecf20Sopenharmony_ci } else 4998c2ecf20Sopenharmony_ci item_make(" %*c%s %s", 5008c2ecf20Sopenharmony_ci indent + 1, ' ', prompt, 5018c2ecf20Sopenharmony_ci menu_is_empty(menu) ? "----" : "--->"); 5028c2ecf20Sopenharmony_ci item_set_tag('m'); 5038c2ecf20Sopenharmony_ci item_set_data(menu); 5048c2ecf20Sopenharmony_ci if (single_menu_mode && menu->data) 5058c2ecf20Sopenharmony_ci goto conf_childs; 5068c2ecf20Sopenharmony_ci return; 5078c2ecf20Sopenharmony_ci case P_COMMENT: 5088c2ecf20Sopenharmony_ci if (prompt) { 5098c2ecf20Sopenharmony_ci child_count++; 5108c2ecf20Sopenharmony_ci item_make(" %*c*** %s ***", indent + 1, ' ', prompt); 5118c2ecf20Sopenharmony_ci item_set_tag(':'); 5128c2ecf20Sopenharmony_ci item_set_data(menu); 5138c2ecf20Sopenharmony_ci } 5148c2ecf20Sopenharmony_ci break; 5158c2ecf20Sopenharmony_ci default: 5168c2ecf20Sopenharmony_ci if (prompt) { 5178c2ecf20Sopenharmony_ci child_count++; 5188c2ecf20Sopenharmony_ci item_make("---%*c%s", indent + 1, ' ', prompt); 5198c2ecf20Sopenharmony_ci item_set_tag(':'); 5208c2ecf20Sopenharmony_ci item_set_data(menu); 5218c2ecf20Sopenharmony_ci } 5228c2ecf20Sopenharmony_ci } 5238c2ecf20Sopenharmony_ci } else 5248c2ecf20Sopenharmony_ci doint = 0; 5258c2ecf20Sopenharmony_ci goto conf_childs; 5268c2ecf20Sopenharmony_ci } 5278c2ecf20Sopenharmony_ci 5288c2ecf20Sopenharmony_ci type = sym_get_type(sym); 5298c2ecf20Sopenharmony_ci if (sym_is_choice(sym)) { 5308c2ecf20Sopenharmony_ci struct symbol *def_sym = sym_get_choice_value(sym); 5318c2ecf20Sopenharmony_ci struct menu *def_menu = NULL; 5328c2ecf20Sopenharmony_ci 5338c2ecf20Sopenharmony_ci child_count++; 5348c2ecf20Sopenharmony_ci for (child = menu->list; child; child = child->next) { 5358c2ecf20Sopenharmony_ci if (menu_is_visible(child) && child->sym == def_sym) 5368c2ecf20Sopenharmony_ci def_menu = child; 5378c2ecf20Sopenharmony_ci } 5388c2ecf20Sopenharmony_ci 5398c2ecf20Sopenharmony_ci val = sym_get_tristate_value(sym); 5408c2ecf20Sopenharmony_ci if (sym_is_changeable(sym)) { 5418c2ecf20Sopenharmony_ci switch (type) { 5428c2ecf20Sopenharmony_ci case S_BOOLEAN: 5438c2ecf20Sopenharmony_ci item_make("[%c]", val == no ? ' ' : '*'); 5448c2ecf20Sopenharmony_ci break; 5458c2ecf20Sopenharmony_ci case S_TRISTATE: 5468c2ecf20Sopenharmony_ci switch (val) { 5478c2ecf20Sopenharmony_ci case yes: ch = '*'; break; 5488c2ecf20Sopenharmony_ci case mod: ch = 'M'; break; 5498c2ecf20Sopenharmony_ci default: ch = ' '; break; 5508c2ecf20Sopenharmony_ci } 5518c2ecf20Sopenharmony_ci item_make("<%c>", ch); 5528c2ecf20Sopenharmony_ci break; 5538c2ecf20Sopenharmony_ci } 5548c2ecf20Sopenharmony_ci item_set_tag('t'); 5558c2ecf20Sopenharmony_ci item_set_data(menu); 5568c2ecf20Sopenharmony_ci } else { 5578c2ecf20Sopenharmony_ci item_make(" "); 5588c2ecf20Sopenharmony_ci item_set_tag(def_menu ? 't' : ':'); 5598c2ecf20Sopenharmony_ci item_set_data(menu); 5608c2ecf20Sopenharmony_ci } 5618c2ecf20Sopenharmony_ci 5628c2ecf20Sopenharmony_ci item_add_str("%*c%s", indent + 1, ' ', menu_get_prompt(menu)); 5638c2ecf20Sopenharmony_ci if (val == yes) { 5648c2ecf20Sopenharmony_ci if (def_menu) { 5658c2ecf20Sopenharmony_ci item_add_str(" (%s)", menu_get_prompt(def_menu)); 5668c2ecf20Sopenharmony_ci item_add_str(" --->"); 5678c2ecf20Sopenharmony_ci if (def_menu->list) { 5688c2ecf20Sopenharmony_ci indent += 2; 5698c2ecf20Sopenharmony_ci build_conf(def_menu); 5708c2ecf20Sopenharmony_ci indent -= 2; 5718c2ecf20Sopenharmony_ci } 5728c2ecf20Sopenharmony_ci } 5738c2ecf20Sopenharmony_ci return; 5748c2ecf20Sopenharmony_ci } 5758c2ecf20Sopenharmony_ci } else { 5768c2ecf20Sopenharmony_ci if (menu == current_menu) { 5778c2ecf20Sopenharmony_ci item_make("---%*c%s", indent + 1, ' ', menu_get_prompt(menu)); 5788c2ecf20Sopenharmony_ci item_set_tag(':'); 5798c2ecf20Sopenharmony_ci item_set_data(menu); 5808c2ecf20Sopenharmony_ci goto conf_childs; 5818c2ecf20Sopenharmony_ci } 5828c2ecf20Sopenharmony_ci child_count++; 5838c2ecf20Sopenharmony_ci val = sym_get_tristate_value(sym); 5848c2ecf20Sopenharmony_ci if (sym_is_choice_value(sym) && val == yes) { 5858c2ecf20Sopenharmony_ci item_make(" "); 5868c2ecf20Sopenharmony_ci item_set_tag(':'); 5878c2ecf20Sopenharmony_ci item_set_data(menu); 5888c2ecf20Sopenharmony_ci } else { 5898c2ecf20Sopenharmony_ci switch (type) { 5908c2ecf20Sopenharmony_ci case S_BOOLEAN: 5918c2ecf20Sopenharmony_ci if (sym_is_changeable(sym)) 5928c2ecf20Sopenharmony_ci item_make("[%c]", val == no ? ' ' : '*'); 5938c2ecf20Sopenharmony_ci else 5948c2ecf20Sopenharmony_ci item_make("-%c-", val == no ? ' ' : '*'); 5958c2ecf20Sopenharmony_ci item_set_tag('t'); 5968c2ecf20Sopenharmony_ci item_set_data(menu); 5978c2ecf20Sopenharmony_ci break; 5988c2ecf20Sopenharmony_ci case S_TRISTATE: 5998c2ecf20Sopenharmony_ci switch (val) { 6008c2ecf20Sopenharmony_ci case yes: ch = '*'; break; 6018c2ecf20Sopenharmony_ci case mod: ch = 'M'; break; 6028c2ecf20Sopenharmony_ci default: ch = ' '; break; 6038c2ecf20Sopenharmony_ci } 6048c2ecf20Sopenharmony_ci if (sym_is_changeable(sym)) { 6058c2ecf20Sopenharmony_ci if (sym->rev_dep.tri == mod) 6068c2ecf20Sopenharmony_ci item_make("{%c}", ch); 6078c2ecf20Sopenharmony_ci else 6088c2ecf20Sopenharmony_ci item_make("<%c>", ch); 6098c2ecf20Sopenharmony_ci } else 6108c2ecf20Sopenharmony_ci item_make("-%c-", ch); 6118c2ecf20Sopenharmony_ci item_set_tag('t'); 6128c2ecf20Sopenharmony_ci item_set_data(menu); 6138c2ecf20Sopenharmony_ci break; 6148c2ecf20Sopenharmony_ci default: 6158c2ecf20Sopenharmony_ci tmp = 2 + strlen(sym_get_string_value(sym)); /* () = 2 */ 6168c2ecf20Sopenharmony_ci item_make("(%s)", sym_get_string_value(sym)); 6178c2ecf20Sopenharmony_ci tmp = indent - tmp + 4; 6188c2ecf20Sopenharmony_ci if (tmp < 0) 6198c2ecf20Sopenharmony_ci tmp = 0; 6208c2ecf20Sopenharmony_ci item_add_str("%*c%s%s", tmp, ' ', menu_get_prompt(menu), 6218c2ecf20Sopenharmony_ci (sym_has_value(sym) || !sym_is_changeable(sym)) ? 6228c2ecf20Sopenharmony_ci "" : " (NEW)"); 6238c2ecf20Sopenharmony_ci item_set_tag('s'); 6248c2ecf20Sopenharmony_ci item_set_data(menu); 6258c2ecf20Sopenharmony_ci goto conf_childs; 6268c2ecf20Sopenharmony_ci } 6278c2ecf20Sopenharmony_ci } 6288c2ecf20Sopenharmony_ci item_add_str("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu), 6298c2ecf20Sopenharmony_ci (sym_has_value(sym) || !sym_is_changeable(sym)) ? 6308c2ecf20Sopenharmony_ci "" : " (NEW)"); 6318c2ecf20Sopenharmony_ci if (menu->prompt->type == P_MENU) { 6328c2ecf20Sopenharmony_ci item_add_str(" %s", menu_is_empty(menu) ? "----" : "--->"); 6338c2ecf20Sopenharmony_ci return; 6348c2ecf20Sopenharmony_ci } 6358c2ecf20Sopenharmony_ci } 6368c2ecf20Sopenharmony_ci 6378c2ecf20Sopenharmony_ciconf_childs: 6388c2ecf20Sopenharmony_ci indent += doint; 6398c2ecf20Sopenharmony_ci for (child = menu->list; child; child = child->next) 6408c2ecf20Sopenharmony_ci build_conf(child); 6418c2ecf20Sopenharmony_ci indent -= doint; 6428c2ecf20Sopenharmony_ci} 6438c2ecf20Sopenharmony_ci 6448c2ecf20Sopenharmony_cistatic void conf(struct menu *menu, struct menu *active_menu) 6458c2ecf20Sopenharmony_ci{ 6468c2ecf20Sopenharmony_ci struct menu *submenu; 6478c2ecf20Sopenharmony_ci const char *prompt = menu_get_prompt(menu); 6488c2ecf20Sopenharmony_ci struct subtitle_part stpart; 6498c2ecf20Sopenharmony_ci struct symbol *sym; 6508c2ecf20Sopenharmony_ci int res; 6518c2ecf20Sopenharmony_ci int s_scroll = 0; 6528c2ecf20Sopenharmony_ci 6538c2ecf20Sopenharmony_ci if (menu != &rootmenu) 6548c2ecf20Sopenharmony_ci stpart.text = menu_get_prompt(menu); 6558c2ecf20Sopenharmony_ci else 6568c2ecf20Sopenharmony_ci stpart.text = NULL; 6578c2ecf20Sopenharmony_ci list_add_tail(&stpart.entries, &trail); 6588c2ecf20Sopenharmony_ci 6598c2ecf20Sopenharmony_ci while (1) { 6608c2ecf20Sopenharmony_ci item_reset(); 6618c2ecf20Sopenharmony_ci current_menu = menu; 6628c2ecf20Sopenharmony_ci build_conf(menu); 6638c2ecf20Sopenharmony_ci if (!child_count) 6648c2ecf20Sopenharmony_ci break; 6658c2ecf20Sopenharmony_ci set_subtitle(); 6668c2ecf20Sopenharmony_ci dialog_clear(); 6678c2ecf20Sopenharmony_ci res = dialog_menu(prompt ? prompt : "Main Menu", 6688c2ecf20Sopenharmony_ci menu_instructions, 6698c2ecf20Sopenharmony_ci active_menu, &s_scroll); 6708c2ecf20Sopenharmony_ci if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL) 6718c2ecf20Sopenharmony_ci break; 6728c2ecf20Sopenharmony_ci if (item_count() != 0) { 6738c2ecf20Sopenharmony_ci if (!item_activate_selected()) 6748c2ecf20Sopenharmony_ci continue; 6758c2ecf20Sopenharmony_ci if (!item_tag()) 6768c2ecf20Sopenharmony_ci continue; 6778c2ecf20Sopenharmony_ci } 6788c2ecf20Sopenharmony_ci submenu = item_data(); 6798c2ecf20Sopenharmony_ci active_menu = item_data(); 6808c2ecf20Sopenharmony_ci if (submenu) 6818c2ecf20Sopenharmony_ci sym = submenu->sym; 6828c2ecf20Sopenharmony_ci else 6838c2ecf20Sopenharmony_ci sym = NULL; 6848c2ecf20Sopenharmony_ci 6858c2ecf20Sopenharmony_ci switch (res) { 6868c2ecf20Sopenharmony_ci case 0: 6878c2ecf20Sopenharmony_ci switch (item_tag()) { 6888c2ecf20Sopenharmony_ci case 'm': 6898c2ecf20Sopenharmony_ci if (single_menu_mode) 6908c2ecf20Sopenharmony_ci submenu->data = (void *) (long) !submenu->data; 6918c2ecf20Sopenharmony_ci else 6928c2ecf20Sopenharmony_ci conf(submenu, NULL); 6938c2ecf20Sopenharmony_ci break; 6948c2ecf20Sopenharmony_ci case 't': 6958c2ecf20Sopenharmony_ci if (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes) 6968c2ecf20Sopenharmony_ci conf_choice(submenu); 6978c2ecf20Sopenharmony_ci else if (submenu->prompt->type == P_MENU) 6988c2ecf20Sopenharmony_ci conf(submenu, NULL); 6998c2ecf20Sopenharmony_ci break; 7008c2ecf20Sopenharmony_ci case 's': 7018c2ecf20Sopenharmony_ci conf_string(submenu); 7028c2ecf20Sopenharmony_ci break; 7038c2ecf20Sopenharmony_ci } 7048c2ecf20Sopenharmony_ci break; 7058c2ecf20Sopenharmony_ci case 2: 7068c2ecf20Sopenharmony_ci if (sym) 7078c2ecf20Sopenharmony_ci show_help(submenu); 7088c2ecf20Sopenharmony_ci else { 7098c2ecf20Sopenharmony_ci reset_subtitle(); 7108c2ecf20Sopenharmony_ci show_helptext("README", mconf_readme); 7118c2ecf20Sopenharmony_ci } 7128c2ecf20Sopenharmony_ci break; 7138c2ecf20Sopenharmony_ci case 3: 7148c2ecf20Sopenharmony_ci reset_subtitle(); 7158c2ecf20Sopenharmony_ci conf_save(); 7168c2ecf20Sopenharmony_ci break; 7178c2ecf20Sopenharmony_ci case 4: 7188c2ecf20Sopenharmony_ci reset_subtitle(); 7198c2ecf20Sopenharmony_ci conf_load(); 7208c2ecf20Sopenharmony_ci break; 7218c2ecf20Sopenharmony_ci case 5: 7228c2ecf20Sopenharmony_ci if (item_is_tag('t')) { 7238c2ecf20Sopenharmony_ci if (sym_set_tristate_value(sym, yes)) 7248c2ecf20Sopenharmony_ci break; 7258c2ecf20Sopenharmony_ci if (sym_set_tristate_value(sym, mod)) 7268c2ecf20Sopenharmony_ci show_textbox(NULL, setmod_text, 6, 74); 7278c2ecf20Sopenharmony_ci } 7288c2ecf20Sopenharmony_ci break; 7298c2ecf20Sopenharmony_ci case 6: 7308c2ecf20Sopenharmony_ci if (item_is_tag('t')) 7318c2ecf20Sopenharmony_ci sym_set_tristate_value(sym, no); 7328c2ecf20Sopenharmony_ci break; 7338c2ecf20Sopenharmony_ci case 7: 7348c2ecf20Sopenharmony_ci if (item_is_tag('t')) 7358c2ecf20Sopenharmony_ci sym_set_tristate_value(sym, mod); 7368c2ecf20Sopenharmony_ci break; 7378c2ecf20Sopenharmony_ci case 8: 7388c2ecf20Sopenharmony_ci if (item_is_tag('t')) 7398c2ecf20Sopenharmony_ci sym_toggle_tristate_value(sym); 7408c2ecf20Sopenharmony_ci else if (item_is_tag('m')) 7418c2ecf20Sopenharmony_ci conf(submenu, NULL); 7428c2ecf20Sopenharmony_ci break; 7438c2ecf20Sopenharmony_ci case 9: 7448c2ecf20Sopenharmony_ci search_conf(); 7458c2ecf20Sopenharmony_ci break; 7468c2ecf20Sopenharmony_ci case 10: 7478c2ecf20Sopenharmony_ci show_all_options = !show_all_options; 7488c2ecf20Sopenharmony_ci break; 7498c2ecf20Sopenharmony_ci } 7508c2ecf20Sopenharmony_ci } 7518c2ecf20Sopenharmony_ci 7528c2ecf20Sopenharmony_ci list_del(trail.prev); 7538c2ecf20Sopenharmony_ci} 7548c2ecf20Sopenharmony_ci 7558c2ecf20Sopenharmony_cistatic int show_textbox_ext(const char *title, char *text, int r, int c, int 7568c2ecf20Sopenharmony_ci *keys, int *vscroll, int *hscroll, update_text_fn 7578c2ecf20Sopenharmony_ci update_text, void *data) 7588c2ecf20Sopenharmony_ci{ 7598c2ecf20Sopenharmony_ci dialog_clear(); 7608c2ecf20Sopenharmony_ci return dialog_textbox(title, text, r, c, keys, vscroll, hscroll, 7618c2ecf20Sopenharmony_ci update_text, data); 7628c2ecf20Sopenharmony_ci} 7638c2ecf20Sopenharmony_ci 7648c2ecf20Sopenharmony_cistatic void show_textbox(const char *title, const char *text, int r, int c) 7658c2ecf20Sopenharmony_ci{ 7668c2ecf20Sopenharmony_ci show_textbox_ext(title, (char *) text, r, c, (int []) {0}, NULL, NULL, 7678c2ecf20Sopenharmony_ci NULL, NULL); 7688c2ecf20Sopenharmony_ci} 7698c2ecf20Sopenharmony_ci 7708c2ecf20Sopenharmony_cistatic void show_helptext(const char *title, const char *text) 7718c2ecf20Sopenharmony_ci{ 7728c2ecf20Sopenharmony_ci show_textbox(title, text, 0, 0); 7738c2ecf20Sopenharmony_ci} 7748c2ecf20Sopenharmony_ci 7758c2ecf20Sopenharmony_cistatic void conf_message_callback(const char *s) 7768c2ecf20Sopenharmony_ci{ 7778c2ecf20Sopenharmony_ci if (save_and_exit) { 7788c2ecf20Sopenharmony_ci if (!silent) 7798c2ecf20Sopenharmony_ci printf("%s", s); 7808c2ecf20Sopenharmony_ci } else { 7818c2ecf20Sopenharmony_ci show_textbox(NULL, s, 6, 60); 7828c2ecf20Sopenharmony_ci } 7838c2ecf20Sopenharmony_ci} 7848c2ecf20Sopenharmony_ci 7858c2ecf20Sopenharmony_cistatic void show_help(struct menu *menu) 7868c2ecf20Sopenharmony_ci{ 7878c2ecf20Sopenharmony_ci struct gstr help = str_new(); 7888c2ecf20Sopenharmony_ci 7898c2ecf20Sopenharmony_ci help.max_width = getmaxx(stdscr) - 10; 7908c2ecf20Sopenharmony_ci menu_get_ext_help(menu, &help); 7918c2ecf20Sopenharmony_ci 7928c2ecf20Sopenharmony_ci show_helptext(menu_get_prompt(menu), str_get(&help)); 7938c2ecf20Sopenharmony_ci str_free(&help); 7948c2ecf20Sopenharmony_ci} 7958c2ecf20Sopenharmony_ci 7968c2ecf20Sopenharmony_cistatic void conf_choice(struct menu *menu) 7978c2ecf20Sopenharmony_ci{ 7988c2ecf20Sopenharmony_ci const char *prompt = menu_get_prompt(menu); 7998c2ecf20Sopenharmony_ci struct menu *child; 8008c2ecf20Sopenharmony_ci struct symbol *active; 8018c2ecf20Sopenharmony_ci 8028c2ecf20Sopenharmony_ci active = sym_get_choice_value(menu->sym); 8038c2ecf20Sopenharmony_ci while (1) { 8048c2ecf20Sopenharmony_ci int res; 8058c2ecf20Sopenharmony_ci int selected; 8068c2ecf20Sopenharmony_ci item_reset(); 8078c2ecf20Sopenharmony_ci 8088c2ecf20Sopenharmony_ci current_menu = menu; 8098c2ecf20Sopenharmony_ci for (child = menu->list; child; child = child->next) { 8108c2ecf20Sopenharmony_ci if (!menu_is_visible(child)) 8118c2ecf20Sopenharmony_ci continue; 8128c2ecf20Sopenharmony_ci if (child->sym) 8138c2ecf20Sopenharmony_ci item_make("%s", menu_get_prompt(child)); 8148c2ecf20Sopenharmony_ci else { 8158c2ecf20Sopenharmony_ci item_make("*** %s ***", menu_get_prompt(child)); 8168c2ecf20Sopenharmony_ci item_set_tag(':'); 8178c2ecf20Sopenharmony_ci } 8188c2ecf20Sopenharmony_ci item_set_data(child); 8198c2ecf20Sopenharmony_ci if (child->sym == active) 8208c2ecf20Sopenharmony_ci item_set_selected(1); 8218c2ecf20Sopenharmony_ci if (child->sym == sym_get_choice_value(menu->sym)) 8228c2ecf20Sopenharmony_ci item_set_tag('X'); 8238c2ecf20Sopenharmony_ci } 8248c2ecf20Sopenharmony_ci dialog_clear(); 8258c2ecf20Sopenharmony_ci res = dialog_checklist(prompt ? prompt : "Main Menu", 8268c2ecf20Sopenharmony_ci radiolist_instructions, 8278c2ecf20Sopenharmony_ci MENUBOX_HEIGTH_MIN, 8288c2ecf20Sopenharmony_ci MENUBOX_WIDTH_MIN, 8298c2ecf20Sopenharmony_ci CHECKLIST_HEIGTH_MIN); 8308c2ecf20Sopenharmony_ci selected = item_activate_selected(); 8318c2ecf20Sopenharmony_ci switch (res) { 8328c2ecf20Sopenharmony_ci case 0: 8338c2ecf20Sopenharmony_ci if (selected) { 8348c2ecf20Sopenharmony_ci child = item_data(); 8358c2ecf20Sopenharmony_ci if (!child->sym) 8368c2ecf20Sopenharmony_ci break; 8378c2ecf20Sopenharmony_ci 8388c2ecf20Sopenharmony_ci sym_set_tristate_value(child->sym, yes); 8398c2ecf20Sopenharmony_ci } 8408c2ecf20Sopenharmony_ci return; 8418c2ecf20Sopenharmony_ci case 1: 8428c2ecf20Sopenharmony_ci if (selected) { 8438c2ecf20Sopenharmony_ci child = item_data(); 8448c2ecf20Sopenharmony_ci show_help(child); 8458c2ecf20Sopenharmony_ci active = child->sym; 8468c2ecf20Sopenharmony_ci } else 8478c2ecf20Sopenharmony_ci show_help(menu); 8488c2ecf20Sopenharmony_ci break; 8498c2ecf20Sopenharmony_ci case KEY_ESC: 8508c2ecf20Sopenharmony_ci return; 8518c2ecf20Sopenharmony_ci case -ERRDISPLAYTOOSMALL: 8528c2ecf20Sopenharmony_ci return; 8538c2ecf20Sopenharmony_ci } 8548c2ecf20Sopenharmony_ci } 8558c2ecf20Sopenharmony_ci} 8568c2ecf20Sopenharmony_ci 8578c2ecf20Sopenharmony_cistatic void conf_string(struct menu *menu) 8588c2ecf20Sopenharmony_ci{ 8598c2ecf20Sopenharmony_ci const char *prompt = menu_get_prompt(menu); 8608c2ecf20Sopenharmony_ci 8618c2ecf20Sopenharmony_ci while (1) { 8628c2ecf20Sopenharmony_ci int res; 8638c2ecf20Sopenharmony_ci const char *heading; 8648c2ecf20Sopenharmony_ci 8658c2ecf20Sopenharmony_ci switch (sym_get_type(menu->sym)) { 8668c2ecf20Sopenharmony_ci case S_INT: 8678c2ecf20Sopenharmony_ci heading = inputbox_instructions_int; 8688c2ecf20Sopenharmony_ci break; 8698c2ecf20Sopenharmony_ci case S_HEX: 8708c2ecf20Sopenharmony_ci heading = inputbox_instructions_hex; 8718c2ecf20Sopenharmony_ci break; 8728c2ecf20Sopenharmony_ci case S_STRING: 8738c2ecf20Sopenharmony_ci heading = inputbox_instructions_string; 8748c2ecf20Sopenharmony_ci break; 8758c2ecf20Sopenharmony_ci default: 8768c2ecf20Sopenharmony_ci heading = "Internal mconf error!"; 8778c2ecf20Sopenharmony_ci } 8788c2ecf20Sopenharmony_ci dialog_clear(); 8798c2ecf20Sopenharmony_ci res = dialog_inputbox(prompt ? prompt : "Main Menu", 8808c2ecf20Sopenharmony_ci heading, 10, 75, 8818c2ecf20Sopenharmony_ci sym_get_string_value(menu->sym)); 8828c2ecf20Sopenharmony_ci switch (res) { 8838c2ecf20Sopenharmony_ci case 0: 8848c2ecf20Sopenharmony_ci if (sym_set_string_value(menu->sym, dialog_input_result)) 8858c2ecf20Sopenharmony_ci return; 8868c2ecf20Sopenharmony_ci show_textbox(NULL, "You have made an invalid entry.", 5, 43); 8878c2ecf20Sopenharmony_ci break; 8888c2ecf20Sopenharmony_ci case 1: 8898c2ecf20Sopenharmony_ci show_help(menu); 8908c2ecf20Sopenharmony_ci break; 8918c2ecf20Sopenharmony_ci case KEY_ESC: 8928c2ecf20Sopenharmony_ci return; 8938c2ecf20Sopenharmony_ci } 8948c2ecf20Sopenharmony_ci } 8958c2ecf20Sopenharmony_ci} 8968c2ecf20Sopenharmony_ci 8978c2ecf20Sopenharmony_cistatic void conf_load(void) 8988c2ecf20Sopenharmony_ci{ 8998c2ecf20Sopenharmony_ci 9008c2ecf20Sopenharmony_ci while (1) { 9018c2ecf20Sopenharmony_ci int res; 9028c2ecf20Sopenharmony_ci dialog_clear(); 9038c2ecf20Sopenharmony_ci res = dialog_inputbox(NULL, load_config_text, 9048c2ecf20Sopenharmony_ci 11, 55, filename); 9058c2ecf20Sopenharmony_ci switch(res) { 9068c2ecf20Sopenharmony_ci case 0: 9078c2ecf20Sopenharmony_ci if (!dialog_input_result[0]) 9088c2ecf20Sopenharmony_ci return; 9098c2ecf20Sopenharmony_ci if (!conf_read(dialog_input_result)) { 9108c2ecf20Sopenharmony_ci set_config_filename(dialog_input_result); 9118c2ecf20Sopenharmony_ci sym_set_change_count(1); 9128c2ecf20Sopenharmony_ci return; 9138c2ecf20Sopenharmony_ci } 9148c2ecf20Sopenharmony_ci show_textbox(NULL, "File does not exist!", 5, 38); 9158c2ecf20Sopenharmony_ci break; 9168c2ecf20Sopenharmony_ci case 1: 9178c2ecf20Sopenharmony_ci show_helptext("Load Alternate Configuration", load_config_help); 9188c2ecf20Sopenharmony_ci break; 9198c2ecf20Sopenharmony_ci case KEY_ESC: 9208c2ecf20Sopenharmony_ci return; 9218c2ecf20Sopenharmony_ci } 9228c2ecf20Sopenharmony_ci } 9238c2ecf20Sopenharmony_ci} 9248c2ecf20Sopenharmony_ci 9258c2ecf20Sopenharmony_cistatic void conf_save(void) 9268c2ecf20Sopenharmony_ci{ 9278c2ecf20Sopenharmony_ci while (1) { 9288c2ecf20Sopenharmony_ci int res; 9298c2ecf20Sopenharmony_ci dialog_clear(); 9308c2ecf20Sopenharmony_ci res = dialog_inputbox(NULL, save_config_text, 9318c2ecf20Sopenharmony_ci 11, 55, filename); 9328c2ecf20Sopenharmony_ci switch(res) { 9338c2ecf20Sopenharmony_ci case 0: 9348c2ecf20Sopenharmony_ci if (!dialog_input_result[0]) 9358c2ecf20Sopenharmony_ci return; 9368c2ecf20Sopenharmony_ci if (!conf_write(dialog_input_result)) { 9378c2ecf20Sopenharmony_ci set_config_filename(dialog_input_result); 9388c2ecf20Sopenharmony_ci return; 9398c2ecf20Sopenharmony_ci } 9408c2ecf20Sopenharmony_ci show_textbox(NULL, "Can't create file!", 5, 60); 9418c2ecf20Sopenharmony_ci break; 9428c2ecf20Sopenharmony_ci case 1: 9438c2ecf20Sopenharmony_ci show_helptext("Save Alternate Configuration", save_config_help); 9448c2ecf20Sopenharmony_ci break; 9458c2ecf20Sopenharmony_ci case KEY_ESC: 9468c2ecf20Sopenharmony_ci return; 9478c2ecf20Sopenharmony_ci } 9488c2ecf20Sopenharmony_ci } 9498c2ecf20Sopenharmony_ci} 9508c2ecf20Sopenharmony_ci 9518c2ecf20Sopenharmony_cistatic int handle_exit(void) 9528c2ecf20Sopenharmony_ci{ 9538c2ecf20Sopenharmony_ci int res; 9548c2ecf20Sopenharmony_ci 9558c2ecf20Sopenharmony_ci save_and_exit = 1; 9568c2ecf20Sopenharmony_ci reset_subtitle(); 9578c2ecf20Sopenharmony_ci dialog_clear(); 9588c2ecf20Sopenharmony_ci if (conf_get_changed()) 9598c2ecf20Sopenharmony_ci res = dialog_yesno(NULL, 9608c2ecf20Sopenharmony_ci "Do you wish to save your new configuration?\n" 9618c2ecf20Sopenharmony_ci "(Press <ESC><ESC> to continue kernel configuration.)", 9628c2ecf20Sopenharmony_ci 6, 60); 9638c2ecf20Sopenharmony_ci else 9648c2ecf20Sopenharmony_ci res = -1; 9658c2ecf20Sopenharmony_ci 9668c2ecf20Sopenharmony_ci end_dialog(saved_x, saved_y); 9678c2ecf20Sopenharmony_ci 9688c2ecf20Sopenharmony_ci switch (res) { 9698c2ecf20Sopenharmony_ci case 0: 9708c2ecf20Sopenharmony_ci if (conf_write(filename)) { 9718c2ecf20Sopenharmony_ci fprintf(stderr, "\n\n" 9728c2ecf20Sopenharmony_ci "Error while writing of the configuration.\n" 9738c2ecf20Sopenharmony_ci "Your configuration changes were NOT saved." 9748c2ecf20Sopenharmony_ci "\n\n"); 9758c2ecf20Sopenharmony_ci return 1; 9768c2ecf20Sopenharmony_ci } 9778c2ecf20Sopenharmony_ci conf_write_autoconf(0); 9788c2ecf20Sopenharmony_ci /* fall through */ 9798c2ecf20Sopenharmony_ci case -1: 9808c2ecf20Sopenharmony_ci if (!silent) 9818c2ecf20Sopenharmony_ci printf("\n\n" 9828c2ecf20Sopenharmony_ci "*** End of the configuration.\n" 9838c2ecf20Sopenharmony_ci "*** Execute 'make' to start the build or try 'make help'." 9848c2ecf20Sopenharmony_ci "\n\n"); 9858c2ecf20Sopenharmony_ci res = 0; 9868c2ecf20Sopenharmony_ci break; 9878c2ecf20Sopenharmony_ci default: 9888c2ecf20Sopenharmony_ci if (!silent) 9898c2ecf20Sopenharmony_ci fprintf(stderr, "\n\n" 9908c2ecf20Sopenharmony_ci "Your configuration changes were NOT saved." 9918c2ecf20Sopenharmony_ci "\n\n"); 9928c2ecf20Sopenharmony_ci if (res != KEY_ESC) 9938c2ecf20Sopenharmony_ci res = 0; 9948c2ecf20Sopenharmony_ci } 9958c2ecf20Sopenharmony_ci 9968c2ecf20Sopenharmony_ci return res; 9978c2ecf20Sopenharmony_ci} 9988c2ecf20Sopenharmony_ci 9998c2ecf20Sopenharmony_cistatic void sig_handler(int signo) 10008c2ecf20Sopenharmony_ci{ 10018c2ecf20Sopenharmony_ci exit(handle_exit()); 10028c2ecf20Sopenharmony_ci} 10038c2ecf20Sopenharmony_ci 10048c2ecf20Sopenharmony_ciint main(int ac, char **av) 10058c2ecf20Sopenharmony_ci{ 10068c2ecf20Sopenharmony_ci char *mode; 10078c2ecf20Sopenharmony_ci int res; 10088c2ecf20Sopenharmony_ci 10098c2ecf20Sopenharmony_ci signal(SIGINT, sig_handler); 10108c2ecf20Sopenharmony_ci 10118c2ecf20Sopenharmony_ci if (ac > 1 && strcmp(av[1], "-s") == 0) { 10128c2ecf20Sopenharmony_ci silent = 1; 10138c2ecf20Sopenharmony_ci /* Silence conf_read() until the real callback is set up */ 10148c2ecf20Sopenharmony_ci conf_set_message_callback(NULL); 10158c2ecf20Sopenharmony_ci av++; 10168c2ecf20Sopenharmony_ci } 10178c2ecf20Sopenharmony_ci conf_parse(av[1]); 10188c2ecf20Sopenharmony_ci conf_read(NULL); 10198c2ecf20Sopenharmony_ci 10208c2ecf20Sopenharmony_ci mode = getenv("MENUCONFIG_MODE"); 10218c2ecf20Sopenharmony_ci if (mode) { 10228c2ecf20Sopenharmony_ci if (!strcasecmp(mode, "single_menu")) 10238c2ecf20Sopenharmony_ci single_menu_mode = 1; 10248c2ecf20Sopenharmony_ci } 10258c2ecf20Sopenharmony_ci 10268c2ecf20Sopenharmony_ci if (init_dialog(NULL)) { 10278c2ecf20Sopenharmony_ci fprintf(stderr, "Your display is too small to run Menuconfig!\n"); 10288c2ecf20Sopenharmony_ci fprintf(stderr, "It must be at least 19 lines by 80 columns.\n"); 10298c2ecf20Sopenharmony_ci return 1; 10308c2ecf20Sopenharmony_ci } 10318c2ecf20Sopenharmony_ci 10328c2ecf20Sopenharmony_ci set_config_filename(conf_get_configname()); 10338c2ecf20Sopenharmony_ci conf_set_message_callback(conf_message_callback); 10348c2ecf20Sopenharmony_ci do { 10358c2ecf20Sopenharmony_ci conf(&rootmenu, NULL); 10368c2ecf20Sopenharmony_ci res = handle_exit(); 10378c2ecf20Sopenharmony_ci } while (res == KEY_ESC); 10388c2ecf20Sopenharmony_ci 10398c2ecf20Sopenharmony_ci return res; 10408c2ecf20Sopenharmony_ci} 1041