5 * An implementation of Paul Williams' DEC compatible state machine parser
6 * This code is in the public domain.
7 * @author Joshua Haberman <joshua@reverberate.org>
11 #include "vtparse_table.h"
14 void vtparse_init(vtparse_t *parser, vtparse_callback_t cb)
16 parser->state = VTPARSE_STATE_GROUND;
17 parser->intermediate_chars[0] = '\0';
18 parser->num_params = 0;
19 parser->ignore_flagged = 0;
23 static void do_action(vtparse_t *parser, vtparse_action_t action, char ch)
25 /* Some actions we handle internally (like parsing parameters), others
26 * we hand to our client for processing */
29 case VTPARSE_ACTION_PRINT:
30 case VTPARSE_ACTION_EXECUTE:
31 case VTPARSE_ACTION_HOOK:
32 case VTPARSE_ACTION_PUT:
33 case VTPARSE_ACTION_OSC_START:
34 case VTPARSE_ACTION_OSC_PUT:
35 case VTPARSE_ACTION_OSC_END:
36 case VTPARSE_ACTION_UNHOOK:
37 case VTPARSE_ACTION_CSI_DISPATCH:
38 case VTPARSE_ACTION_ESC_DISPATCH:
39 parser->cb(parser, action, ch);
42 case VTPARSE_ACTION_IGNORE:
46 case VTPARSE_ACTION_COLLECT:
48 /* Append the character to the intermediate params */
49 int num_intermediate_chars = ntlibc_strlen((char*)parser->intermediate_chars);
51 if(num_intermediate_chars + 1 > MAX_INTERMEDIATE_CHARS)
52 parser->ignore_flagged = 1;
54 parser->intermediate_chars[num_intermediate_chars++] = ch;
59 case VTPARSE_ACTION_PARAM:
61 /* process the param character */
64 parser->num_params += 1;
65 parser->params[parser->num_params-1] = 0;
69 /* the character is a digit */
72 if(parser->num_params == 0)
74 parser->num_params = 1;
75 parser->params[0] = 0;
78 current_param = parser->num_params - 1;
79 parser->params[current_param] *= 10;
80 parser->params[current_param] += (ch - '0');
86 case VTPARSE_ACTION_CLEAR:
87 parser->intermediate_chars[0] = '\0';
88 parser->num_params = 0;
89 parser->ignore_flagged = 0;
93 // Internal error: Unknown action.
98 static void do_state_change(vtparse_t *parser, state_change_t change, char ch)
100 /* A state change is an action and/or a new state to transition to. */
102 vtparse_state_t new_state = STATE(change);
103 vtparse_action_t action = ACTION(change);
108 /* Perform up to three actions:
109 * 1. the exit action of the old state
110 * 2. the action associated with the transition
111 * 3. the entry actionk of the new action
114 vtparse_action_t exit_action = GET_EXIT_ACTIONS(parser->state);
115 vtparse_action_t entry_action = GET_ENTRY_ACTIONS(new_state);
118 do_action(parser, exit_action, 0);
121 do_action(parser, action, ch);
124 do_action(parser, entry_action, 0);
126 parser->state = new_state;
130 do_action(parser, action, ch);
134 void vtparse(vtparse_t *parser, unsigned char *data, int len)
137 for(i = 0; i < len; i++)
139 unsigned char ch = data[i];
141 /* If a transition is defined from the "anywhere" state, always
142 * use that. Otherwise use the transition from the current state. */
144 state_change_t change = GET_STATE_TABLE(VTPARSE_STATE_ANYWHERE, ch);
147 change = GET_STATE_TABLE(parser->state, ch);
149 do_state_change(parser, change, data[i]);