2013-04-16 17:43:28

by Yann E. MORIN

[permalink] [raw]
Subject: [PATCH 0/4] Some kconfig improvements and fixes

Michal, All,

Here is a short series with a few kconfig improvements and fixes:
- fix in ncurses headers location
- fix randconfig always selecting the first entry of a choice
- enhance randconfig with user-suplied seed and/or probability

I'm posting this series for review before I send Michal a final
pull-request before the merge window opens for 3.10.

[PATCH 1/4] kconfig/lxdialog: rationalise the include paths where to find {.n}curses{,w}.h
[PATCH 2/4] kconfig: allow specifying the seed for randconfig
[PATCH 3/4] kconfig: implement KCONFIG_PROBABILITY for randconfig
[PATCH 4/4] kconfig: do randomise choice entries in presence of KCONFIG_ALLCONFIG

Regards,
Yann E. MORIN.


2013-04-16 17:43:31

by Yann E. MORIN

[permalink] [raw]
Subject: [PATCH 1/4] kconfig/lxdialog: rationalise the include paths where to find {.n}curses{,w}.h

The current code does this:

if [ -f /usr/include/ncursesw/curses.h ]; then
echo '-I/usr/include/ncursesw -DCURSES_LOC="<ncursesw/curses.h>"'
elif [ -f /usr/include/ncurses/ncurses.h ]; then
echo '-I/usr/include/ncurses -DCURSES_LOC="<ncurses.h>"'
elif [ -f /usr/include/ncurses/curses.h ]; then
echo '-I/usr/include/ncurses -DCURSES_LOC="<ncurses/curses.h>"'
[...]

This is merely inconsistent:
- adding the full path to the directory in the -I directive,
- especially since that path is already a sub-path of the system
include path,
- and then repeating the sub-path in the #include directive.

Rationalise each include directive:
- only use the filename in the #include directive,
- keep the -I directives: they are always searched for before the
system include path; this ensures the correct header is used.

Using the -I directives and the filename-only in #include is more in
line with how pkg-config behaves, eg.:
$ pkg-config --cflags ncursesw
-I/usr/include/ncursesw

This paves the way for using pkg-config for CFLAGS, too, now we use it
to find the libraries.

