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:
Коммит
b202c0d520
|
@ -174,6 +174,19 @@ Searching in menuconfig:
|
||||||
|
|
||||||
/^hotplug
|
/^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'
|
User interface options for 'menuconfig'
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# Manipulate options in a .config file from the command line
|
# Manipulate options in a .config file from the command line
|
||||||
|
|
||||||
|
myname=${0##*/}
|
||||||
|
|
||||||
# If no prefix forced, use the default CONFIG_
|
# If no prefix forced, use the default CONFIG_
|
||||||
CONFIG_="${CONFIG_-CONFIG_}"
|
CONFIG_="${CONFIG_-CONFIG_}"
|
||||||
|
|
||||||
|
@ -8,7 +10,7 @@ usage() {
|
||||||
cat >&2 <<EOL
|
cat >&2 <<EOL
|
||||||
Manipulate options in a .config file from the command line.
|
Manipulate options in a .config file from the command line.
|
||||||
Usage:
|
Usage:
|
||||||
config options command ...
|
$myname options command ...
|
||||||
commands:
|
commands:
|
||||||
--enable|-e option Enable option
|
--enable|-e option Enable option
|
||||||
--disable|-d option Disable option
|
--disable|-d option Disable option
|
||||||
|
@ -33,14 +35,14 @@ options:
|
||||||
--file config-file .config file to change (default .config)
|
--file config-file .config file to change (default .config)
|
||||||
--keep-case|-k Keep next symbols' case (dont' upper-case it)
|
--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.
|
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.
|
the case of all following symbols unchanged.
|
||||||
|
|
||||||
config uses 'CONFIG_' as the default symbol prefix. Set the environment
|
$myname uses 'CONFIG_' as the default symbol prefix. Set the environment
|
||||||
variable CONFIG_ to the prefix to use. Eg.: CONFIG_="FOO_" config ...
|
variable CONFIG_ to the prefix to use. Eg.: CONFIG_="FOO_" $myname ...
|
||||||
EOL
|
EOL
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
|
@ -527,11 +527,12 @@ int main(int ac, char **av)
|
||||||
seed_env = getenv("KCONFIG_SEED");
|
seed_env = getenv("KCONFIG_SEED");
|
||||||
if( seed_env && *seed_env ) {
|
if( seed_env && *seed_env ) {
|
||||||
char *endp;
|
char *endp;
|
||||||
int tmp = (int)strtol(seed_env, &endp, 10);
|
int tmp = (int)strtol(seed_env, &endp, 0);
|
||||||
if (*endp == '\0') {
|
if (*endp == '\0') {
|
||||||
seed = tmp;
|
seed = tmp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fprintf( stderr, "KCONFIG_SEED=0x%X\n", seed );
|
||||||
srand(seed);
|
srand(seed);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -653,7 +654,8 @@ int main(int ac, char **av)
|
||||||
conf_set_all_new_symbols(def_default);
|
conf_set_all_new_symbols(def_default);
|
||||||
break;
|
break;
|
||||||
case randconfig:
|
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;
|
break;
|
||||||
case defconfig:
|
case defconfig:
|
||||||
conf_set_all_new_symbols(def_default);
|
conf_set_all_new_symbols(def_default);
|
||||||
|
|
|
@ -1040,7 +1040,7 @@ void conf_set_changed_callback(void (*fn)(void))
|
||||||
conf_changed_callback = fn;
|
conf_changed_callback = fn;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void randomize_choice_values(struct symbol *csym)
|
static bool randomize_choice_values(struct symbol *csym)
|
||||||
{
|
{
|
||||||
struct property *prop;
|
struct property *prop;
|
||||||
struct symbol *sym;
|
struct symbol *sym;
|
||||||
|
@ -1053,7 +1053,7 @@ static void randomize_choice_values(struct symbol *csym)
|
||||||
* In both cases stop.
|
* In both cases stop.
|
||||||
*/
|
*/
|
||||||
if (csym->curr.tri != yes)
|
if (csym->curr.tri != yes)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
prop = sym_get_choice_prop(csym);
|
prop = sym_get_choice_prop(csym);
|
||||||
|
|
||||||
|
@ -1077,13 +1077,18 @@ static void randomize_choice_values(struct symbol *csym)
|
||||||
else {
|
else {
|
||||||
sym->def[S_DEF_USER].tri = no;
|
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;
|
csym->flags |= SYMBOL_DEF_USER;
|
||||||
/* clear VALID to get value calculated */
|
/* clear VALID to get value calculated */
|
||||||
csym->flags &= ~(SYMBOL_VALID);
|
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 property *prop;
|
||||||
struct symbol *sym;
|
struct symbol *sym;
|
||||||
|
@ -1100,10 +1105,10 @@ static void set_all_choice_values(struct symbol *csym)
|
||||||
}
|
}
|
||||||
csym->flags |= SYMBOL_DEF_USER;
|
csym->flags |= SYMBOL_DEF_USER;
|
||||||
/* clear VALID to get value calculated */
|
/* 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;
|
struct symbol *sym, *csym;
|
||||||
int i, cnt, pby, pty, ptm; /* pby: probability of boolean = y
|
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 );
|
exit( 1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
bool has_changed = false;
|
||||||
|
|
||||||
for_all_symbols(i, sym) {
|
for_all_symbols(i, sym) {
|
||||||
if (sym_has_value(sym) || (sym->flags & SYMBOL_VALID))
|
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)) {
|
switch (sym_get_type(sym)) {
|
||||||
case S_BOOLEAN:
|
case S_BOOLEAN:
|
||||||
case S_TRISTATE:
|
case S_TRISTATE:
|
||||||
|
has_changed = true;
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case def_yes:
|
case def_yes:
|
||||||
sym->def[S_DEF_USER].tri = 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,
|
* selected in a choice block and we set it to yes,
|
||||||
* and the rest to no.
|
* 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) {
|
for_all_symbols(i, csym) {
|
||||||
if (sym_has_value(csym) || !sym_is_choice(csym))
|
if (sym_has_value(csym) || !sym_is_choice(csym))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
sym_calc_value(csym);
|
sym_calc_value(csym);
|
||||||
if (mode == def_random)
|
if (mode == def_random)
|
||||||
randomize_choice_values(csym);
|
has_changed = randomize_choice_values(csym);
|
||||||
else
|
else {
|
||||||
set_all_choice_values(csym);
|
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_DEF3 0x40000 /* symbol.def[S_DEF_3] is valid */
|
||||||
#define SYMBOL_DEF4 0x80000 /* symbol.def[S_DEF_4] 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_MAXLENGTH 256
|
||||||
#define SYMBOL_HASHSIZE 9973
|
#define SYMBOL_HASHSIZE 9973
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,8 @@ const char *conf_get_autoconfig_name(void);
|
||||||
char *conf_get_default_confname(void);
|
char *conf_get_default_confname(void);
|
||||||
void sym_set_change_count(int count);
|
void sym_set_change_count(int count);
|
||||||
void sym_add_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 {
|
struct conf_printer {
|
||||||
void (*print_symbol)(FILE *, struct symbol *, const char *, void *);
|
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 */
|
/* menu.c */
|
||||||
P(rootmenu,struct menu,);
|
P(rootmenu,struct menu,);
|
||||||
|
|
||||||
|
P(menu_is_empty, bool, (struct menu *menu));
|
||||||
P(menu_is_visible, bool, (struct menu *menu));
|
P(menu_is_visible, bool, (struct menu *menu));
|
||||||
P(menu_has_prompt, bool, (struct menu *menu));
|
P(menu_has_prompt, bool, (struct menu *menu));
|
||||||
P(menu_get_prompt,const char *,(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:
|
do_resize:
|
||||||
if (getmaxy(stdscr) < (height + 6))
|
if (getmaxy(stdscr) < (height + CHECKLIST_HEIGTH_MIN))
|
||||||
return -ERRDISPLAYTOOSMALL;
|
return -ERRDISPLAYTOOSMALL;
|
||||||
if (getmaxx(stdscr) < (width + 6))
|
if (getmaxx(stdscr) < (width + CHECKLIST_WIDTH_MIN))
|
||||||
return -ERRDISPLAYTOOSMALL;
|
return -ERRDISPLAYTOOSMALL;
|
||||||
|
|
||||||
max_choice = MIN(list_height, item_count());
|
max_choice = MIN(list_height, item_count());
|
||||||
|
|
||||||
/* center dialog box on screen */
|
/* center dialog box on screen */
|
||||||
x = (COLS - width) / 2;
|
x = (getmaxx(stdscr) - width) / 2;
|
||||||
y = (LINES - height) / 2;
|
y = (getmaxy(stdscr) - height) / 2;
|
||||||
|
|
||||||
draw_shadow(stdscr, y, x, height, width);
|
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_esc(WINDOW *win);
|
||||||
int on_key_resize(void);
|
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);
|
int init_dialog(const char *backtitle);
|
||||||
void set_dialog_backtitle(const char *backtitle);
|
void set_dialog_backtitle(const char *backtitle);
|
||||||
void set_dialog_subtitles(struct subtitle_list *subtitles);
|
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);
|
strcpy(instr, init);
|
||||||
|
|
||||||
do_resize:
|
do_resize:
|
||||||
if (getmaxy(stdscr) <= (height - 2))
|
if (getmaxy(stdscr) <= (height - INPUTBOX_HEIGTH_MIN))
|
||||||
return -ERRDISPLAYTOOSMALL;
|
return -ERRDISPLAYTOOSMALL;
|
||||||
if (getmaxx(stdscr) <= (width - 2))
|
if (getmaxx(stdscr) <= (width - INPUTBOX_WIDTH_MIN))
|
||||||
return -ERRDISPLAYTOOSMALL;
|
return -ERRDISPLAYTOOSMALL;
|
||||||
|
|
||||||
/* center dialog box on screen */
|
/* center dialog box on screen */
|
||||||
x = (COLS - width) / 2;
|
x = (getmaxx(stdscr) - width) / 2;
|
||||||
y = (LINES - height) / 2;
|
y = (getmaxy(stdscr) - height) / 2;
|
||||||
|
|
||||||
draw_shadow(stdscr, y, x, height, width);
|
draw_shadow(stdscr, y, x, height, width);
|
||||||
|
|
||||||
|
|
|
@ -193,7 +193,7 @@ int dialog_menu(const char *title, const char *prompt,
|
||||||
do_resize:
|
do_resize:
|
||||||
height = getmaxy(stdscr);
|
height = getmaxy(stdscr);
|
||||||
width = getmaxx(stdscr);
|
width = getmaxx(stdscr);
|
||||||
if (height < 15 || width < 65)
|
if (height < MENUBOX_HEIGTH_MIN || width < MENUBOX_WIDTH_MIN)
|
||||||
return -ERRDISPLAYTOOSMALL;
|
return -ERRDISPLAYTOOSMALL;
|
||||||
|
|
||||||
height -= 4;
|
height -= 4;
|
||||||
|
@ -203,8 +203,8 @@ do_resize:
|
||||||
max_choice = MIN(menu_height, item_count());
|
max_choice = MIN(menu_height, item_count());
|
||||||
|
|
||||||
/* center dialog box on screen */
|
/* center dialog box on screen */
|
||||||
x = (COLS - width) / 2;
|
x = (getmaxx(stdscr) - width) / 2;
|
||||||
y = (LINES - height) / 2;
|
y = (getmaxy(stdscr) - height) / 2;
|
||||||
|
|
||||||
draw_shadow(stdscr, y, x, height, width);
|
draw_shadow(stdscr, y, x, height, width);
|
||||||
|
|
||||||
|
|
|
@ -80,7 +80,7 @@ int dialog_textbox(const char *title, char *tbuf, int initial_height,
|
||||||
|
|
||||||
do_resize:
|
do_resize:
|
||||||
getmaxyx(stdscr, height, width);
|
getmaxyx(stdscr, height, width);
|
||||||
if (height < 8 || width < 8)
|
if (height < TEXTBOX_HEIGTH_MIN || width < TEXTBOX_WIDTH_MIN)
|
||||||
return -ERRDISPLAYTOOSMALL;
|
return -ERRDISPLAYTOOSMALL;
|
||||||
if (initial_height != 0)
|
if (initial_height != 0)
|
||||||
height = initial_height;
|
height = initial_height;
|
||||||
|
@ -98,8 +98,8 @@ do_resize:
|
||||||
width = 0;
|
width = 0;
|
||||||
|
|
||||||
/* center dialog box on screen */
|
/* center dialog box on screen */
|
||||||
x = (COLS - width) / 2;
|
x = (getmaxx(stdscr) - width) / 2;
|
||||||
y = (LINES - height) / 2;
|
y = (getmaxy(stdscr) - height) / 2;
|
||||||
|
|
||||||
draw_shadow(stdscr, y, x, height, width);
|
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)
|
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 */
|
/* Display background title if it exists ... - SLH */
|
||||||
if (dlg.backtitle != NULL) {
|
if (dlg.backtitle != NULL) {
|
||||||
int i, len = 0, skip = 0;
|
int i, len = 0, skip = 0;
|
||||||
|
@ -269,10 +274,10 @@ void dialog_clear(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
wmove(stdscr, 1, 1);
|
wmove(stdscr, 1, 1);
|
||||||
if (len > COLS - 2) {
|
if (len > columns - 2) {
|
||||||
const char *ellipsis = "[...] ";
|
const char *ellipsis = "[...] ";
|
||||||
waddstr(stdscr, 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) {
|
for (pos = dlg.subtitles; pos != NULL; pos = pos->next) {
|
||||||
|
@ -298,7 +303,7 @@ void dialog_clear(void)
|
||||||
skip--;
|
skip--;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = len + 1; i < COLS - 1; i++)
|
for (i = len + 1; i < columns - 1; i++)
|
||||||
waddch(stdscr, ACS_HLINE);
|
waddch(stdscr, ACS_HLINE);
|
||||||
}
|
}
|
||||||
wnoutrefresh(stdscr);
|
wnoutrefresh(stdscr);
|
||||||
|
@ -317,7 +322,7 @@ int init_dialog(const char *backtitle)
|
||||||
getyx(stdscr, saved_y, saved_x);
|
getyx(stdscr, saved_y, saved_x);
|
||||||
|
|
||||||
getmaxyx(stdscr, height, width);
|
getmaxyx(stdscr, height, width);
|
||||||
if (height < 19 || width < 80) {
|
if (height < WINDOW_HEIGTH_MIN || width < WINDOW_WIDTH_MIN) {
|
||||||
endwin();
|
endwin();
|
||||||
return -ERRDISPLAYTOOSMALL;
|
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
|
* 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
|
* 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.
|
* 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)
|
void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x)
|
||||||
{
|
{
|
||||||
int newl, cur_x, cur_y;
|
int newl, cur_x, cur_y;
|
||||||
int i, prompt_len, room, wlen;
|
int prompt_len, room, wlen;
|
||||||
char tempstr[MAX_LEN + 1], *word, *sp, *sp2;
|
char tempstr[MAX_LEN + 1], *word, *sp, *sp2, *newline_separator = 0;
|
||||||
|
|
||||||
strcpy(tempstr, prompt);
|
strcpy(tempstr, prompt);
|
||||||
|
|
||||||
prompt_len = strlen(tempstr);
|
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 */
|
if (prompt_len <= width - x * 2) { /* If prompt is short */
|
||||||
wmove(win, y, (width - prompt_len) / 2);
|
wmove(win, y, (width - prompt_len) / 2);
|
||||||
waddstr(win, tempstr);
|
waddstr(win, tempstr);
|
||||||
|
@ -401,7 +398,10 @@ void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x)
|
||||||
newl = 1;
|
newl = 1;
|
||||||
word = tempstr;
|
word = tempstr;
|
||||||
while (word && *word) {
|
while (word && *word) {
|
||||||
sp = strchr(word, ' ');
|
sp = strpbrk(word, "\n ");
|
||||||
|
if (sp && *sp == '\n')
|
||||||
|
newline_separator = sp;
|
||||||
|
|
||||||
if (sp)
|
if (sp)
|
||||||
*sp++ = 0;
|
*sp++ = 0;
|
||||||
|
|
||||||
|
@ -413,7 +413,7 @@ void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x)
|
||||||
if (wlen > room ||
|
if (wlen > room ||
|
||||||
(newl && wlen < 4 && sp
|
(newl && wlen < 4 && sp
|
||||||
&& wlen + 1 + strlen(sp) > room
|
&& wlen + 1 + strlen(sp) > room
|
||||||
&& (!(sp2 = strchr(sp, ' '))
|
&& (!(sp2 = strpbrk(sp, "\n "))
|
||||||
|| wlen + 1 + (sp2 - sp) > room))) {
|
|| wlen + 1 + (sp2 - sp) > room))) {
|
||||||
cur_y++;
|
cur_y++;
|
||||||
cur_x = x;
|
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);
|
wmove(win, cur_y, cur_x);
|
||||||
waddstr(win, word);
|
waddstr(win, word);
|
||||||
getyx(win, cur_y, cur_x);
|
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 == ' ') {
|
if (sp && *sp == ' ') {
|
||||||
cur_x++; /* double space */
|
cur_x++; /* double space */
|
||||||
while (*++sp == ' ') ;
|
while (*++sp == ' ') ;
|
||||||
|
|
|
@ -45,14 +45,14 @@ int dialog_yesno(const char *title, const char *prompt, int height, int width)
|
||||||
WINDOW *dialog;
|
WINDOW *dialog;
|
||||||
|
|
||||||
do_resize:
|
do_resize:
|
||||||
if (getmaxy(stdscr) < (height + 4))
|
if (getmaxy(stdscr) < (height + YESNO_HEIGTH_MIN))
|
||||||
return -ERRDISPLAYTOOSMALL;
|
return -ERRDISPLAYTOOSMALL;
|
||||||
if (getmaxx(stdscr) < (width + 4))
|
if (getmaxx(stdscr) < (width + YESNO_WIDTH_MIN))
|
||||||
return -ERRDISPLAYTOOSMALL;
|
return -ERRDISPLAYTOOSMALL;
|
||||||
|
|
||||||
/* center dialog box on screen */
|
/* center dialog box on screen */
|
||||||
x = (COLS - width) / 2;
|
x = (getmaxx(stdscr) - width) / 2;
|
||||||
y = (LINES - height) / 2;
|
y = (getmaxy(stdscr) - height) / 2;
|
||||||
|
|
||||||
draw_shadow(stdscr, y, x, height, width);
|
draw_shadow(stdscr, y, x, height, width);
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ static const char mconf_readme[] = N_(
|
||||||
"----------\n"
|
"----------\n"
|
||||||
"o Use the Up/Down arrow keys (cursor keys) to highlight the item\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"
|
" 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"
|
"\n"
|
||||||
" Shortcut: Press the option's highlighted letter (hotkey).\n"
|
" Shortcut: Press the option's highlighted letter (hotkey).\n"
|
||||||
" Pressing a hotkey more than once will sequence\n"
|
" Pressing a hotkey more than once will sequence\n"
|
||||||
|
@ -176,7 +176,7 @@ static const char mconf_readme[] = N_(
|
||||||
"\n"),
|
"\n"),
|
||||||
menu_instructions[] = N_(
|
menu_instructions[] = N_(
|
||||||
"Arrow keys navigate the menu. "
|
"Arrow keys navigate the menu. "
|
||||||
"<Enter> selects submenus --->. "
|
"<Enter> selects submenus ---> (or empty submenus ----). "
|
||||||
"Highlighted letters are hotkeys. "
|
"Highlighted letters are hotkeys. "
|
||||||
"Pressing <Y> includes, <N> excludes, <M> modularizes features. "
|
"Pressing <Y> includes, <N> excludes, <M> modularizes features. "
|
||||||
"Press <Esc><Esc> to exit, <?> for Help, </> for Search. "
|
"Press <Esc><Esc> to exit, <?> for Help, </> for Search. "
|
||||||
|
@ -401,7 +401,7 @@ static void search_conf(void)
|
||||||
struct subtitle_part stpart;
|
struct subtitle_part stpart;
|
||||||
|
|
||||||
title = str_new();
|
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_);
|
"(with or without \"%s\")"), CONFIG_, CONFIG_);
|
||||||
|
|
||||||
again:
|
again:
|
||||||
|
@ -498,8 +498,9 @@ static void build_conf(struct menu *menu)
|
||||||
menu->data ? "-->" : "++>",
|
menu->data ? "-->" : "++>",
|
||||||
indent + 1, ' ', prompt);
|
indent + 1, ' ', prompt);
|
||||||
} else
|
} 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_tag('m');
|
||||||
item_set_data(menu);
|
item_set_data(menu);
|
||||||
if (single_menu_mode && menu->data)
|
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)) ?
|
(sym_has_value(sym) || !sym_is_changable(sym)) ?
|
||||||
"" : _(" (NEW)"));
|
"" : _(" (NEW)"));
|
||||||
if (menu->prompt->type == P_MENU) {
|
if (menu->prompt->type == P_MENU) {
|
||||||
item_add_str(" --->");
|
item_add_str(" %s", menu_is_empty(menu) ? "----" : "--->");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -826,7 +827,9 @@ static void conf_choice(struct menu *menu)
|
||||||
dialog_clear();
|
dialog_clear();
|
||||||
res = dialog_checklist(prompt ? _(prompt) : _("Main Menu"),
|
res = dialog_checklist(prompt ? _(prompt) : _("Main Menu"),
|
||||||
_(radiolist_instructions),
|
_(radiolist_instructions),
|
||||||
15, 70, 6);
|
MENUBOX_HEIGTH_MIN,
|
||||||
|
MENUBOX_WIDTH_MIN,
|
||||||
|
CHECKLIST_HEIGTH_MIN);
|
||||||
selected = item_activate_selected();
|
selected = item_activate_selected();
|
||||||
switch (res) {
|
switch (res) {
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -957,8 +960,8 @@ static int handle_exit(void)
|
||||||
dialog_clear();
|
dialog_clear();
|
||||||
if (conf_get_changed())
|
if (conf_get_changed())
|
||||||
res = dialog_yesno(NULL,
|
res = dialog_yesno(NULL,
|
||||||
_("Do you wish to save your new configuration ?\n"
|
_("Do you wish to save your new configuration?\n"
|
||||||
"<ESC><ESC> to continue."),
|
"(Press <ESC><ESC> to continue kernel configuration.)"),
|
||||||
6, 60);
|
6, 60);
|
||||||
else
|
else
|
||||||
res = -1;
|
res = -1;
|
||||||
|
|
|
@ -443,6 +443,22 @@ bool menu_has_prompt(struct menu *menu)
|
||||||
return true;
|
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)
|
bool menu_is_visible(struct menu *menu)
|
||||||
{
|
{
|
||||||
struct menu *child;
|
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"
|
"<n> to remove it. You may press the <Space> key to cycle through the\n"
|
||||||
"available options.\n"
|
"available options.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"A trailing \"--->\" designates a submenu.\n"
|
"A trailing \"--->\" designates a submenu, a trailing \"----\" an\n"
|
||||||
"\n"
|
"empty submenu.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Menu navigation keys\n"
|
"Menu navigation keys\n"
|
||||||
"----------------------------------------------------------------------\n"
|
"----------------------------------------------------------------------\n"
|
||||||
|
@ -131,7 +131,7 @@ static const char nconf_global_help[] = N_(
|
||||||
"\n"),
|
"\n"),
|
||||||
menu_no_f_instructions[] = N_(
|
menu_no_f_instructions[] = N_(
|
||||||
"Legend: [*] built-in [ ] excluded <M> module < > module capable.\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"
|
"\n"
|
||||||
"Use the following keys to navigate the menus:\n"
|
"Use the following keys to navigate the menus:\n"
|
||||||
"Move up or down with <Up> and <Down>.\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"),
|
"For help related to the current menu entry press <?> or <h>.\n"),
|
||||||
menu_instructions[] = N_(
|
menu_instructions[] = N_(
|
||||||
"Legend: [*] built-in [ ] excluded <M> module < > module capable.\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"
|
"\n"
|
||||||
"Use the following keys to navigate the menus:\n"
|
"Use the following keys to navigate the menus:\n"
|
||||||
"Move up or down with <Up> or <Down>.\n"
|
"Move up or down with <Up> or <Down>.\n"
|
||||||
|
@ -365,15 +365,16 @@ static void print_function_line(void)
|
||||||
int i;
|
int i;
|
||||||
int offset = 1;
|
int offset = 1;
|
||||||
const int skip = 1;
|
const int skip = 1;
|
||||||
|
int lines = getmaxy(stdscr);
|
||||||
|
|
||||||
for (i = 0; i < function_keys_num; i++) {
|
for (i = 0; i < function_keys_num; i++) {
|
||||||
(void) wattrset(main_window, attributes[FUNCTION_HIGHLIGHT]);
|
(void) wattrset(main_window, attributes[FUNCTION_HIGHLIGHT]);
|
||||||
mvwprintw(main_window, LINES-3, offset,
|
mvwprintw(main_window, lines-3, offset,
|
||||||
"%s",
|
"%s",
|
||||||
function_keys[i].key_str);
|
function_keys[i].key_str);
|
||||||
(void) wattrset(main_window, attributes[FUNCTION_TEXT]);
|
(void) wattrset(main_window, attributes[FUNCTION_TEXT]);
|
||||||
offset += strlen(function_keys[i].key_str);
|
offset += strlen(function_keys[i].key_str);
|
||||||
mvwprintw(main_window, LINES-3,
|
mvwprintw(main_window, lines-3,
|
||||||
offset, "%s",
|
offset, "%s",
|
||||||
function_keys[i].func);
|
function_keys[i].func);
|
||||||
offset += strlen(function_keys[i].func) + skip;
|
offset += strlen(function_keys[i].func) + skip;
|
||||||
|
@ -694,7 +695,7 @@ static void search_conf(void)
|
||||||
int dres;
|
int dres;
|
||||||
|
|
||||||
title = str_new();
|
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_);
|
"(with or without \"%s\")"), CONFIG_, CONFIG_);
|
||||||
|
|
||||||
again:
|
again:
|
||||||
|
@ -759,9 +760,9 @@ static void build_conf(struct menu *menu)
|
||||||
indent + 1, ' ', prompt);
|
indent + 1, ' ', prompt);
|
||||||
} else
|
} else
|
||||||
item_make(menu, 'm',
|
item_make(menu, 'm',
|
||||||
" %*c%s --->",
|
" %*c%s %s",
|
||||||
indent + 1,
|
indent + 1, ' ', prompt,
|
||||||
' ', prompt);
|
menu_is_empty(menu) ? "----" : "--->");
|
||||||
|
|
||||||
if (single_menu_mode && menu->data)
|
if (single_menu_mode && menu->data)
|
||||||
goto conf_childs;
|
goto conf_childs;
|
||||||
|
@ -903,7 +904,7 @@ static void build_conf(struct menu *menu)
|
||||||
(sym_has_value(sym) || !sym_is_changable(sym)) ?
|
(sym_has_value(sym) || !sym_is_changable(sym)) ?
|
||||||
"" : _(" (NEW)"));
|
"" : _(" (NEW)"));
|
||||||
if (menu->prompt && menu->prompt->type == P_MENU) {
|
if (menu->prompt && menu->prompt->type == P_MENU) {
|
||||||
item_add_str(" --->");
|
item_add_str(" %s", menu_is_empty(menu) ? "----" : "--->");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -954,7 +955,7 @@ static void show_menu(const char *prompt, const char *instructions,
|
||||||
|
|
||||||
clear();
|
clear();
|
||||||
(void) wattrset(main_window, attributes[NORMAL]);
|
(void) wattrset(main_window, attributes[NORMAL]);
|
||||||
print_in_middle(stdscr, 1, 0, COLS,
|
print_in_middle(stdscr, 1, 0, getmaxx(stdscr),
|
||||||
menu_backtitle,
|
menu_backtitle,
|
||||||
attributes[MAIN_HEADING]);
|
attributes[MAIN_HEADING]);
|
||||||
|
|
||||||
|
@ -1455,14 +1456,18 @@ static void conf_save(void)
|
||||||
|
|
||||||
void setup_windows(void)
|
void setup_windows(void)
|
||||||
{
|
{
|
||||||
|
int lines, columns;
|
||||||
|
|
||||||
|
getmaxyx(stdscr, lines, columns);
|
||||||
|
|
||||||
if (main_window != NULL)
|
if (main_window != NULL)
|
||||||
delwin(main_window);
|
delwin(main_window);
|
||||||
|
|
||||||
/* set up the menu and menu 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);
|
keypad(main_window, TRUE);
|
||||||
mwin_max_lines = LINES-7;
|
mwin_max_lines = lines-7;
|
||||||
mwin_max_cols = COLS-6;
|
mwin_max_cols = columns-6;
|
||||||
|
|
||||||
/* panels order is from bottom to top */
|
/* panels order is from bottom to top */
|
||||||
new_panel(main_window);
|
new_panel(main_window);
|
||||||
|
@ -1470,6 +1475,7 @@ void setup_windows(void)
|
||||||
|
|
||||||
int main(int ac, char **av)
|
int main(int ac, char **av)
|
||||||
{
|
{
|
||||||
|
int lines, columns;
|
||||||
char *mode;
|
char *mode;
|
||||||
|
|
||||||
setlocale(LC_ALL, "");
|
setlocale(LC_ALL, "");
|
||||||
|
@ -1495,7 +1501,8 @@ int main(int ac, char **av)
|
||||||
keypad(stdscr, TRUE);
|
keypad(stdscr, TRUE);
|
||||||
curs_set(0);
|
curs_set(0);
|
||||||
|
|
||||||
if (COLS < 75 || LINES < 20) {
|
getmaxyx(stdscr, lines, columns);
|
||||||
|
if (columns < 75 || lines < 20) {
|
||||||
endwin();
|
endwin();
|
||||||
printf("Your terminal should have at "
|
printf("Your terminal should have at "
|
||||||
"least 20 lines and 75 columns\n");
|
"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);
|
total_width = max(msg_width, btns_width);
|
||||||
/* place dialog in middle of screen */
|
/* place dialog in middle of screen */
|
||||||
y = (LINES-(msg_lines+4))/2;
|
y = (getmaxy(stdscr)-(msg_lines+4))/2;
|
||||||
x = (COLS-(total_width+4))/2;
|
x = (getmaxx(stdscr)-(total_width+4))/2;
|
||||||
|
|
||||||
|
|
||||||
/* create the windows */
|
/* create the windows */
|
||||||
|
@ -387,8 +387,8 @@ int dialog_inputbox(WINDOW *main_window,
|
||||||
prompt_width = max(prompt_width, strlen(title));
|
prompt_width = max(prompt_width, strlen(title));
|
||||||
|
|
||||||
/* place dialog in middle of screen */
|
/* place dialog in middle of screen */
|
||||||
y = (LINES-(prompt_lines+4))/2;
|
y = (getmaxy(stdscr)-(prompt_lines+4))/2;
|
||||||
x = (COLS-(prompt_width+4))/2;
|
x = (getmaxx(stdscr)-(prompt_width+4))/2;
|
||||||
|
|
||||||
strncpy(result, init, *result_len);
|
strncpy(result, init, *result_len);
|
||||||
|
|
||||||
|
@ -545,7 +545,7 @@ void show_scroll_win(WINDOW *main_window,
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
int total_lines = get_line_no(text);
|
int total_lines = get_line_no(text);
|
||||||
int x, y;
|
int x, y, lines, columns;
|
||||||
int start_x = 0, start_y = 0;
|
int start_x = 0, start_y = 0;
|
||||||
int text_lines = 0, text_cols = 0;
|
int text_lines = 0, text_cols = 0;
|
||||||
int total_cols = 0;
|
int total_cols = 0;
|
||||||
|
@ -556,6 +556,8 @@ void show_scroll_win(WINDOW *main_window,
|
||||||
WINDOW *pad;
|
WINDOW *pad;
|
||||||
PANEL *panel;
|
PANEL *panel;
|
||||||
|
|
||||||
|
getmaxyx(stdscr, lines, columns);
|
||||||
|
|
||||||
/* find the widest line of msg: */
|
/* find the widest line of msg: */
|
||||||
total_lines = get_line_no(text);
|
total_lines = get_line_no(text);
|
||||||
for (i = 0; i < total_lines; i++) {
|
for (i = 0; i < total_lines; i++) {
|
||||||
|
@ -569,14 +571,14 @@ void show_scroll_win(WINDOW *main_window,
|
||||||
(void) wattrset(pad, attributes[SCROLLWIN_TEXT]);
|
(void) wattrset(pad, attributes[SCROLLWIN_TEXT]);
|
||||||
fill_window(pad, text);
|
fill_window(pad, text);
|
||||||
|
|
||||||
win_lines = min(total_lines+4, LINES-2);
|
win_lines = min(total_lines+4, lines-2);
|
||||||
win_cols = min(total_cols+2, COLS-2);
|
win_cols = min(total_cols+2, columns-2);
|
||||||
text_lines = max(win_lines-4, 0);
|
text_lines = max(win_lines-4, 0);
|
||||||
text_cols = max(win_cols-2, 0);
|
text_cols = max(win_cols-2, 0);
|
||||||
|
|
||||||
/* place window in middle of screen */
|
/* place window in middle of screen */
|
||||||
y = (LINES-win_lines)/2;
|
y = (lines-win_lines)/2;
|
||||||
x = (COLS-win_cols)/2;
|
x = (columns-win_cols)/2;
|
||||||
|
|
||||||
win = newwin(win_lines, win_cols, y, x);
|
win = newwin(win_lines, win_cols, y, x);
|
||||||
keypad(win, TRUE);
|
keypad(win, TRUE);
|
||||||
|
|
|
@ -136,7 +136,7 @@ static struct property *sym_get_range_prop(struct symbol *sym)
|
||||||
return NULL;
|
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);
|
sym_calc_value(sym);
|
||||||
switch (sym->type) {
|
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)
|
static void sym_validate_range(struct symbol *sym)
|
||||||
{
|
{
|
||||||
struct property *prop;
|
struct property *prop;
|
||||||
int base, val, val2;
|
long base, val, val2;
|
||||||
char str[64];
|
char str[64];
|
||||||
|
|
||||||
switch (sym->type) {
|
switch (sym->type) {
|
||||||
|
@ -179,9 +179,9 @@ static void sym_validate_range(struct symbol *sym)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (sym->type == S_INT)
|
if (sym->type == S_INT)
|
||||||
sprintf(str, "%d", val2);
|
sprintf(str, "%ld", val2);
|
||||||
else
|
else
|
||||||
sprintf(str, "0x%x", val2);
|
sprintf(str, "0x%lx", val2);
|
||||||
sym->curr.val = strdup(str);
|
sym->curr.val = strdup(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,6 +300,14 @@ void sym_calc_value(struct symbol *sym)
|
||||||
|
|
||||||
if (sym->flags & SYMBOL_VALID)
|
if (sym->flags & SYMBOL_VALID)
|
||||||
return;
|
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;
|
sym->flags |= SYMBOL_VALID;
|
||||||
|
|
||||||
oldval = sym->curr;
|
oldval = sym->curr;
|
||||||
|
@ -425,6 +433,9 @@ void sym_calc_value(struct symbol *sym)
|
||||||
|
|
||||||
if (sym->flags & SYMBOL_AUTO)
|
if (sym->flags & SYMBOL_AUTO)
|
||||||
sym->flags &= ~SYMBOL_WRITE;
|
sym->flags &= ~SYMBOL_WRITE;
|
||||||
|
|
||||||
|
if (sym->flags & SYMBOL_NEED_SET_CHOICE_VALUES)
|
||||||
|
set_all_choice_values(sym);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sym_clear_all_valid(void)
|
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)
|
bool sym_string_within_range(struct symbol *sym, const char *str)
|
||||||
{
|
{
|
||||||
struct property *prop;
|
struct property *prop;
|
||||||
int val;
|
long val;
|
||||||
|
|
||||||
switch (sym->type) {
|
switch (sym->type) {
|
||||||
case S_STRING:
|
case S_STRING:
|
||||||
|
@ -943,38 +954,98 @@ const char *sym_escape_string_value(const char *in)
|
||||||
return res;
|
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_re_search(const char *pattern)
|
||||||
{
|
{
|
||||||
struct symbol *sym, **sym_arr = NULL;
|
struct symbol *sym, **sym_arr = NULL;
|
||||||
|
struct sym_match **sym_match_arr = NULL;
|
||||||
int i, cnt, size;
|
int i, cnt, size;
|
||||||
regex_t re;
|
regex_t re;
|
||||||
|
regmatch_t match[1];
|
||||||
|
|
||||||
cnt = size = 0;
|
cnt = size = 0;
|
||||||
/* Skip if empty */
|
/* Skip if empty */
|
||||||
if (strlen(pattern) == 0)
|
if (strlen(pattern) == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB|REG_ICASE))
|
if (regcomp(&re, pattern, REG_EXTENDED|REG_ICASE))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
for_all_symbols(i, sym) {
|
for_all_symbols(i, sym) {
|
||||||
|
struct sym_match *tmp_sym_match;
|
||||||
if (sym->flags & SYMBOL_CONST || !sym->name)
|
if (sym->flags & SYMBOL_CONST || !sym->name)
|
||||||
continue;
|
continue;
|
||||||
if (regexec(&re, sym->name, 0, NULL, 0))
|
if (regexec(&re, sym->name, 1, match, 0))
|
||||||
continue;
|
continue;
|
||||||
if (cnt + 1 >= size) {
|
if (cnt + 1 >= size) {
|
||||||
void *tmp = sym_arr;
|
void *tmp;
|
||||||
size += 16;
|
size += 16;
|
||||||
sym_arr = realloc(sym_arr, size * sizeof(struct symbol *));
|
tmp = realloc(sym_match_arr, size * sizeof(struct sym_match *));
|
||||||
if (!sym_arr) {
|
if (!tmp) {
|
||||||
free(tmp);
|
goto sym_re_search_free;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
sym_match_arr = tmp;
|
||||||
}
|
}
|
||||||
sym_calc_value(sym);
|
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_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);
|
regfree(&re);
|
||||||
|
|
||||||
return sym_arr;
|
return sym_arr;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче