/* completion.c - complete a command, a disk, a partition or a file */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008,2009 Free Software Foundation, Inc.
*
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/partition.h>
/* The current word. */
static const char *current_word;
/* The matched string. */
static char *match;
/* The count of candidates. */
static int num_found;
/* The string to be appended. */
static const char *suffix;
/* The callback function to print items. */
/* The state the command line is in. */
/* Add a string to the list of possible completions. COMPLETION is the
string that should be added. EXTRA will be appended if COMPLETION
matches uniquely. The type TYPE specifies what kind of data is added. */
static int
{
{
num_found++;
switch (num_found)
{
case 1:
if (! match)
return 1;
break;
case 2:
if (print_func)
/* Fall through. */
default:
{
char *s = match;
const char *t = completion;
if (print_func)
/* Detect the matched portion. */
while (*s && *t && *s == *t)
{
s++;
t++;
}
*s = '\0';
}
break;
}
}
return 0;
}
static int
{
char *name;
int ret;
char *part_name;
part_name = grub_partition_get_name (p);
if (! part_name)
return 1;
if (! name)
return 1;
return ret;
}
static int
{
{
const char *prefix;
prefix = "\" ";
else if (cmdline_state == GRUB_PARSER_STATE_QUOTE)
prefix = "\' ";
else
prefix = " ";
return 1;
}
{
char *fname;
{
return 1;
}
}
return 0;
}
static int
{
/* Complete the partition part. */
if (dev)
{
{
return 1;
return 1;
}
else
{
return 1;
}
}
return 0;
}
/* Complete a device. */
static int
complete_device (void)
{
/* Check if this is a device or a partition. */
if (! p)
{
/* Complete the disk part. */
if (grub_disk_dev_iterate (iterate_dev))
return 1;
}
else
{
/* Complete the partition part. */
*p = '\0';
*p = ',';
if (dev)
{
{
{
return 1;
}
}
}
else
return 1;
}
return 0;
}
/* Complete a file. */
static int
complete_file (void)
{
char *device;
char *dir;
char *last_dir;
int ret = 0;
if (grub_errno != GRUB_ERR_NONE)
return 1;
if (! dev)
{
ret = 1;
goto fail;
}
if (! fs)
{
ret = 1;
goto fail;
}
'/');
if (dir)
{
char *dirfile;
if (! dir)
{
ret = 1;
goto fail;
}
/* Cut away the filename part. */
/* Iterate the directory. */
if (grub_errno)
{
ret = 1;
goto fail;
}
}
else
{
if (! match)
{
ret = 1;
goto fail;
}
suffix = "";
num_found = 1;
}
fail:
if (dev)
return ret;
}
/* Complete an argument. */
static int
{
return 0;
return 0;
return 1;
/* Add the short arguments. */
{
continue;
return 1;
}
/* First add the built-in arguments. */
return 1;
return 1;
/* Add the long arguments. */
{
char *longarg;
continue;
if (!longarg)
return 1;
{
return 1;
}
}
return 0;
}
static grub_parser_state_t
{
char use;
while (*cmdline)
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
caller can restore the prompt. */
char *
void (*hook) (const char *, grub_completion_type_t, int))
{
int argc;
char **argv;
/* Initialize variables. */
match = 0;
num_found = 0;
suffix = "";
print_func = hook;
*restore = 1;
return 0;
if (argc == 0)
current_word = "";
else
{
if (equals)
/* Complete the value of the variable. */
}
/* Determine the state the command line is in, depending on the
state, it can be determined how to complete. */
{
/* Complete a command. */
{
{
goto fail;
}
}
}
else if (*current_word == '-')
{
if (complete_arguments (buf))
goto fail;
}
{
/* Complete a device. */
if (complete_device ())
goto fail;
}
else
{
/* Complete a file. */
if (complete_file ())
goto fail;
}
/* If more than one match is found those matches will be printed and
the prompt should be restored. */
if (num_found > 1)
*restore = 1;
else
*restore = 0;
/* Return the part that matches. */
if (match)
{
char *ret;
char *escstr;
char *newstr;
int current_len;
int match_len;
int spaces = 0;
/* Count the number of spaces that have to be escaped. XXX:
More than just spaces have to be escaped. */
if (*escstr == ' ')
spaces++;
{
*(newstr++) = '\\';
}
*newstr = '\0';
if (num_found == 1)
if (*ret == '\0')
{
goto fail;
}
if (argc != 0)
return ret;
}
fail:
if (argc != 0)
{
}
return 0;
}