kconfig: support append assignment operator
authorMasahiro Yamada <yamada.masahiro@socionext.com>
Mon, 28 May 2018 09:21:51 +0000 (18:21 +0900)
committerChristian Lamparter <chunkeey@gmail.com>
Sun, 10 Feb 2019 21:13:34 +0000 (22:13 +0100)
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>
Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
config/lkc_proto.h
config/preprocess.c
config/zconf.l

index 6303193f43f21c978b8e685b13e1f8672324d663..a8b7a330587e80f45a0bce6714445b3ef0ac51b1 100644 (file)
@@ -52,6 +52,7 @@ const char * prop_get_type_name(enum prop_type type);
 enum variable_flavor {
        VAR_SIMPLE,
        VAR_RECURSIVE,
+       VAR_APPEND,
 };
 void env_write_dep(FILE *f, const char *auto_conf_name);
 void variable_add(const char *name, const char *value,
index d103683b386edc551ffc526d28bf74434856d7b1..56aa1f0bad0422eab2d1f1f2eb1f8d79f99b769c 100644 (file)
@@ -222,11 +222,23 @@ void variable_add(const char *name, const char *value,
                  enum variable_flavor flavor)
 {
        struct variable *v;
+       char *new_value;
+       bool append = false;
 
        v = variable_lookup(name);
        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 {
+               /* For undefined variables, += assumes the recursive flavor */
+               if (flavor == VAR_APPEND)
+                       flavor = VAR_RECURSIVE;
+
                v = xmalloc(sizeof(*v));
                v->name = xstrdup(name);
                list_add_tail(&v->node, &variable_list);
@@ -235,9 +247,19 @@ void variable_add(const char *name, const char *value,
        v->flavor = flavor;
 
        if (flavor == VAR_SIMPLE)
-               v->value = expand_string(value);
+               new_value = expand_string(value);
        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)
index d0f5b132a9b39802680a3f07343d0c36bf83e4ee..62a0973bee034f4c4fd23bd16f2f1c131665fe3c 100644 (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_SIMPLE; return T_ASSIGN; }
+       "+="    { BEGIN(ASSIGN_VAL); yylval.flavor = VAR_APPEND; return T_ASSIGN; }
        [[:blank:]]+
        .       warn_ignored_character(*yytext);
        \n      {