diff options
Diffstat (limited to 'cpukit/libmisc/monitor/mon-command.c')
-rw-r--r-- | cpukit/libmisc/monitor/mon-command.c | 244 |
1 files changed, 244 insertions, 0 deletions
diff --git a/cpukit/libmisc/monitor/mon-command.c b/cpukit/libmisc/monitor/mon-command.c new file mode 100644 index 0000000000..b16c8f06c0 --- /dev/null +++ b/cpukit/libmisc/monitor/mon-command.c @@ -0,0 +1,244 @@ +/** + * @file + * + * @brief Command support routines for RTEMS monitor. + */ + +/* + * $Id$ + * + * 2001-01-30 KJO (vac4050@cae597.rsc.raytheon.com): + * Fixed rtems_monitor_command_lookup() to accept partial + * commands to uniqeness. Added support for setting + * the monitor prompt via an environment variable: + * RTEMS_MONITOR_PROMPT + * + * CCJ: 26-3-2000, adding command history and command line + * editing. This code is donated from My Right Boot and not + * covered by GPL, only the RTEMS license. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <string.h> +#include <stdio.h> + +#include <rtems.h> +#include <rtems/monitor.h> + +static void +rtems_monitor_show_help ( + const rtems_monitor_command_entry_t *help_cmd, + int max_cmd_len +) +{ +#define MAX_HELP_LINE_LENGTH (75 - max_cmd_len - 2) + + if (help_cmd && help_cmd->command) + { + const char *help = help_cmd->usage; + int help_len = strlen (help); + int spaces = max_cmd_len - strlen (help_cmd->command); + int show_this_line = 0; + int line_one = 1; + int c; + + fprintf(stdout,"%s", help_cmd->command); + + if (help_len == 0) + { + fprintf(stdout," - No help associated.\n"); + return; + } + + while (help_len) + { + fprintf(stdout,"%*c", spaces, ' '); + + if (line_one) + fprintf(stdout," - "); + + spaces = max_cmd_len + 2; + line_one = 0; + + /* + * See if greater then the line length if so, work back + * from the end for a space, tab or lf or cr. + */ + + if (help_len > MAX_HELP_LINE_LENGTH) + { + for (show_this_line = MAX_HELP_LINE_LENGTH - 1; + show_this_line; + show_this_line--) + if ((help[show_this_line] == ' ') || + (help[show_this_line] == '\n') || + (help[show_this_line] == '\r')) + break; + + /* + * If show_this_line is 0, it is a very long word !! + */ + + if (show_this_line == 0) + show_this_line = MAX_HELP_LINE_LENGTH - 1; + } + else + show_this_line = help_len; + + for (c = 0; c < show_this_line; c++) + if ((help[c] == '\r') || (help[c] == '\n')) + show_this_line = c; + else + putchar (help[c]); + + fprintf(stdout,"\n"); + + help += show_this_line; + help_len -= show_this_line; + + /* + * Move past the line feeds or what ever else is being skipped. + */ + + while (help_len) + { + if ((*help != '\r') && (*help != '\n')) + break; + + if (*help != ' ') + { + help++; + help_len--; + break; + } + help++; + help_len--; + } + } + } +} + +void +rtems_monitor_command_usage( + const rtems_monitor_command_entry_t *table, + const char *command_name +) +{ + const rtems_monitor_command_entry_t *command = table; + int max_cmd_len = 0; + + /* if first entry in table is a usage, then print it out */ + + if (command_name && (*command_name != '\0')) + { + command = rtems_monitor_command_lookup (command_name); + + if (command) + rtems_monitor_show_help (command, strlen (command_name)); + else + fprintf(stdout,"Unrecognised command; try just 'help'\n"); + return; + } + + /* + * Find the largest command size. + */ + + while (command) + { + int len = command->command ? strlen (command->command) : 0 ; + + if (len > max_cmd_len) + max_cmd_len = len; + + command = command->next; + } + + max_cmd_len++; + + command = table; + + /* + * Now some nice formatting for the help. + */ + + while (command) + { + rtems_monitor_show_help (command, max_cmd_len); + command = command->next; + } +} + + +void rtems_monitor_help_cmd( + int argc, + char **argv, + const rtems_monitor_command_arg_t *command_arg, + bool verbose __attribute__((unused)) +) +{ + int arg; + const rtems_monitor_command_entry_t *command = + command_arg->monitor_command_entry; + + if (argc == 1) + rtems_monitor_command_usage(command, 0); + else + { + for (arg = 1; argv[arg]; arg++) + rtems_monitor_command_usage(command, argv[arg]); + } +} + +typedef struct { + const char *name; + size_t length; + const rtems_monitor_command_entry_t *match; +} rtems_monitor_command_lookup_entry; + +static bool rtems_monitor_command_lookup_routine( + const rtems_monitor_command_entry_t *e, + void *arg +) +{ + rtems_monitor_command_lookup_entry *le = + (rtems_monitor_command_lookup_entry *) arg; + + /* Check name */ + if (strncmp(e->command, le->name, le->length) == 0) { + /* Check for ambiguity */ + if (le->match == NULL) { + le->match = e; + } else { + return false; + } + } + + return true; +} + +/** + * @brief Looks for a command with the name @a name in the list of registered + * commands. + * + * The parameter @a name must not be NULL. + * + * Returns the corresponding command entry or NULL if no command is found. + */ +const rtems_monitor_command_entry_t *rtems_monitor_command_lookup( + const char *name +) +{ + rtems_monitor_command_lookup_entry e = { + .name = name, + .length = strlen( name), + .match = NULL + }; + + rtems_monitor_command_iterate(rtems_monitor_command_lookup_routine, &e); + + return e.match; +} |