commit-grub
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[2158] 2009-05-02 Bean <address@hidden>


From: Bean
Subject: [2158] 2009-05-02 Bean <address@hidden>
Date: Sat, 02 May 2009 19:49:35 +0000

Revision: 2158
          http://svn.sv.gnu.org/viewvc/?view=rev&root=grub&revision=2158
Author:   bean
Date:     2009-05-02 19:49:34 +0000 (Sat, 02 May 2009)
Log Message:
-----------
2009-05-02  Bean  <address@hidden>

        * conf/common.rmk (grub_script.tab.c): Change normal/parser.y to
        script/sh/parser.y.
        (pkglib_MODULES): Add normal.mod and sh.mod.
        (normal_SOURCES): New variable.
        (normal_mod_CFLAGS): Likewise.
        (normal_mod_LDFLAGS): Likewise.
        (sh_mod_SOURCES): Likewise.
        (sh_mod_CFLAGS): Likewise.
        (sh_mod_LDFLAGS): Likewise.

        * conf/i386-pc.rmk (normal/lexer.c_DEPENDENCIES): Changed to
        script/sh/lexer.c_DEPENDENCIES.
        (kernel_img_SOURCES): Remove kern/rescue.c, and kern/reader.c,
        kern/rescue_reader.c and kern/rescue_parser.c.
        (kernel_img_HEADERS): Remove rescue.h, add reader.h.
        (grub_emu_SOURCES): Change source files.
        (pkglib_MODULES): Remove normal.mod.
        (normal_SOURCES): Removed.
        (normal_mod_CFLAGS): Likewise.
        (normal_mod_LDFLAGS): Likewise.
        * conf/i386-coreboot.rmk: Likewise.
        * conf/i386-efi.rmk: Likewise.
        * conf/i386-ieee1276.rmk: Likewise.
        * conf/powerpc-ieee1275.rmk: Likewise.
        * conf/sparc64-ieee1275.rmk: Likewise.
        * conf/x86_64-efi.rmk: Likewise.

        * include/grub/command.h (grub_command_execute): New inline function.

        * include/grub/menu.h (grub_menu_entry): Removed commands field.

        * include/grub/normal.h: Remove <grub/setjmp.h>.
        (grub_fs_module_list): Moved to normal/autofs.c.
        (grub_exit_env): Removed.
        (grub_command_execute): Likewise.
        (grub_normal_menu_addentry): Renamed to grub_menu_addentry, removed
        parameter script.
        (read_command_list): New function declaration.
        (read_fs_list): Likewise.

        * include/parser.h: Include <grub/reader.h>.
        (grub_parser_split_cmdline): Change type of getline parameter.
        (grub_parser): New structure.
        (grub_parser_class): New variable.
        (grub_parser_execute): New function declaration.
        (grub_register_rescue_parser): Likewise.
        (grub_parser_register): New inline function.
        (grub_parser_unregister): Likewise.
        (grub_parser_get_current): Likewise.
        (grub_parser_set_current): Likewise.

        * include/grub/reader.h: New file.
        * kern/reader.c: Likewise.
        * kern/rescue_parser.c: Likewise.
        * kern/rescue_reader.c: Likewise.
        * normal/autofs.c: Likewise.
        * normal/dyncmd.c: Likewise.

        * include/grub/rescue.h: Removed.
        * normal/command.h: Likewise.

        * include/grub/script.h: Moved to ...
        * include/grub/script_sh.h: ... Moved here.
        * normal/execute.c: Moved to ...
        * script/sh/execute.c: ... Moved here.
        * normal/function.c: Moved to ...
        * script/sh/function.c: ... Moved here.
        * normal/lexer.c: Moved to ...
        * script/sh/lexer.c: ... Moved here.
        * normal/parser.y: Moved to ...
        * script/sh/parser.y: ... Moved here.
        * normal/script.c: Moved to ...
        * script/sh/script.c: ... Moved here.

        * normal/main.c: Remove <grub/rescue.h> and <grub/script.h>, include
        <grub/reader.h>.
        (grub_exit_env): Removed.
        (fs_module_list): Moved to normal/autofs.c.
        (grub_file_getline): Don't handle comment here.
        (free_menu): Skip removed field entry->commands.
        (grub_normal_menu_addentry): Removed as grub_menu_entry, removed
        script parameter.
        (read_config_file): Removed nested parameter, change getline function.
        (grub_enter_normal_mode): Removed.
        (grub_dyncmd_dispatcher): Moved to normal/dyncmd.c.
        (read_command_list): Likewise.
        (autoload_fs_module): Moved to normal/autofs.c.
        (read_fs_list): Likewise.
        (reader_nested): New variable.
        (grub_normal_execute): Run parser.sh to switch to sh parser.
        (grub_cmd_rescue): Removed.
        (cmd_normal): Removed.
        (grub_cmd_normal): Unregister itself at the beginning. Don't register
        rescue command.
        (grub_cmdline_run): New function.
        (grub_normal_reader_init): Likewise.
        (grub_normal_read_line): Likewise.
        (grub_env_write_pager): Likewise.
        (cmdline): New variable.
        (grub_normal_reader): Likewise.
        (GRUB_MOD_INIT): Register normal reader and set as current, register
        pager hook, register normal command with grub_register_command_prio,
        so that it won't show up in command.lst.
        (GRUB_MOD_FINI): Unregister normal reader, unhook pager, clear
        grub_fs_autoload_hook.

        * normal/menu.c: Remove <grub/script.h>, add <grub/command.h>.
        (grub_menu_execute_entry): Replace grub_script_execute with
        grub_parser_execute, change parameter to grub_command_execute.

        * normal/menu_text.c: Remove <grub/script.h>.

        * normal/menu_entry.c: Remove <grub/script.h>, add <grub/command.h>
        and <grub/parser.h>.
        (run): Change editor_getline to use new parser interface. Change
        parameter to grub_command_execute.

        * kern/main.c: Remove <grub/rescue.h>, include <grub/command.h>,
        <grub/reader.h> and <grub/parser.h>.
        (grub_load_normal_mode): Execute normal command.
        (grub_main): Call grub_register_core_commands,
        grub_register_rescue_parser and grub_register_rescue_reader, use
        grub_reader_loop to enter input loop.

        * kern/parser.c (grub_parser_spli_cmdline): Change type of getline
        parameter.
        (grub_parser_class): New variable.
        (grub_parser_execute): New function.

        * loader/i386/multiboot.c: Remove <grub/rescue.h>.
        * loader/multiboot2.c: Likewise.
        * loader/sparc64/ieee1275/linux.c: Likewise.

        * util/grub-emu.c (read_command_list): New dummy function.

Modified Paths:
--------------
    trunk/grub2/ChangeLog
    trunk/grub2/conf/common.rmk
    trunk/grub2/conf/i386-coreboot.rmk
    trunk/grub2/conf/i386-efi.rmk
    trunk/grub2/conf/i386-ieee1275.rmk
    trunk/grub2/conf/i386-pc.rmk
    trunk/grub2/conf/powerpc-ieee1275.rmk
    trunk/grub2/conf/sparc64-ieee1275.rmk
    trunk/grub2/conf/x86_64-efi.rmk
    trunk/grub2/include/grub/command.h
    trunk/grub2/include/grub/menu.h
    trunk/grub2/include/grub/normal.h
    trunk/grub2/include/grub/parser.h
    trunk/grub2/kern/main.c
    trunk/grub2/kern/parser.c
    trunk/grub2/loader/i386/multiboot.c
    trunk/grub2/loader/multiboot2.c
    trunk/grub2/loader/sparc64/ieee1275/linux.c
    trunk/grub2/normal/cmdline.c
    trunk/grub2/normal/main.c
    trunk/grub2/normal/menu.c
    trunk/grub2/normal/menu_entry.c
    trunk/grub2/normal/menu_text.c
    trunk/grub2/util/grub-emu.c

Added Paths:
-----------
    trunk/grub2/include/grub/reader.h
    trunk/grub2/include/grub/script_sh.h
    trunk/grub2/kern/reader.c
    trunk/grub2/kern/rescue_parser.c
    trunk/grub2/kern/rescue_reader.c
    trunk/grub2/normal/autofs.c
    trunk/grub2/normal/dyncmd.c
    trunk/grub2/script/
    trunk/grub2/script/sh/
    trunk/grub2/script/sh/execute.c
    trunk/grub2/script/sh/function.c
    trunk/grub2/script/sh/lexer.c
    trunk/grub2/script/sh/main.c
    trunk/grub2/script/sh/parser.y
    trunk/grub2/script/sh/script.c

Removed Paths:
-------------
    trunk/grub2/include/grub/rescue.h
    trunk/grub2/include/grub/script.h
    trunk/grub2/kern/rescue.c
    trunk/grub2/normal/command.c
    trunk/grub2/normal/execute.c
    trunk/grub2/normal/function.c
    trunk/grub2/normal/lexer.c
    trunk/grub2/normal/parser.y
    trunk/grub2/normal/script.c

Modified: trunk/grub2/ChangeLog
===================================================================
--- trunk/grub2/ChangeLog       2009-05-02 16:55:35 UTC (rev 2157)
+++ trunk/grub2/ChangeLog       2009-05-02 19:49:34 UTC (rev 2158)
@@ -1,3 +1,140 @@
+2009-05-02  Bean  <address@hidden>
+
+       * conf/common.rmk (grub_script.tab.c): Change normal/parser.y to
+       script/sh/parser.y.
+       (pkglib_MODULES): Add normal.mod and sh.mod.
+       (normal_SOURCES): New variable.
+       (normal_mod_CFLAGS): Likewise.
+       (normal_mod_LDFLAGS): Likewise.
+       (sh_mod_SOURCES): Likewise.
+       (sh_mod_CFLAGS): Likewise.
+       (sh_mod_LDFLAGS): Likewise.
+
+       * conf/i386-pc.rmk (normal/lexer.c_DEPENDENCIES): Changed to
+       script/sh/lexer.c_DEPENDENCIES.
+       (kernel_img_SOURCES): Remove kern/rescue.c, and kern/reader.c,
+       kern/rescue_reader.c and kern/rescue_parser.c.
+       (kernel_img_HEADERS): Remove rescue.h, add reader.h.
+       (grub_emu_SOURCES): Change source files.
+       (pkglib_MODULES): Remove normal.mod.
+       (normal_SOURCES): Removed.
+       (normal_mod_CFLAGS): Likewise.
+       (normal_mod_LDFLAGS): Likewise.
+       * conf/i386-coreboot.rmk: Likewise.
+       * conf/i386-efi.rmk: Likewise.
+       * conf/i386-ieee1276.rmk: Likewise.
+       * conf/powerpc-ieee1275.rmk: Likewise.
+       * conf/sparc64-ieee1275.rmk: Likewise.
+       * conf/x86_64-efi.rmk: Likewise.
+
+       * include/grub/command.h (grub_command_execute): New inline function.
+
+       * include/grub/menu.h (grub_menu_entry): Removed commands field.
+
+       * include/grub/normal.h: Remove <grub/setjmp.h>.
+       (grub_fs_module_list): Moved to normal/autofs.c.
+       (grub_exit_env): Removed.
+       (grub_command_execute): Likewise.
+       (grub_normal_menu_addentry): Renamed to grub_menu_addentry, removed
+       parameter script.
+       (read_command_list): New function declaration.
+       (read_fs_list): Likewise.
+
+       * include/parser.h: Include <grub/reader.h>.
+       (grub_parser_split_cmdline): Change type of getline parameter.
+       (grub_parser): New structure.
+       (grub_parser_class): New variable.
+       (grub_parser_execute): New function declaration.
+       (grub_register_rescue_parser): Likewise.
+       (grub_parser_register): New inline function.
+       (grub_parser_unregister): Likewise.
+       (grub_parser_get_current): Likewise.
+       (grub_parser_set_current): Likewise.
+
+       * include/grub/reader.h: New file.
+       * kern/reader.c: Likewise.
+       * kern/rescue_parser.c: Likewise.
+       * kern/rescue_reader.c: Likewise.
+       * normal/autofs.c: Likewise.
+       * normal/dyncmd.c: Likewise.
+
+       * include/grub/rescue.h: Removed.
+       * normal/command.h: Likewise.
+
+       * include/grub/script.h: Moved to ...
+       * include/grub/script_sh.h: ... Moved here.
+       * normal/execute.c: Moved to ...
+       * script/sh/execute.c: ... Moved here.
+       * normal/function.c: Moved to ...
+       * script/sh/function.c: ... Moved here.
+       * normal/lexer.c: Moved to ...
+       * script/sh/lexer.c: ... Moved here.
+       * normal/parser.y: Moved to ...
+       * script/sh/parser.y: ... Moved here.
+       * normal/script.c: Moved to ...
+       * script/sh/script.c: ... Moved here.
+
+       * normal/main.c: Remove <grub/rescue.h> and <grub/script.h>, include
+       <grub/reader.h>.
+       (grub_exit_env): Removed.
+       (fs_module_list): Moved to normal/autofs.c.
+       (grub_file_getline): Don't handle comment here.
+       (free_menu): Skip removed field entry->commands.
+       (grub_normal_menu_addentry): Removed as grub_menu_entry, removed
+       script parameter.
+       (read_config_file): Removed nested parameter, change getline function.
+       (grub_enter_normal_mode): Removed.
+       (grub_dyncmd_dispatcher): Moved to normal/dyncmd.c.
+       (read_command_list): Likewise.
+       (autoload_fs_module): Moved to normal/autofs.c.
+       (read_fs_list): Likewise.
+       (reader_nested): New variable.
+       (grub_normal_execute): Run parser.sh to switch to sh parser.
+       (grub_cmd_rescue): Removed.
+       (cmd_normal): Removed.
+       (grub_cmd_normal): Unregister itself at the beginning. Don't register
+       rescue command.
+       (grub_cmdline_run): New function.
+       (grub_normal_reader_init): Likewise.
+       (grub_normal_read_line): Likewise.
+       (grub_env_write_pager): Likewise.
+       (cmdline): New variable.
+       (grub_normal_reader): Likewise.
+       (GRUB_MOD_INIT): Register normal reader and set as current, register
+       pager hook, register normal command with grub_register_command_prio,
+       so that it won't show up in command.lst.
+       (GRUB_MOD_FINI): Unregister normal reader, unhook pager, clear
+       grub_fs_autoload_hook.
+
+       * normal/menu.c: Remove <grub/script.h>, add <grub/command.h>.
+       (grub_menu_execute_entry): Replace grub_script_execute with
+       grub_parser_execute, change parameter to grub_command_execute.
+
+       * normal/menu_text.c: Remove <grub/script.h>.
+
+       * normal/menu_entry.c: Remove <grub/script.h>, add <grub/command.h>
+       and <grub/parser.h>.
+       (run): Change editor_getline to use new parser interface. Change
+       parameter to grub_command_execute.
+
+       * kern/main.c: Remove <grub/rescue.h>, include <grub/command.h>,
+       <grub/reader.h> and <grub/parser.h>.
+       (grub_load_normal_mode): Execute normal command.
+       (grub_main): Call grub_register_core_commands,
+       grub_register_rescue_parser and grub_register_rescue_reader, use
+       grub_reader_loop to enter input loop.
+
+       * kern/parser.c (grub_parser_spli_cmdline): Change type of getline
+       parameter.
+       (grub_parser_class): New variable.
+       (grub_parser_execute): New function.
+
+       * loader/i386/multiboot.c: Remove <grub/rescue.h>.
+       * loader/multiboot2.c: Likewise.
+       * loader/sparc64/ieee1275/linux.c: Likewise.
+
+       * util/grub-emu.c (read_command_list): New dummy function.
+
 2009-05-02  Robert Millan  <address@hidden>
 
        * util/deviceiter.c (grub_util_iterate_devices): Increase max drive

Modified: trunk/grub2/conf/common.rmk
===================================================================
--- trunk/grub2/conf/common.rmk 2009-05-02 16:55:35 UTC (rev 2157)
+++ trunk/grub2/conf/common.rmk 2009-05-02 19:49:34 UTC (rev 2158)
@@ -56,8 +56,8 @@
 endif
 
 # For the parser.
-grub_script.tab.c grub_script.tab.h: normal/parser.y
-       $(YACC) -d -p grub_script_yy -b grub_script $(srcdir)/normal/parser.y
+grub_script.tab.c grub_script.tab.h: script/sh/parser.y
+       $(YACC) -d -p grub_script_yy -b grub_script $(srcdir)/script/sh/parser.y
 DISTCLEANFILES += grub_script.tab.c grub_script.tab.h
 
 # For grub-emu.
@@ -343,7 +343,7 @@
        loopback.mod fs_uuid.mod configfile.mod echo.mod        \
        terminfo.mod test.mod blocklist.mod hexdump.mod         \
        read.mod sleep.mod loadenv.mod crc.mod parttool.mod     \
-       pcpart.mod memrw.mod boot.mod
+       pcpart.mod memrw.mod boot.mod normal.mod sh.mod
 
 # For boot.mod.
 boot_mod_SOURCES = commands/boot.c
@@ -470,6 +470,21 @@
 memrw_mod_CFLAGS = $(COMMON_CFLAGS)
 memrw_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
+# For normal.mod.
+normal_mod_SOURCES = normal/main.c normal/cmdline.c normal/dyncmd.c \
+       normal/autofs.c normal/handler.c \
+       normal/color.c normal/completion.c normal/datetime.c normal/menu.c \
+       normal/menu_entry.c normal/menu_text.c normal/menu_viewer.c \
+       normal/misc.c
+normal_mod_CFLAGS = $(COMMON_CFLAGS)
+normal_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For sh.mod.
+sh_mod_SOURCES = script/sh/main.c script/sh/script.c script/sh/execute.c \
+       script/sh/function.c script/sh/lexer.c grub_script.tab.c
+sh_mod_CFLAGS = $(COMMON_CFLAGS)
+sh_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
 # Common Video Subsystem specific modules.
 pkglib_MODULES += video.mod videotest.mod bitmap.mod tga.mod jpeg.mod  \
        png.mod font.mod gfxterm.mod

Modified: trunk/grub2/conf/i386-coreboot.rmk
===================================================================
--- trunk/grub2/conf/i386-coreboot.rmk  2009-05-02 16:55:35 UTC (rev 2157)
+++ trunk/grub2/conf/i386-coreboot.rmk  2009-05-02 19:49:34 UTC (rev 2158)
@@ -5,7 +5,7 @@
 COMMON_LDFLAGS = -m32 -nostdlib
 
 # Used by various components.  These rules need to precede them.
-normal/lexer.c_DEPENDENCIES = grub_script.tab.h
+script/sh/lexer.c_DEPENDENCIES = grub_script.tab.h
 
 # Images.
 pkglib_PROGRAMS = kernel.elf
@@ -16,7 +16,8 @@
        kern/i386/multiboot_mmap.c \
        kern/main.c kern/device.c \
        kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
-       kern/misc.c kern/mm.c kern/rescue.c kern/term.c \
+       kern/misc.c kern/mm.c kern/reader.c kern/term.c \
+       kern/rescue_parser.c kern/rescue_reader.c \
        kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
        kern/i386/dl.c kern/parser.c kern/partition.c \
        kern/i386/tsc.c kern/i386/pit.c \
@@ -28,7 +29,7 @@
        symlist.c
 kernel_elf_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
        env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
-       partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \
+       partition.h pc_partition.h reader.h symbol.h term.h time.h types.h \
        machine/boot.h machine/console.h machine/init.h \
        machine/memory.h machine/loader.h list.h handler.h command.h
 kernel_elf_CFLAGS = $(COMMON_CFLAGS)
@@ -100,7 +101,7 @@
 grub_install_SOURCES = util/i386/pc/grub-install.in
 
 # Modules.
