[coreboot] [FILO] r133 - in trunk/filo: fs main/grub
repository service
svn at coreboot.org
Thu Jun 3 19:36:15 CEST 2010
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 at 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
}
More information about the coreboot
mailing list