diff --git a/ChangeLog b/ChangeLog index a93eb9d35..ae1efed75 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2008-01-15 Bean + + * normal/execute.c (grub_script_exec_argument_to_string): Check for undefined variable. + (grub_script_execute_cmdline): Reset grub_errno. + + * normal/main.c (read_config_file): Reset grub_errno. + + * normal/parse.y (script_init): New. + (script): Move function and menuentry here. + (delimiter): New. + (command): Add delimiter at the end of command. + (commands): Adjust to match the new command. + (commandblock): Remove grub_script_lexer_record_start. + (menuentry): Add grub_script_lexer_record_start, use the new commands. + (if): Use the new commands. + + * conf/common.rmk (pkgdata_MODULES): Add echo.mod. + 2008-01-15 Robert Millan * normal/menu.c (run_menu): Move timeout message from here ... diff --git a/conf/common.mk b/conf/common.mk index af7016027..c9701a62a 100644 --- a/conf/common.mk +++ b/conf/common.mk @@ -1341,7 +1341,7 @@ lvm_mod_LDFLAGS = $(COMMON_LDFLAGS) # Commands. pkglib_MODULES += hello.mod boot.mod terminal.mod ls.mod \ cmp.mod cat.mod help.mod font.mod search.mod \ - loopback.mod configfile.mod \ + loopback.mod configfile.mod echo.mod \ terminfo.mod test.mod blocklist.mod hexdump.mod # For hello.mod. @@ -1658,6 +1658,53 @@ cat_mod_LDFLAGS = $(COMMON_LDFLAGS) # For echo.mod echo_mod_SOURCES = commands/echo.c +CLEANFILES += echo.mod mod-echo.o mod-echo.c pre-echo.o echo_mod-commands_echo.o und-echo.lst +ifneq ($(echo_mod_EXPORTS),no) +CLEANFILES += def-echo.lst +DEFSYMFILES += def-echo.lst +endif +MOSTLYCLEANFILES += echo_mod-commands_echo.d +UNDSYMFILES += und-echo.lst + +echo.mod: pre-echo.o mod-echo.o + -rm -f $@ + $(TARGET_CC) $(echo_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ $^ + $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -R .note -R .comment $@ + +pre-echo.o: $(echo_mod_DEPENDENCIES) echo_mod-commands_echo.o + -rm -f $@ + $(TARGET_CC) $(echo_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ echo_mod-commands_echo.o + +mod-echo.o: mod-echo.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(echo_mod_CFLAGS) -c -o $@ $< + +mod-echo.c: moddep.lst genmodsrc.sh + sh $(srcdir)/genmodsrc.sh 'echo' $< > $@ || (rm -f $@; exit 1) + +ifneq ($(echo_mod_EXPORTS),no) +def-echo.lst: pre-echo.o + $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 echo/' > $@ +endif + +und-echo.lst: pre-echo.o + echo 'echo' > $@ + $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ + +echo_mod-commands_echo.o: commands/echo.c + $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(echo_mod_CFLAGS) -MD -c -o $@ $< +-include echo_mod-commands_echo.d + +CLEANFILES += cmd-echo_mod-commands_echo.lst fs-echo_mod-commands_echo.lst +COMMANDFILES += cmd-echo_mod-commands_echo.lst +FSFILES += fs-echo_mod-commands_echo.lst + +cmd-echo_mod-commands_echo.lst: commands/echo.c gencmdlist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(echo_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh echo > $@ || (rm -f $@; exit 1) + +fs-echo_mod-commands_echo.lst: commands/echo.c genfslist.sh + set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(echo_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh echo > $@ || (rm -f $@; exit 1) + + echo_mod_CFLAGS = $(COMMON_CFLAGS) echo_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/conf/common.rmk b/conf/common.rmk index ee0d3099f..c1f367b76 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -213,7 +213,7 @@ lvm_mod_LDFLAGS = $(COMMON_LDFLAGS) # Commands. pkglib_MODULES += hello.mod boot.mod terminal.mod ls.mod \ cmp.mod cat.mod help.mod font.mod search.mod \ - loopback.mod configfile.mod \ + loopback.mod configfile.mod echo.mod \ terminfo.mod test.mod blocklist.mod hexdump.mod # For hello.mod. diff --git a/normal/execute.c b/normal/execute.c index 4462ddd59..ab0897cca 100644 --- a/normal/execute.c +++ b/normal/execute.c @@ -49,7 +49,8 @@ grub_script_execute_argument_to_string (struct grub_script_arg *arg) 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); @@ -67,7 +68,8 @@ grub_script_execute_argument_to_string (struct grub_script_arg *arg) 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); @@ -99,6 +101,9 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd) grubcmd = grub_command_find (cmdline->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); if (! func) diff --git a/normal/main.c b/normal/main.c index aa848994d..5fb3fa007 100644 --- a/normal/main.c +++ b/normal/main.c @@ -261,6 +261,9 @@ read_config_file (const char *config, int nested) /* Execute the command(s). */ grub_script_execute (parsed_script); + /* Ignore errors. */ + grub_errno = GRUB_ERR_NONE; + /* The parsed script was executed, throw it away. */ grub_script_free (parsed_script); } diff --git a/normal/parser.y b/normal/parser.y index 19cd1bd09..ad0b5f756 100644 --- a/normal/parser.y +++ b/normal/parser.y @@ -43,7 +43,7 @@ %token GRUB_PARSER_TOKEN_FI "fi" %token GRUB_PARSER_TOKEN_NAME %token GRUB_PARSER_TOKEN_VAR -%type script grubcmd command commands commandblock menuentry if +%type script_init script grubcmd command commands commandblock menuentry if %type arguments; %type argument; %type "if" "while" "function" "else" "then" "fi" @@ -55,12 +55,22 @@ %% /* It should be possible to do this in a clean way... */ -script: { state->err = 0} newlines commands +script_init: { state->err = 0} script { - state->parsed = $3; + state->parsed = $2; } ; +script: commands { $$ = $1; } + | function '\n' { $$ = 0; } + | menuentry '\n' { $$ = $1; } +; + +delimiter: '\n' + | ';' + | delimiter '\n' +; + newlines: /* Empty */ | newlines '\n' ; @@ -124,41 +134,31 @@ grubcmd: GRUB_PARSER_TOKEN_NAME arguments ; /* A single command. */ -command: grubcmd { $$ = $1; } - | if { $$ = $1; } - | function { $$ = 0; } - | menuentry { $$ = $1; } -; - -/* A block of commands. */ -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 *) $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 +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. */ +commands: command + { + $$ = grub_script_add_cmd (state, 0, $1); + } + | command commands + { + struct grub_script_cmdblock *cmd; + cmd = (struct grub_script_cmdblock *) $2; + $$ = grub_script_add_cmd (state, cmd, $1); + } +; + /* 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 @@ -194,7 +194,6 @@ function: "function" GRUB_PARSER_TOKEN_NAME commandblock: '{' { grub_script_lexer_ref (state->lexerstate); - grub_script_lexer_record_start (state->lexerstate); } newlines commands '}' { @@ -204,10 +203,17 @@ commandblock: '{' ; /* A menu entry. Carefully save the memory that is allocated. */ -menuentry: "menuentry" argument newlines commandblock +menuentry: "menuentry" argument + { + grub_script_lexer_ref (state->lexerstate); + } newlines '{' + { + grub_script_lexer_record_start (state->lexerstate); + } newlines commands '}' { 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); } ; @@ -218,14 +224,14 @@ if_statement: "if" { grub_script_lexer_ref (state->lexerstate); } ; /* The if statement. */ -if: if_statement grubcmd ';' "then" commands "fi" +if: if_statement commands "then" newlines commands "fi" { $$ = grub_script_create_cmdif (state, $2, $5, 0); grub_script_lexer_deref (state->lexerstate); } - | if_statement grubcmd ';' "then" commands "else" commands "fi" + | if_statement commands "then" newlines commands "else" newlines commands "fi" { - $$ = grub_script_create_cmdif (state, $2, $5, $7); + $$ = grub_script_create_cmdif (state, $2, $5, $8); grub_script_lexer_deref (state->lexerstate); } ;