sdl2_frt/visualtest/src/parsehelper.c
Philipp Wiesemann 0e45984fa0 Fixed crash if initialization of EGL failed but was tried again later.
The internal function SDL_EGL_LoadLibrary() did not delete and remove a mostly
uninitialized data structure if loading the library first failed. A later try to
use EGL then skipped initialization and assumed it was previously successful
because the data structure now already existed. This led to at least one crash
in the internal function SDL_EGL_ChooseConfig() because a NULL pointer was
dereferenced to make a call to eglBindAPI().
2015-06-21 17:33:46 +02:00

232 lines
5.2 KiB
C

/* See COPYING.txt for the full license governing this code. */
/**
* \file parsehelper.c
*
* Source file with some helper functions for parsing strings.
*/
#include <SDL_test.h>
#include "SDL_visualtest_harness_argparser.h"
/* this function uses a DFA to count the number of tokens in an agruments string.
state 0 is taken to be the start and end state. State 1 handles a double quoted
argument and state 2 handles unquoted arguments. */
static int
CountTokens(char* args)
{
int index, num_tokens;
int state; /* current state of the DFA */
if(!args)
return -1;
index = 0;
state = 0;
num_tokens = 0;
while(args[index])
{
char ch = args[index];
switch(state)
{
case 0:
if(ch == '\"')
{
state = 1;
num_tokens++;
}
else if(!SDL_isspace(ch))
{
state = 2;
num_tokens++;
}
break;
case 1:
if(ch == '\"')
{
state = 0;
}
break;
case 2:
if(SDL_isspace(ch))
{
state = 0;
}
break;
}
index++;
}
return num_tokens;
}
/* - size of tokens is num_tokens + 1
- uses the same DFA used in CountTokens() to split args into an array of strings */
static int
TokenizeHelper(char* str, char** tokens, int num_tokens, int max_token_len)
{
int index, state, done, st_index, token_index;
if(!str)
{
SDLTest_LogError("str argument cannot be NULL");
return 0;
}
if(!tokens)
{
SDLTest_LogError("tokens argument cannot be NULL");
return 0;
}
if(num_tokens <= 0)
{
SDLTest_LogError("num_tokens argument must be positive");
return 0;
}
if(max_token_len <= 0)
{
SDLTest_LogError("max_token_len argument must be positive");
return 0;
}
/* allocate memory for the tokens */
tokens[num_tokens] = NULL;
for(index = 0; index < num_tokens; index++)
{
tokens[index] = (char*)SDL_malloc(max_token_len);
if(!tokens[index])
{
int i;
SDLTest_LogError("malloc() failed.");
for(i = 0; i < index; i++)
SDL_free(tokens[i]);
return 0;
}
tokens[index][0] = '\0';
}
/* copy the tokens into the array */
st_index = 0;
index = 0;
token_index = 0;
state = 0;
done = 0;
while(!done)
{
char ch = str[index];
switch(state)
{
case 0:
if(ch == '\"')
{
state = 1;
st_index = index + 1;
}
else if(!ch)
done = 1;
else if(ch && !SDL_isspace(ch))
{
state = 2;
st_index = index;
}
break;
case 1:
if(ch == '\"')
{
int i;
state = 0;
for(i = st_index; i < index; i++)
{
tokens[token_index][i - st_index] = str[i];
}
tokens[token_index][i - st_index] = '\0';
token_index++;
}
else if(!ch)
{
SDLTest_LogError("Parsing Error!");
done = 1;
}
break;
case 2:
if(!ch)
done = 1;
if(SDL_isspace(ch) || !ch)
{
int i;
state = 0;
for(i = st_index; i < index; i++)
{
tokens[token_index][i - st_index] = str[i];
}
tokens[token_index][i - st_index] = '\0';
token_index++;
}
break;
}
index++;
}
return 1;
}
char**
SDLVisualTest_Tokenize(char* str, int max_token_len)
{
int num_tokens;
char** tokens;
if(!str)
{
SDLTest_LogError("str argument cannot be NULL");
return NULL;
}
if(max_token_len <= 0)
{
SDLTest_LogError("max_token_len argument must be positive");
return NULL;
}
num_tokens = CountTokens(str);
if(num_tokens == 0)
return NULL;
tokens = (char**)SDL_malloc(sizeof(char*) * (num_tokens + 1));
if(!TokenizeHelper(str, tokens, num_tokens, max_token_len))
{
SDLTest_LogError("TokenizeHelper() failed");
SDL_free(tokens);
return NULL;
}
return tokens;
}
char**
SDLVisualTest_ParseArgsToArgv(char* args)
{
char** argv;
int num_tokens;
num_tokens = CountTokens(args);
if(num_tokens == 0)
return NULL;
/* allocate space for arguments */
argv = (char**)SDL_malloc((num_tokens + 2) * sizeof(char*));
if(!argv)
{
SDLTest_LogError("malloc() failed.");
return NULL;
}
/* tokenize */
if(!TokenizeHelper(args, argv + 1, num_tokens, MAX_SUT_ARGS_LEN))
{
SDLTest_LogError("TokenizeHelper() failed");
SDL_free(argv);
return NULL;
}
argv[0] = NULL;
return argv;
}