]> git.ozlabs.org Git - petitboot/blobdiff - discover/grub2/lexer.l
ui/ncurses: Always provide a key definition for backtab
[petitboot] / discover / grub2 / lexer.l
index 18d16672e59d4c07019cbcb3ce3d8215ca0fa2da..e1aad9931252f98be623a5fc87035a61f3de4ef2 100644 (file)
@@ -1,15 +1,20 @@
 
 %{
+#include "grub2.h"
 #include "parser.h"
 #include <talloc/talloc.h>
+
+void yyerror(struct grub2_parser *parser, const char *fmt, ...);
 %}
 
 %option nounput noinput
+%option batch never-interactive
 %option warn
 %option noyywrap
 %option stack noyy_top_state
 %option reentrant
 %option bison-bridge
+%option yylineno
 %option noyyalloc noyyfree noyyrealloc
 %option extra-type="struct grub2_parser *"
 %option header-file="lexer.h"
@@ -18,7 +23,7 @@
 %x sqstring
 %x dqstring
 
-WORD   [^{}|&$;<> \t\n'"]+
+WORD   [^{}|&$;<> \t\n'"#]+
 VARNAME ([[:alpha:]][_[:alnum:]]*|[0-9]|[\?@\*#])
 
 %%
@@ -26,7 +31,7 @@ VARNAME ([[:alpha:]][_[:alnum:]]*|[0-9]|[\?@\*#])
  /* discard leading & trailing whitespace, but keep inter-word delimeters */
 ^[ \t]+        ;
 [ \t]+$        ;
-[ \t]* return TOKEN_DELIM;
+[ \t]+ return TOKEN_DELIM;
 
  /* reserved words */
 "[["         return TOKEN_LDSQBRACKET;
@@ -35,6 +40,7 @@ VARNAME ([[:alpha:]][_[:alnum:]]*|[0-9]|[\?@\*#])
 "do"         return TOKEN_DO;
 "done"       return TOKEN_DONE;
 "elif"       return TOKEN_ELIF;
+"else"       return TOKEN_ELSE;
 "esac"       return TOKEN_ESAC;
 "fi"         return TOKEN_FI;
 "for"        return TOKEN_FOR;
@@ -43,6 +49,7 @@ VARNAME ([[:alpha:]][_[:alnum:]]*|[0-9]|[\?@\*#])
 "in"         return TOKEN_IN;
 "menuentry"  return TOKEN_MENUENTRY;
 "select"     return TOKEN_SELECT;
+"submenu"    return TOKEN_SUBMENU;
 "then"       return TOKEN_THEN;
 "time"       return TOKEN_TIME;
 "until"      return TOKEN_UTIL;
@@ -50,16 +57,19 @@ VARNAME ([[:alpha:]][_[:alnum:]]*|[0-9]|[\?@\*#])
 
  /* anything that's not a metachar: return as a plain word */
 {WORD} {
-               yylval->strval = talloc_strdup(yyscanner, yytext);
-               yylval->expand = 0;
+               yylval->word = create_word_text(yyget_extra(yyscanner), yytext);
                return TOKEN_WORD;
        }
 
 \${VARNAME} |
 \$\{{VARNAME}\} {
-               yylval->strval = talloc_strdup(yyscanner, yytext);
-               yylval->expand = 1;
-               yylval->split = 1;
+               if (yytext[1] == '{') {
+                       yytext[yyleng-1] = '\0';
+                       yytext++;
+               }
+               yytext++;
+               yylval->word = create_word_var(yyget_extra(yyscanner), yytext,
+                                               true);
                return TOKEN_WORD;
        }
 
@@ -69,12 +79,10 @@ VARNAME ([[:alpha:]][_[:alnum:]]*|[0-9]|[\?@\*#])
        }
 <sqstring>\' {
                yy_pop_state(yyscanner);
-               return TOKEN_WORD;
        }
 <sqstring>[^']+ {
-               yylval->expand = 0;
-               yylval->split = 0;
-               yylval->strval = talloc_strdup(yyscanner, yytext);
+               yylval->word = create_word_text(yyget_extra(yyscanner), yytext);
+               return TOKEN_WORD;
        }
 
  /* double-quoted strings: return a single, expanded word token */
@@ -83,15 +91,25 @@ VARNAME ([[:alpha:]][_[:alnum:]]*|[0-9]|[\?@\*#])
        }
 <dqstring>\" {
                yy_pop_state(yyscanner);
+       }
+<dqstring>([^"\$]|\\\")+ {
+               yylval->word = create_word_text(yyget_extra(yyscanner), yytext);
                return TOKEN_WORD;
        }
-<dqstring>([^"]|\\\")+ {
-               yylval->expand = 1;
-               yylval->split = 0;
-               yylval->strval = talloc_strdup(yyscanner, yytext);
+<dqstring>\${VARNAME} |
+<dqstring>\$\{{VARNAME}\} {
+               if (yytext[1] == '{') {
+                       yytext[yyleng-1] = '\0';
+                       yytext++;
+               }
+               yytext++;
+               yylval->word = create_word_var(yyget_extra(yyscanner), yytext,
+                                               false);
+               return TOKEN_WORD;
        }
 
 
+
  /* blocks */
 "{"    return '{';
 "}"    return '}';
@@ -100,10 +118,12 @@ VARNAME ([[:alpha:]][_[:alnum:]]*|[0-9]|[\?@\*#])
 [ \t]*(;|\n)[ \t]*     return TOKEN_EOL;
 
  /* strip comments */
-#.*$   ;
+#.*    ;
 
-
-.      printf("unknown token '%s'\n", yytext); exit(1);
+.      {
+               yyerror(yyget_extra(yyscanner), "unknown token '%s'\n", yytext);
+               yyterminate();
+       }
 
 %%