Author: stepan Date: Thu Jun 3 19:36:15 2010 New Revision: 133 URL: http://tracker.coreboot.org/trac/filo/changeset/133
Log: initial tab completion support. device matching fails, so only commands can be completed so far. Signed-off-by: Stefan Reinauer stepan@coresystems.de
Modified: trunk/filo/fs/vfs.c trunk/filo/main/grub/completions.c
Modified: trunk/filo/fs/vfs.c ============================================================================== --- trunk/filo/fs/vfs.c Mon May 24 23:59:35 2010 (r132) +++ trunk/filo/fs/vfs.c Thu Jun 3 19:36:15 2010 (r133) @@ -240,3 +240,71 @@ { devclose(); } + +int dir(char *dirname) +{ + char *dev = 0; + const char *path; + int len; + int retval = 0; + int reopen; + + path = strchr(dirname, ':'); + if (path) { + len = path - dirname; + path++; + dev = malloc(len + 1); + memcpy(dev, dirname, len); + dev[len] = '\0'; + } else { + /* No colon is given. Is this device or dirname? */ + if (dirname[0] == '/') { + /* Anything starts with '/' must be a dirname */ + dev = 0; + path = dirname; + } else { + dev = strdup(dirname); + path = 0; + } + } + debug("dev=%s, path=%s\n", dev, path); + + if (dev && dev[0]) { + if (!devopen(dev, &reopen)) { + fsys = 0; + goto out; + } + if (!reopen) + fsys = 0; + } + + if (path) { + if (!fsys || fsys == &nullfs) { + if (!mount_fs()) + goto out; + } + using_devsize = 0; + if (!path[0]) { + printf("No dirname is given.\n"); + goto out; + } + } else { + fsys = &nullfs; + } + + filepos = 0; + errnum = 0; + + /* set "dir" function to list completions */ + print_possibilities = 1; + + retval = fsys->dir_func((char *) path); + +out: + if (dev) + free(dev); + + return retval; +} + +
Modified: trunk/filo/main/grub/completions.c ============================================================================== --- trunk/filo/main/grub/completions.c Mon May 24 23:59:35 2010 (r132) +++ trunk/filo/main/grub/completions.c Thu Jun 3 19:36:15 2010 (r133) @@ -22,11 +22,47 @@ #include <libpayload.h> #include <config.h> #include <grub/shared.h> +#define current_slice 0
static int do_completion; static int unique; static char *unique_string;
+static int incomplete, disk_choice; +static enum +{ + PART_UNSPECIFIED = 0, + PART_DISK, + PART_CHOSEN, +} part_choice; + +int +real_open_partition (int flags) +{ + errnum = ERR_NONE; + return 1; +} + +int +open_partition (void) +{ + return real_open_partition (0); +} + +char * +set_device (char *device) +{ + int result = 0; + + if (result) { + return device + 1; + } else { + if (!*device) + incomplete = 1; + errnum = ERR_DEV_FORMAT; + } + return 0; +}
/* If DO_COMPLETION is true, just print NAME. Otherwise save the unique part into UNIQUE_STRING. */ @@ -62,7 +98,6 @@
int print_completions(int is_filename, int is_completion) { -#ifdef CONFIG_EXPERIMENTAL char *buf = (char *) COMPLETION_BUF; char *ptr = buf;
@@ -71,10 +106,162 @@ unique = 0; do_completion = is_completion;
-#warning FIXME implement print_completions - // FIXME: This function is a dummy, returning an error. - errnum = ERR_BAD_FILENAME; + if (!is_filename) { + /* Print the completions of builtin commands. */ + struct builtin **builtin; + + if (!is_completion) + grub_printf (" Possible commands are:"); + + for (builtin = builtin_table; (*builtin); builtin++) { + /* If *builtin cannot be run in the command-line, skip it. */ + if (!((*builtin)->flags & BUILTIN_CMDLINE)) + continue; + if (substring (buf, (*builtin)->name) <= 0) + print_a_completion ((*builtin)->name); + }
+ if (is_completion && *unique_string) { + if (unique == 1) { + char *u = unique_string + strlen (unique_string); + *u++ = ' '; + *u = 0; + } + strcpy (buf, unique_string); + } + + if (!is_completion) + grub_putchar ('\n'); + + print_error(); + do_completion = 0; + if (errnum) + return -1; + else + return unique - 1; + } + + if (*buf == '/' || (ptr = set_device (buf)) || incomplete) { + errnum = 0; + if (*buf == '(' && (incomplete || ! *ptr)) { + if (!part_choice) { + /* disk completions */ + int disk_no, i, j; + + if (!is_completion) + grub_printf (" Possible disks are: "); + + if (!ptr + || *(ptr-1) != 'd' + || *(ptr-2) != 'n' /* netboot? */ + || *(ptr-2) != 'c') { + for (i = (ptr && (*(ptr-1) == 'd' && *(ptr-2) == 'h') ? 1:0); + i < (ptr && (*(ptr-1) == 'd' && *(ptr-2) == 'f') ? 1:2); + i++) { + for (j = 0; j < 8; j++) { + if ((disk_choice)) { // TODO check geometry + char dev_name[8]; + sprintf (dev_name, "%cd%d", i ? 'h':'f', j); + print_a_completion(dev_name); + } + } + } + } + +#if 0 + if (cdrom_drive != GRUB_INVALID_DRIVE + && (disk_choice || cdrom_drive == current_drive) + && (!ptr + || *(ptr-1) == '(' + || (*(ptr-1) == 'd' && *(ptr-2) == 'c'))) + print_a_completion("cd"); +#endif + + if (is_completion && *unique_string) { + ptr = buf; + while (*ptr != '(') + ptr--; + ptr++; + strcpy (ptr, unique_string); + if (unique == 1) { + ptr += strlen (ptr); + if (*unique_string == 'h') { + *ptr++ = ','; + *ptr = 0; + } else { + *ptr++ = ')'; + *ptr = 0; + } + } + } + + if (!is_completion) + grub_putchar('\n'); + } else { + /* Partition completions */ + if (part_choice == PART_CHOSEN + && open_partition() + && ! IS_PC_SLICE_TYPE_BSD(current_slice)) { + unique = 1; + ptr = buf + strlen(buf); + if (*(ptr - 1) != ')') { + *ptr++ = ')'; + *ptr = 0; + } + } else { + if (!is_completion) + grub_printf (" Possible partitions are:\n"); + real_open_partition(1); + if (is_completion && *unique_string) { + ptr = buf; + while (*ptr++ != ',') + ; + strcpy (ptr, unique_string); + } + } + } + } else if (ptr && *ptr == '/') { + /* filename completions */ + if (!is_completion) + grub_printf (" Possible files are:"); + dir(buf); + + if (is_completion && *unique_string) { + ptr += strlen (ptr); + while (*ptr != '/') + ptr--; + ptr++; + + strcpy(ptr, unique_string); + + if (unique == 1) { + ptr += strlen (unique_string); + + /* Check if the file UNIQUE_STRING is a directory. */ + *ptr = '/'; + *(ptr + 1) = 0; + + dir (buf); + + /* Restore the original unique value. */ + unique = 1; + + if (errnum) { + /* regular file */ + errnum = 0; + *ptr = ' '; + *(ptr + 1) = 0; + } + } + } + + if (!is_completion) + grub_putchar ('\n'); + + } else { + errnum = ERR_BAD_FILENAME; + } + }
print_error(); do_completion = 0; @@ -82,9 +269,4 @@ return -1; else return unique - 1; -#else - errnum = ERR_BAD_FILENAME; - print_error(); - return -1; -#endif }