Hi,

Attached patch adds "break [n]" command support to GRUB script.  This
needs to be applied on top of func-params patch.


-- 
bvk.chaitanya
# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: bvk.gro...@gmail.com-20100505100426-vp7j1j0otn99h0xn
# target_branch: ../func-params/
# testament_sha1: d057b667bba83e45aa888bc058e129c5a9ab58da
# timestamp: 2010-05-05 16:04:16 +0530
# base_revision_id: bvk.gro...@gmail.com-20100505091750-\
#   94q42bwn9s9dzz31
# 
# Begin patch
=== modified file 'conf/common.rmk'
--- conf/common.rmk     2010-04-24 20:09:08 +0000
+++ conf/common.rmk     2010-05-05 10:04:26 +0000
@@ -103,12 +103,12 @@
 # For grub-script-check.
 bin_UTILITIES += grub-script-check
 util/grub-script-check.c_DEPENDENCIES = grub_script_check_init.h
-grub_script_check_SOURCES = gnulib/progname.c gnulib/getdelim.c 
gnulib/getline.c \
-       util/grub-script-check.c util/misc.c util/mm.c \
-       script/main.c script/script.c script/function.c script/lexer.c \
-       kern/handler.c kern/err.c kern/parser.c kern/list.c \
-       kern/misc.c kern/env.c grub_script_check_init.c grub_script.tab.c \
-       grub_script.yy.c
+grub_script_check_SOURCES = gnulib/progname.c gnulib/getdelim.c                
\
+       gnulib/getline.c util/grub-script-check.c util/misc.c           \
+       util/mm.c script/main.c script/script.c script/function.c       \
+       script/lexer.c kern/handler.c kern/err.c kern/parser.c          \
+       kern/list.c kern/misc.c kern/env.c kern/command.c               \
+       grub_script_check_init.c grub_script.tab.c grub_script.yy.c
 grub_script_check_CFLAGS = $(GNULIB_UTIL_CFLAGS)
 MOSTLYCLEANFILES += symlist.c kernel_syms.lst
 DEFSYMFILES += kernel_syms.lst

=== modified file 'conf/tests.rmk'
--- conf/tests.rmk      2010-05-05 09:17:50 +0000
+++ conf/tests.rmk      2010-05-05 10:04:26 +0000
@@ -74,6 +74,9 @@
 check_SCRIPTS += grub_script_functions
 grub_script_functions_SOURCES = tests/grub_script_functions.in
 
+check_SCRIPTS += grub_script_break
+grub_script_break_SOURCES = tests/grub_script_break.in
+
 # List of tests to execute on "make check"
 # SCRIPTED_TESTS    = example_scripted_test
 # SCRIPTED_TESTS   += example_grub_script_test
@@ -91,6 +94,7 @@
 SCRIPTED_TESTS += grub_script_dollar
 SCRIPTED_TESTS += grub_script_comments
 SCRIPTED_TESTS += grub_script_functions
+SCRIPTED_TESTS += grub_script_break
 
 # dependencies between tests and testing-tools
 $(SCRIPTED_TESTS): grub-shell grub-shell-tester

=== modified file 'include/grub/script_sh.h'
--- include/grub/script_sh.h    2010-05-05 09:17:50 +0000
+++ include/grub/script_sh.h    2010-05-05 10:04:26 +0000
@@ -23,6 +23,7 @@
 #include <grub/types.h>
 #include <grub/err.h>
 #include <grub/parser.h>
+#include <grub/command.h>
 
 struct grub_script_mem;
 
@@ -308,6 +309,9 @@
 /* Execute any GRUB pre-parsed command or script.  */
 grub_err_t grub_script_execute (struct grub_script *script);
 
+/* Break command for loops.  */
+grub_err_t grub_script_break (grub_command_t cmd, int argc, char *argv[]);
+
 /* This variable points to the parsed command.  This is used to
    communicate with the bison code.  */
 extern struct grub_script_cmd *grub_script_parsed;

=== modified file 'script/execute.c'
--- script/execute.c    2010-05-05 09:17:50 +0000
+++ script/execute.c    2010-05-05 10:04:26 +0000
@@ -30,8 +30,29 @@
    is sizeof (int) * 3, and one extra for a possible -ve sign.  */
 #define ERRNO_DIGITS_MAX  (sizeof (int) * 3 + 1)
 
+static unsigned long active_loops;
+static unsigned long active_breaks;
 static struct grub_script_scope *scope = 0;
 
