Commit 685e56d2 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull kconfig updates from Michal Marek:
 - use pkg-config to detect curses libraries
 - clean up the way curses headers are searched
 - Some randconfig fixes, of which one had to be reverted
 - KCONFIG_SEED for randconfig debugging
 - memuconfig memory leak plugged
 - menuconfig > breadcrumbs > navigation
 - xconfig compilation fix
 - Other minor fixes

* 'kconfig' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild:
  kconfig: fix lists definition for C++
  Revert "kconfig: fix randomising choice entries in presence of KCONFIG_ALLCONFIG"
  kconfig: implement KCONFIG_PROBABILITY for randconfig
  kconfig: allow specifying the seed for randconfig
  kconfig: fix randomising choice entries in presence of KCONFIG_ALLCONFIG
  kconfig: do not override symbols already set
  kconfig: fix randconfig tristate detection
  kconfig/lxdialog: rationalise the include paths where to find {.n}curses{,w}.h
  menuconfig: Add "breadcrumbs" navigation aid
  menuconfig: Fix memory leak introduced by jump keys feature
  merge_config.sh: Avoid creating unnessary source softlinks
  kconfig: optionally use pkg-config to detect ncurses libs
  menuconfig: optionally use pkg-config to detect ncurses libs
parents 57c29bd3 21ca352b
...@@ -89,6 +89,42 @@ These examples will disable most options (allnoconfig) but enable or ...@@ -89,6 +89,42 @@ These examples will disable most options (allnoconfig) but enable or
disable the options that are explicitly listed in the specified disable the options that are explicitly listed in the specified
mini-config files. mini-config files.
______________________________________________________________________
Environment variables for 'randconfig'
KCONFIG_SEED
--------------------------------------------------
You can set this to the integer value used to seed the RNG, if you want
to somehow debug the behaviour of the kconfig parser/frontends.
If not set, the current time will be used.
KCONFIG_PROBABILITY
--------------------------------------------------
This variable can be used to skew the probabilities. This variable can
be unset or empty, or set to three different formats:
KCONFIG_PROBABILITY y:n split y:m:n split
-----------------------------------------------------------------
unset or empty 50 : 50 33 : 33 : 34
N N : 100-N N/2 : N/2 : 100-N
[1] N:M N+M : 100-(N+M) N : M : 100-(N+M)
[2] N:M:L N : 100-N M : L : 100-(M+L)
where N, M and L are integers (in base 10) in the range [0,100], and so
that:
[1] N+M is in the range [0,100]
[2] M+L is in the range [0,100]
Examples:
KCONFIG_PROBABILITY=10
10% of booleans will be set to 'y', 90% to 'n'
5% of tristates will be set to 'y', 5% to 'm', 90% to 'n'
KCONFIG_PROBABILITY=15:25
40% of booleans will be set to 'y', 60% to 'n'
15% of tristates will be set to 'y', 25% to 'm', 60% to 'n'
KCONFIG_PROBABILITY=10:15:15
10% of booleans will be set to 'y', 90% to 'n'
15% of tristates will be set to 'y', 15% to 'm', 70% to 'n'
______________________________________________________________________ ______________________________________________________________________
Environment variables for 'silentoldconfig' Environment variables for 'silentoldconfig'
......
...@@ -219,7 +219,9 @@ HOSTCFLAGS_gconf.o = `pkg-config --cflags gtk+-2.0 gmodule-2.0 libglade-2.0` \ ...@@ -219,7 +219,9 @@ HOSTCFLAGS_gconf.o = `pkg-config --cflags gtk+-2.0 gmodule-2.0 libglade-2.0` \
HOSTLOADLIBES_mconf = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC)) HOSTLOADLIBES_mconf = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC))
HOSTLOADLIBES_nconf = -lmenu -lpanel -lncurses HOSTLOADLIBES_nconf = $(shell \
pkg-config --libs menu panel ncurses 2>/dev/null \
|| echo "-lmenu -lpanel -lncurses" )
$(obj)/qconf.o: $(obj)/.tmp_qtcheck $(obj)/qconf.o: $(obj)/.tmp_qtcheck
ifeq ($(qconf-target),1) ifeq ($(qconf-target),1)
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <getopt.h> #include <getopt.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/time.h> #include <sys/time.h>
#include <errno.h>
#include "lkc.h" #include "lkc.h"
...@@ -514,14 +515,23 @@ int main(int ac, char **av) ...@@ -514,14 +515,23 @@ int main(int ac, char **av)
{ {
struct timeval now; struct timeval now;
unsigned int seed; unsigned int seed;
char *seed_env;
/* /*
* Use microseconds derived seed, * Use microseconds derived seed,
* compensate for systems where it may be zero * compensate for systems where it may be zero
*/ */
gettimeofday(&now, NULL); gettimeofday(&now, NULL);
seed = (unsigned int)((now.tv_sec + 1) * (now.tv_usec + 1)); seed = (unsigned int)((now.tv_sec + 1) * (now.tv_usec + 1));
seed_env = getenv("KCONFIG_SEED");
if( seed_env && *seed_env ) {
char *endp;
int tmp = (int)strtol(seed_env, &endp, 10);
if (*endp == '\0') {
seed = tmp;
}
}
srand(seed); srand(seed);
break; break;
} }
......
...@@ -1106,10 +1106,54 @@ static void set_all_choice_values(struct symbol *csym) ...@@ -1106,10 +1106,54 @@ static void set_all_choice_values(struct symbol *csym)
void conf_set_all_new_symbols(enum conf_def_mode mode) void conf_set_all_new_symbols(enum conf_def_mode mode)
{ {
struct symbol *sym, *csym; struct symbol *sym, *csym;
int i, cnt; int i, cnt, pby, pty, ptm; /* pby: probability of boolean = y
* pty: probability of tristate = y
* ptm: probability of tristate = m
*/
pby = 50; pty = ptm = 33; /* can't go as the default in switch-case
* below, otherwise gcc whines about
* -Wmaybe-uninitialized */
if (mode == def_random) {
int n, p[3];
char *env = getenv("KCONFIG_PROBABILITY");
n = 0;
while( env && *env ) {
char *endp;
int tmp = strtol( env, &endp, 10 );
if( tmp >= 0 && tmp <= 100 ) {
p[n++] = tmp;
} else {
errno = ERANGE;
perror( "KCONFIG_PROBABILITY" );
exit( 1 );
}
env = (*endp == ':') ? endp+1 : endp;
if( n >=3 ) {
break;
}
}
switch( n ) {
case 1:
pby = p[0]; ptm = pby/2; pty = pby-ptm;
break;
case 2:
pty = p[0]; ptm = p[1]; pby = pty + ptm;
break;
case 3:
pby = p[0]; pty = p[1]; ptm = p[2];
break;
}
if( pty+ptm > 100 ) {
errno = ERANGE;
perror( "KCONFIG_PROBABILITY" );
exit( 1 );
}
}
for_all_symbols(i, sym) { for_all_symbols(i, sym) {
if (sym_has_value(sym)) if (sym_has_value(sym) || (sym->flags & SYMBOL_VALID))
continue; continue;
switch (sym_get_type(sym)) { switch (sym_get_type(sym)) {
case S_BOOLEAN: case S_BOOLEAN:
...@@ -1125,8 +1169,15 @@ void conf_set_all_new_symbols(enum conf_def_mode mode) ...@@ -1125,8 +1169,15 @@ void conf_set_all_new_symbols(enum conf_def_mode mode)
sym->def[S_DEF_USER].tri = no; sym->def[S_DEF_USER].tri = no;
break; break;
case def_random: case def_random:
cnt = sym_get_type(sym) == S_TRISTATE ? 3 : 2; sym->def[S_DEF_USER].tri = no;
sym->def[S_DEF_USER].tri = (tristate)(rand() % cnt); cnt = rand() % 100;
if (sym->type == S_TRISTATE) {
if (cnt < pty)
sym->def[S_DEF_USER].tri = yes;
else if (cnt < (pty+ptm))
sym->def[S_DEF_USER].tri = mod;
} else if (cnt < pby)
sym->def[S_DEF_USER].tri = yes;
break; break;
default: default:
continue; continue;
......
...@@ -50,6 +50,19 @@ struct list_head { ...@@ -50,6 +50,19 @@ struct list_head {
&pos->member != (head); \ &pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member)) pos = list_entry(pos->member.next, typeof(*pos), member))
/**
* list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
* @pos: the type * to use as a loop cursor.
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry_safe(pos, n, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member), \
n = list_entry(pos->member.next, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.next, typeof(*n), member))
/** /**
* list_empty - tests whether a list is empty * list_empty - tests whether a list is empty
* @head: the list to test. * @head: the list to test.
...@@ -88,4 +101,31 @@ static inline void list_add_tail(struct list_head *_new, struct list_head *head) ...@@ -88,4 +101,31 @@ static inline void list_add_tail(struct list_head *_new, struct list_head *head)
__list_add(_new, head->prev, head); __list_add(_new, head->prev, head);
} }
/*
* Delete a list entry by making the prev/next entries
* point to each other.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_del(struct list_head *prev, struct list_head *next)
{
next->prev = prev;
prev->next = next;
}
#define LIST_POISON1 ((void *) 0x00100100)
#define LIST_POISON2 ((void *) 0x00200200)
/**
* list_del - deletes entry from list.
* @entry: the element to delete from the list.
* Note: list_empty() on entry does not return true after this, the entry is
* in an undefined state.
*/
static inline void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
entry->next = (struct list_head*)LIST_POISON1;
entry->prev = (struct list_head*)LIST_POISON2;
}
#endif #endif
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
# What library to link # What library to link
ldflags() ldflags()
{ {
pkg-config --libs ncursesw 2>/dev/null && exit
pkg-config --libs ncurses 2>/dev/null && exit
for ext in so a dll.a dylib ; do for ext in so a dll.a dylib ; do
for lib in ncursesw ncurses curses ; do for lib in ncursesw ncurses curses ; do
$cc -print-file-name=lib${lib}.${ext} | grep -q / $cc -print-file-name=lib${lib}.${ext} | grep -q /
...@@ -20,12 +22,12 @@ ldflags() ...@@ -20,12 +22,12 @@ ldflags()
ccflags() ccflags()
{ {
if [ -f /usr/include/ncursesw/curses.h ]; then if [ -f /usr/include/ncursesw/curses.h ]; then
echo '-I/usr/include/ncursesw -DCURSES_LOC="<ncursesw/curses.h>"' echo '-I/usr/include/ncursesw -DCURSES_LOC="<curses.h>"'
echo ' -DNCURSES_WIDECHAR=1' echo ' -DNCURSES_WIDECHAR=1'
elif [ -f /usr/include/ncurses/ncurses.h ]; then elif [ -f /usr/include/ncurses/ncurses.h ]; then
echo '-I/usr/include/ncurses -DCURSES_LOC="<ncurses.h>"' echo '-I/usr/include/ncurses -DCURSES_LOC="<ncurses.h>"'
elif [ -f /usr/include/ncurses/curses.h ]; then elif [ -f /usr/include/ncurses/curses.h ]; then
echo '-I/usr/include/ncurses -DCURSES_LOC="<ncurses/curses.h>"' echo '-I/usr/include/ncurses -DCURSES_LOC="<curses.h>"'
elif [ -f /usr/include/ncurses.h ]; then elif [ -f /usr/include/ncurses.h ]; then
echo '-DCURSES_LOC="<ncurses.h>"' echo '-DCURSES_LOC="<ncurses.h>"'
else else
......
...@@ -106,8 +106,14 @@ struct dialog_color { ...@@ -106,8 +106,14 @@ struct dialog_color {
int hl; /* highlight this item */ int hl; /* highlight this item */
}; };
struct subtitle_list {
struct subtitle_list *next;
const char *text;
};
struct dialog_info { struct dialog_info {
const char *backtitle; const char *backtitle;
struct subtitle_list *subtitles;
struct dialog_color screen; struct dialog_color screen;
struct dialog_color shadow; struct dialog_color shadow;
struct dialog_color dialog; struct dialog_color dialog;
...@@ -196,6 +202,7 @@ int on_key_resize(void); ...@@ -196,6 +202,7 @@ int on_key_resize(void);
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 end_dialog(int x, int y); void end_dialog(int x, int y);
void attr_clear(WINDOW * win, int height, int width, chtype attr); void attr_clear(WINDOW * win, int height, int width, chtype attr);
void dialog_clear(void); void dialog_clear(void);
......
...@@ -257,12 +257,48 @@ void dialog_clear(void) ...@@ -257,12 +257,48 @@ void dialog_clear(void)
attr_clear(stdscr, LINES, COLS, dlg.screen.atr); attr_clear(stdscr, LINES, COLS, 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; int i, len = 0, skip = 0;
struct subtitle_list *pos;
wattrset(stdscr, dlg.screen.atr); wattrset(stdscr, dlg.screen.atr);
mvwaddstr(stdscr, 0, 1, (char *)dlg.backtitle); mvwaddstr(stdscr, 0, 1, (char *)dlg.backtitle);
for (pos = dlg.subtitles; pos != NULL; pos = pos->next) {
/* 3 is for the arrow and spaces */
len += strlen(pos->text) + 3;
}
wmove(stdscr, 1, 1); wmove(stdscr, 1, 1);
for (i = 1; i < COLS - 1; i++) if (len > COLS - 2) {
const char *ellipsis = "[...] ";
waddstr(stdscr, ellipsis);
skip = len - (COLS - 2 - strlen(ellipsis));
}
for (pos = dlg.subtitles; pos != NULL; pos = pos->next) {
if (skip == 0)
waddch(stdscr, ACS_RARROW);
else
skip--;
if (skip == 0)
waddch(stdscr, ' ');
else
skip--;
if (skip < strlen(pos->text)) {
waddstr(stdscr, pos->text + skip);
skip = 0;
} else
skip -= strlen(pos->text);
if (skip == 0)
waddch(stdscr, ' ');
else
skip--;
}
for (i = len + 1; i < COLS - 1; i++)
waddch(stdscr, ACS_HLINE); waddch(stdscr, ACS_HLINE);
} }
wnoutrefresh(stdscr); wnoutrefresh(stdscr);
...@@ -302,6 +338,11 @@ void set_dialog_backtitle(const char *backtitle) ...@@ -302,6 +338,11 @@ void set_dialog_backtitle(const char *backtitle)
dlg.backtitle = backtitle; dlg.backtitle = backtitle;
} }
void set_dialog_subtitles(struct subtitle_list *subtitles)
{
dlg.subtitles = subtitles;
}
/* /*
* End using dialog functions. * End using dialog functions.
*/ */
......
...@@ -311,6 +311,50 @@ static void set_config_filename(const char *config_filename) ...@@ -311,6 +311,50 @@ static void set_config_filename(const char *config_filename)
filename[sizeof(filename)-1] = '\0'; filename[sizeof(filename)-1] = '\0';
} }
struct subtitle_part {
struct list_head entries;
const char *text;
};
static LIST_HEAD(trail);
static struct subtitle_list *subtitles;
static void set_subtitle(void)
{
struct subtitle_part *sp;
struct subtitle_list *pos, *tmp;
for (pos = subtitles; pos != NULL; pos = tmp) {
tmp = pos->next;
free(pos);
}
subtitles = NULL;
list_for_each_entry(sp, &trail, entries) {
if (sp->text) {
if (pos) {
pos->next = xcalloc(sizeof(*pos), 1);
pos = pos->next;
} else {
subtitles = pos = xcalloc(sizeof(*pos), 1);
}
pos->text = sp->text;
}
}
set_dialog_subtitles(subtitles);
}
static void reset_subtitle(void)
{
struct subtitle_list *pos, *tmp;
for (pos = subtitles; pos != NULL; pos = tmp) {
tmp = pos->next;
free(pos);
}
subtitles = NULL;
set_dialog_subtitles(subtitles);
}
struct search_data { struct search_data {
struct list_head *head; struct list_head *head;
...@@ -353,6 +397,8 @@ static void search_conf(void) ...@@ -353,6 +397,8 @@ static void search_conf(void)
char *dialog_input; char *dialog_input;
int dres, vscroll = 0, hscroll = 0; int dres, vscroll = 0, hscroll = 0;
bool again; bool again;
struct gstr sttext;
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 to search for "
...@@ -379,6 +425,11 @@ static void search_conf(void) ...@@ -379,6 +425,11 @@ static void search_conf(void)
if (strncasecmp(dialog_input_result, CONFIG_, strlen(CONFIG_)) == 0) if (strncasecmp(dialog_input_result, CONFIG_, strlen(CONFIG_)) == 0)
dialog_input += strlen(CONFIG_); dialog_input += strlen(CONFIG_);
sttext = str_new();
str_printf(&sttext, "Search (%s)", dialog_input_result);
stpart.text = str_get(&sttext);
list_add_tail(&stpart.entries, &trail);
sym_arr = sym_re_search(dialog_input); sym_arr = sym_re_search(dialog_input);
do { do {
LIST_HEAD(head); LIST_HEAD(head);
...@@ -389,8 +440,10 @@ static void search_conf(void) ...@@ -389,8 +440,10 @@ static void search_conf(void)
.targets = targets, .targets = targets,
.keys = keys, .keys = keys,
}; };
struct jump_key *pos, *tmp;
res = get_relations_str(sym_arr, &head); res = get_relations_str(sym_arr, &head);
set_subtitle();
dres = show_textbox_ext(_("Search Results"), (char *) dres = show_textbox_ext(_("Search Results"), (char *)
str_get(&res), 0, 0, keys, &vscroll, str_get(&res), 0, 0, keys, &vscroll,
&hscroll, &update_text, (void *) &hscroll, &update_text, (void *)
...@@ -402,9 +455,13 @@ static void search_conf(void) ...@@ -402,9 +455,13 @@ static void search_conf(void)
again = true; again = true;
} }
str_free(&res); str_free(&res);
list_for_each_entry_safe(pos, tmp, &head, entries)
free(pos);
} while (again); } while (again);
free(sym_arr); free(sym_arr);
str_free(&title); str_free(&title);
list_del(trail.prev);
str_free(&sttext);
} }
static void build_conf(struct menu *menu) static void build_conf(struct menu *menu)
...@@ -589,16 +646,24 @@ static void conf(struct menu *menu, struct menu *active_menu) ...@@ -589,16 +646,24 @@ static void conf(struct menu *menu, struct menu *active_menu)
{ {
struct menu *submenu; struct menu *submenu;
const char *prompt = menu_get_prompt(menu); const char *prompt = menu_get_prompt(menu);
struct subtitle_part stpart;
struct symbol *sym; struct symbol *sym;
int res; int res;
int s_scroll = 0; int s_scroll = 0;
if (menu != &rootmenu)
stpart.text = menu_get_prompt(menu);
else
stpart.text = NULL;
list_add_tail(&stpart.entries, &trail);
while (1) { while (1) {
item_reset(); item_reset();
current_menu = menu; current_menu = menu;
build_conf(menu); build_conf(menu);
if (!child_count) if (!child_count)
break; break;
set_subtitle();
dialog_clear(); dialog_clear();
res = dialog_menu(prompt ? _(prompt) : _("Main Menu"), res = dialog_menu(prompt ? _(prompt) : _("Main Menu"),
_(menu_instructions), _(menu_instructions),
...@@ -640,13 +705,17 @@ static void conf(struct menu *menu, struct menu *active_menu) ...@@ -640,13 +705,17 @@ static void conf(struct menu *menu, struct menu *active_menu)
case 2: case 2:
if (sym) if (sym)
show_help(submenu); show_help(submenu);
else else {
reset_subtitle();
show_helptext(_("README"), _(mconf_readme)); show_helptext(_("README"), _(mconf_readme));
}
break; break;
case 3: case 3:
reset_subtitle();
conf_save(); conf_save();
break; break;
case 4: case 4:
reset_subtitle();
conf_load(); conf_load();
break; break;
case 5: case 5:
...@@ -679,6 +748,8 @@ static void conf(struct menu *menu, struct menu *active_menu) ...@@ -679,6 +748,8 @@ static void conf(struct menu *menu, struct menu *active_menu)
break; break;
} }
} }
list_del(trail.prev);
} }
static int show_textbox_ext(const char *title, char *text, int r, int c, int static int show_textbox_ext(const char *title, char *text, int r, int c, int
...@@ -881,6 +952,7 @@ static int handle_exit(void) ...@@ -881,6 +952,7 @@ static int handle_exit(void)
int res; int res;
save_and_exit = 1; save_and_exit = 1;
reset_subtitle();
dialog_clear(); dialog_clear();
if (conf_get_changed()) if (conf_get_changed())
res = dialog_yesno(NULL, res = dialog_yesno(NULL,
......
...@@ -120,10 +120,18 @@ if [ "$MAKE" = "false" ]; then ...@@ -120,10 +120,18 @@ if [ "$MAKE" = "false" ]; then
exit exit
fi fi
# If we have an output dir, setup the O= argument, otherwise leave
# it blank, since O=. will create an unnecessary ./source softlink
OUTPUT_ARG=""
if [ "$OUTPUT" != "." ] ; then
OUTPUT_ARG="O=$OUTPUT"
fi
# Use the merged file as the starting point for: # Use the merged file as the starting point for:
# alldefconfig: Fills in any missing symbols with Kconfig default # alldefconfig: Fills in any missing symbols with Kconfig default
# allnoconfig: Fills in any missing symbols with # CONFIG_* is not set # allnoconfig: Fills in any missing symbols with # CONFIG_* is not set
make KCONFIG_ALLCONFIG=$TMP_FILE O=$OUTPUT $ALLTARGET make KCONFIG_ALLCONFIG=$TMP_FILE $OUTPUT_ARG $ALLTARGET
# Check all specified config values took (might have missed-dependency issues) # Check all specified config values took (might have missed-dependency issues)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment