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

Committer:
shintamainjp
Date:
Sun May 22 02:51:35 2011 +0000
Revision:
0:7147d6024de8
Initial version.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
shintamainjp 0:7147d6024de8 1 /**
shintamainjp 0:7147d6024de8 2 * @file vtparse.c
shintamainjp 0:7147d6024de8 3 * @brief VTParse
shintamainjp 0:7147d6024de8 4 * @details
shintamainjp 0:7147d6024de8 5 * An implementation of Paul Williams' DEC compatible state machine parser
shintamainjp 0:7147d6024de8 6 * This code is in the public domain.
shintamainjp 0:7147d6024de8 7 * @author Joshua Haberman <joshua@reverberate.org>
shintamainjp 0:7147d6024de8 8 */
shintamainjp 0:7147d6024de8 9
shintamainjp 0:7147d6024de8 10 #include <string.h>
shintamainjp 0:7147d6024de8 11 #include <stdlib.h>
shintamainjp 0:7147d6024de8 12 #include <stdio.h>
shintamainjp 0:7147d6024de8 13
shintamainjp 0:7147d6024de8 14 #include "vtparse.h"
shintamainjp 0:7147d6024de8 15 #include "vtparse_table.h"
shintamainjp 0:7147d6024de8 16 #include "ntlibc.h"
shintamainjp 0:7147d6024de8 17
shintamainjp 0:7147d6024de8 18 void vtparse_init(vtparse_t *parser, vtparse_callback_t cb)
shintamainjp 0:7147d6024de8 19 {
shintamainjp 0:7147d6024de8 20 parser->state = VTPARSE_STATE_GROUND;
shintamainjp 0:7147d6024de8 21 parser->intermediate_chars[0] = '\0';
shintamainjp 0:7147d6024de8 22 parser->num_params = 0;
shintamainjp 0:7147d6024de8 23 parser->ignore_flagged = 0;
shintamainjp 0:7147d6024de8 24 parser->cb = cb;
shintamainjp 0:7147d6024de8 25 }
shintamainjp 0:7147d6024de8 26
shintamainjp 0:7147d6024de8 27 static void do_action(vtparse_t *parser, vtparse_action_t action, char ch)
shintamainjp 0:7147d6024de8 28 {
shintamainjp 0:7147d6024de8 29 /* Some actions we handle internally (like parsing parameters), others
shintamainjp 0:7147d6024de8 30 * we hand to our client for processing */
shintamainjp 0:7147d6024de8 31
shintamainjp 0:7147d6024de8 32 switch(action) {
shintamainjp 0:7147d6024de8 33 case VTPARSE_ACTION_PRINT:
shintamainjp 0:7147d6024de8 34 case VTPARSE_ACTION_EXECUTE:
shintamainjp 0:7147d6024de8 35 case VTPARSE_ACTION_HOOK:
shintamainjp 0:7147d6024de8 36 case VTPARSE_ACTION_PUT:
shintamainjp 0:7147d6024de8 37 case VTPARSE_ACTION_OSC_START:
shintamainjp 0:7147d6024de8 38 case VTPARSE_ACTION_OSC_PUT:
shintamainjp 0:7147d6024de8 39 case VTPARSE_ACTION_OSC_END:
shintamainjp 0:7147d6024de8 40 case VTPARSE_ACTION_UNHOOK:
shintamainjp 0:7147d6024de8 41 case VTPARSE_ACTION_CSI_DISPATCH:
shintamainjp 0:7147d6024de8 42 case VTPARSE_ACTION_ESC_DISPATCH:
shintamainjp 0:7147d6024de8 43 parser->cb(parser, action, ch);
shintamainjp 0:7147d6024de8 44 break;
shintamainjp 0:7147d6024de8 45
shintamainjp 0:7147d6024de8 46 case VTPARSE_ACTION_IGNORE:
shintamainjp 0:7147d6024de8 47 /* do nothing */
shintamainjp 0:7147d6024de8 48 break;
shintamainjp 0:7147d6024de8 49
shintamainjp 0:7147d6024de8 50 case VTPARSE_ACTION_COLLECT:
shintamainjp 0:7147d6024de8 51 {
shintamainjp 0:7147d6024de8 52 /* Append the character to the intermediate params */
shintamainjp 0:7147d6024de8 53 int num_intermediate_chars = ntlibc_strlen((char*)parser->intermediate_chars);
shintamainjp 0:7147d6024de8 54
shintamainjp 0:7147d6024de8 55 if(num_intermediate_chars + 1 > MAX_INTERMEDIATE_CHARS)
shintamainjp 0:7147d6024de8 56 parser->ignore_flagged = 1;
shintamainjp 0:7147d6024de8 57 else
shintamainjp 0:7147d6024de8 58 parser->intermediate_chars[num_intermediate_chars++] = ch;
shintamainjp 0:7147d6024de8 59
shintamainjp 0:7147d6024de8 60 break;
shintamainjp 0:7147d6024de8 61 }
shintamainjp 0:7147d6024de8 62
shintamainjp 0:7147d6024de8 63 case VTPARSE_ACTION_PARAM:
shintamainjp 0:7147d6024de8 64 {
shintamainjp 0:7147d6024de8 65 /* process the param character */
shintamainjp 0:7147d6024de8 66 if(ch == ';')
shintamainjp 0:7147d6024de8 67 {
shintamainjp 0:7147d6024de8 68 parser->num_params += 1;
shintamainjp 0:7147d6024de8 69 parser->params[parser->num_params-1] = 0;
shintamainjp 0:7147d6024de8 70 }
shintamainjp 0:7147d6024de8 71 else
shintamainjp 0:7147d6024de8 72 {
shintamainjp 0:7147d6024de8 73 /* the character is a digit */
shintamainjp 0:7147d6024de8 74 int current_param;
shintamainjp 0:7147d6024de8 75
shintamainjp 0:7147d6024de8 76 if(parser->num_params == 0)
shintamainjp 0:7147d6024de8 77 {
shintamainjp 0:7147d6024de8 78 parser->num_params = 1;
shintamainjp 0:7147d6024de8 79 parser->params[0] = 0;
shintamainjp 0:7147d6024de8 80 }
shintamainjp 0:7147d6024de8 81
shintamainjp 0:7147d6024de8 82 current_param = parser->num_params - 1;
shintamainjp 0:7147d6024de8 83 parser->params[current_param] *= 10;
shintamainjp 0:7147d6024de8 84 parser->params[current_param] += (ch - '0');
shintamainjp 0:7147d6024de8 85 }
shintamainjp 0:7147d6024de8 86
shintamainjp 0:7147d6024de8 87 break;
shintamainjp 0:7147d6024de8 88 }
shintamainjp 0:7147d6024de8 89
shintamainjp 0:7147d6024de8 90 case VTPARSE_ACTION_CLEAR:
shintamainjp 0:7147d6024de8 91 parser->intermediate_chars[0] = '\0';
shintamainjp 0:7147d6024de8 92 parser->num_params = 0;
shintamainjp 0:7147d6024de8 93 parser->ignore_flagged = 0;
shintamainjp 0:7147d6024de8 94 break;
shintamainjp 0:7147d6024de8 95
shintamainjp 0:7147d6024de8 96 default:
shintamainjp 0:7147d6024de8 97 // Internal error: Unknown action.
shintamainjp 0:7147d6024de8 98 break;
shintamainjp 0:7147d6024de8 99 }
shintamainjp 0:7147d6024de8 100 }
shintamainjp 0:7147d6024de8 101
shintamainjp 0:7147d6024de8 102 static void do_state_change(vtparse_t *parser, state_change_t change, char ch)
shintamainjp 0:7147d6024de8 103 {
shintamainjp 0:7147d6024de8 104 /* A state change is an action and/or a new state to transition to. */
shintamainjp 0:7147d6024de8 105
shintamainjp 0:7147d6024de8 106 vtparse_state_t new_state = STATE(change);
shintamainjp 0:7147d6024de8 107 vtparse_action_t action = ACTION(change);
shintamainjp 0:7147d6024de8 108
shintamainjp 0:7147d6024de8 109
shintamainjp 0:7147d6024de8 110 if(new_state)
shintamainjp 0:7147d6024de8 111 {
shintamainjp 0:7147d6024de8 112 /* Perform up to three actions:
shintamainjp 0:7147d6024de8 113 * 1. the exit action of the old state
shintamainjp 0:7147d6024de8 114 * 2. the action associated with the transition
shintamainjp 0:7147d6024de8 115 * 3. the entry actionk of the new action
shintamainjp 0:7147d6024de8 116 */
shintamainjp 0:7147d6024de8 117
shintamainjp 0:7147d6024de8 118 vtparse_action_t exit_action = GET_EXIT_ACTIONS(parser->state);
shintamainjp 0:7147d6024de8 119 vtparse_action_t entry_action = GET_ENTRY_ACTIONS(new_state);
shintamainjp 0:7147d6024de8 120
shintamainjp 0:7147d6024de8 121 if(exit_action)
shintamainjp 0:7147d6024de8 122 do_action(parser, exit_action, 0);
shintamainjp 0:7147d6024de8 123
shintamainjp 0:7147d6024de8 124 if(action)
shintamainjp 0:7147d6024de8 125 do_action(parser, action, ch);
shintamainjp 0:7147d6024de8 126
shintamainjp 0:7147d6024de8 127 if(entry_action)
shintamainjp 0:7147d6024de8 128 do_action(parser, entry_action, 0);
shintamainjp 0:7147d6024de8 129
shintamainjp 0:7147d6024de8 130 parser->state = new_state;
shintamainjp 0:7147d6024de8 131 }
shintamainjp 0:7147d6024de8 132 else
shintamainjp 0:7147d6024de8 133 {
shintamainjp 0:7147d6024de8 134 do_action(parser, action, ch);
shintamainjp 0:7147d6024de8 135 }
shintamainjp 0:7147d6024de8 136 }
shintamainjp 0:7147d6024de8 137
shintamainjp 0:7147d6024de8 138 void vtparse(vtparse_t *parser, unsigned char *data, int len)
shintamainjp 0:7147d6024de8 139 {
shintamainjp 0:7147d6024de8 140 int i;
shintamainjp 0:7147d6024de8 141 for(i = 0; i < len; i++)
shintamainjp 0:7147d6024de8 142 {
shintamainjp 0:7147d6024de8 143 unsigned char ch = data[i];
shintamainjp 0:7147d6024de8 144
shintamainjp 0:7147d6024de8 145 /* If a transition is defined from the "anywhere" state, always
shintamainjp 0:7147d6024de8 146 * use that. Otherwise use the transition from the current state. */
shintamainjp 0:7147d6024de8 147
shintamainjp 0:7147d6024de8 148 state_change_t change = GET_STATE_TABLE(VTPARSE_STATE_ANYWHERE, ch);
shintamainjp 0:7147d6024de8 149
shintamainjp 0:7147d6024de8 150 if(!change)
shintamainjp 0:7147d6024de8 151 change = GET_STATE_TABLE(parser->state, ch);
shintamainjp 0:7147d6024de8 152
shintamainjp 0:7147d6024de8 153 do_state_change(parser, change, data[i]);
shintamainjp 0:7147d6024de8 154 }
shintamainjp 0:7147d6024de8 155 }
shintamainjp 0:7147d6024de8 156