command.c 4.88 KB
Newer Older
wdenk's avatar
wdenk committed
1
/*
wdenk's avatar
wdenk committed
2
 * (C) Copyright 2000-2003
wdenk's avatar
wdenk committed
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
 * 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
 */

/*
 *  Command Processor Table
 */

#include <common.h>
#include <command.h>

int
do_version (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	extern char version_string[];
	printf ("\n%s\n", version_string);
	return 0;
}

int
do_echo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	int i, putnl = 1;

	for (i = 1; i < argc; i++) {
		char *p = argv[i], c;

		if (i > 1)
			putc(' ');
49
		while ((c = *p++) != '\0') {
wdenk's avatar
wdenk committed
50 51 52
			if (c == '\\' && *p == 'c') {
				putnl = 0;
				p++;
53
			} else {
wdenk's avatar
wdenk committed
54
				putc(c);
55 56
			}
		}
wdenk's avatar
wdenk committed
57 58 59 60 61 62 63 64 65 66 67
	}

	if (putnl)
		putc('\n');
	return 0;
}

/*
 * Use puts() instead of printf() to avoid printf buffer overflow
 * for long help messages
 */
wdenk's avatar
wdenk committed
68
int do_help (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
wdenk's avatar
wdenk committed
69 70 71 72
{
	int i;
	int rcode = 0;

wdenk's avatar
wdenk committed
73 74
	if (argc == 1) {	/*show list of commands */

75 76 77 78 79 80 81 82 83
		int cmd_items = &__u_boot_cmd_end -
				&__u_boot_cmd_start;	/* pointer arith! */
		cmd_tbl_t *cmd_array[cmd_items];
		int i, j, swaps;

		/* Make array of commands from .uboot_cmd section */
		cmdtp = &__u_boot_cmd_start;
		for (i = 0; i < cmd_items; i++) {
			cmd_array[i] = cmdtp++;
wdenk's avatar
wdenk committed
84 85
		}

86 87 88 89 90 91 92 93 94 95 96 97
		/* Sort command list (trivial bubble sort) */
		for (i = cmd_items - 1; i > 0; --i) {
			swaps = 0;
			for (j = 0; j < i; ++j) {
				if (strcmp (cmd_array[j]->name,
					    cmd_array[j + 1]->name) > 0) {
					cmd_tbl_t *tmp;
					tmp = cmd_array[j];
					cmd_array[j] = cmd_array[j + 1];
					cmd_array[j + 1] = tmp;
					++swaps;
				}
wdenk's avatar
wdenk committed
98
			}
99 100
			if (!swaps)
				break;
wdenk's avatar
wdenk committed
101
		}
wdenk's avatar
wdenk committed
102

wdenk's avatar
wdenk committed
103
		/* print short help (usage) */
104 105 106
		for (i = 0; i < cmd_items; i++) {
			const char *usage = cmd_array[i]->usage;

wdenk's avatar
wdenk committed
107
			/* allow user abort */
wdenk's avatar
wdenk committed
108
			if (ctrlc ())
wdenk's avatar
wdenk committed
109
				return 1;
110
			if (usage == NULL)
wdenk's avatar
wdenk committed
111
				continue;
112
			puts (usage);
wdenk's avatar
wdenk committed
113 114 115 116 117 118
		}
		return 0;
	}
	/*
	 * command help (long version)
	 */
wdenk's avatar
wdenk committed
119 120
	for (i = 1; i < argc; ++i) {
		if ((cmdtp = find_cmd (argv[i])) != NULL) {
wdenk's avatar
wdenk committed
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
#ifdef	CFG_LONGHELP
			/* found - print (long) help info */
			puts (cmdtp->name);
			putc (' ');
			if (cmdtp->help) {
				puts (cmdtp->help);
			} else {
				puts ("- No help available.\n");
				rcode = 1;
			}
			putc ('\n');
#else	/* no long help available */
			if (cmdtp->usage)
				puts (cmdtp->usage);
#endif	/* CFG_LONGHELP */
136
		} else {
wdenk's avatar
wdenk committed
137 138
			printf ("Unknown command '%s' - try 'help'"
				" without arguments for list of all"
wdenk's avatar
wdenk committed
139 140
				" known commands\n\n", argv[i]
					);
wdenk's avatar
wdenk committed
141 142 143 144 145 146
			rcode = 1;
		}
	}
	return rcode;
}

wdenk's avatar
wdenk committed
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177

cmd_tbl_t U_BOOT_CMD(HELP) = MK_CMD_ENTRY(
	"help",	CFG_MAXARGS,	1,	do_help,
 	"help    - print online help\n",
 	"[command ...]\n"
 	"    - show help information (for 'command')\n"
 	"'help' prints online help for the monitor commands.\n\n"
 	"Without arguments, it prints a short usage message for all commands.\n\n"
 	"To get detailed help information for specific commands you can type\n"
  "'help' with one or more command names as arguments.\n"
);

cmd_tbl_t U_BOOT_CMD(QUES) = MK_CMD_ENTRY(
	"?",	CFG_MAXARGS,	1,	do_help,
 	"?       - alias for 'help'\n",
	NULL
);

cmd_tbl_t U_BOOT_CMD(VERS) = MK_CMD_ENTRY(
	"version",	1,		1,	do_version,
 	"version - print monitor version\n",
	NULL
);

cmd_tbl_t U_BOOT_CMD(ECHO) = MK_CMD_ENTRY(
	"echo",	CFG_MAXARGS,	1,	do_echo,
 	"echo    - echo args to console\n",
 	"[args..]\n"
	"    - echo args to console; \\c suppresses newline\n"
);

wdenk's avatar
wdenk committed
178 179 180
/***************************************************************************
 * find command table entry for a command
 */
wdenk's avatar
wdenk committed
181
cmd_tbl_t *find_cmd (const char *cmd)
wdenk's avatar
wdenk committed
182 183
{
	cmd_tbl_t *cmdtp;
wdenk's avatar
wdenk committed
184
	cmd_tbl_t *cmdtp_temp = &__u_boot_cmd_start;	/*Init value */
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
	const char *p;
	int len;
	int n_found = 0;

	/*
	 * Some commands allow length modifiers (like "cp.b");
	 * compare command name only until first dot.
	 */
	len = ((p = strchr(cmd, '.')) == NULL) ? strlen (cmd) : (p - cmd);

	for (cmdtp = &__u_boot_cmd_start;
	     cmdtp != &__u_boot_cmd_end;
	     cmdtp++) {
		if (strncmp (cmd, cmdtp->name, len) == 0) {
			if (len == strlen (cmdtp->name))
				return cmdtp;	/* full match */

			cmdtp_temp = cmdtp;	/* abbreviated command ? */
			n_found++;
		}
wdenk's avatar
wdenk committed
205
	}
206
	if (n_found == 1) {			/* exactly one match */
wdenk's avatar
wdenk committed
207
		return cmdtp_temp;
208
	}
wdenk's avatar
wdenk committed
209

210
	return NULL;	/* not found or ambiguous command */
wdenk's avatar
wdenk committed
211
}