Natural Tiny Shell (NT-Shell) library is a tiny shell library for a small embedded system. The interface is really simple. You should only know ntshell_execute in ntshell.h. So you can port it to any embedded system easily. Please enjoy your small embedded system with it. :)

Dependents:   NaturalTinyShell_TestProgram

Revision:
0:7147d6024de8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vtparse.c	Sun May 22 02:51:35 2011 +0000
@@ -0,0 +1,156 @@
+/**
+ * @file vtparse.c
+ * @brief VTParse
+ * @details
+ * An implementation of Paul Williams' DEC compatible state machine parser
+ * This code is in the public domain.
+ * @author Joshua Haberman <joshua@reverberate.org>
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "vtparse.h"
+#include "vtparse_table.h"
+#include "ntlibc.h"
+
+void vtparse_init(vtparse_t *parser, vtparse_callback_t cb)
+{
+    parser->state                 = VTPARSE_STATE_GROUND;
+    parser->intermediate_chars[0] = '\0';
+    parser->num_params            = 0;
+    parser->ignore_flagged        = 0;
+    parser->cb                    = cb;
+}
+
+static void do_action(vtparse_t *parser, vtparse_action_t action, char ch)
+{
+    /* Some actions we handle internally (like parsing parameters), others
+     * we hand to our client for processing */
+
+    switch(action) {
+        case VTPARSE_ACTION_PRINT:
+        case VTPARSE_ACTION_EXECUTE:
+        case VTPARSE_ACTION_HOOK:
+        case VTPARSE_ACTION_PUT:
+        case VTPARSE_ACTION_OSC_START:
+        case VTPARSE_ACTION_OSC_PUT:
+        case VTPARSE_ACTION_OSC_END:
+        case VTPARSE_ACTION_UNHOOK:
+        case VTPARSE_ACTION_CSI_DISPATCH:
+        case VTPARSE_ACTION_ESC_DISPATCH:
+            parser->cb(parser, action, ch);
+            break;
+
+        case VTPARSE_ACTION_IGNORE:
+            /* do nothing */
+            break;
+
+        case VTPARSE_ACTION_COLLECT:
+        {
+            /* Append the character to the intermediate params */
+            int num_intermediate_chars = ntlibc_strlen((char*)parser->intermediate_chars);
+
+            if(num_intermediate_chars + 1 > MAX_INTERMEDIATE_CHARS)
+                parser->ignore_flagged = 1;
+            else
+                parser->intermediate_chars[num_intermediate_chars++] = ch;
+
+            break;
+        }
+
+        case VTPARSE_ACTION_PARAM:
+        {
+            /* process the param character */
+            if(ch == ';')
+            {
+                parser->num_params += 1;
+                parser->params[parser->num_params-1] = 0;
+            }
+            else
+            {
+                /* the character is a digit */
+                int current_param;
+
+                if(parser->num_params == 0)
+                {
+                    parser->num_params = 1;
+                    parser->params[0]  = 0;
+                }
+
+                current_param = parser->num_params - 1;
+                parser->params[current_param] *= 10;
+                parser->params[current_param] += (ch - '0');
+            }
+
+            break;
+        }
+
+        case VTPARSE_ACTION_CLEAR:
+            parser->intermediate_chars[0] = '\0';
+            parser->num_params            = 0;
+            parser->ignore_flagged        = 0;
+            break;
+
+        default:
+            // Internal error: Unknown action.
+            break;
+    }
+}
+
+static void do_state_change(vtparse_t *parser, state_change_t change, char ch)
+{
+    /* A state change is an action and/or a new state to transition to. */
+
+    vtparse_state_t  new_state = STATE(change);
+    vtparse_action_t action    = ACTION(change);
+
+
+    if(new_state)
+    {
+        /* Perform up to three actions:
+         *   1. the exit action of the old state
+         *   2. the action associated with the transition
+         *   3. the entry actionk of the new action
+         */
+
+        vtparse_action_t exit_action = GET_EXIT_ACTIONS(parser->state);
+        vtparse_action_t entry_action = GET_ENTRY_ACTIONS(new_state);
+
+        if(exit_action)
+            do_action(parser, exit_action, 0);
+
+        if(action)
+            do_action(parser, action, ch);
+
+        if(entry_action)
+            do_action(parser, entry_action, 0);
+
+        parser->state = new_state;
+    }
+    else
+    {
+        do_action(parser, action, ch);
+    }
+}
+
+void vtparse(vtparse_t *parser, unsigned char *data, int len)
+{
+    int i;
+    for(i = 0; i < len; i++)
+    {
+        unsigned char ch = data[i];
+
+        /* If a transition is defined from the "anywhere" state, always
+         * use that.  Otherwise use the transition from the current state. */
+
+        state_change_t change = GET_STATE_TABLE(VTPARSE_STATE_ANYWHERE, ch);
+
+        if(!change)
+            change = GET_STATE_TABLE(parser->state, ch);
+
+        do_state_change(parser, change, data[i]);
+    }
+}
+