kconfig: use T_WORD instead of T_VARIABLE for variables
[carl9170fw.git] / config / zconf.l
index a0eec5ae617684b06f8f44c3ca7d2ac403ec37b8..eec4a5a97639d509104da10d367e95fa9039eadd 100644 (file)
@@ -1,13 +1,13 @@
 %option nostdinit noyywrap never-interactive full ecs
-%option 8bit nodefault perf-report perf-report
-%option noinput
-%x COMMAND HELP STRING PARAM
+%option 8bit nodefault yylineno
+%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>
@@ -16,6 +16,8 @@
 
 #include "lkc.h"
 
+#define YY_DECL                static int yylex1(void)
+
 #define START_STRSIZE  16
 
 static struct {
@@ -23,18 +25,21 @@ static struct {
        int lineno;
 } current_pos;
 
+static int prev_token = T_EOL;
 static char *text;
 static int text_size, text_asize;
 
 struct buffer {
-        struct buffer *parent;
-        YY_BUFFER_STATE state;
+       struct buffer *parent;
+       YY_BUFFER_STATE state;
 };
 
 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);
 
@@ -52,7 +57,7 @@ static void append_string(const char *str, int size)
        if (new_size > text_asize) {
                new_size += START_STRSIZE - 1;
                new_size &= -START_STRSIZE;
-               text = realloc(text, new_size);
+               text = xrealloc(text, new_size);
                text_asize = new_size;
        }
        memcpy(text + text_size, str, size);
@@ -66,9 +71,16 @@ static void alloc_string(const char *str, int size)
        memcpy(text, str, size);
        text[size] = 0;
 }
+
+static void warn_ignored_character(char chr)
+{
+       fprintf(stderr,
+               "%s:%d:warning: ignoring unsupported character '%c'\n",
+               current_file->name, yylineno, chr);
+}
 %}
 
-n      [A-Za-z0-9_]
+n      [A-Za-z0-9_-]
 
 %%
        int str = 0;
@@ -76,16 +88,9 @@ n    [A-Za-z0-9_]
 
 [ \t]*#.*\n    |
 [ \t]*\n       {
-       current_file->lineno++;
        return T_EOL;
 }
 [ \t]*#.*
-
-
-[ \t]+ {
-       BEGIN(COMMAND);
-}
-
 .      {
        unput(yytext[0]);
        BEGIN(COMMAND);
@@ -95,26 +100,49 @@ 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 = current_file->lineno;
+               current_pos.lineno = yylineno;
                if (id && id->flags & TF_COMMAND) {
-                       zconflval.id = id;
+                       BEGIN(PARAM);
+                       yylval.id = id;
                        return id->token;
                }
                alloc_string(yytext, yyleng);
-               zconflval.string = text;
+               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);
+       }
+       "="     { BEGIN(ASSIGN_VAL); return T_EQUAL; }
+       ":="    { BEGIN(ASSIGN_VAL); return T_COLON_EQUAL; }
+       "+="    { BEGIN(ASSIGN_VAL); return T_PLUS_EQUAL; }
+       [[:blank:]]+
+       .       warn_ignored_character(*yytext);
        \n      {
                BEGIN(INITIAL);
-               current_file->lineno++;
                return T_EOL;
        }
 }
 
+<ASSIGN_VAL>{
+       [^[:blank:]\n]+.*       {
+               alloc_string(yytext, yyleng);
+               yylval.string = text;
+               return T_ASSIGN_VAL;
+       }
+       \n      { BEGIN(INITIAL); return T_EOL; }
+       .
+}
+
 <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;
@@ -122,64 +150,68 @@ n [A-Za-z0-9_]
        "!"     return T_NOT;
        "="     return T_EQUAL;
        "!="    return T_UNEQUAL;
+       "<="    return T_LESS_EQUAL;
+       ">="    return T_GREATER_EQUAL;
+       "<"     return T_LESS;
+       ">"     return T_GREATER;
        \"|\'   {
                str = yytext[0];
                new_string();
                BEGIN(STRING);
        }
