Hello. I discovered that the lines like
echo \"hello\"
and
echo "a
b"
weren't parsed correctly.
Here is a fix. I have tested it throughly yet

-- 
Regards
Vladimir 'phcoder' Serbinenko
diff --git a/ChangeLog b/ChangeLog
index 3eb4bfd..4b3bf75 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2009-06-10  Vladimir Serbinenko  <phco...@gmail.com>
+
+	Fix handling of string like \"hello\" and "a
+	b"
+
+	* script/sh/lexer.c (check_textstate): accept GRUB_PARSER_STATE_ESC
+	(grub_script_yylex): fix parsing of quoting, escaping and newline
+
 2009-06-09  Michel Hermier  <michel.herm...@gmail.com>
 
 	* fs/i386/pc/pxe.c (grub_pxefs_read): Fix returned values.
diff --git a/script/sh/lexer.c b/script/sh/lexer.c
index 3ec7827..784bb79 100644
--- a/script/sh/lexer.c
+++ b/script/sh/lexer.c
@@ -39,6 +39,7 @@ static int
 check_textstate (grub_parser_state_t state)
 {
   return (state == GRUB_PARSER_STATE_TEXT
+	  || state == GRUB_PARSER_STATE_ESC
 	  || state == GRUB_PARSER_STATE_QUOTE
 	  || state == GRUB_PARSER_STATE_DQUOTE);
 }
@@ -155,18 +156,20 @@ grub_script_yylex (union YYSTYPE *yylval, struct grub_parser_param *parsestate)
       return token;
     }
 
-  for (;! state->done && (*state->script || firstrun); firstrun = 0)
+  for (;! state->done; firstrun = 0)
     {
       
       if (! *state->script)
 	{
 	  /* Check if more tokens are requested by the parser.  */
 	  if (((state->refs && ! parsestate->err)
-	       || state->state == GRUB_PARSER_STATE_ESC)
+	       || state->state == GRUB_PARSER_STATE_ESC
+	       || state->state == GRUB_PARSER_STATE_QUOTE
+	       || state->state == GRUB_PARSER_STATE_DQUOTE)
 	      && state->getline)
 	    {
 	      int doexit = 0;
-	      while (!state->script || ! grub_strlen (state->script))
+	      while (! state->script || ! *state->script)
 		{
 		  grub_free (state->newscript);
 		  state->newscript = 0;
@@ -182,11 +185,18 @@ grub_script_yylex (union YYSTYPE *yylval, struct grub_parser_param *parsestate)
 		break;
 	      grub_dprintf ("scripting", "token=`\\n'\n");
 	      recordchar (state, '\n');
-	      if (state->state != GRUB_PARSER_STATE_ESC)
+	      if (state->state != GRUB_PARSER_STATE_ESC
+		  && state->state != GRUB_PARSER_STATE_DQUOTE
+		  && state->state != GRUB_PARSER_STATE_QUOTE)
 		{
 		  state->tokenonhold = '\n';
 		  break;
 		}
+	      if (state->state == GRUB_PARSER_STATE_DQUOTE
+		  || state->state == GRUB_PARSER_STATE_QUOTE)
+		yylval->arg = grub_script_arg_add (parsestate, yylval->arg,
+						   GRUB_SCRIPT_ARG_TYPE_STR,
+						   "\n");
 	    }
 	  else
 	    {
@@ -199,8 +209,9 @@ grub_script_yylex (union YYSTYPE *yylval, struct grub_parser_param *parsestate)
 	    }
 	}
 
-      newstate = grub_parser_cmdline_state (state->state, *state->script, &use);
-      
+      newstate = grub_parser_cmdline_state (state->state, *state->script, 
+					    &use);
+
       /* Check if it is a text.  */
       if (check_textstate (newstate))
 	{
@@ -270,7 +281,9 @@ grub_script_yylex (union YYSTYPE *yylval, struct grub_parser_param *parsestate)
 		 when a special token was found.  It will be recognized
 		 next time when this function is called.  */
 	      if (newstate == GRUB_PARSER_STATE_TEXT
-		  && state->state != GRUB_PARSER_STATE_ESC)
+		  && state->state != GRUB_PARSER_STATE_ESC
+		  && state->state != GRUB_PARSER_STATE_QUOTE
+		  && state->state != GRUB_PARSER_STATE_DQUOTE)
 		{
 		  int breakout = 0;
 		  
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to