2006-05-20 Marco Gerards <marco@gnu.org>

* normal/lexer.c (grub_script_yylex): Don't filter out newlines.

	* normal/parser.y (commandblock): Defined as <cmd>.  A subroutine
	for `menuentry'.
	(script): Accept leading newlines.
	(newlines): New rule to describe 0 or more newlines.
	(commands): Accept `command' with trailing newline.  Fixed the
	order in which arguments were passed to `grub_script_add_cmd'.
	Accept commands separated by newlines.
	(function): Changed to accept newlines.
	(menuentry) Rewritten.

	* normal/script.c (grub_script_create_cmdmenu): Add new entries in
	front of the list, instead of to the end.
This commit is contained in:
marco_g 2006-05-20 11:10:22 +00:00
parent 577b405042
commit 7dc4f874a6
3 changed files with 51 additions and 30 deletions

View File

@ -1,7 +1,7 @@
/* lexer.c - The scripting lexer. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2005 Free Software Foundation, Inc.
* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -147,7 +147,7 @@ grub_script_yylex (YYSTYPE *yylval, struct grub_parser_param *parsestate)
while (r == -1)
{
r = grub_script_yylex2 (yylval, parsestate);
if (r == ' ' || r == '\n')
if (r == ' ')
r = -1;
}
return r;

View File

@ -1,7 +1,7 @@
/* parser.y - The scripting parser. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2005 Free Software Foundation, Inc.
* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -44,7 +44,7 @@
%token GRUB_PARSER_TOKEN_FI "fi"
%token GRUB_PARSER_TOKEN_NAME
%token GRUB_PARSER_TOKEN_VAR
%type <cmd> script grubcmd command commands menuentry if
%type <cmd> script grubcmd command commands commandblock menuentry if
%type <arglist> arguments;
%type <arg> argument;
%type <string> "if" "while" "function" "else" "then" "fi"
@ -56,12 +56,16 @@
%%
/* It should be possible to do this in a clean way... */
script: { state->err = 0} commands
script: { state->err = 0} newlines commands
{
state->parsed = $2;
state->parsed = $3;
}
;
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
@ -128,15 +132,25 @@ command: grubcmd { $$ = $1; }
;
/* A block of commands. */
commands: command
commands: command '\n'
{
$$ = grub_script_add_cmd (state, 0, $1);
}
| command
{
$$ = grub_script_add_cmd (state, 0, $1);
}
| command ';' commands
{
struct grub_script_cmdblock *cmd;
cmd = (struct grub_script_cmdblock *) $1;
$$ = grub_script_add_cmd (state, cmd, $3);
cmd = (struct grub_script_cmdblock *) $3;
$$ = grub_script_add_cmd (state, cmd, $1);
}
| command '\n' newlines commands
{
struct grub_script_cmdblock *cmd;
cmd = (struct grub_script_cmdblock *) $4;
$$ = grub_script_add_cmd (state, cmd, $1);
}
| error
{
@ -146,17 +160,22 @@ commands: command
}
;
/* A function. Carefully save the memory that is allocated. */
/* A function. Carefully save the memory that is allocated. Don't
change any stuff because it might seem like a fun thing to do!
Special care was take to make sure the mid-rule actions are
executed on the right moment. So the `commands' rule should be
recognised after executing the `grub_script_mem_record; and before
`grub_script_mem_record_stop'. */
function: "function" GRUB_PARSER_TOKEN_NAME
{
grub_script_lexer_ref (state->lexerstate);
} '{'
} newlines '{'
{
/* The first part of the function was recognised.
Now start recording the memory usage to store
this function. */
state->func_mem = grub_script_mem_record (state);
} commands '}'
} newlines commands '}'
{
struct grub_script *script;
@ -164,29 +183,33 @@ function: "function" GRUB_PARSER_TOKEN_NAME
was recorded. */
state->func_mem = grub_script_mem_record_stop (state,
state->func_mem);
script = grub_script_create ($6, state->func_mem);
script = grub_script_create ($8, state->func_mem);
if (script)
grub_script_function_create ($2, script);
grub_script_lexer_deref (state->lexerstate);
}
;
/* A menu entry. Carefully save the memory that is allocated. */
menuentry: "menuentry" argument
{
/* Carefully designed, together with `menuentry' so everything happens
just in the expected order. */
commandblock: '{'
{
grub_script_lexer_ref (state->lexerstate);
} '{'
{
/* Record sourcecode of the menu entry. It can be
parsed multiple times if it is part of a
loop. */
grub_script_lexer_record_start (state->lexerstate);
} commands '}'
grub_script_lexer_record_start (state->lexerstate);
}
newlines commands '}'
{
grub_script_lexer_deref (state->lexerstate);
$$ = $4;
}
;
/* A menu entry. Carefully save the memory that is allocated. */
menuentry: "menuentry" argument newlines commandblock
{
char *menu_entry;
menu_entry = grub_script_lexer_record_stop (state->lexerstate);
$$ = grub_script_create_cmdmenu (state, $2, menu_entry, 0);
grub_script_lexer_deref (state->lexerstate);
}
;

View File

@ -1,7 +1,7 @@
/* script.c -- Functions to create an in memory description of the script. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2005 Free Software Foundation, Inc.
* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -253,16 +253,14 @@ grub_script_add_cmd (struct grub_parser_param *state,
cmdblock->cmd.exec = grub_script_execute_cmdblock;
cmdblock->cmd.next = 0;
cmdblock->cmdlist = cmd;
cmd->next = 0;
}
else
{
struct grub_script_cmd **last;
for (last = &cmdblock->cmdlist; *last; last = &(*last)->next);
*last = cmd;
cmd->next = cmdblock->cmdlist;
cmdblock->cmdlist = cmd;
}
cmd->next = 0;
return (struct grub_script_cmd *) cmdblock;
}