Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'kconfig' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild

Pull kconfig updates from Michal Marek:
- dependency solver fix for make defconfig
- randconfig fixes, one of which had to be reverted again
- more user-friendly sorting of search results
- hex and range keywords support longs
- fix for [mn]conf not to rely on particular behavior of the LINES and
COLS variables
- cleanup of magic constants in kconfig/lxdialog
- [mn]conf formatting fixes
- fix for scripts/config's help text in out-of-tree usage (under a
different name)

* 'kconfig' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild:
kconfig: allow "hex" and "range" to support longs
Revert "kconfig: fix randomising choice entries in presence of KCONFIG_ALLCONFIG"
kconfig: fix randomising choice entries in presence of KCONFIG_ALLCONFIG
kconfig: loop as long as we changed some symbols in randconfig
kconfig/[mn]conf: make it explicit in the search box that a regexp is possible
kconfig: sort found symbols by relevance
kconfig/conf: print the seed used to initialise the RNG for randconfig
kconfig/conf: accept a base-16 seed for randconfig
kconfig/conf: fix randconfig setting multiple symbols in a choice
scripts/config: replace hard-coded script name by a dynamic value
mconf/nconf: mark empty menus/menuconfigs different from non-empty ones
nconf: use function calls instead of ncurses' variables LINES and COLS
mconf: use function calls instead of ncurses' variables LINES and COLS
kconfig/lxdialog: handle newline characters in print_autowrap()
kconfig/lxdialog: Use new mininimum resize definitions in conf_choice()
kconfig/lxdialog: Add definitions for mininimum (re)size values
kconfig: Fix defconfig when one choice menu selects options that another choice menu depends on

