📄 mon-command.c
字号:
/* * Command parsing routines for RTEMS monitor * * TODO: * * $Id: mon-command.c,v 1.12.2.1 2003/07/08 08:37:40 ralf Exp $ */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <rtems.h>#include <rtems/monitor.h>#include <stdio.h>#include <string.h>#include <stdlib.h>/* * 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. *//* * Some key labels to define special keys. */#define KEYS_EXTENDED (0x8000)#define KEYS_NORMAL_MASK (0x00ff)#define KEYS_INS (0)#define KEYS_DEL (1)#define KEYS_UARROW (2)#define KEYS_DARROW (3)#define KEYS_LARROW (4)#define KEYS_RARROW (5)#define KEYS_HOME (6)#define KEYS_END (7) #define KEYS_F1 (8) #define KEYS_F2 (9) #define KEYS_F3 (10)#define KEYS_F4 (11)#define KEYS_F5 (12)#define KEYS_F6 (13)#define KEYS_F7 (14)#define KEYS_F8 (15)#define KEYS_F9 (16)#define KEYS_F10 (17)#define RTEMS_COMMAND_BUFFER_SIZE (75)static char monitor_prompt[32];#ifndef RTEMS_UNIXstatic char buffer[RTEMS_COMMAND_BUFFER_SIZE];static int pos;static int logged_in;#endif/* * History data. */#define RTEMS_COMMAND_HISTORIES (20)#ifndef RTEMS_UNIXstatic char history_buffer[RTEMS_COMMAND_HISTORIES][RTEMS_COMMAND_BUFFER_SIZE];static int history_pos[RTEMS_COMMAND_HISTORIES];static int history;static int history_next;#endif/* * Translation tables. Not sure if this is the best way to * handle this, how-ever I wish to avoid the overhead of * including a more complete and standard environment such * as ncurses. */struct translation_table{ char expecting; struct translation_table *branch; unsigned int key;};static struct translation_table trans_two[] ={ { '~', 0, KEYS_INS }, { 0, 0, 0 }};static struct translation_table trans_three[] ={ { '~', 0, KEYS_DEL }, { 0, 0, 0 }};static struct translation_table trans_tab_csi[] ={ { '2', trans_two, 0 }, { '3', trans_three, 0 }, { 'A', 0, KEYS_UARROW }, { 'B', 0, KEYS_DARROW }, { 'D', 0, KEYS_LARROW }, { 'C', 0, KEYS_RARROW }, { 'F', 0, KEYS_END }, { 'H', 0, KEYS_HOME }, { 0, 0, 0 }};static struct translation_table trans_tab_O[] ={ { '1', 0, KEYS_F1 }, { '2', 0, KEYS_F2 }, { '3', 0, KEYS_F3 }, { '4', 0, KEYS_F4 }, { '5', 0, KEYS_F5 }, { '6', 0, KEYS_F6 }, { '7', 0, KEYS_F7 }, { '8', 0, KEYS_F8 }, { '9', 0, KEYS_F9 }, { ':', 0, KEYS_F10 }, { 'P', 0, KEYS_F1 }, { 'Q', 0, KEYS_F2 }, { 'R', 0, KEYS_F3 }, { 'S', 0, KEYS_F4 }, { 'T', 0, KEYS_F5 }, { 'U', 0, KEYS_F6 }, { 'V', 0, KEYS_F7 }, { 'W', 0, KEYS_F8 }, { 'X', 0, KEYS_F9 }, { 'Y', 0, KEYS_F10 }, { 0, 0, 0 }};static struct translation_table trans_tab[] ={ { '[', trans_tab_csi, 0 }, /* CSI command sequences */ { 'O', trans_tab_O, 0 }, /* O are the fuction keys */ { 0, 0, 0 }};/* * Perform a basic tranlation for some ANSI/VT100 key codes. * This code could do with a timeout on the ESC as it is * now lost from the input stream. It is not* used by the * line editor below so considiered not worth the effort. */static unsigned intrtems_monitor_getchar (){ struct translation_table *translation = 0; for (;;) { char c = getchar (); if (c == 27) translation = trans_tab; else { /* * If no translation happing just pass through * and return the key. */ if (translation) { /* * Scan the current table for the key, and if found * see if this key is a fork. If so follow it and * wait else return the extended key. */ int index = 0; int branched = 0; while ((translation[index].expecting != '\0') || (translation[index].key != '\0')) { if (translation[index].expecting == c) { /* * A branch is take if more keys are to come. */ if (translation[index].branch == 0) return KEYS_EXTENDED | translation[index].key; else { translation = translation[index].branch; branched = 1; break; } } index++; } /* * Who knows what these keys are, just drop them. */ if (!branched) translation = 0; } else return c; } }}#ifndef RTEMS_UNIX/* * The line editor with history. */static intrtems_monitor_line_editor ( char *command){ int repeating = 0; memset (buffer, 0, RTEMS_COMMAND_BUFFER_SIZE); history = history_next; pos = 0; if (!logged_in) printf ("\nMonitor ready, press enter to login.\n\n"); else printf ("%s $ ", monitor_prompt); while (1) { unsigned int extended_key = rtems_monitor_getchar (); char c = extended_key & KEYS_NORMAL_MASK; /* * Make the extended_key usable as a boolean. */ extended_key &= ~KEYS_NORMAL_MASK; if (!extended_key && !logged_in) { if (c == '\n') { logged_in = 1; /* * The prompt has changed from `>' to `$' to help know * which version of the monitor code people are using. */ printf("%s $ ", monitor_prompt); } } else { if (extended_key) { switch (c) { case KEYS_END: printf (buffer + pos); pos = (int) strlen (buffer); break; case KEYS_HOME: printf ("\r%s $ ", monitor_prompt); pos = 0; break; case KEYS_LARROW: if (pos > 0) { pos--; putchar ('\b'); } break; case KEYS_RARROW: if ((pos < RTEMS_COMMAND_BUFFER_SIZE) && (buffer[pos] != '\0')) { putchar (buffer[pos]); pos++; } break; case KEYS_UARROW: /* * If we are moving up the histories then we need to save the working * buffer. */ if (history) { int end; int bs; if (history == history_next) { memcpy (history_buffer[history_next], buffer, RTEMS_COMMAND_BUFFER_SIZE); history_pos[history_next] = pos; } history--; memcpy (buffer, history_buffer[history], RTEMS_COMMAND_BUFFER_SIZE); pos = history_pos[history]; printf ("\r%*c", RTEMS_COMMAND_BUFFER_SIZE, ' '); printf ("\r%s $ %s", monitor_prompt, buffer); end = (int) strlen (buffer); for (bs = 0; bs < (end - pos); bs++) putchar ('\b'); } break; case KEYS_DARROW: if (history < history_next) { int end; int bs; history++; memcpy (buffer, history_buffer[history], RTEMS_COMMAND_BUFFER_SIZE); pos = history_pos[history]; printf ("\r%*c", RTEMS_COMMAND_BUFFER_SIZE, ' '); printf ("\r%s $ %s", monitor_prompt, buffer); end = (int) strlen (buffer); for (bs = 0; bs < (end - pos); bs++) putchar ('\b'); } break; case KEYS_DEL: if (buffer[pos] != '\0') { int end; int bs; strcpy (&buffer[pos], &buffer[pos + 1]); printf ("\r%s $ %s", monitor_prompt, buffer); end = (int) strlen (buffer); for (bs = 0; bs < (end - pos); bs++) putchar ('\b'); } break; } } else { switch (c) { case '\b': case '\x7e': case '\x7f': if (pos > 0) { int bs; pos--; strcpy (buffer + pos, buffer + pos + 1); printf ("\b%s \b", buffer + pos); for (bs = 0; bs < ((int) strlen (buffer) - pos); bs++) putchar ('\b'); } break; case '\n': /* * Process the command. */ printf ("\n"); repeating = 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -