grub-devel
[Top][All Lists]
Advanced

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

[Patch] Scripting engine


From: Vladimir Serbinenko
Subject: [Patch] Scripting engine
Date: Wed, 24 Aug 2005 11:36:36 +0200
User-agent: Mozilla Thunderbird 1.0.2-1.3.2 (X11/20050324)

I wrote the preciew version of scripting engine. I'll add some comments
soonly.
Parser parses everytime one command because the commands could be
entered from
commandline. Bison converts in kind of pseudocode. Arithmethic support
will be done
by separate parser because arithmetic parse is very different form bash one.
Patch is attached. The next thing I'll do is adding entry handling and
changing menu
parser to the call of scripting engine. It would be good if then it
could be incorporated
to CVS because it would be easy to developpe and debug.

                                                                        
            Vladimir


diff -urN ./grub2_3/conf/i386-pc.mk ./grub2_4/conf/i386-pc.mk
--- ./grub2_3/conf/i386-pc.mk   2005-08-24 11:25:39.000000000 +0200
+++ ./grub2_4/conf/i386-pc.mk   2005-08-24 11:23:42.000000000 +0200
@@ -686,11 +686,11 @@
        partmap/amiga.c partmap/apple.c partmap/pc.c partmap/sun.c      \
        util/console.c util/grub-emu.c util/misc.c                      \
        util/i386/pc/biosdisk.c util/i386/pc/getroot.c                  \
-       util/i386/pc/misc.c
-CLEANFILES += grub-emu grub_emu-commands_boot.o grub_emu-commands_cat.o 
grub_emu-commands_hexcat.o grub_emu-commands_cmp.o 
grub_emu-commands_configfile.o grub_emu-commands_default.o 
grub_emu-commands_help.o grub_emu-commands_terminal.o grub_emu-commands_ls.o 
grub_emu-commands_timeout.o grub_emu-commands_i386_pc_halt.o 
grub_emu-commands_i386_pc_reboot.o grub_emu-disk_loopback.o grub_emu-fs_ext2.o 
grub_emu-fs_fat.o grub_emu-fs_fshelp.o grub_emu-fs_hfs.o grub_emu-fs_iso9660.o 
grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_ufs.o grub_emu-kern_device.o 
grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_env.o grub_emu-kern_err.o 
grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-kern_loader.o 
grub_emu-kern_main.o grub_emu-kern_misc.o grub_emu-kern_partition.o 
grub_emu-kern_rescue.o grub_emu-kern_term.o grub_emu-normal_arg.o 
grub_emu-normal_cmdline.o grub_emu-normal_command.o grub_emu-normal_context.o 
grub_emu-normal_main.o grub_emu-normal_menu.o grub_emu-normal_menu_entry.o 
grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_pc.o 
grub_emu-partmap_sun.o grub_emu-util_console.o grub_emu-util_grub_emu.o 
grub_emu-util_misc.o grub_emu-util_i386_pc_biosdisk.o 
grub_emu-util_i386_pc_getroot.o grub_emu-util_i386_pc_misc.o
-MOSTLYCLEANFILES += grub_emu-commands_boot.d grub_emu-commands_cat.d 
grub_emu-commands_hexcat.d grub_emu-commands_cmp.d 
grub_emu-commands_configfile.d grub_emu-commands_default.d 
grub_emu-commands_help.d grub_emu-commands_terminal.d grub_emu-commands_ls.d 
grub_emu-commands_timeout.d grub_emu-commands_i386_pc_halt.d 
grub_emu-commands_i386_pc_reboot.d grub_emu-disk_loopback.d grub_emu-fs_ext2.d 
grub_emu-fs_fat.d grub_emu-fs_fshelp.d grub_emu-fs_hfs.d grub_emu-fs_iso9660.d 
grub_emu-fs_jfs.d grub_emu-fs_minix.d grub_emu-fs_ufs.d grub_emu-kern_device.d 
grub_emu-kern_disk.d grub_emu-kern_dl.d grub_emu-kern_env.d grub_emu-kern_err.d 
grub_emu-kern_file.d grub_emu-kern_fs.d grub_emu-kern_loader.d 
grub_emu-kern_main.d grub_emu-kern_misc.d grub_emu-kern_partition.d 
grub_emu-kern_rescue.d grub_emu-kern_term.d grub_emu-normal_arg.d 
grub_emu-normal_cmdline.d grub_emu-normal_command.d grub_emu-normal_context.d 
grub_emu-normal_main.d grub_emu-normal_menu.d grub_emu-normal_menu_entry.d 
grub_emu-partmap_amiga.d grub_emu-partmap_apple.d grub_emu-partmap_pc.d 
grub_emu-partmap_sun.d grub_emu-util_console.d grub_emu-util_grub_emu.d 
grub_emu-util_misc.d grub_emu-util_i386_pc_biosdisk.d 
grub_emu-util_i386_pc_getroot.d grub_emu-util_i386_pc_misc.d
+       util/i386/pc/misc.c normal/parser.c
+CLEANFILES += grub-emu grub_emu-commands_boot.o grub_emu-commands_cat.o 
grub_emu-commands_hexcat.o grub_emu-commands_cmp.o 
grub_emu-commands_configfile.o grub_emu-commands_default.o 
grub_emu-commands_help.o grub_emu-commands_terminal.o grub_emu-commands_ls.o 
grub_emu-commands_timeout.o grub_emu-commands_i386_pc_halt.o 
grub_emu-commands_i386_pc_reboot.o grub_emu-disk_loopback.o grub_emu-fs_ext2.o 
grub_emu-fs_fat.o grub_emu-fs_fshelp.o grub_emu-fs_hfs.o grub_emu-fs_iso9660.o 
grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_ufs.o grub_emu-kern_device.o 
grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_env.o grub_emu-kern_err.o 
grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-kern_loader.o 
grub_emu-kern_main.o grub_emu-kern_misc.o grub_emu-kern_partition.o 
grub_emu-kern_rescue.o grub_emu-kern_term.o grub_emu-normal_arg.o 
grub_emu-normal_cmdline.o grub_emu-normal_command.o grub_emu-normal_context.o 
grub_emu-normal_main.o grub_emu-normal_menu.o grub_emu-normal_menu_entry.o 
grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_pc.o 
grub_emu-partmap_sun.o grub_emu-util_console.o grub_emu-util_grub_emu.o 
grub_emu-util_misc.o grub_emu-util_i386_pc_biosdisk.o 
grub_emu-util_i386_pc_getroot.o grub_emu-util_i386_pc_misc.o 
grub_emu-normal_parser.o
+MOSTLYCLEANFILES += grub_emu-commands_boot.d grub_emu-commands_cat.d 
grub_emu-commands_hexcat.d grub_emu-commands_cmp.d 
grub_emu-commands_configfile.d grub_emu-commands_default.d 
grub_emu-commands_help.d grub_emu-commands_terminal.d grub_emu-commands_ls.d 
grub_emu-commands_timeout.d grub_emu-commands_i386_pc_halt.d 
grub_emu-commands_i386_pc_reboot.d grub_emu-disk_loopback.d grub_emu-fs_ext2.d 
grub_emu-fs_fat.d grub_emu-fs_fshelp.d grub_emu-fs_hfs.d grub_emu-fs_iso9660.d 
grub_emu-fs_jfs.d grub_emu-fs_minix.d grub_emu-fs_ufs.d grub_emu-kern_device.d 
grub_emu-kern_disk.d grub_emu-kern_dl.d grub_emu-kern_env.d grub_emu-kern_err.d 
grub_emu-kern_file.d grub_emu-kern_fs.d grub_emu-kern_loader.d 
grub_emu-kern_main.d grub_emu-kern_misc.d grub_emu-kern_partition.d 
grub_emu-kern_rescue.d grub_emu-kern_term.d grub_emu-normal_arg.d 
grub_emu-normal_cmdline.d grub_emu-normal_command.d grub_emu-normal_context.d 
grub_emu-normal_main.d grub_emu-normal_menu.d grub_emu-normal_menu_entry.d 
grub_emu-partmap_amiga.d grub_emu-partmap_apple.d grub_emu-partmap_pc.d 
grub_emu-partmap_sun.d grub_emu-util_console.d grub_emu-util_grub_emu.d 
grub_emu-util_misc.d grub_emu-util_i386_pc_biosdisk.d 
grub_emu-util_i386_pc_getroot.d grub_emu-util_i386_pc_misc.d 
grub_emu-normal_parser.d
 
