summaryrefslogtreecommitdiff
path: root/scripts/kconfig/zconf.y
diff options
context:
space:
mode:
authorMasahiro Yamada <yamada.masahiro@socionext.com>2018-05-28 18:21:49 +0900
committerMasahiro Yamada <yamada.masahiro@socionext.com>2018-05-29 03:31:19 +0900
commit9ced3bddec080e974e910bf887715540a8d9d96b (patch)
tree4bb735afdabb6e4b9dd6f2d607a596fde7b37301 /scripts/kconfig/zconf.y
parent9de071536c87cb814e210bd762fcf7f645d514a9 (diff)
kconfig: support user-defined function and recursively expanded variable
Now, we got a basic ability to test compiler capability in Kconfig. config CC_HAS_STACKPROTECTOR def_bool $(shell,($(CC) -Werror -fstack-protector -E -x c /dev/null -o /dev/null 2>/dev/null) && echo y || echo n) This works, but it is ugly to repeat this long boilerplate. We want to describe like this: config CC_HAS_STACKPROTECTOR bool default $(cc-option,-fstack-protector) It is straight-forward to add a new function, but I do not like to hard-code specialized functions like that. Hence, here is another feature, user-defined function. This works as a textual shorthand with parameterization. A user-defined function is defined by using the = operator, and can be referenced in the same way as built-in functions. A user-defined function in Make is referenced like $(call my-func,arg1,arg2), but I omitted the 'call' to make the syntax shorter. The definition of a user-defined function contains $(1), $(2), etc. in its body to reference the parameters. It is grammatically valid to pass more or fewer arguments when calling it. We already exploit this feature in our makefiles; scripts/Kbuild.include defines cc-option which takes two arguments at most, but most of the callers pass only one argument. By the way, a variable is supported as a subset of this feature since a variable is "a user-defined function with zero argument". In this context, I mean "variable" as recursively expanded variable. I will add a different flavored variable in the next commit. The code above can be written as follows: [Example Code] success = $(shell,($(1)) >/dev/null 2>&1 && echo y || echo n) cc-option = $(success,$(CC) -Werror $(1) -E -x c /dev/null -o /dev/null) config CC_HAS_STACKPROTECTOR def_bool $(cc-option,-fstack-protector) [Result] $ make -s alldefconfig && tail -n 1 .config CONFIG_CC_HAS_STACKPROTECTOR=y Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Diffstat (limited to 'scripts/kconfig/zconf.y')
-rw-r--r--scripts/kconfig/zconf.y19
1 files changed, 18 insertions, 1 deletions
diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y
index 8a82aaf27581..e15e8c7063e0 100644
--- a/scripts/kconfig/zconf.y
+++ b/scripts/kconfig/zconf.y
@@ -77,6 +77,9 @@ static struct menu *current_menu, *current_entry;
%token T_CLOSE_PAREN
%token T_OPEN_PAREN
%token T_EOL
+%token <string> T_VARIABLE
+%token T_ASSIGN
+%token <string> T_ASSIGN_VAL
%left T_OR
%left T_AND
@@ -92,7 +95,7 @@ static struct menu *current_menu, *current_entry;
%type <id> end
%type <id> option_name
%type <menu> if_entry menu_entry choice_entry
-%type <string> symbol_option_arg word_opt
+%type <string> symbol_option_arg word_opt assign_val
%destructor {
fprintf(stderr, "%s:%d: missing end statement for this entry\n",
@@ -143,6 +146,7 @@ common_stmt:
| config_stmt
| menuconfig_stmt
| source_stmt
+ | assignment_stmt
;
option_error:
@@ -511,6 +515,15 @@ symbol: nonconst_symbol
word_opt: /* empty */ { $$ = NULL; }
| T_WORD
+/* assignment statement */
+
+assignment_stmt: T_VARIABLE T_ASSIGN assign_val T_EOL { variable_add($1, $3); free($1); free($3); }
+
+assign_val:
+ /* empty */ { $$ = xstrdup(""); };
+ | T_ASSIGN_VAL
+;
+
%%
void conf_parse(const char *name)
@@ -525,6 +538,10 @@ void conf_parse(const char *name)
if (getenv("ZCONF_DEBUG"))
yydebug = 1;
yyparse();
+
+ /* Variables are expanded in the parse phase. We can free them here. */
+ variable_all_del();
+
if (yynerrs)
exit(1);
if (!modules_sym)