[2244] 2009-06-04 Vladimir Serbinenko <[email protected]>

Vladimir Serbinenko <[email protected]>
Newsgroups gmane.comp.boot-loaders.grub.cvs
Message-ID <[email protected]>
Revision: 2244
          http://svn.sv.gnu.org/viewvc/?view=rev&root=grub&revision=2244
Author:   phcoder
Date:     2009-06-04 16:18:35 +0000 (Thu, 04 Jun 2009)
Log Message:
-----------
2009-06-04  Vladimir Serbinenko  <[email protected]>

	Script fixes

	* include/grub/script_sh.h (grub_script_cmdline): remove cmdline
	(grub_lexer_param): add tokenonhold
	(grub_script_create_cmdline): remove cmdline. All callers updated
	(grub_script_function_create): make functionname
	grub_script_arg. All callers updated
	(grub_script_execute_argument_to_string): new prototype
	* kern/parser.c (state_transitions): reorder
	(grub_parser_cmdline_state): fix a bug and make more compact
	* script/sh/execute.c (grub_script_execute_argument_to_string): 
	make global
	(grub_script_execute_cmdline): use new format
	* script/sh/function.c (grub_script_function_create): make functionname
	grub_script_arg. All callers updated
	* script/sh/lexer.c (grub_script_lexer_init): initilaize tokenonhold
	(grub_script_yylex): remove
	(grub_script_yylex2): renamed to ...
	(grub_script_yylex): ...renamed
	parse the expressions like a${b}c
	* script/sh/parser.y (GRUB_PARSER_TOKEN_ARG): new typed terminal
	(GRUB_PARSER_TOKEN_VAR): remove
	(GRUB_PARSER_TOKEN_NAME): likewise
	("if"): declare as typeless
	("while"): likewise
	("function"): likewise
	("else"): likewise
	("then"): likewise
	("fi"): likewise
	(text): remove
	(argument): likewise
	(script): accept empty scripts and make exit on error
	(arguments): use GRUB_PARSER_TOKEN_ARG
	(function): likewise
	(command): move error handling to script
	(menuentry): move grub_script_lexer_ref before
	* script/sh/script.c (grub_script_create_cmdline): remove cmdline 
	argument. All callers updated

Modified Paths:
--------------
    trunk/grub2/ChangeLog
    trunk/grub2/include/grub/script_sh.h
    trunk/grub2/kern/parser.c
    trunk/grub2/script/sh/execute.c
    trunk/grub2/script/sh/function.c
    trunk/grub2/script/sh/lexer.c
    trunk/grub2/script/sh/parser.y
    trunk/grub2/script/sh/script.c

Modified: trunk/grub2/ChangeLog
===================================================================
--- trunk/grub2/ChangeLog	2009-06-04 11:37:44 UTC (rev 2243)
+++ trunk/grub2/ChangeLog	2009-06-04 16:18:35 UTC (rev 2244)
@@ -1,3 +1,44 @@
+2009-06-04  Vladimir Serbinenko  <[email protected]>
+
+	Script fixes
+
+	* include/grub/script_sh.h (grub_script_cmdline): remove cmdline
+	(grub_lexer_param): add tokenonhold
+	(grub_script_create_cmdline): remove cmdline. All callers updated
+	(grub_script_function_create): make functionname
+	grub_script_arg. All callers updated
+	(grub_script_execute_argument_to_string): new prototype
+	* kern/parser.c (state_transitions): reorder
+	(grub_parser_cmdline_state): fix a bug and make more compact
+	* script/sh/execute.c (grub_script_execute_argument_to_string): 
+	make global
+	(grub_script_execute_cmdline): use new format
+	* script/sh/function.c (grub_script_function_create): make functionname
+	grub_script_arg. All callers updated
+	* script/sh/lexer.c (grub_script_lexer_init): initilaize tokenonhold
+	(grub_script_yylex): remove
+	(grub_script_yylex2): renamed to ...
+	(grub_script_yylex): ...renamed
+	parse the expressions like a${b}c
+	* script/sh/parser.y (GRUB_PARSER_TOKEN_ARG): new typed terminal
+	(GRUB_PARSER_TOKEN_VAR): remove
+	(GRUB_PARSER_TOKEN_NAME): likewise
+	("if"): declare as typeless
+	("while"): likewise
+	("function"): likewise
+	("else"): likewise
+	("then"): likewise
+	("fi"): likewise
+	(text): remove
+	(argument): likewise
+	(script): accept empty scripts and make exit on error
+	(arguments): use GRUB_PARSER_TOKEN_ARG
+	(function): likewise
+	(command): move error handling to script
+	(menuentry): move grub_script_lexer_ref before
+	* script/sh/script.c (grub_script_create_cmdline): remove cmdline 
+	argument. All callers updated
+
 2009-06-04  Robert Millan  <[email protected]>
 
 	Prevent GRUB from probing floppies during boot.

