kconfig: update current_pos in the second lexer
[carl9170fw.git] / config / zconf.l
index 40ccc135fa1d568cba6fb44338374b54a2f954f4..052a9864b7ec5bd2a5b09f3313f10408d8b3538e 100644 (file)
@@ -16,6 +16,8 @@
 
 #include "lkc.h"
 
+#define YY_DECL                static int yylex1(void)
+
 #define START_STRSIZE  16
 
 static struct {
@@ -23,6 +25,8 @@ static struct {
        int lineno;
 } current_pos;
 
+static int prev_prev_token = T_EOL;
+static int prev_token = T_EOL;
 static char *text;
 static int text_size, text_asize;
 
@@ -88,12 +92,6 @@ n    [A-Za-z0-9_-]
        return T_EOL;
 }
 [ \t]*#.*
-
-
-[ \t]+ {
-       BEGIN(COMMAND);
-}
-
 .      {
        unput(yytext[0]);
        BEGIN(COMMAND);
@@ -103,27 +101,24 @@ n [A-Za-z0-9_-]
 <COMMAND>{
        {n}+    {
                const struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
-               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_VARIABLE;
+               return T_WORD;
        }
        ({n}|$)+        {
                /* this token includes at least one '$' */
                yylval.string = expand_token(yytext, yyleng);
                if (strlen(yylval.string))
-                       return T_VARIABLE;
+                       return T_WORD;
                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; }
+       "="     return T_EQUAL;
+       ":="    return T_COLON_EQUAL;
+       "+="    return T_PLUS_EQUAL;
        [[:blank:]]+
        .       warn_ignored_character(*yytext);
        \n      {
@@ -143,6 +138,9 @@ n   [A-Za-z0-9_-]
 }
 
 <PARAM>{
+       "modules"               return T_MODULES;
+       "defconfig_list"        return T_DEFCONFIG_LIST;
+       "allnoconfig_y"         return T_ALLNOCONFIG_Y;
        "&&"    return T_AND;
        "||"    return T_OR;
        "("     return T_OPEN_PAREN;
@@ -160,17 +158,16 @@ n [A-Za-z0-9_-]
                BEGIN(STRING);
        }
        \n      BEGIN(INITIAL); return T_EOL;
-       ({n}|[/.])+     {
+       {n}+    {
                const struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
                if (id && id->flags & TF_PARAM) {
-                       yylval.id = id;
                        return id->token;
                }
                alloc_string(yytext, yyleng);
                yylval.string = text;
                return T_WORD;
        }
-       ({n}|[/.$])+    {
+       ({n}|$)+        {
                /* this token includes at least one '$' */
                yylval.string = expand_token(yytext, yyleng);
                if (strlen(yylval.string))
@@ -181,26 +178,13 @@ n [A-Za-z0-9_-]
        \\\n    ;
        [[:blank:]]+
        .       warn_ignored_character(*yytext);
-       <<EOF>> {
-               BEGIN(INITIAL);
-       }
 }
 
 <STRING>{
        "$".*   append_expanded_string(yytext);
-       [^$'"\\\n]+/\n  {
-               append_string(yytext, yyleng);
-               yylval.string = text;
-               return T_WORD_QUOTE;
-       }
        [^$'"\\\n]+     {
                append_string(yytext, yyleng);
        }
-       \\.?/\n {
-               append_string(yytext + 1, yyleng - 1);
-               yylval.string = text;
-               return T_WORD_QUOTE;
-       }
        \\.?    {
                append_string(yytext + 1, yyleng - 1);
        }
@@ -216,8 +200,10 @@ n  [A-Za-z0-9_-]
                fprintf(stderr,
                        "%s:%d:warning: multi-line strings not supported\n",
                        zconf_curname(), zconf_lineno());
+               unput('\n');
                BEGIN(INITIAL);
-               return T_EOL;
+               yylval.string = text;
+               return T_WORD_QUOTE;
        }
        <<EOF>> {
                BEGIN(INITIAL);
@@ -273,6 +259,12 @@ n  [A-Za-z0-9_-]
 }
 
 <<EOF>>        {
+       BEGIN(INITIAL);
+
+       if (prev_token != T_EOL && prev_token != T_HELPTEXT)
+               fprintf(stderr, "%s:%d:warning: no new line at end of file\n",
+                       current_file->name, yylineno);
+
        if (current_file) {
                zconf_endfile();
                return T_EOL;
@@ -282,6 +274,41 @@ n  [A-Za-z0-9_-]
 }
 
 %%
+
+/* second stage lexer */
+int yylex(void)
+{
+       int token;
+
+repeat:
+       token = yylex1();
+
+       if (prev_token == T_EOL || prev_token == T_HELPTEXT) {
+               if (token == T_EOL) {
+                       /* Do not pass unneeded T_EOL to the parser. */
+                       goto repeat;
+               } else {
+                       /*
+                        * For the parser, update file/lineno at the first token
+                        * of each statement. Generally, \n is a statement
+                        * terminator in Kconfig, but it is not always true
+                        * because \n could be escaped by a backslash.
+                        */
+                       current_pos.file = current_file;
+                       current_pos.lineno = yylineno;
+               }
+       }
+
+       if (prev_prev_token == T_EOL && prev_token == T_WORD &&
+           (token == T_EQUAL || token == T_COLON_EQUAL || token == T_PLUS_EQUAL))
+               BEGIN(ASSIGN_VAL);
+
+       prev_prev_token = prev_token;
+       prev_token = token;
+
+       return token;
+}
+
 static char *expand_token(const char *in, size_t n)
 {
        char *out;