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

diff --cc conf/common.rmk
Simple merge
Simple merge
index 3ad0b9dffc53f2a480256dba9fe2d5a549326ffd,2040be13cd53d6364e58902177b7b16f2a5fe378..a9b3a002c488c65a6c0b4bebedf2a3ab3b8f594f
     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;
++
+ /* Scope for grub script functions.  */
+ struct grub_script_scope
+ {
+   struct grub_script_argv argv;
+ };
  static struct grub_script_scope *scope = 0;
  
- static char *
- grub_script_env_get (const char *name)
 +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)) == 0 ||
 +         (*p != '\0'))
 +    return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad break");
 +
 +  active_breaks = grub_min (active_loops, count);
 +  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 };
  
-   if (grub_isdigit (name[0]))
+   errors += grub_script_argv_next (&result);
+   if (! grub_env_special (name))
      {
-       num = grub_strtoul (name, &p, 10);
-       if (p && *p == '\0')
+       char *v = grub_env_get (name);
+       if (v && v[0])
        {
-         if (num == 0)
-           return 0; /* XXX no file name, for now.  */
+         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);
+   else if (grub_strcmp (name, "#") == 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;
+       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;
  
-         return (num > scope->argc ? 0 : scope->args[num - 1]);
+       for (i = 0; ! errors && i < scope->argv.argc; i++)
+       {
+         if (i != 0)
+           errors += grub_script_argv_next (&result);
+         if (type == GRUB_SCRIPT_ARG_TYPE_VAR)
+           errors += grub_script_argv_split_append (&result,
+                                                    scope->argv.args[i]);
+         else
+           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);
-       return buf;
+       grub_script_argv_free (&result);
+       return 0;
      }
-   else
-     return grub_env_get (name);
+   return result.args;
  }
  
  static grub_err_t
@@@ -262,18 -227,18 +248,21 @@@ grub_err_
  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 *old_scope;
    struct grub_script_scope new_scope;
  
-   new_scope.argc = argc;
-   new_scope.args = args;
-   grub_list_push (GRUB_AS_LIST_P (&scope), GRUB_AS_LIST (&new_scope));
 +  active_loops = 0;
+   new_scope.argv.argc = argc;
+   new_scope.argv.args = args;
+   old_scope = scope;
+   scope = &new_scope;
  
    ret = grub_script_execute (func->func);
  
-   grub_list_pop (GRUB_AS_LIST_P (&scope));
 +  active_loops = loops;
+   scope = old_scope;
    return ret;
  }
  
@@@ -395,31 -355,20 +379,28 @@@ grub_script_execute_cmdfor (struct grub
  {
    int 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;
  
 +  active_loops++;
    result = 0;
-   for (i = 0; i < argcount; i++)
+   for (i = 0; i < argv.argc; i++)
      {
 -      grub_script_env_set (cmdfor->name->str, argv.args[i]);
 -      result = grub_script_execute_cmd (cmdfor->list);
 +      if (! active_breaks)
 +      {
-         grub_script_env_set (cmdfor->name->str, args[i]);
++        grub_script_env_set (cmdfor->name->str, argv.args[i]);
 +        result = grub_script_execute_cmd (cmdfor->list);
 +      }
-       grub_free (args[i]);
      }
  
-   grub_free (args);
 +  if (active_breaks)
 +    active_breaks--;
 +
 +  active_loops--;
+   grub_script_argv_free (&argv);
    return result;
  }