2005-08-12 Yoshinori K. Okuji <okuji@enbug.org>
* DISTLIST: Added normal/completion.c. * normal/completion.c: New file. * term/i386/pc/console.c (grub_console_getwh): New function. (grub_console_term): Assign grub_console_getwh to getwh. * normal/cmdline.c (grub_tab_complete): Removed. Now the same function is defined in normal/completion.c as grub_normal_do_completion. (grub_cmdline_get): Use grub_normal_do_completion instead of grub_tab_complete. * kern/partition.c (grub_partition_map_iterate): Return 1 if HOOK returns non-zero, otherwise return 0. (grub_partition_iterate): First, probe the partition map. Then, call ITERATE only for this partition map. * kern/misc.c (grub_strncmp): Rewritten. * kern/disk.c (grub_disk_dev_iterate): Return 1 if P->ITERATE returns non-zero. Otherwise return 0. * include/grub/partition.h (grub_partition_map_iterate): Return int instead of void. * include/grub/normal.h (grub_normal_do_completion): New prototype. * include/grub/misc.h (grub_strncmp): Change the type of N to grub_size_t. * include/grub/disk.h (grub_disk_dev_iterate): Return int instead of void. * normal/menu.c (draw_border): Cast GRUB_TERM_BORDER_WIDTH to unsigned explictly before comparing it with I. * kern/main.c (grub_env_write_root): Add the attribute unused into VAR. * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Added normal/completion.c. (normal_mod_SOURCES): Likewise. * conf/i386-pc.rmk (grub_emu_SOURCES): Likewise. (normal_mod_SOURCES): Likewise. * normal/command.c (grub_iterate_commands): If ITERATE returns non-zero, return one immediately.
This commit is contained in:
parent
e85e144bfc
commit
8de3495c7b
18 changed files with 192 additions and 348 deletions
300
normal/cmdline.c
300
normal/cmdline.c
|
@ -133,304 +133,6 @@ grub_history_replace (int pos, char *s)
|
|||
hist_lines[pos] = grub_strdup (s);
|
||||
}
|
||||
|
||||
/* Try to complete the string in BUF, return the characters that
|
||||
should be added to the string. This command outputs the possible
|
||||
completions, in that case set RESTORE to 1 so the caller can
|
||||
restore the prompt. */
|
||||
static char *
|
||||
grub_tab_complete (char *buf, int *restore)
|
||||
{
|
||||
char *pos = buf;
|
||||
char *path;
|
||||
|
||||
char *found = 0;
|
||||
int begin;
|
||||
int end;
|
||||
int len;
|
||||
int numfound = 0;
|
||||
|
||||
/* The disk that is used for grub_partition_iterate. */
|
||||
grub_device_t partdev;
|
||||
|
||||
/* String that is added when matched. */
|
||||
char *matchstr;
|
||||
|
||||
auto void print_simple_completion (char *comp);
|
||||
auto void print_partition_completion (char *comp);
|
||||
auto int NESTED_FUNC_ATTR add_completion (const char *comp, const char *match,
|
||||
const char *what,
|
||||
void (*print_completion) (char *));
|
||||
auto int iterate_commands (grub_command_t cmd);
|
||||
auto int iterate_dev (const char *devname);
|
||||
auto int iterate_part (const grub_partition_t p);
|
||||
auto int iterate_dir (const char *filename, int dir);
|
||||
|
||||
|
||||
|
||||
void print_simple_completion (char *comp)
|
||||
{
|
||||
grub_printf (" %s", comp);
|
||||
}
|
||||
|
||||
void print_partition_completion (char *comp)
|
||||
{
|
||||
grub_print_partinfo (partdev, comp);
|
||||
grub_errno = 0;
|
||||
}
|
||||
|
||||
/* Add a string to the list of possible completions. COMP is the
|
||||
string that should be added. If this string completely matches
|
||||
add the string MATCH to the input after adding COMP. The string
|
||||
WHAT contains a discription of the kind of data that is added.
|
||||
Use PRINT_COMPLETION to show the completions if there are
|
||||
multiple matches. XXX: Because of a bug in gcc it is required to
|
||||
use __regparm__ in some cases. */
|
||||
|
||||
int NESTED_FUNC_ATTR add_completion (const char *comp, const char *match,
|
||||
const char *what,
|
||||
void (*print_completion) (char *))
|
||||
{
|
||||
/* Bug in strncmp then len ==0. */
|
||||
if (!len || grub_strncmp (pos, comp, len) == 0)
|
||||
{
|
||||
numfound++;
|
||||
|
||||
if (numfound == 1)
|
||||
{
|
||||
begin = len;
|
||||
found = grub_strdup (comp);
|
||||
end = grub_strlen (found);
|
||||
matchstr = (char *) match;
|
||||
}
|
||||
/* Multiple matches found, print the first instead of completing. */
|
||||
else if (numfound == 2)
|
||||
{
|
||||
grub_printf ("\nPossible %s are:\n", what);
|
||||
print_completion (found);
|
||||
}
|
||||
|
||||
if (numfound > 1)
|
||||
{
|
||||
char *s1 = found;
|
||||
const char *s2 = comp;
|
||||
int cnt = 0;
|
||||
|
||||
print_completion ((char *) comp);
|
||||
|
||||
/* Find out how many characters match. */
|
||||
while ((cnt < end) && *s1 && *s2 && (*s1 == *s2))
|
||||
{
|
||||
s1++;
|
||||
s2++;
|
||||
cnt++;
|
||||
}
|
||||
end = cnt;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int iterate_part (const grub_partition_t p)
|
||||
{
|
||||
add_completion (grub_partition_get_name (p), ")", "partitions",
|
||||
print_partition_completion);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int iterate_dir (const char *filename, int dir)
|
||||
{
|
||||
if (!dir)
|
||||
add_completion (filename, " ", "files", print_simple_completion);
|
||||
else
|
||||
{
|
||||
char fname[grub_strlen (filename) + 2];
|
||||
grub_strcpy (fname, filename);
|
||||
grub_sprintf (fname, "%s/", filename);
|
||||
add_completion (fname, "", "files", print_simple_completion);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int iterate_dev (const char *devname)
|
||||
{
|
||||
grub_device_t dev;
|
||||
|
||||
/* Complete the partition part. */
|
||||
dev = grub_device_open (devname);
|
||||
|
||||
if (dev)
|
||||
{
|
||||
if (dev->disk && dev->disk->has_partitions)
|
||||
add_completion (devname, ",", "disks", print_simple_completion);
|
||||
else
|
||||
add_completion (devname, ")", "disks", print_simple_completion);
|
||||
}
|
||||
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int iterate_commands (grub_command_t cmd)
|
||||
{
|
||||
if (grub_command_find (cmd->name))
|
||||
{
|
||||
if (cmd->flags & GRUB_COMMAND_FLAG_CMDLINE)
|
||||
add_completion (cmd->name, " ", "commands",
|
||||
print_simple_completion);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Remove blank space on the beginning of the line. */
|
||||
while (*pos == ' ')
|
||||
pos++;
|
||||
|
||||
/* Check if the string is a command or path. */
|
||||
path = grub_strchr (pos, ' ');
|
||||
|
||||
if (!path)
|
||||
{
|
||||
/* Tab complete a command. */
|
||||
len = grub_strlen (pos);
|
||||
|
||||
grub_iterate_commands (iterate_commands);
|
||||
}
|
||||
else
|
||||
{
|
||||
pos = path;
|
||||
|
||||
/* Remove blank space on the beginning of the line. */
|
||||
while (*pos == ' ')
|
||||
pos++;
|
||||
|
||||
/* Check if this is a completion for a device name. */
|
||||
if (*pos == '(' && !grub_strchr (pos, ')'))
|
||||
{
|
||||
/* Check if this is a device or partition. */
|
||||
char *partition = grub_strchr (++pos, ',');
|
||||
|
||||
if (!partition)
|
||||
{
|
||||
/* Complete the disk part. */
|
||||
len = grub_strlen (pos);
|
||||
grub_disk_dev_iterate (iterate_dev);
|
||||
if (grub_errno)
|
||||
goto fail;
|
||||
}
|
||||
else
|
||||
{
|
||||
*partition = '\0';
|
||||
|
||||
/* Complete the partition part. */
|
||||
partdev = grub_device_open (pos);
|
||||
*partition = ',';
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
|
||||
if (partdev)
|
||||
{
|
||||
if (partdev->disk && partdev->disk->has_partitions)
|
||||
{
|
||||
pos = partition + 1;
|
||||
len = grub_strlen (pos);
|
||||
|
||||
grub_partition_iterate (partdev->disk, iterate_part);
|
||||
if (grub_errno)
|
||||
grub_errno = 0;
|
||||
}
|
||||
|
||||
grub_device_close (partdev);
|
||||
}
|
||||
else
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
char *device = grub_file_get_device_name (pos);
|
||||
grub_device_t dev;
|
||||
grub_fs_t fs;
|
||||
|
||||
dev = grub_device_open (device);
|
||||
if (!dev)
|
||||
goto fail;
|
||||
|
||||
fs = grub_fs_probe (dev);
|
||||
if (grub_errno)
|
||||
goto fail;
|
||||
|
||||
pos = grub_strrchr (pos, '/');
|
||||
if (pos)
|
||||
{
|
||||
char *dir;
|
||||
char *dirfile;
|
||||
pos++;
|
||||
len = grub_strlen (pos);
|
||||
|
||||
dir = grub_strchr (path, '/');
|
||||
if (!dir)
|
||||
{
|
||||
*restore = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
dir = grub_strdup (dir);
|
||||
|
||||
/* Cut away the filename part. */
|
||||
dirfile = grub_strrchr (dir, '/');
|
||||
dirfile[1] = '\0';
|
||||
|
||||
/* Tab complete a file. */
|
||||
(fs->dir) (dev, dir, iterate_dir);
|
||||
if (dev)
|
||||
grub_device_close (dev);
|
||||
|
||||
grub_free (device);
|
||||
grub_free (dir);
|
||||
|
||||
if (grub_errno)
|
||||
goto fail;
|
||||
}
|
||||
else
|
||||
{
|
||||
found = grub_strdup ("/");
|
||||
matchstr = "";
|
||||
numfound = 1;
|
||||
begin = 0;
|
||||
end = 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* If more than one match is found those matches will be printed and
|
||||
the prompt should be restored. */
|
||||
if (numfound > 1)
|
||||
*restore = 1;
|
||||
else
|
||||
*restore = 0;
|
||||
|
||||
/* Return the part that matches. */
|
||||
if (end && found)
|
||||
{
|
||||
char *insert;
|
||||
insert = grub_malloc (end - begin + 1 + sizeof (matchstr));
|
||||
grub_strncpy (insert, found + begin, end - begin);
|
||||
insert[end - begin] = '\0';
|
||||
if (numfound == 1)
|
||||
grub_strcat (insert, matchstr);
|
||||
grub_free (found);
|
||||
|
||||
return insert;
|
||||
}
|
||||
|
||||
fail:
|
||||
grub_free (found);
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
grub_cmdline_run (int nested)
|
||||
{
|
||||
|
@ -607,7 +309,7 @@ grub_cmdline_get (const char *prompt, char cmdline[], unsigned max_len,
|
|||
buf[lpos] = '\0';
|
||||
|
||||
|
||||
insert = grub_tab_complete (buf, &restore);
|
||||
insert = grub_normal_do_completion (buf, &restore);
|
||||
/* Restore the original string. */
|
||||
buf[lpos] = backup;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue