parsehelper.c (5318B)
1/* See COPYING.txt for the full license governing this code. */ 2/** 3 * \file parsehelper.c 4 * 5 * Source file with some helper functions for parsing strings. 6 */ 7 8#include <SDL_test.h> 9#include "SDL_visualtest_harness_argparser.h" 10 11/* this function uses a DFA to count the number of tokens in an agruments string. 12 state 0 is taken to be the start and end state. State 1 handles a double quoted 13 argument and state 2 handles unquoted arguments. */ 14static int 15CountTokens(char* args) 16{ 17 int index, num_tokens; 18 int state; /* current state of the DFA */ 19 20 if(!args) 21 return -1; 22 23 index = 0; 24 state = 0; 25 num_tokens = 0; 26 while(args[index]) 27 { 28 char ch = args[index]; 29 switch(state) 30 { 31 case 0: 32 if(ch == '\"') 33 { 34 state = 1; 35 num_tokens++; 36 } 37 else if(!SDL_isspace(ch)) 38 { 39 state = 2; 40 num_tokens++; 41 } 42 break; 43 44 case 1: 45 if(ch == '\"') 46 { 47 state = 0; 48 } 49 break; 50 51 case 2: 52 if(SDL_isspace(ch)) 53 { 54 state = 0; 55 } 56 break; 57 } 58 index++; 59 } 60 return num_tokens; 61} 62 63/* - size of tokens is num_tokens + 1 64- uses the same DFA used in CountTokens() to split args into an array of strings */ 65static int 66TokenizeHelper(char* str, char** tokens, int num_tokens, int max_token_len) 67{ 68 int index, state, done, st_index, token_index; 69 70 if(!str) 71 { 72 SDLTest_LogError("str argument cannot be NULL"); 73 return 0; 74 } 75 if(!tokens) 76 { 77 SDLTest_LogError("tokens argument cannot be NULL"); 78 return 0; 79 } 80 if(num_tokens <= 0) 81 { 82 SDLTest_LogError("num_tokens argument must be positive"); 83 return 0; 84 } 85 if(max_token_len <= 0) 86 { 87 SDLTest_LogError("max_token_len argument must be positive"); 88 return 0; 89 } 90 91 /* allocate memory for the tokens */ 92 tokens[num_tokens] = NULL; 93 for(index = 0; index < num_tokens; index++) 94 { 95 tokens[index] = (char*)SDL_malloc(max_token_len); 96 if(!tokens[index]) 97 { 98 int i; 99 SDLTest_LogError("malloc() failed."); 100 for(i = 0; i < index; i++) 101 SDL_free(tokens[i]); 102 return 0; 103 } 104 tokens[index][0] = '\0'; 105 } 106 107 /* copy the tokens into the array */ 108 st_index = 0; 109 index = 0; 110 token_index = 0; 111 state = 0; 112 done = 0; 113 while(!done) 114 { 115 char ch = str[index]; 116 switch(state) 117 { 118 case 0: 119 if(ch == '\"') 120 { 121 state = 1; 122 st_index = index + 1; 123 } 124 else if(!ch) 125 done = 1; 126 else if(ch && !SDL_isspace(ch)) 127 { 128 state = 2; 129 st_index = index; 130 } 131 break; 132 133 case 1: 134 if(ch == '\"') 135 { 136 int i; 137 state = 0; 138 for(i = st_index; i < index; i++) 139 { 140 tokens[token_index][i - st_index] = str[i]; 141 } 142 tokens[token_index][i - st_index] = '\0'; 143 token_index++; 144 } 145 else if(!ch) 146 { 147 SDLTest_LogError("Parsing Error!"); 148 done = 1; 149 } 150 break; 151 152 case 2: 153 if(!ch) 154 done = 1; 155 if(SDL_isspace(ch) || !ch) 156 { 157 int i; 158 state = 0; 159 for(i = st_index; i < index; i++) 160 { 161 tokens[token_index][i - st_index] = str[i]; 162 } 163 tokens[token_index][i - st_index] = '\0'; 164 token_index++; 165 } 166 break; 167 } 168 index++; 169 } 170 return 1; 171} 172 173char** 174SDLVisualTest_Tokenize(char* str, int max_token_len) 175{ 176 int num_tokens; 177 char** tokens; 178 179 if(!str) 180 { 181 SDLTest_LogError("str argument cannot be NULL"); 182 return NULL; 183 } 184 if(max_token_len <= 0) 185 { 186 SDLTest_LogError("max_token_len argument must be positive"); 187 return NULL; 188 } 189 190 num_tokens = CountTokens(str); 191 if(num_tokens == 0) 192 return NULL; 193 194 tokens = (char**)SDL_malloc(sizeof(char*) * (num_tokens + 1)); 195 if(!TokenizeHelper(str, tokens, num_tokens, max_token_len)) 196 { 197 SDLTest_LogError("TokenizeHelper() failed"); 198 SDL_free(tokens); 199 return NULL; 200 } 201 return tokens; 202} 203 204char** 205SDLVisualTest_ParseArgsToArgv(char* args) 206{ 207 char** argv; 208 int num_tokens; 209 210 num_tokens = CountTokens(args); 211 if(num_tokens == 0) 212 return NULL; 213 214 /* allocate space for arguments */ 215 argv = (char**)SDL_malloc((num_tokens + 2) * sizeof(char*)); 216 if(!argv) 217 { 218 SDLTest_LogError("malloc() failed."); 219 return NULL; 220 } 221 222 /* tokenize */ 223 if(!TokenizeHelper(args, argv + 1, num_tokens, MAX_SUT_ARGS_LEN)) 224 { 225 SDLTest_LogError("TokenizeHelper() failed"); 226 SDL_free(argv); 227 return NULL; 228 } 229 argv[0] = NULL; 230 return argv; 231}