-grub-emu: grub_emu-commands_boot.o grub_emu-commands_cat.o 
grub_emu-commands_hexcat.o grub_emu-commands_cmp.o 
grub_emu-commands_configfile.o grub_emu-commands_default.o 
grub_emu-commands_help.o grub_emu-commands_terminal.o grub_emu-commands_ls.o 
grub_emu-commands_timeout.o grub_emu-commands_i386_pc_halt.o 
grub_emu-commands_i386_pc_reboot.o grub_emu-disk_loopback.o grub_emu-fs_ext2.o 
grub_emu-fs_fat.o grub_emu-fs_fshelp.o grub_emu-fs_hfs.o grub_emu-fs_iso9660.o 
grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_ufs.o grub_emu-kern_device.o 
grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_env.o grub_emu-kern_err.o 
grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-kern_loader.o 
grub_emu-kern_main.o grub_emu-kern_misc.o grub_emu-kern_partition.o 
grub_emu-kern_rescue.o grub_emu-kern_term.o grub_emu-normal_arg.o 
grub_emu-normal_cmdline.o grub_emu-normal_command.o grub_emu-normal_context.o 
grub_emu-normal_main.o grub_emu-normal_menu.o grub_emu-normal_menu_entry.o 
grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_pc.o 
grub_emu-partmap_sun.o grub_emu-util_console.o grub_emu-util_grub_emu.o 
grub_emu-util_misc.o grub_emu-util_i386_pc_biosdisk.o 
grub_emu-util_i386_pc_getroot.o grub_emu-util_i386_pc_misc.o
+grub-emu: grub_emu-commands_boot.o grub_emu-commands_cat.o 
grub_emu-commands_hexcat.o grub_emu-commands_cmp.o 
grub_emu-commands_configfile.o grub_emu-commands_default.o 
grub_emu-commands_help.o grub_emu-commands_terminal.o grub_emu-commands_ls.o 
grub_emu-commands_timeout.o grub_emu-commands_i386_pc_halt.o 
grub_emu-commands_i386_pc_reboot.o grub_emu-disk_loopback.o grub_emu-fs_ext2.o 
grub_emu-fs_fat.o grub_emu-fs_fshelp.o grub_emu-fs_hfs.o grub_emu-fs_iso9660.o 
grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_ufs.o grub_emu-kern_device.o 
grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_env.o grub_emu-kern_err.o 
grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-kern_loader.o 
grub_emu-kern_main.o grub_emu-kern_misc.o grub_emu-kern_partition.o 
grub_emu-kern_rescue.o grub_emu-kern_term.o grub_emu-normal_arg.o 
grub_emu-normal_cmdline.o grub_emu-normal_command.o grub_emu-normal_context.o 
grub_emu-normal_main.o grub_emu-normal_menu.o grub_emu-normal_menu_entry.o 
grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_pc.o 
grub_emu-partmap_sun.o grub_emu-util_console.o grub_emu-util_grub_emu.o 
grub_emu-util_misc.o grub_emu-util_i386_pc_biosdisk.o 
grub_emu-util_i386_pc_getroot.o grub_emu-util_i386_pc_misc.o 
grub_emu-normal_parser.o
        $(BUILD_CC) -o $@ $^ $(BUILD_LDFLAGS) $(grub_emu_LDFLAGS)
 
 grub_emu-commands_boot.o: commands/boot.c
@@ -1101,6 +1101,14 @@
 
 -include grub_emu-util_i386_pc_misc.d
 
+grub_emu-normal_parser.o: normal/parser.c
+       $(BUILD_CC) -Inormal -I$(srcdir)/normal $(BUILD_CPPFLAGS) 
$(BUILD_CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -c -o $@ $<
+
+grub_emu-normal_parser.d: normal/parser.c
+       set -e;           $(BUILD_CC) -Inormal -I$(srcdir)/normal 
$(BUILD_CPPFLAGS) $(BUILD_CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -M $<        
| sed 's,parser\.o[ :]*,grub_emu-normal_parser.o $@ : ,g' > $@;         [ -s $@ 
] || rm -f $@
+
+-include grub_emu-normal_parser.d
+
 
 grub_emu_LDFLAGS = $(LIBCURSES)
 
@@ -1699,9 +1707,9 @@
 # For normal.mod.
 normal_mod_SOURCES = normal/arg.c normal/cmdline.c normal/command.c    \
        normal/context.c normal/main.c normal/menu.c                    \
-       normal/menu_entry.c normal/i386/setjmp.S
-CLEANFILES += normal.mod mod-normal.o mod-normal.c pre-normal.o 
normal_mod-normal_arg.o normal_mod-normal_cmdline.o normal_mod-normal_command.o 
normal_mod-normal_context.o normal_mod-normal_main.o normal_mod-normal_menu.o 
normal_mod-normal_menu_entry.o normal_mod-normal_i386_setjmp.o def-normal.lst 
und-normal.lst
-MOSTLYCLEANFILES += normal_mod-normal_arg.d normal_mod-normal_cmdline.d 
normal_mod-normal_command.d normal_mod-normal_context.d 
normal_mod-normal_main.d normal_mod-normal_menu.d 
normal_mod-normal_menu_entry.d normal_mod-normal_i386_setjmp.d
+       normal/menu_entry.c normal/i386/setjmp.S normal/parser.c
+CLEANFILES += normal.mod mod-normal.o mod-normal.c pre-normal.o 
normal_mod-normal_arg.o normal_mod-normal_cmdline.o normal_mod-normal_command.o 
normal_mod-normal_context.o normal_mod-normal_main.o normal_mod-normal_menu.o 
normal_mod-normal_menu_entry.o normal_mod-normal_i386_setjmp.o 
normal_mod-normal_parser.o def-normal.lst und-normal.lst
+MOSTLYCLEANFILES += normal_mod-normal_arg.d normal_mod-normal_cmdline.d 
normal_mod-normal_command.d normal_mod-normal_context.d 
normal_mod-normal_main.d normal_mod-normal_menu.d 
normal_mod-normal_menu_entry.d normal_mod-normal_i386_setjmp.d 
normal_mod-normal_parser.d
 DEFSYMFILES += def-normal.lst
 UNDSYMFILES += und-normal.lst
 
@@ -1710,7 +1718,7 @@
        $(LD) -r -d -o $@ $^
        $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -R .note -R 
.comment $@
 
-pre-normal.o: normal_mod-normal_arg.o normal_mod-normal_cmdline.o 
normal_mod-normal_command.o normal_mod-normal_context.o 
normal_mod-normal_main.o normal_mod-normal_menu.o 
normal_mod-normal_menu_entry.o normal_mod-normal_i386_setjmp.o
+pre-normal.o: normal_mod-normal_arg.o normal_mod-normal_cmdline.o 
normal_mod-normal_command.o normal_mod-normal_context.o 
normal_mod-normal_main.o normal_mod-normal_menu.o 
normal_mod-normal_menu_entry.o normal_mod-normal_i386_setjmp.o 
normal_mod-normal_parser.o
        -rm -f $@
        $(LD) -r -d -o $@ $^
 
@@ -1879,6 +1887,25 @@
        set -e;           $(CC) -Inormal/i386 -I$(srcdir)/normal/i386 
$(CPPFLAGS) $(ASFLAGS) $(normal_mod_ASFLAGS) -E $<          | sh 
$(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1)
 
 
+normal_mod-normal_parser.o: normal/parser.c
+       $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) 
$(normal_mod_CFLAGS) -c -o $@ $<
+
+normal_mod-normal_parser.d: normal/parser.c
+       set -e;           $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) 
$(CFLAGS) $(normal_mod_CFLAGS) -M $<      | sed 's,parser\.o[ 
:]*,normal_mod-normal_parser.o $@ : ,g' > $@;       [ -s $@ ] || rm -f $@
+
+-include normal_mod-normal_parser.d
+
+CLEANFILES += cmd-parser.lst fs-parser.lst
+COMMANDFILES += cmd-parser.lst
+FSFILES += fs-parser.lst
+
+cmd-parser.lst: normal/parser.c gencmdlist.sh
+       set -e;           $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) 
$(CFLAGS) $(normal_mod_CFLAGS) -E $<      | sh $(srcdir)/gencmdlist.sh normal > 
$@ || (rm -f $@; exit 1)
+
+fs-parser.lst: normal/parser.c genfslist.sh
+       set -e;           $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) 
$(CFLAGS) $(normal_mod_CFLAGS) -E $<      | sh $(srcdir)/genfslist.sh normal > 
$@ || (rm -f $@; exit 1)
+
+
 normal_mod_CFLAGS = $(COMMON_CFLAGS)
 normal_mod_ASFLAGS = $(COMMON_ASFLAGS)
 
