#define YY_INPUT(buf,res,max) do { res = 0; } while (0)
/* forward declarations */
+static int resplit (const char *input, yyscan_t yyscanner);
static void grub_lexer_yyfree (void *, yyscan_t yyscanner);
static void* grub_lexer_yyalloc (yy_size_t, yyscan_t yyscanner);
static void* grub_lexer_yyrealloc (void*, yy_size_t, yyscan_t yyscanner);
ESC \\.
VARIABLE ${NAME}|$\{{NAME}\}|${DIGITS}|$\{{DIGITS}\}|$\?|$\{\?\}
-DQSTR \"([^\\\"]|{ESC})*\"
-SQSTR \'[^\']*\'
+DQSTR \"([^\"]|{ESC})*\"
+SQSTR \'([^\'])*\'
WORD ({CHAR}|{DQSTR}|{SQSTR}|{ESC}|{VARIABLE})+
+DQSTR2 {WORD}?\"({ESC}|[^\"])*\n
+SQSTR2 {WORD}?\'({ESC}|[^\'])*\n
+
%x SPLIT
%x DQUOTE
%x SQUOTE
%x VAR
+%x DQMULTILINE
+%x SQMULTILINE
%%
{NAME} { RECORD; return GRUB_PARSER_TOKEN_NAME; }
{WORD} {
RECORD;
- /* resplit yytext */
- grub_dprintf ("lexer", "word: [%s]\n", yytext);
- yypush_buffer_state (YY_CURRENT_BUFFER, yyscanner);
- if (yy_scan_string (yytext, yyscanner))
- {
- yyextra->lexerstate->merge_start = 1;
- yy_push_state (SPLIT, yyscanner);
- }
- else
- {
- grub_script_yyerror (yyextra, 0);
- yypop_buffer_state (yyscanner);
- return GRUB_PARSER_TOKEN_WORD;
- }
+ yypush_buffer_state (YY_CURRENT_BUFFER, yyscanner);
+ if (resplit (yytext, yyscanner))
+ {
+ yypop_buffer_state (yyscanner);
+ return GRUB_PARSER_TOKEN_WORD;
+ }
}
+{DQSTR2} {
+ yy_push_state (DQMULTILINE, yyscanner);
+ grub_script_lexer_ref (yyextra->lexerstate);
+ yymore ();
+ }
+<DQMULTILINE>{
+ \"{WORD}? {
+ RECORD;
+ grub_script_lexer_deref (yyextra->lexerstate);
+ yy_pop_state (yyscanner);
+ yypush_buffer_state (YY_CURRENT_BUFFER, yyscanner);
+ if (resplit (yytext, yyscanner))
+ {
+ yypop_buffer_state (yyscanner);
+ return GRUB_PARSER_TOKEN_WORD;
+ }
+ }
+ {ESC} { yymore(); }
+ [^\"] { yymore(); }
+}
-.|\n {
- grub_script_yyerror (yyextra, "unrecognized token");
- return GRUB_PARSER_TOKEN_BAD;
+{SQSTR2} {
+ yy_push_state (SQMULTILINE, yyscanner);
+ grub_script_lexer_ref (yyextra->lexerstate);
+ yymore ();
}
+<SQMULTILINE>{
+ \'{WORD}? {
+ RECORD;
+ grub_script_lexer_deref (yyextra->lexerstate);
+ yy_pop_state (yyscanner);
+ yypush_buffer_state (YY_CURRENT_BUFFER, yyscanner);
+ if (resplit (yytext, yyscanner))
+ {
+ yypop_buffer_state (yyscanner);
+ return GRUB_PARSER_TOKEN_WORD;
+ }
+ }
+ {ESC} { yymore(); }
+ [^\'] { yymore(); }
+}
+
/* Split word into multiple args */
<SPLIT>{
(.|\n) { COPY (yytext, yyleng); }
}
+. { /* ignore */ }
<<EOF>> {
yypop_buffer_state (yyscanner);
if (! grub_script_lexer_yywrap (yyextra))
return GRUB_PARSER_TOKEN_EOF;
}
}
-
%%
+#if 0
+int
+yywrap (yyscan_t yyscanner)
+{
+ char *line = 0;
+ struct grub_lexer_param *lexerstate = yyget_extra(yyscanner)->lexerstate;
+
+ grub_printf ("yywrap\n");
+ if (lexerstate->getline)
+ {
+ lexerstate->getline (&line, 1);
+ if (! line)
+ return 1;
+
+ yy_scan_string (line, yyscanner);
+ return 0;
+ }
+ return 1;
+}
+#endif
+
static void
grub_lexer_yyfree (void *ptr, yyscan_t yyscanner __attribute__ ((unused)))
{
return grub_realloc (ptr, size);
}
-#define MAX(a,b) ((a) < (b) ? (b) : (a))
-
static void copy_string (struct grub_parser_param *parser, const char *str, unsigned hint)
{
int size;
len = hint ? hint : grub_strlen (str);
if (parser->lexerstate->used + len >= parser->lexerstate->size)
{
- size = MAX (len, parser->lexerstate->size) * 2;
+ size = grub_max (len, parser->lexerstate->size) * 2;
ptr = grub_realloc (parser->lexerstate->text, size);
if (!ptr)
{
grub_strcpy (parser->lexerstate->text + parser->lexerstate->used - 1, str);
parser->lexerstate->used += len;
}
+
+static int
+resplit (const char *text, yyscan_t yyscanner)
+{
+ /* resplit text */
+ if (yy_scan_string (text, yyscanner))
+ {
+ yyget_extra (yyscanner)->lexerstate->merge_start = 1;
+ yy_push_state (SPLIT, yyscanner);
+ return 0;
+ }
+ grub_script_yyerror (yyget_extra (yyscanner), 0);
+ return 1;
+}