]> git.ozlabs.org Git - petitboot/blobdiff - discover/grub2/grub2-lexer.l
discover/pb-discover: #include <locale.h> for musl libc
[petitboot] / discover / grub2 / grub2-lexer.l
index 066af6073baa78012a8dd7d513696adb96eefaa9..b55a71578a93413f1be1251bc3e680a9b9bc3097 100644 (file)
@@ -22,14 +22,15 @@ void yyerror(struct grub2_parser *parser, const char *fmt, ...);
 %x dqstring
 
 WORD   [^{}|&$;<> \t\n'"#]+
-VARNAME ([[:alpha:]][_[:alnum:]]*|[0-9]|[\?@\*#])
+DELIM  [ \t]+
+BLANK  ["]{2}|[']{2}
+NUMBER 0|[1-9][0-9]*
+VARNAME ([[:alpha:]][_[:alnum:]]*|{NUMBER}|[\?@\*#])
 
 %%
 
- /* discard leading & trailing whitespace, but keep inter-word delimeters */
-^[ \t]+        ;
-[ \t]+$        ;
-[ \t]+ return TOKEN_DELIM;
+ /* discard whitespace, unless we're looking for inter-word delimiters */
+{DELIM}             { if (yyget_extra(yyscanner)->inter_word) return TOKEN_DELIM; }
 
  /* reserved words */
 "[["         return TOKEN_LDSQBRACKET;
@@ -53,9 +54,16 @@ VARNAME ([[:alpha:]][_[:alnum:]]*|[0-9]|[\?@\*#])
 "until"      return TOKEN_UTIL;
 "while"      return TOKEN_WHILE;
 
+ /* ignore quoted empty strings */
+{BLANK} {
+               yylval->word = create_word_text(yyget_extra(yyscanner), "");
+               yyget_extra(yyscanner)->inter_word = true;
+               return TOKEN_WORD;
+       }
  /* anything that's not a metachar: return as a plain word */
 {WORD} {
                yylval->word = create_word_text(yyget_extra(yyscanner), yytext);
+               yyget_extra(yyscanner)->inter_word = true;
                return TOKEN_WORD;
        }
 
@@ -68,6 +76,7 @@ VARNAME ([[:alpha:]][_[:alnum:]]*|[0-9]|[\?@\*#])
                yytext++;
                yylval->word = create_word_var(yyget_extra(yyscanner), yytext,
                                                true);
+               yyget_extra(yyscanner)->inter_word = true;
                return TOKEN_WORD;
        }
 
@@ -80,6 +89,7 @@ VARNAME ([[:alpha:]][_[:alnum:]]*|[0-9]|[\?@\*#])
        }
 <sqstring>[^']+ {
                yylval->word = create_word_text(yyget_extra(yyscanner), yytext);
+               yyget_extra(yyscanner)->inter_word = true;
                return TOKEN_WORD;
        }
 
@@ -92,6 +102,7 @@ VARNAME ([[:alpha:]][_[:alnum:]]*|[0-9]|[\?@\*#])
        }
 <dqstring>([^"\$]|\\\")+ {
                yylval->word = create_word_text(yyget_extra(yyscanner), yytext);
+               yyget_extra(yyscanner)->inter_word = true;
                return TOKEN_WORD;
        }
 <dqstring>\${VARNAME} |
@@ -103,17 +114,21 @@ VARNAME ([[:alpha:]][_[:alnum:]]*|[0-9]|[\?@\*#])
                yytext++;
                yylval->word = create_word_var(yyget_extra(yyscanner), yytext,
                                                false);
+               yyget_extra(yyscanner)->inter_word = true;
                return TOKEN_WORD;
        }
 
 
 
  /* blocks */
-"{"    return '{';
-"}"    return '}';
+"{"    { yyget_extra(yyscanner)->inter_word = false; return '{'; }
+"}"    { yyget_extra(yyscanner)->inter_word = false; return '}'; }
 
  /* end-of-line */
-[ \t]*(;|\n)[ \t]*     return TOKEN_EOL;
+[ \t]*(;|\n)[ \t]*     {
+               yyget_extra(yyscanner)->inter_word = false;
+               return TOKEN_EOL;
+       }
 
  /* strip comments */
 #.*    ;