Signed-off-by: "Yann E. MORIN" <[email protected]>
---
scripts/kconfig/lxdialog/check-lxdialog.sh | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/scripts/kconfig/lxdialog/check-lxdialog.sh b/scripts/kconfig/lxdialog/check-lxdialog.sh
index 782d200..9d2a4c5 100644
--- a/scripts/kconfig/lxdialog/check-lxdialog.sh
+++ b/scripts/kconfig/lxdialog/check-lxdialog.sh
@@ -22,12 +22,12 @@ ldflags()
ccflags()
{
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'
elif [ -f /usr/include/ncurses/ncurses.h ]; then
echo '-I/usr/include/ncurses -DCURSES_LOC="<ncurses.h>"'
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
echo '-DCURSES_LOC="<ncurses.h>"'
else
--
1.7.2.5

2013-04-16 17:43:36

by Yann E. MORIN

[permalink] [raw]
Subject: [PATCH 3/4] kconfig: implement KCONFIG_PROBABILITY for randconfig

Introduce a KCONFIG_PROBABILITY environment variable to tweak the
probability between 0 (all options off) and 100 (all options on).

[Patch originally written by Peter for Buildroot, see: ]
[http://git.buildroot.org/buildroot/commit/?id=3435c1afb5 ]

Signed-off-by: Peter Korsgaard <[email protected]>
[[email protected]: add to Documentation/]
Signed-off-by: "Yann E. MORIN" <[email protected]>
---
Documentation/kbuild/kconfig.txt | 17 +++++++++++++++++
scripts/kconfig/confdata.c | 22 +++++++++++++++++++---
2 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/Documentation/kbuild/kconfig.txt b/Documentation/kbuild/kconfig.txt
index dbf746b..1817128 100644
--- a/Documentation/kbuild/kconfig.txt
+++ b/Documentation/kbuild/kconfig.txt
@@ -98,6 +98,23 @@ 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
+--------------------------------------------------
+If this variable is set and contains an integer in the range [0,100],
+then its value is used as a probability each variable is set. If the
+variable is a tristate, there is then a further 50% chance it is set
+to either 'M' or 'Y'. If KCONFIG_PROBABILITY is not set, then the
+default is 50. Examples (rounded figures):
+ KCONFIG_PROBABILITY=33
+ boolean : no : 67% yes: 33%
+ tristrate : no : 67% mod: 16% yes: 16%
+ KCONFIG_PROBABILITY=50
+ boolean : no : 50% yes: 50%
+ tristate : no : 50% mod: 25% yes: 25%
+ KCONFIG_PROBABILITY=67
+ boolean : no : 33% yes: 67%
+ tristrate : no : 33% mod: 33% yes: 33%
+
______________________________________________________________________
Environment variables for 'silentoldconfig'

diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index 13ddf11..8d8d853 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -1106,7 +1106,16 @@ static void set_all_choice_values(struct symbol *csym)
void conf_set_all_new_symbols(enum conf_def_mode mode)
{
struct symbol *sym, *csym;
- int i, cnt;
+ int i, cnt, prob = 50;
+
+ if (mode == def_random) {
+ char *endp, *env = getenv("KCONFIG_PROBABILITY");
+ if (env && *env) {
+ int tmp = (int)strtol(env, &endp, 10);
+ if (*endp == '\0' && tmp >= 0 && tmp <= 100)
+ prob = tmp;
+ }
+ }

for_all_symbols(i, sym) {
if (sym_has_value(sym))
@@ -1125,8 +1134,15 @@ void conf_set_all_new_symbols(enum conf_def_mode mode)
sym->def[S_DEF_USER].tri = no;
break;
case def_random:
- cnt = sym_get_type(sym) == S_TRISTATE ? 3 : 2;
- sym->def[S_DEF_USER].tri = (tristate)(rand() % cnt);
+ cnt = (rand() % 100) - (100 - prob);
+ if (cnt < 0)
+ sym->def[S_DEF_USER].tri = no;
+ else
+ if ((sym_get_type(sym) == S_TRISTATE)
+ && (cnt > prob/2))
+ sym->def[S_DEF_USER].tri = mod;
+ else
+ sym->def[S_DEF_USER].tri = yes;
break;
default:
continue;
--
1.7.2.5

2013-04-16 17:43:48

by Yann E. MORIN

[permalink] [raw]
Subject: [PATCH 4/4] kconfig: do randomise choice entries in presence of KCONFIG_ALLCONFIG

Currently, randconfig does randomise choice entries, unless KCONFIG_ALLCONFIG
is specified.

For example, given those two files (Thomas' test-case):

---8<--- Config.test.in
config OPTIONA
bool "Option A"

choice
prompt "This is a choice"

config CHOICE_OPTIONA
bool "Choice Option A"

config CHOICE_OPTIONB
bool "Choice Option B"

endchoice

config OPTIONB
bool "Option B"
---8<--- Config.test.in

---8<--- config.defaults
CONFIG_OPTIONA=y
---8<--- config.defaults

And running:
./scripts/kconfig/conf --randconfig Config.test.in

does properly randomise the two choice symbols (and the two booleans).

However, running:
KCONFIG_ALLCONFIG=config.defaults \
./scripts/kconfig/conf --randconfig Config.test.in

does *not* reandomise the two choice entries, and only CHOICE_OPTIONA
will ever be selected. (OPTIONA will always be set (expected), and
OPTIONB will be be properly randomised (expected).)

This patch defers setting that a choice has a value until a symbol for
that choice is indeed set, so that choices are properly randomised when
KCONFIG_ALLCONFIG is set, but not if a symbol for that choice is set.

Also, as a side-efect, this patch fixes the following case:

---8<---
choice
config OPTION_A
bool "Option A"
config OPTION_B
bool "Option B"
config OPTION_C
bool "Option C"
endchoice
---8<---

which could previously generate such .config files:

---8<--- ---8<---
CONFIG_OPTION_A=y CONFIG_OPTION_A=y
CONFIG_OPTION_B=y # CONFIG_OPTION_B is not set
# CONFIG_OPTION_C is not set CONFIG_OPTION_C=y
---8<--- ---8<---

Ie., the first entry in a choice is always set, plus zero or one of
the other options may be set.

This patch ensures that only one option may be set for a choice.

Reported-by: Thomas Petazzoni <[email protected]>
Signed-off-by: "Yann E. MORIN" <[email protected]>
Cc: Thomas Petazzoni <[email protected]>
Cc: Michal Marek <[email protected]>
Cc: Sam Ravnborg <[email protected]>
Cc: Arnaud Lacombe <[email protected]>

---
Changes v2 -> v3
- ensure only one symbol is set in a choice

Changes v1 -> v2:
- further postpone setting that a choice has a value until
one is indeed set
- do not print symbols that are part of an invisible choice
---
scripts/kconfig/confdata.c | 7 ++++---
1 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index 8d8d853..5487279 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -288,8 +288,6 @@ load:
for_all_symbols(i, sym) {
sym->flags |= SYMBOL_CHANGED;
sym->flags &= ~(def_flags|SYMBOL_VALID);
- if (sym_is_choice(sym))
- sym->flags |= def_flags;
switch (sym->type) {
case S_INT:
case S_HEX:
@@ -379,13 +377,13 @@ setsym:
case mod:
if (cs->def[def].tri == yes) {
conf_warning("%s creates inconsistent choice state", sym->name);
- cs->flags &= ~def_flags;
}
break;
case yes:
if (cs->def[def].tri != no)
conf_warning("override: %s changes choice state", sym->name);
cs->def[def].val = sym;
+ cs->flags |= def_flags;
break;
}
cs->def[def].tri = EXPR_OR(cs->def[def].tri, sym->def[def].tri);
@@ -791,6 +789,8 @@ int conf_write(const char *name)
sym_calc_value(sym);
if (!(sym->flags & SYMBOL_WRITE))
goto next;
+ if (sym_is_choice_value(sym) && !menu_is_visible(menu->parent))
+ goto next;
sym->flags &= ~SYMBOL_WRITE;

conf_write_symbol(out, sym, &kconfig_printer_cb, NULL);
@@ -1077,6 +1077,7 @@ static void randomize_choice_values(struct symbol *csym)
else {
sym->def[S_DEF_USER].tri = no;
}
+ sym->flags &= ~(SYMBOL_VALID);
}
csym->flags |= SYMBOL_DEF_USER;
/* clear VALID to get value calculated */
--
1.7.2.5

2013-04-16 17:44:09

by Yann E. MORIN

[permalink] [raw]
Subject: [PATCH 2/4] kconfig: allow specifying the seed for randconfig

For reproducibility, it can be useful to be able to specify the
seed to use to seed the RNG.

Add a new KCONFIG_SEED environment variable which can be set to
the seed to use:
$ make KCONFIG_SEED=42 randconfig
$ sha1sum .config
70a128c8dcc61303069e1be352cce64114dfcbca .config
$ make KCONFIG_SEED=42 randconfig
$ sha1sum .config
70a128c8dcc61303069e1be352cce64114dfcbca .config

It's very usefull for eg. debugging the kconfig parser.

Signed-off-by: "Yann E. MORIN" <[email protected]>
---
Documentation/kbuild/kconfig.txt | 9 +++++++++
scripts/kconfig/conf.c | 12 +++++++++++-
2 files changed, 20 insertions(+), 1 deletions(-)

diff --git a/Documentation/kbuild/kconfig.txt b/Documentation/kbuild/kconfig.txt
index b8b77bb..dbf746b 100644
--- a/Documentation/kbuild/kconfig.txt
+++ b/Documentation/kbuild/kconfig.txt
@@ -90,6 +90,15 @@ disable the options that are explicitly listed in the specified
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.
+
+______________________________________________________________________
Environment variables for 'silentoldconfig'

KCONFIG_NOSILENTUPDATE
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c
index e39fcd8..bde5b95 100644
--- a/scripts/kconfig/conf.c
+++ b/scripts/kconfig/conf.c
@@ -13,6 +13,7 @@
#include <getopt.h>
#include <sys/stat.h>
#include <sys/time.h>
+#include <errno.h>

#include "lkc.h"

@@ -514,14 +515,23 @@ int main(int ac, char **av)
{
struct timeval now;
unsigned int seed;
+ char *seed_env;

/*
* Use microseconds derived seed,
* compensate for systems where it may be zero
*/
gettimeofday(&now, NULL);
-
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);
break;
}
--
1.7.2.5