diff -urN ./grub2_3/conf/i386-pc.rmk ./grub2_4/conf/i386-pc.rmk
--- ./grub2_3/conf/i386-pc.rmk  2005-08-08 15:08:59.000000000 +0200
+++ ./grub2_4/conf/i386-pc.rmk  2005-08-20 16:37:09.000000000 +0200
@@ -90,7 +90,7 @@
        partmap/amiga.c partmap/apple.c partmap/pc.c partmap/sun.c      \
        util/console.c util/grub-emu.c util/misc.c                      \
        util/i386/pc/biosdisk.c util/i386/pc/getroot.c                  \
-       util/i386/pc/misc.c
+       util/i386/pc/misc.c normal/parser.c
 
 grub_emu_LDFLAGS = $(LIBCURSES)
 
@@ -163,7 +163,7 @@
 # For normal.mod.
 normal_mod_SOURCES = normal/arg.c normal/cmdline.c normal/command.c    \
        normal/context.c normal/main.c normal/menu.c                    \
-       normal/menu_entry.c normal/i386/setjmp.S
+       normal/menu_entry.c normal/i386/setjmp.S normal/parser.c
 normal_mod_CFLAGS = $(COMMON_CFLAGS)
 normal_mod_ASFLAGS = $(COMMON_ASFLAGS)
 
diff -urN ./grub2_3/conf/powerpc-ieee1275.mk ./grub2_4/conf/powerpc-ieee1275.mk
--- ./grub2_3/conf/powerpc-ieee1275.mk  2005-08-24 11:25:39.000000000 +0200
+++ ./grub2_4/conf/powerpc-ieee1275.mk  2005-08-24 11:23:42.000000000 +0200
@@ -78,11 +78,11 @@
        partmap/amiga.c partmap/apple.c partmap/pc.c partmap/sun.c      \
        util/console.c util/grub-emu.c util/misc.c                      \
        util/i386/pc/biosdisk.c util/i386/pc/getroot.c                  \
-       util/powerpc/ieee1275/misc.c
-CLEANFILES += grub-emu grub_emu-commands_boot.o grub_emu-commands_cat.o 
grub_emu-commands_cmp.o grub_emu-commands_configfile.o 
grub_emu-commands_default.o grub_emu-commands_help.o 
grub_emu-commands_terminal.o grub_emu-commands_ls.o grub_emu-commands_timeout.o 
grub_emu-commands_ieee1275_halt.o grub_emu-commands_ieee1275_reboot.o 
grub_emu-disk_loopback.o grub_emu-commands_hexcat.o grub_emu-fs_ext2.o 
grub_emu-fs_fat.o grub_emu-fs_fshelp.o grub_emu-fs_hfs.o grub_emu-fs_iso9660.o 
grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_ufs.o grub_emu-kern_device.o 
grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_env.o grub_emu-kern_err.o 
grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-kern_loader.o 
grub_emu-kern_main.o grub_emu-kern_misc.o grub_emu-kern_partition.o 
grub_emu-kern_rescue.o grub_emu-kern_term.o grub_emu-normal_arg.o 
grub_emu-normal_cmdline.o grub_emu-normal_command.o grub_emu-normal_context.o 
grub_emu-normal_main.o grub_emu-normal_menu.o grub_emu-normal_menu_entry.o 
grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_pc.o 
grub_emu-partmap_sun.o grub_emu-util_console.o grub_emu-util_grub_emu.o 
grub_emu-util_misc.o grub_emu-util_i386_pc_biosdisk.o 
grub_emu-util_i386_pc_getroot.o grub_emu-util_powerpc_ieee1275_misc.o
-MOSTLYCLEANFILES += grub_emu-commands_boot.d grub_emu-commands_cat.d 
grub_emu-commands_cmp.d grub_emu-commands_configfile.d 
grub_emu-commands_default.d grub_emu-commands_help.d 
grub_emu-commands_terminal.d grub_emu-commands_ls.d grub_emu-commands_timeout.d 
grub_emu-commands_ieee1275_halt.d grub_emu-commands_ieee1275_reboot.d 
grub_emu-disk_loopback.d grub_emu-commands_hexcat.d grub_emu-fs_ext2.d 
grub_emu-fs_fat.d grub_emu-fs_fshelp.d grub_emu-fs_hfs.d grub_emu-fs_iso9660.d 
grub_emu-fs_jfs.d grub_emu-fs_minix.d grub_emu-fs_ufs.d grub_emu-kern_device.d 
grub_emu-kern_disk.d grub_emu-kern_dl.d grub_emu-kern_env.d grub_emu-kern_err.d 
grub_emu-kern_file.d grub_emu-kern_fs.d grub_emu-kern_loader.d 
grub_emu-kern_main.d grub_emu-kern_misc.d grub_emu-kern_partition.d 
grub_emu-kern_rescue.d grub_emu-kern_term.d grub_emu-normal_arg.d 
grub_emu-normal_cmdline.d grub_emu-normal_command.d grub_emu-normal_context.d 
grub_emu-normal_main.d grub_emu-normal_menu.d grub_emu-normal_menu_entry.d 
grub_emu-partmap_amiga.d grub_emu-partmap_apple.d grub_emu-partmap_pc.d 
grub_emu-partmap_sun.d grub_emu-util_console.d grub_emu-util_grub_emu.d 
grub_emu-util_misc.d grub_emu-util_i386_pc_biosdisk.d 
grub_emu-util_i386_pc_getroot.d grub_emu-util_powerpc_ieee1275_misc.d
+       util/powerpc/ieee1275/misc.c normal/parser.c
+CLEANFILES += grub-emu grub_emu-commands_boot.o grub_emu-commands_cat.o 
grub_emu-commands_cmp.o grub_emu-commands_configfile.o 
grub_emu-commands_default.o grub_emu-commands_help.o 
grub_emu-commands_terminal.o grub_emu-commands_ls.o grub_emu-commands_timeout.o 
grub_emu-commands_ieee1275_halt.o grub_emu-commands_ieee1275_reboot.o 
grub_emu-disk_loopback.o grub_emu-commands_hexcat.o grub_emu-fs_ext2.o 
grub_emu-fs_fat.o grub_emu-fs_fshelp.o grub_emu-fs_hfs.o grub_emu-fs_iso9660.o 
grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_ufs.o grub_emu-kern_device.o 
grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_env.o grub_emu-kern_err.o 
grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-kern_loader.o 
grub_emu-kern_main.o grub_emu-kern_misc.o grub_emu-kern_partition.o 
grub_emu-kern_rescue.o grub_emu-kern_term.o grub_emu-normal_arg.o 
grub_emu-normal_cmdline.o grub_emu-normal_command.o grub_emu-normal_context.o 
grub_emu-normal_main.o grub_emu-normal_menu.o grub_emu-normal_menu_entry.o 
grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_pc.o 
grub_emu-partmap_sun.o grub_emu-util_console.o grub_emu-util_grub_emu.o 
grub_emu-util_misc.o grub_emu-util_i386_pc_biosdisk.o 
grub_emu-util_i386_pc_getroot.o grub_emu-util_powerpc_ieee1275_misc.o 
grub_emu-normal_parser.o
+MOSTLYCLEANFILES += grub_emu-commands_boot.d grub_emu-commands_cat.d 
grub_emu-commands_cmp.d grub_emu-commands_configfile.d 
grub_emu-commands_default.d grub_emu-commands_help.d 
grub_emu-commands_terminal.d grub_emu-commands_ls.d grub_emu-commands_timeout.d 
grub_emu-commands_ieee1275_halt.d grub_emu-commands_ieee1275_reboot.d 
grub_emu-disk_loopback.d grub_emu-commands_hexcat.d grub_emu-fs_ext2.d 
grub_emu-fs_fat.d grub_emu-fs_fshelp.d grub_emu-fs_hfs.d grub_emu-fs_iso9660.d 
grub_emu-fs_jfs.d grub_emu-fs_minix.d grub_emu-fs_ufs.d grub_emu-kern_device.d 
grub_emu-kern_disk.d grub_emu-kern_dl.d grub_emu-kern_env.d grub_emu-kern_err.d 
grub_emu-kern_file.d grub_emu-kern_fs.d grub_emu-kern_loader.d 
grub_emu-kern_main.d grub_emu-kern_misc.d grub_emu-kern_partition.d 
grub_emu-kern_rescue.d grub_emu-kern_term.d grub_emu-normal_arg.d 
grub_emu-normal_cmdline.d grub_emu-normal_command.d grub_emu-normal_context.d 
grub_emu-normal_main.d grub_emu-normal_menu.d grub_emu-normal_menu_entry.d 
grub_emu-partmap_amiga.d grub_emu-partmap_apple.d grub_emu-partmap_pc.d 
grub_emu-partmap_sun.d grub_emu-util_console.d grub_emu-util_grub_emu.d 
grub_emu-util_misc.d grub_emu-util_i386_pc_biosdisk.d 
grub_emu-util_i386_pc_getroot.d grub_emu-util_powerpc_ieee1275_misc.d 
grub_emu-normal_parser.d
 
-grub-emu: grub_emu-commands_boot.o grub_emu-commands_cat.o 
grub_emu-commands_cmp.o grub_emu-commands_configfile.o 
grub_emu-commands_default.o grub_emu-commands_help.o 
grub_emu-commands_terminal.o grub_emu-commands_ls.o grub_emu-commands_timeout.o 
grub_emu-commands_ieee1275_halt.o grub_emu-commands_ieee1275_reboot.o 
grub_emu-disk_loopback.o grub_emu-commands_hexcat.o grub_emu-fs_ext2.o 
grub_emu-fs_fat.o grub_emu-fs_fshelp.o grub_emu-fs_hfs.o grub_emu-fs_iso9660.o 
grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_ufs.o grub_emu-kern_device.o 
grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_env.o grub_emu-kern_err.o 
grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-kern_loader.o 
grub_emu-kern_main.o grub_emu-kern_misc.o grub_emu-kern_partition.o 
grub_emu-kern_rescue.o grub_emu-kern_term.o grub_emu-normal_arg.o 
grub_emu-normal_cmdline.o grub_emu-normal_command.o grub_emu-normal_context.o 
grub_emu-normal_main.o grub_emu-normal_menu.o grub_emu-normal_menu_entry.o 
grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_pc.o 
grub_emu-partmap_sun.o grub_emu-util_console.o grub_emu-util_grub_emu.o 
grub_emu-util_misc.o grub_emu-util_i386_pc_biosdisk.o 
grub_emu-util_i386_pc_getroot.o grub_emu-util_powerpc_ieee1275_misc.o
+grub-emu: grub_emu-commands_boot.o grub_emu-commands_cat.o 
grub_emu-commands_cmp.o grub_emu-commands_configfile.o 
grub_emu-commands_default.o grub_emu-commands_help.o 
grub_emu-commands_terminal.o grub_emu-commands_ls.o grub_emu-commands_timeout.o 
grub_emu-commands_ieee1275_halt.o grub_emu-commands_ieee1275_reboot.o 
grub_emu-disk_loopback.o grub_emu-commands_hexcat.o grub_emu-fs_ext2.o 
grub_emu-fs_fat.o grub_emu-fs_fshelp.o grub_emu-fs_hfs.o grub_emu-fs_iso9660.o 
grub_emu-fs_jfs.o grub_emu-fs_minix.o grub_emu-fs_ufs.o grub_emu-kern_device.o 
grub_emu-kern_disk.o grub_emu-kern_dl.o grub_emu-kern_env.o grub_emu-kern_err.o 
grub_emu-kern_file.o grub_emu-kern_fs.o grub_emu-kern_loader.o 
grub_emu-kern_main.o grub_emu-kern_misc.o grub_emu-kern_partition.o 
grub_emu-kern_rescue.o grub_emu-kern_term.o grub_emu-normal_arg.o 
grub_emu-normal_cmdline.o grub_emu-normal_command.o grub_emu-normal_context.o 
grub_emu-normal_main.o grub_emu-normal_menu.o grub_emu-normal_menu_entry.o 
grub_emu-partmap_amiga.o grub_emu-partmap_apple.o grub_emu-partmap_pc.o 
grub_emu-partmap_sun.o grub_emu-util_console.o grub_emu-util_grub_emu.o 
grub_emu-util_misc.o grub_emu-util_i386_pc_biosdisk.o 
grub_emu-util_i386_pc_getroot.o grub_emu-util_powerpc_ieee1275_misc.o 
grub_emu-normal_parser.o
        $(BUILD_CC) -o $@ $^ $(BUILD_LDFLAGS) $(grub_emu_LDFLAGS)
 
 grub_emu-commands_boot.o: commands/boot.c
@@ -493,6 +493,14 @@
 
 -include grub_emu-util_powerpc_ieee1275_misc.d
 
+grub_emu-normal_parser.o: normal/parser.c
+       $(BUILD_CC) -Inormal -I$(srcdir)/normal $(BUILD_CPPFLAGS) 
$(BUILD_CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -c -o $@ $<
+
+grub_emu-normal_parser.d: normal/parser.c
+       set -e;           $(BUILD_CC) -Inormal -I$(srcdir)/normal 
$(BUILD_CPPFLAGS) $(BUILD_CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -M $<        
| sed 's,parser\.o[ :]*,grub_emu-normal_parser.o $@ : ,g' > $@;         [ -s $@ 
] || rm -f $@
+
+-include grub_emu-normal_parser.d
+
 
 grub_emu_LDFLAGS = $(LIBCURSES)
 
@@ -1189,9 +1197,9 @@
 normal_mod_SOURCES = normal/arg.c normal/cmdline.c normal/command.c    \
        normal/context.c normal/main.c normal/menu.c                    \
        normal/menu_entry.c                                             \
-       normal/powerpc/setjmp.S
-CLEANFILES += normal.mod mod-normal.o mod-normal.c pre-normal.o 
normal_mod-normal_arg.o normal_mod-normal_cmdline.o normal_mod-normal_command.o 
normal_mod-normal_context.o normal_mod-normal_main.o normal_mod-normal_menu.o 
normal_mod-normal_menu_entry.o normal_mod-normal_powerpc_setjmp.o 
def-normal.lst und-normal.lst
-MOSTLYCLEANFILES += normal_mod-normal_arg.d normal_mod-normal_cmdline.d 
normal_mod-normal_command.d normal_mod-normal_context.d 
normal_mod-normal_main.d normal_mod-normal_menu.d 
normal_mod-normal_menu_entry.d normal_mod-normal_powerpc_setjmp.d
+       normal/powerpc/setjmp.S normal/parser.c
+CLEANFILES += normal.mod mod-normal.o mod-normal.c pre-normal.o 
normal_mod-normal_arg.o normal_mod-normal_cmdline.o normal_mod-normal_command.o 
normal_mod-normal_context.o normal_mod-normal_main.o normal_mod-normal_menu.o 
normal_mod-normal_menu_entry.o normal_mod-normal_powerpc_setjmp.o 
normal_mod-normal_parser.o def-normal.lst und-normal.lst
+MOSTLYCLEANFILES += normal_mod-normal_arg.d normal_mod-normal_cmdline.d 
normal_mod-normal_command.d normal_mod-normal_context.d 
normal_mod-normal_main.d normal_mod-normal_menu.d 
normal_mod-normal_menu_entry.d normal_mod-normal_powerpc_setjmp.d 
normal_mod-normal_parser.d
 DEFSYMFILES += def-normal.lst
 UNDSYMFILES += und-normal.lst
 
@@ -1200,7 +1208,7 @@
        $(LD) -r -d -o $@ $^
        $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -R .note -R 
.comment $@
 
-pre-normal.o: normal_mod-normal_arg.o normal_mod-normal_cmdline.o 
normal_mod-normal_command.o normal_mod-normal_context.o 
normal_mod-normal_main.o normal_mod-normal_menu.o 
normal_mod-normal_menu_entry.o normal_mod-normal_powerpc_setjmp.o
+pre-normal.o: normal_mod-normal_arg.o normal_mod-normal_cmdline.o 
normal_mod-normal_command.o normal_mod-normal_context.o 
normal_mod-normal_main.o normal_mod-normal_menu.o 
normal_mod-normal_menu_entry.o normal_mod-normal_powerpc_setjmp.o 
normal_mod-normal_parser.o
        -rm -f $@
        $(LD) -r -d -o $@ $^
 
@@ -1369,6 +1377,25 @@
        set -e;           $(CC) -Inormal/powerpc -I$(srcdir)/normal/powerpc 
$(CPPFLAGS) $(ASFLAGS) $(normal_mod_ASFLAGS) -E $<    | sh 
$(srcdir)/genfslist.sh normal > $@ || (rm -f $@; exit 1)
 
 
+normal_mod-normal_parser.o: normal/parser.c
+       $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) $(CFLAGS) 
$(normal_mod_CFLAGS) -c -o $@ $<
+
+normal_mod-normal_parser.d: normal/parser.c
+       set -e;           $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) 
$(CFLAGS) $(normal_mod_CFLAGS) -M $<      | sed 's,parser\.o[ 
:]*,normal_mod-normal_parser.o $@ : ,g' > $@;       [ -s $@ ] || rm -f $@
+
+-include normal_mod-normal_parser.d
+
+CLEANFILES += cmd-parser.lst fs-parser.lst
+COMMANDFILES += cmd-parser.lst
+FSFILES += fs-parser.lst
+
+cmd-parser.lst: normal/parser.c gencmdlist.sh
+       set -e;           $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) 
$(CFLAGS) $(normal_mod_CFLAGS) -E $<      | sh $(srcdir)/gencmdlist.sh normal > 
$@ || (rm -f $@; exit 1)
+
+fs-parser.lst: normal/parser.c genfslist.sh
+       set -e;           $(CC) -Inormal -I$(srcdir)/normal $(CPPFLAGS) 
$(CFLAGS) $(normal_mod_CFLAGS) -E $<      | sh $(srcdir)/genfslist.sh normal > 
$@ || (rm -f $@; exit 1)
+
+
 normal_mod_CFLAGS = $(COMMON_CFLAGS)
 normal_mod_ASFLAGS = $(COMMON_ASFLAGS)
 
diff -urN ./grub2_3/conf/powerpc-ieee1275.rmk 
./grub2_4/conf/powerpc-ieee1275.rmk
--- ./grub2_3/conf/powerpc-ieee1275.rmk 2005-08-08 15:10:12.000000000 +0200
+++ ./grub2_4/conf/powerpc-ieee1275.rmk 2005-08-24 11:23:25.000000000 +0200
@@ -48,7 +48,7 @@
        partmap/amiga.c partmap/apple.c partmap/pc.c partmap/sun.c      \
        util/console.c util/grub-emu.c util/misc.c                      \
        util/i386/pc/biosdisk.c util/i386/pc/getroot.c                  \
-       util/powerpc/ieee1275/misc.c
+       util/powerpc/ieee1275/misc.c normal/parser.c
 
 grub_emu_LDFLAGS = $(LIBCURSES)
 
@@ -119,7 +119,7 @@
 normal_mod_SOURCES = normal/arg.c normal/cmdline.c normal/command.c    \
        normal/context.c normal/main.c normal/menu.c                    \
        normal/menu_entry.c                                             \
-       normal/powerpc/setjmp.S
+       normal/powerpc/setjmp.S normal/parser.c
 normal_mod_CFLAGS = $(COMMON_CFLAGS)
 normal_mod_ASFLAGS = $(COMMON_ASFLAGS)
 
diff -urN ./grub2_3/include/grub/err.h ./grub2_4/include/grub/err.h
--- ./grub2_3/include/grub/err.h        2005-08-08 12:05:38.000000000 +0200
+++ ./grub2_4/include/grub/err.h        2005-08-22 16:11:44.000000000 +0200
@@ -49,7 +49,9 @@
     GRUB_ERR_NO_KERNEL,
     GRUB_ERR_BAD_FONT,
     GRUB_ERR_NOT_IMPLEMENTED_YET,
-    GRUB_ERR_SYMLINK_LOOP
+    GRUB_ERR_SYMLINK_LOOP,
+    GRUB_ERR_PARSE,
+    GRUB_ERR_FALSE
   }
 grub_err_t;
 
diff -urN ./grub2_3/include/grub/script.h ./grub2_4/include/grub/script.h
--- ./grub2_3/include/grub/script.h     1970-01-01 01:00:00.000000000 +0100
+++ ./grub2_4/include/grub/script.h     2005-08-24 11:03:59.000000000 +0200
@@ -0,0 +1,92 @@
+#include <grub/err.h>
+
+#define GRUB_SCRIPT_SPECIALCHARS ";\n \t\r"
+#define WORDCUTS "|&;<> \t()"
+
+#define GRUB_SCRIPT_COMMAND_FLAG_NOT 0x1
+
+enum grub_script_superchar_type
+  {
+    GRUB_SCRIPT_SUPERCHAR_PLAIN, /* Just a normal string*/
+    GRUB_SCRIPT_SUPERCHAR_VARIABLE, /* $var */
+    GRUB_SCRIPT_SUPERCHAR_COMMAND,
+    GRUB_SCRIPT_SUPERCHAR_ARITHMETIC
+  };
+
+/* Character string is represented like connected list 
+   by parts of type grub_script_superchar */
+struct grub_script_superchar
+{
+  enum grub_script_superchar_type type;
+  union
+  {
+    char *plain;
+    char *var_name;
+    char *cmd;
+    char *expr;
+  };
+  struct grub_script_superchar *next;
+};
+
+/* Argument list*/
+struct grub_script_superchars
+{
+  struct grub_script_superchar str;
+  struct grub_script_superchars *next;
+};
+
+enum grub_script_command_type
+  {
+    GRUB_SCRIPT_COMMAND_NORMAL, /* Command without scripting*/
+    GRUB_SCRIPT_COMMAND_FORIN, /* for ... in ... */
+    GRUB_SCRIPT_COMMAND_STACK_LOOKUP /* done, fi, ...*/
+  };
+
+enum grub_script_command_chain
+  {
+    GRUB_SCRIPT_CHAIN_NORMAL, /* Normal*/
+    GRUB_SCRIPT_CHAIN_OR, /* after || */
+    GRUB_SCRIPT_CHAIN_AND /* after &&*/
+  };
+
+struct grub_script_command
+{
+  enum grub_script_command_type type;
+  enum grub_script_command_chain chain;
+  int flags;
+  union
+  {
+    struct grub_script_superchars *normal;
+    struct
+    {
+      struct grub_script_superchars *var;
+      struct grub_script_superchars *vals;
+      struct grub_script_commandlist *lookup;
+    };
+  };
+};
+
+struct grub_script_commandlist
+{
+  struct grub_script_command cmd;
+  struct grub_script_commandlist *next;
+};
+
+enum grub_script_stackitemtype {GRUB_SCRIPT_STACKITEM_FORIN};
+
+struct grub_script_stackitem
+{
+  enum grub_script_stackitemtype type;
+  struct grub_script_commandlist *cmd;
+  union 
+  {
+    struct
+    {
+      char **list, *var;
+      int num, cur;
+    };
+  };
+};
+
+grub_err_t
+grub_script_command_execute (char *cmd, char * (*nextline) (void));
diff -urN ./grub2_3/normal/command.c ./grub2_4/normal/command.c
--- ./grub2_3/normal/command.c  2005-08-08 12:05:42.000000000 +0200
+++ ./grub2_4/normal/command.c  2005-08-22 16:18:33.000000000 +0200
@@ -24,6 +24,7 @@
 #include <grub/term.h>
 #include <grub/env.h>
 #include <grub/dl.h>
+#include <grub/script.h>
 
 static grub_command_t grub_command_list;
 
