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.
15 void vtparse_init(vtparse_t
*parser
, vtparse_callback_t cb
)
17 parser
->state
= VTPARSE_STATE_GROUND
;
18 parser
->intermediate_chars
[0] = '\0';
19 parser
->num_params
= 0;
20 parser
->ignore_flagged
= 0;
24 static void do_action(vtparse_t
*parser
, vtparse_action_t action
, char ch
)
26 /* Some actions we handle internally (like parsing parameters), others
27 * we hand to our client for processing */
30 case VTPARSE_ACTION_PRINT
:
31 case VTPARSE_ACTION_EXECUTE
:
32 case VTPARSE_ACTION_HOOK
:
33 case VTPARSE_ACTION_PUT
:
34 case VTPARSE_ACTION_OSC_START
:
35 case VTPARSE_ACTION_OSC_PUT
:
36 case VTPARSE_ACTION_OSC_END
:
37 case VTPARSE_ACTION_UNHOOK
:
38 case VTPARSE_ACTION_CSI_DISPATCH
:
39 case VTPARSE_ACTION_ESC_DISPATCH
:
40 parser
->cb(parser
, action
, ch
);
43 case VTPARSE_ACTION_IGNORE
:
47 case VTPARSE_ACTION_COLLECT
:
49 /* Append the character to the intermediate params */
50 int num_intermediate_chars
= strlen((char*)parser
->intermediate_chars
);
52 if(num_intermediate_chars
+ 1 > MAX_INTERMEDIATE_CHARS
)
53 parser
->ignore_flagged
= 1;
55 parser
->intermediate_chars
[num_intermediate_chars
++] = ch
;
60 case VTPARSE_ACTION_PARAM
:
62 /* process the param character */
65 parser
->num_params
+= 1;
66 parser
->params
[parser
->num_params
-1] = 0;
70 /* the character is a digit */
73 if(parser
->num_params
== 0)
75 parser
->num_params
= 1;
76 parser
->params
[0] = 0;
79 current_param
= parser
->num_params
- 1;
80 parser
->params
[current_param
] *= 10;
81 parser
->params
[current_param
] += (ch
- '0');
87 case VTPARSE_ACTION_CLEAR
:
88 parser
->intermediate_chars
[0] = '\0';
89 parser
->num_params
= 0;
90 parser
->ignore_flagged
= 0;
94 fprintf(stderr
, "Internal error, unknown action %d", 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
= EXIT_ACTIONS
[parser
->state
];
115 vtparse_action_t entry_action
= 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
= STATE_TABLE
[VTPARSE_STATE_ANYWHERE
][ch
];
147 change
= STATE_TABLE
[parser
->state
][ch
];
149 do_state_change(parser
, change
, data
[i
]);