From: BVK Chaitanya Date: Wed, 12 May 2010 12:29:09 +0000 (+0530) Subject: pull-in func-params again X-Git-Tag: 1.99~666^2~4^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=2e961bd737d387493ad6275c40b559041cc911ed;p=thirdparty%2Fgrub.git pull-in func-params again --- 2e961bd737d387493ad6275c40b559041cc911ed diff --cc script/execute.c index 3ad0b9dff,2040be13c..a9b3a002c --- a/script/execute.c +++ b/script/execute.c @@@ -30,61 -30,112 +30,133 @@@ 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; +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 char * - grub_script_env_get (const char *name) + 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; + active_loops = 0; - new_scope.argc = argc; - new_scope.args = args; - grub_list_push (GRUB_AS_LIST_P (&scope), GRUB_AS_LIST (&new_scope)); + 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]); } + if (active_breaks) + active_breaks--; + + active_loops--; - grub_free (args); + grub_script_argv_free (&argv); return result; }