-pkglib_MODULES = linux.mod normal.mod multiboot.mod    \
+pkglib_MODULES = linux.mod multiboot.mod               \
        aout.mod play.mod serial.mod ata.mod            \
        memdisk.mod pci.mod lspci.mod reboot.mod        \
        halt.mod datetime.mod date.mod datehook.mod     \
@@ -111,27 +112,6 @@
 linux_mod_CFLAGS = $(COMMON_CFLAGS)
 linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
-#
-# Only arch dependant part of normal.mod will be here. Common part for
-# all architecures of normal.mod is at start and should be kept at sync
-# with other makefiles.
-# 
-# Please put arch dependant part of normal.mod at the end of list to
-# keep it simpler to update to different architectures.
-#
-normal_mod_SOURCES = normal/cmdline.c normal/command.c normal/handler.c        
\
-       normal/completion.c normal/datetime.c normal/execute.c          \
-       normal/function.c normal/lexer.c normal/main.c normal/menu.c    \
-       normal/menu_text.c                                              \
-       normal/color.c                                                  \
-       normal/menu_viewer.c normal/menu_entry.c                        \
-       normal/misc.c grub_script.tab.c                                 \
-       normal/script.c                                                 \
-       normal/i386/setjmp.S
-normal_mod_CFLAGS = $(COMMON_CFLAGS)
-normal_mod_ASFLAGS = $(COMMON_ASFLAGS)
-normal_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
 # For reboot.mod.
 reboot_mod_SOURCES = commands/reboot.c kern/i386/reboot.c
 reboot_mod_CFLAGS = $(COMMON_CFLAGS)

Modified: trunk/grub2/conf/i386-efi.rmk
===================================================================
--- trunk/grub2/conf/i386-efi.rmk       2009-05-02 16:55:35 UTC (rev 2157)
+++ trunk/grub2/conf/i386-efi.rmk       2009-05-02 19:49:34 UTC (rev 2158)
@@ -5,7 +5,7 @@
 COMMON_LDFLAGS = -melf_i386 -nostdlib
 
 # Used by various components.  These rules need to precede them.
-normal/lexer.c_DEPENDENCIES = grub_script.tab.h
+script/sh/lexer.c_DEPENDENCIES = grub_script.tab.h
 
 # Utilities.
 bin_UTILITIES = grub-mkimage
@@ -80,7 +80,7 @@
 grub_install_SOURCES = util/i386/efi/grub-install.in
 
 # Modules.
-pkglib_MODULES = kernel.mod normal.mod chain.mod appleldr.mod \
+pkglib_MODULES = kernel.mod chain.mod appleldr.mod \
        linux.mod halt.mod reboot.mod pci.mod lspci.mod \
        datetime.mod date.mod datehook.mod loadbios.mod fixvideo.mod
 
@@ -88,7 +88,8 @@
 kernel_mod_EXPORTS = no
 kernel_mod_SOURCES = kern/i386/efi/startup.S kern/main.c kern/device.c \
        kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
-       kern/misc.c kern/mm.c kern/rescue.c kern/term.c \
+       kern/misc.c kern/mm.c kern/reader.c kern/term.c \
+       kern/rescue_parser.c kern/rescue_reader.c \
        kern/i386/dl.c kern/i386/efi/init.c kern/parser.c kern/partition.c \
        kern/env.c symlist.c kern/efi/efi.c kern/efi/init.c kern/efi/mm.c \
        term/efi/console.c disk/efi/efidisk.c \
@@ -98,7 +99,7 @@
        kern/generic/millisleep.c
 kernel_mod_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
        env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
-       partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \
+       partition.h pc_partition.h reader.h symbol.h term.h time.h types.h \
        efi/efi.h efi/time.h efi/disk.h list.h handler.h command.h
 kernel_mod_CFLAGS = $(COMMON_CFLAGS)
 kernel_mod_ASFLAGS = $(COMMON_ASFLAGS)
@@ -114,27 +115,6 @@
 kernel_syms.lst: $(addprefix include/grub/,$(kernel_mod_HEADERS)) config.h 
genkernsyms.sh
        /bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
 
-#
-# Only arch dependant part of normal.mod will be here. Common part for
-# all architecures of normal.mod is at start and should be kept at sync
-# with other makefiles.
-# 
-# Please put arch dependant part of normal.mod at the end of list to
-# keep it simpler to update to different architectures.
-#
-normal_mod_SOURCES = normal/cmdline.c normal/command.c normal/handler.c        
\
-       normal/completion.c normal/datetime.c normal/execute.c          \
-       normal/function.c normal/lexer.c normal/main.c normal/menu.c    \
-       normal/menu_text.c                                              \
-       normal/color.c                                                  \
-       normal/menu_viewer.c normal/menu_entry.c                        \
-       normal/misc.c grub_script.tab.c                                 \
-       normal/script.c                                                 \
-       normal/i386/setjmp.S
-normal_mod_CFLAGS = $(COMMON_CFLAGS)
-normal_mod_ASFLAGS = $(COMMON_ASFLAGS)
-normal_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
 # For chain.mod.
 chain_mod_SOURCES = loader/efi/chainloader.c
 chain_mod_CFLAGS = $(COMMON_CFLAGS)

Modified: trunk/grub2/conf/i386-ieee1275.rmk
===================================================================
--- trunk/grub2/conf/i386-ieee1275.rmk  2009-05-02 16:55:35 UTC (rev 2157)
+++ trunk/grub2/conf/i386-ieee1275.rmk  2009-05-02 19:49:34 UTC (rev 2158)
@@ -5,7 +5,7 @@
 COMMON_LDFLAGS = -nostdlib -static -lgcc
 
 # Used by various components.  These rules need to precede them.
-normal/lexer.c_DEPENDENCIES = grub_script.tab.h
+script/sh/lexer.c_DEPENDENCIES = grub_script.tab.h
 
 # Images.
 pkglib_PROGRAMS = kernel.elf
@@ -17,7 +17,8 @@
        kern/ieee1275/cmain.c kern/ieee1275/openfw.c \
        kern/main.c kern/device.c \
        kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
-       kern/misc.c kern/mm.c kern/rescue.c kern/term.c \
+       kern/misc.c kern/mm.c kern/reader.c kern/term.c \
+       kern/rescue_parser.c kern/rescue_reader.c \
        kern/i386/dl.c kern/parser.c kern/partition.c \
        kern/env.c \
        kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
@@ -28,7 +29,7 @@
        symlist.c
 kernel_elf_HEADERS = cache.h device.h disk.h dl.h elf.h elfload.h \
        env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
-       partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \
+       partition.h pc_partition.h reader.h symbol.h term.h time.h types.h \
        ieee1275/ieee1275.h machine/kernel.h machine/loader.h machine/memory.h \
        list.h handler.h command.h
 kernel_elf_CFLAGS = $(COMMON_CFLAGS)
@@ -101,32 +102,11 @@
 grub_install_SOURCES = util/ieee1275/grub-install.in
 
 # Modules.
-pkglib_MODULES = normal.mod halt.mod reboot.mod suspend.mod            \
-       multiboot.mod aout.mod serial.mod linux.mod     \
+pkglib_MODULES = halt.mod reboot.mod suspend.mod               \
+       multiboot.mod aout.mod serial.mod linux.mod             \
        nand.mod memdisk.mod pci.mod lspci.mod datetime.mod     \
        date.mod datehook.mod lsmmap.mod
 
-#
-# Only arch dependant part of normal.mod will be here. Common part for
-# all architecures of normal.mod is at start and should be kept at sync
-# with other makefiles.
-# 
-# Please put arch dependant part of normal.mod at the end of list to
-# keep it simpler to update to different architectures.
-#
-normal_mod_SOURCES = normal/cmdline.c normal/command.c normal/handler.c        
\
-       normal/completion.c normal/datetime.c normal/execute.c          \
-       normal/function.c normal/lexer.c normal/main.c normal/menu.c    \
-       normal/menu_text.c                                              \
-       normal/color.c                                                  \
-       normal/menu_viewer.c normal/menu_entry.c                        \
-       normal/misc.c grub_script.tab.c                                 \
-       normal/script.c                                                 \
-       normal/i386/setjmp.S
-normal_mod_CFLAGS = $(COMMON_CFLAGS)
-normal_mod_ASFLAGS = $(COMMON_ASFLAGS)
-normal_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
 # For multiboot.mod.
 multiboot_mod_SOURCES = loader/ieee1275/multiboot2.c \
                        loader/i386/multiboot_helper.S \

Modified: trunk/grub2/conf/i386-pc.rmk
===================================================================
--- trunk/grub2/conf/i386-pc.rmk        2009-05-02 16:55:35 UTC (rev 2157)
+++ trunk/grub2/conf/i386-pc.rmk        2009-05-02 19:49:34 UTC (rev 2158)
@@ -7,7 +7,7 @@
 COMMON_LDFLAGS = -m32 -nostdlib
 
 # Used by various components.  These rules need to precede them.
-normal/lexer.c_DEPENDENCIES = grub_script.tab.h
+script/sh/lexer.c_DEPENDENCIES = grub_script.tab.h
 
 # Images.
 pkglib_IMAGES = boot.img diskboot.img kernel.img pxeboot.img lnxboot.img \
@@ -46,7 +46,8 @@
 # For kernel.img.
 kernel_img_SOURCES = kern/i386/pc/startup.S kern/main.c kern/device.c \
        kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
-       kern/misc.c kern/mm.c kern/rescue.c kern/term.c \
+       kern/misc.c kern/mm.c kern/reader.c kern/term.c \
+       kern/rescue_parser.c kern/rescue_reader.c \
        kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
        kern/i386/dl.c kern/i386/pc/init.c kern/i386/pc/mmap.c \
        kern/parser.c kern/partition.c \
@@ -58,7 +59,7 @@
        symlist.c
 kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
        env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
-       partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \
+       partition.h pc_partition.h reader.h symbol.h term.h time.h types.h \
        machine/biosdisk.h machine/boot.h machine/console.h machine/init.h \
        machine/memory.h machine/loader.h machine/vga.h machine/vbe.h \
        machine/kernel.h machine/pxe.h list.h handler.h command.h
@@ -131,16 +132,17 @@
        io/gzio.c                                                       \
        kern/device.c kern/disk.c kern/dl.c kern/elf.c kern/env.c       \
        kern/err.c kern/list.c kern/handler.c                           \
-       kern/command.c kern/corecmd.c commands/extcmd.c                 \
-       normal/execute.c kern/file.c kern/fs.c normal/lexer.c           \
-       commands/boot.c kern/main.c kern/misc.c kern/parser.c           \
-       grub_script.tab.c kern/partition.c kern/rescue.c kern/term.c    \
-       lib/arg.c normal/cmdline.c normal/command.c normal/datetime.c   \
-       normal/function.c normal/handler.c      \
+       kern/command.c kern/corecmd.c commands/extcmd.c kern/file.c     \
+       kern/fs.c commands/boot.c kern/main.c kern/misc.c kern/parser.c \
+       kern/partition.c kern/reader.c kern/term.c                      \
+       kern/rescue_reader.c kern/rescue_parser.c                       \
+       lib/arg.c normal/cmdline.c normal/datetime.c normal/misc.c      \
+       normal/handler.c normal/autofs.c                                \
        normal/completion.c normal/main.c normal/color.c                \
        normal/menu.c normal/menu_entry.c normal/menu_viewer.c          \
        normal/menu_text.c                                              \
-       normal/misc.c normal/script.c                                   \
+       script/sh/main.c script/sh/execute.c script/sh/function.c       \
+       script/sh/lexer.c script/sh/script.c grub_script.tab.c          \
        partmap/amiga.c partmap/apple.c partmap/pc.c partmap/sun.c      \
        partmap/acorn.c partmap/gpt.c                                   \
        \
@@ -176,7 +178,7 @@
 # For grub-mkrescue.
 grub_mkrescue_SOURCES = util/i386/pc/grub-mkrescue.in
 
-pkglib_MODULES = biosdisk.mod chain.mod normal.mod \
+pkglib_MODULES = biosdisk.mod chain.mod \
        multiboot.mod reboot.mod halt.mod       \
        vbe.mod vbetest.mod vbeinfo.mod play.mod serial.mod     \
        ata.mod vga.mod memdisk.mod pci.mod lspci.mod   \
@@ -204,27 +206,6 @@
 linux_mod_CFLAGS = $(COMMON_CFLAGS)
 linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
-#
-# Only arch dependant part of normal.mod will be here. Common part for
-# all architecures of normal.mod is at start and should be kept at sync
-# with other makefiles.
-# 
-# Please put arch dependant part of normal.mod at the end of list to
-# keep it simpler to update to different architectures.
-#
-normal_mod_SOURCES = normal/cmdline.c normal/command.c normal/datetime.c \
-       normal/completion.c normal/execute.c normal/handler.c           \
-       normal/function.c normal/lexer.c normal/main.c normal/menu.c    \
-       normal/menu_text.c                                              \
-       normal/color.c                                                  \
-       normal/menu_viewer.c normal/menu_entry.c                        \
-       normal/misc.c grub_script.tab.c                                 \
-       normal/script.c                                                 \
-       normal/i386/setjmp.S
-normal_mod_CFLAGS = $(COMMON_CFLAGS)
-normal_mod_ASFLAGS = $(COMMON_ASFLAGS)
-normal_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
 # For reboot.mod.
 reboot_mod_SOURCES = commands/reboot.c
 reboot_mod_CFLAGS = $(COMMON_CFLAGS)

Modified: trunk/grub2/conf/powerpc-ieee1275.rmk
===================================================================
--- trunk/grub2/conf/powerpc-ieee1275.rmk       2009-05-02 16:55:35 UTC (rev 
2157)
+++ trunk/grub2/conf/powerpc-ieee1275.rmk       2009-05-02 19:49:34 UTC (rev 
2158)
@@ -6,7 +6,7 @@
 COMMON_LDFLAGS += -nostdlib
 
 # Used by various components.  These rules need to precede them.
-normal/lexer.c_DEPENDENCIES = grub_script.tab.h
+script/sh/lexer.c_DEPENDENCIES = grub_script.tab.h
 
 # Images.
 
@@ -14,7 +14,7 @@
 DEFSYMFILES += kernel_syms.lst
 
 kernel_elf_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
-       env.h err.h file.h fs.h kernel.h misc.h mm.h net.h parser.h rescue.h \
+       env.h err.h file.h fs.h kernel.h misc.h mm.h net.h parser.h reader.h \
        symbol.h term.h time.h types.h powerpc/libgcc.h loader.h partition.h \
        pc_partition.h ieee1275/ieee1275.h machine/kernel.h handler.h list.h \
        command.h
@@ -82,7 +82,8 @@
 kernel_elf_SOURCES = kern/powerpc/ieee1275/startup.S kern/ieee1275/cmain.c \
        kern/ieee1275/ieee1275.c kern/main.c kern/device.c              \
        kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c          \
-       kern/misc.c kern/mm.c kern/rescue.c kern/term.c         \
+       kern/misc.c kern/mm.c kern/reader.c kern/term.c         \
+       kern/rescue_parser.c kern/rescue_reader.c \
        kern/list.c kern/handler.c kern/command.c kern/corecmd.c        \
        kern/ieee1275/init.c                                            \
        kern/ieee1275/mmap.c                                            \
@@ -109,7 +110,6 @@
 # Modules.
 pkglib_MODULES = halt.mod \
        linux.mod \
-       normal.mod \
        reboot.mod \
        suspend.mod \
         multiboot.mod \
@@ -121,27 +121,6 @@
 linux_mod_CFLAGS = $(COMMON_CFLAGS)
 linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
-#
-# Only arch dependant part of normal.mod will be here. Common part for
-# all architecures of normal.mod is at start and should be kept at sync
-# with other makefiles.
-# 
-# Please put arch dependant part of normal.mod at the end of list to
-# keep it simpler to update to different architectures.
-#
-normal_mod_SOURCES = normal/cmdline.c normal/command.c normal/datetime.c \
-       normal/completion.c normal/execute.c normal/handler.c           \
-       normal/function.c normal/lexer.c normal/main.c normal/menu.c    \
-       normal/menu_text.c                                              \
-       normal/color.c                                                  \
-       normal/menu_viewer.c normal/menu_entry.c                        \
-       normal/misc.c grub_script.tab.c                                 \
-       normal/script.c                                                 \
-       normal/powerpc/setjmp.S
-normal_mod_CFLAGS = $(COMMON_CFLAGS)
-normal_mod_ASFLAGS = $(COMMON_ASFLAGS)
-normal_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
 # For suspend.mod
 suspend_mod_SOURCES = commands/ieee1275/suspend.c
 suspend_mod_CFLAGS = $(COMMON_CFLAGS)

Modified: trunk/grub2/conf/sparc64-ieee1275.rmk
===================================================================
--- trunk/grub2/conf/sparc64-ieee1275.rmk       2009-05-02 16:55:35 UTC (rev 
2157)
+++ trunk/grub2/conf/sparc64-ieee1275.rmk       2009-05-02 19:49:34 UTC (rev 
2158)
@@ -6,7 +6,7 @@
 COMMON_LDFLAGS = -melf64_sparc -nostdlib -mno-relax
 
 # Used by various components.  These rules need to precede them.
-normal/lexer.c_DEPENDENCIES = grub_script.tab.h
+script/sh/lexer.c_DEPENDENCIES = grub_script.tab.h
 
 # Images.
 pkglib_IMAGES = boot.img diskboot.img kernel.img
@@ -28,14 +28,15 @@
 
 kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
        env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
-       partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \
+       partition.h pc_partition.h reader.h symbol.h term.h time.h types.h \
        list.h handler.h command.h \
        sparc64/libgcc.h ieee1275/ieee1275.h machine/kernel.h \
        sparc64/ieee1275/ieee1275.h
 kernel_img_SOURCES = kern/sparc64/ieee1275/crt0.S kern/ieee1275/cmain.c        
\
        kern/ieee1275/ieee1275.c kern/main.c kern/device.c              \
        kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c          \
-       kern/misc.c kern/mm.c kern/rescue.c kern/term.c                 \
+       kern/misc.c kern/mm.c kern/reader.c kern/term.c                 \
+       kern/rescue_parser.c kern/rescue_reader.c \
        kern/list.c kern/handler.c kern/command.c kern/corecmd.c        \
        kern/sparc64/ieee1275/ieee1275.c                                \
        kern/sparc64/ieee1275/init.c                                    \
@@ -142,7 +143,6 @@
 # Modules.
 pkglib_MODULES = halt.mod \
        linux.mod \
-       normal.mod \
        reboot.mod \
        memdisk.mod \
        lsmmap.mod
@@ -152,27 +152,6 @@
 linux_mod_CFLAGS = $(COMMON_CFLAGS)
 linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
-#
-# Only arch dependant part of normal.mod will be here. Common part for
-# all architecures of normal.mod is at start and should be kept at sync
-# with other makefiles.
-# 
-# Please put arch dependant part of normal.mod at the end of list to
-# keep it simpler to update to different architectures.
-#
-normal_mod_SOURCES = lib/arg.c normal/cmdline.c normal/command.c       \
-       normal/datetime.c normal/completion.c normal/execute.c          \
-       normal/function.c normal/lexer.c normal/main.c normal/menu.c    \
-       normal/handler.c normal/menu_text.c                             \
-       normal/color.c                                                  \
-       normal/menu_viewer.c normal/menu_entry.c                        \
-       normal/misc.c grub_script.tab.c                                 \
-       normal/script.c                                                 \
-       normal/sparc64/setjmp.S
-normal_mod_CFLAGS = $(COMMON_CFLAGS)
-normal_mod_ASFLAGS = $(COMMON_ASFLAGS)
-normal_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
 # For reboot.mod.
 reboot_mod_SOURCES = commands/reboot.c
 reboot_mod_CFLAGS = $(COMMON_CFLAGS)

Modified: trunk/grub2/conf/x86_64-efi.rmk
===================================================================
--- trunk/grub2/conf/x86_64-efi.rmk     2009-05-02 16:55:35 UTC (rev 2157)
+++ trunk/grub2/conf/x86_64-efi.rmk     2009-05-02 19:49:34 UTC (rev 2158)
@@ -5,10 +5,7 @@
 COMMON_LDFLAGS = -melf_x86_64 -nostdlib
 
 # Used by various components.  These rules need to precede them.
-normal/execute.c_DEPENDENCIES = grub_script.tab.h
-normal/command.c_DEPENDENCIES = grub_script.tab.h
-normal/function.c_DEPENDENCIES = grub_script.tab.h
-normal/lexer.c_DEPENDENCIES = grub_script.tab.h
+script/sh/lexer.c_DEPENDENCIES = grub_script.tab.h
 
 # Utilities.
 bin_UTILITIES = grub-mkimage
@@ -81,7 +78,7 @@
 grub_install_SOURCES = util/i386/efi/grub-install.in
 
 # Modules.
-pkglib_MODULES = kernel.mod normal.mod chain.mod appleldr.mod \
+pkglib_MODULES = kernel.mod chain.mod appleldr.mod \
        halt.mod reboot.mod linux.mod pci.mod lspci.mod \
        datetime.mod date.mod datehook.mod loadbios.mod fixvideo.mod
 
@@ -90,7 +87,8 @@
 kernel_mod_SOURCES = kern/x86_64/efi/startup.S kern/x86_64/efi/callwrap.S \
        kern/main.c kern/device.c \
        kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
-       kern/misc.c kern/mm.c kern/rescue.c kern/term.c \
+       kern/misc.c kern/mm.c kern/reader.c kern/term.c \
+       kern/rescue_parser.c kern/rescue_reader.c \
        kern/x86_64/dl.c kern/i386/efi/init.c kern/parser.c kern/partition.c \
        kern/env.c symlist.c kern/efi/efi.c kern/efi/init.c kern/efi/mm.c \
        kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
@@ -99,7 +97,7 @@
        term/efi/console.c disk/efi/efidisk.c
 kernel_mod_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
        env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
-       partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \
+       partition.h pc_partition.h reader.h symbol.h term.h time.h types.h \
        efi/efi.h efi/time.h efi/disk.h machine/loader.h list.h handler.h \
        command.h
 kernel_mod_CFLAGS = $(COMMON_CFLAGS)
@@ -116,27 +114,6 @@
 kernel_syms.lst: $(addprefix include/grub/,$(kernel_mod_HEADERS)) config.h 
genkernsyms.sh
        /bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1)
 
-#
-# Only arch dependant part of normal.mod will be here. Common part for
-# all architecures of normal.mod is at start and should be kept at sync
-# with other makefiles.
-# 
-# Please put arch dependant part of normal.mod at the end of list to
-# keep it simpler to update to different architectures.
-#
-normal_mod_SOURCES = normal/cmdline.c normal/command.c normal/handler.c        
\
-       normal/completion.c normal/datetime.c normal/execute.c          \
-       normal/function.c normal/lexer.c normal/main.c normal/menu.c    \
-       normal/menu_text.c                                              \
-       normal/color.c                                                  \
-       normal/menu_viewer.c normal/menu_entry.c                        \
-       normal/misc.c grub_script.tab.c                                 \
-       normal/script.c                                                 \
-       normal/x86_64/setjmp.S
-normal_mod_CFLAGS = $(COMMON_CFLAGS)
-normal_mod_ASFLAGS = $(COMMON_ASFLAGS)
-normal_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
 # For chain.mod.
 chain_mod_SOURCES = loader/efi/chainloader.c
 chain_mod_CFLAGS = $(COMMON_CFLAGS)
@@ -197,5 +174,4 @@
 fixvideo_mod_CFLAGS = $(COMMON_CFLAGS)
 fixvideo_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
-include $(srcdir)/conf/i386.mk
 include $(srcdir)/conf/common.mk

Modified: trunk/grub2/include/grub/command.h
===================================================================
--- trunk/grub2/include/grub/command.h  2009-05-02 16:55:35 UTC (rev 2157)
+++ trunk/grub2/include/grub/command.h  2009-05-02 19:49:34 UTC (rev 2158)
@@ -106,6 +106,15 @@
   return grub_named_list_find (GRUB_AS_NAMED_LIST (grub_command_list), name);
 }
 
+static inline grub_err_t
+grub_command_execute (const char *name, int argc, char **argv)
+{
+  grub_command_t cmd;
+
+  cmd = grub_command_find (name);
+  return (cmd) ? cmd->func (cmd, argc, argv) : GRUB_ERR_FILE_NOT_FOUND;
+}
+
 static inline int
 grub_command_iterate (int (*func) (grub_command_t))
 {

Modified: trunk/grub2/include/grub/menu.h
===================================================================
--- trunk/grub2/include/grub/menu.h     2009-05-02 16:55:35 UTC (rev 2157)
+++ trunk/grub2/include/grub/menu.h     2009-05-02 19:49:34 UTC (rev 2158)
@@ -38,9 +38,6 @@
      E.classes->next is the first class if it is not NULL.  */
   struct grub_menu_entry_class *classes;
 
-  /* The commands associated with this menu entry.  */
-  struct grub_script *commands;
-
   /* The sourcecode of the menu entry, used by the editor.  */
   const char *sourcecode;
 

Modified: trunk/grub2/include/grub/normal.h
===================================================================
--- trunk/grub2/include/grub/normal.h   2009-05-02 16:55:35 UTC (rev 2157)
+++ trunk/grub2/include/grub/normal.h   2009-05-02 19:49:34 UTC (rev 2158)
@@ -20,7 +20,6 @@
 #ifndef GRUB_NORMAL_HEADER
 #define GRUB_NORMAL_HEADER     1
 
-#include <grub/setjmp.h>
 #include <grub/symbol.h>
 #include <grub/err.h>
 #include <grub/env.h>
@@ -42,17 +41,6 @@
   };
 typedef enum grub_completion_type grub_completion_type_t;
 
-/* This is used to store the names of filesystem modules for auto-loading.  */
-struct grub_fs_module_list
-{
-  char *name;
-  struct grub_fs_module_list *next;
-};
-typedef struct grub_fs_module_list *grub_fs_module_list_t;
-
-/* To exit from the normal mode.  */
-extern grub_jmp_buf grub_exit_env;
-
 extern struct grub_menu_viewer grub_normal_text_menu_viewer;
 
 /* Callback structure menu viewers can use to provide user feedback when
@@ -86,19 +74,14 @@
 grub_menu_entry_t grub_menu_get_entry (grub_menu_t menu, int no);
 int grub_menu_get_timeout (void);
 void grub_menu_set_timeout (int timeout);
-void grub_cmdline_run (int nested);
 int grub_cmdline_get (const char *prompt, char cmdline[], unsigned max_len,
                      int echo_char, int readline);
 grub_err_t grub_set_history (int newsize);
-int grub_command_execute (char *cmdline, int interactive);
 void grub_normal_init_page (void);
 void grub_menu_init_page (int nested, int edit);
 char *grub_normal_do_completion (char *buf, int *restore,
                                 void (*hook) (const char *item, 
grub_completion_type_t type, int count));
 grub_err_t grub_normal_print_device_info (const char *name);
-grub_err_t grub_normal_menu_addentry (int argc, const char **args,
-                                     struct grub_script *script,
-                                     const char *sourcecode);
 char *grub_env_write_color_normal (struct grub_env_var *var, const char *val);
 char *grub_env_write_color_highlight (struct grub_env_var *var, const char 
*val);
 void grub_parse_color_name_pair (grub_uint8_t *ret, const char *name);
@@ -107,6 +90,11 @@
 char *grub_file_getline (grub_file_t file);
 void read_handler_list (void);
 void free_handler_list (void);
+void read_command_list (void);
+void read_fs_list (void);
+void grub_cmdline_run (int nested);
+grub_err_t grub_menu_addentry (int argc, const char **args,
+                              const char *sourcecode);
 
 #ifdef GRUB_UTIL
 void grub_normal_init (void);

Modified: trunk/grub2/include/grub/parser.h
===================================================================
--- trunk/grub2/include/grub/parser.h   2009-05-02 16:55:35 UTC (rev 2157)
+++ trunk/grub2/include/grub/parser.h   2009-05-02 19:49:34 UTC (rev 2158)
@@ -1,7 +1,7 @@
 /* parser.h - prototypes for the command line parser.  */
 /*
  *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2007  Free Software Foundation, Inc.
+ *  Copyright (C) 2005,2007,2009  Free Software Foundation, Inc.
  *
  *  GRUB is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -22,6 +22,7 @@
 
 #include <grub/types.h>
 #include <grub/err.h>
+#include <grub/reader.h>
 
 /* All the states for the command line.  */
 typedef enum
@@ -61,7 +62,56 @@
 
 grub_err_t
 EXPORT_FUNC (grub_parser_split_cmdline) (const char *cmdline,
-                                        grub_err_t (*getline) (char **),
+                                        grub_reader_getline_t getline,
                                         int *argc, char ***argv);
 
+struct grub_parser
+{
+  /* The next parser.  */
+  struct grub_parser *next;
+
+  /* The parser name.  */
+  const char *name;
+
+  /* Initialize the parser.  */
+  grub_err_t (*init) (void);
+
+  /* Clean up the parser.  */
+  grub_err_t (*fini) (void);
+
+  grub_err_t (*parse_line) (char *line, grub_reader_getline_t getline);
+};
+typedef struct grub_parser *grub_parser_t;
+
+extern struct grub_handler_class EXPORT_VAR(grub_parser_class);
+grub_err_t EXPORT_FUNC(grub_parser_execute) (char *source);
+
+static inline void
+grub_parser_register (const char *name __attribute__ ((unused)),
+                     grub_parser_t parser)
+{
+  grub_handler_register (&grub_parser_class, GRUB_AS_HANDLER (parser));
+}
+
+static inline void
+grub_parser_unregister (grub_parser_t parser)
+{
+  grub_handler_unregister (&grub_parser_class, GRUB_AS_HANDLER (parser));
+}
+
+static inline grub_parser_t
+grub_parser_get_current (void)
+{
+  return (grub_parser_t) grub_parser_class.cur_handler;
+}
+
+static inline grub_err_t
+grub_parser_set_current (grub_parser_t parser)
+{
+  return grub_handler_set_current (&grub_parser_class,
+                                  GRUB_AS_HANDLER (parser));
+}
+
+void grub_register_rescue_parser (void);
+
 #endif /* ! GRUB_PARSER_HEADER */

Added: trunk/grub2/include/grub/reader.h
===================================================================
--- trunk/grub2/include/grub/reader.h                           (rev 0)
+++ trunk/grub2/include/grub/reader.h   2009-05-02 19:49:34 UTC (rev 2158)
@@ -0,0 +1,79 @@
+/* reader.h - prototypes for command line reader.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_READER_HEADER
+#define GRUB_READER_HEADER     1
+
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/handler.h>
+
+typedef grub_err_t (*grub_reader_getline_t) (char **, int);
+
+struct grub_reader
+{
+  /* The next reader.  */
+  struct grub_parser *next;
+
+  /* The reader name.  */
+  const char *name;
+
+  /* Initialize the reader.  */
+  grub_err_t (*init) (void);
+
+  /* Clean up the reader.  */
+  grub_err_t (*fini) (void);
+
+  grub_reader_getline_t read_line;
+};
+typedef struct grub_reader *grub_reader_t;
+
+extern struct grub_handler_class EXPORT_VAR(grub_reader_class);
+
+grub_err_t EXPORT_FUNC(grub_reader_loop) (grub_reader_getline_t getline);
+
+static inline void
+grub_reader_register (const char *name __attribute__ ((unused)),
+                     grub_reader_t reader)
+{
+  grub_handler_register (&grub_reader_class, GRUB_AS_HANDLER (reader));
+}
+
+static inline void
+grub_reader_unregister (grub_reader_t reader)
+{
+  grub_handler_unregister (&grub_reader_class, GRUB_AS_HANDLER (reader));
+}
+
+static inline grub_reader_t
+grub_reader_get_current (void)
+{
+  return (grub_reader_t) grub_reader_class.cur_handler;
+}
+
+static inline grub_err_t
+grub_reader_set_current (grub_reader_t reader)
+{
+  return grub_handler_set_current (&grub_reader_class,
+                                  GRUB_AS_HANDLER (reader));
+}
+
+void grub_register_rescue_reader (void);
+
+#endif /* ! GRUB_READER_HEADER */

Deleted: trunk/grub2/include/grub/rescue.h
===================================================================
--- trunk/grub2/include/grub/rescue.h   2009-05-02 16:55:35 UTC (rev 2157)
+++ trunk/grub2/include/grub/rescue.h   2009-05-02 19:49:34 UTC (rev 2158)
@@ -1,27 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_RESCUE_HEADER
-#define GRUB_RESCUE_HEADER     1
-
-#include <grub/symbol.h>
-
-/* Enter rescue mode.  */
-void grub_enter_rescue_mode (void);
-
-#endif /* ! GRUB_RESCUE_HEADER */

Deleted: trunk/grub2/include/grub/script.h
===================================================================
--- trunk/grub2/include/grub/script.h   2009-05-02 16:55:35 UTC (rev 2157)
+++ trunk/grub2/include/grub/script.h   2009-05-02 19:49:34 UTC (rev 2158)
@@ -1,287 +0,0 @@
-/* script.h  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GRUB_SCRIPT_HEADER
-#define GRUB_SCRIPT_HEADER     1
-
-#include <grub/types.h>
-#include <grub/err.h>
-#include <grub/parser.h>
-
-struct grub_script_mem;
-
-/* The generic header for each scripting command or structure.  */
-struct grub_script_cmd
-{
-  /* This function is called to execute the command.  */
-  grub_err_t (*exec) (struct grub_script_cmd *cmd);
-
-  /* The next command.  This can be used by the parent to form a chain
-     of commands.  */
-  struct grub_script_cmd *next;
-};
-
-struct grub_script
-{
-  struct grub_script_mem *mem;
-  struct grub_script_cmd *cmd;
-};
-
-typedef enum
-{
-  GRUB_SCRIPT_ARG_TYPE_STR,
-  GRUB_SCRIPT_ARG_TYPE_VAR
-} grub_script_arg_type_t;
-
-/* A part of an argument.  */
-struct grub_script_arg
-{
-  grub_script_arg_type_t type;
-
-  char *str;
-
-  /* Next argument part.  */
-  struct grub_script_arg *next;
-};
-
-/* A complete argument.  It consists of a list of one or more `struct
-   grub_script_arg's.  */
-struct grub_script_arglist
-{
-  struct grub_script_arglist *next;
-  struct grub_script_arg *arg;
-  /* Only stored in the first link.  */
-  int argcount;
-};
-
-/* A single command line.  */
-struct grub_script_cmdline
-{
-  struct grub_script_cmd cmd;
-
-  /* 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.  */
-struct grub_script_cmdblock
-{
-  struct grub_script_cmd cmd;
-
-  /* A chain of commands.  */
-  struct grub_script_cmd *cmdlist;
-};
-
-/* An if statement.  */
-struct grub_script_cmdif
-{
-  struct grub_script_cmd cmd;
-
-  /* The command used to check if the 'if' is true or false.  */
-  struct grub_script_cmd *exec_to_evaluate;
-
-  /* The code executed in case the result of 'if' was true.  */
-  struct grub_script_cmd *exec_on_true;
-
-  /* The code executed in case the result of 'if' was false.  */
-  struct grub_script_cmd *exec_on_false;
-};
-
-/* A menu entry generate statement.  */
-struct grub_script_cmd_menuentry
-{
-  struct grub_script_cmd cmd;
-
-  /* The arguments for this menu entry.  */
-  struct grub_script_arglist *arglist;
-
-  /* The sourcecode the entry will be generated from.  */
-  const char *sourcecode;
-
-  /* Options.  XXX: Not used yet.  */
-  int options;
-};
-
-/* State of the lexer as passed to the lexer.  */
-struct grub_lexer_param
-{
-  /* Set to 0 when the lexer is done.  */
-  int done;
-
-  /* State of the state machine.  */
-  grub_parser_state_t state;
-
-  /* Function used by the lexer to get a new line when more input is
-     expected, but not available.  */
-  grub_err_t (*getline) (char **);
-
-  /* A reference counter.  If this is >0 it means that the parser
-     expects more tokens and `getline' should be called to fetch more.
-     Otherwise the lexer can stop processing if the current buffer is
-     depleted.  */
-  int refs;
-
-  /* The character stream that has to be parsed.  */
-  char *script;
-  char *newscript; /* XXX */
-
-  /* While walking through the databuffer, `record' the characters to
-     this other buffer.  It can be used to edit the menu entry at a
-     later moment.  */
-
-  /* If true, recording is enabled.  */
-  int record;
-
-  /* Points to the recording.  */
-  char *recording;
-
-  /* index in the RECORDING.  */ 
-  int recordpos;
-
-  /* Size of RECORDING.  */
-  int recordlen;
-};
-
-/* State of the parser as passes to the parser.  */
-struct grub_parser_param
-{
-  /* Keep track of the memory allocated for this specific
-     function.  */
-  struct grub_script_mem *func_mem;
-
-  /* When set to 0, no errors have occured during parsing.  */
-  int err;
-
-  /* The memory that was used while parsing and scanning.  */
-  struct grub_script_mem *memused;
-
-  /* The result of the parser.  */
-  struct grub_script_cmd *parsed;
-
-  struct grub_lexer_param *lexerstate;
-};
-
-struct grub_script_arglist *
-grub_script_create_arglist (struct grub_parser_param *state);
-
-struct grub_script_arglist *
-grub_script_add_arglist (struct grub_parser_param *state,
-                        struct grub_script_arglist *list,
-                        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);
-
-struct grub_script_cmd *
-grub_script_create_cmdif (struct grub_parser_param *state,
-                         struct grub_script_cmd *exec_to_evaluate,
-                         struct grub_script_cmd *exec_on_true,
-                         struct grub_script_cmd *exec_on_false);
-
-struct grub_script_cmd *
-grub_script_create_cmdmenu (struct grub_parser_param *state,
-                           struct grub_script_arglist *arglist,
-                           char *sourcecode,
-                           int options);
-
-struct grub_script_cmd *
-grub_script_add_cmd (struct grub_parser_param *state,
-                    struct grub_script_cmdblock *cmdblock,
-                    struct grub_script_cmd *cmd);
-struct grub_script_arg *
-grub_script_arg_add (struct grub_parser_param *state,
-                    struct grub_script_arg *arg,
-                    grub_script_arg_type_t type, char *str);
-
-struct grub_script *grub_script_parse (char *script,
-                                      grub_err_t (*getline) (char **));
-void grub_script_free (struct grub_script *script);
-struct grub_script *grub_script_create (struct grub_script_cmd *cmd,
-                                       struct grub_script_mem *mem);
-
-struct grub_lexer_param *grub_script_lexer_init (char *s,
-                                                grub_err_t (*getline) (char 
**));
-void grub_script_lexer_ref (struct grub_lexer_param *);
-void grub_script_lexer_deref (struct grub_lexer_param *);
-void grub_script_lexer_record_start (struct grub_lexer_param *);
-char *grub_script_lexer_record_stop (struct grub_lexer_param *);
-
-/* Functions to track allocated memory.  */
-struct grub_script_mem *grub_script_mem_record (struct grub_parser_param 
*state);
-struct grub_script_mem *grub_script_mem_record_stop (struct grub_parser_param 
*state, 
-                                                    struct grub_script_mem 
*restore);
-void *grub_script_malloc (struct grub_parser_param *state, grub_size_t size);
-
-/* Functions used by bison.  */
-union YYSTYPE;
-int grub_script_yylex (union YYSTYPE *, struct grub_parser_param *);
-int grub_script_yyparse (struct grub_parser_param *);
-void grub_script_yyerror (struct grub_parser_param *, char const *);
-
-/* Commands to execute, don't use these directly.  */
-grub_err_t grub_script_execute_cmdline (struct grub_script_cmd *cmd);
-grub_err_t grub_script_execute_cmdblock (struct grub_script_cmd *cmd);
-grub_err_t grub_script_execute_cmdif (struct grub_script_cmd *cmd);
-grub_err_t grub_script_execute_menuentry (struct grub_script_cmd *cmd);
-
-/* Execute any GRUB pre-parsed command or script.  */
-grub_err_t grub_script_execute (struct grub_script *script);
-
-/* This variable points to the parsed command.  This is used to
-   communicate with the bison code.  */
-extern struct grub_script_cmd *grub_script_parsed;
-
-
-
-/* The function description.  */
-struct grub_script_function
-{
-  /* The name.  */
-  char *name;
-
-  /* The script function.  */
-  struct grub_script *func;
-
-  /* The flags.  */
-  unsigned flags;
-
-  /* The next element.  */
-  struct grub_script_function *next;
-
-  int references;
-};
-typedef struct grub_script_function *grub_script_function_t;
-
-grub_script_function_t grub_script_function_create (char *functionname,
-                                                   struct grub_script *cmd);
-void grub_script_function_remove (const char *name);
-grub_script_function_t grub_script_function_find (char *functionname);
-int grub_script_function_iterate (int (*iterate) (grub_script_function_t));
-int grub_script_function_call (grub_script_function_t func,
-                              int argc, char **args);
-
-#endif /* ! GRUB_SCRIPT_HEADER */

Copied: trunk/grub2/include/grub/script_sh.h (from rev 2157, 
trunk/grub2/include/grub/script.h)
===================================================================
--- trunk/grub2/include/grub/script_sh.h                                (rev 0)
+++ trunk/grub2/include/grub/script_sh.h        2009-05-02 19:49:34 UTC (rev 
2158)
@@ -0,0 +1,287 @@
+/* normal_parser.h  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_NORMAL_PARSER_HEADER
+#define GRUB_NORMAL_PARSER_HEADER      1
+
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/parser.h>
+
+struct grub_script_mem;
+
+/* The generic header for each scripting command or structure.  */
+struct grub_script_cmd
+{
+  /* This function is called to execute the command.  */
+  grub_err_t (*exec) (struct grub_script_cmd *cmd);
+
+  /* The next command.  This can be used by the parent to form a chain
+     of commands.  */
+  struct grub_script_cmd *next;
+};
+
+struct grub_script
+{
+  struct grub_script_mem *mem;
+  struct grub_script_cmd *cmd;
+};
+
+typedef enum
+{
+  GRUB_SCRIPT_ARG_TYPE_STR,
+  GRUB_SCRIPT_ARG_TYPE_VAR
+} grub_script_arg_type_t;
+
+/* A part of an argument.  */
+struct grub_script_arg
+{
+  grub_script_arg_type_t type;
+
+  char *str;
+
+  /* Next argument part.  */
+  struct grub_script_arg *next;
+};
+
+/* A complete argument.  It consists of a list of one or more `struct
+   grub_script_arg's.  */
+struct grub_script_arglist
+{
+  struct grub_script_arglist *next;
+  struct grub_script_arg *arg;
+  /* Only stored in the first link.  */
+  int argcount;
+};
+
+/* A single command line.  */
+struct grub_script_cmdline
+{
+  struct grub_script_cmd cmd;
+
+  /* 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.  */
+struct grub_script_cmdblock
+{
+  struct grub_script_cmd cmd;
+
+  /* A chain of commands.  */
+  struct grub_script_cmd *cmdlist;
+};
+
+/* An if statement.  */
+struct grub_script_cmdif
+{
+  struct grub_script_cmd cmd;
+
+  /* The command used to check if the 'if' is true or false.  */
+  struct grub_script_cmd *exec_to_evaluate;
+
+  /* The code executed in case the result of 'if' was true.  */
+  struct grub_script_cmd *exec_on_true;
+
+  /* The code executed in case the result of 'if' was false.  */
+  struct grub_script_cmd *exec_on_false;
+};
+
+/* A menu entry generate statement.  */
+struct grub_script_cmd_menuentry
+{
+  struct grub_script_cmd cmd;
+
+  /* The arguments for this menu entry.  */
+  struct grub_script_arglist *arglist;
+
+  /* The sourcecode the entry will be generated from.  */
+  const char *sourcecode;
+
+  /* Options.  XXX: Not used yet.  */
+  int options;
+};
+
+/* State of the lexer as passed to the lexer.  */
+struct grub_lexer_param
+{
+  /* Set to 0 when the lexer is done.  */
+  int done;
+
+  /* State of the state machine.  */
+  grub_parser_state_t state;
+
+  /* Function used by the lexer to get a new line when more input is
+     expected, but not available.  */
+  grub_reader_getline_t getline;
+
+  /* A reference counter.  If this is >0 it means that the parser
+     expects more tokens and `getline' should be called to fetch more.
+     Otherwise the lexer can stop processing if the current buffer is
+     depleted.  */
+  int refs;
+
+  /* The character stream that has to be parsed.  */
+  char *script;
+  char *newscript; /* XXX */
+
+  /* While walking through the databuffer, `record' the characters to
+     this other buffer.  It can be used to edit the menu entry at a
+     later moment.  */
+
+  /* If true, recording is enabled.  */
+  int record;
+
+  /* Points to the recording.  */
+  char *recording;
+
+  /* index in the RECORDING.  */
+  int recordpos;
+
+  /* Size of RECORDING.  */
+  int recordlen;
+};
+
+/* State of the parser as passes to the parser.  */
+struct grub_parser_param
+{
+  /* Keep track of the memory allocated for this specific
+     function.  */
+  struct grub_script_mem *func_mem;
+
+  /* When set to 0, no errors have occured during parsing.  */
+  int err;
+
+  /* The memory that was used while parsing and scanning.  */
+  struct grub_script_mem *memused;
+
+  /* The result of the parser.  */
+  struct grub_script_cmd *parsed;
+
+  struct grub_lexer_param *lexerstate;
+};
+
+struct grub_script_arglist *
+grub_script_create_arglist (struct grub_parser_param *state);
+
+struct grub_script_arglist *
+grub_script_add_arglist (struct grub_parser_param *state,
+                        struct grub_script_arglist *list,
+                        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);
+
+struct grub_script_cmd *
+grub_script_create_cmdif (struct grub_parser_param *state,
+                         struct grub_script_cmd *exec_to_evaluate,
+                         struct grub_script_cmd *exec_on_true,
+                         struct grub_script_cmd *exec_on_false);
+
+struct grub_script_cmd *
+grub_script_create_cmdmenu (struct grub_parser_param *state,
+                           struct grub_script_arglist *arglist,
+                           char *sourcecode,
+                           int options);
+
+struct grub_script_cmd *
+grub_script_add_cmd (struct grub_parser_param *state,
+                    struct grub_script_cmdblock *cmdblock,
+                    struct grub_script_cmd *cmd);
+struct grub_script_arg *
+grub_script_arg_add (struct grub_parser_param *state,
+                    struct grub_script_arg *arg,
+                    grub_script_arg_type_t type, char *str);
+
+struct grub_script *grub_script_parse (char *script,
+                                      grub_reader_getline_t getline);
+void grub_script_free (struct grub_script *script);
+struct grub_script *grub_script_create (struct grub_script_cmd *cmd,
+                                       struct grub_script_mem *mem);
+
+struct grub_lexer_param *grub_script_lexer_init (char *s,
+                                                grub_reader_getline_t getline);
+void grub_script_lexer_ref (struct grub_lexer_param *);
+void grub_script_lexer_deref (struct grub_lexer_param *);
+void grub_script_lexer_record_start (struct grub_lexer_param *);
+char *grub_script_lexer_record_stop (struct grub_lexer_param *);
+
+/* Functions to track allocated memory.  */
+struct grub_script_mem *grub_script_mem_record (struct grub_parser_param 
*state);
+struct grub_script_mem *grub_script_mem_record_stop (struct grub_parser_param 
*state,
+                                                    struct grub_script_mem 
*restore);
+void *grub_script_malloc (struct grub_parser_param *state, grub_size_t size);
+
+/* Functions used by bison.  */
+union YYSTYPE;
+int grub_script_yylex (union YYSTYPE *, struct grub_parser_param *);
+int grub_script_yyparse (struct grub_parser_param *);
+void grub_script_yyerror (struct grub_parser_param *, char const *);
+
+/* Commands to execute, don't use these directly.  */
+grub_err_t grub_script_execute_cmdline (struct grub_script_cmd *cmd);
+grub_err_t grub_script_execute_cmdblock (struct grub_script_cmd *cmd);
+grub_err_t grub_script_execute_cmdif (struct grub_script_cmd *cmd);
+grub_err_t grub_script_execute_menuentry (struct grub_script_cmd *cmd);
+
+/* Execute any GRUB pre-parsed command or script.  */
+grub_err_t grub_script_execute (struct grub_script *script);
+
+/* This variable points to the parsed command.  This is used to
+   communicate with the bison code.  */
+extern struct grub_script_cmd *grub_script_parsed;
+
+
+
+/* The function description.  */
+struct grub_script_function
+{
+  /* The name.  */
+  char *name;
+
+  /* The script function.  */
+  struct grub_script *func;
+
+  /* The flags.  */
+  unsigned flags;
+
+  /* The next element.  */
+  struct grub_script_function *next;
+
+  int references;
+};
+typedef struct grub_script_function *grub_script_function_t;
+
+grub_script_function_t grub_script_function_create (char *functionname,
+                                                   struct grub_script *cmd);
+void grub_script_function_remove (const char *name);
+grub_script_function_t grub_script_function_find (char *functionname);
+int grub_script_function_iterate (int (*iterate) (grub_script_function_t));
+int grub_script_function_call (grub_script_function_t func,
+                              int argc, char **args);
+
+#endif /* ! GRUB_NORMAL_PARSER_HEADER */

Modified: trunk/grub2/kern/main.c
===================================================================
--- trunk/grub2/kern/main.c     2009-05-02 16:55:35 UTC (rev 2157)
+++ trunk/grub2/kern/main.c     2009-05-02 19:49:34 UTC (rev 2158)
@@ -22,11 +22,13 @@
 #include <grub/symbol.h>
 #include <grub/dl.h>
 #include <grub/term.h>
-#include <grub/rescue.h>
 #include <grub/file.h>
 #include <grub/device.h>
 #include <grub/env.h>
 #include <grub/mm.h>
+#include <grub/command.h>
+#include <grub/reader.h>
+#include <grub/parser.h>
 
 void
 grub_module_iterate (int (*hook) (struct grub_module_header *header))
@@ -120,6 +122,9 @@
   
   /* Something went wrong.  Print errors here to let user know why we're 
entering rescue mode.  */
   grub_print_error ();
+  grub_errno = 0;
+
+  grub_command_execute ("normal", 0, 0);
 }
 
 /* The main routine.  */
@@ -144,9 +149,10 @@
   grub_env_export ("prefix");
   grub_set_root_dev ();
 
-  /* Load the normal mode module.  */
+  grub_register_core_commands ();
+  grub_register_rescue_parser ();
+  grub_register_rescue_reader ();
+  
   grub_load_normal_mode ();
-  
-  /* Enter the rescue mode.  */
-  grub_enter_rescue_mode ();
+  grub_reader_loop (0);
 }

Modified: trunk/grub2/kern/parser.c
===================================================================
--- trunk/grub2/kern/parser.c   2009-05-02 16:55:35 UTC (rev 2157)
+++ trunk/grub2/kern/parser.c   2009-05-02 19:49:34 UTC (rev 2158)
@@ -1,7 +1,7 @@
 /* parser.c - the part of the parser that can return partial tokens */
 /*
  *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2007  Free Software Foundation, Inc.
+ *  Copyright (C) 2005,2007,2009  Free Software Foundation, Inc.
  *
  *  GRUB is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -100,7 +100,7 @@
 
 
 grub_err_t
-grub_parser_split_cmdline (const char *cmdline, grub_err_t (*getline) (char 
**),
+grub_parser_split_cmdline (const char *cmdline, grub_reader_getline_t getline,
                           int *argc, char ***argv)
 {
   grub_parser_state_t state = GRUB_PARSER_STATE_TEXT;
@@ -152,7 +152,7 @@
       if (! *rd)
        {
          if (getline)
-           getline (&rd);
+           getline (&rd, 1);
          else break;
        }
 
@@ -227,3 +227,45 @@
 
   return 0;
 }
+
+struct grub_handler_class grub_parser_class =
+  {
+    .name = "parser"
+  };
+
+grub_err_t
+grub_parser_execute (char *source)
+{
+  auto grub_err_t getline (char **line, int cont);
+  grub_err_t getline (char **line, int cont __attribute__ ((unused)))
+    {
+      char *p;
+
+      if (! source)
+       {
+         *line = 0;
+         return 0;
+       }
+
+      p = grub_strchr (source, '\n');
+      if (p)
+       *(p++) = 0;
+
+      *line = grub_strdup (source);
+      source = p;
+      return 0;
+    }
+
+  while (source)
+    {
+      char *line;
+      grub_parser_t parser;
+
+      getline (&line, 0);
+      parser = grub_parser_get_current ();
+      parser->parse_line (line, getline);
+      grub_free (line);
+    }
+
+  return grub_errno;
+}

Added: trunk/grub2/kern/reader.c
===================================================================
--- trunk/grub2/kern/reader.c                           (rev 0)
+++ trunk/grub2/kern/reader.c   2009-05-02 19:49:34 UTC (rev 2158)
@@ -0,0 +1,49 @@
+/* reader.c - reader support */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/mm.h>
+#include <grub/reader.h>
+#include <grub/parser.h>
+
+struct grub_handler_class grub_reader_class =
+  {
+    .name = "reader"
+  };
+
+grub_err_t
+grub_reader_loop (grub_reader_getline_t getline)
+{
+  while (1)
+    {
+      char *line;
+      grub_reader_getline_t func;
+
+      /* Print an error, if any.  */
+      grub_print_error ();
+      grub_errno = GRUB_ERR_NONE;
+
+      func = (getline) ? : grub_reader_get_current ()->read_line;
+      if ((func (&line, 0)) || (! line))
+       return grub_errno;
+
+      grub_parser_get_current ()->parse_line (line, func);
+      grub_free (line);
+    }
+}

Deleted: trunk/grub2/kern/rescue.c
===================================================================
--- trunk/grub2/kern/rescue.c   2009-05-02 16:55:35 UTC (rev 2157)
+++ trunk/grub2/kern/rescue.c   2009-05-02 19:49:34 UTC (rev 2158)
@@ -1,163 +0,0 @@
-/* rescue.c - rescue mode */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2003,2005,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/kernel.h>
-#include <grub/rescue.h>
-#include <grub/term.h>
-#include <grub/misc.h>
-#include <grub/disk.h>
-#include <grub/file.h>
-#include <grub/mm.h>
-#include <grub/err.h>
-#include <grub/loader.h>
-#include <grub/dl.h>
-#include <grub/partition.h>
-#include <grub/env.h>
-#include <grub/parser.h>
-#include <grub/list.h>
-#include <grub/command.h>
-
-#define GRUB_RESCUE_BUF_SIZE   256
-#define GRUB_RESCUE_MAX_ARGS   20
-
-static char linebuf[GRUB_RESCUE_BUF_SIZE];
-
-/* Prompt to input a command and read the line.  */
-static void
-grub_rescue_get_command_line (const char *prompt)
-{
-  int c;
-  int pos = 0;
-  
-  grub_printf (prompt);
-  grub_memset (linebuf, 0, GRUB_RESCUE_BUF_SIZE);
-  
-  while ((c = GRUB_TERM_ASCII_CHAR (grub_getkey ())) != '\n' && c != '\r')
-    {
-      if (grub_isprint (c))
-       {
-         if (pos < GRUB_RESCUE_BUF_SIZE - 1)
-           {
-             linebuf[pos++] = c;
-             grub_putchar (c);
-           }
-       }
-      else if (c == '\b')
-       {
-         if (pos > 0)
-           {
-             linebuf[--pos] = 0;
-             grub_putchar (c);
-             grub_putchar (' ');
-             grub_putchar (c);
-           }
-       }
-      grub_refresh ();
-    }
-
-  grub_putchar ('\n');
-  grub_refresh ();
-}
-
-static void
-attempt_normal_mode (void)
-{
-  grub_command_t cmd;
-
-  cmd = grub_command_find ("normal");
-  if (cmd)
-    (cmd->func) (cmd, 0, 0);
-}
-
-/* Enter the rescue mode.  */
-void
-grub_enter_rescue_mode (void)
-{
-  auto grub_err_t getline (char **line);
-  
-  grub_err_t getline (char **line)
-    {
-      grub_rescue_get_command_line ("> ");
-      *line = linebuf;
-      return 0;
-    }
-
-  grub_register_core_commands ();
-
-  /* First of all, attempt to execute the normal mode.  */
-  attempt_normal_mode ();
-
-  grub_printf ("Entering rescue mode...\n");
-  
-  while (1)
-    {
-      char *line = linebuf;
-      char *name;
-      int n;
-      grub_command_t cmd;
-      char **args;
-
-      /* Print an error, if any.  */
-      grub_print_error ();
-      grub_errno = GRUB_ERR_NONE;
-
-      /* Get a command line.  */
-      grub_rescue_get_command_line ("grub rescue> ");
-      if (line[0] == 0)
-       continue;
-
-      if (grub_parser_split_cmdline (line, getline, &n, &args) || n < 0)
-       continue;
-
-      /* In case of an assignment set the environment accordingly
-        instead of calling a function.  */
-      if (n == 0 && grub_strchr (line, '='))
-       {
-         char *val = grub_strchr (args[0], '=');
-         val[0] = 0;
-         grub_env_set (args[0], val + 1);
-         val[0] = '=';
-          grub_free (args[0]);
-         continue;
-       }
-
-      /* Get the command name.  */
-      name = args[0];
-
-      /* If nothing is specified, restart.  */
-      if (*name == '\0')
-       {
-         grub_free (args[0]);
-         continue;
-       }
-      
-      cmd = grub_command_find (name);
-      if (cmd)
-       {
-         (cmd->func) (cmd, n, &args[1]);
-       }
-      else
-       {
-         grub_printf ("Unknown command `%s'\n", name);
-         grub_printf ("Try `help' for usage\n");
-       }
-
-      grub_free (args[0]);
-    }
-}

