2005-10-24 Marco Gerards <mgerards@xs4all.nl>
* include/grub/parser.h: New file. * kern/parser.c: Likewise. * conf/i386-pc.rmk (kernel_img_SOURCES): Add `kern/parser.c'. (grub_setup_SOURCES): Likewise. (grub_probefs_SOURCES): Likewise. (grub_emu_SOURCES): Likewise. (kernel_img_HEADERS): Add `parser.h'. * conf/powerpc-ieee1275.rmk (grubof_HEADERS): Add `parser.h'. (grub_emu_SOURCES): Add `kern/parser.c'. (grubof_SOURCES): Likewise. * conf/sparc64-ieee1275.rmk (grubof_HEADERS): Add `parser.h'. (grubof_SOURCES): Add `kern/parser.c'. * include/grub/misc.h (grub_split_cmdline): Removed prototype. * kern/misc.c (grub_split_cmdline): Removed function. * kern/rescue.c: Include <grub/parser.h>. (grub_enter_rescue_mode): Use `grub_parser_split_cmdline' instead of `grub_split_cmdline'. * normal/command.c: Include <grub/parser.h>. (grub_command_execute): Use `grub_parser_split_cmdline' instead of `grub_split_cmdline'. * normal/completion.c: Include <grub/parser.h>. (cmdline_state): New variable. (iterate_dir): End the filename with a quote depending on the command line state. (get_state): new function. (grub_normal_do_completion): Use `grub_parser_split_cmdline' to split the arguments and determine the current argument. When the argument string is not quoted, escape all spaces.
This commit is contained in:
parent
6d8f4b0e60
commit
04ccf3ec6f
14 changed files with 531 additions and 324 deletions
|
@ -24,6 +24,7 @@
|
|||
#include <grub/term.h>
|
||||
#include <grub/env.h>
|
||||
#include <grub/dl.h>
|
||||
#include <grub/parser.h>
|
||||
|
||||
static grub_command_t grub_command_list;
|
||||
|
||||
|
@ -203,7 +204,7 @@ grub_command_execute (char *cmdline, int interactive)
|
|||
char **arglist;
|
||||
int numargs;
|
||||
|
||||
if (grub_split_cmdline (cmdline, cmdline_get, &num, &args))
|
||||
if (grub_parser_split_cmdline (cmdline, cmdline_get, &num, &args))
|
||||
return 0;
|
||||
|
||||
/* In case of an assignment set the environment accordingly instead
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <grub/partition.h>
|
||||
#include <grub/disk.h>
|
||||
#include <grub/file.h>
|
||||
#include <grub/parser.h>
|
||||
|
||||
/* The current word. */
|
||||
static char *current_word;
|
||||
|
@ -41,6 +42,8 @@ static const char *suffix;
|
|||
/* The callback function to print items. */
|
||||
static void (*print_func) (const char *, grub_completion_type_t, int);
|
||||
|
||||
/* The state the command line is in. */
|
||||
static grub_parser_state_t cmdline_state;
|
||||
|
||||
|
||||
/* Add a string to the list of possible completions. COMPLETION is the
|
||||
|
@ -125,7 +128,15 @@ iterate_dir (const char *filename, int dir)
|
|||
{
|
||||
if (! dir)
|
||||
{
|
||||
if (add_completion (filename, " ", GRUB_COMPLETION_TYPE_FILE))
|
||||
const char *prefix;
|
||||
if (cmdline_state == GRUB_PARSER_STATE_DQUOTE)
|
||||
prefix = "\" ";
|
||||
else if (cmdline_state == GRUB_PARSER_STATE_QUOTE)
|
||||
prefix = "\' ";
|
||||
else
|
||||
prefix = " ";
|
||||
|
||||
if (add_completion (filename, prefix, GRUB_COMPLETION_TYPE_FILE))
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
|
@ -358,6 +369,19 @@ complete_arguments (char *command)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static grub_parser_state_t
|
||||
get_state (const char *cmdline)
|
||||
{
|
||||
grub_parser_state_t state = GRUB_PARSER_STATE_TEXT;
|
||||
char use;
|
||||
|
||||
while (*cmdline)
|
||||
state = grub_parser_cmdline_state (state, *(cmdline++), &use);
|
||||
return state;
|
||||
}
|
||||
|
||||
|
||||
/* Try to complete the string in BUF. Return the characters that
|
||||
should be added to the string. This command outputs the possible
|
||||
completions by calling HOOK, in that case set RESTORE to 1 so the
|
||||
|
@ -366,7 +390,8 @@ char *
|
|||
grub_normal_do_completion (char *buf, int *restore,
|
||||
void (*hook) (const char *, grub_completion_type_t, int))
|
||||
{
|
||||
char *first_word;
|
||||
int argc;
|
||||
char **argv;
|
||||
|
||||
/* Initialize variables. */
|
||||
match = 0;
|
||||
|
@ -375,45 +400,38 @@ grub_normal_do_completion (char *buf, int *restore,
|
|||
print_func = hook;
|
||||
|
||||
*restore = 1;
|
||||
|
||||
/* Find the first word. */
|
||||
for (first_word = buf; *first_word == ' '; first_word++)
|
||||
;
|
||||
|
||||
/* Find the delimeter of the current word. */
|
||||
for (current_word = first_word + grub_strlen (first_word);
|
||||
current_word > first_word;
|
||||
current_word--)
|
||||
if (*current_word == ' ' || *current_word == '=')
|
||||
break;
|
||||
|
||||
if (current_word == first_word)
|
||||
if (grub_parser_split_cmdline (buf, 0, &argc, &argv))
|
||||
return 0;
|
||||
|
||||
current_word = argv[argc];
|
||||
|
||||
/* Determine the state the command line is in, depending on the
|
||||
state, it can be determined how to complete. */
|
||||
cmdline_state = get_state (buf);
|
||||
|
||||
if (argc == 0)
|
||||
{
|
||||
/* Complete a command. */
|
||||
if (grub_iterate_commands (iterate_command))
|
||||
goto fail;
|
||||
}
|
||||
else if (*current_word == '-')
|
||||
{
|
||||
if (complete_arguments (buf))
|
||||
goto fail;
|
||||
}
|
||||
else if (*current_word == '(' && ! grub_strchr (current_word, ')'))
|
||||
{
|
||||
/* Complete a device. */
|
||||
if (complete_device ())
|
||||
goto fail;
|
||||
}
|
||||
else
|
||||
{
|
||||
current_word++;
|
||||
|
||||
if (*current_word == '-')
|
||||
{
|
||||
if (complete_arguments (buf))
|
||||
goto fail;
|
||||
}
|
||||
else if (*current_word == '(' && ! grub_strchr (current_word, ')'))
|
||||
{
|
||||
/* Complete a device. */
|
||||
if (complete_device ())
|
||||
goto fail;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Complete a file. */
|
||||
if (complete_file ())
|
||||
goto fail;
|
||||
}
|
||||
/* Complete a file. */
|
||||
if (complete_file ())
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* If more than one match is found those matches will be printed and
|
||||
|
@ -427,13 +445,32 @@ grub_normal_do_completion (char *buf, int *restore,
|
|||
if (match)
|
||||
{
|
||||
char *ret;
|
||||
char *escstr;
|
||||
char *newstr;
|
||||
int current_len;
|
||||
int match_len;
|
||||
int spaces = 0;
|
||||
|
||||
current_len = grub_strlen (current_word);
|
||||
match_len = grub_strlen (match);
|
||||
ret = grub_malloc (match_len - current_len + grub_strlen (suffix) + 1);
|
||||
grub_strcpy (ret, match + current_len);
|
||||
|
||||
/* Count the number of spaces that have to be escaped. XXX:
|
||||
More than just spaces have to be escaped. */
|
||||
for (escstr = match + current_len; *escstr; escstr++)
|
||||
if (*escstr == ' ')
|
||||
spaces++;
|
||||
|
||||
ret = grub_malloc (match_len - current_len + grub_strlen (suffix) + spaces + 1);
|
||||
newstr = ret;
|
||||
for (escstr = match + current_len; *escstr; escstr++)
|
||||
{
|
||||
if (*escstr == ' ' && cmdline_state != GRUB_PARSER_STATE_QUOTE
|
||||
&& cmdline_state != GRUB_PARSER_STATE_QUOTE)
|
||||
*(newstr++) = '\\';
|
||||
*(newstr++) = *escstr;
|
||||
}
|
||||
*newstr = '\0';
|
||||
|
||||
if (num_found == 1)
|
||||
grub_strcat (ret, suffix);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue