lexer-rewrite rebase commit

This commit is contained in:
BVK Chaitanya 2010-01-22 19:07:27 +05:30
parent bf86e59a76
commit 547e494f1b
25 changed files with 1214 additions and 652 deletions

View file

@ -1,7 +1,7 @@
/* execute.c -- Execute a GRUB script. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2005,2007,2008,2009 Free Software Foundation, Inc.
* Copyright (C) 2005,2007,2008,2009,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
@ -35,49 +35,146 @@ grub_script_execute_cmd (struct grub_script_cmd *cmd)
return cmd->exec (cmd);
}
/* Parse ARG and return the textual representation. Add strings are
concatenated and all values of the variables are filled in. */
char *
grub_script_execute_argument_to_string (struct grub_script_arg *arg)
#define ROUND_UPTO(sz,up) (((sz) + (up) - 1) / (up) * (up))
/* Expand arguments in ARGLIST into multiple arguments. */
char **
grub_script_execute_arglist_to_argv (struct grub_script_arglist *arglist)
{
int size = 0;
char *val;
char *chararg;
struct grub_script_arg *argi;
int i;
int oom;
int argc;
int empty;
char *ptr;
char **argv;
char *value;
struct grub_script_arg *arg;
/* First determine the size of the argument. */
for (argi = arg; argi; argi = argi->next)
auto void push (char *str);
void push (char *str)
{
char **p;
if (oom)
return;
p = grub_realloc (argv, ROUND_UPTO (sizeof(char*) * (argc + 1), 32));
if (!p)
oom = 1;
else
{
p[argc++] = str;
argv = p;
}
}
auto char* append (const char *str, grub_size_t nchar);
char* append (const char *str, grub_size_t nchar)
{
int len;
int old;
char *p;
if (oom || !str)
return 0;
len = nchar ?: grub_strlen (str);
old = argv[argc - 1] ? grub_strlen (argv[argc - 1]) : 0;
p = grub_realloc (argv[argc - 1], ROUND_UPTO(old + len + 1, 32));
if (p)
{
grub_strncpy (p + old, str, len);
p[old + len] = '\0';
}
else
{
oom = 1;
grub_free (argv[argc - 1]);
}
argv[argc - 1] = p;
return argv[argc - 1];
}
/* Move *STR to the begining of next word, but return current word. */
auto char* move_to_next (char **str);
char* move_to_next (char **str)
{
char *end;
char *start;
if (oom || !str || !*str)
return 0;
start = *str;
while (*start && grub_isspace (*start)) start++;
if (*start == '\0')
return 0;
end = start + 1;
while (*end && !grub_isspace (*end)) end++;
*str = end;
return start;
}
oom = 0;
argv = 0;
argc = 0;
push (0);
for (; arglist; arglist = arglist->next)
{
if (argi->type == 1)
empty = 1;
arg = arglist->arg;
while (arg)
{
val = grub_env_get (argi->str);
if (val)
size += grub_strlen (val);
switch (arg->type)
{
case GRUB_SCRIPT_ARG_TYPE_VAR:
value = grub_env_get (arg->str);
while (*value && (ptr = move_to_next(&value)))
{
empty = 0;
append (ptr, value - ptr);
if (*value) push(0);
}
break;
case GRUB_SCRIPT_ARG_TYPE_TEXT:
if (grub_strlen (arg->str) > 0)
{
empty = 0;
append (arg->str, 0);
}
break;
case GRUB_SCRIPT_ARG_TYPE_DQSTR:
case GRUB_SCRIPT_ARG_TYPE_SQSTR:
empty = 0;
append (arg->str, 0);
break;
case GRUB_SCRIPT_ARG_TYPE_DQVAR:
empty = 0;
append (grub_env_get (arg->str), 0);
break;
}
arg = arg->next;
}
else
size += grub_strlen (argi->str);
if (!empty)
push (0);
}
push (0); /* Ensure argv[argc] == 0. */
if (oom)
{
for (i = 0; i < argc; i++)
grub_free (argv[i]);
grub_free (argv);
argv = 0;
}
/* Create the argument. */
chararg = grub_malloc (size + 1);
if (! chararg)
return 0;
*chararg = '\0';
/* First determine the size of the argument. */
for (argi = arg; argi; argi = argi->next)
{
if (argi->type == 1)
{
val = grub_env_get (argi->str);
if (val)
grub_strcat (chararg, val);
}
else
grub_strcat (chararg, argi->str);
}
return chararg;
return argv;
}
/* Execute a single command line. */
@ -85,7 +182,6 @@ grub_err_t
grub_script_execute_cmdline (struct grub_script_cmd *cmd)
{
struct grub_script_cmdline *cmdline = (struct grub_script_cmdline *) cmd;
struct grub_script_arglist *arglist;
char **args = 0;
int i = 0;
grub_command_t grubcmd;
@ -96,7 +192,11 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd)
char *cmdname;
/* Lookup the command. */
cmdname = grub_script_execute_argument_to_string (cmdline->arglist->arg);
args = grub_script_execute_arglist_to_argv (cmdline->arglist);
if (!args)
return grub_errno;
cmdname = args[0];
grubcmd = grub_command_find (cmdname);
if (! grubcmd)
{
@ -129,27 +229,15 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd)
return 0;
}
}
grub_free (cmdname);
if (cmdline->arglist->next)
{
argcount = cmdline->arglist->argcount - 1;
/* Create argv from the arguments. */
args = grub_malloc (sizeof (char *) * argcount);
for (arglist = cmdline->arglist->next; arglist; arglist = arglist->next)
{
char *str;
str = grub_script_execute_argument_to_string (arglist->arg);
args[i++] = str;
}
}
/* Count argv size. */
for (argcount = 0; args[argcount]; argcount++);
/* Execute the GRUB command or function. */
if (grubcmd)
ret = (grubcmd->func) (grubcmd, argcount, args);
ret = (grubcmd->func) (grubcmd, argcount - 1, args + 1);
else
ret = grub_script_function_call (func, argcount, args);
ret = grub_script_function_call (func, argcount - 1, args + 1);
/* Free arguments. */
for (i = 0; i < argcount; i++)
@ -202,7 +290,6 @@ grub_err_t
grub_script_execute_menuentry (struct grub_script_cmd *cmd)
{
struct grub_script_cmd_menuentry *cmd_menuentry;
struct grub_script_arglist *arglist;
char **args = 0;
int argcount = 0;
int i = 0;
@ -211,22 +298,11 @@ grub_script_execute_menuentry (struct grub_script_cmd *cmd)
if (cmd_menuentry->arglist)
{
argcount = cmd_menuentry->arglist->argcount;
args = grub_script_execute_arglist_to_argv (cmd_menuentry->arglist);
if (!args)
return grub_errno;
/* Create argv from the arguments. */
args = grub_malloc (sizeof (char *) * argcount);
if (! args)
{
return grub_errno;
}
for (arglist = cmd_menuentry->arglist; arglist; arglist = arglist->next)
{
char *str;
str = grub_script_execute_argument_to_string (arglist->arg);
args[i++] = str;
}
for (argcount = 0; args[argcount]; argcount++);
}
grub_normal_add_menu_entry (argcount, (const char **) args,