Added: trunk/grub2/kern/rescue_parser.c
===================================================================
--- trunk/grub2/kern/rescue_parser.c                            (rev 0)
+++ trunk/grub2/kern/rescue_parser.c    2009-05-02 19:49:34 UTC (rev 2158)
@@ -0,0 +1,84 @@
+/* rescue_parser.c - rescue mode parser  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/mm.h>
+#include <grub/env.h>
+#include <grub/parser.h>
+#include <grub/misc.h>
+#include <grub/command.h>
+
+static grub_err_t
+grub_rescue_parse_line (char *line, grub_reader_getline_t getline)
+{
+  char *name;
+  int n;
+  grub_command_t cmd;
+  char **args;
+
+  if (grub_parser_split_cmdline (line, getline, &n, &args) || n < 0)
+    return grub_errno;
+
+  /* In case of an assignment set the environment accordingly
+     instead of calling a function.  */
+  if (n == 0 && grub_strchr (line, '='))
+    {
+      char *val = grub_strchr (args[0], '=');
+      val[0] = 0;
+      grub_env_set (args[0], val + 1);
+      val[0] = '=';
+      goto quit;
+    }
+
+  /* Get the command name.  */
+  name = args[0];
+
+  /* If nothing is specified, restart.  */
+  if (*name == '\0')
+    goto quit;
+
+  cmd = grub_command_find (name);
+  if (cmd)
+    {
+      (cmd->func) (cmd, n, &args[1]);
+    }
+  else
+    {
+      grub_printf ("Unknown command `%s'\n", name);
+      grub_printf ("Try `help' for usage\n");
+    }
+
+ quit:
+  grub_free (args[0]);
+  grub_free (args);
+
+  return grub_errno;
+}
+
+static struct grub_parser grub_rescue_parser =
+  {
+    .name = "rescue",
+    .parse_line = grub_rescue_parse_line
+  };
+
+void
+grub_register_rescue_parser (void)
+{
+  grub_parser_register ("rescue", &grub_rescue_parser);
+}

Added: trunk/grub2/kern/rescue_reader.c
===================================================================
--- trunk/grub2/kern/rescue_reader.c                            (rev 0)
+++ trunk/grub2/kern/rescue_reader.c    2009-05-02 19:49:34 UTC (rev 2158)
@@ -0,0 +1,88 @@
+/* rescue_reader.c - rescue mode reader  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/reader.h>
+#include <grub/misc.h>
+#include <grub/term.h>
+
+#define GRUB_RESCUE_BUF_SIZE   256
+
+static char linebuf[GRUB_RESCUE_BUF_SIZE];
+
+static grub_err_t
+grub_rescue_init (void)
+{
+  grub_printf ("Entering rescue mode...\n");
+  return 0;
+}
+
+/* Prompt to input a command and read the line.  */
+static grub_err_t
+grub_rescue_read_line (char **line, int cont)
+{
+  int c;
+  int pos = 0;
+
+  grub_printf ((cont) ? "> " : "grub rescue> ");
+  grub_memset (linebuf, 0, GRUB_RESCUE_BUF_SIZE);
+
+  while ((c = GRUB_TERM_ASCII_CHAR (grub_getkey ())) != '\n' && c != '\r')
+    {
+      if (grub_isprint (c))
+       {
+         if (pos < GRUB_RESCUE_BUF_SIZE - 1)
+           {
+             linebuf[pos++] = c;
+             grub_putchar (c);
+           }
+       }
+      else if (c == '\b')
+       {
+         if (pos > 0)
+           {
+             linebuf[--pos] = 0;
+             grub_putchar (c);
+             grub_putchar (' ');
+             grub_putchar (c);
+           }
+       }
+      grub_refresh ();
+    }
+
+  grub_putchar ('\n');
+  grub_refresh ();
+
+  *line = grub_strdup (linebuf);
+
+  return 0;
+}
+
+static struct grub_reader grub_rescue_reader =
+  {
+    .name = "rescue",
+    .init = grub_rescue_init,
+    .read_line = grub_rescue_read_line
+  };
+
+void
+grub_register_rescue_reader (void)
+{
+  grub_reader_register ("rescue", &grub_rescue_reader);
+}

Modified: trunk/grub2/loader/i386/multiboot.c
===================================================================
--- trunk/grub2/loader/i386/multiboot.c 2009-05-02 16:55:35 UTC (rev 2157)
+++ trunk/grub2/loader/i386/multiboot.c 2009-05-02 19:49:34 UTC (rev 2158)
@@ -37,7 +37,6 @@
 #include <grub/aout.h>
 #include <grub/file.h>
 #include <grub/err.h>
-#include <grub/rescue.h>
 #include <grub/dl.h>
 #include <grub/mm.h>
 #include <grub/misc.h>

Modified: trunk/grub2/loader/multiboot2.c
===================================================================
--- trunk/grub2/loader/multiboot2.c     2009-05-02 16:55:35 UTC (rev 2157)
+++ trunk/grub2/loader/multiboot2.c     2009-05-02 19:49:34 UTC (rev 2158)
@@ -24,7 +24,6 @@
 #include <grub/elfload.h>
 #include <grub/file.h>
 #include <grub/err.h>
-#include <grub/rescue.h>
 #include <grub/dl.h>
 #include <grub/mm.h>
 #include <grub/misc.h>

Modified: trunk/grub2/loader/sparc64/ieee1275/linux.c
===================================================================
--- trunk/grub2/loader/sparc64/ieee1275/linux.c 2009-05-02 16:55:35 UTC (rev 
2157)
+++ trunk/grub2/loader/sparc64/ieee1275/linux.c 2009-05-02 19:49:34 UTC (rev 
2158)
@@ -22,7 +22,6 @@
 #include <grub/loader.h>
 #include <grub/dl.h>
 #include <grub/mm.h>
-#include <grub/rescue.h>
 #include <grub/misc.h>
 #include <grub/ieee1275/ieee1275.h>
 #include <grub/machine/loader.h>

Added: trunk/grub2/normal/autofs.c
===================================================================
--- trunk/grub2/normal/autofs.c                         (rev 0)
+++ trunk/grub2/normal/autofs.c 2009-05-02 19:49:34 UTC (rev 2158)
@@ -0,0 +1,134 @@
+/* autofs.c - support auto-loading from fs.lst */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/mm.h>
+#include <grub/dl.h>
+#include <grub/env.h>
+#include <grub/misc.h>
+#include <grub/fs.h>
+#include <grub/normal.h>
+
+/* This is used to store the names of filesystem modules for auto-loading.  */
+struct grub_fs_module_list
+{
+  char *name;
+  struct grub_fs_module_list *next;
+};
+typedef struct grub_fs_module_list *grub_fs_module_list_t;
+
+static grub_fs_module_list_t fs_module_list = 0;
+
+/* The auto-loading hook for filesystems.  */
+static int
+autoload_fs_module (void)
+{
+  grub_fs_module_list_t p;
+
+  while ((p = fs_module_list) != 0)
+    {
+      if (! grub_dl_get (p->name) && grub_dl_load (p->name))
+       return 1;
+
+      fs_module_list = p->next;
+      grub_free (p->name);
+      grub_free (p);
+    }
+
+  return 0;
+}
+
+/* Read the file fs.lst for auto-loading.  */
+void
+read_fs_list (void)
+{
+  const char *prefix;
+  static int first_time = 1;
+
+  /* Make sure that this function does not get executed twice.  */
+  if (! first_time)
+    return;
+  first_time = 0;
+
+  prefix = grub_env_get ("prefix");
+  if (prefix)
+    {
+      char *filename;
+
+      filename = grub_malloc (grub_strlen (prefix) + sizeof ("/fs.lst"));
+      if (filename)
+       {
+         grub_file_t file;
+
+         grub_sprintf (filename, "%s/fs.lst", prefix);
+         file = grub_file_open (filename);
+         if (file)
+           {
+             while (1)
+               {
+                 char *buf;
+                 char *p;
+                 char *q;
+                 grub_fs_module_list_t fs_mod;
+
+                 buf = grub_file_getline (file);
+                 if (! buf)
+                   break;
+
+                 p = buf;
+                 q = buf + grub_strlen (buf) - 1;
+
+                 /* Ignore space.  */
+                 while (grub_isspace (*p))
+                   p++;
+
+                 while (p < q && grub_isspace (*q))
+                   *q-- = '\0';
+
+                 /* If the line is empty, skip it.  */
+                 if (p >= q)
+                   continue;
+
+                 fs_mod = grub_malloc (sizeof (*fs_mod));
+                 if (! fs_mod)
+                   continue;
+
+                 fs_mod->name = grub_strdup (p);
+                 if (! fs_mod->name)
+                   {
+                     grub_free (fs_mod);
+                     continue;
+                   }
+
+                 fs_mod->next = fs_module_list;
+                 fs_module_list = fs_mod;
+               }
+
+             grub_file_close (file);
+           }
+
+         grub_free (filename);
+       }
+    }
+
+  /* Ignore errors.  */
+  grub_errno = GRUB_ERR_NONE;
+
+  /* Set the hook.  */
+  grub_fs_autoload_hook = autoload_fs_module;
+}

Modified: trunk/grub2/normal/cmdline.c
===================================================================
--- trunk/grub2/normal/cmdline.c        2009-05-02 16:55:35 UTC (rev 2157)
+++ trunk/grub2/normal/cmdline.c        2009-05-02 19:49:34 UTC (rev 2158)
@@ -132,37 +132,6 @@
   hist_lines[pos] = grub_strdup (s);
 }
 
-void
-grub_cmdline_run (int nested)
-{
-  grub_normal_init_page ();
-  grub_setcursor (1);
-  
-  grub_printf ("\
- [ Minimal BASH-like line editing is supported. For the first word, TAB\n\
-   lists possible command completions. Anywhere else TAB lists possible\n\
-   device/file completions.%s ]\n\n",
-              nested ? " ESC at any time exits." : "");
-  
-  while (1)
-    {
-      static char cmdline[GRUB_MAX_CMDLINE];
-
-      grub_print_error ();
-      grub_errno = GRUB_ERR_NONE;
-      cmdline[0] = '\0';
-      
-      if (! grub_cmdline_get ("grub> ", cmdline, sizeof (cmdline), 0, 1)
-         && nested)
-       return;
-
-      if (! *cmdline)
-       continue;
-
-      grub_command_execute (cmdline, 1);
-    }
-}
-
 /* A completion hook to print items.  */
 static void
 print_completion (const char *item, grub_completion_type_t type, int count)

Deleted: trunk/grub2/normal/command.c
===================================================================
--- trunk/grub2/normal/command.c        2009-05-02 16:55:35 UTC (rev 2157)
+++ trunk/grub2/normal/command.c        2009-05-02 19:49:34 UTC (rev 2158)
@@ -1,70 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2005,2006,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/normal.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/err.h>
-#include <grub/term.h>
-#include <grub/env.h>
-#include <grub/dl.h>
-#include <grub/parser.h>
-#include <grub/script.h>
-#include <grub/list.h>
-#include <grub/command.h>
-
-int
-grub_command_execute (char *cmdline, int interactive)
-{
-  auto grub_err_t cmdline_get (char **s);
-  grub_err_t cmdline_get (char **s)
-    {
-      *s = grub_malloc (GRUB_MAX_CMDLINE);
-      *s[0] = '\0';
-      return grub_cmdline_get (">", *s, GRUB_MAX_CMDLINE, 0, 1);
-    }
-
-  grub_err_t ret = 0;
-  char *pager;
-  struct grub_script *parsed_script;
-  
-  /* Enable the pager if the environment pager is set to 1.  */
-  if (interactive)
-    pager = grub_env_get ("pager");
-  else
-    pager = NULL;
-  if (pager && (! grub_strcmp (pager, "1")))
-    grub_set_more (1);
-
-  /* Parse the script.  */
-  parsed_script = grub_script_parse (cmdline, cmdline_get);
-
-  if (parsed_script)
-    {
-      /* Execute the command(s).  */
-      grub_script_execute (parsed_script);
-
-      /* The parsed script was executed, throw it away.  */
-      grub_script_free (parsed_script);
-    }
-
-  if (pager && (! grub_strcmp (pager, "1")))
-    grub_set_more (0);
-
-  return ret;
-}

Added: trunk/grub2/normal/dyncmd.c
===================================================================
--- trunk/grub2/normal/dyncmd.c                         (rev 0)
+++ trunk/grub2/normal/dyncmd.c 2009-05-02 19:49:34 UTC (rev 2158)
@@ -0,0 +1,158 @@
+/* dyncmd.c - support dynamic command */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/env.h>
+#include <grub/misc.h>
+#include <grub/command.h>
+#include <grub/normal.h>
+
+static grub_err_t
+grub_dyncmd_dispatcher (struct grub_command *cmd,
+                       int argc, char **args)
+{
+  char *modname = cmd->data;
+  grub_dl_t mod;
+  grub_err_t ret;
+
+  mod = grub_dl_load (modname);
+  if (mod)
+    {
+      char *name;
+
+      grub_free (modname);
+      grub_dl_ref (mod);
+
+      name = (char *) cmd->name;
+      grub_unregister_command (cmd);
+
+      cmd = grub_command_find (name);
+      if (cmd)
+       ret = (cmd->func) (cmd, argc, args);
+      else
+       ret = grub_errno;
+
+      grub_free (name);
+    }
+  else
+    ret = grub_errno;
+
+  return ret;
+}
+
+/* Read the file command.lst for auto-loading.  */
+void
+read_command_list (void)
+{
+  const char *prefix;
+  static int first_time = 1;
+
+  /* Make sure that this function does not get executed twice.  */
+  if (! first_time)
+    return;
+  first_time = 0;
+
+  prefix = grub_env_get ("prefix");
+  if (prefix)
+    {
+      char *filename;
+
+      filename = grub_malloc (grub_strlen (prefix) + sizeof ("/command.lst"));
+      if (filename)
+       {
+         grub_file_t file;
+
+         grub_sprintf (filename, "%s/command.lst", prefix);
+         file = grub_file_open (filename);
+         if (file)
+           {
+             char *buf = 0;
+             for (;; grub_free(buf))
+               {
+                 char *p, *name, *modname;
+                 grub_command_t cmd;
+                 int prio = 0;
+
+                 buf = grub_file_getline (file);
+
+                 if (! buf)
+                   break;
+
+                 name = buf;
+                 if (*name == '*')
+                   {
+                     name++;
+                     prio++;
+                   }
+
+                 if (! grub_isgraph (name[0]))
+                   continue;
+
+                 p = grub_strchr (name, ':');
+                 if (! p)
+                   continue;
+
+                 *p = '\0';
+                 while (*++p == ' ')
+                   ;
+
+                 if (! grub_isgraph (*p))
+                   continue;
+
+                 if (grub_dl_get (p))
+                   continue;
+
+                 name = grub_strdup (name);
+                 if (! name)
+                   continue;
+
+                 modname = grub_strdup (p);
+                 if (! modname)
+                   {
+                     grub_free (name);
+                     continue;
+                   }
+
+                 cmd = grub_register_command_prio (name,
+                                                   grub_dyncmd_dispatcher,
+                                                   0, "not loaded", prio);
+                 if (! cmd)
+                   {
+                     grub_free (name);
+                     grub_free (modname);
+                     continue;
+                   }
+                 cmd->flags |= GRUB_COMMAND_FLAG_DYNCMD;
+                 cmd->data = modname;
+
+                 /* Update the active flag.  */
+                 grub_command_find (name);
+               }
+
+             grub_file_close (file);
+           }
+
+         grub_free (filename);
+       }
+    }
+
+  /* Ignore errors.  */
+  grub_errno = GRUB_ERR_NONE;
+}

Deleted: trunk/grub2/normal/execute.c
===================================================================
--- trunk/grub2/normal/execute.c        2009-05-02 16:55:35 UTC (rev 2157)
+++ trunk/grub2/normal/execute.c        2009-05-02 19:49:34 UTC (rev 2158)
@@ -1,251 +0,0 @@
-/* execute.c -- Execute a GRUB script.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/normal.h>
-#include <grub/env.h>
-#include <grub/script.h>
-#include <grub/lib/arg.h>
-
-static grub_err_t
-grub_script_execute_cmd (struct grub_script_cmd *cmd)
-{
-  if (cmd == 0)
-    return 0;
-
-  return cmd->exec (cmd);
-}
-
-/* Parse ARG and return the textual representation.  Add strings are
-   concatenated and all values of the variables are filled in.  */
-static char *
-grub_script_execute_argument_to_string (struct grub_script_arg *arg)
-{
-  int size = 0;
-  char *val;
-  char *chararg;
-  struct grub_script_arg *argi;
-
-  /* First determine the size of the argument.  */
-  for (argi = arg; argi; argi = argi->next)
-    {
-      if (argi->type == 1)
-       {
-         val = grub_env_get (argi->str);
-         if (val)
-           size += grub_strlen (val);
-       }
-      else
-       size += grub_strlen (argi->str);
-    }
-
-  /* Create the argument.  */
-  chararg = grub_malloc (size + 1);
-  if (! chararg)
-    return 0;
-
-  *chararg = '\0';
-  /* First determine the size of the argument.  */
-  for (argi = arg; argi; argi = argi->next)
-    {
-      if (argi->type == 1)
-       {
-         val = grub_env_get (argi->str);
-         if (val)
-           grub_strcat (chararg, val);
-       }
-      else
-       grub_strcat (chararg, argi->str);
-    }
-
-  return chararg;
-}
-
-/* Execute a single command line.  */
-grub_err_t
-grub_script_execute_cmdline (struct grub_script_cmd *cmd)
-{
-  struct grub_script_cmdline *cmdline = (struct grub_script_cmdline *) cmd;
-  struct grub_script_arglist *arglist;
-  char **args = 0;
-  int i = 0;
-  grub_command_t grubcmd;
-  grub_err_t ret = 0;
-  int argcount = 0;
-  grub_script_function_t func = 0;
-  char errnobuf[6];
-
-  /* Lookup the command.  */
-  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)
-       {
-         /* As a last resort, try if it is an assignment.  */
-         char *assign = grub_strdup (cmdline->cmdname);
-         char *eq = grub_strchr (assign, '=');
-
-         if (eq)
-           {
-             /* Create two strings and set the variable.  */
-             *eq = '\0';
-             eq++;
-             grub_env_set (assign, eq);
-
-             /* This was set because the command was not found.  */
-             grub_errno = GRUB_ERR_NONE;
-           }
-         grub_free (assign);
-         return 0;
-       }
-    }
-
-  if (cmdline->arglist)
-    {
-      argcount = cmdline->arglist->argcount;
-
-      /* Create argv from the arguments.  */
-      args = grub_malloc (sizeof (char *) * argcount);
-      for (arglist = cmdline->arglist; arglist; arglist = arglist->next)
-       {
-         char *str;
-         str = grub_script_execute_argument_to_string (arglist->arg);
-         args[i++] = str;
-       }
-    }
-
-  /* Execute the GRUB command or function.  */
-  if (grubcmd)
-    ret = (grubcmd->func) (grubcmd, argcount, args);
-  else
-    ret = grub_script_function_call (func, argcount, args);
-
-  /* Free arguments.  */
-  for (i = 0; i < argcount; i++)
-    grub_free (args[i]);
-  grub_free (args);
-
-  grub_sprintf (errnobuf, "%d", ret);
-  grub_env_set ("?", errnobuf);
-
-  return ret;
-}
-
-/* Execute a block of one or more commands.  */
-grub_err_t
-grub_script_execute_cmdblock (struct grub_script_cmd *cmd)
-{
-  struct grub_script_cmdblock *cmdblock = (struct grub_script_cmdblock *) cmd;
-
-  /* Loop over every command and execute it.  */
-  for (cmd = cmdblock->cmdlist; cmd; cmd = cmd->next)
-    grub_script_execute_cmd (cmd);
-
-  return 0;
-}
-
-/* Execute an if statement.  */
-grub_err_t
-grub_script_execute_cmdif (struct grub_script_cmd *cmd)
-{
-  struct grub_script_cmdif *cmdif = (struct grub_script_cmdif *) cmd;
-  char *result;
-
-  /* Check if the commands results in a true or a false.  The value is
-     read from the env variable `?'.  */
-  grub_script_execute_cmd (cmdif->exec_to_evaluate);
-  result = grub_env_get ("?");
-
-  /* Execute the `if' or the `else' part depending on the value of
-     `?'.  */
-  if (result && ! grub_strcmp (result, "0"))
-    return grub_script_execute_cmd (cmdif->exec_on_true);
-  else
-    return grub_script_execute_cmd (cmdif->exec_on_false);
-}
-
-/* Execute the menu entry generate statement.  */
-grub_err_t
-grub_script_execute_menuentry (struct grub_script_cmd *cmd)
-{
-  struct grub_script_cmd_menuentry *cmd_menuentry;
-  struct grub_script_arglist *arglist;
-  struct grub_script *script;
-  char **args = 0;
-  int argcount = 0;
-  int i = 0;
-
-  cmd_menuentry = (struct grub_script_cmd_menuentry *) cmd;
-
-  if (cmd_menuentry->arglist)
-    {
-      argcount = cmd_menuentry->arglist->argcount;
-
-      /* Create argv from the arguments.  */
-      args = grub_malloc (sizeof (char *) * argcount);
-
-      if (! args)
-       {
-         return grub_errno;
-       }
-
-      for (arglist = cmd_menuentry->arglist; arglist; arglist = arglist->next)
-       {
-         char *str;
-         str = grub_script_execute_argument_to_string (arglist->arg);
-         args[i++] = str;
-       }
-    }
-
-  /* Parse the menu entry *again*.  */
-  script = grub_script_parse ((char *) cmd_menuentry->sourcecode, 0);
-
-  /* Add new menu entry.  */
-  if (script)
-    {
-      grub_normal_menu_addentry (argcount, (const char **)args,
-                                script, cmd_menuentry->sourcecode);
-    }
-
-  /* Free arguments.  */
-  for (i = 0; i < argcount; i++)
-    grub_free (args[i]);
-  grub_free (args);
-
-  return grub_errno;
-}
-
-
-
-/* Execute any GRUB pre-parsed command or script.  */
-grub_err_t
-grub_script_execute (struct grub_script *script)
-{
-  if (script == 0)
-    return 0;
-
-  return grub_script_execute_cmd (script->cmd);
-}
-

