* [PATCH] Multiline double and single quote strings in GRUB script
@ 2010-06-12 7:02 BVK Chaitanya
2010-06-28 16:58 ` Vladimir 'φ-coder/phcoder' Serbinenko
0 siblings, 1 reply; 3+ messages in thread
From: BVK Chaitanya @ 2010-06-12 7:02 UTC (permalink / raw)
To: The development of GRUB 2
[-- Attachment #1: Type: text/plain, Size: 234 bytes --]
Hi,
Attached patch adds support for logical linebreaks (ie, backslash
followed by newline) and multi-line double quoted and single quoted
strings in GRUB script. Its also available in people/bvk/nl-fix
branch.
--
bvk.chaitanya
[-- Attachment #2: newline-fix.patch --]
[-- Type: text/x-patch, Size: 18467 bytes --]
# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: bvk.groups@gmail.com-20100612065349-d418wf1gesneq3lh
# target_branch: ../mainline/
# testament_sha1: 8430edc467e1c9276304cd28ecb0baf126c68d14
# timestamp: 2010-06-12 12:23:56 +0530
# base_revision_id: gregoire.sutre@gmail.com-20100608105242-\
# c3z8o8ivju9aetz7
#
# Begin patch
=== modified file 'include/grub/script_sh.h'
--- include/grub/script_sh.h 2010-03-26 15:43:06 +0000
+++ include/grub/script_sh.h 2010-06-12 05:36:02 +0000
@@ -195,6 +195,12 @@
/* Type of text. */
grub_script_arg_type_t type;
+ /* Flag to indicate resplit in progres. */
+ unsigned resplit;
+
+ /* Text that is unput. */
+ char *prefix;
+
/* Flex scanner. */
void *yyscanner;
@@ -284,7 +290,7 @@
void grub_script_lexer_deref (struct grub_lexer_param *);
void grub_script_lexer_record_start (struct grub_parser_param *);
char *grub_script_lexer_record_stop (struct grub_parser_param *);
-int grub_script_lexer_yywrap (struct grub_parser_param *);
+int grub_script_lexer_yywrap (struct grub_parser_param *, const char *input);
void grub_script_lexer_record (struct grub_parser_param *, char *);
/* Functions to track allocated memory. */
=== modified file 'script/lexer.c'
--- script/lexer.c 2010-02-11 13:19:57 +0000
+++ script/lexer.c 2010-06-12 06:32:06 +0000
@@ -98,8 +98,6 @@
return result;
}
-#define MAX(a,b) ((a) < (b) ? (b) : (a))
-
/* Record STR if input recording is enabled. */
void
grub_script_lexer_record (struct grub_parser_param *parser, char *str)
@@ -115,7 +113,7 @@
if (lexer->recordpos + len + 1 > lexer->recordlen)
{
old = lexer->recording;
- lexer->recordlen = MAX (len, lexer->recordlen) * 2;
+ lexer->recordlen = grub_max (len, lexer->recordlen) * 2;
lexer->recording = grub_realloc (lexer->recording, lexer->recordlen);
if (!lexer->recording)
{
@@ -131,76 +129,86 @@
lexer->recordpos += len;
}
-/* Append '\n' to SRC, before '\0' */
-static char *
-append_newline (const char *src)
-{
- char *line;
- grub_size_t len;
-
- len = grub_strlen (src);
- line = grub_malloc (len + 2);
- if (!line)
- return 0;
-
- grub_strcpy (line, src);
-
- line[len] = '\n';
- line[len + 1] = '\0';
- return line;
-}
-
/* Read next line of input if necessary, and set yyscanner buffers. */
int
-grub_script_lexer_yywrap (struct grub_parser_param *parserstate)
+grub_script_lexer_yywrap (struct grub_parser_param *parserstate,
+ const char *input)
{
int len;
- char *line;
- char *line2;
+ char *p = 0;
+ char *line = 0;
YY_BUFFER_STATE buffer;
struct grub_lexer_param *lexerstate = parserstate->lexerstate;
- if (!lexerstate->refs)
- return 0;
+ if (! lexerstate->refs && ! lexerstate->prefix && ! input)
+ return 1;
- if (!lexerstate->getline)
+ if (! lexerstate->getline && ! input)
{
grub_script_yyerror (parserstate, "unexpected end of file");
- return 0;
+ return 1;
}
line = 0;
- buffer = 0;
- lexerstate->getline (&line, 1);
- if (!line)
- {
- grub_script_yyerror (parserstate, 0); /* XXX this could be for ^C case? */
- return 0;
- }
-
- len = grub_strlen (line);
- if (line[len - 1] == '\n')
- {
- buffer = yy_scan_string (line, lexerstate->yyscanner);
- }
+ if (! input)
+ lexerstate->getline (&line, 1);
else
- {
- line2 = append_newline (line);
- if (line2)
- {
- buffer = yy_scan_string (line2, lexerstate->yyscanner);
- grub_free (line2);
- }
- }
-
+ line = grub_strdup (input);
+
+ /* Ensure '\n' at the end. */
+ if (line && line[0] == '\0')
+ {
+ grub_free (line);
+ line = grub_strdup ("\n");
+ }
+
+ if (line && (len = grub_strlen(line)) && line[len - 1] != '\n')
+ {
+ p = grub_realloc (line, len + 2);
+ if (p)
+ {
+ p[len++] = '\n';
+ p[len] = '\0';
+ }
+ line = p;
+ }
+
+ if (! line)
+ {
+ grub_script_yyerror (parserstate, "out of memory");
+ return 1;
+ }
+
+ /* Prepend any left over unput-text. */
+ if (lexerstate->prefix)
+ {
+ int plen = grub_strlen (lexerstate->prefix);
+
+ p = grub_malloc (len + plen + 1);
+ if (! p)
+ {
+ grub_free (line);
+ return 1;
+ }
+ grub_strcpy (p, lexerstate->prefix);
+ lexerstate->prefix = 0;
+
+ grub_strcpy (p + plen, line);
+ grub_free (line);
+
+ line = p;
+ len = len + plen;
+ }
+
+ buffer = yy_scan_string (line, lexerstate->yyscanner);
grub_free (line);
- if (!buffer)
+
+ if (! buffer)
{
grub_script_yyerror (parserstate, 0);
- return 0;
+ return 1;
}
-
- return 1;
+ return 0;
}
struct grub_lexer_param *
@@ -231,35 +239,18 @@
grub_free (lexerstate);
return 0;
}
-
- buffer = 0;
- script = script ? : "\n";
- len = grub_strlen (script);
-
- if (script[len - 1] == '\n')
- {
- buffer = yy_scan_string (script, lexerstate->yyscanner);
- }
- else
- {
- script2 = append_newline (script);
- if (script2)
- {
- buffer = yy_scan_string (script2, lexerstate->yyscanner);
- grub_free (script2);
- }
- }
-
- if (!buffer)
- {
+ yyset_extra (parser, lexerstate->yyscanner);
+ parser->lexerstate = lexerstate;
+
+ if (grub_script_lexer_yywrap (parser, script ?: "\n"))
+ {
+ parser->lexerstate = 0;
yylex_destroy (lexerstate->yyscanner);
grub_free (lexerstate->yyscanner);
-
grub_free (lexerstate->text);
grub_free (lexerstate);
return 0;
}
- yyset_extra (parser, lexerstate->yyscanner);
return lexerstate;
}
=== modified file 'script/yylex.l'
--- script/yylex.l 2010-04-30 08:20:41 +0000
+++ script/yylex.l 2010-06-12 06:53:49 +0000
@@ -58,6 +58,9 @@
#define YY_INPUT(buf,res,max) do { res = 0; } while (0)
/* forward declarations */
+static int grub_lexer_unput (const char *input, yyscan_t yyscanner);
+static int grub_lexer_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);
@@ -99,7 +102,7 @@
%option never-interactive
%option noyyfree noyyalloc noyyrealloc
-%option nounistd nostdinit nodefault noyylineno noyywrap
+%option nounistd nostdinit nodefault noyylineno
/* Reduce lexer size, by not defining these. */
%option noyy_top_state
@@ -118,12 +121,16 @@
DIGITS [[:digit:]]+
NAME [[:alpha:]_][[:alnum:][:digit:]_]*
-ESC \\.
+ESC \\(.|\n)
+SQCHR [^\']
+DQCHR {ESC}|[^\\\"]
+DQSTR \"{DQCHR}*\"
+SQSTR \'{SQCHR}*\'
VARIABLE ${NAME}|$\{{NAME}\}|${DIGITS}|$\{{DIGITS}\}|$\?|$\{\?\}
-DQSTR \"([^\\\"]|{ESC})*\"
-SQSTR \'[^\']*\'
WORD ({CHAR}|{DQSTR}|{SQSTR}|{ESC}|{VARIABLE})+
+MULTILINE {WORD}?((\"{DQCHR}*)|(\'{SQCHR}*)|(\\\n))
+
%x SPLIT
%x DQUOTE
%x SQUOTE
@@ -170,34 +177,32 @@
"function" { RECORD; return GRUB_PARSER_TOKEN_FUNCTION; }
"menuentry" { RECORD; return GRUB_PARSER_TOKEN_MENUENTRY; }
+{MULTILINE} {
+ if (grub_lexer_unput (yytext, yyscanner))
+ return GRUB_PARSER_TOKEN_BAD;
+ }
+
{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 (grub_lexer_resplit (yytext, yyscanner))
+ {
+ yypop_buffer_state (yyscanner);
+ return GRUB_PARSER_TOKEN_WORD;
+ }
+ yyextra->lexerstate->resplit = 1;
}
-
-.|\n {
- grub_script_yyerror (yyextra, "unrecognized token");
- return GRUB_PARSER_TOKEN_BAD;
+. {
+ grub_script_yyerror (yyextra, yytext);
+ return GRUB_PARSER_TOKEN_BAD;
}
/* Split word into multiple args */
<SPLIT>{
\\. { COPY (yytext + 1, yyleng - 1); }
+ \\\n { /* ignore */ }
\" {
yy_push_state (DQUOTE, yyscanner);
ARG (GRUB_SCRIPT_ARG_TYPE_TEXT);
@@ -215,6 +220,7 @@
<<EOF>> {
yy_pop_state (yyscanner);
yypop_buffer_state (yyscanner);
+ yyextra->lexerstate->resplit = 0;
yyextra->lexerstate->merge_end = 1;
ARG (GRUB_SCRIPT_ARG_TYPE_TEXT);
}
@@ -272,15 +278,20 @@
<<EOF>> {
yypop_buffer_state (yyscanner);
- if (! grub_script_lexer_yywrap (yyextra))
- {
- yyextra->lexerstate->eof = 1;
- return GRUB_PARSER_TOKEN_EOF;
- }
+ yyextra->lexerstate->eof = 1;
+ return GRUB_PARSER_TOKEN_EOF;
}
-
%%
+int
+yywrap (yyscan_t yyscanner)
+{
+ if (yyget_extra (yyscanner)->lexerstate->resplit)
+ return 1;
+
+ return grub_script_lexer_yywrap (yyget_extra (yyscanner), 0);
+}
+
static void
grub_lexer_yyfree (void *ptr, yyscan_t yyscanner __attribute__ ((unused)))
{
@@ -300,8 +311,6 @@
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;
@@ -311,7 +320,7 @@
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)
{
@@ -325,3 +334,34 @@
grub_strcpy (parser->lexerstate->text + parser->lexerstate->used - 1, str);
parser->lexerstate->used += len;
}
+
+static int
+grub_lexer_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;
+}
+
+static int
+grub_lexer_unput (const char *text, yyscan_t yyscanner)
+{
+ struct grub_lexer_param *lexerstate = yyget_extra (yyscanner)->lexerstate;
+
+ if (lexerstate->prefix)
+ grub_free (lexerstate->prefix);
+
+ lexerstate->prefix = grub_strdup (text);
+ if (! lexerstate->prefix)
+ {
+ grub_script_yyerror (yyget_extra (yyscanner), "out of memory");
+ return 1;
+ }
+ return 0;
+}
=== modified file 'tests/grub_script_echo1.in'
--- tests/grub_script_echo1.in 2010-01-22 13:37:27 +0000
+++ tests/grub_script_echo1.in 2010-06-12 06:53:49 +0000
@@ -30,3 +30,45 @@
foo=echo
$foo 1234
+
+echo "one
+"
+echo "one
+\""
+echo "one
+two"
+
+echo one"two
+"three
+echo one"two
+\""three
+echo one"two
+\"three\"
+four"
+
+
+echo 'one
+'
+echo 'one
+\'
+echo 'one
+two'
+echo one'two
+'
+echo one'two
+\'
+echo one'two
+\'three
+
+# echo "one\
+# two"
+# echo 'one\
+# two'
+# echo foo\
+# bar
+# \
+# echo foo
+# echo "one
+#
+# two"
+
# Begin bundle
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
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2010-07-17 4:26 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-06-12 7:02 [PATCH] Multiline double and single quote strings in GRUB script BVK Chaitanya
2010-06-28 16:58 ` Vladimir 'φ-coder/phcoder' Serbinenko
2010-07-17 4:25 ` BVK Chaitanya
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.