2 * VTParse - an implementation of Paul Williams' DEC compatible state machine parser
4 * Author: Joshua Haberman <joshua@reverberate.org>
6 * This code is in the public domain.
11 void vtparse_init(vtparse_t
*parser
, vtparse_callback_t cb
)
13 parser
->state
= VTPARSE_STATE_GROUND
;
14 parser
->num_intermediate_chars
= 0;
15 parser
->num_params
= 0;
16 parser
->ignore_flagged
= 0;
20 static void do_action(vtparse_t
*parser
, vtparse_action_t action
, char ch
)
22 /* Some actions we handle internally (like parsing parameters), others
23 * we hand to our client for processing */
26 case VTPARSE_ACTION_PRINT
:
27 case VTPARSE_ACTION_EXECUTE
:
28 case VTPARSE_ACTION_HOOK
:
29 case VTPARSE_ACTION_PUT
:
30 case VTPARSE_ACTION_OSC_START
:
31 case VTPARSE_ACTION_OSC_PUT
:
32 case VTPARSE_ACTION_OSC_END
:
33 case VTPARSE_ACTION_UNHOOK
:
34 case VTPARSE_ACTION_CSI_DISPATCH
:
35 case VTPARSE_ACTION_ESC_DISPATCH
:
36 parser
->cb(parser
, action
, ch
);
39 case VTPARSE_ACTION_IGNORE
:
43 case VTPARSE_ACTION_COLLECT
:
45 /* Append the character to the intermediate params */
46 if(parser
->num_intermediate_chars
+ 1 > MAX_INTERMEDIATE_CHARS
)
47 parser
->ignore_flagged
= 1;
49 parser
->intermediate_chars
[parser
->num_intermediate_chars
++] = ch
;
54 case VTPARSE_ACTION_PARAM
:
56 /* process the param character */
59 parser
->num_params
+= 1;
60 parser
->params
[parser
->num_params
-1] = 0;
64 /* the character is a digit */
67 if(parser
->num_params
== 0)
69 parser
->num_params
= 1;
70 parser
->params
[0] = 0;
73 current_param
= parser
->num_params
- 1;
74 parser
->params
[current_param
] *= 10;
75 parser
->params
[current_param
] += (ch
- '0');
81 case VTPARSE_ACTION_CLEAR
:
82 parser
->num_intermediate_chars
= 0;
83 parser
->num_params
= 0;
84 parser
->ignore_flagged
= 0;
88 parser
->cb(parser
, VTPARSE_ACTION_ERROR
, 0);
92 static void do_state_change(vtparse_t
*parser
, state_change_t change
, char ch
)
94 /* A state change is an action and/or a new state to transition to. */
96 vtparse_state_t new_state
= STATE(change
);
97 vtparse_action_t action
= ACTION(change
);
102 /* Perform up to three actions:
103 * 1. the exit action of the old state
104 * 2. the action associated with the transition
105 * 3. the entry action of the new state
108 vtparse_action_t exit_action
= EXIT_ACTIONS
[parser
->state
-1];
109 vtparse_action_t entry_action
= ENTRY_ACTIONS
[new_state
-1];
112 do_action(parser
, exit_action
, 0);
115 do_action(parser
, action
, ch
);
118 do_action(parser
, entry_action
, 0);
120 parser
->state
= new_state
;
124 do_action(parser
, action
, ch
);
128 void vtparse(vtparse_t
*parser
, unsigned char *data
, int len
)
131 for(i
= 0; i
< len
; i
++)
133 unsigned char ch
= data
[i
];
134 state_change_t change
= STATE_TABLE
[parser
->state
-1][ch
];
135 do_state_change(parser
, change
, ch
);