merge with mainline

This commit is contained in:
BVK Chaitanya 2010-09-04 21:02:48 +05:30
commit 9fcd1ee541
8 changed files with 239 additions and 12 deletions

View file

@ -34,6 +34,10 @@
static unsigned long is_continue;
static unsigned long active_loops;
static unsigned long active_breaks;
static unsigned long function_return;
#define GRUB_SCRIPT_SCOPE_MALLOCED 1
#define GRUB_SCRIPT_SCOPE_ARGS_MALLOCED 2
#define GRUB_SCRIPT_SCOPE_MALLOCED 1
#define GRUB_SCRIPT_SCOPE_ARGS_MALLOCED 2
@ -143,6 +147,30 @@ grub_script_setparams (grub_command_t cmd __attribute__((unused)),
return GRUB_ERR_NONE;
}
grub_err_t
grub_script_return (grub_command_t cmd __attribute__((unused)),
int argc, char *argv[])
{
char *p;
unsigned long n;
if (! scope || argc > 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "not in function scope");
if (argc == 0)
{
function_return = 1;
return grub_strtoul (grub_env_get ("?"), NULL, 10);
}
n = grub_strtoul (argv[0], &p, 10);
if (*p != '\0')
return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad argument");
function_return = 1;
return n ? grub_error (GRUB_ERR_TEST_FAILURE, "false") : GRUB_ERR_NONE;
}
static int
grub_env_special (const char *name)
{
@ -370,6 +398,7 @@ grub_script_function_call (grub_script_function_t func, int argc, char **args)
ret = grub_script_execute (func->func);
function_return = 0;
active_loops = loops;
replace_scope (old_scope); /* free any scopes by setparams */
return ret;
@ -518,8 +547,16 @@ grub_script_execute_cmdlist (struct grub_script_cmd *list)
struct grub_script_cmd *cmd;
/* Loop over every command and execute it. */
for (cmd = list->next; cmd && ! active_breaks; cmd = cmd->next)
ret = grub_script_execute_cmd (cmd);
for (cmd = list->next; cmd; cmd = cmd->next)
{
if (active_breaks)
break;
ret = grub_script_execute_cmd (cmd);
if (function_return)
break;
}
return ret;
}
@ -528,14 +565,17 @@ grub_script_execute_cmdlist (struct grub_script_cmd *list)
grub_err_t
grub_script_execute_cmdif (struct grub_script_cmd *cmd)
{
struct grub_script_cmdif *cmdif = (struct grub_script_cmdif *) cmd;
int ret;
char *result;
struct grub_script_cmdif *cmdif = (struct grub_script_cmdif *) cmd;
/* Check if the commands results in a true or a false. The value is
read from the env variable `?'. */
grub_script_execute_cmd (cmdif->exec_to_evaluate);
result = grub_env_get ("?");
ret = grub_script_execute_cmd (cmdif->exec_to_evaluate);
if (function_return)
return ret;
result = grub_env_get ("?");
grub_errno = GRUB_ERR_NONE;
/* Execute the `if' or the `else' part depending on the value of
@ -569,6 +609,8 @@ grub_script_execute_cmdfor (struct grub_script_cmd *cmd)
{
grub_script_env_set (cmdfor->name->str, argv.args[i]);
result = grub_script_execute_cmd (cmdfor->list);
if (function_return)
break;
}
}
@ -584,18 +626,21 @@ grub_script_execute_cmdfor (struct grub_script_cmd *cmd)
grub_err_t
grub_script_execute_cmdwhile (struct grub_script_cmd *cmd)
{
int cond;
int result;
struct grub_script_cmdwhile *cmdwhile = (struct grub_script_cmdwhile *) cmd;
active_loops++;
result = 0;
do {
cond = grub_script_execute_cmd (cmdwhile->cond);
if (cmdwhile->until ? !cond : cond)
result = grub_script_execute_cmd (cmdwhile->cond);
if (function_return)
break;
if (cmdwhile->until ? !result : result)
break;
result = grub_script_execute_cmd (cmdwhile->list);
if (function_return)
break;
if (active_breaks == 1 && is_continue)
active_breaks = 0;