visualtest/src/parsehelper.c
author Ryan C. Gordon <icculus@icculus.org>
Sun, 21 Oct 2018 22:40:17 -0400
changeset 12345 50e1cca28b39
parent 7924 fcb86d323770
permissions -rw-r--r--
wasapi/win32: Sort initial device lists by device GUID.

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