parse.c
来自「开放源码实时操作系统源码.」· C语言 代码 · 共 492 行 · 第 1/2 页
C
492 行
//==========================================================================
//
// parse.c
//
// RedBoot command line parsing routine
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
// Copyright (C) 2004, 2005, 2006 eCosCentric Limited
//
// eCos 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 or (at your option) any later version.
//
// eCos 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 eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): gthomas
// Contributors: gthomas, eCosCentric
// Date: 2000-07-14
// Purpose:
// Description:
//
// This code is part of RedBoot (tm).
//
//####DESCRIPTIONEND####
//
//==========================================================================
#include <redboot.h>
#include <cyg/hal/hal_arch.h>
#include <cyg/hal/hal_intr.h>
#include <cyg/hal/hal_cache.h>
#include CYGHWR_MEMORY_LAYOUT_H
#include <cyg/hal/hal_tables.h>
// Define table boundaries
extern struct cmd __RedBoot_CMD_TAB__[], __RedBoot_CMD_TAB_END__;
//
// Scan through an input line and break it into "arguments". These
// are space delimited strings. Return a structure which points to
// the strings, similar to a Unix program. Multiple commands in the line
// are separated by ; similar to sh. If we find a semi we stop processing the
// line, terminate the current command with a null and return the start
// of the next command in *line. parse() can then be called again to
// process the next command on the line.
// Note: original input is destroyed by replacing the delimiters with
// null ('\0') characters for ease of use.
//
struct cmd *
parse(char **line, int *argc, char **argv)
{
char *cp = *line;
char *pp;
int indx = 0;
int semi = 0;
while (*cp) {
// Skip leading spaces
while (*cp && *cp == ' ') cp++;
if (!*cp) {
break; // Line ended with a string of spaces
}
if (*cp == ';') {
*cp = '\0';
semi=1;
break;
}
if (indx < MAX_ARGV) {
argv[indx++] = cp;
} else {
diag_printf("Too many arguments - stopped at: '%s'\n", cp);
}
while (*cp) {
if (*cp == ' ') {
*cp++ = '\0';
break;
} else if (*cp == ';') {
break;
} else if (*cp == '"') {
// Swallow quote, scan till following one
if (argv[indx-1] == cp) {
argv[indx-1] = ++cp;
}
pp = cp;
while (*cp && *cp != '"') {
if (*cp == '\\') {
// Skip over escape - allows for escaped '"'
cp++;
}
// Move string to swallow escapes
*pp++ = *cp++;
}
if (!*cp) {
diag_printf("Unbalanced string!\n");
} else {
if (pp != cp) *pp = '\0';
*cp++ = '\0';
break;
}
} else {
cp++;
}
}
}
if (semi) {
*line = cp + 1;
} else {
*line = cp;
}
*argc = indx;
return cmd_search(__RedBoot_CMD_TAB__, &__RedBoot_CMD_TAB_END__, argv[0]);
}
//
// Search through a list of commands
//
struct cmd *
cmd_search(struct cmd *tab, struct cmd *tabend, char *arg)
{
int cmd_len;
struct cmd *cmd, *cmd2;
// Search command table
cmd_len = strlen(arg);
cmd = tab;
while (cmd != tabend) {
if (strncasecmp(arg, cmd->str, cmd_len) == 0) {
if (strlen(cmd->str) > cmd_len) {
// Check for ambiguous commands here
// Note: If there are commands which are not length-unique
// then this check will be invalid. E.g. "du" and "dump"
bool first = true;
cmd2 = tab;
while (cmd2 != tabend) {
if ((cmd != cmd2) &&
(strncasecmp(arg, cmd2->str, cmd_len) == 0)) {
if (first) {
diag_printf("Ambiguous command '%s', choices are: %s",
arg, cmd->str);
first = false;
}
diag_printf(" %s", cmd2->str);
}
cmd2++;
}
if (!first) {
// At least one ambiguity found - fail the lookup
diag_printf("\n");
return (struct cmd *)0;
}
}
return cmd;
}
cmd++;
}
return (struct cmd *)0;
}
void
cmd_usage(struct cmd *tab, struct cmd *tabend, char *prefix)
{
struct cmd *cmd;
diag_printf("Usage:\n");
for (cmd = tab; cmd != tabend; cmd++) {
diag_printf(" %s%s %s\n", prefix, cmd->str, cmd->usage);
}
}
//
// Handle illegal memory accesses (and other abort conditions)
//
static hal_jmp_buf error_jmpbuf;
static cyg_bool redboot_exec_call = false;
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
__externC void* volatile __mem_fault_handler;
static void error_handler(void)
{
hal_longjmp(error_jmpbuf, 1);
}
#endif
// Routine to allow code to invoke RedBoot commands. This is useful
// during initialization and in platform specific code.
//
// Call it like this:
//
// result = redboot_exec( "load", "-m", "file", "foo", 0 );
//
// Note the terminating zero. The result will be zero if the command
// succeeded, and <0 if something went wrong.
#define ARGV_MAX 20
int redboot_exec( char *command, ... )
{
int argc;
char *argv[ARGV_MAX+1];
va_list ap;
struct cmd *cmd;
int result = 0;
va_start(ap, command);
argv[0] = command;
for( argc = 1; argc < ARGV_MAX; argc++ )
{
char *arg = va_arg(ap, char *);
if( arg == 0 )
break;
argv[argc] = arg;
}
argv[argc] = NULL;
if(( cmd = cmd_search(__RedBoot_CMD_TAB__, &__RedBoot_CMD_TAB_END__, command) ))
{
// Try to handle aborts - messy because of the stack unwinding...
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
__mem_fault_handler = error_handler;
#endif
redboot_exec_call = true;
if (hal_setjmp(error_jmpbuf))
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?