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
This commit is contained in:
commit
b202c0d520
19 changed files with 262 additions and 100 deletions
|
@ -174,6 +174,19 @@ Searching in menuconfig:
|
|||
|
||||
/^hotplug
|
||||
|
||||
When searching, symbols are sorted thus:
|
||||
- exact match first: an exact match is when the search matches
|
||||
the complete symbol name;
|
||||
- alphabetical order: when two symbols do not match exactly,
|
||||
they are sorted in alphabetical order (in the user's current
|
||||
locale).
|
||||
For example: ^ATH.K matches:
|
||||
ATH5K ATH9K ATH5K_AHB ATH5K_DEBUG [...] ATH6KL ATH6KL_DEBUG
|
||||
[...] ATH9K_AHB ATH9K_BTCOEX_SUPPORT ATH9K_COMMON [...]
|
||||
of which only ATH5K and ATH9K match exactly and so are sorted
|
||||
first (and in alphabetical order), then come all other symbols,
|
||||
sorted in alphabetical order.
|
||||
|
||||
______________________________________________________________________
|
||||
User interface options for 'menuconfig'
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#!/bin/bash
|
||||
# Manipulate options in a .config file from the command line
|
||||
|
||||
myname=${0##*/}
|
||||
|
||||
# If no prefix forced, use the default CONFIG_
|
||||
CONFIG_="${CONFIG_-CONFIG_}"
|
||||
|
||||
|
@ -8,7 +10,7 @@ usage() {
|
|||
cat >&2 <<EOL
|
||||
Manipulate options in a .config file from the command line.
|
||||
Usage:
|
||||
config options command ...
|
||||
$myname options command ...
|
||||
commands:
|
||||
--enable|-e option Enable option
|
||||
--disable|-d option Disable option
|
||||
|
@ -33,14 +35,14 @@ options:
|
|||
--file config-file .config file to change (default .config)
|
||||
--keep-case|-k Keep next symbols' case (dont' upper-case it)
|
||||
|
||||
config doesn't check the validity of the .config file. This is done at next
|
||||
$myname doesn't check the validity of the .config file. This is done at next
|
||||
make time.
|
||||
|
||||
By default, config will upper-case the given symbol. Use --keep-case to keep
|
||||
By default, $myname will upper-case the given symbol. Use --keep-case to keep
|
||||
the case of all following symbols unchanged.
|
||||
|
||||
config uses 'CONFIG_' as the default symbol prefix. Set the environment
|
||||
variable CONFIG_ to the prefix to use. Eg.: CONFIG_="FOO_" config ...
|
||||
$myname uses 'CONFIG_' as the default symbol prefix. Set the environment
|
||||
variable CONFIG_ to the prefix to use. Eg.: CONFIG_="FOO_" $myname ...
|
||||
EOL
|
||||
exit 1
|
||||
}
|
||||
|
|
|
@ -527,11 +527,12 @@ int main(int ac, char **av)
|
|||
seed_env = getenv("KCONFIG_SEED");
|
||||
if( seed_env && *seed_env ) {
|
||||
char *endp;
|
||||
int tmp = (int)strtol(seed_env, &endp, 10);
|
||||
int tmp = (int)strtol(seed_env, &endp, 0);
|
||||
if (*endp == '\0') {
|
||||
seed = tmp;
|
||||
}
|
||||
}
|
||||
fprintf( stderr, "KCONFIG_SEED=0x%X\n", seed );
|
||||
srand(seed);
|
||||
break;
|
||||
}
|
||||
|
@ -653,7 +654,8 @@ int main(int ac, char **av)
|
|||
conf_set_all_new_symbols(def_default);
|
||||
break;
|
||||
case randconfig:
|
||||
conf_set_all_new_symbols(def_random);
|
||||
/* Really nothing to do in this loop */
|
||||
while (conf_set_all_new_symbols(def_random)) ;
|
||||
break;
|
||||
case defconfig:
|
||||
conf_set_all_new_symbols(def_default);
|
||||
|
|
|
@ -1040,7 +1040,7 @@ void conf_set_changed_callback(void (*fn)(void))
|
|||
conf_changed_callback = fn;
|
||||
}
|
||||
|
||||
static void randomize_choice_values(struct symbol *csym)
|
||||
static bool randomize_choice_values(struct symbol *csym)
|
||||
{
|
||||
struct property *prop;
|
||||
struct symbol *sym;
|
||||
|
@ -1053,7 +1053,7 @@ static void randomize_choice_values(struct symbol *csym)
|
|||
* In both cases stop.
|
||||
*/
|
||||
if (csym->curr.tri != yes)
|
||||
return;
|
||||
return false;
|
||||
|
||||
prop = sym_get_choice_prop(csym);
|
||||
|
||||
|
@ -1077,13 +1077,18 @@ static void randomize_choice_values(struct symbol *csym)
|
|||
else {
|
||||
sym->def[S_DEF_USER].tri = no;
|
||||
}
|
||||
sym->flags |= SYMBOL_DEF_USER;
|
||||
/* clear VALID to get value calculated */
|
||||
sym->flags &= ~SYMBOL_VALID;
|
||||
}
|
||||
csym->flags |= SYMBOL_DEF_USER;
|
||||
/* clear VALID to get value calculated */
|
||||
csym->flags &= ~(SYMBOL_VALID);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void set_all_choice_values(struct symbol *csym)
|
||||
void set_all_choice_values(struct symbol *csym)
|
||||
{
|
||||
struct property *prop;
|
||||
struct symbol *sym;
|
||||
|
@ -1100,10 +1105,10 @@ static void set_all_choice_values(struct symbol *csym)
|
|||
}
|
||||
csym->flags |= SYMBOL_DEF_USER;
|
||||
/* clear VALID to get value calculated */
|
||||
csym->flags &= ~(SYMBOL_VALID);
|
||||
csym->flags &= ~(SYMBOL_VALID | SYMBOL_NEED_SET_CHOICE_VALUES);
|
||||
}
|
||||
|
||||
void conf_set_all_new_symbols(enum conf_def_mode mode)
|
||||
bool conf_set_all_new_symbols(enum conf_def_mode mode)
|
||||
{
|
||||
struct symbol *sym, *csym;
|
||||
int i, cnt, pby, pty, ptm; /* pby: probability of boolean = y
|
||||
|
@ -1151,6 +1156,7 @@ void conf_set_all_new_symbols(enum conf_def_mode mode)
|
|||
exit( 1 );
|
||||
}
|
||||
}
|
||||
bool has_changed = false;
|
||||
|
||||
for_all_symbols(i, sym) {
|
||||
if (sym_has_value(sym) || (sym->flags & SYMBOL_VALID))
|
||||
|
@ -1158,6 +1164,7 @@ void conf_set_all_new_symbols(enum conf_def_mode mode)
|
|||
switch (sym_get_type(sym)) {
|
||||
case S_BOOLEAN:
|
||||
case S_TRISTATE:
|
||||
has_changed = true;
|
||||
switch (mode) {
|
||||
case def_yes:
|
||||
sym->def[S_DEF_USER].tri = yes;
|
||||
|
@ -1202,14 +1209,26 @@ void conf_set_all_new_symbols(enum conf_def_mode mode)
|
|||
* selected in a choice block and we set it to yes,
|
||||
* and the rest to no.
|
||||
*/
|
||||
if (mode != def_random) {
|
||||
for_all_symbols(i, csym) {
|
||||
if ((sym_is_choice(csym) && !sym_has_value(csym)) ||
|
||||
sym_is_choice_value(csym))
|
||||
csym->flags |= SYMBOL_NEED_SET_CHOICE_VALUES;
|
||||
}
|
||||
}
|
||||
|
||||
for_all_symbols(i, csym) {
|
||||
if (sym_has_value(csym) || !sym_is_choice(csym))
|
||||
continue;
|
||||
|
||||
sym_calc_value(csym);
|
||||
if (mode == def_random)
|
||||
randomize_choice_values(csym);
|
||||
else
|
||||
has_changed = randomize_choice_values(csym);
|
||||
else {
|
||||
set_all_choice_values(csym);
|
||||
has_changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
return has_changed;
|
||||
}
|
||||
|
|
|
@ -106,6 +106,9 @@ struct symbol {
|
|||
#define SYMBOL_DEF3 0x40000 /* symbol.def[S_DEF_3] is valid */
|
||||
#define SYMBOL_DEF4 0x80000 /* symbol.def[S_DEF_4] is valid */
|
||||
|
||||
/* choice values need to be set before calculating this symbol value */
|
||||
#define SYMBOL_NEED_SET_CHOICE_VALUES 0x100000
|
||||
|
||||
#define SYMBOL_MAXLENGTH 256
|
||||
#define SYMBOL_HASHSIZE 9973
|
||||
|
||||
|
|
|
@ -86,7 +86,8 @@ const char *conf_get_autoconfig_name(void);
|
|||
char *conf_get_default_confname(void);
|
||||
void sym_set_change_count(int count);
|
||||
void sym_add_change_count(int count);
|
||||
void conf_set_all_new_symbols(enum conf_def_mode mode);
|
||||
bool conf_set_all_new_symbols(enum conf_def_mode mode);
|
||||
void set_all_choice_values(struct symbol *csym);
|
||||
|
||||
struct conf_printer {
|
||||
void (*print_symbol)(FILE *, struct symbol *, const char *, void *);
|
||||
|
|
|
@ -14,6 +14,7 @@ P(conf_set_message_callback, void,(void (*fn)(const char *fmt, va_list ap)));
|
|||
/* menu.c */
|
||||
P(rootmenu,struct menu,);
|
||||
|
||||
P(menu_is_empty, bool, (struct menu *menu));
|
||||
P(menu_is_visible, bool, (struct menu *menu));
|
||||
P(menu_has_prompt, bool, (struct menu *menu));
|
||||
P(menu_get_prompt,const char *,(struct menu *menu));
|
||||
|
|
|
@ -132,16 +132,16 @@ int dialog_checklist(const char *title, const char *prompt, int height,
|
|||
}
|
||||
|
||||
do_resize:
|
||||
if (getmaxy(stdscr) < (height + 6))
|
||||
if (getmaxy(stdscr) < (height + CHECKLIST_HEIGTH_MIN))
|
||||
return -ERRDISPLAYTOOSMALL;
|
||||
if (getmaxx(stdscr) < (width + 6))
|
||||
if (getmaxx(stdscr) < (width + CHECKLIST_WIDTH_MIN))
|
||||
return -ERRDISPLAYTOOSMALL;
|
||||
|
||||
max_choice = MIN(list_height, item_count());
|
||||
|
||||
/* center dialog box on screen */
|
||||
x = (COLS - width) / 2;
|
||||
y = (LINES - height) / 2;
|
||||
x = (getmaxx(stdscr) - width) / 2;
|
||||
y = (getmaxy(stdscr) - height) / 2;
|
||||
|
||||
draw_shadow(stdscr, y, x, height, width);
|
||||
|
||||
|
|
|
@ -200,6 +200,20 @@ int item_is_tag(char tag);
|
|||
int on_key_esc(WINDOW *win);
|
||||
int on_key_resize(void);
|
||||
|
||||
/* minimum (re)size values */
|
||||
#define CHECKLIST_HEIGTH_MIN 6 /* For dialog_checklist() */
|
||||
#define CHECKLIST_WIDTH_MIN 6
|
||||
#define INPUTBOX_HEIGTH_MIN 2 /* For dialog_inputbox() */
|
||||
#define INPUTBOX_WIDTH_MIN 2
|
||||
#define MENUBOX_HEIGTH_MIN 15 /* For dialog_menu() */
|
||||
#define MENUBOX_WIDTH_MIN 65
|
||||
#define TEXTBOX_HEIGTH_MIN 8 /* For dialog_textbox() */
|
||||
#define TEXTBOX_WIDTH_MIN 8
|
||||
#define YESNO_HEIGTH_MIN 4 /* For dialog_yesno() */
|
||||
#define YESNO_WIDTH_MIN 4
|
||||
#define WINDOW_HEIGTH_MIN 19 /* For init_dialog() */
|
||||
#define WINDOW_WIDTH_MIN 80
|
||||
|
||||
int init_dialog(const char *backtitle);
|
||||
void set_dialog_backtitle(const char *backtitle);
|
||||
void set_dialog_subtitles(struct subtitle_list *subtitles);
|
||||
|
|
|
@ -56,14 +56,14 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width
|
|||
strcpy(instr, init);
|
||||
|
||||
do_resize:
|
||||
if (getmaxy(stdscr) <= (height - 2))
|
||||
if (getmaxy(stdscr) <= (height - INPUTBOX_HEIGTH_MIN))
|
||||
return -ERRDISPLAYTOOSMALL;
|
||||
if (getmaxx(stdscr) <= (width - 2))
|
||||
if (getmaxx(stdscr) <= (width - INPUTBOX_WIDTH_MIN))
|
||||
return -ERRDISPLAYTOOSMALL;
|
||||
|
||||
/* center dialog box on screen */
|
||||
x = (COLS - width) / 2;
|
||||
y = (LINES - height) / 2;
|
||||
x = (getmaxx(stdscr) - width) / 2;
|
||||
y = (getmaxy(stdscr) - height) / 2;
|
||||
|
||||
draw_shadow(stdscr, y, x, height, width);
|
||||
|
||||
|
|
|
@ -193,7 +193,7 @@ int dialog_menu(const char *title, const char *prompt,
|
|||
do_resize:
|
||||
height = getmaxy(stdscr);
|
||||
width = getmaxx(stdscr);
|
||||
if (height < 15 || width < 65)
|
||||
if (height < MENUBOX_HEIGTH_MIN || width < MENUBOX_WIDTH_MIN)
|
||||
return -ERRDISPLAYTOOSMALL;
|
||||
|
||||
height -= 4;
|
||||
|
@ -203,8 +203,8 @@ do_resize:
|
|||
max_choice = MIN(menu_height, item_count());
|
||||
|
||||
/* center dialog box on screen */
|
||||
x = (COLS - width) / 2;
|
||||
y = (LINES - height) / 2;
|
||||
x = (getmaxx(stdscr) - width) / 2;
|
||||
y = (getmaxy(stdscr) - height) / 2;
|
||||
|
||||
draw_shadow(stdscr, y, x, height, width);
|
||||
|
||||
|
|
|
@ -80,7 +80,7 @@ int dialog_textbox(const char *title, char *tbuf, int initial_height,
|
|||
|
||||
do_resize:
|
||||
getmaxyx(stdscr, height, width);
|
||||
if (height < 8 || width < 8)
|
||||
if (height < TEXTBOX_HEIGTH_MIN || width < TEXTBOX_WIDTH_MIN)
|
||||
return -ERRDISPLAYTOOSMALL;
|
||||
if (initial_height != 0)
|
||||
height = initial_height;
|
||||
|
@ -98,8 +98,8 @@ do_resize:
|
|||
width = 0;
|
||||
|
||||
/* center dialog box on screen */
|
||||
x = (COLS - width) / 2;
|
||||
y = (LINES - height) / 2;
|
||||
x = (getmaxx(stdscr) - width) / 2;
|
||||
y = (getmaxy(stdscr) - height) / 2;
|
||||
|
||||
draw_shadow(stdscr, y, x, height, width);
|
||||
|
||||
|
|
|
@ -254,7 +254,12 @@ void attr_clear(WINDOW * win, int height, int width, chtype attr)
|
|||
|
||||
void dialog_clear(void)
|
||||
{
|
||||
attr_clear(stdscr, LINES, COLS, dlg.screen.atr);
|
||||
int lines, columns;
|
||||
|
||||
lines = getmaxy(stdscr);
|
||||
columns = getmaxx(stdscr);
|
||||
|
||||
attr_clear(stdscr, lines, columns, dlg.screen.atr);
|
||||
/* Display background title if it exists ... - SLH */
|
||||
if (dlg.backtitle != NULL) {
|
||||
int i, len = 0, skip = 0;
|
||||
|
@ -269,10 +274,10 @@ void dialog_clear(void)
|
|||
}
|
||||
|
||||
wmove(stdscr, 1, 1);
|
||||
if (len > COLS - 2) {
|
||||
if (len > columns - 2) {
|
||||
const char *ellipsis = "[...] ";
|
||||
waddstr(stdscr, ellipsis);
|
||||
skip = len - (COLS - 2 - strlen(ellipsis));
|
||||
skip = len - (columns - 2 - strlen(ellipsis));
|
||||
}
|
||||
|
||||
for (pos = dlg.subtitles; pos != NULL; pos = pos->next) {
|
||||
|
@ -298,7 +303,7 @@ void dialog_clear(void)
|
|||
skip--;
|
||||
}
|
||||
|
||||
for (i = len + 1; i < COLS - 1; i++)
|
||||
for (i = len + 1; i < columns - 1; i++)
|
||||
waddch(stdscr, ACS_HLINE);
|
||||
}
|
||||
wnoutrefresh(stdscr);
|
||||
|
@ -317,7 +322,7 @@ int init_dialog(const char *backtitle)
|
|||
getyx(stdscr, saved_y, saved_x);
|
||||
|
||||
getmaxyx(stdscr, height, width);
|
||||
if (height < 19 || width < 80) {
|
||||
if (height < WINDOW_HEIGTH_MIN || width < WINDOW_WIDTH_MIN) {
|
||||
endwin();
|
||||
return -ERRDISPLAYTOOSMALL;
|
||||
}
|
||||
|
@ -371,27 +376,19 @@ void print_title(WINDOW *dialog, const char *title, int width)
|
|||
/*
|
||||
* Print a string of text in a window, automatically wrap around to the
|
||||
* next line if the string is too long to fit on one line. Newline
|
||||
* characters '\n' are replaced by spaces. We start on a new line
|
||||
* characters '\n' are propperly processed. We start on a new line
|
||||
* if there is no room for at least 4 nonblanks following a double-space.
|
||||
*/
|
||||
void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x)
|
||||
{
|
||||
int newl, cur_x, cur_y;
|
||||
int i, prompt_len, room, wlen;
|
||||
char tempstr[MAX_LEN + 1], *word, *sp, *sp2;
|
||||
int prompt_len, room, wlen;
|
||||
char tempstr[MAX_LEN + 1], *word, *sp, *sp2, *newline_separator = 0;
|
||||
|
||||
strcpy(tempstr, prompt);
|
||||
|
||||
prompt_len = strlen(tempstr);
|
||||
|
||||
/*
|
||||
* Remove newlines
|
||||
*/
|
||||
for (i = 0; i < prompt_len; i++) {
|
||||
if (tempstr[i] == '\n')
|
||||
tempstr[i] = ' ';
|
||||
}
|
||||
|
||||
if (prompt_len <= width - x * 2) { /* If prompt is short */
|
||||
wmove(win, y, (width - prompt_len) / 2);
|
||||
waddstr(win, tempstr);
|
||||
|
@ -401,7 +398,10 @@ void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x)
|
|||
newl = 1;
|
||||
word = tempstr;
|
||||
while (word && *word) {
|
||||
sp = strchr(word, ' ');
|
||||
sp = strpbrk(word, "\n ");
|
||||
if (sp && *sp == '\n')
|
||||
newline_separator = sp;
|
||||
|
||||
if (sp)
|
||||
*sp++ = 0;
|
||||
|
||||
|
@ -413,7 +413,7 @@ void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x)
|
|||
if (wlen > room ||
|
||||
(newl && wlen < 4 && sp
|
||||
&& wlen + 1 + strlen(sp) > room
|
||||
&& (!(sp2 = strchr(sp, ' '))
|
||||
&& (!(sp2 = strpbrk(sp, "\n "))
|
||||
|| wlen + 1 + (sp2 - sp) > room))) {
|
||||
cur_y++;
|
||||
cur_x = x;
|
||||
|
@ -421,7 +421,15 @@ void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x)
|
|||
wmove(win, cur_y, cur_x);
|
||||
waddstr(win, word);
|
||||
getyx(win, cur_y, cur_x);
|
||||
cur_x++;
|
||||
|
||||
/* Move to the next line if the word separator was a newline */
|
||||
if (newline_separator) {
|
||||
cur_y++;
|
||||
cur_x = x;
|
||||
newline_separator = 0;
|
||||
} else
|
||||
cur_x++;
|
||||
|
||||
if (sp && *sp == ' ') {
|
||||
cur_x++; /* double space */
|
||||
while (*++sp == ' ') ;
|
||||
|
|
|
@ -45,14 +45,14 @@ int dialog_yesno(const char *title, const char *prompt, int height, int width)
|
|||
WINDOW *dialog;
|
||||
|
||||
do_resize:
|
||||
if (getmaxy(stdscr) < (height + 4))
|
||||
if (getmaxy(stdscr) < (height + YESNO_HEIGTH_MIN))
|
||||
return -ERRDISPLAYTOOSMALL;
|
||||
if (getmaxx(stdscr) < (width + 4))
|
||||
if (getmaxx(stdscr) < (width + YESNO_WIDTH_MIN))
|
||||
return -ERRDISPLAYTOOSMALL;
|
||||
|
||||
/* center dialog box on screen */
|
||||
x = (COLS - width) / 2;
|
||||
y = (LINES - height) / 2;
|
||||
x = (getmaxx(stdscr) - width) / 2;
|
||||
y = (getmaxy(stdscr) - height) / 2;
|
||||
|
||||
draw_shadow(stdscr, y, x, height, width);
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ static const char mconf_readme[] = N_(
|
|||
"----------\n"
|
||||
"o Use the Up/Down arrow keys (cursor keys) to highlight the item\n"
|
||||
" you wish to change or submenu wish to select and press <Enter>.\n"
|
||||
" Submenus are designated by \"--->\".\n"
|
||||
" Submenus are designated by \"--->\", empty ones by \"----\".\n"
|
||||
"\n"
|
||||
" Shortcut: Press the option's highlighted letter (hotkey).\n"
|
||||
" Pressing a hotkey more than once will sequence\n"
|
||||
|
@ -176,7 +176,7 @@ static const char mconf_readme[] = N_(
|
|||
"\n"),
|
||||
menu_instructions[] = N_(
|
||||
"Arrow keys navigate the menu. "
|
||||
"<Enter> selects submenus --->. "
|
||||
"<Enter> selects submenus ---> (or empty submenus ----). "
|
||||
"Highlighted letters are hotkeys. "
|
||||
"Pressing <Y> includes, <N> excludes, <M> modularizes features. "
|
||||
"Press <Esc><Esc> to exit, <?> for Help, </> for Search. "
|
||||
|
@ -401,7 +401,7 @@ static void search_conf(void)
|
|||
struct subtitle_part stpart;
|
||||
|
||||
title = str_new();
|
||||
str_printf( &title, _("Enter %s (sub)string to search for "
|
||||
str_printf( &title, _("Enter %s (sub)string or regexp to search for "
|
||||
"(with or without \"%s\")"), CONFIG_, CONFIG_);
|
||||
|
||||
again:
|
||||
|
@ -498,8 +498,9 @@ static void build_conf(struct menu *menu)
|
|||
menu->data ? "-->" : "++>",
|
||||
indent + 1, ' ', prompt);
|
||||
} else
|
||||
item_make(" %*c%s --->", indent + 1, ' ', prompt);
|
||||
|
||||
item_make(" %*c%s %s",
|
||||
indent + 1, ' ', prompt,
|
||||
menu_is_empty(menu) ? "----" : "--->");
|
||||
item_set_tag('m');
|
||||
item_set_data(menu);
|
||||
if (single_menu_mode && menu->data)
|
||||
|
@ -630,7 +631,7 @@ static void build_conf(struct menu *menu)
|
|||
(sym_has_value(sym) || !sym_is_changable(sym)) ?
|
||||
"" : _(" (NEW)"));
|
||||
if (menu->prompt->type == P_MENU) {
|
||||
item_add_str(" --->");
|
||||
item_add_str(" %s", menu_is_empty(menu) ? "----" : "--->");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -826,7 +827,9 @@ static void conf_choice(struct menu *menu)
|
|||
dialog_clear();
|
||||
res = dialog_checklist(prompt ? _(prompt) : _("Main Menu"),
|
||||
_(radiolist_instructions),
|
||||
15, 70, 6);
|
||||
MENUBOX_HEIGTH_MIN,
|
||||
MENUBOX_WIDTH_MIN,
|
||||
CHECKLIST_HEIGTH_MIN);
|
||||
selected = item_activate_selected();
|
||||
switch (res) {
|
||||
case 0:
|
||||
|
@ -957,8 +960,8 @@ static int handle_exit(void)
|
|||
dialog_clear();
|
||||
if (conf_get_changed())
|
||||
res = dialog_yesno(NULL,
|
||||
_("Do you wish to save your new configuration ?\n"
|
||||
"<ESC><ESC> to continue."),
|
||||
_("Do you wish to save your new configuration?\n"
|
||||
"(Press <ESC><ESC> to continue kernel configuration.)"),
|
||||
6, 60);
|
||||
else
|
||||
res = -1;
|
||||
|
|
|
@ -443,6 +443,22 @@ bool menu_has_prompt(struct menu *menu)
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine if a menu is empty.
|
||||
* A menu is considered empty if it contains no or only
|
||||
* invisible entries.
|
||||
*/
|
||||
bool menu_is_empty(struct menu *menu)
|
||||
{
|
||||
struct menu *child;
|
||||
|
||||
for (child = menu->list; child; child = child->next) {
|
||||
if (menu_is_visible(child))
|
||||
return(false);
|
||||
}
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool menu_is_visible(struct menu *menu)
|
||||
{
|
||||
struct menu *child;
|
||||
|
|
|
@ -45,8 +45,8 @@ static const char nconf_global_help[] = N_(
|
|||
"<n> to remove it. You may press the <Space> key to cycle through the\n"
|
||||
"available options.\n"
|
||||
"\n"
|
||||
"A trailing \"--->\" designates a submenu.\n"
|
||||
"\n"
|
||||
"A trailing \"--->\" designates a submenu, a trailing \"----\" an\n"
|
||||
"empty submenu.\n"
|
||||
"\n"
|
||||
"Menu navigation keys\n"
|
||||
"----------------------------------------------------------------------\n"
|
||||
|
@ -131,7 +131,7 @@ static const char nconf_global_help[] = N_(
|
|||
"\n"),
|
||||
menu_no_f_instructions[] = N_(
|
||||
"Legend: [*] built-in [ ] excluded <M> module < > module capable.\n"
|
||||
"Submenus are designated by a trailing \"--->\".\n"
|
||||
"Submenus are designated by a trailing \"--->\", empty ones by \"----\".\n"
|
||||
"\n"
|
||||
"Use the following keys to navigate the menus:\n"
|
||||
"Move up or down with <Up> and <Down>.\n"
|
||||
|
@ -148,7 +148,7 @@ menu_no_f_instructions[] = N_(
|
|||
"For help related to the current menu entry press <?> or <h>.\n"),
|
||||
menu_instructions[] = N_(
|
||||
"Legend: [*] built-in [ ] excluded <M> module < > module capable.\n"
|
||||
"Submenus are designated by a trailing \"--->\".\n"
|
||||
"Submenus are designated by a trailing \"--->\", empty ones by \"----\".\n"
|
||||
"\n"
|
||||
"Use the following keys to navigate the menus:\n"
|
||||
"Move up or down with <Up> or <Down>.\n"
|
||||
|
@ -365,15 +365,16 @@ static void print_function_line(void)
|
|||
int i;
|
||||
int offset = 1;
|
||||
const int skip = 1;
|
||||
int lines = getmaxy(stdscr);
|
||||
|
||||
for (i = 0; i < function_keys_num; i++) {
|
||||
(void) wattrset(main_window, attributes[FUNCTION_HIGHLIGHT]);
|
||||
mvwprintw(main_window, LINES-3, offset,
|
||||
mvwprintw(main_window, lines-3, offset,
|
||||
"%s",
|
||||
function_keys[i].key_str);
|
||||
(void) wattrset(main_window, attributes[FUNCTION_TEXT]);
|
||||
offset += strlen(function_keys[i].key_str);
|
||||
mvwprintw(main_window, LINES-3,
|
||||
mvwprintw(main_window, lines-3,
|
||||
offset, "%s",
|
||||
function_keys[i].func);
|
||||
offset += strlen(function_keys[i].func) + skip;
|
||||
|
@ -694,7 +695,7 @@ static void search_conf(void)
|
|||
int dres;
|
||||
|
||||
title = str_new();
|
||||
str_printf( &title, _("Enter %s (sub)string to search for "
|
||||
str_printf( &title, _("Enter %s (sub)string or regexp to search for "
|
||||
"(with or without \"%s\")"), CONFIG_, CONFIG_);
|
||||
|
||||
again:
|
||||
|
@ -759,9 +760,9 @@ static void build_conf(struct menu *menu)
|
|||
indent + 1, ' ', prompt);
|
||||
} else
|
||||
item_make(menu, 'm',
|
||||
" %*c%s --->",
|
||||
indent + 1,
|
||||
' ', prompt);
|
||||
" %*c%s %s",
|
||||
indent + 1, ' ', prompt,
|
||||
menu_is_empty(menu) ? "----" : "--->");
|
||||
|
||||
if (single_menu_mode && menu->data)
|
||||
goto conf_childs;
|
||||
|
@ -903,7 +904,7 @@ static void build_conf(struct menu *menu)
|
|||
(sym_has_value(sym) || !sym_is_changable(sym)) ?
|
||||
"" : _(" (NEW)"));
|
||||
if (menu->prompt && menu->prompt->type == P_MENU) {
|
||||
item_add_str(" --->");
|
||||
item_add_str(" %s", menu_is_empty(menu) ? "----" : "--->");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -954,7 +955,7 @@ static void show_menu(const char *prompt, const char *instructions,
|
|||
|
||||
clear();
|
||||
(void) wattrset(main_window, attributes[NORMAL]);
|
||||
print_in_middle(stdscr, 1, 0, COLS,
|
||||
print_in_middle(stdscr, 1, 0, getmaxx(stdscr),
|
||||
menu_backtitle,
|
||||
attributes[MAIN_HEADING]);
|
||||
|
||||
|
@ -1455,14 +1456,18 @@ static void conf_save(void)
|
|||
|
||||
void setup_windows(void)
|
||||
{
|
||||
int lines, columns;
|
||||
|
||||
getmaxyx(stdscr, lines, columns);
|
||||
|
||||
if (main_window != NULL)
|
||||
delwin(main_window);
|
||||
|
||||
/* set up the menu and menu window */
|
||||
main_window = newwin(LINES-2, COLS-2, 2, 1);
|
||||
main_window = newwin(lines-2, columns-2, 2, 1);
|
||||
keypad(main_window, TRUE);
|
||||
mwin_max_lines = LINES-7;
|
||||
mwin_max_cols = COLS-6;
|
||||
mwin_max_lines = lines-7;
|
||||
mwin_max_cols = columns-6;
|
||||
|
||||
/* panels order is from bottom to top */
|
||||
new_panel(main_window);
|
||||
|
@ -1470,6 +1475,7 @@ void setup_windows(void)
|
|||
|
||||
int main(int ac, char **av)
|
||||
{
|
||||
int lines, columns;
|
||||
char *mode;
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
|
@ -1495,7 +1501,8 @@ int main(int ac, char **av)
|
|||
keypad(stdscr, TRUE);
|
||||
curs_set(0);
|
||||
|
||||
if (COLS < 75 || LINES < 20) {
|
||||
getmaxyx(stdscr, lines, columns);
|
||||
if (columns < 75 || lines < 20) {
|
||||
endwin();
|
||||
printf("Your terminal should have at "
|
||||
"least 20 lines and 75 columns\n");
|
||||
|
|
|
@ -276,8 +276,8 @@ int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...)
|
|||
|
||||
total_width = max(msg_width, btns_width);
|
||||
/* place dialog in middle of screen */
|
||||
y = (LINES-(msg_lines+4))/2;
|
||||
x = (COLS-(total_width+4))/2;
|
||||
y = (getmaxy(stdscr)-(msg_lines+4))/2;
|
||||
x = (getmaxx(stdscr)-(total_width+4))/2;
|
||||
|
||||
|
||||
/* create the windows */
|
||||
|
@ -387,8 +387,8 @@ int dialog_inputbox(WINDOW *main_window,
|
|||
prompt_width = max(prompt_width, strlen(title));
|
||||
|
||||
/* place dialog in middle of screen */
|
||||
y = (LINES-(prompt_lines+4))/2;
|
||||
x = (COLS-(prompt_width+4))/2;
|
||||
y = (getmaxy(stdscr)-(prompt_lines+4))/2;
|
||||
x = (getmaxx(stdscr)-(prompt_width+4))/2;
|
||||
|
||||
strncpy(result, init, *result_len);
|
||||
|
||||
|
@ -545,7 +545,7 @@ void show_scroll_win(WINDOW *main_window,
|
|||
{
|
||||
int res;
|
||||
int total_lines = get_line_no(text);
|
||||
int x, y;
|
||||
int x, y, lines, columns;
|
||||
int start_x = 0, start_y = 0;
|
||||
int text_lines = 0, text_cols = 0;
|
||||
int total_cols = 0;
|
||||
|
@ -556,6 +556,8 @@ void show_scroll_win(WINDOW *main_window,
|
|||
WINDOW *pad;
|
||||
PANEL *panel;
|
||||
|
||||
getmaxyx(stdscr, lines, columns);
|
||||
|
||||
/* find the widest line of msg: */
|
||||
total_lines = get_line_no(text);
|
||||
for (i = 0; i < total_lines; i++) {
|
||||
|
@ -569,14 +571,14 @@ void show_scroll_win(WINDOW *main_window,
|
|||
(void) wattrset(pad, attributes[SCROLLWIN_TEXT]);
|
||||
fill_window(pad, text);
|
||||
|
||||
win_lines = min(total_lines+4, LINES-2);
|
||||
win_cols = min(total_cols+2, COLS-2);
|
||||
win_lines = min(total_lines+4, lines-2);
|
||||
win_cols = min(total_cols+2, columns-2);
|
||||
text_lines = max(win_lines-4, 0);
|
||||
text_cols = max(win_cols-2, 0);
|
||||
|
||||
/* place window in middle of screen */
|
||||
y = (LINES-win_lines)/2;
|
||||
x = (COLS-win_cols)/2;
|
||||
y = (lines-win_lines)/2;
|
||||
x = (columns-win_cols)/2;
|
||||
|
||||
win = newwin(win_lines, win_cols, y, x);
|
||||
keypad(win, TRUE);
|
||||
|
|
|
@ -136,7 +136,7 @@ static struct property *sym_get_range_prop(struct symbol *sym)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int sym_get_range_val(struct symbol *sym, int base)
|
||||
static long sym_get_range_val(struct symbol *sym, int base)
|
||||
{
|
||||
sym_calc_value(sym);
|
||||
switch (sym->type) {
|
||||
|
@ -155,7 +155,7 @@ static int sym_get_range_val(struct symbol *sym, int base)
|
|||
static void sym_validate_range(struct symbol *sym)
|
||||
{
|
||||
struct property *prop;
|
||||
int base, val, val2;
|
||||
long base, val, val2;
|
||||
char str[64];
|
||||
|
||||
switch (sym->type) {
|
||||
|
@ -179,9 +179,9 @@ static void sym_validate_range(struct symbol *sym)
|
|||
return;
|
||||
}
|
||||
if (sym->type == S_INT)
|
||||
sprintf(str, "%d", val2);
|
||||
sprintf(str, "%ld", val2);
|
||||
else
|
||||
sprintf(str, "0x%x", val2);
|
||||
sprintf(str, "0x%lx", val2);
|
||||
sym->curr.val = strdup(str);
|
||||
}
|
||||
|
||||
|
@ -300,6 +300,14 @@ void sym_calc_value(struct symbol *sym)
|
|||
|
||||
if (sym->flags & SYMBOL_VALID)
|
||||
return;
|
||||
|
||||
if (sym_is_choice_value(sym) &&
|
||||
sym->flags & SYMBOL_NEED_SET_CHOICE_VALUES) {
|
||||
sym->flags &= ~SYMBOL_NEED_SET_CHOICE_VALUES;
|
||||
prop = sym_get_choice_prop(sym);
|
||||
sym_calc_value(prop_get_symbol(prop));
|
||||
}
|
||||
|
||||
sym->flags |= SYMBOL_VALID;
|
||||
|
||||
oldval = sym->curr;
|
||||
|
@ -425,6 +433,9 @@ void sym_calc_value(struct symbol *sym)
|
|||
|
||||
if (sym->flags & SYMBOL_AUTO)
|
||||
sym->flags &= ~SYMBOL_WRITE;
|
||||
|
||||
if (sym->flags & SYMBOL_NEED_SET_CHOICE_VALUES)
|
||||
set_all_choice_values(sym);
|
||||
}
|
||||
|
||||
void sym_clear_all_valid(void)
|
||||
|
@ -583,7 +594,7 @@ bool sym_string_valid(struct symbol *sym, const char *str)
|
|||
bool sym_string_within_range(struct symbol *sym, const char *str)
|
||||
{
|
||||
struct property *prop;
|
||||
int val;
|
||||
long val;
|
||||
|
||||
switch (sym->type) {
|
||||
case S_STRING:
|
||||
|
@ -943,38 +954,98 @@ const char *sym_escape_string_value(const char *in)
|
|||
return res;
|
||||
}
|
||||
|
||||
struct sym_match {
|
||||
struct symbol *sym;
|
||||
off_t so, eo;
|
||||
};
|
||||
|
||||
/* Compare matched symbols as thus:
|
||||
* - first, symbols that match exactly
|
||||
* - then, alphabetical sort
|
||||
*/
|
||||
static int sym_rel_comp( const void *sym1, const void *sym2 )
|
||||
{
|
||||
struct sym_match *s1 = *(struct sym_match **)sym1;
|
||||
struct sym_match *s2 = *(struct sym_match **)sym2;
|
||||
int l1, l2;
|
||||
|
||||
/* Exact match:
|
||||
* - if matched length on symbol s1 is the length of that symbol,
|
||||
* then this symbol should come first;
|
||||
* - if matched length on symbol s2 is the length of that symbol,
|
||||
* then this symbol should come first.
|
||||
* Note: since the search can be a regexp, both symbols may match
|
||||
* exactly; if this is the case, we can't decide which comes first,
|
||||
* and we fallback to sorting alphabetically.
|
||||
*/
|
||||
l1 = s1->eo - s1->so;
|
||||
l2 = s2->eo - s2->so;
|
||||
if (l1 == strlen(s1->sym->name) && l2 != strlen(s2->sym->name))
|
||||
return -1;
|
||||
if (l1 != strlen(s1->sym->name) && l2 == strlen(s2->sym->name))
|
||||
return 1;
|
||||
|
||||
/* As a fallback, sort symbols alphabetically */
|
||||
return strcmp(s1->sym->name, s2->sym->name);
|
||||
}
|
||||
|
||||
struct symbol **sym_re_search(const char *pattern)
|
||||
{
|
||||
struct symbol *sym, **sym_arr = NULL;
|
||||
struct sym_match **sym_match_arr = NULL;
|
||||
int i, cnt, size;
|
||||
regex_t re;
|
||||
regmatch_t match[1];
|
||||
|
||||
cnt = size = 0;
|
||||
/* Skip if empty */
|
||||
if (strlen(pattern) == 0)
|
||||
return NULL;
|
||||
if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB|REG_ICASE))
|
||||
if (regcomp(&re, pattern, REG_EXTENDED|REG_ICASE))
|
||||
return NULL;
|
||||
|
||||
for_all_symbols(i, sym) {
|
||||
struct sym_match *tmp_sym_match;
|
||||
if (sym->flags & SYMBOL_CONST || !sym->name)
|
||||
continue;
|
||||
if (regexec(&re, sym->name, 0, NULL, 0))
|
||||
if (regexec(&re, sym->name, 1, match, 0))
|
||||
continue;
|
||||
if (cnt + 1 >= size) {
|
||||
void *tmp = sym_arr;
|
||||
void *tmp;
|
||||
size += 16;
|
||||
sym_arr = realloc(sym_arr, size * sizeof(struct symbol *));
|
||||
if (!sym_arr) {
|
||||
free(tmp);
|
||||
return NULL;
|
||||
tmp = realloc(sym_match_arr, size * sizeof(struct sym_match *));
|
||||
if (!tmp) {
|
||||
goto sym_re_search_free;
|
||||
}
|
||||
sym_match_arr = tmp;
|
||||
}
|
||||
sym_calc_value(sym);
|
||||
sym_arr[cnt++] = sym;
|
||||
tmp_sym_match = (struct sym_match*)malloc(sizeof(struct sym_match));
|
||||
if (!tmp_sym_match)
|
||||
goto sym_re_search_free;
|
||||
tmp_sym_match->sym = sym;
|
||||
/* As regexec return 0, we know we have a match, so
|
||||
* we can use match[0].rm_[se]o without further checks
|
||||
*/
|
||||
tmp_sym_match->so = match[0].rm_so;
|
||||
tmp_sym_match->eo = match[0].rm_eo;
|
||||
sym_match_arr[cnt++] = tmp_sym_match;
|
||||
}
|
||||
if (sym_arr)
|
||||
if (sym_match_arr) {
|
||||
qsort(sym_match_arr, cnt, sizeof(struct sym_match*), sym_rel_comp);
|
||||
sym_arr = malloc((cnt+1) * sizeof(struct symbol));
|
||||
if (!sym_arr)
|
||||
goto sym_re_search_free;
|
||||
for (i = 0; i < cnt; i++)
|
||||
sym_arr[i] = sym_match_arr[i]->sym;
|
||||
sym_arr[cnt] = NULL;
|
||||
}
|
||||
sym_re_search_free:
|
||||
if (sym_match_arr) {
|
||||
for (i = 0; i < cnt; i++)
|
||||
free(sym_match_arr[i]);
|
||||
free(sym_match_arr);
|
||||
}
|
||||
regfree(&re);
|
||||
|
||||
return sym_arr;
|
||||
|
|
Loading…
Reference in a new issue