+grub_err_t
+grub_script_break (grub_command_t cmd __attribute__((unused)),
+                  int argc, char *argv[])
+{
+  char *p = 0;
+  unsigned long count;
+
+  if (argc == 0)
+    count = 1;
+
+  else if ((argc > 1) ||
+          (count = grub_strtoul (argv[0], &p, 10)) > active_loops ||
+          (*p != '\0'))
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad break");
+
+  active_breaks = count;
+  return GRUB_ERR_NONE;
+}
+
 static char *
 grub_script_env_get (const char *name)
 {
@@ -242,8 +263,10 @@
 grub_script_function_call (grub_script_function_t func, int argc, char **args)
 {
   grub_err_t ret = 0;
+  unsigned long loops = active_loops;
   struct grub_script_scope new_scope;
 
+  active_loops = 0;
   new_scope.argc = argc;
   new_scope.args = args;
   grub_list_push (GRUB_AS_LIST_P (&scope), GRUB_AS_LIST (&new_scope));
@@ -251,6 +274,7 @@
   ret = grub_script_execute (func->func);
 
   grub_list_pop (GRUB_AS_LIST_P (&scope));
+  active_loops = loops;
   return ret;
 }
 
@@ -338,7 +362,7 @@
   struct grub_script_cmd *cmd;
 
   /* Loop over every command and execute it.  */
-  for (cmd = list->next; cmd; cmd = cmd->next)
+  for (cmd = list->next; cmd && ! active_breaks; cmd = cmd->next)
     ret = grub_script_execute_cmd (cmd);
 
   return ret;
@@ -380,14 +404,22 @@
   if (!args)
     return grub_errno;
 
+  active_loops++;
   result = 0;
   for (i = 0; i < argcount; i++)
     {
-      grub_script_env_set (cmdfor->name->str, args[i]);
-      result = grub_script_execute_cmd (cmdfor->list);
+      if (! active_breaks)
+       {
+         grub_script_env_set (cmdfor->name->str, args[i]);
+         result = grub_script_execute_cmd (cmdfor->list);
+       }
       grub_free (args[i]);
     }
 
+  if (active_breaks)
+    active_breaks--;
+
+  active_loops--;
   grub_free (args);
   return result;
 }
@@ -400,6 +432,7 @@
   int result;
   struct grub_script_cmdwhile *cmdwhile = (struct grub_script_cmdwhile *) cmd;
 
+  active_loops++;
   result = 0;
   do {
     cond = grub_script_execute_cmd (cmdwhile->cond);
@@ -407,8 +440,16 @@
       break;
 
     result = grub_script_execute_cmd (cmdwhile->list);
+
+    if (active_breaks)
+      {
+       active_breaks--;
+       break;
+      }
+
   } while (1); /* XXX Put a check for ^C here */
 
+  active_loops--;
   return result;
 }
 

=== modified file 'script/main.c'
--- script/main.c       2009-11-23 15:37:33 +0000
+++ script/main.c       2010-05-05 10:04:26 +0000
@@ -17,6 +17,7 @@
  */
 
 #include <grub/dl.h>
+#include <grub/i18n.h>
 #include <grub/parser.h>
 #include <grub/script_sh.h>
 
@@ -49,6 +50,8 @@
 GRUB_MOD_INIT(sh)
 {
   grub_parser_register ("grub", &grub_sh_parser);
+  grub_register_command ("break", grub_script_break,
+                        N_("[n]"), N_("Exit from loops"));
 }
 
 GRUB_MOD_FINI(sh)

=== added file 'tests/grub_script_break.in'
--- tests/grub_script_break.in  1970-01-01 00:00:00 +0000
+++ tests/grub_script_break.in  2010-05-05 10:04:26 +0000
@@ -0,0 +1,86 @@
+#! @builddir@/grub-shell-tester
+#
+# Copyright (C) 2010  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/>.
+
+# break without any arguments
+for i in 1 2 3 4 5 6 7 8 9 10
+do
+  echo $i
+  if test "$i" = 5
+  then
+    break
+  fi
+done
+
+# break with one
+for i in 1 2 3 4 5 6 7 8 9 10
+do
+  echo $i
+  if test "$i" = 5
+  then
+    break 1
+  fi
+done
+
+# break with loop count
+for i in 1 2 3 4 5
+do
+  for j in a b c d e f
+  do
+    echo "$i $j"
+    if test "$i" = 3
+    then
+      if test "$j" = d
+      then
+        break 2
+      fi
+    fi
+  done
+done
+
+# break into middle loop
+for i in 1 2 3 4 5
+do
+  for j in a b c d e f
+  do
+    echo "$i $j"
+    if test "$i" = 3
+    then
+      if test "$j" = d
+      then
+        break 1
+      fi
+    fi
+  done
+done
+
+# while and until loops
+a=
+while test "$a" != "aaaaaaa"
+do
+  a="a$a"
+  for i in 1 2 3 4
+  do
+    b=
+    until test "$b" = "bbbbb"
+    do
+      b="b$b"
+      echo "$a $i $b"
+      if test "$i" = 3; then echo "break 2"; break 2; fi
+    done
+  done
+done
+

=== modified file 'util/grub-script-check.c'
--- util/grub-script-check.c    2010-05-05 08:35:06 +0000
+++ util/grub-script-check.c    2010-05-05 10:04:26 +0000
@@ -57,6 +57,14 @@
   fflush (stdout);
 }
 
+grub_err_t
+grub_script_break (grub_command_t cmd __attribute__((unused)),
+                  int argc __attribute__((unused)),
+                  char *argv[] __attribute__((unused)))
+{
+  return 0;
+}
+
 char *
 grub_script_execute_argument_to_string (struct grub_script_arg *arg 
__attribute__ ((unused)))
 {

# Begin bundle
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
j/+LuSKcKEh+ZtnZAA==
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to