visualtest/src/parsehelper.c
author Alex Szpakowski
Thu, 31 Dec 2015 21:16:43 -0400
changeset 9995 d79480c1e151
parent 7924 fcb86d323770
permissions -rw-r--r--
Updated some header comments and iOS documentation to better clarify high-dpi / retina support and screen-coordinate sizes versus pixel sizes.
     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 }