]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
not command (!) support
authorBVK Chaitanya <bvk@dbook>
Sun, 5 Sep 2010 09:27:28 +0000 (14:57 +0530)
committerBVK Chaitanya <bvk@dbook>
Sun, 5 Sep 2010 09:27:28 +0000 (14:57 +0530)
Makefile.util.def
grub-core/script/execute.c
grub-core/script/yylex.l
tests/grub_script_not.in [new file with mode: 0644]

index dd38774fdfa4d321dc7d1a47f2a00676f02bd9fc..e0900c73fee2baaadd400c3673df87ee84e0a792 100644 (file)
@@ -531,6 +531,12 @@ script = {
   common = tests/grub_script_expansion.in;
 };
 
+script = {
+  testcase;
+  name = grub_script_not;
+  common = tests/grub_script_not.in;
+};
+
 program = {
   testcase;
   name = example_unit_test;
index a7baee96cfede8f75ed34cb705b595472a68a947..b43ec85e17212ef99725454dd046a631eabc520f 100644 (file)
@@ -547,13 +547,32 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd)
   grub_script_function_t func = 0;
   char errnobuf[18];
   char *cmdname;
+  int argc;
+  char **args;
+  int invert;
   struct grub_script_argv argv = { 0, 0, 0 };
 
   /* Lookup the command.  */
   if (grub_script_arglist_to_argv (cmdline->arglist, &argv) || ! argv.args[0])
     return grub_errno;
 
+  invert = 0;
+  argc = argv.argc - 1;
+  args = argv.args + 1;
   cmdname = argv.args[0];
+  if (grub_strcmp (cmdname, "!") == 0)
+    {
+      if (argv.argc < 2 || ! argv.args[1])
+       {
+         grub_script_argv_free (&argv);
+         return grub_error (GRUB_ERR_BAD_ARGUMENT, "missing arguments");
+       }
+
+      invert = 1;
+      argc = argv.argc - 2;
+      args = argv.args + 2;
+      cmdname = argv.args[1];
+    }
   grubcmd = grub_command_find (cmdname);
   if (! grubcmd)
     {
@@ -594,13 +613,15 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd)
     {
       if ((grubcmd->flags & GRUB_COMMAND_FLAG_BLOCKS) &&
          (grubcmd->flags & GRUB_COMMAND_FLAG_EXTCMD))
-       ret = grub_extcmd_dispatcher (grubcmd, argv.argc - 1, argv.args + 1,
-                                     argv.script);
+       ret = grub_extcmd_dispatcher (grubcmd, argc, args, argv.script);
       else
-       ret = (grubcmd->func) (grubcmd, argv.argc - 1, argv.args + 1);
+       ret = (grubcmd->func) (grubcmd, argc, args);
     }
   else
-    ret = grub_script_function_call (func, argv.argc - 1, argv.args + 1);
+    ret = grub_script_function_call (func, argc, args);
+
+  if (invert)
+    ret = ! ret;
 
   /* Free arguments.  */
   grub_script_argv_free (&argv);
index d4cad80973b055324eacf59712368496437b9408..55620b6bdc6f1d3e5ce377a04838c175fb306e82 100644 (file)
@@ -155,7 +155,6 @@ MULTILINE       {WORD}?((\"{DQCHR}*)|(\'{SQCHR}*)|(\\\n))
 ">"             { RECORD; return GRUB_PARSER_TOKEN_GT;      }
 
  /* Reserved words */
-"!"             { RECORD; return GRUB_PARSER_TOKEN_NOT;       }
 "{"             { RECORD; return GRUB_PARSER_TOKEN_LBR;       }
 "}"             { RECORD; return GRUB_PARSER_TOKEN_RBR;       }
 "[["            { RECORD; return GRUB_PARSER_TOKEN_RSQBR2;    }
diff --git a/tests/grub_script_not.in b/tests/grub_script_not.in
new file mode 100644 (file)
index 0000000..ff71039
--- /dev/null
@@ -0,0 +1,62 @@
+#! @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/>.
+
+true
+echo $?
+
+! true
+echo $?
+
+false
+echo $?
+
+! false
+echo $?
+
+#
+# Negated forms (copied from grub_script_if.in)
+#
+
+#basic if, execute
+if ! true; then echo yes; fi
+
+#basic if, no execution
+if ! false; then echo no; fi
+
+#if else, execute if path
+if ! true; then echo yes; else echo no; fi
+
+#if else, execute else path
+if ! false; then echo no; else echo yes; fi
+
+#if elif, execute elif
+if ! false; then echo no; elif ! true; then echo yes; fi
+
+#if elif else, execute else
+if ! false; then echo no; elif ! false; then echo no; else echo yes; fi
+
+#if elif(1) elif(2), execute elif(2)
+if false; then echo no; elif ! false; then echo no; elif ! true; then echo yes; fi
+
+#if elif(1) elif(2) else, execute else
+if false; then echo no; elif false; then echo no; elif ! false; then echo no; else echo yes; fi
+
+#if {if elif else}, execute elif
+if true; then if false; then echo no; elif ! true; then echo yes; else echo no; fi; fi
+
+#if {if elif} else, execute elif. ofcourse no dangling-else problem due to "fi"
+if true; then if ! false; then echo no; elif true; then echo yes; fi; else echo no; fi