-       \n      BEGIN(INITIAL); current_file->lineno++; return T_EOL;
-       ---     /* ignore */
-       ({n}|[-/.])+    {
+       \n      BEGIN(INITIAL); return T_EOL;
+       ({n}|[/.])+     {
                const struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
                if (id && id->flags & TF_PARAM) {
-                       zconflval.id = id;
+                       yylval.id = id;
                        return id->token;
                }
                alloc_string(yytext, yyleng);
-               zconflval.string = text;
+               yylval.string = text;
                return T_WORD;
        }
-       #.*     /* comment */
-       \\\n    current_file->lineno++;
-       .
-       <<EOF>> {
-               BEGIN(INITIAL);
+       ({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:]]+
+       .       warn_ignored_character(*yytext);
 }
 
 <STRING>{
-       [^'"\\\n]+/\n   {
-               append_string(yytext, yyleng);
-               zconflval.string = text;
-               return T_WORD_QUOTE;
-       }
-       [^'"\\\n]+      {
+       "$".*   append_expanded_string(yytext);
+       [^$'"\\\n]+     {
                append_string(yytext, yyleng);
        }
-       \\.?/\n {
-               append_string(yytext + 1, yyleng - 1);
-               zconflval.string = text;
-               return T_WORD_QUOTE;
-       }
        \\.?    {
                append_string(yytext + 1, yyleng - 1);
        }
        \'|\"   {
                if (str == yytext[0]) {
                        BEGIN(PARAM);
-                       zconflval.string = text;
+                       yylval.string = text;
                        return T_WORD_QUOTE;
                } else
                        append_string(yytext, 1);
        }
        \n      {
-               printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno());
-               current_file->lineno++;
+               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);
+               yylval.string = text;
+               return T_WORD_QUOTE;
        }
 }
 
@@ -207,12 +239,10 @@ n [A-Za-z0-9_]
                }
        }
        [ \t]*\n/[^ \t\n] {
-               current_file->lineno++;
                zconf_endhelp();
                return T_HELPTEXT;
        }
        [ \t]*\n        {
-               current_file->lineno++;
                append_string("\n", 1);
        }
        [^ \t\n].* {
@@ -232,6 +262,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;
@@ -241,6 +277,76 @@ n  [A-Za-z0-9_]
 }
 
 %%
+
+/* second stage lexer */
+int yylex(void)
+{
+       int token;
+
+repeat:
+       token = yylex1();
+
+       /* Do not pass unneeded T_EOL to the parser. */
+       if ((prev_token == T_EOL || prev_token == T_HELPTEXT) && token == T_EOL)
+               goto repeat;
+
+       prev_token = token;
+
+       return token;
+}
+
+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();
@@ -250,7 +356,7 @@ void zconf_starthelp(void)
 
 static void zconf_endhelp(void)
 {
-       zconflval.string = text;
+       yylval.string = text;
        BEGIN(INITIAL);
 }
 
@@ -283,7 +389,7 @@ void zconf_initscan(const char *name)
 {
        yyin = zconf_fopen(name);
        if (!yyin) {
-               printf("can't find file %s\n", name);
+               fprintf(stderr, "can't find file %s\n", name);
                exit(1);
        }
 
@@ -291,7 +397,7 @@ void zconf_initscan(const char *name)
        memset(current_buf, 0, sizeof(*current_buf));
 
        current_file = file_lookup(name);
-       current_file->lineno = 1;
+       yylineno = 1;
 }
 
 void zconf_nextfile(const char *name)
@@ -304,35 +410,34 @@ void zconf_nextfile(const char *name)
        current_buf->state = YY_CURRENT_BUFFER;
        yyin = zconf_fopen(file->name);
        if (!yyin) {
-               printf("%s:%d: can't open file \"%s\"\n",
-                   zconf_curname(), zconf_lineno(), file->name);
+               fprintf(stderr, "%s:%d: can't open file \"%s\"\n",
+                       zconf_curname(), zconf_lineno(), file->name);
                exit(1);
        }
        yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
        buf->parent = current_buf;
        current_buf = buf;
 
-       for (iter = current_file->parent; iter; iter = iter->parent ) {
-               if (!strcmp(current_file->name,iter->name) ) {
-                       printf("%s:%d: recursive inclusion detected. "
-                              "Inclusion path:\n  current file : '%s'\n",
-                              zconf_curname(), zconf_lineno(),
-                              zconf_curname());
-                       iter = current_file->parent;
-                       while (iter && \
-                              strcmp(iter->name,current_file->name)) {
-                               printf("  included from: '%s:%d'\n",
-                                      iter->name, iter->lineno-1);
+       current_file->lineno = yylineno;
+       file->parent = current_file;
+
+       for (iter = current_file; iter; iter = iter->parent) {
+               if (!strcmp(iter->name, file->name)) {
+                       fprintf(stderr,
+                               "Recursive inclusion detected.\n"
+                               "Inclusion path:\n"
+                               "  current file : %s\n", file->name);
+                       iter = file;
+                       do {
                                iter = iter->parent;
-                       }
-                       if (iter)
-                               printf("  included from: '%s:%d'\n",
-                                      iter->name, iter->lineno+1);
+                               fprintf(stderr, "  included from: %s:%d\n",
+                                       iter->name, iter->lineno - 1);
+                       } while (strcmp(iter->name, file->name));
                        exit(1);
                }
        }
-       file->lineno = 1;
-       file->parent = current_file;
+
+       yylineno = 1;
        current_file = file;
 }
 
@@ -341,6 +446,8 @@ static void zconf_endfile(void)
        struct buffer *parent;
 
        current_file = current_file->parent;
+       if (current_file)
+               yylineno = current_file->lineno;
 
        parent = current_buf->parent;
        if (parent) {