Deleted: trunk/grub2/normal/function.c
===================================================================
--- trunk/grub2/normal/function.c       2009-05-02 16:55:35 UTC (rev 2157)
+++ trunk/grub2/normal/function.c       2009-05-02 19:49:34 UTC (rev 2158)
@@ -1,125 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2007  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/misc.h>
-#include <grub/script.h>
-#include <grub/parser.h>
-#include <grub/mm.h>
-
-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_t func;
-  grub_script_function_t *p;
-  
-  func = (grub_script_function_t) grub_malloc (sizeof (*func));
-  if (! func)
-    return 0;
-
-  func->name = grub_strdup (functionname);
-  if (! func->name)
-    {
-      grub_free (func);
-      return 0;
-    }
-  
-  func->func = cmd;
-
-  /* Keep the list sorted for simplicity.  */
-  p = &grub_script_function_list;
-  while (*p)
-    {
-      if (grub_strcmp ((*p)->name, functionname) >= 0)
-       break;
-
-      p = &((*p)->next);
-    }
-
-  /* If the function already exists, overwrite the old function.  */
-  if (*p && grub_strcmp ((*p)->name, functionname) == 0)
-    {
-      grub_script_function_t q;
-
-      q = *p;
-      grub_script_free (q->func);
-      q->func = cmd;
-      grub_free (func);
-      func = q;
-    }
-  else
-    {
-      func->next = *p;
-      *p = func;
-    }
-
-  return func;
-}
-
-void
-grub_script_function_remove (const char *name)
-{
-  grub_script_function_t *p, q;
-
-  for (p = &grub_script_function_list, q = *p; q; p = &(q->next), q = q->next)
-    if (grub_strcmp (name, q->name) == 0)
-      {
-        *p = q->next;
-       grub_free (q->name);
-       grub_script_free (q->func);
-        grub_free (q);
-        break;
-      }
-}
-
-grub_script_function_t
-grub_script_function_find (char *functionname)
-{
-  grub_script_function_t func;
-
-  for (func = grub_script_function_list; func; func = func->next)
-    if (grub_strcmp (functionname, func->name) == 0)
-      break;
-
-  if (! func)
-    grub_error (GRUB_ERR_UNKNOWN_COMMAND, "unknown command `%s'", 
functionname);
-
-  return func;
-}
-
-int
-grub_script_function_iterate (int (*iterate) (grub_script_function_t))
-{
-  grub_script_function_t func;
-  
-  for (func = grub_script_function_list; func; func = func->next)
-    if (iterate (func))
-      return 1;
-  
-  return 0;
-}
-
-int
-grub_script_function_call (grub_script_function_t func,
-                          int argc __attribute__((unused)),
-                          char **args __attribute__((unused)))
-{
-  /* XXX: Arguments are not supported yet.  */
-  return grub_script_execute (func->func);
-}

Deleted: trunk/grub2/normal/lexer.c
===================================================================
--- trunk/grub2/normal/lexer.c  2009-05-02 16:55:35 UTC (rev 2157)
+++ trunk/grub2/normal/lexer.c  2009-05-02 19:49:34 UTC (rev 2158)
@@ -1,364 +0,0 @@
-/* lexer.c - The scripting lexer.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2006,2007,2008  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/parser.h>
-#include <grub/misc.h>
-#include <grub/mm.h>
-#include <grub/script.h>
-
-#include "grub_script.tab.h"
-
-static int
-check_varstate (grub_parser_state_t state)
-{
-  return (state == GRUB_PARSER_STATE_VARNAME
-         || state == GRUB_PARSER_STATE_VAR
-         || state == GRUB_PARSER_STATE_QVAR
-         || state == GRUB_PARSER_STATE_VARNAME2
-         || state == GRUB_PARSER_STATE_QVARNAME
-         || state == GRUB_PARSER_STATE_QVARNAME2);
-}
-
-static int
-check_textstate (grub_parser_state_t state)
-{
-  return (state == GRUB_PARSER_STATE_TEXT
-         || state == GRUB_PARSER_STATE_QUOTE
-         || state == GRUB_PARSER_STATE_DQUOTE);
-}
-
-struct grub_lexer_param *
-grub_script_lexer_init (char *script, grub_err_t (*getline) (char **))
-{
-  struct grub_lexer_param *param;
-
-  param = grub_malloc (sizeof (*param));
-  if (! param)
-    return 0;
-
-  param->state = GRUB_PARSER_STATE_TEXT;
-  param->getline = getline;
-  param->refs = 0;
-  param->done = 0;
-  param->newscript = 0;
-  param->script = script;
-  param->record = 0;
-  param->recording = 0;
-  param->recordpos = 0;
-  param->recordlen = 0;
-
-  return param;
-}
-
-void
-grub_script_lexer_ref (struct grub_lexer_param *state)
-{
-  state->refs++;
-}
-
-void
-grub_script_lexer_deref (struct grub_lexer_param *state)
-{
-  state->refs--;
-}
-
-/* Start recording all characters passing through the lexer.  */
-void
-grub_script_lexer_record_start (struct grub_lexer_param *state)
-{
-  state->record = 1;
-  state->recordlen = 100;
-  state->recording = grub_malloc (state->recordlen);
-  state->recordpos = 0;
-}
-
-char *
-grub_script_lexer_record_stop (struct grub_lexer_param *state)
-{
-  state->record = 0;
-
-  /* Delete the last character, it is a `}'.  */
-  if (state->recordpos > 0)
-    {
-      if (state->recording[--state->recordpos] != '}')
-       {
-         grub_printf ("Internal error while parsing menu entry");
-         for (;;); /* XXX */
-       }
-      state->recording[state->recordpos] = '\0';
-    }
-
-  return state->recording;
-}
-
-/* When recording is enabled, record the character C as the next item
-   in the character stream.  */
-static void
-recordchar (struct grub_lexer_param *state, char c)
-{
-  if (state->recordpos == state->recordlen)
-    {
-      char *old = state->recording;
-      state->recordlen += 100;
-      state->recording = grub_realloc (state->recording, state->recordlen);
-      if (! state->recording)
-       {
-         grub_free (old);
-         state->record = 0;
-       }
-    }
-  state->recording[state->recordpos++] = c;
-}
-
-/* Fetch the next character for the lexer.  */
-static void
-nextchar (struct grub_lexer_param *state)
-{
-  if (state->record)
-    recordchar (state, *state->script);
-  state->script++;
-}
-
-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;
-
-  if (state->done)
-    return 0;
-
-  if (! *state->script)
-    {
-      /* 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);
-             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';
-       }
-    }
-
-  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.  */
-      if (newstate == GRUB_PARSER_STATE_TEXT)
-       {
-         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");
-                     return ' ';
-                   }
-                 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;
-             }
-           }
-       }
-
-      /* 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;
-             *(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->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;
-    }
-  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;
-    }
-}
-
-void
-grub_script_yyerror (struct grub_parser_param *lex __attribute__ ((unused)),
-                    char const *err)
-{
-  grub_printf ("%s\n", err);
-}

Modified: trunk/grub2/normal/main.c
===================================================================
--- trunk/grub2/normal/main.c   2009-05-02 16:55:35 UTC (rev 2157)
+++ trunk/grub2/normal/main.c   2009-05-02 19:49:34 UTC (rev 2158)
@@ -20,20 +20,15 @@
 #include <grub/kernel.h>
 #include <grub/normal.h>
 #include <grub/dl.h>
-#include <grub/rescue.h>
 #include <grub/misc.h>
 #include <grub/file.h>
 #include <grub/mm.h>
 #include <grub/term.h>
 #include <grub/env.h>
 #include <grub/parser.h>
-#include <grub/script.h>
+#include <grub/reader.h>
 #include <grub/menu_viewer.h>
 
-grub_jmp_buf grub_exit_env;
-
-static grub_fs_module_list_t fs_module_list = 0;
-
 #define GRUB_DEFAULT_HISTORY_SIZE      50
 
 /* Read a line from the file FILE.  */
@@ -43,7 +38,6 @@
   char c;
   int pos = 0;
   int literal = 0;
-  int comment = 0;
   char *cmdline;
   int max_len = 64;
 
@@ -84,16 +78,9 @@
       if (c == '\\')
        literal = 1;
 
-      if (comment)
+      if (pos == 0)
        {
-         if (c == '\n')
-           comment = 0;
-       }
-      else if (pos == 0)
-       {
-         if (c == '#')
-           comment = 1;
-         else if (! grub_isspace (c))
+         if (! grub_isspace (c))
            cmdline[pos++] = c;
        }
       else
@@ -138,7 +125,6 @@
     {
       grub_menu_entry_t next_entry = entry->next;
 
-      grub_script_free (entry->commands);
       grub_free ((void *) entry->title);
       grub_free ((void *) entry->sourcecode);
       entry = next_entry;
@@ -164,8 +150,8 @@
 }
 
 grub_err_t
-grub_normal_menu_addentry (int argc, const char **args,
-                           struct grub_script *script, const char *sourcecode)
+grub_menu_addentry (int argc, const char **args,
+                   const char *sourcecode)
 {
   const char *menutitle = 0;
   const char *menusourcecode;
@@ -237,7 +223,7 @@
              /* Handle invalid argument.  */
              failed = 1;
              grub_error (GRUB_ERR_MENU,
-                          "invalid argument for menuentry: %s", args[i]);
+                         "invalid argument for menuentry: %s", args[i]);
              break;
            }
        }
@@ -251,7 +237,7 @@
        {
          failed = 1;
          grub_error (GRUB_ERR_MENU,
-                      "too many titles for menuentry: %s", args[i]);
+                     "too many titles for menuentry: %s", args[i]);
          break;
        }
     }
@@ -287,7 +273,6 @@
       return grub_errno;
     }
 
-  (*last)->commands = script;
   (*last)->title = menutitle;
   (*last)->classes = classes_head;
   (*last)->next = 0;
@@ -299,35 +284,72 @@
 }
 
 static grub_menu_t
