[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