Hello. This patch fixes a bunch of bugs in scripting engine

-- 
Regards
Vladimir 'phcoder' Serbinenko
diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h
index 159da62..ab5bf43 100644
--- a/include/grub/script_sh.h
+++ b/include/grub/script_sh.h
@@ -77,11 +77,6 @@ struct grub_script_cmdline
 
   /* The arguments for this command.  */
   struct grub_script_arglist *arglist;
-
-  /* The command name of this command.  XXX: Perhaps an argument
-     should be used for this so we can use variables as command
-     name.  */
-  char *cmdname;
 };
 
 /* A block of commands, this can be used to group commands.  */
@@ -161,6 +156,9 @@ struct grub_lexer_param
 
   /* Size of RECORDING.  */
   int recordlen;
+
+  /* The token that is already parsed but not yet returned. */
+  int tokenonhold;
 };
 
 /* State of the parser as passes to the parser.  */
@@ -191,7 +189,6 @@ grub_script_add_arglist (struct grub_parser_param *state,
 			 struct grub_script_arg *arg);
 struct grub_script_cmd *
 grub_script_create_cmdline (struct grub_parser_param *state,
-			    char *cmdname,
 			    struct grub_script_arglist *arglist);
 struct grub_script_cmd *
 grub_script_create_cmdblock (struct grub_parser_param *state);
@@ -276,7 +273,7 @@ struct grub_script_function
 };
 typedef struct grub_script_function *grub_script_function_t;
 
-grub_script_function_t grub_script_function_create (char *functionname,
+grub_script_function_t grub_script_function_create (struct grub_script_arg *functionname,
 						    struct grub_script *cmd);
 void grub_script_function_remove (const char *name);
 grub_script_function_t grub_script_function_find (char *functionname);
@@ -284,4 +281,7 @@ int grub_script_function_iterate (int (*iterate) (grub_script_function_t));
 int grub_script_function_call (grub_script_function_t func,
 			       int argc, char **args);
 
+char *
+grub_script_execute_argument_to_string (struct grub_script_arg *arg);
+
 #endif /* ! GRUB_NORMAL_PARSER_HEADER */
diff --git a/kern/parser.c b/kern/parser.c
index 685ab22..ee6b169 100644
--- a/kern/parser.c
+++ b/kern/parser.c
@@ -47,8 +47,8 @@ static struct grub_parser_state_transition state_transitions[] =
 
   { GRUB_PARSER_STATE_QVAR, GRUB_PARSER_STATE_QVARNAME2, '{', 0},
   { GRUB_PARSER_STATE_QVAR, GRUB_PARSER_STATE_QVARNAME, 0, 1},
-  { GRUB_PARSER_STATE_QVARNAME, GRUB_PARSER_STATE_DQUOTE, ' ', 1},
   { GRUB_PARSER_STATE_QVARNAME, GRUB_PARSER_STATE_TEXT, '\"', 0},
+  { GRUB_PARSER_STATE_QVARNAME, GRUB_PARSER_STATE_DQUOTE, ' ', 1},
   { GRUB_PARSER_STATE_QVARNAME2, GRUB_PARSER_STATE_DQUOTE, '}', 0},
 
   { 0, 0, 0, 0}
@@ -60,9 +60,7 @@ grub_parser_state_t
 grub_parser_cmdline_state (grub_parser_state_t state, char c, char *result)
 {
   struct grub_parser_state_transition *transition;
-  struct grub_parser_state_transition *next_match = 0;
   struct grub_parser_state_transition default_transition;
-  int found = 0;
 
   default_transition.to_state = state;
   default_transition.keep_value = 1;
@@ -70,26 +68,24 @@ grub_parser_cmdline_state (grub_parser_state_t state, char c, char *result)
   /* Look for a good translation.  */
   for (transition = state_transitions; transition->from_state; transition++)
     {
+      if (transition->from_state != state)
+	continue;
       /* An exact match was found, use it.  */
-      if (transition->from_state == state && transition->input == c)
-	{
-	  found = 1;
-	  break;
-	}
+      if (transition->input == c)
+	break;
+
+      if (transition->input == ' ' && ! grub_isalpha (c) 
+	  && ! grub_isdigit (c) && c != '_')
+	break;
 
       /* A less perfect match was found, use this one if no exact
 	 match can be found.  */
-      if (transition->from_state == state && transition->input == 0)
-	next_match = transition;
+      if (transition->input == 0)
+	break;
     }
 
-  if (! found)
-    {
-      if (next_match)
-	transition = next_match;
-      else
-	transition = &default_transition;
-    }
+  if (! transition->from_state)
+    transition = &default_transition;
 
   if (transition->keep_value)
     *result = c;
diff --git a/script/sh/execute.c b/script/sh/execute.c
index 0989f79..e0b7b2e 100644
--- a/script/sh/execute.c
+++ b/script/sh/execute.c
@@ -37,7 +37,7 @@ grub_script_execute_cmd (struct grub_script_cmd *cmd)
 
 /* Parse ARG and return the textual representation.  Add strings are
    concatenated and all values of the variables are filled in.  */
-static char *
+char *
 grub_script_execute_argument_to_string (struct grub_script_arg *arg)
 {
   int size = 0;
@@ -93,20 +93,22 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd)
   int argcount = 0;
   grub_script_function_t func = 0;
   char errnobuf[6];
+  char *cmdname;
 
   /* Lookup the command.  */
-  grubcmd = grub_command_find (cmdline->cmdname);
+  cmdname = grub_script_execute_argument_to_string (cmdline->arglist->arg);
+  grubcmd = grub_command_find (cmdname);
   if (! grubcmd)
     {
       /* Ignore errors.  */
       grub_errno = GRUB_ERR_NONE;
 
       /* It's not a GRUB command, try all functions.  */
-      func = grub_script_function_find (cmdline->cmdname);
+      func = grub_script_function_find (cmdname);
       if (! func)
 	{
 	  /* As a last resort, try if it is an assignment.  */
-	  char *assign = grub_strdup (cmdline->cmdname);
+	  char *assign = grub_strdup (cmdname);
 	  char *eq = grub_strchr (assign, '=');
 
 	  if (eq)
@@ -123,14 +125,15 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd)
 	  return 0;
 	}
     }
+  grub_free (cmdname);
 
-  if (cmdline->arglist)
+  if (cmdline->arglist->next)
     {
-      argcount = cmdline->arglist->argcount;
+      argcount = cmdline->arglist->argcount - 1;
 
       /* Create argv from the arguments.  */
       args = grub_malloc (sizeof (char *) * argcount);
-      for (arglist = cmdline->arglist; arglist; arglist = arglist->next)
+      for (arglist = cmdline->arglist->next; arglist; arglist = arglist->next)
 	{
 	  char *str;
 	  str = grub_script_execute_argument_to_string (arglist->arg);
diff --git a/script/sh/function.c b/script/sh/function.c
index db6b903..dc411cc 100644
--- a/script/sh/function.c
+++ b/script/sh/function.c
@@ -24,7 +24,8 @@
 static grub_script_function_t grub_script_function_list;
 
 grub_script_function_t
-grub_script_function_create (char *functionname, struct grub_script *cmd)
+grub_script_function_create (struct grub_script_arg *functionname_arg, 
+			     struct grub_script *cmd)
 {
   grub_script_function_t func;
   grub_script_function_t *p;
@@ -33,7 +34,7 @@ grub_script_function_create (char *functionname, struct grub_script *cmd)
   if (! func)
     return 0;
 
-  func->name = grub_strdup (functionname);
+  func->name = grub_script_execute_argument_to_string (functionname_arg);
   if (! func->name)
     {
       grub_free (func);
@@ -46,14 +47,14 @@ grub_script_function_create (char *functionname, struct grub_script *cmd)
   p = &grub_script_function_list;
   while (*p)
     {
-      if (grub_strcmp ((*p)->name, functionname) >= 0)
+      if (grub_strcmp ((*p)->name, func->name) >= 0)
 	break;
 
       p = &((*p)->next);
     }
 
   /* If the function already exists, overwrite the old function.  */
-  if (*p && grub_strcmp ((*p)->name, functionname) == 0)
+  if (*p && grub_strcmp ((*p)->name, func->name) == 0)
     {
       grub_script_function_t q;
 
diff --git a/script/sh/lexer.c b/script/sh/lexer.c
index 8bae487..1dba553 100644
--- a/script/sh/lexer.c
+++ b/script/sh/lexer.c
@@ -62,6 +62,7 @@ grub_script_lexer_init (char *script, grub_reader_getline_t getline)
   param->recording = 0;
   param->recordpos = 0;
   param->recordlen = 0;
+  param->tokenonhold = 0;
 
   return param;
 }
@@ -136,224 +137,247 @@ nextchar (struct grub_lexer_param *state)
 }
 
 int
-grub_script_yylex2 (union YYSTYPE *yylval,
-		    struct grub_parser_param *parsestate);
-
-int
 grub_script_yylex (union YYSTYPE *yylval, struct grub_parser_param *parsestate)
 {
-  int r = -1;
-
-  while (r == -1)
-    {
-      r = grub_script_yylex2 (yylval, parsestate);
-      if (r == ' ')
-	r = -1;
-    }
-  return r;
-}
-
-int
-grub_script_yylex2 (union YYSTYPE *yylval, struct grub_parser_param *parsestate)
-{
   grub_parser_state_t newstate;
   char use;
   char *buffer;
   char *bp;
   struct grub_lexer_param *state = parsestate->lexerstate;
+  int firstrun = 1;
 
-  if (state->done)
-    return 0;
+  yylval->arg = 0;
 
-  if (! *state->script)
+  if (state->tokenonhold)
     {
-      /* Check if more tokens are requested by the parser.  */
-      if ((state->refs
-	   || state->state == GRUB_PARSER_STATE_ESC)
-	  && state->getline)
-	{
-	  while (!state->script || ! grub_strlen (state->script))
-	    {
-	      grub_free (state->newscript);
-	      state->newscript = 0;
-	      state->getline (&state->newscript, 1);
-	      state->script = state->newscript;
-	      if (! state->script)
-		return 0;
-	    }
-	  grub_dprintf ("scripting", "token=`\\n'\n");
-	  recordchar (state, '\n');
-	  if (state->state != GRUB_PARSER_STATE_ESC)
-	    return '\n';
-	}
-      else
-	{
-	  grub_free (state->newscript);
-	  state->newscript = 0;
-	  state->done = 1;
-	  grub_dprintf ("scripting", "token=`\\n'\n");
-	  return '\n';
-	}
+      int token = state->tokenonhold;
+      state->tokenonhold = 0;
+      return token;
     }
 
-  newstate = grub_parser_cmdline_state (state->state, *state->script, &use);
-
-  /* Check if it is a text.  */
-  if (check_textstate (newstate))
+  for (;! state->done && (*state->script || firstrun); firstrun = 0)
     {
-      /* In case the string is not quoted, this can be a one char
-	 length symbol.  */
-      if (newstate == GRUB_PARSER_STATE_TEXT)
+      
+      if (! *state->script)
 	{
-	  switch (*state->script)
+	  /* Check if more tokens are requested by the parser.  */
+	  if (((state->refs && ! parsestate->err)
+	       || state->state == GRUB_PARSER_STATE_ESC)
+	      && state->getline)
 	    {
-	    case ' ':
-	      while (*state->script)
+	      int doexit = 0;
+	      while (!state->script || ! grub_strlen (state->script))
 		{
-		  newstate = grub_parser_cmdline_state (state->state,
-							*state->script, &use);
-		  if (! (state->state == GRUB_PARSER_STATE_TEXT
-			 && *state->script == ' '))
+		  grub_free (state->newscript);
+		  state->newscript = 0;
+		  state->getline (&state->newscript, 1);
+		  state->script = state->newscript;
+		  if (! state->script)
 		    {
-		      grub_dprintf ("scripting", "token=` '\n");
-		      return ' ';
+		      doexit = 1;
+		      break;
 		    }
-		  state->state = newstate;
-		  nextchar (state);
 		}
-	      grub_dprintf ("scripting", "token=` '\n");
-	      return ' ';
-	    case '{':
-	    case '}':
-	    case ';':
-	    case '\n':
-	      {
-		char c;
-		grub_dprintf ("scripting", "token=`%c'\n", *state->script);
-		c = *state->script;;
-		nextchar (state);
-		return c;
-	      }
+	      if (doexit)
+		break;
+	      grub_dprintf ("scripting", "token=`\\n'\n");
+	      recordchar (state, '\n');
+	      if (state->state != GRUB_PARSER_STATE_ESC)
+		{
+		  state->tokenonhold = '\n';
+		  break;
+		}
+	    }
+	  else
+	    {
+	      grub_free (state->newscript);
+	      state->newscript = 0;
+	      state->done = 1;
+	      grub_dprintf ("scripting", "token=`\\n'\n");
+	      state->tokenonhold = '\n';
+	      break;
 	    }
 	}
 
-      /* XXX: Use a better size.  */
-      buffer = grub_script_malloc (parsestate, 2048);
-      if (! buffer)
-	return 0;
-
-      bp = buffer;
-
-      /* Read one token, possible quoted.  */
-      while (*state->script)
+      newstate = grub_parser_cmdline_state (state->state, *state->script, &use);
+      
+      /* Check if it is a text.  */
+      if (check_textstate (newstate))
 	{
-	  newstate = grub_parser_cmdline_state (state->state,
-						*state->script, &use);
-
-	  /* Check if a variable name starts.  */
-	  if (check_varstate (newstate))
-	    break;
-
-	  /* If the string is not quoted or escaped, stop processing
-	     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)
+	  /* In case the string is not quoted, this can be a one char
+	     length symbol.  */
+	  if (newstate == GRUB_PARSER_STATE_TEXT)
 	    {
-	      int breakout = 0;
-
-	      switch (use)
+	      int doexit = 0;
+	      switch (*state->script)
 		{
 		case ' ':
+		  while (*state->script)
+		    {
+		      newstate = grub_parser_cmdline_state (state->state,
+							    *state->script, &use);
+		      if (! (state->state == GRUB_PARSER_STATE_TEXT
+			     && *state->script == ' '))
+			{
+			  grub_dprintf ("scripting", "token=` '\n");
+			  if (! firstrun)
+			    doexit = 1;
+			  break;
+			}
+		      state->state = newstate;
+		      nextchar (state);
+		    }
+		  grub_dprintf ("scripting", "token=` '\n");
+		  if (! firstrun)
+		    doexit = 1;
+		  break;
 		case '{':
 		case '}':
 		case ';':
 		case '\n':
-		  breakout = 1;
+		  {
+		    char c;
+		    grub_dprintf ("scripting", "token=`%c'\n", *state->script);
+		    c = *state->script;;
+		    nextchar (state);
+		    state->tokenonhold = c;
+		    doexit = 1;
+		    break;
+		  }
 		}
-	      if (breakout)
+	      if (doexit)
 		break;
-	      *(bp++) = use;
 	    }
-	  else if (use)
-	    *(bp++) = use;
 
+	  /* XXX: Use a better size.  */
+	  buffer = grub_script_malloc (parsestate, 2048);
+	  if (! buffer)
+	    return 0;
+	  
+	  bp = buffer;
+	  
+	  /* Read one token, possible quoted.  */
+	  while (*state->script)
+	    {
+	      newstate = grub_parser_cmdline_state (state->state,
+						    *state->script, &use);
+	      
+	      /* Check if a variable name starts.  */
+	      if (check_varstate (newstate))
+		break;
+	      
+	      /* If the string is not quoted or escaped, stop processing
+		 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)
+		{
+		  int breakout = 0;
+		  
+		  switch (use)
+		    {
+		    case ' ':
+		    case '{':
+		    case '}':
+		    case ';':
+		    case '\n':
+		      breakout = 1;
+		    }
+		  if (breakout)
+		    break;
+		  *(bp++) = use;
+		}
+	      else if (use)
+		*(bp++) = use;
+	      
+	      state->state = newstate;
+	      nextchar (state);
+	    }
+
+	  /* A string of text was read in.  */
+	  *bp = '\0';
+	  grub_dprintf ("scripting", "token=`%s'\n", buffer);
+	  yylval->arg = grub_script_arg_add (parsestate, yylval->arg,
+					     GRUB_SCRIPT_ARG_TYPE_STR, buffer);
+	  
+	}
+      else if (newstate == GRUB_PARSER_STATE_VAR
+	       || newstate == GRUB_PARSER_STATE_QVAR)
+	{
+	  /* XXX: Use a better size.  */
+	  buffer = grub_script_malloc (parsestate, 2096);
+	  if (! buffer)
+	    return 0;
+	  
+	  bp = buffer;
+	  
+	  /* This is a variable, read the variable name.  */
+	  while (*state->script)
+	    {
+	      newstate = grub_parser_cmdline_state (state->state,
+						    *state->script, &use);
+	      
+	      /* Check if this character is not part of the variable name
+		 anymore.  */
+	      if (! (check_varstate (newstate)))
+		{
+		  if (state->state == GRUB_PARSER_STATE_VARNAME2
+		  || state->state == GRUB_PARSER_STATE_QVARNAME2)
+		    nextchar (state);
+		  state->state = newstate;
+		  break;
+		}
+	      
+	      if (use)
+		*(bp++) = use;
+	      nextchar (state);
+	      state->state = newstate;
+	    }
+	  
+	  *bp = '\0';
 	  state->state = newstate;
-	  nextchar (state);
+	  yylval->arg = grub_script_arg_add (parsestate, yylval->arg,
+					     GRUB_SCRIPT_ARG_TYPE_VAR, buffer);
+	  grub_dprintf ("scripting", "vartoken=`%s'\n", buffer);	  
 	}
+      else
+	{
+	  /* There is either text or a variable name.  In the case you
+	 arrive here there is a serious problem with the lexer.  */
+	  grub_error (GRUB_ERR_BAD_ARGUMENT, "Internal error\n");
+	  return 0;
+	}
+    }
+  
+  if (yylval->arg == 0)
+    {
+      int token = state->tokenonhold;
+      state->tokenonhold = 0;
+      return token;
+    }
 
-      /* A string of text was read in.  */
-      *bp = '\0';
-      grub_dprintf ("scripting", "token=`%s'\n", buffer);
-      yylval->string = buffer;
-
+  if (yylval->arg->next == 0 && yylval->arg->type == GRUB_SCRIPT_ARG_TYPE_STR)
+    {
       /* Detect some special tokens.  */
-      if (! grub_strcmp (buffer, "while"))
+      if (! grub_strcmp (yylval->arg->str, "while"))
 	return GRUB_PARSER_TOKEN_WHILE;
-      else if (! grub_strcmp (buffer, "if"))
+      else if (! grub_strcmp (yylval->arg->str, "if"))
 	return GRUB_PARSER_TOKEN_IF;
-      else if (! grub_strcmp (buffer, "function"))
+      else if (! grub_strcmp (yylval->arg->str, "function"))
 	return GRUB_PARSER_TOKEN_FUNCTION;
-      else if (! grub_strcmp (buffer, "menuentry"))
+      else if (! grub_strcmp (yylval->arg->str, "menuentry"))
 	return GRUB_PARSER_TOKEN_MENUENTRY;
-      else if (! grub_strcmp (buffer, "@"))
+      else if (! grub_strcmp (yylval->arg->str, "@"))
 	return GRUB_PARSER_TOKEN_MENUENTRY;
-      else if (! grub_strcmp (buffer, "else"))
+      else if (! grub_strcmp (yylval->arg->str, "else"))
 	return GRUB_PARSER_TOKEN_ELSE;
-      else if (! grub_strcmp (buffer, "then"))
+      else if (! grub_strcmp (yylval->arg->str, "then"))
 	return GRUB_PARSER_TOKEN_THEN;
-      else if (! grub_strcmp (buffer, "fi"))
+      else if (! grub_strcmp (yylval->arg->str, "fi"))
 	return GRUB_PARSER_TOKEN_FI;
-      else
-	return GRUB_PARSER_TOKEN_NAME;
     }
-  else if (newstate == GRUB_PARSER_STATE_VAR
-	   || newstate == GRUB_PARSER_STATE_QVAR)
-    {
-      /* XXX: Use a better size.  */
-      buffer = grub_script_malloc (parsestate, 2096);
-      if (! buffer)
-	return 0;
-
-      bp = buffer;
-
-      /* This is a variable, read the variable name.  */
-      while (*state->script)
-	{
-	  newstate = grub_parser_cmdline_state (state->state,
-						*state->script, &use);
-
-	  /* Check if this character is not part of the variable name
-	     anymore.  */
-	  if (! (check_varstate (newstate)))
-	    {
-	      if (state->state == GRUB_PARSER_STATE_VARNAME2
-		  || state->state == GRUB_PARSER_STATE_QVARNAME2)
-		nextchar (state);
-	      state->state = newstate;
-	      break;
-	    }
-
-	  if (use)
-	    *(bp++) = use;
-	  nextchar (state);
-	  state->state = newstate;
-	}
 
-      *bp = '\0';
-      state->state = newstate;
-      yylval->string = buffer;
-      grub_dprintf ("scripting", "vartoken=`%s'\n", buffer);
-
-      return GRUB_PARSER_TOKEN_VAR;
-    }
-  else
-    {
-      /* There is either text or a variable name.  In the case you
-	 arrive here there is a serious problem with the lexer.  */
-      grub_error (GRUB_ERR_BAD_ARGUMENT, "Internal error\n");
-      return 0;
-    }
+  return GRUB_PARSER_TOKEN_ARG;
 }
 
 void
diff --git a/script/sh/parser.y b/script/sh/parser.y
index 366f6b0..094a885 100644
--- a/script/sh/parser.y
+++ b/script/sh/parser.y
@@ -42,13 +42,10 @@
 %token GRUB_PARSER_TOKEN_ELSE		"else"
 %token GRUB_PARSER_TOKEN_THEN		"then"
 %token GRUB_PARSER_TOKEN_FI		"fi"
-%token GRUB_PARSER_TOKEN_NAME
-%token GRUB_PARSER_TOKEN_VAR
+%token GRUB_PARSER_TOKEN_ARG
 %type <cmd> script_init script grubcmd command commands commandblock menuentry if
 %type <arglist> arguments;
-%type <arg> argument;
-%type <string> "if" "while" "function" "else" "then" "fi"
-%type <string> text GRUB_PARSER_TOKEN_NAME GRUB_PARSER_TOKEN_VAR
+%type <arg> GRUB_PARSER_TOKEN_ARG;
 
 %pure-parser
 %lex-param { struct grub_parser_param *state };
@@ -62,9 +59,18 @@ script_init:	{ state->err = 0; } script
 		  }
 ;
 
-script:		commands { $$ = $1; }
+script:		{ $$ = 0; }
+                | '\n' { $$ = 0; }
+                | commands { $$ = $1; }
 		| function '\n' { $$ = 0; }
 		| menuentry '\n' { $$ = $1; }
+		| error
+		  {
+		    $$ = 0;
+		    yyerror (state, "Incorrect command");
+		    state->err = 1;
+		    yyerrok;
+		  }
 ;
 
 delimiter:	'\n'
@@ -76,61 +82,21 @@ newlines:	/* Empty */
 		| newlines '\n'
 ;
 
-/* Some tokens are both used as token or as plain text.  XXX: Add all
-   tokens without causing conflicts.  */
-text:		GRUB_PARSER_TOKEN_NAME
-		  {
-		    $$ = $1;
-		  }
-		| "if"
-		  {
-		    $$ = $1;
-		  }
-		| "while"
-		  {
-		    $$ = $1;
-		  }
-;
 
-/* An argument can consist of some static text mixed with variables,
-   for example: `foo${bar}baz'.  */
-argument:	GRUB_PARSER_TOKEN_VAR
-		  {
-		    $$ = grub_script_arg_add (state, 0, GRUB_SCRIPT_ARG_TYPE_VAR, $1);
-		  }
-		| text
-		  {
-		    $$ = grub_script_arg_add (state, 0, GRUB_SCRIPT_ARG_TYPE_STR, $1);
-		  }
-/* XXX: Currently disabled to simplify the parser.  This should be
-   parsed by yet another parser for readability.  */
-/* 		| argument GRUB_PARSER_TOKEN_VAR */
-/* 		  { */
-/* 		    $$ = grub_script_arg_add ($1, GRUB_SCRIPT_ARG_TYPE_VAR, $2); */
-/* 		  } */
-/* 		| argument text */
-/* 		  { */
-/* 		    $$ = grub_script_arg_add ($1, GRUB_SCRIPT_ARG_TYPE_STR, $2); */
-/* 		  } */
-;
 
-arguments:	argument
+arguments:	GRUB_PARSER_TOKEN_ARG
 		  {
 		    $$ = grub_script_add_arglist (state, 0, $1);
 		  }
-		| arguments argument
+		| arguments GRUB_PARSER_TOKEN_ARG
 		  {
 		    $$ = grub_script_add_arglist (state, $1, $2);
 		  }
 ;
 
-grubcmd:	GRUB_PARSER_TOKEN_NAME arguments
+grubcmd:	arguments
 		  {
-		    $$ = grub_script_create_cmdline (state, $1, $2);
-		  }
-		| GRUB_PARSER_TOKEN_NAME
-		  {
-		    $$ = grub_script_create_cmdline (state, $1, 0);
+		    $$ = grub_script_create_cmdline (state, $1);
 		  }
 ;
 
@@ -138,13 +104,6 @@ grubcmd:	GRUB_PARSER_TOKEN_NAME arguments
 command:	grubcmd delimiter { $$ = $1; }
 		| if delimiter 	{ $$ = $1; }
 		| commandblock delimiter { $$ = $1; }
-		| error delimiter
-		  {
-		    $$ = 0;
-		    yyerror (state, "Incorrect command");
-		    state->err = 1;
-		    yyerrok;
-		  }
 ;
 
 /* A block of commands.  */
@@ -166,7 +125,7 @@ commands:	command
    executed on the right moment.  So the `commands' rule should be
    recognized after executing the `grub_script_mem_record; and before
    `grub_script_mem_record_stop'.  */
-function:	"function" GRUB_PARSER_TOKEN_NAME
+function:	"function" GRUB_PARSER_TOKEN_ARG
 		  {
 		    grub_script_lexer_ref (state->lexerstate);
 		  } newlines '{'
@@ -204,10 +163,10 @@ commandblock:	'{'
 ;
 
 /* A menu entry.  Carefully save the memory that is allocated.  */
-menuentry:	"menuentry" arguments
+menuentry:	"menuentry"
 		  {
 		    grub_script_lexer_ref (state->lexerstate);
-		  } newlines '{'
+		  } arguments newlines '{'
 		  {
 		    grub_script_lexer_record_start (state->lexerstate);
 		  } newlines commands '}'
@@ -215,7 +174,7 @@ menuentry:	"menuentry" arguments
 		    char *menu_entry;
 		    menu_entry = grub_script_lexer_record_stop (state->lexerstate);
 		    grub_script_lexer_deref (state->lexerstate);
-		    $$ = grub_script_create_cmdmenu (state, $2, menu_entry, 0);
+		    $$ = grub_script_create_cmdmenu (state, $3, menu_entry, 0);
 		  }
 ;
 
diff --git a/script/sh/script.c b/script/sh/script.c
index 3e80b83..89fa947 100644
--- a/script/sh/script.c
+++ b/script/sh/script.c
@@ -161,7 +161,7 @@ grub_script_add_arglist (struct grub_parser_param *state,
    holds all arguments for this command.  */
 struct grub_script_cmd *
 grub_script_create_cmdline (struct grub_parser_param *state,
-			    char *cmdname, struct grub_script_arglist *arglist)
+			    struct grub_script_arglist *arglist)
 {
   struct grub_script_cmdline *cmd;
 
@@ -171,7 +171,6 @@ grub_script_create_cmdline (struct grub_parser_param *state,
   cmd->cmd.exec = grub_script_execute_cmdline;
   cmd->cmd.next = 0;
   cmd->arglist = arglist;
-  cmd->cmdname = cmdname;
 
   return (struct grub_script_cmd *) cmd;
 }
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to