-read_config_file (const char *config, int nested)
+read_config_file (const char *config)
 {
   grub_file_t file;
-  auto grub_err_t getline (char **line);
-  int currline = 0;
-  int errors = 0;
+  grub_parser_t old_parser = 0;
   
-  grub_err_t getline (char **line)
+  auto grub_err_t getline (char **line, int cont);
+  grub_err_t getline (char **line, int cont __attribute__ ((unused)))
     {
-      currline++;
+      while (1)
+       {
+         char *buf;
 
-      *line = grub_file_getline (file);
-      if (! *line)
-       return grub_errno;
+         *line = buf = grub_file_getline (file);
+         if (! buf)
+           return grub_errno;
 
+         if (buf[0] == '#')
+           {
+             if (buf[1] == '!')
+               {
+                 grub_parser_t parser;
+                 grub_named_list_t list;
+
+                 buf += 2;
+                 while (grub_isspace (*buf))
+                   buf++;
+
+                 if (! old_parser)
+                   old_parser = grub_parser_get_current ();
+
+                 list = GRUB_AS_NAMED_LIST (grub_parser_class.handler_list);
+                 parser = grub_named_list_find (list, buf);
+                 if (parser)
+                   grub_parser_set_current (parser);
+                 else
+                   {
+                     char cmd_name[8 + grub_strlen (buf)];
+
+                     /* Perhaps it's not loaded yet, try the autoload
+                        command.  */
+                     grub_strcpy (cmd_name, "parser.");
+                     grub_strcat (cmd_name, buf);
+                     grub_command_execute (cmd_name, 0, 0);
+                   }
+               }
+             grub_free (*line);
+           }
+         else
+           break;
+       }
+
       return GRUB_ERR_NONE;
     }
 
   grub_menu_t newmenu;
 
   newmenu = grub_env_get_data_slot ("menu");
-
-  if (nested || ! newmenu)
+  if (! newmenu)
     {
       newmenu = grub_malloc (sizeof (*newmenu));
       if (! newmenu)
        return 0;
       newmenu->size = 0;
       newmenu->entry_list = 0;
+
+      grub_env_set_data_slot ("menu", newmenu);
     }
 
   /* Try to open the config file.  */
@@ -335,58 +357,15 @@
   if (! file)
     return 0;
 
-  grub_env_set_data_slot ("menu", newmenu);
-
-  while (1)
-    {
-      struct grub_script *parsed_script;
-      int startline;
-      char *cmdline;
-
-      cmdline = grub_file_getline (file);
-      if (!cmdline)
-       break;
-
-      startline = ++currline;
-
-      /* Execute the script, line for line.  */
-      parsed_script = grub_script_parse (cmdline, getline);
-
-      grub_free (cmdline);
-
-      if (! parsed_script)
-       {
-         grub_printf ("(line %d-%d)\n", startline, currline);
-         errors++;
-         continue;
-       }
-
-      /* 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);
-    }
-
+  grub_reader_loop (getline);
   grub_file_close (file);
 
-  if (errors > 0)
-    grub_wait_after_message ();
+  if (old_parser)
+    grub_parser_set_current (old_parser);
 
   return newmenu;
 }
 
-/* This starts the normal mode.  */
-void
-grub_enter_normal_mode (const char *config)
-{
-  if (grub_setjmp (grub_exit_env) == 0)
-    grub_normal_execute (config, 0, 0);
-}
-
 /* Initialize the screen.  */
 void
 grub_normal_init_page (void)
@@ -409,238 +388,8 @@
 #undef TITLE
 }
 
-static grub_err_t
-grub_dyncmd_dispatcher (struct grub_command *cmd,
-                       int argc, char **args)
-{
-  char *modname = cmd->data;
-  grub_dl_t mod;
-  grub_err_t ret;
+static int reader_nested;
 
-  mod = grub_dl_load (modname);
-  if (mod)
-    {
-      char *name;
-
-      grub_free (modname);
-      grub_dl_ref (mod);
-
-      name = (char *) cmd->name;
-      grub_unregister_command (cmd);
-
-      cmd = grub_command_find (name);
-      if (cmd)
-       ret = (cmd->func) (cmd, argc, args);
-      else
-       ret = grub_errno;
-
-      grub_free (name);
-    }
-  else
-    ret = grub_errno;
-
-  return ret;
-}
-
-/* Read the file command.lst for auto-loading.  */
-static void
-read_command_list (void)
-{
-  const char *prefix;
-  static int first_time = 1;
-
-  /* Make sure that this function does not get executed twice.  */
-  if (! first_time)
-    return;
-  first_time = 0;
-    
-  prefix = grub_env_get ("prefix");
-  if (prefix)
-    {
-      char *filename;
-
-      filename = grub_malloc (grub_strlen (prefix) + sizeof ("/command.lst"));
-      if (filename)
-       {
-         grub_file_t file;
-         
-         grub_sprintf (filename, "%s/command.lst", prefix);
-         file = grub_file_open (filename);
-         if (file)
-           {
-             char *buf = 0;
-             for (;; grub_free(buf))
-               {
-                 char *p, *name, *modname;
-                 grub_command_t cmd;
-                 int prio = 0;
-
-                 buf = grub_file_getline (file);
-
-                 if (! buf)
-                   break;
-                 
-                 name = buf;
-                 if (*name == '*')
-                   {
-                     name++;
-                     prio++;
-                   }
-
-                 if (! grub_isgraph (name[0]))
-                   continue;
-
-                 p = grub_strchr (name, ':');
-                 if (! p)
-                   continue;
-
-                 *p = '\0';
-                 while (*++p == ' ')
-                   ;
-
-                 if (! grub_isgraph (*p))
-                   continue;
-
-                 if (grub_dl_get (p))
-                   continue;
-
-                 name = grub_strdup (name);
-                 if (! name)
-                   continue;
-
-                 modname = grub_strdup (p);
-                 if (! modname)
-                   {
-                     grub_free (name);
-                     continue;
-                   }
-
-                 cmd = grub_register_command_prio (name,
-                                                   grub_dyncmd_dispatcher,
-                                                   0, "not loaded", prio);
-                 if (! cmd)
-                   {
-                     grub_free (name);
-                     grub_free (modname);
-                     continue;
-                   }
-                 cmd->flags |= GRUB_COMMAND_FLAG_DYNCMD;
-                 cmd->data = modname;
-
-                 /* Update the active flag.  */
-                 grub_command_find (name);
-               }
-
-             grub_file_close (file);
-           }
-
-         grub_free (filename);
-       }
-    }
-
-  /* Ignore errors.  */
-  grub_errno = GRUB_ERR_NONE;
-}
-
-/* The auto-loading hook for filesystems.  */
-static int
-autoload_fs_module (void)
-{
-  grub_fs_module_list_t p;
-
-  while ((p = fs_module_list) != 0)
-    {
-      if (! grub_dl_get (p->name) && grub_dl_load (p->name))
-       return 1;
-
-      fs_module_list = p->next;
-      grub_free (p->name);
-      grub_free (p);
-    }
-
-  return 0;
-}
-
-/* Read the file fs.lst for auto-loading.  */
-static void
-read_fs_list (void)
-{
-  const char *prefix;
-  static int first_time = 1;
-
-  /* Make sure that this function does not get executed twice.  */
-  if (! first_time)
-    return;
-  first_time = 0;
-  
-  prefix = grub_env_get ("prefix");
-  if (prefix)
-    {
-      char *filename;
-
-      filename = grub_malloc (grub_strlen (prefix) + sizeof ("/fs.lst"));
-      if (filename)
-       {
-         grub_file_t file;
-         
-         grub_sprintf (filename, "%s/fs.lst", prefix);
-         file = grub_file_open (filename);
-         if (file)
-           {
-             while (1)
-               {
-                 char *buf;
-                 char *p;
-                 char *q;
-                 grub_fs_module_list_t fs_mod;
-                 
-                 buf = grub_file_getline (file);
-                 if (! buf)
-                   break;
-
-                 p = buf;
-                 q = buf + grub_strlen (buf) - 1;
-
-                 /* Ignore space.  */
-                 while (grub_isspace (*p))
-                   p++;
-
-                 while (p < q && grub_isspace (*q))
-                   *q-- = '\0';
-
-                 /* If the line is empty, skip it.  */
-                 if (p >= q)
-                   continue;
-
-                 fs_mod = grub_malloc (sizeof (*fs_mod));
-                 if (! fs_mod)
-                   continue;
-
-                 fs_mod->name = grub_strdup (p);
-                 if (! fs_mod->name)
-                   {
-                     grub_free (fs_mod);
-                     continue;
-                   }
-
-                 fs_mod->next = fs_module_list;
-                 fs_module_list = fs_mod;
-               }
-
-             grub_file_close (file);
-           }
-
-         grub_free (filename);
-       }
-    }
-
-  /* Ignore errors.  */
-  grub_errno = GRUB_ERR_NONE;
-
-  /* Set the hook.  */
-  grub_fs_autoload_hook = autoload_fs_module;
-}
-
 /* Read the config file COFIG, and execute the menu interface or
    the command-line interface if BATCH is false.  */
 void
@@ -651,10 +400,13 @@
   read_command_list ();
   read_fs_list ();
   read_handler_list ();
+  grub_command_execute ("parser.sh", 0, 0);
+
+  reader_nested = nested;
   
   if (config)
     {
-      menu = read_config_file (config, nested);
+      menu = read_config_file (config);
 
       /* Ignore any error.  */
       grub_errno = GRUB_ERR_NONE;
@@ -663,40 +415,28 @@
   if (! batch)
     {
       if (menu && menu->size)
-        {
-          grub_menu_viewer_show_menu (menu, nested);
-          if (nested)
-            free_menu (menu);
-        }
-      else
-        grub_cmdline_run (nested);
+       {
+         grub_menu_viewer_show_menu (menu, nested);
+         if (nested)
+           free_menu (menu);
+       }
     }
 }
 
-static grub_err_t
-grub_cmd_rescue (struct grub_command *cmd __attribute__ ((unused)),
-                int argc __attribute__ ((unused)),
-                char **args __attribute__ ((unused)))
+/* This starts the normal mode.  */
+void
+grub_enter_normal_mode (const char *config)
 {
-  grub_longjmp (grub_exit_env, 0);
-
-  /* Never reach here.  */
-  return 0;
+  grub_normal_execute (config, 0, 0);
 }
 
-static grub_command_t cmd_normal;
-
 /* Enter normal mode from rescue mode.  */
 static grub_err_t
-grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)),
+grub_cmd_normal (struct grub_command *cmd,
                 int argc, char *argv[])
 {
-  grub_command_t cmd_rescue;
+  grub_unregister_command (cmd);
 
-  grub_unregister_command (cmd_normal);
-  cmd_rescue = grub_register_command ("rescue", grub_cmd_rescue,
-                                     0, "enter rescue mode");
-
   if (argc == 0)
     {
       /* Guess the config filename. It is necessary to make CONFIG static,
@@ -722,12 +462,77 @@
     grub_enter_normal_mode (argv[0]);
 
 quit:
-  grub_unregister_command (cmd_rescue);
-  cmd_normal = grub_register_command_prio ("normal", grub_cmd_normal,
-                                          0, "enter normal mode", 0);
   return 0;
 }
 
+void
+grub_cmdline_run (int nested)
+{
+  grub_reader_t reader = grub_reader_get_current ();
+
+  reader_nested = nested;
+  if (reader->init)
+    reader->init ();
+  grub_reader_loop (0);
+}
+
+static grub_err_t
+grub_normal_reader_init (void)
+{
+  grub_normal_init_page ();
+  grub_setcursor (1);
+
+  grub_printf ("\
+ [ Minimal BASH-like line editing is supported. For the first word, TAB\n\
+   lists possible command completions. Anywhere else TAB lists possible\n\
+   device/file completions.%s ]\n\n",
+              reader_nested ? " ESC at any time exits." : "");
+
+  return 0;
+}
+
+static char cmdline[GRUB_MAX_CMDLINE];
+
+static grub_err_t
+grub_normal_read_line (char **line, int cont)
+{
+  grub_parser_t parser = grub_parser_get_current ();
+  char prompt[8 + grub_strlen (parser->name)];
+
+  grub_sprintf (prompt, "%s:%s> ", parser->name, (cont) ? "" : "grub");
+
+  while (1)
+    {
+      cmdline[0] = 0;
+      if (grub_cmdline_get (prompt, cmdline, sizeof (cmdline), 0, 1))
+       break;
+
+      if ((reader_nested) || (cont))
+       {
+         *line = 0;
+         return grub_errno;
+       }
+    }
+
+  *line = grub_strdup (cmdline);
+  return 0;
+}
+
+static struct grub_reader grub_normal_reader =
+  {
+    .name = "normal",
+    .init = grub_normal_reader_init,
+    .read_line = grub_normal_read_line
+  };
+
+static char *
+grub_env_write_pager (struct grub_env_var *var __attribute__ ((unused)),
+                     const char *val)
+{
+  grub_set_more ((*val == '1'));
+  return grub_strdup (val);
+}
+
 GRUB_MOD_INIT(normal)
 {
   /* Normal mode shouldn't be unloaded.  */
@@ -738,9 +543,13 @@
 
   grub_set_history (GRUB_DEFAULT_HISTORY_SIZE);
 
+  grub_reader_register ("normal", &grub_normal_reader);
+  grub_reader_set_current (&grub_normal_reader);
+  grub_register_variable_hook ("pager", 0, grub_env_write_pager);
+
   /* Register a command "normal" for the rescue mode.  */
-  cmd_normal = grub_register_command ("normal", grub_cmd_normal,
-                                     0, "enter normal mode");
+  grub_register_command_prio ("normal", grub_cmd_normal,
+                             0, "Enter normal mode", 0);
 
   /* Reload terminal colors when these variables are written to.  */
   grub_register_variable_hook ("color_normal", NULL, 
grub_env_write_color_normal);
@@ -754,6 +563,8 @@
 GRUB_MOD_FINI(normal)
 {
   grub_set_history (0);
-  grub_unregister_command (cmd_normal);
+  grub_reader_unregister (&grub_normal_reader);
+  grub_register_variable_hook ("pager", 0, 0);
+  grub_fs_autoload_hook = 0;
   free_handler_list ();
 }

Modified: trunk/grub2/normal/menu.c
===================================================================
--- trunk/grub2/normal/menu.c   2009-05-02 16:55:35 UTC (rev 2157)
+++ trunk/grub2/normal/menu.c   2009-05-02 19:49:34 UTC (rev 2158)
@@ -23,8 +23,8 @@
 #include <grub/mm.h>
 #include <grub/time.h>
 #include <grub/env.h>
-#include <grub/script.h>
 #include <grub/menu_viewer.h>
+#include <grub/command.h>
 
 /* Get a menu entry by its index in the entry list.  */
 grub_menu_entry_t
@@ -123,11 +123,11 @@
 void
 grub_menu_execute_entry(grub_menu_entry_t entry)
 {
-  grub_script_execute (entry->commands);
+  grub_parser_execute ((char *) entry->sourcecode);
 
   if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ())
     /* Implicit execution of boot, only if something is loaded.  */
-    grub_command_execute ("boot", 0);
+    grub_command_execute ("boot", 0, 0);
 }
 
 /* Execute ENTRY from the menu MENU, falling back to entries specified

Modified: trunk/grub2/normal/menu_entry.c
===================================================================
--- trunk/grub2/normal/menu_entry.c     2009-05-02 16:55:35 UTC (rev 2157)
+++ trunk/grub2/normal/menu_entry.c     2009-05-02 19:49:34 UTC (rev 2158)
@@ -21,7 +21,8 @@
 #include <grub/misc.h>
 #include <grub/mm.h>
 #include <grub/loader.h>
-#include <grub/script.h>
+#include <grub/command.h>
+#include <grub/parser.h>
 
 enum update_mode
   {
@@ -970,12 +971,11 @@
 static int
 run (struct screen *screen)
 {
-  struct grub_script *parsed_script = 0;
   int currline = 0;
   char *nextline;
 
-  auto grub_err_t editor_getline (char **line);
-  grub_err_t editor_getline (char **line)
+  auto grub_err_t editor_getline (char **line, int cont);
+  grub_err_t editor_getline (char **line, int cont __attribute__ ((unused)))
     {
       struct line *linep = screen->lines + currline;
       char *p;
@@ -1008,23 +1008,14 @@
   /* Execute the script, line for line.  */
   while (currline < screen->num_lines)
     {
-      editor_getline (&nextline);
-      parsed_script = grub_script_parse (nextline, editor_getline);
-      if (parsed_script)
-       {
-         /* Execute the command(s).  */
-         grub_script_execute (parsed_script);
-         
-         /* The parsed script was executed, throw it away.  */
-         grub_script_free (parsed_script);
-       }
-      else
+      editor_getline (&nextline, 0);
+      if (grub_parser_get_current ()->parse_line (nextline, editor_getline))
        break;
     }
 
   if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ())
     /* Implicit execution of boot, only if something is loaded.  */
-    grub_command_execute ("boot", 0);
+    grub_command_execute ("boot", 0, 0);
 
   if (grub_errno != GRUB_ERR_NONE)
     {

Modified: trunk/grub2/normal/menu_text.c
===================================================================
--- trunk/grub2/normal/menu_text.c      2009-05-02 16:55:35 UTC (rev 2157)
+++ trunk/grub2/normal/menu_text.c      2009-05-02 19:49:34 UTC (rev 2158)
@@ -24,7 +24,6 @@
 #include <grub/mm.h>
 #include <grub/time.h>
 #include <grub/env.h>
-#include <grub/script.h>
 #include <grub/menu_viewer.h>
 
 /* Time to delay after displaying an error message about a default/fallback

Deleted: trunk/grub2/normal/parser.y
===================================================================
--- trunk/grub2/normal/parser.y 2009-05-02 16:55:35 UTC (rev 2157)
+++ trunk/grub2/normal/parser.y 2009-05-02 19:49:34 UTC (rev 2158)
@@ -1,238 +0,0 @@
-/* parser.y - The scripting parser.  */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-%{
-#include <grub/script.h>
-#include <grub/mm.h>
-
-#define YYFREE         grub_free
-#define YYMALLOC       grub_malloc
-#define YYLTYPE_IS_TRIVIAL      0
-#define YYENABLE_NLS   0
-
-%}
-
-%union {
-  struct grub_script_cmd *cmd;
-  struct grub_script_arglist *arglist;
-  struct grub_script_arg *arg;
-  char *string;
-}
-
-%token GRUB_PARSER_TOKEN_IF            "if"
-%token GRUB_PARSER_TOKEN_WHILE         "while"
-%token GRUB_PARSER_TOKEN_FUNCTION      "function"
-%token GRUB_PARSER_TOKEN_MENUENTRY     "menuentry"
-%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
-%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
-
-%pure-parser
-%lex-param { struct grub_parser_param *state };
-%parse-param { struct grub_parser_param *state };
-
-%%
-/* It should be possible to do this in a clean way...  */
-script_init:   { state->err = 0; } script
-                 {
-                   state->parsed = $2;
-                 }
-;
-
-script:                commands { $$ = $1; }
-               | function '\n' { $$ = 0; }
-               | menuentry '\n' { $$ = $1; }
-;
-
-delimiter:     '\n'
-               | ';'
-               | delimiter '\n'
-;
-
-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
-                 {
-                   $$ = $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
-                 {
-                   $$ = grub_script_add_arglist (state, 0, $1);
-                 }
-               | arguments argument
-                 {
-                   $$ = grub_script_add_arglist (state, $1, $2);
-                 }
-;
-
-grubcmd:       GRUB_PARSER_TOKEN_NAME arguments
-                 {
-                   $$ = grub_script_create_cmdline (state, $1, $2);
-                 }
-               | 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.  */
-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
-   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
-                 { 
-                   grub_script_lexer_ref (state->lexerstate);
-                 } newlines '{'
-                 { 
-                   /* The first part of the function was recognized.
-                      Now start recording the memory usage to store
-                      this function.  */
-                   state->func_mem = grub_script_mem_record (state);
-                 } newlines commands '}'
-                 {
-                   struct grub_script *script;
-
-                   /* All the memory usage for parsing this function
-                      was recorded.  */
-                   state->func_mem = grub_script_mem_record_stop (state,
-                                                                  
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);
-                 }
-;
-
-/* Carefully designed, together with `menuentry' so everything happens
-   just in the expected order.  */
-commandblock:  '{'
-                 {
-                   grub_script_lexer_ref (state->lexerstate);
-                 }
-                newlines commands '}'
-                  {
-                   grub_script_lexer_deref (state->lexerstate);
-                   $$ = $4;
-                 }
-;
-
-/* A menu entry.  Carefully save the memory that is allocated.  */
-menuentry:     "menuentry" arguments
-                 {
-                   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);
-                 }
-;
-
-/* The first part of the if statement.  It's used to switch the lexer
-   to a state in which it demands more tokens.  */
-if_statement:  "if" { grub_script_lexer_ref (state->lexerstate); }
-;
-
-/* The if statement.  */
-if:             if_statement commands "then" newlines commands "fi"
-                 {
-                   $$ = grub_script_create_cmdif (state, $2, $5, 0);
-                   grub_script_lexer_deref (state->lexerstate);
-                 }
-                | if_statement commands "then" newlines commands "else" 
newlines commands  "fi"
-                 {
-                   $$ = grub_script_create_cmdif (state, $2, $5, $8);
-                   grub_script_lexer_deref (state->lexerstate);
-                 }
-;

Deleted: trunk/grub2/normal/script.c
===================================================================
--- trunk/grub2/normal/script.c 2009-05-02 16:55:35 UTC (rev 2157)
+++ trunk/grub2/normal/script.c 2009-05-02 19:49:34 UTC (rev 2158)
@@ -1,348 +0,0 @@
-/* script.c -- Functions to create an in memory description of the script. */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2006,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/misc.h>
-#include <grub/script.h>
-#include <grub/parser.h>
-#include <grub/mm.h>
-
-/* It is not possible to deallocate the memory when a syntax error was
-   found.  Because of that it is required to keep track of all memory
-   allocations.  The memory is freed in case of an error, or
-   assigned to the parsed script when parsing was successful.  */
-
-/* XXX */
-
-/* In case of the normal malloc, some additional bytes are allocated
-   for this datastructure.  All reserved memory is stored in a linked
-   list so it can be easily freed.  The original memory can be found
-   from &mem.  */
-struct grub_script_mem
-{
-  struct grub_script_mem *next;
-  char mem;
-};
-
-/* Return malloc'ed memory and keep track of the allocation.  */
-void *
-grub_script_malloc (struct grub_parser_param *state, grub_size_t size)
-{
-  struct grub_script_mem *mem;
-  mem = (struct grub_script_mem *) grub_malloc (size + sizeof (*mem)
-                                               - sizeof (char));
-
-  grub_dprintf ("scripting", "malloc %p\n", mem);
-  mem->next = state->memused;
-  state->memused = mem;
-  return (void *) &mem->mem;
-}
-
-/* Free all memory described by MEM.  */
-static void
-grub_script_mem_free (struct grub_script_mem *mem)
-{
-  struct grub_script_mem *memfree;
-
-  while (mem)
-    {
-      memfree = mem->next;
-      grub_dprintf ("scripting", "free %p\n", mem);
-      grub_free (mem);
-      mem = memfree;
-    }
-}
-
-/* Start recording memory usage.  Returns the memory that should be
-   restored when calling stop.  */
-struct grub_script_mem *
-grub_script_mem_record (struct grub_parser_param *state)
-{
-  struct grub_script_mem *mem = state->memused;
-  state->memused = 0;
-
-  return mem;
-}
-
-/* Stop recording memory usage.  Restore previous recordings using
-   RESTORE.  Return the recorded memory.  */
-struct grub_script_mem *
-grub_script_mem_record_stop (struct grub_parser_param *state,
-                            struct grub_script_mem *restore)
-{
-  struct grub_script_mem *mem = state->memused;
-  state->memused = restore;
-  return mem;
-}
-
-/* Free the memory reserved for CMD and all of it's children.  */
-void
-grub_script_free (struct grub_script *script)
-{
-  if (! script)
-    return;
-  grub_script_mem_free (script->mem);
-  grub_free (script);
-}
-
-
-
-/* Extend the argument arg with a variable or string of text.  If ARG
-   is zero a new list is created.  */
-struct grub_script_arg *
-grub_script_arg_add (struct grub_parser_param *state, struct grub_script_arg 
*arg,
-                    grub_script_arg_type_t type, char *str)
-{
-  struct grub_script_arg *argpart;
-  struct grub_script_arg *ll;
-  
-  argpart = (struct grub_script_arg *) grub_script_malloc (state, sizeof 
(*arg));
-  argpart->type = type;
-  argpart->str = str;
-  argpart->next = 0;
-
-  if (! arg)
-    return argpart;
-
-  for (ll = arg; ll->next; ll = ll->next);
-  ll->next = argpart;
-      
-  return arg;
-}
-
-/* Add the argument ARG to the end of the argument list LIST.  If LIST
-   is zero, a new list will be created.  */
-struct grub_script_arglist *
-grub_script_add_arglist (struct grub_parser_param *state,
-                        struct grub_script_arglist *list, struct 
grub_script_arg *arg)
-{
-  struct grub_script_arglist *link;
-  struct grub_script_arglist *ll;
-
-  grub_dprintf ("scripting", "arglist\n");
-
-  link = (struct grub_script_arglist *) grub_script_malloc (state, sizeof 
(*link));
-  link->next = 0;
-  link->arg = arg;
-  link->argcount = 0;
-
-  if (! list)
-    {
-      link->argcount++;
-      return link;
-    }
-
-  list->argcount++;
-
-  /* Look up the last link in the chain.  */
-  for (ll = list; ll->next; ll = ll->next);
-  ll->next = link;
-
-  return list;
-}
-
-/* Create a command that describes a single command line.  CMDLINE
-   contains the name of the command that should be executed.  ARGLIST
-   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_cmdline *cmd;
-
-  grub_dprintf ("scripting", "cmdline\n");
-
-  cmd = grub_script_malloc (state, sizeof (*cmd));
-  cmd->cmd.exec = grub_script_execute_cmdline;
-  cmd->cmd.next = 0;
-  cmd->arglist = arglist;
-  cmd->cmdname = cmdname;
-
-  return (struct grub_script_cmd *) cmd;
-}
-
-/* Create a command that functions as an if statement.  If BOOL is
-   evaluated to true (the value is returned in envvar '?'), the
-   interpreter will run the command TRUE, otherwise the interpreter
-   runs the command FALSE.  */
-struct grub_script_cmd *
-grub_script_create_cmdif (struct grub_parser_param *state,
-                         struct grub_script_cmd *exec_to_evaluate,
-                         struct grub_script_cmd *exec_on_true,
-                         struct grub_script_cmd *exec_on_false)
-{
-  struct grub_script_cmdif *cmd;
-
-  grub_dprintf ("scripting", "cmdif\n");
-
-  cmd = grub_script_malloc (state, sizeof (*cmd));
-  cmd->cmd.exec = grub_script_execute_cmdif;
-  cmd->cmd.next = 0;
-  cmd->exec_to_evaluate = exec_to_evaluate;
-  cmd->exec_on_true = exec_on_true;
-  cmd->exec_on_false = exec_on_false;
-
-  return (struct grub_script_cmd *) cmd;
-}
-
-/* Create a command that adds a menu entry to the menu.  Title is an
-   argument that is parsed to generate a string that can be used as
-   the title.  The sourcecode for this entry is passed in SOURCECODE.
-   The options for this entry are passed in OPTIONS.  */
-struct grub_script_cmd *
-grub_script_create_cmdmenu (struct grub_parser_param *state,
-                           struct grub_script_arglist *arglist,
-                           char *sourcecode,
-                           int options)
-{
-  struct grub_script_cmd_menuentry *cmd;
-  int i;
-
-  /* Skip leading newlines to make the sourcecode better readable when
-     using the editor.  */
-  while (*sourcecode == '\n')
-    sourcecode++;
-
-  /* Having trailing returns can some some annoying conflicts, remove
-     them.  XXX: Can the parser be improved to handle this?  */
-  for (i = grub_strlen (sourcecode) - 1; i > 0; i--)
-    {
-      if (sourcecode[i] != '\n')
-       break;
-      sourcecode[i] = '\0';
-    }
-
-  cmd = grub_script_malloc (state, sizeof (*cmd));
-  cmd->cmd.exec = grub_script_execute_menuentry;
-  cmd->cmd.next = 0;
-  /* XXX: Check if this memory is properly freed.  */
-  cmd->sourcecode = sourcecode;
-  cmd->arglist = arglist;
-  cmd->options = options;
-
-  return (struct grub_script_cmd *) cmd;
-}
-
-/* Create a block of commands.  CMD contains the command that should
-   be added at the end of CMDBLOCK's list.  If CMDBLOCK is zero, a new
-   cmdblock will be created.  */
-struct grub_script_cmd *
-grub_script_add_cmd (struct grub_parser_param *state,
-                    struct grub_script_cmdblock *cmdblock,
-                    struct grub_script_cmd *cmd)
-{
-  grub_dprintf ("scripting", "cmdblock\n");
-
-  if (! cmd)
-    return (struct grub_script_cmd *) cmdblock;
-
-  if (! cmdblock)
-    {
-      cmdblock = (struct grub_script_cmdblock *) grub_script_malloc (state,
-                                                                    sizeof 
(*cmdblock));
-      cmdblock->cmd.exec = grub_script_execute_cmdblock;
-      cmdblock->cmd.next = 0;
-      cmdblock->cmdlist = cmd;
-      cmd->next = 0;
-    }
-  else
-    {
-      cmd->next = cmdblock->cmdlist;
-      cmdblock->cmdlist = cmd;
-    }
-
-  return (struct grub_script_cmd *) cmdblock;
-}
-
-
-
-struct grub_script *
-grub_script_create (struct grub_script_cmd *cmd, struct grub_script_mem *mem)
-{
-  struct grub_script *parsed;
-
-  parsed = grub_malloc (sizeof (*parsed));
-  if (! parsed)
-    {
-      grub_script_mem_free (mem);
-      grub_free (cmd);
-
-      return 0;
-    }
-
-  parsed->mem = mem;
-  parsed->cmd = cmd;
-
-  return parsed;
-}
-
-/* Parse the script passed in SCRIPT and return the parsed
-   datastructure that is ready to be interpreted.  */
-struct grub_script *
-grub_script_parse (char *script, grub_err_t (*getline) (char **))
-{
-  struct grub_script *parsed;
-  struct grub_script_mem *membackup;
-  struct grub_lexer_param *lexstate;
-  struct grub_parser_param *parsestate;
-
-  parsed = grub_malloc (sizeof (*parsed));
-  if (! parsed)
-    return 0;
-
-  parsestate = grub_malloc (sizeof (*parsestate));
-  if (! parsestate)
-    return 0;
-
-  parsestate->err = 0;
-  parsestate->func_mem = 0;
-  parsestate->memused = 0;
-  parsestate->parsed = 0;
-
-  /* Initialize the lexer.  */
-  lexstate = grub_script_lexer_init (script, getline);
-  if (! lexstate)
-    {
-      grub_free (parsed);
-      grub_free (parsestate);
-      return 0;
-    }
-
-  parsestate->lexerstate = lexstate;
-
-  membackup = grub_script_mem_record (parsestate);
-
-  /* Parse the script.  */
-  if (grub_script_yyparse (parsestate) || parsestate->err)
-    {
-      struct grub_script_mem *memfree;
-      memfree = grub_script_mem_record_stop (parsestate, membackup);
-      grub_script_mem_free (memfree);
-      grub_free (lexstate);
-      grub_free (parsestate);
-      return 0;
-    }
-
-  parsed->mem = grub_script_mem_record_stop (parsestate, membackup);
-  parsed->cmd = parsestate->parsed;
-
-  grub_free (lexstate);
-  grub_free (parsestate);
-
-  return parsed;
-}

Copied: trunk/grub2/script/sh/execute.c (from rev 2157, 
trunk/grub2/normal/execute.c)
===================================================================
--- trunk/grub2/script/sh/execute.c                             (rev 0)
+++ trunk/grub2/script/sh/execute.c     2009-05-02 19:49:34 UTC (rev 2158)
@@ -0,0 +1,245 @@
+/* execute.c -- Execute a GRUB script.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/env.h>
+#include <grub/script_sh.h>
+#include <grub/command.h>
+#include <grub/menu.h>
+#include <grub/lib/arg.h>
+#include <grub/normal.h>
+
+static grub_err_t
+grub_script_execute_cmd (struct grub_script_cmd *cmd)
+{
+  if (cmd == 0)
+    return 0;
+
+  return cmd->exec (cmd);
+}
+
+/* Parse ARG and return the textual representation.  Add strings are
+   concatenated and all values of the variables are filled in.  */
+static char *
+grub_script_execute_argument_to_string (struct grub_script_arg *arg)
+{
+  int size = 0;
+  char *val;
+  char *chararg;
+  struct grub_script_arg *argi;
+
+  /* First determine the size of the argument.  */
+  for (argi = arg; argi; argi = argi->next)
+    {
+      if (argi->type == 1)
+       {
+         val = grub_env_get (argi->str);
+         if (val)
+           size += grub_strlen (val);
+       }
+      else
+       size += grub_strlen (argi->str);
+    }
+
+  /* Create the argument.  */
+  chararg = grub_malloc (size + 1);
+  if (! chararg)
+    return 0;
+
+  *chararg = '\0';
+  /* First determine the size of the argument.  */
+  for (argi = arg; argi; argi = argi->next)
+    {
+      if (argi->type == 1)
+       {
+         val = grub_env_get (argi->str);
+         if (val)
+           grub_strcat (chararg, val);
+       }
+      else
+       grub_strcat (chararg, argi->str);
+    }
+
+  return chararg;
+}
+
+/* Execute a single command line.  */
+grub_err_t
+grub_script_execute_cmdline (struct grub_script_cmd *cmd)
+{
+  struct grub_script_cmdline *cmdline = (struct grub_script_cmdline *) cmd;
+  struct grub_script_arglist *arglist;
+  char **args = 0;
+  int i = 0;
+  grub_command_t grubcmd;
+  grub_err_t ret = 0;
+  int argcount = 0;
+  grub_script_function_t func = 0;
+  char errnobuf[6];
+
+  /* Lookup the command.  */
+  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)
+       {
+         /* As a last resort, try if it is an assignment.  */
+         char *assign = grub_strdup (cmdline->cmdname);
+         char *eq = grub_strchr (assign, '=');
+
+         if (eq)
+           {
+             /* Create two strings and set the variable.  */
+             *eq = '\0';
+             eq++;
+             grub_env_set (assign, eq);
+
+             /* This was set because the command was not found.  */
+             grub_errno = GRUB_ERR_NONE;
+           }
+         grub_free (assign);
+         return 0;
+       }
+    }
+
+  if (cmdline->arglist)
+    {
+      argcount = cmdline->arglist->argcount;
+
+      /* Create argv from the arguments.  */
+      args = grub_malloc (sizeof (char *) * argcount);
+      for (arglist = cmdline->arglist; arglist; arglist = arglist->next)
+       {
+         char *str;
+         str = grub_script_execute_argument_to_string (arglist->arg);
+         args[i++] = str;
+       }
+    }
+
+  /* Execute the GRUB command or function.  */
+  if (grubcmd)
+    ret = (grubcmd->func) (grubcmd, argcount, args);
+  else
+    ret = grub_script_function_call (func, argcount, args);
+
+  /* Free arguments.  */
+  for (i = 0; i < argcount; i++)
+    grub_free (args[i]);
+  grub_free (args);
+
+  grub_sprintf (errnobuf, "%d", ret);
+  grub_env_set ("?", errnobuf);
+
+  return ret;
+}
+
+/* Execute a block of one or more commands.  */
+grub_err_t
+grub_script_execute_cmdblock (struct grub_script_cmd *cmd)
+{
+  struct grub_script_cmdblock *cmdblock = (struct grub_script_cmdblock *) cmd;
+
+  /* Loop over every command and execute it.  */
+  for (cmd = cmdblock->cmdlist; cmd; cmd = cmd->next)
+    grub_script_execute_cmd (cmd);
+
+  return 0;
+}
+
+/* Execute an if statement.  */
+grub_err_t
+grub_script_execute_cmdif (struct grub_script_cmd *cmd)
+{
+  struct grub_script_cmdif *cmdif = (struct grub_script_cmdif *) cmd;
+  char *result;
+
+  /* Check if the commands results in a true or a false.  The value is
+     read from the env variable `?'.  */
+  grub_script_execute_cmd (cmdif->exec_to_evaluate);
+  result = grub_env_get ("?");
+
+  /* Execute the `if' or the `else' part depending on the value of
+     `?'.  */
+  if (result && ! grub_strcmp (result, "0"))
+    return grub_script_execute_cmd (cmdif->exec_on_true);
+  else
+    return grub_script_execute_cmd (cmdif->exec_on_false);
+}
+
+/* Execute the menu entry generate statement.  */
+grub_err_t
+grub_script_execute_menuentry (struct grub_script_cmd *cmd)
+{
+  struct grub_script_cmd_menuentry *cmd_menuentry;
+  struct grub_script_arglist *arglist;
+  char **args = 0;
+  int argcount = 0;
+  int i = 0;
+
+  cmd_menuentry = (struct grub_script_cmd_menuentry *) cmd;
+
+  if (cmd_menuentry->arglist)
+    {
+      argcount = cmd_menuentry->arglist->argcount;
+
+      /* Create argv from the arguments.  */
+      args = grub_malloc (sizeof (char *) * argcount);
+
+      if (! args)
+       {
+         return grub_errno;
+       }
+
+      for (arglist = cmd_menuentry->arglist; arglist; arglist = arglist->next)
+       {
+         char *str;
+         str = grub_script_execute_argument_to_string (arglist->arg);
+         args[i++] = str;
+       }
+    }
+
+  grub_menu_addentry (argcount, (const char **) args,
+                     cmd_menuentry->sourcecode);
+
+  /* Free arguments.  */
+  for (i = 0; i < argcount; i++)
+    grub_free (args[i]);
+  grub_free (args);
+
+  return grub_errno;
+}
+
+
+
+/* Execute any GRUB pre-parsed command or script.  */
+grub_err_t
+grub_script_execute (struct grub_script *script)
+{
+  if (script == 0)
+    return 0;
+
+  return grub_script_execute_cmd (script->cmd);
+}
+