+262 -100
+13
Documentation/kbuild/kconfig.txt
··· 174 174 175 175 /^hotplug 176 176 177 + When searching, symbols are sorted thus: 178 + - exact match first: an exact match is when the search matches 179 + the complete symbol name; 180 + - alphabetical order: when two symbols do not match exactly, 181 + they are sorted in alphabetical order (in the user's current 182 + locale). 183 + For example: ^ATH.K matches: 184 + ATH5K ATH9K ATH5K_AHB ATH5K_DEBUG [...] ATH6KL ATH6KL_DEBUG 185 + [...] ATH9K_AHB ATH9K_BTCOEX_SUPPORT ATH9K_COMMON [...] 186 + of which only ATH5K and ATH9K match exactly and so are sorted 187 + first (and in alphabetical order), then come all other symbols, 188 + sorted in alphabetical order. 189 + 177 190 ______________________________________________________________________ 178 191 User interface options for 'menuconfig' 179 192
+7 -5
scripts/config
··· 1 1 #!/bin/bash 2 2 # Manipulate options in a .config file from the command line 3 3 4 + myname=${0##*/} 5 + 4 6 # If no prefix forced, use the default CONFIG_ 5 7 CONFIG_="${CONFIG_-CONFIG_}" 6 8 ··· 10 8 cat >&2 <<EOL 11 9 Manipulate options in a .config file from the command line. 12 10 Usage: 13 - config options command ... 11 + $myname options command ... 14 12 commands: 15 13 --enable|-e option Enable option 16 14 --disable|-d option Disable option ··· 35 33 --file config-file .config file to change (default .config) 36 34 --keep-case|-k Keep next symbols' case (dont' upper-case it) 37 35 38 - config doesn't check the validity of the .config file. This is done at next 36 + $myname doesn't check the validity of the .config file. This is done at next 39 37 make time. 40 38 41 - By default, config will upper-case the given symbol. Use --keep-case to keep 39 + By default, $myname will upper-case the given symbol. Use --keep-case to keep 42 40 the case of all following symbols unchanged. 43 41 44 - config uses 'CONFIG_' as the default symbol prefix. Set the environment 45 - variable CONFIG_ to the prefix to use. Eg.: CONFIG_="FOO_" config ... 42 + $myname uses 'CONFIG_' as the default symbol prefix. Set the environment 43 + variable CONFIG_ to the prefix to use. Eg.: CONFIG_="FOO_" $myname ... 46 44 EOL 47 45 exit 1 48 46 }
+4 -2
scripts/kconfig/conf.c
··· 527 527 seed_env = getenv("KCONFIG_SEED"); 528 528 if( seed_env && *seed_env ) { 529 529 char *endp; 530 - int tmp = (int)strtol(seed_env, &endp, 10); 530 + int tmp = (int)strtol(seed_env, &endp, 0); 531 531 if (*endp == '\0') { 532 532 seed = tmp; 533 533 } 534 534 } 535 + fprintf( stderr, "KCONFIG_SEED=0x%X\n", seed ); 535 536 srand(seed); 536 537 break; 537 538 } ··· 654 653 conf_set_all_new_symbols(def_default); 655 654 break; 656 655 case randconfig: 657 - conf_set_all_new_symbols(def_random); 656 + /* Really nothing to do in this loop */ 657 + while (conf_set_all_new_symbols(def_random)) ; 658 658 break; 659 659 case defconfig: 660 660 conf_set_all_new_symbols(def_default);
+26 -7
scripts/kconfig/confdata.c
··· 1040 1040 conf_changed_callback = fn; 1041 1041 } 1042 1042 1043 - static void randomize_choice_values(struct symbol *csym) 1043 + static bool randomize_choice_values(struct symbol *csym) 1044 1044 { 1045 1045 struct property *prop; 1046 1046 struct symbol *sym; ··· 1053 1053 * In both cases stop. 1054 1054 */ 1055 1055 if (csym->curr.tri != yes) 1056 - return; 1056 + return false; 1057 1057 1058 1058 prop = sym_get_choice_prop(csym); 1059 1059 ··· 1077 1077 else { 1078 1078 sym->def[S_DEF_USER].tri = no; 1079 1079 } 1080 + sym->flags |= SYMBOL_DEF_USER; 1081 + /* clear VALID to get value calculated */ 1082 + sym->flags &= ~SYMBOL_VALID; 1080 1083 } 1081 1084 csym->flags |= SYMBOL_DEF_USER; 1082 1085 /* clear VALID to get value calculated */ 1083 1086 csym->flags &= ~(SYMBOL_VALID); 1087 + 1088 + return true; 1084 1089 } 1085 1090 1086 - static void set_all_choice_values(struct symbol *csym) 1091 + void set_all_choice_values(struct symbol *csym) 1087 1092 { 1088 1093 struct property *prop; 1089 1094 struct symbol *sym; ··· 1105 1100 } 1106 1101 csym->flags |= SYMBOL_DEF_USER; 1107 1102 /* clear VALID to get value calculated */ 1108 - csym->flags &= ~(SYMBOL_VALID); 1103 + csym->flags &= ~(SYMBOL_VALID | SYMBOL_NEED_SET_CHOICE_VALUES); 1109 1104 } 1110 1105 1111 - void conf_set_all_new_symbols(enum conf_def_mode mode) 1106 + bool conf_set_all_new_symbols(enum conf_def_mode mode) 1112 1107 { 1113 1108 struct symbol *sym, *csym; 1114 1109 int i, cnt, pby, pty, ptm; /* pby: probability of boolean = y ··· 1156 1151 exit( 1 ); 1157 1152 } 1158 1153 } 1154 + bool has_changed = false; 1159 1155 1160 1156 for_all_symbols(i, sym) { 1161 1157 if (sym_has_value(sym) || (sym->flags & SYMBOL_VALID)) ··· 1164 1158 switch (sym_get_type(sym)) { 1165 1159 case S_BOOLEAN: 1166 1160 case S_TRISTATE: 1161 + has_changed = true; 1167 1162 switch (mode) { 1168 1163 case def_yes: 1169 1164 sym->def[S_DEF_USER].tri = yes; ··· 1209 1202 * selected in a choice block and we set it to yes, 1210 1203 * and the rest to no. 1211 1204 */ 1205 + if (mode != def_random) { 1206 + for_all_symbols(i, csym) { 1207 + if ((sym_is_choice(csym) && !sym_has_value(csym)) || 1208 + sym_is_choice_value(csym)) 1209 + csym->flags |= SYMBOL_NEED_SET_CHOICE_VALUES; 1210 + } 1211 + } 1212 + 1212 1213 for_all_symbols(i, csym) { 1213 1214 if (sym_has_value(csym) || !sym_is_choice(csym)) 1214 1215 continue; 1215 1216 1216 1217 sym_calc_value(csym); 1217 1218 if (mode == def_random) 1218 - randomize_choice_values(csym); 1219 - else 1219 + has_changed = randomize_choice_values(csym); 1220 + else { 1220 1221 set_all_choice_values(csym); 1222 + has_changed = true; 1223 + } 1221 1224 } 1225 + 1226 + return has_changed; 1222 1227 }
+3
scripts/kconfig/expr.h
··· 106 106 #define SYMBOL_DEF3 0x40000 /* symbol.def[S_DEF_3] is valid */ 107 107 #define SYMBOL_DEF4 0x80000 /* symbol.def[S_DEF_4] is valid */ 108 108 109 + /* choice values need to be set before calculating this symbol value */ 110 + #define SYMBOL_NEED_SET_CHOICE_VALUES 0x100000 111 + 109 112 #define SYMBOL_MAXLENGTH 256 110 113 #define SYMBOL_HASHSIZE 9973 111 114
+2 -1
scripts/kconfig/lkc.h
··· 86 86 char *conf_get_default_confname(void); 87 87 void sym_set_change_count(int count); 88 88 void sym_add_change_count(int count); 89 - void conf_set_all_new_symbols(enum conf_def_mode mode); 89 + bool conf_set_all_new_symbols(enum conf_def_mode mode); 90 + void set_all_choice_values(struct symbol *csym); 90 91 91 92 struct conf_printer { 92 93 void (*print_symbol)(FILE *, struct symbol *, const char *, void *);
+1
scripts/kconfig/lkc_proto.h
··· 14 14 /* menu.c */ 15 15 P(rootmenu,struct menu,); 16 16 17 + P(menu_is_empty, bool, (struct menu *menu)); 17 18 P(menu_is_visible, bool, (struct menu *menu)); 18 19 P(menu_has_prompt, bool, (struct menu *menu)); 19 20 P(menu_get_prompt,const char *,(struct menu *menu));
+4 -4
scripts/kconfig/lxdialog/checklist.c
··· 132 132 } 133 133 134 134 do_resize: 135 - if (getmaxy(stdscr) < (height + 6)) 135 + if (getmaxy(stdscr) < (height + CHECKLIST_HEIGTH_MIN)) 136 136 return -ERRDISPLAYTOOSMALL; 137 - if (getmaxx(stdscr) < (width + 6)) 137 + if (getmaxx(stdscr) < (width + CHECKLIST_WIDTH_MIN)) 138 138 return -ERRDISPLAYTOOSMALL; 139 139 140 140 max_choice = MIN(list_height, item_count()); 141 141 142 142 /* center dialog box on screen */ 143 - x = (COLS - width) / 2; 144 - y = (LINES - height) / 2; 143 + x = (getmaxx(stdscr) - width) / 2; 144 + y = (getmaxy(stdscr) - height) / 2; 145 145 146 146 draw_shadow(stdscr, y, x, height, width); 147 147
+14
scripts/kconfig/lxdialog/dialog.h
··· 200 200 int on_key_esc(WINDOW *win); 201 201 int on_key_resize(void); 202 202 203 + /* minimum (re)size values */ 204 + #define CHECKLIST_HEIGTH_MIN 6 /* For dialog_checklist() */ 205 + #define CHECKLIST_WIDTH_MIN 6 206 + #define INPUTBOX_HEIGTH_MIN 2 /* For dialog_inputbox() */ 207 + #define INPUTBOX_WIDTH_MIN 2 208 + #define MENUBOX_HEIGTH_MIN 15 /* For dialog_menu() */ 209 + #define MENUBOX_WIDTH_MIN 65 210 + #define TEXTBOX_HEIGTH_MIN 8 /* For dialog_textbox() */ 211 + #define TEXTBOX_WIDTH_MIN 8 212 + #define YESNO_HEIGTH_MIN 4 /* For dialog_yesno() */ 213 + #define YESNO_WIDTH_MIN 4 214 + #define WINDOW_HEIGTH_MIN 19 /* For init_dialog() */ 215 + #define WINDOW_WIDTH_MIN 80 216 + 203 217 int init_dialog(const char *backtitle); 204 218 void set_dialog_backtitle(const char *backtitle); 205 219 void set_dialog_subtitles(struct subtitle_list *subtitles);
+4 -4
scripts/kconfig/lxdialog/inputbox.c
··· 56 56 strcpy(instr, init); 57 57 58 58 do_resize: 59 - if (getmaxy(stdscr) <= (height - 2)) 59 + if (getmaxy(stdscr) <= (height - INPUTBOX_HEIGTH_MIN)) 60 60 return -ERRDISPLAYTOOSMALL; 61 - if (getmaxx(stdscr) <= (width - 2)) 61 + if (getmaxx(stdscr) <= (width - INPUTBOX_WIDTH_MIN)) 62 62 return -ERRDISPLAYTOOSMALL; 63 63 64 64 /* center dialog box on screen */ 65 - x = (COLS - width) / 2; 66 - y = (LINES - height) / 2; 65 + x = (getmaxx(stdscr) - width) / 2; 66 + y = (getmaxy(stdscr) - height) / 2; 67 67 68 68 draw_shadow(stdscr, y, x, height, width); 69 69
+3 -3
scripts/kconfig/lxdialog/menubox.c
··· 193 193 do_resize: 194 194 height = getmaxy(stdscr); 195 195 width = getmaxx(stdscr); 196 - if (height < 15 || width < 65) 196 + if (height < MENUBOX_HEIGTH_MIN || width < MENUBOX_WIDTH_MIN) 197 197 return -ERRDISPLAYTOOSMALL; 198 198 199 199 height -= 4; ··· 203 203 max_choice = MIN(menu_height, item_count()); 204 204 205 205 /* center dialog box on screen */ 206 - x = (COLS - width) / 2; 207 - y = (LINES - height) / 2; 206 + x = (getmaxx(stdscr) - width) / 2; 207 + y = (getmaxy(stdscr) - height) / 2; 208 208 209 209 draw_shadow(stdscr, y, x, height, width); 210 210
+3 -3
scripts/kconfig/lxdialog/textbox.c
··· 80 80 81 81 do_resize: 82 82 getmaxyx(stdscr, height, width); 83 - if (height < 8 || width < 8) 83 + if (height < TEXTBOX_HEIGTH_MIN || width < TEXTBOX_WIDTH_MIN) 84 84 return -ERRDISPLAYTOOSMALL; 85 85 if (initial_height != 0) 86 86 height = initial_height; ··· 98 98 width = 0; 99 99 100 100 /* center dialog box on screen */ 101 - x = (COLS - width) / 2; 102 - y = (LINES - height) / 2; 101 + x = (getmaxx(stdscr) - width) / 2; 102 + y = (getmaxy(stdscr) - height) / 2; 103 103 104 104 draw_shadow(stdscr, y, x, height, width); 105 105
+27 -19
scripts/kconfig/lxdialog/util.c
··· 254 254 255 255 void dialog_clear(void) 256 256 { 257 - attr_clear(stdscr, LINES, COLS, dlg.screen.atr); 257 + int lines, columns; 258 + 259 + lines = getmaxy(stdscr); 260 + columns = getmaxx(stdscr); 261 + 262 + attr_clear(stdscr, lines, columns, dlg.screen.atr); 258 263 /* Display background title if it exists ... - SLH */ 259 264 if (dlg.backtitle != NULL) { 260 265 int i, len = 0, skip = 0; ··· 274 269 } 275 270 276 271 wmove(stdscr, 1, 1); 277 - if (len > COLS - 2) { 272 + if (len > columns - 2) { 278 273 const char *ellipsis = "[...] "; 279 274 waddstr(stdscr, ellipsis); 280 - skip = len - (COLS - 2 - strlen(ellipsis)); 275 + skip = len - (columns - 2 - strlen(ellipsis)); 281 276 } 282 277 283 278 for (pos = dlg.subtitles; pos != NULL; pos = pos->next) { ··· 303 298 skip--; 304 299 } 305 300 306 - for (i = len + 1; i < COLS - 1; i++) 301 + for (i = len + 1; i < columns - 1; i++) 307 302 waddch(stdscr, ACS_HLINE); 308 303 } 309 304 wnoutrefresh(stdscr); ··· 322 317 getyx(stdscr, saved_y, saved_x); 323 318 324 319 getmaxyx(stdscr, height, width); 325 - if (height < 19 || width < 80) { 320 + if (height < WINDOW_HEIGTH_MIN || width < WINDOW_WIDTH_MIN) { 326 321 endwin(); 327 322 return -ERRDISPLAYTOOSMALL; 328 323 } ··· 376 371 /* 377 372 * Print a string of text in a window, automatically wrap around to the 378 373 * next line if the string is too long to fit on one line. Newline 379 - * characters '\n' are replaced by spaces. We start on a new line 374 + * characters '\n' are propperly processed. We start on a new line 380 375 * if there is no room for at least 4 nonblanks following a double-space. 381 376 */ 382 377 void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x) 383 378 { 384 379 int newl, cur_x, cur_y; 385 - int i, prompt_len, room, wlen; 386 - char tempstr[MAX_LEN + 1], *word, *sp, *sp2; 380 + int prompt_len, room, wlen; 381 + char tempstr[MAX_LEN + 1], *word, *sp, *sp2, *newline_separator = 0; 387 382 388 383 strcpy(tempstr, prompt); 389 384 390 385 prompt_len = strlen(tempstr); 391 - 392 - /* 393 - * Remove newlines 394 - */ 395 - for (i = 0; i < prompt_len; i++) { 396 - if (tempstr[i] == '\n') 397 - tempstr[i] = ' '; 398 - } 399 386 400 387 if (prompt_len <= width - x * 2) { /* If prompt is short */ 401 388 wmove(win, y, (width - prompt_len) / 2); ··· 398 401 newl = 1; 399 402 word = tempstr; 400 403 while (word && *word) { 401 - sp = strchr(word, ' '); 404 + sp = strpbrk(word, "\n "); 405 + if (sp && *sp == '\n') 406 + newline_separator = sp; 407 + 402 408 if (sp) 403 409 *sp++ = 0; 404 410 ··· 413 413 if (wlen > room || 414 414 (newl && wlen < 4 && sp 415 415 && wlen + 1 + strlen(sp) > room 416 - && (!(sp2 = strchr(sp, ' ')) 416 + && (!(sp2 = strpbrk(sp, "\n ")) 417 417 || wlen + 1 + (sp2 - sp) > room))) { 418 418 cur_y++; 419 419 cur_x = x; ··· 421 421 wmove(win, cur_y, cur_x); 422 422 waddstr(win, word); 423 423 getyx(win, cur_y, cur_x); 424 - cur_x++; 424 + 425 + /* Move to the next line if the word separator was a newline */ 426 + if (newline_separator) { 427 + cur_y++; 428 + cur_x = x; 429 + newline_separator = 0; 430 + } else 431 + cur_x++; 432 + 425 433 if (sp && *sp == ' ') { 426 434 cur_x++; /* double space */ 427 435 while (*++sp == ' ') ;
+4 -4
scripts/kconfig/lxdialog/yesno.c
··· 45 45 WINDOW *dialog; 46 46 47 47 do_resize: 48 - if (getmaxy(stdscr) < (height + 4)) 48 + if (getmaxy(stdscr) < (height + YESNO_HEIGTH_MIN)) 49 49 return -ERRDISPLAYTOOSMALL; 50 - if (getmaxx(stdscr) < (width + 4)) 50 + if (getmaxx(stdscr) < (width + YESNO_WIDTH_MIN)) 51 51 return -ERRDISPLAYTOOSMALL; 52 52 53 53 /* center dialog box on screen */ 54 - x = (COLS - width) / 2; 55 - y = (LINES - height) / 2; 54 + x = (getmaxx(stdscr) - width) / 2; 55 + y = (getmaxy(stdscr) - height) / 2; 56 56 57 57 draw_shadow(stdscr, y, x, height, width); 58 58
+12 -9
scripts/kconfig/mconf.c
··· 48 48 "----------\n" 49 49 "o Use the Up/Down arrow keys (cursor keys) to highlight the item\n" 50 50 " you wish to change or submenu wish to select and press <Enter>.\n" 51 - " Submenus are designated by \"--->\".\n" 51 + " Submenus are designated by \"--->\", empty ones by \"----\".\n" 52 52 "\n" 53 53 " Shortcut: Press the option's highlighted letter (hotkey).\n" 54 54 " Pressing a hotkey more than once will sequence\n" ··· 176 176 "\n"), 177 177 menu_instructions[] = N_( 178 178 "Arrow keys navigate the menu. " 179 - "<Enter> selects submenus --->. " 179 + "<Enter> selects submenus ---> (or empty submenus ----). " 180 180 "Highlighted letters are hotkeys. " 181 181 "Pressing <Y> includes, <N> excludes, <M> modularizes features. " 182 182 "Press <Esc><Esc> to exit, <?> for Help, </> for Search. " ··· 401 401 struct subtitle_part stpart; 402 402 403 403 title = str_new(); 404 - str_printf( &title, _("Enter %s (sub)string to search for " 404 + str_printf( &title, _("Enter %s (sub)string or regexp to search for " 405 405 "(with or without \"%s\")"), CONFIG_, CONFIG_); 406 406 407 407 again: ··· 498 498 menu->data ? "-->" : "++>", 499 499 indent + 1, ' ', prompt); 500 500 } else 501 - item_make(" %*c%s --->", indent + 1, ' ', prompt); 502 - 501 + item_make(" %*c%s %s", 502 + indent + 1, ' ', prompt, 503 + menu_is_empty(menu) ? "----" : "--->"); 503 504 item_set_tag('m'); 504 505 item_set_data(menu); 505 506 if (single_menu_mode && menu->data) ··· 631 630 (sym_has_value(sym) || !sym_is_changable(sym)) ? 632 631 "" : _(" (NEW)")); 633 632 if (menu->prompt->type == P_MENU) { 634 - item_add_str(" --->"); 633 + item_add_str(" %s", menu_is_empty(menu) ? "----" : "--->"); 635 634 return; 636 635 } 637 636 } ··· 827 826 dialog_clear(); 828 827 res = dialog_checklist(prompt ? _(prompt) : _("Main Menu"), 829 828 _(radiolist_instructions), 830 - 15, 70, 6); 829 + MENUBOX_HEIGTH_MIN, 830 + MENUBOX_WIDTH_MIN, 831 + CHECKLIST_HEIGTH_MIN); 831 832 selected = item_activate_selected(); 832 833 switch (res) { 833 834 case 0: ··· 960 957 dialog_clear(); 961 958 if (conf_get_changed()) 962 959 res = dialog_yesno(NULL, 963 - _("Do you wish to save your new configuration ?\n" 964 - "<ESC><ESC> to continue."), 960 + _("Do you wish to save your new configuration?\n" 961 + "(Press <ESC><ESC> to continue kernel configuration.)"), 965 962 6, 60); 966 963 else 967 964 res = -1;
+16
scripts/kconfig/menu.c
··· 443 443 return true; 444 444 } 445 445 446 + /* 447 + * Determine if a menu is empty. 448 + * A menu is considered empty if it contains no or only 449 + * invisible entries. 450 + */ 451 + bool menu_is_empty(struct menu *menu) 452 + { 453 + struct menu *child; 454 + 455 + for (child = menu->list; child; child = child->next) { 456 + if (menu_is_visible(child)) 457 + return(false); 458 + } 459 + return(true); 460 + } 461 + 446 462 bool menu_is_visible(struct menu *menu) 447 463 { 448 464 struct menu *child;
+23 -16
scripts/kconfig/nconf.c
··· 45 45 "<n> to remove it. You may press the <Space> key to cycle through the\n" 46 46 "available options.\n" 47 47 "\n" 48 - "A trailing \"--->\" designates a submenu.\n" 49 - "\n" 48 + "A trailing \"--->\" designates a submenu, a trailing \"----\" an\n" 49 + "empty submenu.\n" 50 50 "\n" 51 51 "Menu navigation keys\n" 52 52 "----------------------------------------------------------------------\n" ··· 131 131 "\n"), 132 132 menu_no_f_instructions[] = N_( 133 133 "Legend: [*] built-in [ ] excluded <M> module < > module capable.\n" 134 - "Submenus are designated by a trailing \"--->\".\n" 134 + "Submenus are designated by a trailing \"--->\", empty ones by \"----\".\n" 135 135 "\n" 136 136 "Use the following keys to navigate the menus:\n" 137 137 "Move up or down with <Up> and <Down>.\n" ··· 148 148 "For help related to the current menu entry press <?> or <h>.\n"), 149 149 menu_instructions[] = N_( 150 150 "Legend: [*] built-in [ ] excluded <M> module < > module capable.\n" 151 - "Submenus are designated by a trailing \"--->\".\n" 151 + "Submenus are designated by a trailing \"--->\", empty ones by \"----\".\n" 152 152 "\n" 153 153 "Use the following keys to navigate the menus:\n" 154 154 "Move up or down with <Up> or <Down>.\n" ··· 365 365 int i; 366 366 int offset = 1; 367 367 const int skip = 1; 368 + int lines = getmaxy(stdscr); 368 369 369 370 for (i = 0; i < function_keys_num; i++) { 370 371 (void) wattrset(main_window, attributes[FUNCTION_HIGHLIGHT]); 371 - mvwprintw(main_window, LINES-3, offset, 372 + mvwprintw(main_window, lines-3, offset, 372 373 "%s", 373 374 function_keys[i].key_str); 374 375 (void) wattrset(main_window, attributes[FUNCTION_TEXT]); 375 376 offset += strlen(function_keys[i].key_str); 376 - mvwprintw(main_window, LINES-3, 377 + mvwprintw(main_window, lines-3, 377 378 offset, "%s", 378 379 function_keys[i].func); 379 380 offset += strlen(function_keys[i].func) + skip; ··· 695 694 int dres; 696 695 697 696 title = str_new(); 698 - str_printf( &title, _("Enter %s (sub)string to search for " 697 + str_printf( &title, _("Enter %s (sub)string or regexp to search for " 699 698 "(with or without \"%s\")"), CONFIG_, CONFIG_); 700 699 701 700 again: ··· 760 759 indent + 1, ' ', prompt); 761 760 } else 762 761 item_make(menu, 'm', 763 - " %*c%s --->", 764 - indent + 1, 765 - ' ', prompt); 762 + " %*c%s %s", 763 + indent + 1, ' ', prompt, 764 + menu_is_empty(menu) ? "----" : "--->"); 766 765 767 766 if (single_menu_mode && menu->data) 768 767 goto conf_childs; ··· 904 903 (sym_has_value(sym) || !sym_is_changable(sym)) ? 905 904 "" : _(" (NEW)")); 906 905 if (menu->prompt && menu->prompt->type == P_MENU) { 907 - item_add_str(" --->"); 906 + item_add_str(" %s", menu_is_empty(menu) ? "----" : "--->"); 908 907 return; 909 908 } 910 909 } ··· 955 954 956 955 clear(); 957 956 (void) wattrset(main_window, attributes[NORMAL]); 958 - print_in_middle(stdscr, 1, 0, COLS, 957 + print_in_middle(stdscr, 1, 0, getmaxx(stdscr), 959 958 menu_backtitle, 960 959 attributes[MAIN_HEADING]); 961 960 ··· 1456 1455 1457 1456 void setup_windows(void) 1458 1457 { 1458 + int lines, columns; 1459 + 1460 + getmaxyx(stdscr, lines, columns); 1461 + 1459 1462 if (main_window != NULL) 1460 1463 delwin(main_window); 1461 1464 1462 1465 /* set up the menu and menu window */ 1463 - main_window = newwin(LINES-2, COLS-2, 2, 1); 1466 + main_window = newwin(lines-2, columns-2, 2, 1); 1464 1467 keypad(main_window, TRUE); 1465 - mwin_max_lines = LINES-7; 1466 - mwin_max_cols = COLS-6; 1468 + mwin_max_lines = lines-7; 1469 + mwin_max_cols = columns-6; 1467 1470 1468 1471 /* panels order is from bottom to top */ 1469 1472 new_panel(main_window); ··· 1475 1470 1476 1471 int main(int ac, char **av) 1477 1472 { 1473 + int lines, columns; 1478 1474 char *mode; 1479 1475 1480 1476 setlocale(LC_ALL, ""); ··· 1501 1495 keypad(stdscr, TRUE); 1502 1496 curs_set(0); 1503 1497 1504 - if (COLS < 75 || LINES < 20) { 1498 + getmaxyx(stdscr, lines, columns); 1499 + if (columns < 75 || lines < 20) { 1505 1500 endwin(); 1506 1501 printf("Your terminal should have at " 1507 1502 "least 20 lines and 75 columns\n");
+11 -9
scripts/kconfig/nconf.gui.c
··· 276 276 277 277 total_width = max(msg_width, btns_width); 278 278 /* place dialog in middle of screen */ 279 - y = (LINES-(msg_lines+4))/2; 280 - x = (COLS-(total_width+4))/2; 279 + y = (getmaxy(stdscr)-(msg_lines+4))/2; 280 + x = (getmaxx(stdscr)-(total_width+4))/2; 281 281 282 282 283 283 /* create the windows */ ··· 387 387 prompt_width = max(prompt_width, strlen(title)); 388 388 389 389 /* place dialog in middle of screen */ 390 - y = (LINES-(prompt_lines+4))/2; 391 - x = (COLS-(prompt_width+4))/2; 390 + y = (getmaxy(stdscr)-(prompt_lines+4))/2; 391 + x = (getmaxx(stdscr)-(prompt_width+4))/2; 392 392 393 393 strncpy(result, init, *result_len); 394 394 ··· 545 545 { 546 546 int res; 547 547 int total_lines = get_line_no(text); 548 - int x, y; 548 + int x, y, lines, columns; 549 549 int start_x = 0, start_y = 0; 550 550 int text_lines = 0, text_cols = 0; 551 551 int total_cols = 0; ··· 555 555 WINDOW *win; 556 556 WINDOW *pad; 557 557 PANEL *panel; 558 + 559 + getmaxyx(stdscr, lines, columns); 558 560 559 561 /* find the widest line of msg: */ 560 562 total_lines = get_line_no(text); ··· 571 569 (void) wattrset(pad, attributes[SCROLLWIN_TEXT]); 572 570 fill_window(pad, text); 573 571 574 - win_lines = min(total_lines+4, LINES-2); 575 - win_cols = min(total_cols+2, COLS-2); 572 + win_lines = min(total_lines+4, lines-2); 573 + win_cols = min(total_cols+2, columns-2); 576 574 text_lines = max(win_lines-4, 0); 577 575 text_cols = max(win_cols-2, 0); 578 576 579 577 /* place window in middle of screen */ 580 - y = (LINES-win_lines)/2; 581 - x = (COLS-win_cols)/2; 578 + y = (lines-win_lines)/2; 579 + x = (columns-win_cols)/2; 582 580 583 581 win = newwin(win_lines, win_cols, y, x); 584 582 keypad(win, TRUE);
+85 -14
scripts/kconfig/symbol.c
··· 136 136 return NULL; 137 137 } 138 138 139 - static int sym_get_range_val(struct symbol *sym, int base) 139 + static long sym_get_range_val(struct symbol *sym, int base) 140 140 { 141 141 sym_calc_value(sym); 142 142 switch (sym->type) { ··· 155 155 static void sym_validate_range(struct symbol *sym) 156 156 { 157 157 struct property *prop; 158 - int base, val, val2; 158 + long base, val, val2; 159 159 char str[64]; 160 160 161 161 switch (sym->type) { ··· 179 179 return; 180 180 } 181 181 if (sym->type == S_INT) 182 - sprintf(str, "%d", val2); 182 + sprintf(str, "%ld", val2); 183 183 else 184 - sprintf(str, "0x%x", val2); 184 + sprintf(str, "0x%lx", val2); 185 185 sym->curr.val = strdup(str); 186 186 } 187 187 ··· 300 300 301 301 if (sym->flags & SYMBOL_VALID) 302 302 return; 303 + 304 + if (sym_is_choice_value(sym) && 305 + sym->flags & SYMBOL_NEED_SET_CHOICE_VALUES) { 306 + sym->flags &= ~SYMBOL_NEED_SET_CHOICE_VALUES; 307 + prop = sym_get_choice_prop(sym); 308 + sym_calc_value(prop_get_symbol(prop)); 309 + } 310 + 303 311 sym->flags |= SYMBOL_VALID; 304 312 305 313 oldval = sym->curr; ··· 433 425 434 426 if (sym->flags & SYMBOL_AUTO) 435 427 sym->flags &= ~SYMBOL_WRITE; 428 + 429 + if (sym->flags & SYMBOL_NEED_SET_CHOICE_VALUES) 430 + set_all_choice_values(sym); 436 431 } 437 432 438 433 void sym_clear_all_valid(void) ··· 594 583 bool sym_string_within_range(struct symbol *sym, const char *str) 595 584 { 596 585 struct property *prop; 597 - int val; 586 + long val; 598 587 599 588 switch (sym->type) { 600 589 case S_STRING: ··· 954 943 return res; 955 944 } 956 945 946 + struct sym_match { 947 + struct symbol *sym; 948 + off_t so, eo; 949 + }; 950 + 951 + /* Compare matched symbols as thus: 952 + * - first, symbols that match exactly 953 + * - then, alphabetical sort 954 + */ 955 + static int sym_rel_comp( const void *sym1, const void *sym2 ) 956 + { 957 + struct sym_match *s1 = *(struct sym_match **)sym1; 958 + struct sym_match *s2 = *(struct sym_match **)sym2; 959 + int l1, l2; 960 + 961 + /* Exact match: 962 + * - if matched length on symbol s1 is the length of that symbol, 963 + * then this symbol should come first; 964 + * - if matched length on symbol s2 is the length of that symbol, 965 + * then this symbol should come first. 966 + * Note: since the search can be a regexp, both symbols may match 967 + * exactly; if this is the case, we can't decide which comes first, 968 + * and we fallback to sorting alphabetically. 969 + */ 970 + l1 = s1->eo - s1->so; 971 + l2 = s2->eo - s2->so; 972 + if (l1 == strlen(s1->sym->name) && l2 != strlen(s2->sym->name)) 973 + return -1; 974 + if (l1 != strlen(s1->sym->name) && l2 == strlen(s2->sym->name)) 975 + return 1; 976 + 977 + /* As a fallback, sort symbols alphabetically */ 978 + return strcmp(s1->sym->name, s2->sym->name); 979 + } 980 + 957 981 struct symbol **sym_re_search(const char *pattern) 958 982 { 959 983 struct symbol *sym, **sym_arr = NULL; 984 + struct sym_match **sym_match_arr = NULL; 960 985 int i, cnt, size; 961 986 regex_t re; 987 + regmatch_t match[1]; 962 988 963 989 cnt = size = 0; 964 990 /* Skip if empty */ 965 991 if (strlen(pattern) == 0) 966 992 return NULL; 967 - if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB|REG_ICASE)) 993 + if (regcomp(&re, pattern, REG_EXTENDED|REG_ICASE)) 968 994 return NULL; 969 995 970 996 for_all_symbols(i, sym) { 997 + struct sym_match *tmp_sym_match; 971 998 if (sym->flags & SYMBOL_CONST || !sym->name) 972 999 continue; 973 - if (regexec(&re, sym->name, 0, NULL, 0)) 1000 + if (regexec(&re, sym->name, 1, match, 0)) 974 1001 continue; 975 1002 if (cnt + 1 >= size) { 976 - void *tmp = sym_arr; 1003 + void *tmp; 977 1004 size += 16; 978 - sym_arr = realloc(sym_arr, size * sizeof(struct symbol *)); 979 - if (!sym_arr) { 980 - free(tmp); 981 - return NULL; 1005 + tmp = realloc(sym_match_arr, size * sizeof(struct sym_match *)); 1006 + if (!tmp) { 1007 + goto sym_re_search_free; 982 1008 } 1009 + sym_match_arr = tmp; 983 1010 } 984 1011 sym_calc_value(sym); 985 - sym_arr[cnt++] = sym; 1012 + tmp_sym_match = (struct sym_match*)malloc(sizeof(struct sym_match)); 1013 + if (!tmp_sym_match) 1014 + goto sym_re_search_free; 1015 + tmp_sym_match->sym = sym; 1016 + /* As regexec return 0, we know we have a match, so 1017 + * we can use match[0].rm_[se]o without further checks 1018 + */ 1019 + tmp_sym_match->so = match[0].rm_so; 1020 + tmp_sym_match->eo = match[0].rm_eo; 1021 + sym_match_arr[cnt++] = tmp_sym_match; 986 1022 } 987 - if (sym_arr) 1023 + if (sym_match_arr) { 1024 + qsort(sym_match_arr, cnt, sizeof(struct sym_match*), sym_rel_comp); 1025 + sym_arr = malloc((cnt+1) * sizeof(struct symbol)); 1026 + if (!sym_arr) 1027 + goto sym_re_search_free; 1028 + for (i = 0; i < cnt; i++) 1029 + sym_arr[i] = sym_match_arr[i]->sym; 988 1030 sym_arr[cnt] = NULL; 1031 + } 1032 + sym_re_search_free: 1033 + if (sym_match_arr) { 1034 + for (i = 0; i < cnt; i++) 1035 + free(sym_match_arr[i]); 1036 + free(sym_match_arr); 1037 + } 989 1038 regfree(&re); 990 1039 991 1040 return sym_arr;