This update includes u2 and u2-1, and fix a small problem caused by u2-2.
--
Bean
2007-06-28 Bean <[EMAIL PROTECTED]>
* kern/parser.c (state_transitions): Exit GRUB_PARSER_STATE_VARNAME
state when "/" is encountered.
* normal/execute.c (grub_script_argument_to_string): Check for
undefined variable.
* normal/execute.c (grub_script_execute_cmdline): Reset grub_errno.
* normal/main.c (read_config_file): Reset grub_errno.
* normal/lexer.c (grub_script_yylex2): Construct arg structure when
mixed text is detected.
* normal/lexer.c (check_textstate): Add GRUB_PARSER_STATE_ESC.
* normal/parser.y : Change attribute of token GRUB_PARSER_TOKEN_VAR.
Index: kern/parser.c
===================================================================
RCS file: /sources/grub/grub2/kern/parser.c,v
retrieving revision 1.2
diff -u -r1.2 parser.c
--- kern/parser.c 23 Nov 2005 03:36:24 -0000 1.2
+++ kern/parser.c 28 Jun 2007 03:31:55 -0000
@@ -44,6 +44,7 @@
{ GRUB_PARSER_STATE_VAR, GRUB_PARSER_STATE_VARNAME2, '{', 0},
{ GRUB_PARSER_STATE_VAR, GRUB_PARSER_STATE_VARNAME, 0, 1},
{ GRUB_PARSER_STATE_VARNAME, GRUB_PARSER_STATE_TEXT, ' ', 1},
+ { GRUB_PARSER_STATE_VARNAME, GRUB_PARSER_STATE_TEXT, '/', 1},
{ GRUB_PARSER_STATE_VARNAME2, GRUB_PARSER_STATE_TEXT, '}', 0},
{ GRUB_PARSER_STATE_QVAR, GRUB_PARSER_STATE_QVARNAME2, '{', 0},
Index: normal/execute.c
===================================================================
RCS file: /sources/grub/grub2/normal/execute.c,v
retrieving revision 1.4
diff -u -r1.4 execute.c
--- normal/execute.c 28 May 2006 21:58:34 -0000 1.4
+++ normal/execute.c 28 Jun 2007 03:31:55 -0000
@@ -50,7 +50,8 @@
if (argi->type == 1)
{
val = grub_env_get (argi->str);
- size += grub_strlen (val);
+ if (val)
+ size += grub_strlen (val);
}
else
size += grub_strlen (argi->str);
@@ -68,7 +69,8 @@
if (argi->type == 1)
{
val = grub_env_get (argi->str);
- grub_strcat (chararg, val);
+ if (val)
+ grub_strcat (chararg, val);
}
else
grub_strcat (chararg, argi->str);
@@ -100,6 +102,9 @@
grubcmd = grub_command_find (cmdline->cmdname);
if (! grubcmd)
{
+ /* Reset grub_errno. */
+ grub_errno = GRUB_ERR_NONE;
+
/* It's not a GRUB command, try all functions. */
func = grub_script_function_find (cmdline->cmdname);
if (! func)
@@ -119,7 +124,8 @@
grub_errno = GRUB_ERR_NONE;
}
grub_free (assign);
- return 0;
+ ret = grub_errno;
+ goto quit;
}
}
@@ -168,6 +174,7 @@
grub_free (args[i]);
grub_free (args);
+quit:
grub_sprintf (errnobuf, "%d", ret);
grub_env_set ("?", errnobuf);
Index: normal/lexer.c
===================================================================
RCS file: /sources/grub/grub2/normal/lexer.c,v
retrieving revision 1.6
diff -u -r1.6 lexer.c
--- normal/lexer.c 4 Jun 2006 15:56:55 -0000 1.6
+++ normal/lexer.c 28 Jun 2007 03:31:55 -0000
@@ -41,7 +41,8 @@
{
return (state == GRUB_PARSER_STATE_TEXT
|| state == GRUB_PARSER_STATE_QUOTE
- || state == GRUB_PARSER_STATE_DQUOTE);
+ || state == GRUB_PARSER_STATE_DQUOTE
+ || state == GRUB_PARSER_STATE_ESC);
}
struct grub_lexer_param *
@@ -161,6 +162,8 @@
char *buffer;
char *bp;
struct grub_lexer_param *state = parsestate->lexerstate;
+ struct grub_script_arg *arg = 0;
+ int done = 0;
if (state->done)
return 0;
@@ -196,13 +199,14 @@
}
}
+back:
newstate = grub_parser_cmdline_state (state->state, *state->script, &use);
/* Check if it is a text. */
if (check_textstate (newstate))
{
/* In case the string is not quoted, this can be a one char
- length symbol. */
+ length symbol. */
if (newstate == GRUB_PARSER_STATE_TEXT)
{
switch (*state->script)
@@ -213,7 +217,7 @@
newstate = grub_parser_cmdline_state (state->state,
*state->script, &use);
if (! (state->state == GRUB_PARSER_STATE_TEXT
- && *state->script == ' '))
+ && *state->script == ' '))
{
grub_dprintf ("scripting", "token=` '\n");
return ' ';
@@ -260,8 +264,6 @@
if (newstate == GRUB_PARSER_STATE_TEXT
&& state->state != GRUB_PARSER_STATE_ESC)
{
- int breakout = 0;
-
switch (use)
{
case ' ':
@@ -269,13 +271,13 @@
case '}':
case ';':
case '\n':
- breakout = 1;
+ done = 1;
}
- if (breakout)
+ if (done)
break;
- *(bp++) = use;
}
- else if (use)
+
+ if (use)
*(bp++) = use;
state->state = newstate;
@@ -285,27 +287,39 @@
/* A string of text was read in. */
*bp = '\0';
grub_dprintf ("scripting", "token=`%s'\n", buffer);
- yylval->string = buffer;
- /* Detect some special tokens. */
- if (! grub_strcmp (buffer, "while"))
- return GRUB_PARSER_TOKEN_WHILE;
- else if (! grub_strcmp (buffer, "if"))
- return GRUB_PARSER_TOKEN_IF;
- else if (! grub_strcmp (buffer, "function"))
- return GRUB_PARSER_TOKEN_FUNCTION;
- else if (! grub_strcmp (buffer, "menuentry"))
- return GRUB_PARSER_TOKEN_MENUENTRY;
- else if (! grub_strcmp (buffer, "@"))
- return GRUB_PARSER_TOKEN_MENUENTRY;
- else if (! grub_strcmp (buffer, "else"))
- return GRUB_PARSER_TOKEN_ELSE;
- else if (! grub_strcmp (buffer, "then"))
- return GRUB_PARSER_TOKEN_THEN;
- else if (! grub_strcmp (buffer, "fi"))
- return GRUB_PARSER_TOKEN_FI;
- else
- return GRUB_PARSER_TOKEN_NAME;
+ if (!*state->script)
+ done = 1;
+
+ if ((done) && (!arg))
+ {
+ yylval->string = buffer;
+
+ /* Detect some special tokens. */
+ if (! grub_strcmp (buffer, "while"))
+ return GRUB_PARSER_TOKEN_WHILE;
+ else if (! grub_strcmp (buffer, "if"))
+ return GRUB_PARSER_TOKEN_IF;
+ else if (! grub_strcmp (buffer, "function"))
+ return GRUB_PARSER_TOKEN_FUNCTION;
+ else if (! grub_strcmp (buffer, "menuentry"))
+ return GRUB_PARSER_TOKEN_MENUENTRY;
+ else if (! grub_strcmp (buffer, "@"))
+ return GRUB_PARSER_TOKEN_MENUENTRY;
+ else if (! grub_strcmp (buffer, "else"))
+ return GRUB_PARSER_TOKEN_ELSE;
+ else if (! grub_strcmp (buffer, "then"))
+ return GRUB_PARSER_TOKEN_THEN;
+ else if (! grub_strcmp (buffer, "fi"))
+ return GRUB_PARSER_TOKEN_FI;
+ else
+ return GRUB_PARSER_TOKEN_NAME;
+ }
+
+ if (bp != buffer)
+ arg =
+ grub_script_arg_add (parsestate, arg, GRUB_SCRIPT_ARG_TYPE_STR,
+ buffer);
}
else if (newstate == GRUB_PARSER_STATE_VAR
|| newstate == GRUB_PARSER_STATE_QVAR)
@@ -341,19 +355,33 @@
}
*bp = '\0';
- state->state = newstate;
- yylval->string = buffer;
- grub_dprintf ("scripting", "vartoken=`%s'\n", buffer);
+ if (newstate == GRUB_PARSER_STATE_VARNAME)
+ state->state = GRUB_PARSER_STATE_TEXT;
- return GRUB_PARSER_TOKEN_VAR;
+ if (bp != buffer)
+ arg = grub_script_arg_add (parsestate, arg, GRUB_SCRIPT_ARG_TYPE_VAR,
+ buffer);
}
else
{
/* There is either text or a variable name. In the case you
- arrive here there is a serious problem with the lexer. */
+ arrive here there is a serious problem with the lexer. */
grub_error (GRUB_ERR_BAD_ARGUMENT, "Internal error\n");
return 0;
}
+
+ if ((done) || (! *state->script))
+ {
+ if (arg)
+ {
+ yylval->arg = arg;
+ return GRUB_PARSER_TOKEN_VAR;
+ }
+ else
+ return ' ';
+ }
+
+ goto back;
}
void
Index: normal/main.c
===================================================================
RCS file: /sources/grub/grub2/normal/main.c,v
retrieving revision 1.20
diff -u -r1.20 main.c
--- normal/main.c 5 Mar 2007 20:32:43 -0000 1.20
+++ normal/main.c 28 Jun 2007 03:31:55 -0000
@@ -262,6 +262,9 @@
/* Execute the command(s). */
grub_script_execute (parsed_script);
+ /* Reset grub_errno. */
+ grub_errno = GRUB_ERR_NONE;
+
/* The parsed script was executed, throw it away. */
grub_script_free (parsed_script);
}
Index: normal/parser.y
===================================================================
RCS file: /sources/grub/grub2/normal/parser.y,v
retrieving revision 1.6
diff -u -r1.6 parser.y
--- normal/parser.y 4 Jun 2006 15:56:55 -0000 1.6
+++ normal/parser.y 28 Jun 2007 03:31:55 -0000
@@ -46,9 +46,9 @@
%token GRUB_PARSER_TOKEN_VAR
%type <cmd> script grubcmd command commands commandblock menuentry if
%type <arglist> arguments;
-%type <arg> argument;
+%type <arg> argument GRUB_PARSER_TOKEN_VAR;
%type <string> "if" "while" "function" "else" "then" "fi"
-%type <string> text GRUB_PARSER_TOKEN_NAME GRUB_PARSER_TOKEN_VAR
+%type <string> text GRUB_PARSER_TOKEN_NAME
%pure-parser
%lex-param { struct grub_parser_param *state };
@@ -86,7 +86,7 @@
for example: `foo${bar}baz'. */
argument: GRUB_PARSER_TOKEN_VAR
{
- $$ = grub_script_arg_add (state, 0,
GRUB_SCRIPT_ARG_TYPE_VAR, $1);
+ $$ = $1;
}
| text
{
_______________________________________________
Grub-devel mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/grub-devel