kconfig: support append assignment operator

Support += operator.  This appends a space and the text on the
righthand side to a variable.

The timing of the evaluation of the righthand side depends on the
flavor of the variable.  If the lefthand side was originally defined
as a simple variable, the righthand side is expanded immediately.
Otherwise, the expansion is deferred.  Appending something to an
undefined variable results in a recursive variable.

To implement this, we need to remember the flavor of variables.

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
This commit is contained in:
Masahiro Yamada 2018-05-28 18:21:51 +09:00
parent 1175c02506
commit ed2a22f277
3 changed files with 27 additions and 3 deletions

View File

@ -52,6 +52,7 @@ const char * prop_get_type_name(enum prop_type type);
enum variable_flavor { enum variable_flavor {
VAR_SIMPLE, VAR_SIMPLE,
VAR_RECURSIVE, VAR_RECURSIVE,
VAR_APPEND,
}; };
void env_write_dep(FILE *f, const char *auto_conf_name); void env_write_dep(FILE *f, const char *auto_conf_name);
void variable_add(const char *name, const char *value, void variable_add(const char *name, const char *value,

View File

@ -222,11 +222,23 @@ void variable_add(const char *name, const char *value,
enum variable_flavor flavor) enum variable_flavor flavor)
{ {
struct variable *v; struct variable *v;
char *new_value;
bool append = false;
v = variable_lookup(name); v = variable_lookup(name);
if (v) { if (v) {
free(v->value); /* For defined variables, += inherits the existing flavor */
if (flavor == VAR_APPEND) {
flavor = v->flavor;
append = true;
} else {
free(v->value);
}
} else { } else {
/* For undefined variables, += assumes the recursive flavor */
if (flavor == VAR_APPEND)
flavor = VAR_RECURSIVE;
v = xmalloc(sizeof(*v)); v = xmalloc(sizeof(*v));
v->name = xstrdup(name); v->name = xstrdup(name);
list_add_tail(&v->node, &variable_list); list_add_tail(&v->node, &variable_list);
@ -235,9 +247,19 @@ void variable_add(const char *name, const char *value,
v->flavor = flavor; v->flavor = flavor;
if (flavor == VAR_SIMPLE) if (flavor == VAR_SIMPLE)
v->value = expand_string(value); new_value = expand_string(value);
else else
v->value = xstrdup(value); new_value = xstrdup(value);
if (append) {
v->value = xrealloc(v->value,
strlen(v->value) + strlen(new_value) + 2);
strcat(v->value, " ");
strcat(v->value, new_value);
free(new_value);
} else {
v->value = new_value;
}
} }
static void variable_del(struct variable *v) static void variable_del(struct variable *v)

View File

@ -116,6 +116,7 @@ n [A-Za-z0-9_-]
} }
"=" { BEGIN(ASSIGN_VAL); yylval.flavor = VAR_RECURSIVE; return T_ASSIGN; } "=" { BEGIN(ASSIGN_VAL); yylval.flavor = VAR_RECURSIVE; return T_ASSIGN; }
":=" { BEGIN(ASSIGN_VAL); yylval.flavor = VAR_SIMPLE; return T_ASSIGN; } ":=" { BEGIN(ASSIGN_VAL); yylval.flavor = VAR_SIMPLE; return T_ASSIGN; }
"+=" { BEGIN(ASSIGN_VAL); yylval.flavor = VAR_APPEND; return T_ASSIGN; }
[[:blank:]]+ [[:blank:]]+
. warn_ignored_character(*yytext); . warn_ignored_character(*yytext);
\n { \n {