sdl

FORK: Simple Directmedia Layer
git clone https://git.neptards.moe/neptards/sdl.git
Log | Files | Refs

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. */
     14 static int
     15 CountTokens(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 */
     65 static int
     66 TokenizeHelper(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 
    173 char**
    174 SDLVisualTest_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 
    204 char**
    205 SDLVisualTest_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 }