Copied: trunk/grub2/script/sh/function.c (from rev 2157, 
trunk/grub2/normal/function.c)
===================================================================
--- trunk/grub2/script/sh/function.c                            (rev 0)
+++ trunk/grub2/script/sh/function.c    2009-05-02 19:49:34 UTC (rev 2158)
@@ -0,0 +1,125 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2007,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/misc.h>
+#include <grub/script_sh.h>
+#include <grub/parser.h>
+#include <grub/mm.h>
+
+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_t func;
+  grub_script_function_t *p;
+
+  func = (grub_script_function_t) grub_malloc (sizeof (*func));
+  if (! func)
+    return 0;
+
+  func->name = grub_strdup (functionname);
+  if (! func->name)
+    {
+      grub_free (func);
+      return 0;
+    }
+
+  func->func = cmd;
+
+  /* Keep the list sorted for simplicity.  */
+  p = &grub_script_function_list;
+  while (*p)
+    {
+      if (grub_strcmp ((*p)->name, functionname) >= 0)
+       break;
+
+      p = &((*p)->next);
+    }
+
+  /* If the function already exists, overwrite the old function.  */
+  if (*p && grub_strcmp ((*p)->name, functionname) == 0)
+    {
+      grub_script_function_t q;
+
+      q = *p;
+      grub_script_free (q->func);
+      q->func = cmd;
+      grub_free (func);
+      func = q;
+    }
+  else
+    {
+      func->next = *p;
+      *p = func;
+    }
+
+  return func;
+}
+
+void
+grub_script_function_remove (const char *name)
+{
+  grub_script_function_t *p, q;
+
+  for (p = &grub_script_function_list, q = *p; q; p = &(q->next), q = q->next)
+    if (grub_strcmp (name, q->name) == 0)
+      {
+        *p = q->next;
+       grub_free (q->name);
+       grub_script_free (q->func);
+        grub_free (q);
+        break;
+      }
+}
+
+grub_script_function_t
+grub_script_function_find (char *functionname)
+{
+  grub_script_function_t func;
+
+  for (func = grub_script_function_list; func; func = func->next)
+    if (grub_strcmp (functionname, func->name) == 0)
+      break;
+
+  if (! func)
+    grub_error (GRUB_ERR_UNKNOWN_COMMAND, "unknown command `%s'", 
functionname);
+
+  return func;
+}
+
+int
+grub_script_function_iterate (int (*iterate) (grub_script_function_t))
+{
+  grub_script_function_t func;
+
+  for (func = grub_script_function_list; func; func = func->next)
+    if (iterate (func))
+      return 1;
+
+  return 0;
+}
+
+int
+grub_script_function_call (grub_script_function_t func,
+                          int argc __attribute__((unused)),
+                          char **args __attribute__((unused)))
+{
+  /* XXX: Arguments are not supported yet.  */
+  return grub_script_execute (func->func);
+}

Copied: trunk/grub2/script/sh/lexer.c (from rev 2157, 
trunk/grub2/normal/lexer.c)
===================================================================
--- trunk/grub2/script/sh/lexer.c                               (rev 0)
+++ trunk/grub2/script/sh/lexer.c       2009-05-02 19:49:34 UTC (rev 2158)
@@ -0,0 +1,364 @@
+/* lexer.c - The scripting lexer.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/parser.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/script_sh.h>
+
+#include "grub_script.tab.h"
+
+static int
+check_varstate (grub_parser_state_t state)
+{
+  return (state == GRUB_PARSER_STATE_VARNAME
+         || state == GRUB_PARSER_STATE_VAR
+         || state == GRUB_PARSER_STATE_QVAR
+         || state == GRUB_PARSER_STATE_VARNAME2
+         || state == GRUB_PARSER_STATE_QVARNAME
+         || state == GRUB_PARSER_STATE_QVARNAME2);
+}
+
+static int
+check_textstate (grub_parser_state_t state)
+{
+  return (state == GRUB_PARSER_STATE_TEXT
+         || state == GRUB_PARSER_STATE_QUOTE
+         || state == GRUB_PARSER_STATE_DQUOTE);
+}
+
+struct grub_lexer_param *
+grub_script_lexer_init (char *script, grub_reader_getline_t getline)
+{
+  struct grub_lexer_param *param;
+
+  param = grub_malloc (sizeof (*param));
+  if (! param)
+    return 0;
+
+  param->state = GRUB_PARSER_STATE_TEXT;
+  param->getline = getline;
+  param->refs = 0;
+  param->done = 0;
+  param->newscript = 0;
+  param->script = script;
+  param->record = 0;
+  param->recording = 0;
+  param->recordpos = 0;
+  param->recordlen = 0;
+
+  return param;
+}
+
+void
+grub_script_lexer_ref (struct grub_lexer_param *state)
+{
+  state->refs++;
+}
+
+void
+grub_script_lexer_deref (struct grub_lexer_param *state)
+{
+  state->refs--;
+}
+
+/* Start recording all characters passing through the lexer.  */
+void
+grub_script_lexer_record_start (struct grub_lexer_param *state)
+{
+  state->record = 1;
+  state->recordlen = 100;
+  state->recording = grub_malloc (state->recordlen);
+  state->recordpos = 0;
+}
+
+char *
+grub_script_lexer_record_stop (struct grub_lexer_param *state)
+{
+  state->record = 0;
+
+  /* Delete the last character, it is a `}'.  */
+  if (state->recordpos > 0)
+    {
+      if (state->recording[--state->recordpos] != '}')
+       {
+         grub_printf ("Internal error while parsing menu entry");
+         for (;;); /* XXX */
+       }
+      state->recording[state->recordpos] = '\0';
+    }
+
+  return state->recording;
+}
+
+/* When recording is enabled, record the character C as the next item
+   in the character stream.  */
+static void
+recordchar (struct grub_lexer_param *state, char c)
+{
+  if (state->recordpos == state->recordlen)
+    {
+      char *old = state->recording;
+      state->recordlen += 100;
+      state->recording = grub_realloc (state->recording, state->recordlen);
+      if (! state->recording)
+       {
+         grub_free (old);
+         state->record = 0;
+       }
+    }
+  state->recording[state->recordpos++] = c;
+}
+
+/* Fetch the next character for the lexer.  */
+static void
+nextchar (struct grub_lexer_param *state)
+{
+  if (state->record)
+    recordchar (state, *state->script);
+  state->script++;
+}
+
+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;
+
+  if (state->done)
+    return 0;
+
+  if (! *state->script)
+    {
+      /* 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';
+       }
+    }
+
+  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.  */
+      if (newstate == GRUB_PARSER_STATE_TEXT)
+       {
+         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");
+                     return ' ';
+                   }
+                 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;
+             }
+           }
+       }
+
+      /* 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;
+             *(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->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;
+    }
+  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;
+    }
+}
+
+void
+grub_script_yyerror (struct grub_parser_param *lex __attribute__ ((unused)),
+                    char const *err)
+{
+  grub_printf ("%s\n", err);
+}

Copied: trunk/grub2/script/sh/main.c (from rev 2157, 
trunk/grub2/normal/command.c)
===================================================================
--- trunk/grub2/script/sh/main.c                                (rev 0)
+++ trunk/grub2/script/sh/main.c        2009-05-02 19:49:34 UTC (rev 2158)
@@ -0,0 +1,58 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/parser.h>
+#include <grub/script_sh.h>
+
+static grub_err_t
+grub_normal_parse_line (char *line, grub_reader_getline_t getline)
+{
+  struct grub_script *parsed_script;
+
+  /* Parse the script.  */
+  parsed_script = grub_script_parse (line, getline);
+
+  if (parsed_script)
+    {
+      /* Execute the command(s).  */
+      grub_script_execute (parsed_script);
+
+      /* The parsed script was executed, throw it away.  */
+      grub_script_free (parsed_script);
+    }
+
+  return grub_errno;
+}
+
+static struct grub_parser grub_sh_parser =
+  {
+    .name = "sh",
+    .parse_line = grub_normal_parse_line
+  };
+
+GRUB_MOD_INIT(sh)
+{
+  (void) mod;
+  grub_parser_register ("sh", &grub_sh_parser);
+}
+
+GRUB_MOD_FINI(sh)
+{
+  grub_parser_unregister (&grub_sh_parser);
+}

Copied: trunk/grub2/script/sh/parser.y (from rev 2157, 
trunk/grub2/normal/parser.y)
===================================================================
--- trunk/grub2/script/sh/parser.y                              (rev 0)
+++ trunk/grub2/script/sh/parser.y      2009-05-02 19:49:34 UTC (rev 2158)
@@ -0,0 +1,238 @@
+/* parser.y - The scripting parser.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+%{
+#include <grub/script_sh.h>
+#include <grub/mm.h>
+
+#define YYFREE         grub_free
+#define YYMALLOC       grub_malloc
+#define YYLTYPE_IS_TRIVIAL      0
+#define YYENABLE_NLS   0
+
+%}
+
+%union {
+  struct grub_script_cmd *cmd;
+  struct grub_script_arglist *arglist;
+  struct grub_script_arg *arg;
+  char *string;
+}
+

@@ Diff output truncated at 153600 characters. @@




reply via email to

[Prev in Thread] Current Thread [Next in Thread]