@@ -181,68 +182,28 @@
 int
 grub_command_execute (char *cmdline)
 {
-  auto grub_err_t cmdline_get (char **s);
-  grub_err_t cmdline_get (char **s)
+  auto char *cmdline_get (void);
+  char *cmdline_get (void)
     {
-      *s = grub_malloc (GRUB_MAX_CMDLINE);
-      *s[0] = '\0';
-      return grub_cmdline_get (">", *s, GRUB_MAX_CMDLINE, 0, 1);
+      char *s;
+      s = grub_malloc (GRUB_MAX_CMDLINE);
+      s[0] = '\0';
+      grub_cmdline_get (">", s, GRUB_MAX_CMDLINE, 0, 1);
+      return s;
     }
 
-  grub_command_t cmd;
-  grub_err_t ret = 0;
   char *pager;
-  int num;
-  char **args;
-  struct grub_arg_list *state;
-  struct grub_arg_option *parser;
-  int maxargs = 0;
-  char **arglist;
-  int numargs;
-
-  if (grub_split_cmdline (cmdline, cmdline_get, &num, &args))
-    return 0;
-  
-  /* In case of an assignment set the environment accordingly instead
-     of calling a function.  */
-  if (num == 0 && grub_strchr (args[0], '='))
-    {
-      char *val = grub_strchr (args[0], '=');
-      val[0] = 0;
-      grub_env_set (args[0], val + 1);
-      val[0] = '=';
-      return 0;
-    }
-  
-  cmd = grub_command_find (args[0]);
-  if (! cmd)
-    return -1;
+  grub_err_t ret;
 
   /* Enable the pager if the environment pager is set to 1.  */
   pager = grub_env_get ("pager");
   if (pager && (! grub_strcmp (pager, "1")))
     grub_set_more (1);
-  
-  parser = (struct grub_arg_option *) cmd->options;
-  while (parser && (parser++)->doc)
-    maxargs++;
-
-  state = grub_malloc (sizeof (struct grub_arg_list) * maxargs);
-  grub_memset (state, 0, sizeof (struct grub_arg_list) * maxargs);
-  if (! (cmd->flags & GRUB_COMMAND_FLAG_NO_ARG_PARSE))
-    {
-      if (grub_arg_parse (cmd, num, &args[1], state, &arglist, &numargs))
-       ret = (cmd->func) (state, numargs, arglist);
-    }
-  else
-    ret = (cmd->func) (state, num, &args[1]);
-  
-  grub_free (state);
 
+  ret = grub_script_command_execute (grub_strdup (cmdline), cmdline_get);
   if (pager && (! grub_strcmp (pager, "1")))
-    grub_set_more (0);
-  
-  grub_free (args);
+    grub_set_more (0); 
+
   return ret;
 }
 
@@ -375,6 +336,40 @@
   return 0;
 }
 
+static grub_err_t
+echo_command (struct grub_arg_list *state __attribute__ ((unused)),
+              int argc,
+             char **args)
+{
+  int i;
+  
+  for (i = 0; i < argc; i++)
+    {
+      grub_printf (args[i]);
+      grub_printf (" ");
+    }
+
+  grub_printf ("\n");
+
+  return 0;
+}
+
+static grub_err_t
+true_command (struct grub_arg_list *state __attribute__ ((unused)),
+             int argc __attribute__ ((unused)),
+             char **args __attribute__ ((unused)))
+{
+  return 0;
+}
+
+static grub_err_t
+false_command (struct grub_arg_list *state __attribute__ ((unused)),
+             int argc __attribute__ ((unused)),
+             char **args __attribute__ ((unused)))
+{
+  return GRUB_ERR_FALSE;
+}
+
 void
 grub_command_init (void)
 {
@@ -401,4 +396,13 @@
 
   grub_register_command ("lsmod", lsmod_command, GRUB_COMMAND_FLAG_BOTH,
                         "lsmod", "Show loaded modules.", 0);
+
+  grub_register_command ("echo", echo_command, GRUB_COMMAND_FLAG_BOTH,
+                        "echo TEXT", "Print TEXT.", 0);
+
+  grub_register_command ("true", true_command, GRUB_COMMAND_FLAG_BOTH,
+                        "true", "Return non-error.", 0);
+
+  grub_register_command ("false", false_command, GRUB_COMMAND_FLAG_BOTH,
+                        "false", "Return error.", 0);
 }