Modified: trunk/grub2/include/grub/script_sh.h
===================================================================
--- trunk/grub2/include/grub/script_sh.h	2009-06-04 11:37:44 UTC (rev 2243)
+++ trunk/grub2/include/grub/script_sh.h	2009-06-04 16:18:35 UTC (rev 2244)
@@ -77,11 +77,6 @@
 
   /* 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 @@
 
   /* 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 @@
 			 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 @@
 };
 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_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 */

Modified: trunk/grub2/kern/parser.c
===================================================================
--- trunk/grub2/kern/parser.c	2009-06-04 11:37:44 UTC (rev 2243)
+++ trunk/grub2/kern/parser.c	2009-06-04 16:18:35 UTC (rev 2244)
@@ -47,8 +47,8 @@
 
   { 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_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 @@
   /* 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;

Modified: trunk/grub2/script/sh/execute.c
===================================================================
--- trunk/grub2/script/sh/execute.c	2009-06-04 11:37:44 UTC (rev 2243)
+++ trunk/grub2/script/sh/execute.c	2009-06-04 16:18:35 UTC (rev 2244)
@@ -37,7 +37,7 @@
 
 /* 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 @@
   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 @@
 	  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);

Modified: trunk/grub2/script/sh/function.c
===================================================================
--- trunk/grub2/script/sh/function.c	2009-06-04 11:37:44 UTC (rev 2243)
+++ trunk/grub2/script/sh/function.c	2009-06-04 16:18:35 UTC (rev 2244)
@@ -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 @@
   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 @@
   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;
 

Modified: trunk/grub2/script/sh/lexer.c
===================================================================
--- trunk/grub2/script/sh/lexer.c	2009-06-04 11:37:44 UTC (rev 2243)
+++ trunk/grub2/script/sh/lexer.c	2009-06-04 16:18:35 UTC (rev 2244)
@@ -62,6 +62,7 @@
   param->recording = 0;
   param->recordpos = 0;
   param->recordlen = 0;
+  param->tokenonhold = 0;
 
   return param;
 }
@@ -136,224 +137,248 @@
 }
 
 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;
+		  if (use)
+		    *(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

Modified: trunk/grub2/script/sh/parser.y
===================================================================
--- trunk/grub2/script/sh/parser.y	2009-06-04 11:37:44 UTC (rev 2243)
+++ trunk/grub2/script/sh/parser.y	2009-06-04 16:18:35 UTC (rev 2244)
@@ -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:		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,75 +82,28 @@
 		| 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_script_create_cmdline (state, $1);
 		  }
-		| GRUB_PARSER_TOKEN_NAME
-		  {
-		    $$ = grub_script_create_cmdline (state, $1, 0);
-		  }
 ;
 
 /* A single command.  */
 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 @@
    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 @@
 ;
 
 /* 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 @@
 		    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);
 		  }
 ;
 

Modified: trunk/grub2/script/sh/script.c
===================================================================
--- trunk/grub2/script/sh/script.c	2009-06-04 11:37:44 UTC (rev 2243)
+++ trunk/grub2/script/sh/script.c	2009-06-04 16:18:35 UTC (rev 2244)
@@ -161,7 +161,7 @@
    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 @@
   cmd->cmd.exec = grub_script_execute_cmdline;
   cmd->cmd.next = 0;
   cmd->arglist = arglist;
-  cmd->cmdname = cmdname;
 
   return (struct grub_script_cmd *) cmd;
 }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.