summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--commands/Kconfig4
-rw-r--r--commands/Makefile2
-rw-r--r--commands/readline.c60
-rw-r--r--common/command.c106
-rw-r--r--include/list.h24
-rw-r--r--lib/driver.c2
6 files changed, 127 insertions, 71 deletions
diff --git a/commands/Kconfig b/commands/Kconfig
index 6ec703133b..8d1ca9da39 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -27,6 +27,10 @@ config CMD_HELP
default y
prompt "help"
+config CMD_READLINE
+ tristate
+ prompt "readline"
+
endmenu
menu "file commands "
diff --git a/commands/Makefile b/commands/Makefile
index b010d6678e..f57d1dee48 100644
--- a/commands/Makefile
+++ b/commands/Makefile
@@ -32,4 +32,4 @@ obj-$(CONFIG_CMD_TEST) += test.o
obj-$(CONFIG_CMD_FLASH) += flash.o
obj-$(CONFIG_CMD_MEMINFO) += meminfo.o
obj-$(CONFIG_CMD_TIMEOUT) += timeout.o
-
+obj-$(CONFIG_CMD_READLINE) += readline.o
diff --git a/commands/readline.c b/commands/readline.c
new file mode 100644
index 0000000000..921b72aeb8
--- /dev/null
+++ b/commands/readline.c
@@ -0,0 +1,60 @@
+/*
+ * (C) Copyright 2000-2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <command.h>
+#include <malloc.h>
+#include <xfuncs.h>
+#include <environment.h>
+
+static int do_readline (cmd_tbl_t *cmdtp, int argc, char *argv[])
+{
+ char *buf = xzalloc(CONFIG_CBSIZE);
+
+ if (argc < 3) {
+ u_boot_cmd_usage(cmdtp);
+ return 1;
+ }
+
+ if (readline(argv[1], buf, CONFIG_CBSIZE) < 0) {
+ free(buf);
+ return 1;
+ }
+
+ setenv(argv[2], buf);
+ free(buf);
+
+ return 0;
+}
+
+static __maybe_unused char cmd_readline_help[] =
+"Usage: readline <prompt> VAR\n"
+"readline reads a line of user input into variable VAR.\n";
+
+U_BOOT_CMD_START(readline)
+ .maxargs = 3,
+ .cmd = do_readline,
+ .usage = "prompt for user input",
+ U_BOOT_CMD_HELP(cmd_readline_help)
+U_BOOT_CMD_END
+
diff --git a/common/command.c b/common/command.c
index c78da7e3a5..fdd7444e6d 100644
--- a/common/command.c
+++ b/common/command.c
@@ -73,37 +73,6 @@ U_BOOT_CMD_END
#ifdef CONFIG_SHELL_HUSH
-static int do_readline (cmd_tbl_t *cmdtp, int argc, char *argv[])
-{
- char *buf = xzalloc(CONFIG_CBSIZE);
-
- if (argc < 3) {
- u_boot_cmd_usage(cmdtp);
- return 1;
- }
-
- if (readline(argv[1], buf, CONFIG_CBSIZE) < 0) {
- free(buf);
- return 1;
- }
-
- setenv(argv[2], buf);
- free(buf);
-
- return 0;
-}
-
-static __maybe_unused char cmd_readline_help[] =
-"Usage: readline <prompt> VAR\n"
-"readline reads a line of user input into variable VAR.\n";
-
-U_BOOT_CMD_START(readline)
- .maxargs = 3,
- .cmd = do_readline,
- .usage = "prompt for user input",
- U_BOOT_CMD_HELP(cmd_readline_help)
-U_BOOT_CMD_END
-
static int do_exit (cmd_tbl_t *cmdtp, int argc, char *argv[])
{
int r;
@@ -150,32 +119,17 @@ EXPORT_SYMBOL(u_boot_cmd_usage);
*/
static int do_help (cmd_tbl_t * cmdtp, int argc, char *argv[])
{
- if (argc == 1) { /*show list of commands */
- int cmd_items = &__u_boot_cmd_end -
- &__u_boot_cmd_start; /* pointer arith! */
- int i;
-
- /* No need to sort the command list. The linker already did
- * this for us.
- */
- cmdtp = &__u_boot_cmd_start;
- for (i = 0; i < cmd_items; i++) {
- /* print short help (usage) */
-
- /* allow user abort */
- if (ctrlc ())
- return 1;
+ if (argc == 1) { /* show list of commands */
+ for_each_command(cmdtp) {
if (!cmdtp->usage)
continue;
printf("%10s - %s\n", cmdtp->name, cmdtp->usage);
- cmdtp++;
}
return 0;
}
- /*
- * command help (long version)
- */
- if ((cmdtp = find_cmd (argv[1])) != NULL) {
+
+ /* command help (long version) */
+ if ((cmdtp = find_cmd(argv[1])) != NULL) {
u_boot_cmd_usage(cmdtp);
return 0;
} else {
@@ -204,7 +158,13 @@ U_BOOT_CMD_START(help)
U_BOOT_CMD_HELP(cmd_help_help)
U_BOOT_CMD_END
-#ifdef CONFIG_MODULES
+static int compare(struct list_head *a, struct list_head *b)
+{
+ char *na = list_entry(a, cmd_tbl_t, list)->name;
+ char *nb = list_entry(b, cmd_tbl_t, list)->name;
+
+ return strcmp(na, nb);
+}
int register_command(cmd_tbl_t *cmd)
{
@@ -214,17 +174,37 @@ int register_command(cmd_tbl_t *cmd)
* with a module.
*/
- printf("register command %s\n", cmd->name);
+ debug("register command %s\n", cmd->name);
/*
* Would be nice to have some kind of list_add_sort
* to keep the command list in order
*/
- list_add_tail(&cmd->list, &command_list);
+ list_add_sort(&cmd->list, &command_list, compare);
+
+ if (cmd->aliases) {
+ char **aliases = cmd->aliases;
+ while(*aliases) {
+ char *usage = "alias for ";
+ cmd_tbl_t *c = xzalloc(sizeof(cmd_tbl_t));
+
+ memcpy(c, cmd, sizeof(cmd_tbl_t));
+
+ c->name = *aliases;
+ c->usage = xmalloc(strlen(usage) + strlen(cmd->name) + 1);
+ sprintf(c->usage, "%s%s", usage, cmd->name);
+
+ c->aliases = NULL;
+
+ register_command(c);
+
+ aliases++;
+ }
+ }
return 0;
}
-#endif
+EXPORT_SYMBOL(register_command);
/*
* find command table entry for a command
@@ -247,20 +227,6 @@ cmd_tbl_t *find_cmd (const char *cmd)
cmdtp_temp = cmdtp; /* abbreviated command ? */
n_found++;
}
-
- if (cmdtp->aliases) {
- char **aliases = cmdtp->aliases;
- while(*aliases) {
- if (strncmp (cmd, *aliases, len) == 0) {
- if (len == strlen (cmdtp->name))
- return cmdtp; /* full match */
-
- cmdtp_temp = cmdtp; /* abbreviated command ? */
- n_found++;
- }
- aliases++;
- }
- }
}
if (n_found == 1) { /* exactly one match */
@@ -283,7 +249,7 @@ static int init_command_list(void)
for (cmdtp = &__u_boot_cmd_start;
cmdtp != &__u_boot_cmd_end;
cmdtp++)
- list_add_tail(&cmdtp->list, &command_list);
+ register_command(cmdtp);
return 0;
}
diff --git a/include/list.h b/include/list.h
index 17d3576ed2..1e8bc51b9d 100644
--- a/include/list.h
+++ b/include/list.h
@@ -429,6 +429,30 @@ static inline void list_splice_init(struct list_head *list,
&pos->member != (head); \
pos = n, n = list_entry(n->member.prev, typeof(*n), member))
+/**
+ * list_add_sort - add a new entry to a sorted list
+ * @new: new entry to be added
+ * @head: list head to add it in
+ * @compare: Compare function to compare two list entries
+ *
+ * Insert a new entry before the specified head.
+ * This is useful for implementing queues.
+ */
+static inline void list_add_sort(struct list_head *new, struct list_head *head,
+ int (*compare)(struct list_head *a, struct list_head *b))
+{
+ struct list_head *pos, *insert = head;
+
+ list_for_each(pos, head) {
+ if (compare(pos, new) < 0)
+ continue;
+ insert = pos;
+ break;
+ }
+
+ list_add_tail(new, insert);
+}
+
/*
* Double linked lists with a single pointer list head.
* Mostly useful for hash tables where the two pointer list head is
diff --git a/lib/driver.c b/lib/driver.c
index b16a9e3841..a356b4e118 100644
--- a/lib/driver.c
+++ b/lib/driver.c
@@ -127,6 +127,7 @@ int dev_add_child(struct device_d *dev, struct device_d *child)
return 0;
}
+EXPORT_SYMBOL(dev_add_child);
struct driver_d *get_driver_by_name(const char *name)
{
@@ -181,6 +182,7 @@ struct device_d *get_device_by_path(const char *path)
return get_device_by_id(path + 5);
}
+EXPORT_SYMBOL(get_device_by_path);
ssize_t dev_read(struct device_d *dev, void *buf, size_t count, unsigned long offset, ulong flags)
{