/*
* Command parsing routines for RTEMS monitor
*
* TODO:
*
* $Id$
*/
#include <rtems.h>
#include <rtems/monitor.h>
#include <stdio.h>
#include <string.h>
/*
* make_argv(cp): token-count
* Break up the command line in 'cp' into global argv[] and argc (return
* value).
*/
int
rtems_monitor_make_argv(
char *cp,
int *argc_p,
char **argv)
{
int argc = 0;
while ((cp = strtok(cp, " \t\n\r")))
{
argv[argc++] = cp;
cp = (char *) NULL;
}
argv[argc] = (char *) NULL; /* end of argv */
return *argc_p = argc;
}
/*
* Read and break up a monitor command
*
* We have to loop on the gets call, since it will return NULL under UNIX
* RTEMS when we get a signal (eg: SIGALRM).
*/
int
rtems_monitor_command_read(char *command,
int *argc,
char **argv)
{
static char monitor_prompt[32];
/*
* put node number in the prompt if we are multiprocessing
*/
if (!rtems_configuration_get_user_multiprocessing_table())
sprintf(monitor_prompt, "%s", MONITOR_PROMPT);
else if (rtems_monitor_default_node != rtems_monitor_node)
sprintf(monitor_prompt, "%d-%s-%d", rtems_monitor_node, MONITOR_PROMPT, rtems_monitor_default_node);
else
sprintf(monitor_prompt, "%d-%s", rtems_monitor_node, MONITOR_PROMPT);
#ifdef RTEMS_UNIX
/* RTEMS on unix gets so many interrupt system calls this is hosed */
printf("%s> ", monitor_prompt);
fflush(stdout);
while (gets(command) == (char *) 0)
;
#else
do
{
printf("%s> ", monitor_prompt);
fflush(stdout);
} while (gets(command) == (char *) 0);
#endif
return rtems_monitor_make_argv(command, argc, argv);
}
/*
* Look up a command in a command table
*
*/
rtems_monitor_command_entry_t *
rtems_monitor_command_lookup(
rtems_monitor_command_entry_t *table,
int argc,
char **argv
)
{
rtems_monitor_command_entry_t *p;
rtems_monitor_command_entry_t *abbreviated_match = 0;
int abbreviated_matches = 0;
char *command;
int command_length;
command = argv[0];
if ((table == 0) || (command == 0))
goto failed;
command_length = strlen(command);
for (p = table; p->command; p++)
if (STREQ(command, p->command)) /* exact match */
goto done;
else if (STRNEQ(command, p->command, command_length))
{
abbreviated_matches++;
abbreviated_match = p;
}
/* no perfect match; is there a non-ambigous abbreviated match? */
if ( ! abbreviated_match)
{
printf("Unrecognized command '%s'; try 'help'\n", command);
goto failed;
}
if (abbreviated_matches > 1)
{
printf("Command '%s' is ambiguous; try 'help'\n", command);
goto failed;
}
p = abbreviated_match;
done:
if (p->command_function == 0)
goto failed;
return p;
failed:
return 0;
}
void
rtems_monitor_command_usage(rtems_monitor_command_entry_t *table,
char *command_string)
{
rtems_monitor_command_entry_t *help = 0;
char *help_command_argv[2];
/* if first entry in table is a usage, then print it out */
if (command_string == 0)
{
if (STREQ(table->command, "--usage--") && table->usage)
help = table;
}
else
{
help_command_argv[0] = command_string;
help_command_argv[1] = 0;
help = rtems_monitor_command_lookup(table, 1, help_command_argv);
}
if (help)
printf("%s\n", help->usage);
}
void
rtems_monitor_help_cmd(
int argc,
char **argv,
unsigned32 command_arg,
boolean verbose
)
{
int arg;
rtems_monitor_command_entry_t *command;
command = (rtems_monitor_command_entry_t *) command_arg;
if (argc == 1)
rtems_monitor_command_usage(command, 0);
else
{
for (arg=1; argv[arg]; arg++)
rtems_monitor_command_usage(command, argv[arg]);
}
}