kconfig: expand lefthand side of assignment statement
[carl9170fw.git] / config / zconf.l
index 3bf7a27e0a280f13087edfa603dcb609950c4a1c..d2d9d87bea6ea63bcfa6dec6b33b06ce4fad5289 100644 (file)
@@ -1,13 +1,13 @@
 %option nostdinit noyywrap never-interactive full ecs
 %option 8bit nodefault yylineno
-%option noinput
-%x COMMAND HELP STRING PARAM
+%x COMMAND HELP STRING PARAM ASSIGN_VAL
 %{
 /*
  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
  * Released under the terms of the GNU GPL v2.0.
  */
 
+#include <assert.h>
 #include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -35,6 +35,8 @@ struct buffer *current_buf;
 
 static int last_ts, first_ts;
 
+static char *expand_token(const char *in, size_t n);
+static void append_expanded_string(const char *in);
 static void zconf_endhelp(void);
 static void zconf_endfile(void);
 
@@ -101,17 +103,28 @@ n [A-Za-z0-9_-]
 <COMMAND>{
        {n}+    {
                const struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
-               BEGIN(PARAM);
                current_pos.file = current_file;
                current_pos.lineno = yylineno;
                if (id && id->flags & TF_COMMAND) {
+                       BEGIN(PARAM);
                        yylval.id = id;
                        return id->token;
                }
                alloc_string(yytext, yyleng);
                yylval.string = text;
-               return T_WORD;
+               return T_VARIABLE;
        }
+       ({n}|$)+        {
+               /* this token includes at least one '$' */
+               yylval.string = expand_token(yytext, yyleng);
+               if (strlen(yylval.string))
+                       return T_VARIABLE;
+               free(yylval.string);
+       }
+       "="     { 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      {
                BEGIN(INITIAL);
@@ -119,6 +132,16 @@ n  [A-Za-z0-9_-]
        }
 }
 
+<ASSIGN_VAL>{
+       [^[:blank:]\n]+.*       {
+               alloc_string(yytext, yyleng);
+               yylval.string = text;
+               return T_ASSIGN_VAL;
+       }
+       \n      { BEGIN(INITIAL); return T_EOL; }
+       .
+}
+
 <PARAM>{
        "&&"    return T_AND;
        "||"    return T_OR;
@@ -147,6 +170,13 @@ n  [A-Za-z0-9_-]
                yylval.string = text;
                return T_WORD;
        }
+       ({n}|[/.$])+    {
+               /* this token includes at least one '$' */
+               yylval.string = expand_token(yytext, yyleng);
+               if (strlen(yylval.string))
+                       return T_WORD;
+               free(yylval.string);
+       }
        #.*     /* comment */
        \\\n    ;
        [[:blank:]]+
@@ -157,12 +187,13 @@ n [A-Za-z0-9_-]
 }
 
 <STRING>{
-       [^'"\\\n]+/\n   {
+       "$".*   append_expanded_string(yytext);
+       [^$'"\\\n]+/\n  {
                append_string(yytext, yyleng);
                yylval.string = text;
                return T_WORD_QUOTE;
        }
-       [^'"\\\n]+      {
+       [^$'"\\\n]+     {
                append_string(yytext, yyleng);
        }
        \\.?/\n {
@@ -249,6 +280,58 @@ n  [A-Za-z0-9_-]
 }
 
 %%
+static char *expand_token(const char *in, size_t n)
+{
+       char *out;
+       int c;
+       char c2;
+       const char *rest, *end;
+
+       new_string();
+       append_string(in, n);
+
+       /* get the whole line because we do not know the end of token. */
+       while ((c = input()) != EOF) {
+               if (c == '\n') {
+                       unput(c);
+                       break;
+               }
+               c2 = c;
+               append_string(&c2, 1);
+       }
+
+       rest = text;
+       out = expand_one_token(&rest);
+
+       /* push back unused characters to the input stream */
+       end = rest + strlen(rest);
+       while (end > rest)
+               unput(*--end);
+
+       free(text);
+
+       return out;
+}
+
+static void append_expanded_string(const char *str)
+{
+       const char *end;
+       char *res;
+
+       str++;
+
+       res = expand_dollar(&str);
+
+       /* push back unused characters to the input stream */
+       end = str + strlen(str);
+       while (end > str)
+               unput(*--end);
+
+       append_string(res, strlen(res));
+
+       free(res);
+}
+
 void zconf_starthelp(void)
 {
        new_string();