summaryrefslogtreecommitdiff
path: root/scripts/kconfig
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/kconfig')
-rw-r--r--scripts/kconfig/conf.c19
-rw-r--r--scripts/kconfig/confdata.c6
-rwxr-xr-xscripts/kconfig/kconfig-sym-check.pl2
-rw-r--r--scripts/kconfig/lexer.l3
-rw-r--r--scripts/kconfig/lkc.h2
-rw-r--r--scripts/kconfig/lkc_proto.h1
-rw-r--r--scripts/kconfig/lxdialog/textbox.c2
-rw-r--r--scripts/kconfig/menu.c66
-rw-r--r--scripts/kconfig/parser.y8
-rwxr-xr-xscripts/kconfig/streamline_config.pl20
-rw-r--r--scripts/kconfig/symbol.c106
-rw-r--r--scripts/kconfig/tests/conftest.py27
-rw-r--r--scripts/kconfig/tests/def_type/Kconfig28
-rw-r--r--scripts/kconfig/tests/def_type/__init__.py18
-rw-r--r--scripts/kconfig/tests/def_type/expected_guard_n9
-rw-r--r--scripts/kconfig/tests/def_type/expected_guard_y11
-rw-r--r--scripts/kconfig/tests/def_type/guard_n.config1
-rw-r--r--scripts/kconfig/tests/def_type/guard_y.config1
-rw-r--r--scripts/kconfig/tests/err_num_bounds/Kconfig79
-rw-r--r--scripts/kconfig/tests/err_num_bounds/__init__.py12
-rw-r--r--scripts/kconfig/tests/err_num_bounds/expected_stderr10
-rw-r--r--scripts/kconfig/tests/err_num_mismatch/Kconfig38
-rw-r--r--scripts/kconfig/tests/err_num_mismatch/__init__.py9
-rw-r--r--scripts/kconfig/tests/err_num_mismatch/expected_stderr4
-rw-r--r--scripts/kconfig/tests/err_num_non_numeric_ref/Kconfig75
-rw-r--r--scripts/kconfig/tests/err_num_non_numeric_ref/__init__.py9
-rw-r--r--scripts/kconfig/tests/err_num_non_numeric_ref/expected_stderr16
-rw-r--r--scripts/kconfig/tests/err_recursive_dep/Kconfig24
-rw-r--r--scripts/kconfig/tests/err_recursive_dep/expected_stderr13
-rw-r--r--scripts/kconfig/tests/randconfig_probability/Kconfig12
-rw-r--r--scripts/kconfig/tests/randconfig_probability/__init__.py130
-rw-r--r--scripts/kconfig/tests/savedefconfig_range/Kconfig67
-rw-r--r--scripts/kconfig/tests/savedefconfig_range/__init__.py8
-rw-r--r--scripts/kconfig/tests/savedefconfig_range/config8
-rw-r--r--scripts/kconfig/tests/savedefconfig_range/expected_defconfig0
-rw-r--r--scripts/kconfig/tests/warn_changed_input/Kconfig5
-rw-r--r--scripts/kconfig/tests/warn_changed_input/__init__.py21
-rw-r--r--scripts/kconfig/tests/warn_changed_input/expected_config1
-rw-r--r--scripts/kconfig/tests/warn_num_bounds/Kconfig24
-rw-r--r--scripts/kconfig/tests/warn_num_bounds/__init__.py25
-rw-r--r--scripts/kconfig/tests/warn_num_bounds/config7
-rw-r--r--scripts/kconfig/tests/warn_num_bounds/expected_config11
-rw-r--r--scripts/kconfig/tests/warn_num_bounds/expected_config_stderr3
-rw-r--r--scripts/kconfig/tests/warn_num_bounds/expected_frontend_config11
-rw-r--r--scripts/kconfig/tests/warn_num_bounds/expected_frontend_stderr0
45 files changed, 882 insertions, 70 deletions
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c
index fe8ba09b0039..31c6fd25e6ec 100644
--- a/scripts/kconfig/conf.c
+++ b/scripts/kconfig/conf.c
@@ -186,12 +186,23 @@ static void conf_set_all_new_symbols(enum conf_def_mode mode)
if (mode == def_random) {
int n, p[3];
+ bool warned = false;
char *env = getenv("KCONFIG_PROBABILITY");
n = 0;
while (env && *env) {
char *endp;
- int tmp = strtol(env, &endp, 10);
+ long tmp = strtol(env, &endp, 10);
+
+ if (!isdigit((unsigned char)*env) ||
+ (*endp && *endp != ':') ||
+ (*endp == ':' && (!endp[1] || n == 2))) {
+ if (!warned) {
+ fprintf(stderr,
+ "warning: KCONFIG_PROBABILITY has malformed format\n");
+ warned = true;
+ }
+ }
if (tmp >= 0 && tmp <= 100) {
p[n++] = tmp;
@@ -227,6 +238,9 @@ static void conf_set_all_new_symbols(enum conf_def_mode mode)
perror("KCONFIG_PROBABILITY");
exit(1);
}
+
+ if (warned && getenv("KCONFIG_WERROR"))
+ exit(1);
}
menu_for_each_entry(menu) {
@@ -469,6 +483,9 @@ static void conf_choice(struct menu *menu)
}
printf("\n");
}
+ /* Nothing to ask if none of the choice values is visible. */
+ if (!cnt)
+ return;
printf("%*schoice", indent - 1, "");
if (cnt == 1) {
printf("[1]: 1\n");
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index 4234a51d16fd..2227d89d6328 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -354,6 +354,12 @@ static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p)
case S_INT:
case S_HEX:
if (sym_string_valid(sym, p)) {
+ if (def != S_DEF_AUTO &&
+ !sym_string_check_bounds(sym, p))
+ /* hex uses 64-bit unsigned integer */
+ conf_warning("value '%s' for %s is outside the 64-bit %s integer bounds",
+ p, sym->name,
+ sym->type == S_INT ? "signed" : "unsigned");
sym->def[def].val = xstrdup(p);
sym->flags |= def_flags;
} else {
diff --git a/scripts/kconfig/kconfig-sym-check.pl b/scripts/kconfig/kconfig-sym-check.pl
index daa5285fdefc..c8dd07f8b27c 100755
--- a/scripts/kconfig/kconfig-sym-check.pl
+++ b/scripts/kconfig/kconfig-sym-check.pl
@@ -90,7 +90,7 @@ foreach my $file (@files) {
next;
}
- if (/^\s*(default|def_bool|def_tristate|select|depends\s+on|imply|visible\s+if|range|if|bool|tristate|int|hex|string|prompt)\s+(.+)\s*$/) {
+ if (/^\s*(default|def_bool|def_tristate|def_string|def_int|def_hex|select|depends\s+on|imply|visible\s+if|range|if|bool|tristate|int|hex|string|prompt)\s+(.+)\s*$/) {
my $s = $2;
$s =~ s/"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'//g;
$s =~ s/#.*//;
diff --git a/scripts/kconfig/lexer.l b/scripts/kconfig/lexer.l
index a6155422b4a6..1fa521199d4a 100644
--- a/scripts/kconfig/lexer.l
+++ b/scripts/kconfig/lexer.l
@@ -105,6 +105,9 @@ n [A-Za-z0-9_-]
"comment" return T_COMMENT;
"config" return T_CONFIG;
"def_bool" return T_DEF_BOOL;
+"def_hex" return T_DEF_HEX;
+"def_int" return T_DEF_INT;
+"def_string" return T_DEF_STRING;
"def_tristate" return T_DEF_TRISTATE;
"default" return T_DEFAULT;
"depends" return T_DEPENDS;
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h
index 7e6f6ca299cf..bbc99f75b416 100644
--- a/scripts/kconfig/lkc.h
+++ b/scripts/kconfig/lkc.h
@@ -89,7 +89,7 @@ struct property *menu_add_prompt(enum prop_type type, const char *prompt,
struct expr *dep);
void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep);
void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep);
-void menu_finalize(void);
+int menu_finalize(void);
void menu_set_type(int type);
extern struct menu rootmenu;
diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h
index 8914b4e8f2a8..8b436c87ba4a 100644
--- a/scripts/kconfig/lkc_proto.h
+++ b/scripts/kconfig/lkc_proto.h
@@ -31,6 +31,7 @@ bool sym_set_tristate_value(struct symbol *sym,tristate tri);
void choice_set_value(struct menu *choice, struct symbol *sym);
tristate sym_toggle_tristate_value(struct symbol *sym);
bool sym_string_valid(struct symbol *sym, const char *newval);
+bool sym_string_check_bounds(struct symbol *sym, const char *str);
bool sym_string_within_range(struct symbol *sym, const char *str);
bool sym_set_string_value(struct symbol *sym, const char *newval);
bool sym_is_changeable(const struct symbol *sym);
diff --git a/scripts/kconfig/lxdialog/textbox.c b/scripts/kconfig/lxdialog/textbox.c
index 0abaf635978f..3fe7682fc8a8 100644
--- a/scripts/kconfig/lxdialog/textbox.c
+++ b/scripts/kconfig/lxdialog/textbox.c
@@ -145,8 +145,6 @@ static void refresh_text_box(WINDOW *dialog, WINDOW *box, int boxh, int boxw,
/*
* Display text from a file in a dialog box.
- *
- * keys is a null-terminated array
*/
int dialog_textbox(const char *title, const char *tbuf, int initial_height,
int initial_width, int *_vscroll, int *_hscroll,
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index 9c079e92a9ed..bda3e2650216 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -234,17 +234,42 @@ void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep)
menu_add_prop(type, expr_alloc_symbol(sym), dep);
}
-static int menu_validate_number(struct symbol *sym, struct symbol *sym2)
-{
- return sym2->type == S_INT || sym2->type == S_HEX ||
- (sym2->type == S_UNKNOWN && sym_string_valid(sym, sym2->name));
+/* Validate the sym2 value for numeric sym. */
+static int menu_validate_number(struct symbol *sym, struct symbol *sym2,
+ const struct property *prop)
+{
+ if (sym->type != S_INT && sym->type != S_HEX)
+ return 0;
+
+ if (sym2->type == sym->type)
+ return 0;
+
+ if (sym2->type != S_UNKNOWN ||
+ !sym_string_valid(sym, sym2->name)) {
+ fprintf(stderr, "%s:%d: error: '%s' is an invalid value for '%s'\n",
+ prop->filename, prop->lineno, sym2->name,
+ sym_type_name(sym->type));
+ return 1;
+ }
+
+ if (!sym_string_check_bounds(sym, sym2->name)) {
+ fprintf(stderr,
+ "%s:%d: error: %s constant '%s' is outside the 64-bit %s bounds\n",
+ prop->filename, prop->lineno, sym_type_name(sym->type),
+ sym2->name, sym->type == S_INT ? "signed" : "unsigned");
+
+ return 1;
+ }
+
+ return 0;
}
-static void sym_check_prop(struct symbol *sym)
+static int sym_check_prop(struct symbol *sym)
{
struct property *prop;
struct symbol *sym2;
char *use;
+ int errors = 0;
for (prop = sym->prop; prop; prop = prop->next) {
switch (prop->type) {
@@ -258,10 +283,7 @@ static void sym_check_prop(struct symbol *sym)
break;
sym2 = prop_get_symbol(prop);
if (sym->type == S_HEX || sym->type == S_INT) {
- if (!menu_validate_number(sym, sym2))
- prop_warn(prop,
- "'%s': number is invalid",
- sym->name);
+ errors += menu_validate_number(sym, sym2, prop);
}
if (sym_is_choice(sym)) {
struct menu *choice = sym_get_choice_menu(sym2);
@@ -287,27 +309,33 @@ static void sym_check_prop(struct symbol *sym)
"'%s' has wrong type. '%s' only "
"accept arguments of bool and "
"tristate type", sym2->name, use);
+ if (sym_is_choice_value(sym2))
+ prop_warn(prop,
+ "config symbol '%s' uses %s for '%s', but '%s' is a choice value",
+ sym->name, use, sym2->name, sym2->name);
break;
case P_RANGE:
if (sym->type != S_INT && sym->type != S_HEX)
prop_warn(prop, "range is only allowed "
"for int or hex symbols");
- if (!menu_validate_number(sym, prop->expr->left.sym) ||
- !menu_validate_number(sym, prop->expr->right.sym))
- prop_warn(prop, "range is invalid");
+ errors += menu_validate_number(sym, prop->expr->left.sym, prop);
+ errors += menu_validate_number(sym, prop->expr->right.sym, prop);
break;
default:
;
}
}
+
+ return errors;
}
-static void _menu_finalize(struct menu *parent, bool inside_choice)
+static int _menu_finalize(struct menu *parent, bool inside_choice)
{
struct menu *menu, *last_menu;
struct symbol *sym;
struct property *prop;
struct expr *basedep, *dep, *dep2;
+ int errors = 0;
sym = parent->sym;
if (parent->list) {
@@ -393,7 +421,7 @@ static void _menu_finalize(struct menu *parent, bool inside_choice)
* moving on
*/
for (menu = parent->list; menu; menu = menu->next)
- _menu_finalize(menu, sym && sym_is_choice(sym));
+ errors += _menu_finalize(menu, sym && sym_is_choice(sym));
} else if (!inside_choice && sym) {
/*
* Automatic submenu creation. If sym is a symbol and A, B, C,
@@ -461,7 +489,7 @@ static void _menu_finalize(struct menu *parent, bool inside_choice)
}
/* Superset, put in submenu */
next:
- _menu_finalize(menu, false);
+ errors += _menu_finalize(menu, false);
menu->parent = parent;
last_menu = menu;
}
@@ -519,14 +547,16 @@ static void _menu_finalize(struct menu *parent, bool inside_choice)
menu_warn(parent, "config symbol defined without type");
/* Check properties connected to this symbol */
- sym_check_prop(sym);
+ errors += sym_check_prop(sym);
sym->flags |= SYMBOL_WARNED;
}
+
+ return errors;
}
-void menu_finalize(void)
+int menu_finalize(void)
{
- _menu_finalize(&rootmenu, false);
+ return _menu_finalize(&rootmenu, false);
}
bool menu_has_prompt(const struct menu *menu)
diff --git a/scripts/kconfig/parser.y b/scripts/kconfig/parser.y
index 5fb6f07b6ad2..ecb18c213d83 100644
--- a/scripts/kconfig/parser.y
+++ b/scripts/kconfig/parser.y
@@ -53,6 +53,9 @@ struct menu *current_menu, *current_entry, *current_choice;
%token T_CONFIG
%token T_DEFAULT
%token T_DEF_BOOL
+%token T_DEF_HEX
+%token T_DEF_INT
+%token T_DEF_STRING
%token T_DEF_TRISTATE
%token T_DEPENDS
%token T_ENDCHOICE
@@ -309,6 +312,9 @@ type:
default:
T_DEFAULT { $$ = S_UNKNOWN; }
| T_DEF_BOOL { $$ = S_BOOLEAN; }
+ | T_DEF_HEX { $$ = S_HEX; }
+ | T_DEF_INT { $$ = S_INT; }
+ | T_DEF_STRING { $$ = S_STRING; }
| T_DEF_TRISTATE { $$ = S_TRISTATE; }
/* if entry */
@@ -587,7 +593,7 @@ void conf_parse(const char *name)
menu_add_prompt(P_MENU, "Main menu", NULL);
}
- menu_finalize();
+ yynerrs += menu_finalize();
menu_for_each_entry(menu) {
struct menu *child;
diff --git a/scripts/kconfig/streamline_config.pl b/scripts/kconfig/streamline_config.pl
index 8677d1ca06a7..6a52a98eb40e 100755
--- a/scripts/kconfig/streamline_config.pl
+++ b/scripts/kconfig/streamline_config.pl
@@ -145,6 +145,7 @@ my %prompts;
my %objects;
my %config2kfile;
my %defaults;
+my %types;
my $var;
my $iflevel = 0;
my @ifdeps;
@@ -224,6 +225,7 @@ sub read_kconfig {
} elsif ($state ne "NONE" && /^\s*def(_(bool|tristate)|ault)\s+(\S.*)$/) {
my $dep = $3;
$defaults{$config} = 1;
+ $types{$config} = $2 if (defined($2));
if ($dep !~ /^\s*(y|m|n)\s*$/) {
$dep =~ s/.*\sif\s+//;
$depends{$config} .= " " . $dep;
@@ -240,7 +242,13 @@ sub read_kconfig {
}
# configs without prompts must be selected
- } elsif ($state ne "NONE" && /^\s*(tristate\s+\S|prompt\b)/) {
+ } elsif ($state ne "NONE" && /^\s*(bool|boolean)(\s+\S.*)?$/) {
+ $types{$config} = "bool";
+ $prompts{$config} = 1 if (defined($2));
+ } elsif ($state ne "NONE" && /^\s*tristate(\s+\S.*)?$/) {
+ $types{$config} = "tristate";
+ $prompts{$config} = 1 if (defined($1));
+ } elsif ($state ne "NONE" && /^\s*prompt\b/) {
# note if the config has a prompt
$prompts{$config} = 1;
@@ -707,7 +715,15 @@ foreach my $module (keys(%modules)) {
}
print STDERR "module $module did not have configs";
foreach my $conf (@arr) {
- print STDERR " " , $conf;
+ my $c = $conf;
+ $c =~ s/^CONFIG_//;
+ if (!$localyesconfig && defined($types{$c}) && $types{$c} eq "bool") {
+ print STDERR " $conf (boolean, not supported with =m)";
+ } elsif (defined($types{$c})) {
+ print STDERR " $conf ($types{$c})";
+ } else {
+ print STDERR " " , $conf;
+ }
}
print STDERR "\n";
}
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index 7e81b3676ee9..4ced4dd6485b 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -5,6 +5,7 @@
#include <sys/types.h>
#include <ctype.h>
+#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <regex.h>
@@ -141,8 +142,15 @@ struct property *sym_get_range_prop(struct symbol *sym)
return NULL;
}
-static long long sym_get_range_val(struct symbol *sym, int base)
+union range_value {
+ long long s;
+ unsigned long long u;
+};
+
+static union range_value sym_get_range_val(struct symbol *sym, int base)
{
+ union range_value val;
+
sym_calc_value(sym);
switch (sym->type) {
case S_INT:
@@ -154,15 +162,25 @@ static long long sym_get_range_val(struct symbol *sym, int base)
default:
break;
}
- return strtoll(sym->curr.val, NULL, base);
+ if (base == 10)
+ val.s = strtoll(sym->curr.val, NULL, base);
+ else
+ /* HEX */
+ val.u = strtoull(sym->curr.val, NULL, base);
+ return val;
}
-static void sym_validate_range(struct symbol *sym)
+/*
+ * Return the nearest range bound for an out-of-range default value.
+ * Return NULL if the value is valid or the symbol has no active range.
+ */
+static struct symbol *sym_get_near_range_bound(struct symbol *sym,
+ const char *value)
{
struct property *prop;
struct symbol *range_sym;
int base;
- long long val, val2;
+ union range_value val, val2;
switch (sym->type) {
case S_INT:
@@ -172,21 +190,40 @@ static void sym_validate_range(struct symbol *sym)
base = 16;
break;
default:
- return;
+ return NULL;
}
prop = sym_get_range_prop(sym);
if (!prop)
- return;
- val = strtoll(sym->curr.val, NULL, base);
+ return NULL;
+ if (base == 10)
+ val.s = strtoll(value, NULL, base);
+ else
+ val.u = strtoull(value, NULL, base);
range_sym = prop->expr->left.sym;
val2 = sym_get_range_val(range_sym, base);
- if (val >= val2) {
+
+ if (base == 10 && val.s >= val2.s) {
range_sym = prop->expr->right.sym;
val2 = sym_get_range_val(range_sym, base);
- if (val <= val2)
- return;
+ if (val.s <= val2.s)
+ return NULL;
+ } else if (base == 16 && val.u >= val2.u) {
+ range_sym = prop->expr->right.sym;
+ val2 = sym_get_range_val(range_sym, base);
+ if (val.u <= val2.u)
+ return NULL;
}
- sym->curr.val = range_sym->curr.val;
+
+ return range_sym;
+}
+
+static void sym_validate_range(struct symbol *sym)
+{
+ struct symbol *range_sym;
+
+ range_sym = sym_get_near_range_bound(sym, sym->curr.val);
+ if (range_sym)
+ sym->curr.val = range_sym->curr.val;
}
static void sym_set_changed(struct symbol *sym)
@@ -711,10 +748,26 @@ bool sym_string_valid(struct symbol *sym, const char *str)
}
}
+bool sym_string_check_bounds(struct symbol *sym, const char *str)
+{
+ errno = 0;
+
+ if (sym->type == S_INT)
+ strtoll(str, NULL, 10);
+ else if (sym->type == S_HEX)
+ strtoull(str, NULL, 16);
+ else
+ /* string */
+ return true;
+
+ return errno != ERANGE;
+}
+
bool sym_string_within_range(struct symbol *sym, const char *str)
{
struct property *prop;
long long val;
+ unsigned long long uval;
switch (sym->type) {
case S_STRING:
@@ -722,21 +775,25 @@ bool sym_string_within_range(struct symbol *sym, const char *str)
case S_INT:
if (!sym_string_valid(sym, str))
return false;
+ if (!sym_string_check_bounds(sym, str))
+ return false;
prop = sym_get_range_prop(sym);
if (!prop)
return true;
val = strtoll(str, NULL, 10);
- return val >= sym_get_range_val(prop->expr->left.sym, 10) &&
- val <= sym_get_range_val(prop->expr->right.sym, 10);
+ return val >= sym_get_range_val(prop->expr->left.sym, 10).s &&
+ val <= sym_get_range_val(prop->expr->right.sym, 10).s;
case S_HEX:
if (!sym_string_valid(sym, str))
return false;
+ if (!sym_string_check_bounds(sym, str))
+ return false;
prop = sym_get_range_prop(sym);
if (!prop)
return true;
- val = strtoll(str, NULL, 16);
- return val >= sym_get_range_val(prop->expr->left.sym, 16) &&
- val <= sym_get_range_val(prop->expr->right.sym, 16);
+ uval = strtoull(str, NULL, 16);
+ return uval >= sym_get_range_val(prop->expr->left.sym, 16).u &&
+ uval <= sym_get_range_val(prop->expr->right.sym, 16).u;
case S_BOOLEAN:
case S_TRISTATE:
switch (str[0]) {
@@ -812,7 +869,7 @@ bool sym_set_string_value(struct symbol *sym, const char *newval)
const char *sym_get_string_default(struct symbol *sym)
{
struct property *prop;
- struct symbol *ds;
+ struct symbol *ds, *range_sym;
const char *str = "";
tristate val;
@@ -830,11 +887,6 @@ const char *sym_get_string_default(struct symbol *sym)
val = EXPR_AND(expr_calc_value(prop->expr), prop->visible.tri);
break;
default:
- /*
- * The following fails to handle the situation
- * where a default value is further limited by
- * the valid range.
- */
ds = prop_get_symbol(prop);
if (ds != NULL) {
sym_calc_value(ds);
@@ -878,6 +930,11 @@ const char *sym_get_string_default(struct symbol *sym)
default:
break;
}
+
+ range_sym = sym_get_near_range_bound(sym, str);
+ if (range_sym)
+ str = range_sym->curr.val;
+
return str;
}
@@ -1196,6 +1253,7 @@ static struct symbol *sym_check_expr_deps(const struct expr *e)
case E_GTH:
case E_LEQ:
case E_LTH:
+ case E_RANGE:
case E_UNEQUAL:
sym = sym_check_deps(e->left.sym);
if (sym)
@@ -1243,7 +1301,9 @@ static struct symbol *sym_check_sym_deps(struct symbol *sym)
sym2 = sym_check_expr_deps(prop->visible.expr);
if (sym2)
break;
- if (prop->type != P_DEFAULT || sym_is_choice(sym))
+ if (sym_is_choice(sym))
+ continue;
+ if (prop->type != P_DEFAULT && prop->type != P_RANGE)
continue;
stack.expr = &prop->expr;
sym2 = sym_check_expr_deps(prop->expr);
diff --git a/scripts/kconfig/tests/conftest.py b/scripts/kconfig/tests/conftest.py
index 66f95e4ed58c..d22c080a4e40 100644
--- a/scripts/kconfig/tests/conftest.py
+++ b/scripts/kconfig/tests/conftest.py
@@ -57,9 +57,12 @@ class Conf:
# Override 'srctree' environment to make the test as the top directory
extra_env['srctree'] = self._test_dir
- # Clear KCONFIG_DEFCONFIG_LIST to keep unit tests from being affected
- # by the user's environment.
- extra_env['KCONFIG_DEFCONFIG_LIST'] = ''
+ # Clear all KCONFIG_* environment variables
+ env = {
+ varname: os.environ[varname]
+ for varname in os.environ.keys()
+ if not varname.startswith("KCONFIG_")
+ }
# Run Kconfig in a temporary directory.
# This directory is automatically removed when done.
@@ -75,7 +78,7 @@ class Conf:
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
cwd=temp_dir,
- env=dict(os.environ, **extra_env))
+ env=dict(env, **extra_env))
# If input key sequence is given, feed it to stdin.
if in_keys:
@@ -156,13 +159,13 @@ class Conf:
return self._run_conf('--oldconfig', dot_config=dot_config,
interactive=True, in_keys=in_keys)
- def olddefconfig(self, dot_config=None):
+ def olddefconfig(self, dot_config=None, **kw):
"""Run olddefconfig.
dot_config: .config file to use for configuration base (optional)
returncode: exit status of the Kconfig executable
"""
- return self._run_conf('--olddefconfig', dot_config=dot_config)
+ return self._run_conf('--olddefconfig', dot_config=dot_config, **kw)
def defconfig(self, defconfig):
"""Run defconfig.
@@ -226,13 +229,15 @@ class Conf:
return self._allconfig('rand', all_config, extra_env=extra_env)
- def savedefconfig(self, dot_config):
+ def savedefconfig(self, dot_config, out_file='defconfig', **kw):
"""Run savedefconfig.
dot_config: .config file for input
+ out_file: defconfig file for output
returncode: exit status of the Kconfig executable
"""
- return self._run_conf('--savedefconfig', out_file='defconfig')
+ return self._run_conf('--savedefconfig={}'.format(out_file),
+ dot_config=dot_config, out_file=out_file, **kw)
def listnewconfig(self, dot_config=None):
"""Run listnewconfig.
@@ -312,6 +317,12 @@ class Conf:
return self._matches('stderr', expected)
+@pytest.fixture(autouse=True)
+def clear_werror(monkeypatch):
+ # extra_env can set strict mode, but cannot remove an inherited flag.
+ monkeypatch.delenv('KCONFIG_WERROR', raising=False)
+
+
@pytest.fixture(scope="module")
def conf(request):
"""Create a Conf instance and provide it to test functions."""
diff --git a/scripts/kconfig/tests/def_type/Kconfig b/scripts/kconfig/tests/def_type/Kconfig
new file mode 100644
index 000000000000..fbee37a63179
--- /dev/null
+++ b/scripts/kconfig/tests/def_type/Kconfig
@@ -0,0 +1,28 @@
+# SPDX-License-Identifier: GPL-2.0
+# The def_<type> shorthands: a type definition plus a default value.
+
+config MODULES
+ bool "Enable loadable module support"
+ modules
+ default y
+
+config GUARD
+ bool "Guard symbol"
+
+config DEF_BOOL
+ def_bool GUARD
+
+config DEF_TRISTATE
+ def_tristate m if GUARD
+
+config DEF_STRING
+ def_string "guarded" if GUARD
+ default "fallback"
+
+config DEF_INT
+ def_int 64 if GUARD
+ default 32
+
+config DEF_HEX
+ def_hex 0xdead if GUARD
+ default 0x0
diff --git a/scripts/kconfig/tests/def_type/__init__.py b/scripts/kconfig/tests/def_type/__init__.py
new file mode 100644
index 000000000000..1ebaf5da07c8
--- /dev/null
+++ b/scripts/kconfig/tests/def_type/__init__.py
@@ -0,0 +1,18 @@
+# SPDX-License-Identifier: GPL-2.0
+"""
+Set a symbol's type and its default value in one line.
+
+"def_bool", "def_tristate", "def_string", "def_int" and "def_hex" are
+shorthand for a type definition plus a "default" property. Check that
+each one sets the type, and that an "if" on the shorthand does not
+disturb the usual default cascade: the shorthand is only the first arm
+of the list, so a later "default" still applies when its condition is
+not met.
+"""
+
+def test(conf):
+ assert conf.olddefconfig(dot_config='guard_y.config') == 0
+ assert conf.config_matches('expected_guard_y')
+
+ assert conf.olddefconfig(dot_config='guard_n.config') == 0
+ assert conf.config_matches('expected_guard_n')
diff --git a/scripts/kconfig/tests/def_type/expected_guard_n b/scripts/kconfig/tests/def_type/expected_guard_n
new file mode 100644
index 000000000000..14719720a8b9
--- /dev/null
+++ b/scripts/kconfig/tests/def_type/expected_guard_n
@@ -0,0 +1,9 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# Main menu
+#
+CONFIG_MODULES=y
+# CONFIG_GUARD is not set
+CONFIG_DEF_STRING="fallback"
+CONFIG_DEF_INT=32
+CONFIG_DEF_HEX=0x0
diff --git a/scripts/kconfig/tests/def_type/expected_guard_y b/scripts/kconfig/tests/def_type/expected_guard_y
new file mode 100644
index 000000000000..b2844072d0b8
--- /dev/null
+++ b/scripts/kconfig/tests/def_type/expected_guard_y
@@ -0,0 +1,11 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# Main menu
+#
+CONFIG_MODULES=y
+CONFIG_GUARD=y
+CONFIG_DEF_BOOL=y
+CONFIG_DEF_TRISTATE=m
+CONFIG_DEF_STRING="guarded"
+CONFIG_DEF_INT=64
+CONFIG_DEF_HEX=0xdead
diff --git a/scripts/kconfig/tests/def_type/guard_n.config b/scripts/kconfig/tests/def_type/guard_n.config
new file mode 100644
index 000000000000..ed9ad6c1a2d4
--- /dev/null
+++ b/scripts/kconfig/tests/def_type/guard_n.config
@@ -0,0 +1 @@
+# CONFIG_GUARD is not set
diff --git a/scripts/kconfig/tests/def_type/guard_y.config b/scripts/kconfig/tests/def_type/guard_y.config
new file mode 100644
index 000000000000..afe35b084542
--- /dev/null
+++ b/scripts/kconfig/tests/def_type/guard_y.config
@@ -0,0 +1 @@
+CONFIG_GUARD=y
diff --git a/scripts/kconfig/tests/err_num_bounds/Kconfig b/scripts/kconfig/tests/err_num_bounds/Kconfig
new file mode 100644
index 000000000000..c439366c03b6
--- /dev/null
+++ b/scripts/kconfig/tests/err_num_bounds/Kconfig
@@ -0,0 +1,79 @@
+# SPDX-License-Identifier: GPL-2.0
+# Test bounds checks for 'int' and 'hex' constants
+
+config INT_SOURCE
+ int
+
+config HEX_SOURCE
+ hex
+
+config BOOL_SOURCE
+ bool
+
+# Valid values at the limits of the type
+
+config INT_MIN
+ int
+ default -9223372036854775808
+
+config INT_MAX
+ int
+ default 9223372036854775807
+
+config HEX_MIN
+ hex
+ default 0x0
+
+config HEX_MAX
+ hex
+ default 0xffffffffffffffff
+
+config INT_RANGE_LIMITS
+ int
+ range -9223372036854775808 9223372036854775807
+
+config HEX_RANGE_LIMITS
+ hex
+ range 0 0xffffffffffffffff
+
+config INT_FROM_INT
+ int
+ default INT_SOURCE
+
+config HEX_FROM_HEX
+ hex
+ default HEX_SOURCE
+
+# Constants outside the bounds
+
+config INT_DEFAULT_TOO_HIGH
+ int
+ default 10000000000000000000
+
+config INT_DEFAULT_TOO_LOW
+ int
+ default -9223372036854775809
+
+config INT_RANGE_TOO_HIGH
+ int
+ range 0 10000000000000000000
+
+config INT_RANGE_TOO_LOW
+ int
+ range -10000000000000000000 0
+
+config INT_RANGE_BOTH_OUTSIDE
+ int
+ range -9223372036854775809 10000000000000000000
+
+config HEX_DEFAULT_TOO_HIGH
+ hex
+ default 0x10000000000000000
+
+config HEX_RANGE_TOO_HIGH
+ hex
+ range 0 0x10000000000000000
+
+config HEX_RANGE_BOTH_TOO_HIGH
+ hex
+ range 0x10000000000000000 0x20000000000000000
diff --git a/scripts/kconfig/tests/err_num_bounds/__init__.py b/scripts/kconfig/tests/err_num_bounds/__init__.py
new file mode 100644
index 000000000000..72ac6aa24491
--- /dev/null
+++ b/scripts/kconfig/tests/err_num_bounds/__init__.py
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-2.0
+"""
+Detect constants outside the 'int' and 'hex' bounds.
+
+An int constant must fit in a signed 64-bit integer, and a hex constant must
+fit in an unsigned 64-bit integer.
+"""
+
+
+def test(conf):
+ assert conf.olddefconfig() == 1
+ assert conf.stderr_matches('expected_stderr')
diff --git a/scripts/kconfig/tests/err_num_bounds/expected_stderr b/scripts/kconfig/tests/err_num_bounds/expected_stderr
new file mode 100644
index 000000000000..5f89cf4afff8
--- /dev/null
+++ b/scripts/kconfig/tests/err_num_bounds/expected_stderr
@@ -0,0 +1,10 @@
+Kconfig:51: error: integer constant '10000000000000000000' is outside the 64-bit signed bounds
+Kconfig:55: error: integer constant '-9223372036854775809' is outside the 64-bit signed bounds
+Kconfig:59: error: integer constant '10000000000000000000' is outside the 64-bit signed bounds
+Kconfig:63: error: integer constant '-10000000000000000000' is outside the 64-bit signed bounds
+Kconfig:67: error: integer constant '-9223372036854775809' is outside the 64-bit signed bounds
+Kconfig:67: error: integer constant '10000000000000000000' is outside the 64-bit signed bounds
+Kconfig:71: error: hex constant '0x10000000000000000' is outside the 64-bit unsigned bounds
+Kconfig:75: error: hex constant '0x10000000000000000' is outside the 64-bit unsigned bounds
+Kconfig:79: error: hex constant '0x10000000000000000' is outside the 64-bit unsigned bounds
+Kconfig:79: error: hex constant '0x20000000000000000' is outside the 64-bit unsigned bounds
diff --git a/scripts/kconfig/tests/err_num_mismatch/Kconfig b/scripts/kconfig/tests/err_num_mismatch/Kconfig
new file mode 100644
index 000000000000..8406f3bb6419
--- /dev/null
+++ b/scripts/kconfig/tests/err_num_mismatch/Kconfig
@@ -0,0 +1,38 @@
+# SPDX-License-Identifier: GPL-2.0
+# Test 'int' and 'hex' symbols that reference each other
+
+config INT_SOURCE
+ int
+
+config HEX_SOURCE
+ hex
+
+# 'hex' reference from 'int'
+
+config INT_DEFAULT_HEX
+ int
+ default HEX_SOURCE
+
+config INT_RANGE_HEX
+ int
+ range HEX_SOURCE 1
+
+# A hex symbol must not reference an int symbol
+
+config HEX_DEFAULT_INT
+ hex
+ default INT_SOURCE
+
+config HEX_RANGE_INT
+ hex
+ range INT_SOURCE 0x1
+
+# Referencing the same type is valid
+
+config INT_FROM_INT
+ int
+ default INT_SOURCE
+
+config HEX_FROM_HEX
+ hex
+ range 0 HEX_SOURCE
diff --git a/scripts/kconfig/tests/err_num_mismatch/__init__.py b/scripts/kconfig/tests/err_num_mismatch/__init__.py
new file mode 100644
index 000000000000..275f2a6e9a5b
--- /dev/null
+++ b/scripts/kconfig/tests/err_num_mismatch/__init__.py
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0
+"""
+Reject direct references ('default' or 'range') between int and hex options.
+"""
+
+
+def test(conf):
+ assert conf.olddefconfig() == 1
+ assert conf.stderr_matches('expected_stderr')
diff --git a/scripts/kconfig/tests/err_num_mismatch/expected_stderr b/scripts/kconfig/tests/err_num_mismatch/expected_stderr
new file mode 100644
index 000000000000..587c34467ae6
--- /dev/null
+++ b/scripts/kconfig/tests/err_num_mismatch/expected_stderr
@@ -0,0 +1,4 @@
+Kconfig:14: error: 'HEX_SOURCE' is an invalid value for 'integer'
+Kconfig:18: error: 'HEX_SOURCE' is an invalid value for 'integer'
+Kconfig:24: error: 'INT_SOURCE' is an invalid value for 'hex'
+Kconfig:28: error: 'INT_SOURCE' is an invalid value for 'hex'
diff --git a/scripts/kconfig/tests/err_num_non_numeric_ref/Kconfig b/scripts/kconfig/tests/err_num_non_numeric_ref/Kconfig
new file mode 100644
index 000000000000..0ca7a4a460f6
--- /dev/null
+++ b/scripts/kconfig/tests/err_num_non_numeric_ref/Kconfig
@@ -0,0 +1,75 @@
+# SPDX-License-Identifier: GPL-2.0
+# Test non-numeric symbol references from numeric symbols
+
+config BOOL_SOURCE
+ bool
+
+config TRISTATE_SOURCE
+ tristate
+
+config STRING_SOURCE
+ string
+
+# Invalid int defaults
+
+config INT_DEFAULT_BOOL
+ int
+ default BOOL_SOURCE
+
+config INT_DEFAULT_TRISTATE
+ int
+ default TRISTATE_SOURCE
+
+config INT_DEFAULT_STRING
+ int
+ default STRING_SOURCE
+
+# Invalid hex defaults
+
+config HEX_DEFAULT_BOOL
+ hex
+ default BOOL_SOURCE
+
+config HEX_DEFAULT_TRISTATE
+ hex
+ default TRISTATE_SOURCE
+
+config HEX_DEFAULT_STRING
+ hex
+ default STRING_SOURCE
+
+# Invalid int ranges
+
+config INT_RANGE_BOOL
+ int
+ range BOOL_SOURCE 1
+
+config INT_RANGE_TRISTATE
+ int
+ range TRISTATE_SOURCE 1
+
+config INT_RANGE_STRING
+ int
+ range STRING_SOURCE 1
+
+config INT_RANGE_MULTIPLE
+ int
+ range BOOL_SOURCE TRISTATE_SOURCE
+
+# Invalid hex ranges
+
+config HEX_RANGE_BOOL
+ hex
+ range BOOL_SOURCE 0x1
+
+config HEX_RANGE_TRISTATE
+ hex
+ range TRISTATE_SOURCE 0x1
+
+config HEX_RANGE_STRING
+ hex
+ range STRING_SOURCE 0x1
+
+config HEX_RANGE_MULTIPLE
+ hex
+ range BOOL_SOURCE TRISTATE_SOURCE
diff --git a/scripts/kconfig/tests/err_num_non_numeric_ref/__init__.py b/scripts/kconfig/tests/err_num_non_numeric_ref/__init__.py
new file mode 100644
index 000000000000..9632907abead
--- /dev/null
+++ b/scripts/kconfig/tests/err_num_non_numeric_ref/__init__.py
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0
+"""
+Reject nonnumeric symbol references from int and hex properties.
+"""
+
+
+def test(conf):
+ assert conf.olddefconfig() == 1
+ assert conf.stderr_matches('expected_stderr')
diff --git a/scripts/kconfig/tests/err_num_non_numeric_ref/expected_stderr b/scripts/kconfig/tests/err_num_non_numeric_ref/expected_stderr
new file mode 100644
index 000000000000..005f855ecbdd
--- /dev/null
+++ b/scripts/kconfig/tests/err_num_non_numeric_ref/expected_stderr
@@ -0,0 +1,16 @@
+Kconfig:17: error: 'BOOL_SOURCE' is an invalid value for 'integer'
+Kconfig:21: error: 'TRISTATE_SOURCE' is an invalid value for 'integer'
+Kconfig:25: error: 'STRING_SOURCE' is an invalid value for 'integer'
+Kconfig:31: error: 'BOOL_SOURCE' is an invalid value for 'hex'
+Kconfig:35: error: 'TRISTATE_SOURCE' is an invalid value for 'hex'
+Kconfig:39: error: 'STRING_SOURCE' is an invalid value for 'hex'
+Kconfig:45: error: 'BOOL_SOURCE' is an invalid value for 'integer'
+Kconfig:49: error: 'TRISTATE_SOURCE' is an invalid value for 'integer'
+Kconfig:53: error: 'STRING_SOURCE' is an invalid value for 'integer'
+Kconfig:57: error: 'BOOL_SOURCE' is an invalid value for 'integer'
+Kconfig:57: error: 'TRISTATE_SOURCE' is an invalid value for 'integer'
+Kconfig:63: error: 'BOOL_SOURCE' is an invalid value for 'hex'
+Kconfig:67: error: 'TRISTATE_SOURCE' is an invalid value for 'hex'
+Kconfig:71: error: 'STRING_SOURCE' is an invalid value for 'hex'
+Kconfig:75: error: 'BOOL_SOURCE' is an invalid value for 'hex'
+Kconfig:75: error: 'TRISTATE_SOURCE' is an invalid value for 'hex'
diff --git a/scripts/kconfig/tests/err_recursive_dep/Kconfig b/scripts/kconfig/tests/err_recursive_dep/Kconfig
index ebdb3ffd8717..bd1ff92bcab2 100644
--- a/scripts/kconfig/tests/err_recursive_dep/Kconfig
+++ b/scripts/kconfig/tests/err_recursive_dep/Kconfig
@@ -61,3 +61,27 @@ config G
bool "G"
endmenu
+
+# depends on and range
+
+config H1
+ int
+ depends on H2 < H3
+
+config H2
+ int
+ range H3 H1
+
+config H3
+ int
+ range H1 H2
+
+# range
+
+config I1
+ int
+ range I2 I2
+
+config I2
+ int
+ range I1 I1
diff --git a/scripts/kconfig/tests/err_recursive_dep/expected_stderr b/scripts/kconfig/tests/err_recursive_dep/expected_stderr
index fc2e860af082..08f843087678 100644
--- a/scripts/kconfig/tests/err_recursive_dep/expected_stderr
+++ b/scripts/kconfig/tests/err_recursive_dep/expected_stderr
@@ -36,3 +36,16 @@ error: recursive dependency detected!
symbol G depends on G
For a resolution refer to Documentation/kbuild/kconfig-language.rst
subsection "Kconfig recursive dependency limitations"
+
+error: recursive dependency detected!
+ symbol H1 depends on H2
+ symbol H2 range value contains H3
+ symbol H3 range value contains H1
+For a resolution refer to Documentation/kbuild/kconfig-language.rst
+subsection "Kconfig recursive dependency limitations"
+
+error: recursive dependency detected!
+ symbol I1 range value contains I2
+ symbol I2 range value contains I1
+For a resolution refer to Documentation/kbuild/kconfig-language.rst
+subsection "Kconfig recursive dependency limitations"
diff --git a/scripts/kconfig/tests/randconfig_probability/Kconfig b/scripts/kconfig/tests/randconfig_probability/Kconfig
new file mode 100644
index 000000000000..84f4e5fcc51e
--- /dev/null
+++ b/scripts/kconfig/tests/randconfig_probability/Kconfig
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+config MODULES
+ bool
+ default y
+ modules
+
+config BOOL
+ bool "Bool"
+
+config TRI
+ tristate "Tristate"
diff --git a/scripts/kconfig/tests/randconfig_probability/__init__.py b/scripts/kconfig/tests/randconfig_probability/__init__.py
new file mode 100644
index 000000000000..e6e5dda10ad9
--- /dev/null
+++ b/scripts/kconfig/tests/randconfig_probability/__init__.py
@@ -0,0 +1,130 @@
+# SPDX-License-Identifier: GPL-2.0-only
+"""Validate KCONFIG_PROBABILITY without changing the supported distributions."""
+
+
+def test_malformed_warns(conf):
+ probabilities = [
+ 'invalid', ' ', '50%', '50 ', '0x32', '10 20', '10:20x',
+ '10:20:invalid', '10:20:30x',
+ ':50', '50:', '10::20', '10:20:', '10:20:30:', '10:20:30:40',
+ '-0', '+0', '+', '-', '+100:0', ' \t100:0', '0: \t100:0',
+ ]
+ for probability in probabilities:
+ assert conf._run_conf('--randconfig', extra_env={
+ 'KCONFIG_PROBABILITY': probability,
+ 'KCONFIG_SEED': '0',
+ }) == 0, repr(probability)
+ assert ('warning: KCONFIG_PROBABILITY has malformed format' in
+ conf.stderr), repr(probability)
+ assert conf.stderr.count('warning:') == 1, repr(probability)
+ assert conf.config is not None, repr(probability)
+
+
+def test_malformed_preserves_config(conf):
+ probabilities = [('50%', '50:0:0'), ('-0', '0')]
+ for seed in range(20):
+ for probability, equivalent in probabilities:
+ context = 'probability={!r}, equivalent={!r}, seed={}'.format(
+ probability, equivalent, seed)
+ assert conf._run_conf('--randconfig', extra_env={
+ 'KCONFIG_PROBABILITY': probability,
+ 'KCONFIG_SEED': hex(seed),
+ }) == 0, context
+ assert ('warning: KCONFIG_PROBABILITY has malformed format' in
+ conf.stderr), context
+ assert conf.stderr.count('warning:') == 1, context
+ malformed = conf.config
+
+ assert conf._run_conf('--randconfig', extra_env={
+ 'KCONFIG_PROBABILITY': equivalent,
+ 'KCONFIG_SEED': hex(seed),
+ }) == 0, context
+ assert 'warning:' not in conf.stderr, context
+ assert conf.config == malformed, context
+
+
+def test_werror(conf):
+ probabilities = [
+ ('', 0), ('50', 0), ('50%', 1), ('-0', 1), ('10:20:30:40', 1),
+ ]
+ for probability, status in probabilities:
+ for werror in ['', '0', '1']:
+ context = 'probability={!r}, werror={!r}'.format(
+ probability, werror)
+ assert conf._run_conf('--randconfig', extra_env={
+ 'KCONFIG_PROBABILITY': probability,
+ 'KCONFIG_SEED': '0',
+ 'KCONFIG_WERROR': werror,
+ }) == status, context
+ if status:
+ assert ('warning: KCONFIG_PROBABILITY has malformed format' in
+ conf.stderr), context
+ assert conf.stderr.count('warning:') == 1, context
+ else:
+ assert 'warning:' not in conf.stderr, context
+
+
+def test_out_of_range(conf):
+ probabilities = [
+ '-1', '101', '+101', '0:101', '0:0:101', '60:41', '0:60:41',
+ '4294967296', '-4294967296',
+ '999999999999999999999999', '-999999999999999999999999',
+ ]
+ for probability in probabilities:
+ assert conf._run_conf('--randconfig', extra_env={
+ 'KCONFIG_PROBABILITY': probability,
+ 'KCONFIG_SEED': '0',
+ }) == 1, repr(probability)
+ assert 'KCONFIG_PROBABILITY:' in conf.stderr, repr(probability)
+
+
+def test_valid(conf):
+ probabilities = [
+ ('0', 'n', 'n'),
+ ('0:0', 'n', 'n'),
+ ('100:0', 'y', 'y'),
+ ('0:100', 'y', 'm'),
+ ('100:0:0', 'y', 'n'),
+ ('0:100:0', 'n', 'y'),
+ ('0:0:100', 'n', 'm'),
+ ('000:000:100', 'n', 'm'),
+ ]
+ for probability, boolean, tristate in probabilities:
+ assert conf._run_conf('--randconfig', extra_env={
+ 'KCONFIG_PROBABILITY': probability,
+ 'KCONFIG_SEED': '0',
+ }) == 0, repr(probability)
+ assert 'warning:' not in conf.stderr, repr(probability)
+ for symbol, value in [('BOOL', boolean), ('TRI', tristate)]:
+ if value == 'n':
+ expected = '# CONFIG_{} is not set'.format(symbol)
+ else:
+ expected = 'CONFIG_{}={}'.format(symbol, value)
+ assert expected in conf.config.splitlines(), repr(probability)
+
+
+def test_single_probability_matches_tristate_split(conf):
+ for seed in range(20):
+ context = 'seed={}'.format(seed)
+ assert conf._run_conf('--randconfig', extra_env={
+ 'KCONFIG_PROBABILITY': '50',
+ 'KCONFIG_SEED': hex(seed),
+ }) == 0, context
+ assert 'warning:' not in conf.stderr, context
+ single = conf.config
+
+ # 50% boolean y; 25% tristate y, 25% m, and 50% n.
+ assert conf._run_conf('--randconfig', extra_env={
+ 'KCONFIG_PROBABILITY': '50:25:25',
+ 'KCONFIG_SEED': hex(seed),
+ }) == 0, context
+ assert 'warning:' not in conf.stderr, context
+ assert conf.config == single, context
+
+
+def test_empty(conf):
+ assert conf._run_conf('--randconfig', extra_env={
+ 'KCONFIG_PROBABILITY': '',
+ 'KCONFIG_SEED': '0',
+ }) == 0
+ assert 'warning:' not in conf.stderr
diff --git a/scripts/kconfig/tests/savedefconfig_range/Kconfig b/scripts/kconfig/tests/savedefconfig_range/Kconfig
new file mode 100644
index 000000000000..d879870a5267
--- /dev/null
+++ b/scripts/kconfig/tests/savedefconfig_range/Kconfig
@@ -0,0 +1,67 @@
+# SPDX-License-Identifier: GPL-2.0
+
+# Static default and range values
+
+config INT_DEFAULT_ABOVE_RANGE
+ int
+ range 1 1
+ default 16
+
+config INT_DEFAULT_BELOW_RANGE
+ int
+ range 4 8
+ default 2
+
+# Default and range values determined by other options
+
+config RANGE_UPPER_BOUND
+ int
+ default 3
+
+config INT_DYNAMIC_RANGE
+ int
+ range 0 RANGE_UPPER_BOUND
+ default 4
+
+# Hex
+
+config HEX_DEFAULT_ABOVE_RANGE
+ hex
+ range 0x10 0x20
+ default 0x40
+
+# Implicit default value of 0
+
+config INT_IMPLICIT_DEFAULT_ZERO
+ int
+ range 1 4
+
+# Conditional range
+
+config USE_FIRST_RANGE
+ bool
+ default y
+
+config INT_CONDITIONAL_RANGE
+ int
+ range 1 2 if USE_FIRST_RANGE
+ range 3 4 if !USE_FIRST_RANGE
+ default 3
+
+# Conditional default
+
+config USE_DEFAULT
+ bool
+ default y
+
+config INT_CONDITIONAL_DEFAULT
+ int
+ range 1 2
+ default 3 if USE_DEFAULT
+
+# Default outside of the range of a symbol with a prompt
+
+config INT_PROMPT_DEFAULT_ABOVE_RANGE
+ int "int with prompt"
+ range 1 4
+ default 8
diff --git a/scripts/kconfig/tests/savedefconfig_range/__init__.py b/scripts/kconfig/tests/savedefconfig_range/__init__.py
new file mode 100644
index 000000000000..961454be732c
--- /dev/null
+++ b/scripts/kconfig/tests/savedefconfig_range/__init__.py
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0
+"""Test savedefconfig with numerical defaults outside of ranges."""
+
+
+def test(conf):
+ assert conf._run_conf('--savedefconfig=defconfig', dot_config='config',
+ out_file='defconfig') == 0
+ assert conf.config_matches('expected_defconfig')
diff --git a/scripts/kconfig/tests/savedefconfig_range/config b/scripts/kconfig/tests/savedefconfig_range/config
new file mode 100644
index 000000000000..079a3107a02b
--- /dev/null
+++ b/scripts/kconfig/tests/savedefconfig_range/config
@@ -0,0 +1,8 @@
+CONFIG_INT_DEFAULT_ABOVE_RANGE=1
+CONFIG_INT_DEFAULT_BELOW_RANGE=4
+CONFIG_INT_DYNAMIC_RANGE=3
+CONFIG_HEX_DEFAULT_ABOVE_RANGE=0x20
+CONFIG_INT_IMPLICIT_DEFAULT_ZERO=1
+CONFIG_INT_CONDITIONAL_RANGE=2
+CONFIG_INT_CONDITIONAL_DEFAULT=2
+CONFIG_INT_PROMPT_DEFAULT_ABOVE_RANGE=4
diff --git a/scripts/kconfig/tests/savedefconfig_range/expected_defconfig b/scripts/kconfig/tests/savedefconfig_range/expected_defconfig
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/scripts/kconfig/tests/savedefconfig_range/expected_defconfig
diff --git a/scripts/kconfig/tests/warn_changed_input/Kconfig b/scripts/kconfig/tests/warn_changed_input/Kconfig
index 69845e2f3fb3..df4183a08420 100644
--- a/scripts/kconfig/tests/warn_changed_input/Kconfig
+++ b/scripts/kconfig/tests/warn_changed_input/Kconfig
@@ -26,6 +26,11 @@ config NUM
Kconfig resolves it to the constrained in-range value.
The warning should report that adjustment.
+config HEX_RANGE
+ hex
+ range 0 0xfffffffffffffffe
+ default 0xffffffffffffffff
+
config DUP
bool "DUP"
depends on DEP
diff --git a/scripts/kconfig/tests/warn_changed_input/__init__.py b/scripts/kconfig/tests/warn_changed_input/__init__.py
index 4c3bca6af846..17b602dd280e 100644
--- a/scripts/kconfig/tests/warn_changed_input/__init__.py
+++ b/scripts/kconfig/tests/warn_changed_input/__init__.py
@@ -8,26 +8,21 @@ KCONFIG_WARN_CHANGED_INPUT is enabled.
def test(conf):
+ warn_changed_input = {
+ "KCONFIG_WARN_CHANGED_INPUT": "1",
+ }
+
assert conf.olddefconfig('config') == 0
assert 'user-provided values changed by Kconfig' not in conf.stderr
- assert conf._run_conf('--olddefconfig', dot_config='config',
- extra_env={
- 'KCONFIG_WARN_CHANGED_INPUT': '1',
- }) == 0
+ assert conf.olddefconfig('config', extra_env=warn_changed_input) == 0
assert conf.stderr_contains('expected_stderr')
assert conf.config_matches('expected_config')
- assert conf._run_conf('--olddefconfig', dot_config='config',
- extra_env={
- 'KCONFIG_WARN_CHANGED_INPUT': '1',
- }, silent=True) == 0
+ assert conf.olddefconfig('config', extra_env=warn_changed_input,
+ silent=True) == 0
assert conf.stderr_contains('expected_stderr')
- assert conf._run_conf('--savedefconfig=defconfig', dot_config='config',
- out_file='defconfig',
- extra_env={
- 'KCONFIG_WARN_CHANGED_INPUT': '1',
- }) == 0
+ assert conf.savedefconfig('config', extra_env=warn_changed_input) == 0
assert conf.stderr_contains('expected_stderr')
assert conf.config_matches('expected_defconfig')
diff --git a/scripts/kconfig/tests/warn_changed_input/expected_config b/scripts/kconfig/tests/warn_changed_input/expected_config
index fe8bbec66c53..6a8d98a69b7e 100644
--- a/scripts/kconfig/tests/warn_changed_input/expected_config
+++ b/scripts/kconfig/tests/warn_changed_input/expected_config
@@ -4,3 +4,4 @@
#
# CONFIG_DEP is not set
CONFIG_NUM=20
+CONFIG_HEX_RANGE=0xfffffffffffffffe
diff --git a/scripts/kconfig/tests/warn_num_bounds/Kconfig b/scripts/kconfig/tests/warn_num_bounds/Kconfig
new file mode 100644
index 000000000000..a810225a58a3
--- /dev/null
+++ b/scripts/kconfig/tests/warn_num_bounds/Kconfig
@@ -0,0 +1,24 @@
+# SPDX-License-Identifier: GPL-2.0
+
+mainmenu "Numeric bounds test"
+
+config INT_TOO_LOW
+ int "Integer below its type bounds"
+
+config INT_TOO_HIGH
+ int "Integer above its type bounds"
+
+config HEX_TOO_HIGH
+ hex "Hex value above its type bounds"
+
+config INT_MIN
+ int "Minimum valid integer"
+
+config INT_MAX
+ int "Maximum valid integer"
+
+config HEX_MIN
+ hex "Minimum valid hex value"
+
+config HEX_MAX
+ hex "Maximum valid hex value"
diff --git a/scripts/kconfig/tests/warn_num_bounds/__init__.py b/scripts/kconfig/tests/warn_num_bounds/__init__.py
new file mode 100644
index 000000000000..db7518258217
--- /dev/null
+++ b/scripts/kconfig/tests/warn_num_bounds/__init__.py
@@ -0,0 +1,25 @@
+# SPDX-License-Identifier: GPL-2.0
+"""Test user values outside the numeric type bounds."""
+
+
+def test(conf):
+ in_keys = (
+ '-9223372036854775809\n'
+ '-1\n'
+ '9223372036854775808\n'
+ '1\n'
+ '0x10000000000000000\n'
+ '0x1\n'
+ '-9223372036854775808\n'
+ '9223372036854775807\n'
+ '0x0\n'
+ '0xffffffffffffffff\n'
+ )
+
+ assert conf.oldaskconfig(in_keys=in_keys) == 0
+ assert conf.stderr_matches('expected_frontend_stderr')
+ assert conf.config_matches('expected_frontend_config')
+
+ assert conf.olddefconfig('config') == 0
+ assert conf.stderr_matches('expected_config_stderr')
+ assert conf.config_matches('expected_config')
diff --git a/scripts/kconfig/tests/warn_num_bounds/config b/scripts/kconfig/tests/warn_num_bounds/config
new file mode 100644
index 000000000000..74bf263f99bf
--- /dev/null
+++ b/scripts/kconfig/tests/warn_num_bounds/config
@@ -0,0 +1,7 @@
+CONFIG_INT_TOO_LOW=-9223372036854775809
+CONFIG_INT_TOO_HIGH=9223372036854775808
+CONFIG_HEX_TOO_HIGH=0x10000000000000000
+CONFIG_INT_MIN=-9223372036854775808
+CONFIG_INT_MAX=9223372036854775807
+CONFIG_HEX_MIN=0x0
+CONFIG_HEX_MAX=0xffffffffffffffff
diff --git a/scripts/kconfig/tests/warn_num_bounds/expected_config b/scripts/kconfig/tests/warn_num_bounds/expected_config
new file mode 100644
index 000000000000..8b1aef612bc6
--- /dev/null
+++ b/scripts/kconfig/tests/warn_num_bounds/expected_config
@@ -0,0 +1,11 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# Numeric bounds test
+#
+CONFIG_INT_TOO_LOW=-9223372036854775809
+CONFIG_INT_TOO_HIGH=9223372036854775808
+CONFIG_HEX_TOO_HIGH=0x10000000000000000
+CONFIG_INT_MIN=-9223372036854775808
+CONFIG_INT_MAX=9223372036854775807
+CONFIG_HEX_MIN=0x0
+CONFIG_HEX_MAX=0xffffffffffffffff
diff --git a/scripts/kconfig/tests/warn_num_bounds/expected_config_stderr b/scripts/kconfig/tests/warn_num_bounds/expected_config_stderr
new file mode 100644
index 000000000000..be2ed7fbf648
--- /dev/null
+++ b/scripts/kconfig/tests/warn_num_bounds/expected_config_stderr
@@ -0,0 +1,3 @@
+.config:1:warning: value '-9223372036854775809' for INT_TOO_LOW is outside the 64-bit signed integer bounds
+.config:2:warning: value '9223372036854775808' for INT_TOO_HIGH is outside the 64-bit signed integer bounds
+.config:3:warning: value '0x10000000000000000' for HEX_TOO_HIGH is outside the 64-bit unsigned integer bounds
diff --git a/scripts/kconfig/tests/warn_num_bounds/expected_frontend_config b/scripts/kconfig/tests/warn_num_bounds/expected_frontend_config
new file mode 100644
index 000000000000..a7e842517026
--- /dev/null
+++ b/scripts/kconfig/tests/warn_num_bounds/expected_frontend_config
@@ -0,0 +1,11 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# Numeric bounds test
+#
+CONFIG_INT_TOO_LOW=-1
+CONFIG_INT_TOO_HIGH=1
+CONFIG_HEX_TOO_HIGH=0x1
+CONFIG_INT_MIN=-9223372036854775808
+CONFIG_INT_MAX=9223372036854775807
+CONFIG_HEX_MIN=0x0
+CONFIG_HEX_MAX=0xffffffffffffffff
diff --git a/scripts/kconfig/tests/warn_num_bounds/expected_frontend_stderr b/scripts/kconfig/tests/warn_num_bounds/expected_frontend_stderr
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/scripts/kconfig/tests/warn_num_bounds/expected_frontend_stderr