Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of NaturalTinyShell by
vtparse.cpp
00001 /** 00002 * @file vtparse.cpp 00003 * @brief VTParse 00004 * @details 00005 * An implementation of Paul Williams' DEC compatible state machine parser 00006 * This code is in the public domain. 00007 * @author Joshua Haberman <joshua@reverberate.org> 00008 */ 00009 00010 #include <string.h> 00011 #include <stdlib.h> 00012 #include <stdio.h> 00013 00014 #include "vtparse.h" 00015 #include "vtparse_table.h" 00016 #include "ntlibc.h" 00017 00018 void vtparse_init(vtparse_t *parser, vtparse_callback_t cb) 00019 { 00020 parser->state = VTPARSE_STATE_GROUND; 00021 parser->intermediate_chars[0] = '\0'; 00022 parser->num_params = 0; 00023 parser->ignore_flagged = 0; 00024 parser->cb = cb; 00025 } 00026 00027 static void do_action(vtparse_t *parser, vtparse_action_t action, char ch) 00028 { 00029 /* Some actions we handle internally (like parsing parameters), others 00030 * we hand to our client for processing */ 00031 00032 switch(action) { 00033 case VTPARSE_ACTION_PRINT: 00034 case VTPARSE_ACTION_EXECUTE: 00035 case VTPARSE_ACTION_HOOK: 00036 case VTPARSE_ACTION_PUT: 00037 case VTPARSE_ACTION_OSC_START: 00038 case VTPARSE_ACTION_OSC_PUT: 00039 case VTPARSE_ACTION_OSC_END: 00040 case VTPARSE_ACTION_UNHOOK: 00041 case VTPARSE_ACTION_CSI_DISPATCH: 00042 case VTPARSE_ACTION_ESC_DISPATCH: 00043 parser->cb(parser, action, ch); 00044 break; 00045 00046 case VTPARSE_ACTION_IGNORE: 00047 /* do nothing */ 00048 break; 00049 00050 case VTPARSE_ACTION_COLLECT: 00051 { 00052 /* Append the character to the intermediate params */ 00053 int num_intermediate_chars = ntlibc_strlen((char*)parser->intermediate_chars); 00054 00055 if(num_intermediate_chars + 1 > MAX_INTERMEDIATE_CHARS) 00056 parser->ignore_flagged = 1; 00057 else 00058 parser->intermediate_chars[num_intermediate_chars++] = ch; 00059 00060 break; 00061 } 00062 00063 case VTPARSE_ACTION_PARAM: 00064 { 00065 /* process the param character */ 00066 if(ch == ';') 00067 { 00068 parser->num_params += 1; 00069 parser->params[parser->num_params-1] = 0; 00070 } 00071 else 00072 { 00073 /* the character is a digit */ 00074 int current_param; 00075 00076 if(parser->num_params == 0) 00077 { 00078 parser->num_params = 1; 00079 parser->params[0] = 0; 00080 } 00081 00082 current_param = parser->num_params - 1; 00083 parser->params[current_param] *= 10; 00084 parser->params[current_param] += (ch - '0'); 00085 } 00086 00087 break; 00088 } 00089 00090 case VTPARSE_ACTION_CLEAR: 00091 parser->intermediate_chars[0] = '\0'; 00092 parser->num_params = 0; 00093 parser->ignore_flagged = 0; 00094 break; 00095 00096 default: 00097 // Internal error: Unknown action. 00098 break; 00099 } 00100 } 00101 00102 static void do_state_change(vtparse_t *parser, state_change_t change, char ch) 00103 { 00104 /* A state change is an action and/or a new state to transition to. */ 00105 00106 vtparse_state_t new_state = STATE(change); 00107 vtparse_action_t action = ACTION(change); 00108 00109 00110 if(new_state) 00111 { 00112 /* Perform up to three actions: 00113 * 1. the exit action of the old state 00114 * 2. the action associated with the transition 00115 * 3. the entry actionk of the new action 00116 */ 00117 00118 vtparse_action_t exit_action = GET_EXIT_ACTIONS(parser->state); 00119 vtparse_action_t entry_action = GET_ENTRY_ACTIONS(new_state); 00120 00121 if(exit_action) 00122 do_action(parser, exit_action, 0); 00123 00124 if(action) 00125 do_action(parser, action, ch); 00126 00127 if(entry_action) 00128 do_action(parser, entry_action, 0); 00129 00130 parser->state = new_state; 00131 } 00132 else 00133 { 00134 do_action(parser, action, ch); 00135 } 00136 } 00137 00138 void vtparse(vtparse_t *parser, unsigned char *data, int len) 00139 { 00140 int i; 00141 for(i = 0; i < len; i++) 00142 { 00143 unsigned char ch = data[i]; 00144 00145 /* If a transition is defined from the "anywhere" state, always 00146 * use that. Otherwise use the transition from the current state. */ 00147 00148 state_change_t change = GET_STATE_TABLE(VTPARSE_STATE_ANYWHERE, ch); 00149 00150 if(!change) 00151 change = GET_STATE_TABLE(parser->state, ch); 00152 00153 do_state_change(parser, change, data[i]); 00154 } 00155 } 00156
Generated on Wed Jul 13 2022 02:50:59 by
1.7.2