diff -urN ./grub2_3/normal/parser.y ./grub2_4/normal/parser.y
--- ./grub2_3/normal/parser.y   1970-01-01 01:00:00.000000000 +0100
+++ ./grub2_4/normal/parser.y   2005-08-24 11:18:21.000000000 +0200
@@ -0,0 +1,717 @@
+%{
+#include <grub/script.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/env.h>
+#include <grub/normal.h>
+
+#define PUTLNBUF 100
+#define malloc grub_malloc
+#define free grub_free
+
+static struct grub_script_commandlist *curexec;
+static int yylex (void);
+static void yyerror (const char *s);
+static int generate_end = 0;
+static int nopnum = 0;
+
+/* NOT DONE: brace expansion, vars like ${.../../..}, $*, ..., command 
expansion, arithmetic expansion,
+ arithmetic, logic, pipe, redirecting, heredoc, herestring, case esac , 
+ if then elif else fi,
+ for (()), function, entry, until, while, time, arrays, ~, special variables, 
pathname expansion,
+ aliases, builtin commands, prompting */
+
+
+%}
+
+%union 
+{
+  struct grub_script_commandlist *lst;
+  struct grub_script_superchars *str;
+};
+
+%token ENTER
+%token FOR
+%token SEMICOLON
+%token IN
+%token DO
+%token DONE
+%token NOP
+%token <str> WORD
+%token OR
+%token AND
+%token NOT
+
+%type <lst> commandlist
+%type <lst> command
+%type <lst> pre_command
+%type <lst> execlist
+%type <str> arglist
+
+%error-verbose
+
+%%
+
+out:/* command
+   { 
+     curexec = $1; 
+   }
+   |*/ command  
+   {
+     generate_end = 1;
+     nopnum=0;
+     curexec = $1; 
+   }
+
+commandlist  : command
+             | commandlist command
+             {
+              if (!$1)
+                $$ = $2;
+              else
+                {
+                  $$ = $1;
+                  if ($2)
+                    {
+                      struct grub_script_commandlist *cur;
+                      cur = $2;
+                      while (cur->next)
+                        cur = cur->next;
+                      cur->next = $2;
+                    }
+                }
+            };
+
+arglist : WORD
+        | arglist WORD
+        {
+         struct grub_script_superchars *cur;
+         $$ = $1;
+         cur = $1;
+         while (cur->next)
+           cur = cur->next;
+         cur->next = $2;
+       };
+
+command : cmdend
+        {
+         $$ = 0;
+        }
+        | NOP NOP NOP NOP 
+        {
+         $$ = 0;
+        }
+        | execlist cmdend
+        ;
+
+execlist : pre_command
+         | NOT pre_command
+         {
+          $$ = $2;
+          $$->cmd.flags |= GRUB_SCRIPT_COMMAND_FLAG_NOT;
+         }
+         | execlist AND pre_command
+         {
+          struct grub_script_commandlist *cur;
+          $$ = $1;
+          cur = $1;
+          while (cur->next)
+            cur = cur->next;
+          cur->next = $3;         
+          $3->cmd.chain = GRUB_SCRIPT_CHAIN_AND;
+        }
+         | execlist OR pre_command
+         {
+          struct grub_script_commandlist *cur;
+          $$ = $1;
+          cur = $1;
+          while (cur->next)
+            cur = cur->next;
+          cur->next = $3;
+          $3->cmd.chain = GRUB_SCRIPT_CHAIN_OR;
+        }
+         ;
+
+
+pre_command :
+        arglist /* Normal command */
+        {
+         $$ = grub_malloc (sizeof (struct grub_script_commandlist));
+         $$->cmd.type = GRUB_SCRIPT_CHAIN_NORMAL;
+         $$->cmd.chain = GRUB_SCRIPT_COMMAND_NORMAL;
+         $$->cmd.normal = $1;
+         $$->cmd.flags = 0;
+         $$->next = 0;
+       }
+        | FOR WORD IN arglist cmdend DO commandlist DONE
+        {
+         $$ = grub_malloc (sizeof (struct grub_script_commandlist));
+         $$->cmd.type = GRUB_SCRIPT_COMMAND_FORIN;
+         $$->cmd.var = $2;
+         $$->cmd.vals = $4;
+         $$->cmd.flags = 0;
+         $$->cmd.chain = GRUB_SCRIPT_CHAIN_NORMAL;
+         $$->next = $7;
+         struct grub_script_commandlist *cur;
+         cur = $7;
+         while (cur->next)
+           cur = cur->next;      
+         cur->next = (struct grub_script_commandlist *) 
+           grub_malloc (sizeof (struct grub_script_commandlist));
+         cur->next->next = 0;
+         cur->next->cmd.type = GRUB_SCRIPT_COMMAND_STACK_LOOKUP;
+         cur->next->cmd.chain = GRUB_SCRIPT_COMMAND_NORMAL;
+         cur->next->cmd.flags = 0;
+         $$->cmd.lookup = cur->next;
+       }
+        ;
+
+
+cmdend: ENTER
+      | SEMICOLON
+      ;
+
+%%
+
+static char *curcmd, *curptr;
+static char * (*nl) (void);
+
+static int
+yylex (void)
+{
+  char *putstr = 0, putln = 0, curch;
+  int putptr = 0;
+  /*Lexic analyzer mode: 0 - normal, 1 - between ", 2 - between ' */
+  int mode = 0;
+  
+  auto void cur_putchar (char ch);
+  void cur_putchar (char ch)
+    {
+      if (!(putptr % PUTLNBUF))
+       {
+         putln += PUTLNBUF;
+         putstr = grub_realloc (putstr, putln);
+       }
+      putstr[putptr++] = ch;
+    }
+
+  /* Check if next token is a KEYWORD. Set SEPARATOR to 1 if KEYWORD is a 
token separator like || */
+  auto int check_for_keyword (char *keyword, int separator);
+  int check_for_keyword (char *keyword, int separator)
+    {
+      unsigned keylen = grub_strlen (keyword);
+      if (!curcmd)
+       curptr = curcmd = nl ();      
+      if (mode == 0 && grub_strlen (curptr) >= keylen 
+         && !grub_memcmp (curptr, keyword, keylen) 
+         && (!curptr[keylen] || grub_strchr (WORDCUTS, curptr[keylen]) || 
separator))
+       {
+         curptr += keylen;
+         return 1;
+       }
+
+      return 0;
+    }
+
+  auto void add_wordpart (enum grub_script_superchar_type type);
+  void add_wordpart (enum grub_script_superchar_type type)
+    {
+      struct grub_script_superchar *cur;
+      if (!putstr)
+       return;
+      if (!yylval.str)
+       {
+         yylval.str = (struct grub_script_superchars *) 
+           grub_malloc (sizeof (struct grub_script_superchars));
+         cur = &(yylval.str->str);
+         yylval.str->next = 0;
+       }
+      else
+       {
+         cur = &(yylval.str->str);
+         while (cur->next)
+           cur = cur->next;  
+         cur->next = (struct grub_script_superchar *) 
+           grub_malloc (sizeof (struct grub_script_superchar));
+         cur = cur->next;        
+       }
+      cur->type = type;
+      cur->next = 0;
+      switch (type)
+       {
+       case GRUB_SCRIPT_SUPERCHAR_PLAIN:
+         cur->plain = putstr;
+         break;
+
+       case GRUB_SCRIPT_SUPERCHAR_VARIABLE:
+         cur->var_name = putstr;
+         break;
+
+       case GRUB_SCRIPT_SUPERCHAR_COMMAND:
+         cur->cmd = putstr;
+         break;
+
+       case GRUB_SCRIPT_SUPERCHAR_ARITHMETIC:
+         cur->expr = putstr;
+         break;
+       }
+      putstr = 0;  
+      putln = 0;
+      putptr = 0;
+    }
+
+  auto void script_ungetchar (void);
+  void script_ungetchar (void)
+    {
+      if (curptr)
+       curptr--;
+      else
+       {
+         curcmd = grub_malloc (sizeof (char));
+         curptr = curcmd;
+         curptr[0] = 0;
+       }
+    }
+
+  auto int script_getchar (void);
+  int script_getchar (void)
+    {
+      if (curptr && !*curptr)
+       {
+         free (curcmd);
+         curptr = curcmd = 0;
+         return '\n';
+       }
+
+      if (!curcmd)
+       curptr = curcmd = nl ();
+      
+      return *(curptr++);
+    }
+
+  if (nopnum)
+    {
+      nopnum--;
+      return NOP;
+    }
+
+  if (generate_end)
+    {
+      generate_end = 0;
+      return 0;
+    }
+
+  while (*curptr && grub_isspace (*curptr))
+    curptr++;
+
+  if (*curptr && *curptr == '#')
+    {
+      free (curcmd);
+      curptr = curcmd = 0;
+      return ENTER;
+    }
+
+  if (check_for_keyword ("for", 0))
+    return FOR;
+
+  if (check_for_keyword ("in", 0))
+    return IN;
+
+  if (check_for_keyword ("do", 0))
+    return DO;
+
+  if (check_for_keyword ("done", 0))
+    return DONE;
+
+  if (check_for_keyword ("!", 0))
+    return NOT;
+
+  if (check_for_keyword ("||", 1))
+    return OR;
+
+  if (check_for_keyword ("&&", 1))
+    return AND;
+
+  if (check_for_keyword (";", 1))
+    return SEMICOLON;
+
+  curch = script_getchar ();
+    
+
+  /* Normal word */
+  /* FIXME: brace expansion*/
+  /* FIXME: filename expansion*/
+  if (!grub_strchr (GRUB_SCRIPT_SPECIALCHARS, curch) || mode)
+    {
+      yylval.str = 0;
+      while (!grub_strchr (GRUB_SCRIPT_SPECIALCHARS, curch) || mode)
+       {
+         switch (curch)
+           {
+           case '\\':
+             /* Inside ' */
+             if (mode == 2)
+               {
+                 cur_putchar ('\\');
+                 break;
+               }
+             curch = script_getchar ();
+             /* Escaped newline */
+             if (curch == '\n')
+               {
+                 break;
+               }
+             cur_putchar (curch);
+             curch = script_getchar ();
+             break;
+
+           case '"':
+             if (mode == 0)
+               {
+                 mode = 1;
+                 curch = script_getchar ();
+                 break;
+               }
+             if (mode == 1)
+               {
+                 mode = 0;
+                 curch = script_getchar ();
+                 break;
+               }
+             cur_putchar (curch);
+             curch = script_getchar ();
+             break;
+
+           case '\'':
+             if (mode == 0)
+               {
+                 mode = 2;
+                 curch = script_getchar ();
+                 break;
+               }
+             if (mode == 2)
+               {
+                 mode = 0;
+                 curch = script_getchar ();
+                 break;
+               }
+             cur_putchar (curch);
+             curch = script_getchar ();
+             break;
+
+           case '$':
+             if (mode == 2)
+               {
+                 cur_putchar ('$');
+                 break;
+               }
+             add_wordpart (GRUB_SCRIPT_SUPERCHAR_PLAIN);
+             switch (curch = script_getchar ())
+               {
+               case '{':
+                 while ((curch = script_getchar ()) != '}')
+                   cur_putchar (curch);
+                 add_wordpart (GRUB_SCRIPT_SUPERCHAR_VARIABLE);
+                 curch = script_getchar ();
+                 break;
+
+               case '(':
+                 if ((curch = script_getchar ()) == '(')
+                   {
+                     int parcnt = 2;
+                     while (parcnt)
+                       {
+                         curch = script_getchar ();
+                         if (curch == '\\')
+                           {
+                             cur_putchar (curch);
+                             cur_putchar (script_getchar ());
+                             continue;
+                           }
+                         if (curch == '(')
+                           parcnt++;
+                         if (curch == ')')
+                           parcnt--;
+                           
+                         cur_putchar (curch);
+                       }
+                     add_wordpart (GRUB_SCRIPT_SUPERCHAR_ARITHMETIC);
+                     curch = script_getchar ();
+                     break;
+                   }
+                 {
+                   int parcnt = 1;
+                   while (parcnt)
+                     {
+                       if (curch == '\\')
+                         {
+                           cur_putchar (curch);
+                           cur_putchar (script_getchar ());
+                           curch = script_getchar ();
+                           continue;
+                         }
+                       if (curch == '(')
+                         parcnt++;
+                       if (curch == ')')
+                         parcnt--;
+                       
+                       cur_putchar (curch);
+                       curch = script_getchar ();
+                     }
+                   add_wordpart (GRUB_SCRIPT_SUPERCHAR_COMMAND);
+                   curch = script_getchar ();
+                   break;
+                 }
+               default:
+                 {
+                   int made = 0;
+                   while (grub_isalpha (curch) || grub_isdigit (curch))
+                     {
+                       cur_putchar (curch);
+                       made = 1;
+                       curch = script_getchar ();
+                     }
+                   if (made)
+                     add_wordpart (GRUB_SCRIPT_SUPERCHAR_VARIABLE);
+                   else
+                     {
+                       cur_putchar ('$');
+                       add_wordpart (GRUB_SCRIPT_SUPERCHAR_PLAIN);
+                     }
+                 }
+                 break;
+               }
+             break;
+             
+           case '`':
+             if (mode == 2)
+               {
+                 cur_putchar ('`');
+                 break;
+               }
+             add_wordpart (GRUB_SCRIPT_SUPERCHAR_PLAIN);
+             curch = script_getchar ();
+             while (curch != '`')
+               {
+                 if (curch == '\\')
+                   {
+                     cur_putchar (curch);
+                     curch = script_getchar ();
+                   }
+                 
+                 cur_putchar (curch);
+                 curch = script_getchar ();
+               }
+             curch = script_getchar ();
+             add_wordpart (GRUB_SCRIPT_SUPERCHAR_COMMAND);
+             break;
+
+           default:
+             cur_putchar (curch);
+             curch = script_getchar ();
+             break;
+           }
+       }
+      script_ungetchar ();
+      add_wordpart (GRUB_SCRIPT_SUPERCHAR_PLAIN);
+      return WORD;
+    }
+
+  if (curch == '\n')
+    return ENTER;
+  
+}
+
+static char *
+superchartostring (struct grub_script_superchar *in)
+{
+  char *retstr = 0;
+  int curret = 0, old;
+  struct grub_script_superchar *cur = in;
+  while (cur)
+    {
+      switch (cur->type)
+       {
+       case GRUB_SCRIPT_SUPERCHAR_PLAIN:
+         old = curret;
+         curret += grub_strlen (cur->plain);
+         retstr = grub_realloc (retstr, curret + 1);
+         grub_memcpy (retstr + old, cur->plain, sizeof (char) * grub_strlen 
(cur->plain));
+         break;
+
+         /* FIXME variables like ${...:...}*/
+       case GRUB_SCRIPT_SUPERCHAR_VARIABLE:
+         {
+           char *tmp;
+           old = curret;
+           tmp = grub_env_get (cur->var_name);
+           if (!tmp)
+             break;
+           curret += grub_strlen (tmp);
+           retstr = grub_realloc (retstr, curret + 1);
+           grub_memcpy (retstr + old, tmp, sizeof (char) * grub_strlen (tmp));
+           break;
+         }
+       }
+      cur = cur->next;
+    }
+  retstr[curret] = 0;
+  return retstr;
+}
+
+static void
+supercharstostrings (struct grub_script_superchars *in, int *num, char ***out)
+{
+  struct grub_script_superchars *cur = in;
+  *num = 0;
+  *out = 0;
+  while (cur)
+    {
+      *out = (char **) grub_realloc (*out, (*num + 1) * sizeof (char **));
+      (*out)[*num] = superchartostring (&(cur->str));
+      if (!(*out)[*num])
+       continue;
+      (*num)++;
+      cur = cur->next;
+    }
+}
+
+static void
+yyerror (const char *s)
+{
+  grub_error (GRUB_ERR_PARSE, s);
+}
+
+static grub_err_t
+grub_script_command_execute_real (void)
+{
+  grub_err_t ret = 0;
+  grub_command_t cmd;
+  struct grub_script_stackitem *stack = 0;
+  int stackcnt = 0;
+  nopnum = 0;
+  generate_end = 0;
+
+  auto void exec_forin (void);
+  void exec_forin (void)
+    {
+      if (stack[stackcnt - 1].cur >= stack[stackcnt - 1].num)
+       {
+         curexec = curexec->cmd.lookup;
+         stack = (struct grub_script_stackitem *) 
+           grub_realloc (stack, sizeof (struct grub_script_stackitem) * 
(--stackcnt));
+         return;
+       }
+      grub_env_set (stack[stackcnt - 1].var, stack[stackcnt - 
1].list[stack[stackcnt - 1].cur++]);
+    }
+
+  yyparse ();
+
+  while (curexec)
+    {
+      if (curexec->cmd.chain == GRUB_SCRIPT_CHAIN_AND && ret)
+       {
+         curexec = curexec->next;
+         continue;
+       }
+      if (curexec->cmd.chain == GRUB_SCRIPT_CHAIN_OR && !ret)
+       {
+         curexec = curexec->next;
+         continue;
+       }
+      switch (curexec->cmd.type)
+       {
+       case GRUB_SCRIPT_COMMAND_NORMAL:
+         {
+           int num;
+           char **args = 0;
+           struct grub_arg_list *state;
+           struct grub_arg_option *parser;
+           int maxargs = 0;
+           char **arglist;
+           int numargs;
+           supercharstostrings (curexec->cmd.normal, &num, &args);
+           /* In case of an assignment set the environment accordingly instead
+              of calling a function.  */
+           if (num == 1 && grub_strchr (args[0], '='))
+             {
+               char *val = grub_strchr (args[0], '=');
+               val[0] = 0;
+               grub_env_set (args[0], val + 1);
+               val[0] = '=';
+               ret = 0;
+               break;
+             }
+             cmd = grub_command_find (args[0]);
+             if (! cmd)
+               {
+                 ret = grub_error (GRUB_ERR_UNKNOWN_COMMAND, "Command not 
found");
+                 break;
+               }
+
+             parser = (struct grub_arg_option *) cmd->options;
+             while (parser && (parser++)->doc)
+               maxargs++;
+
+             state = grub_malloc (sizeof (struct grub_arg_list) * maxargs);
+             grub_memset (state, 0, sizeof (struct grub_arg_list) * maxargs);
+             if (! (cmd->flags & GRUB_COMMAND_FLAG_NO_ARG_PARSE))
+               {
+                 if (grub_arg_parse (cmd, num - 1, &args[1], state, &arglist, 
&numargs))
+                   ret = (cmd->func) (state, numargs, arglist);
+               }
+             else
+               ret = (cmd->func) (state, num - 1, &args[1]);
+  
+             grub_free (state);
+  
+             grub_free (args);
+             break;
+         }
+         
+       case GRUB_SCRIPT_COMMAND_FORIN:
+         {
+           stack = (struct grub_script_stackitem *) 
+             grub_realloc (stack, sizeof (struct grub_script_stackitem) * 
(stackcnt + 1));
+           stack[stackcnt].type = GRUB_SCRIPT_STACKITEM_FORIN;
+           stack[stackcnt].var = superchartostring (&curexec->cmd.var->str);
+           stack[stackcnt].list = 0;
+           supercharstostrings (curexec->cmd.vals, &stack[stackcnt].num, 
&stack[stackcnt].list);
+           stack[stackcnt].cmd = curexec;
+           stack[stackcnt].cur = 0;
+           stackcnt++;
+           exec_forin ();
+           break;
+         }
+       case GRUB_SCRIPT_COMMAND_STACK_LOOKUP:
+         {
+           switch (stack[stackcnt - 1].type)
+             {
+             case GRUB_SCRIPT_STACKITEM_FORIN:
+               curexec = stack[stackcnt - 1].cmd;
+               exec_forin ();
+               break;
+             }
+           break;
+         }
+       }
+      if (curexec->cmd.flags & GRUB_SCRIPT_COMMAND_FLAG_NOT)
+       ret = ret ? 0 : GRUB_ERR_FALSE;
+      curexec = curexec->next;
+    }
+
+  return ret; 
+}
+
+grub_err_t 
+grub_script_command_execute (char *in, char * (*nextline) (void))
+{
+  grub_err_t ret = 0;
+  curptr = curcmd = in;
+  nl = nextline;
+  while (curptr && grub_errno != GRUB_ERR_PARSE)
+    ret = grub_script_command_execute_real ();
+  return ret;
+}
+
+

reply via email to

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