summaryrefslogtreecommitdiffstats
path: root/cpukit/libmisc/shell/shell_getchar.c
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/libmisc/shell/shell_getchar.c')
-rw-r--r--cpukit/libmisc/shell/shell_getchar.c176
1 files changed, 176 insertions, 0 deletions
diff --git a/cpukit/libmisc/shell/shell_getchar.c b/cpukit/libmisc/shell/shell_getchar.c
new file mode 100644
index 0000000000..b214a9511f
--- /dev/null
+++ b/cpukit/libmisc/shell/shell_getchar.c
@@ -0,0 +1,176 @@
+/*
+ *
+ * Handle keys for the shell.
+ *
+ * Author:
+ *
+ * Chris Johns (chrisj@rtems.org)
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <time.h>
+
+#include <rtems.h>
+#include <rtems/error.h>
+#include <rtems/system.h>
+#include <rtems/shell.h>
+#include <rtems/shellconfig.h>
+#include "internal.h"
+
+/*
+ * Taken from the monitor code.
+ */
+
+/*
+ * 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;
+ const struct translation_table *branch;
+ unsigned int key;
+};
+
+static const struct translation_table trans_one[] =
+{
+ { '\x7e', 0, RTEMS_SHELL_KEYS_HOME },
+ { 0, 0, 0 }
+};
+
+static const struct translation_table trans_two[] =
+{
+ { '~', 0, RTEMS_SHELL_KEYS_INS },
+ { 0, 0, 0 }
+};
+
+static const struct translation_table trans_three[] =
+{
+ { '~', 0, RTEMS_SHELL_KEYS_DEL },
+ { 0, 0, 0 }
+};
+
+static const struct translation_table trans_tab_csi[] =
+{
+ { '1', trans_one, 0 },
+ { '2', trans_two, 0 },
+ { '3', trans_three, 0 },
+ { 'A', 0, RTEMS_SHELL_KEYS_UARROW },
+ { 'B', 0, RTEMS_SHELL_KEYS_DARROW },
+ { 'D', 0, RTEMS_SHELL_KEYS_LARROW },
+ { 'C', 0, RTEMS_SHELL_KEYS_RARROW },
+ { 'F', 0, RTEMS_SHELL_KEYS_END },
+ { 'H', 0, RTEMS_SHELL_KEYS_HOME },
+ { 0, 0, 0 }
+};
+
+static const struct translation_table trans_tab_O[] =
+{
+ { '1', 0, RTEMS_SHELL_KEYS_F1 },
+ { '2', 0, RTEMS_SHELL_KEYS_F2 },
+ { '3', 0, RTEMS_SHELL_KEYS_F3 },
+ { '4', 0, RTEMS_SHELL_KEYS_F4 },
+ { '5', 0, RTEMS_SHELL_KEYS_F5 },
+ { '6', 0, RTEMS_SHELL_KEYS_F6 },
+ { '7', 0, RTEMS_SHELL_KEYS_F7 },
+ { '8', 0, RTEMS_SHELL_KEYS_F8 },
+ { '9', 0, RTEMS_SHELL_KEYS_F9 },
+ { ':', 0, RTEMS_SHELL_KEYS_F10 },
+ { 'F', 0, RTEMS_SHELL_KEYS_END },
+ { 'P', 0, RTEMS_SHELL_KEYS_F1 },
+ { 'Q', 0, RTEMS_SHELL_KEYS_F2 },
+ { 'R', 0, RTEMS_SHELL_KEYS_F3 },
+ { 'S', 0, RTEMS_SHELL_KEYS_F4 },
+ { 'T', 0, RTEMS_SHELL_KEYS_F5 },
+ { 'U', 0, RTEMS_SHELL_KEYS_F6 },
+ { 'V', 0, RTEMS_SHELL_KEYS_F7 },
+ { 'W', 0, RTEMS_SHELL_KEYS_F8 },
+ { 'X', 0, RTEMS_SHELL_KEYS_F9 },
+ { 'Y', 0, RTEMS_SHELL_KEYS_F10 },
+ { 0, 0, 0 }
+};
+
+static const 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.
+ */
+
+unsigned int
+rtems_shell_getchar (FILE *in)
+{
+ const struct translation_table *translation = 0;
+ for (;;)
+ {
+ int c = fgetc (in);
+ if (c == EOF)
+ return EOF;
+ 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 RTEMS_SHELL_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;
+ }
+ }
+}
+