]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
pull-in func-params branch
authorBVK Chaitanya <bvk.groups@gmail.com>
Wed, 12 May 2010 12:05:07 +0000 (17:35 +0530)
committerBVK Chaitanya <bvk.groups@gmail.com>
Wed, 12 May 2010 12:05:07 +0000 (17:35 +0530)
1  2 
conf/common.rmk
include/grub/script_sh.h
script/execute.c
tests/grub_script_shift.in

diff --cc conf/common.rmk
Simple merge
index 8610348f6ba9bf678a967f0c878aca5bf5e13c3b,5455fc763436c7243d8a57b8c4e341c59ec26b46..2b4c4e2f24369b72af4e8f69937a11e3bc033b5d
@@@ -64,6 -63,13 +64,13 @@@ struct grub_script_ar
    struct grub_script_arg *next;
  };
  
 -  int argc;
+ /* An argument vector.  */
+ struct grub_script_argv
+ {
++  unsigned argc;
+   char **args;
+ };
  /* A complete argument.  It consists of a list of one or more `struct
     grub_script_arg's.  */
  struct grub_script_arglist
index d3f8e9b258eacc1b14bc49eaf00e288148845043,2040be13cd53d6364e58902177b7b16f2a5fe378..d83f519144f0a2967b3ad44ffc4be247883c623f
     is sizeof (int) * 3, and one extra for a possible -ve sign.  */
  #define ERRNO_DIGITS_MAX  (sizeof (int) * 3 + 1)
  
+ /* Scope for grub script functions.  */
+ struct grub_script_scope
+ {
+   struct grub_script_argv argv;
+ };
  static struct grub_script_scope *scope = 0;
  
-       if (*p != '\0')
 +grub_err_t
 +grub_script_cmd_shift (grub_command_t cmd __attribute__((unused)),
 +                     int argc, char *argv[])
 +{
 +  char *p = 0;
 +  unsigned long n = 0;
 +
 +  if (! scope)
 +    return GRUB_ERR_NONE;
 +
++  if (scope->argv.argc == 0)
++    return GRUB_ERR_NONE;
++
 +  if (argc == 0)
 +    n = 1;
++
 +  else if (argc > 1)
 +    return GRUB_ERR_BAD_ARGUMENT;
++
 +  else
 +    {
 +      n = grub_strtoul (argv[0], &p, 10);
-   scope->shift = (unsigned int)(n > scope->argc ? 0 : n);
++      if (*p != '\0' || n > scope->argv.argc)
 +      return GRUB_ERR_BAD_ARGUMENT;
 +    }
 +
- static char *
- grub_script_env_get (const char *name)
++  scope->argv.argc -= n;
++  scope->argv.args += n;
 +  return GRUB_ERR_NONE;
 +}
 +
+ static int
+ grub_env_special (const char *name)
  {
-   char *p = 0;
-   unsigned long num = 0;
+   if (grub_isdigit (name[0]) ||
+       grub_strcmp (name, "#") == 0 ||
+       grub_strcmp (name, "*") == 0 ||
+       grub_strcmp (name, "@") == 0)
+     return 1;
+   return 0;
+ }
  
-   if (! scope)
-     return grub_env_get (name);
+ static char **
+ grub_script_env_get (const char *name, grub_script_arg_type_t type)
+ {
+   int errors = 0;
+   struct grub_script_argv result = { 0, 0 };
+   errors += grub_script_argv_next (&result);
+   if (! grub_env_special (name))
+     {
+       char *v = grub_env_get (name);
+       if (v && v[0])
+       {
+         if (type == GRUB_SCRIPT_ARG_TYPE_VAR)
+           errors += grub_script_argv_split_append (&result, v);
+         else
+           errors += grub_script_argv_append (&result, v);
+       }
+     }
+   else if (! scope)
+     errors += grub_script_argv_append (&result, 0);
  
-   if (grub_isdigit (name[0]))
+   else if (grub_strcmp (name, "#") == 0)
      {
-       num = grub_strtoul (name, &p, 10);
-       if (p && *p == '\0')
+       char buffer[ERRNO_DIGITS_MAX + 1];
+       grub_snprintf (buffer, sizeof (buffer), "%u", scope->argv.argc);
+       errors += grub_script_argv_append (&result, buffer);
+     }
+   else if (grub_strcmp (name, "*") == 0)
+     {
 -      int i;
++      unsigned i;
+       for (i = 0; ! errors && i < scope->argv.argc; i++)
+       if (type == GRUB_SCRIPT_ARG_TYPE_VAR)
+         {
+           if (i != 0)
+             errors += grub_script_argv_next (&result);
+           errors += grub_script_argv_split_append (&result,
+                                                    scope->argv.args[i]);
+         }
+       else
+         {
+           if (i != 0)
+             errors += grub_script_argv_append (&result, " ");
+           errors += grub_script_argv_append (&result,
+                                              scope->argv.args[i]);
+         }
+     }
+   else if (grub_strcmp (name, "@") == 0)
+     {
 -      int i;
++      unsigned i;
+       for (i = 0; ! errors && i < scope->argv.argc; i++)
        {
-         if (num == 0)
-           return 0; /* XXX no file name, for now.  */
+         if (i != 0)
+           errors += grub_script_argv_next (&result);
  
-         if (num > scope->argc - scope->shift)
-           return 0;
+         if (type == GRUB_SCRIPT_ARG_TYPE_VAR)
+           errors += grub_script_argv_split_append (&result,
+                                                    scope->argv.args[i]);
          else
-           return scope->args[num - 1 + scope->shift];
+           errors += grub_script_argv_append (&result,
+                                              scope->argv.args[i]);
        }
-       else
+     }
+   else
+     {
+       unsigned long num = grub_strtoul (name, 0, 10);
+       if (num == 0)
+       ; /* XXX no file name, for now.  */
+       else if (num <= scope->argv.argc)
        {
-         grub_error (GRUB_ERR_BAD_ARGUMENT, "bad variabe name substitution");
-         return 0;
+         if (type == GRUB_SCRIPT_ARG_TYPE_VAR)
+           errors += grub_script_argv_split_append (&result,
+                                                    scope->argv.args[num - 1]);
+         else
+           errors += grub_script_argv_append (&result,
+                                              scope->argv.args[num - 1]);
        }
      }
-   else if (grub_strcmp (name, "#") == 0)
+   if (errors)
      {
-       static char buf[32]; /* Rewritten everytime.  */
-       grub_snprintf (buf, sizeof (buf), "%u", scope->argc - scope->shift);
-       return buf;
+       grub_script_argv_free (&result);
+       return 0;
      }
-   else
-     return grub_env_get (name);
+   return result.args;
  }
  
  static grub_err_t
@@@ -399,14 -353,12 +384,12 @@@ grub_script_execute_cmdif (struct grub_
  grub_err_t
  grub_script_execute_cmdfor (struct grub_script_cmd *cmd)
  {
--  int i;
++  unsigned i;
    int result;
-   char **args;
-   int argcount;
+   struct grub_script_argv argv;
    struct grub_script_cmdfor *cmdfor = (struct grub_script_cmdfor *) cmd;
  
-   args = grub_script_execute_arglist_to_argv (cmdfor->words, &argcount);
-   if (!args)
+   if (grub_script_arglist_to_argv (cmdfor->words, &argv))
      return grub_errno;
  
    result = 0;
index 542e72974f5958df1d8c72aa1f2935feda42fbee,0000000000000000000000000000000000000000..c7c94ab1896f924b96f039ab354a55357b64395d
mode 100644,000000..100644
--- /dev/null
@@@ -1,69 -1,0 +1,69 @@@
- function f2 {
-   echo f2 $# $1 $2 $3
-   shift 1
-   echo f2 $# $1 $2 $3
- }
- function f3 {
-   echo f3 $# $1 $2 $3
-   shift 3
-   echo f3 $# $1 $2 $3
- }
- function f4 {
-   echo f4 $# $1 $2 $3
-   shift 100
-   echo f4 $# $1 $2 $3
- }
 +#! @builddir@/grub-shell-tester
 +
 +# Run GRUB script in a Qemu instance
 +# 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/>.
 +
 +function f1 {
 +  echo f1 $# $1 $2 $3
 +  shift
 +  echo f1 $# $1 $2 $3
 +}
 +
 +f1
 +f1 a
 +f1 a b
 +f1 a b c
 +f1 a b c d
 +f1 a b c d e
 +
++function f2 {
++  echo f2 $# $1 $2 $3
++  shift 1
++  echo f2 $# $1 $2 $3
++}
++
 +f2
 +f2 a
 +f2 a b
 +f2 a b c
 +f2 a b c d
 +f2 a b c d e
 +
++function f3 {
++  echo f3 $# $1 $2 $3
++  shift 3
++  echo f3 $# $1 $2 $3
++}
++
 +f3
 +f3 a
 +f3 a b
 +f3 a b c
 +f3 a b c d
 +f3 a b c d e
 +
++function f4 {
++  echo f4 $# $1 $2 $3
++  shift 100
++  echo f4 $# $1 $2 $3
++}
++
 +f4
 +f4 a
 +f4 a b
 +f4 a b c
 +f4 a b c d
 +f4 a b c d e