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>
diff --git a/scripts/kconfig/preprocess.c b/scripts/kconfig/preprocess.c
index d103683..56aa1f0 100644
--- a/scripts/kconfig/preprocess.c
+++ b/scripts/kconfig/preprocess.c
@@ -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)