+2006-16-04 Marco Gerards <marco@gnu.org>
+
+ * normal/command.c (grub_command_init): Remove the title command.
+
+ * normal/lexer.c (grub_script_yylex): Renamed from this...
+ (grub_script_yylex2): ... to this.
+ (grub_script_yylex): New function. Temporary
+ introduced to filter some tokens.
+ (grub_script_yyerror): Print a newline.
+
+ * normal/main.c (read_config_file): Output information about the
+ lines that contain errors. Wait for a key after all lines have
+ been processed. Don't return an empty menu.
+
+ * normal/parser.y (func_mem): Don't initialize.
+ (menu_entry): Likewise.
+ (err): New variable.
+ (script): Don't return anything when an error was encountered.
+ (ws, returns): Removed rules.
+ (argument): Disabled concatenated variable support.
+ (arguments): Remove explicit separators.
+ (grubcmd): Likewise.
+ (function): Likewise.
+ (menuentry): Likewise.
+ (if): Likewise.
+ (commands): Likewise. Add error handling.
+
+ * normal/script.c (grub_script_create_cmdline): If
+ `grub_script_parsed' is 0, assume the parser encountered an error.
+
2006-04-02 Yoshinori K. Okuji <okuji@enbug.org>
* configure.ac: Add support for EFI. Fix the typo
grub_file_t file;
auto grub_err_t getline (char **line);
int currline = 0;
+ int errors = 0;
grub_err_t getline (char **line)
{
while (get_line (file, cmdline, sizeof (cmdline)))
{
struct grub_script *parsed_script;
+ int startline;
- currline++;
+ startline = ++currline;
/* Execute the script, line for line. */
parsed_script = grub_script_parse (cmdline, getline);
if (! parsed_script)
{
- /* Wait until the user pushes any key so that the user can
- see what happened. */
- grub_printf ("\nPress any key to continue...");
- (void) grub_getkey ();
-
- grub_file_close (file);
- return 0;
+ grub_printf ("(line %d-%d)\n", startline, currline);
+ errors++;
+ continue;
}
/* Execute the command(s). */
}
grub_file_close (file);
+
+ if (errors > 0)
+ {
+ /* Wait until the user pushes any key so that the user can
+ see what happened. */
+ grub_printf ("\nPress any key to continue...");
+ (void) grub_getkey ();
+ }
+
+ /* If the menu is empty, just drop it. */
+ if (current_menu->size == 0)
+ {
+ grub_free (current_menu);
+ return 0;
+ }
+
return newmenu;
}
#define YYMALLOC grub_malloc
/* Keep track of the memory allocated for this specific function. */
-static struct grub_script_mem *func_mem = 0;
+static struct grub_script_mem *func_mem;
-static char *menu_entry = 0;
+static char *menu_entry;
+
+static int err;
%}
%%
/* It should be possible to do this in a clean way... */
-script: commands returns
+script: { err = 0} commands
{
- grub_script_parsed = $1;
+ grub_script_parsed = err ? 0 : $2;
}
;
}
;
-ws: /* Empty */
- | ' '
-;
-
-returns: /* Empty */
- | '\n'
-;
-
/* 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 (0, GRUB_SCRIPT_ARG_TYPE_STR, $1);
}
- | 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);
- }
+/* XXX: Currently disabled to simplify the parser. This should be
+ parsed by yet another parser for readibility. */
+/* | 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
{
$$ = grub_script_add_arglist (0, $1);
}
- | arguments ' ' argument
+ | arguments argument
{
- $$ = grub_script_add_arglist ($1, $3);
+ $$ = grub_script_add_arglist ($1, $2);
}
;
-grubcmd: ws GRUB_PARSER_TOKEN_NAME ' ' arguments ws
+grubcmd: GRUB_PARSER_TOKEN_NAME arguments
{
- $$ = grub_script_create_cmdline ($2, $4);
+ $$ = grub_script_create_cmdline ($1, $2);
}
- | ws GRUB_PARSER_TOKEN_NAME ws
+ | GRUB_PARSER_TOKEN_NAME
{
- $$ = grub_script_create_cmdline ($2, 0);
+ $$ = grub_script_create_cmdline ($1, 0);
}
;
command: grubcmd { $$ = $1; }
| if { $$ = $1; }
| function { $$ = 0; }
- | menuentry { $$ = $1; }
+ | menuentry { $$ = $1; }
;
/* A block of commands. */
{
$$ = grub_script_add_cmd (0, $1);
}
- | commands ';' command
+ | command ';' commands
{
struct grub_script_cmdblock *cmd;
cmd = (struct grub_script_cmdblock *) $1;
$$ = grub_script_add_cmd (cmd, $3);
}
- | commands '\n' command
- {
- struct grub_script_cmdblock *cmd;
- cmd = (struct grub_script_cmdblock *) $1;
- $$ = grub_script_add_cmd (cmd, $3);
+ | error
+ {
+ yyerror ("Incorrect command");
+ err = 1;
+ yyerrok;
}
;
/* A function. Carefully save the memory that is allocated. */
-function: "function" ' ' GRUB_PARSER_TOKEN_NAME
+function: "function" GRUB_PARSER_TOKEN_NAME
{
grub_script_lexer_ref ();
- } ws '{' returns
+ } '{'
{
/* The first part of the function was recognised.
Now start recording the memory usage to store
this function. */
func_mem = grub_script_mem_record ();
- } commands returns '}'
+ } commands '}'
{
struct grub_script *script;
/* All the memory usage for parsing this function
was recorded. */
func_mem = grub_script_mem_record_stop (func_mem);
- script = grub_script_create ($9, func_mem);
+ script = grub_script_create ($6, func_mem);
if (script)
- grub_script_function_create ($3, script);
+ grub_script_function_create ($2, script);
grub_script_lexer_deref ();
}
;
/* A menu entry. Carefully save the memory that is allocated. */
-menuentry: "menuentry" ' ' argument
+menuentry: "menuentry" argument
{
grub_script_lexer_ref ();
- } ws '{' returns
+ } '{'
{
/* Record sourcecode of the menu entry. It can be
parsed multiple times if it is part of a
loop. */
grub_script_lexer_record_start ();
- } commands returns '}'
+ } commands '}'
{
menu_entry = grub_script_lexer_record_stop ();
- $$ = grub_script_create_cmdmenu ($3, menu_entry, 0);
+ $$ = grub_script_create_cmdmenu ($2, menu_entry, 0);
grub_script_lexer_deref ();
}
;
;
/* The if statement. */
-if: if_statement grubcmd ';' ws "then" returns commands returns "fi"
+if: if_statement grubcmd ';' "then" commands "fi"
{
- $$ = grub_script_create_cmdif ($2, $7, 0);
+ $$ = grub_script_create_cmdif ($2, $5, 0);
grub_script_lexer_deref ();
}
- | if_statement grubcmd ';' ws "then" returns commands returns "else" returns commands returns "fi"
+ | if_statement grubcmd ';' "then" commands "else" commands "fi"
{
- $$ = grub_script_create_cmdif ($2, $7, $11);
+ $$ = grub_script_create_cmdif ($2, $5, $7);
grub_script_lexer_deref ();
}
;