visualtest/src/sut_configparser.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.
     1 /* See COPYING.txt for the full license governing this code. */
     2 /**
     3  * \file sut_configparser.c
     4  *
     5  * Source file for the parser for SUT config files.
     6  */
     7 
     8 #include <limits.h>
     9 #include <string.h>
    10 #include <SDL_test.h>
    11 #include <SDL_rwops.h>
    12 #include "SDL_visualtest_sut_configparser.h"
    13 #include "SDL_visualtest_parsehelper.h"
    14 #include "SDL_visualtest_rwhelper.h"
    15 
    16 int
    17 SDLVisualTest_ParseSUTConfig(char* file, SDLVisualTest_SUTConfig* config)
    18 {
    19     char line[MAX_SUTOPTION_LINE_LENGTH];
    20     SDLVisualTest_RWHelperBuffer buffer;
    21     char* token_ptr;
    22     char* token_end;
    23     int num_lines, i, token_len;
    24     SDL_RWops* rw;
    25 
    26     if(!file)
    27     {
    28         SDLTest_LogError("file argument cannot be NULL");
    29         return 0;
    30     }
    31     if(!config)
    32     {
    33         SDLTest_LogError("config argument cannot be NULL");
    34         return 0;
    35     }
    36 
    37     /* count the number of lines */
    38     rw = SDL_RWFromFile(file, "r");
    39     if(!rw)
    40     {
    41         SDLTest_LogError("SDL_RWFromFile() failed");
    42         return 0;
    43     }
    44     SDLVisualTest_RWHelperResetBuffer(&buffer);
    45     num_lines = SDLVisualTest_RWHelperCountNonEmptyLines(rw, &buffer, '#');
    46     if(num_lines == -1)
    47         return 0;
    48     else if(num_lines == 0)
    49     {
    50         config->options = NULL;
    51         config->num_options = 0;
    52         SDL_RWclose(rw);
    53         return 1;
    54     }
    55 
    56     /* allocate memory */
    57     SDL_RWseek(rw, 0, RW_SEEK_SET);
    58     SDLVisualTest_RWHelperResetBuffer(&buffer);
    59     config->num_options = num_lines;
    60     config->options = (SDLVisualTest_SUTOption*)SDL_malloc(num_lines * 
    61                       sizeof(SDLVisualTest_SUTOption));
    62     if(!config->options)
    63     {
    64         SDLTest_LogError("malloc() failed");
    65         SDL_RWclose(rw);
    66         return 0;
    67     }
    68 
    69     /* actually parse the options */
    70     for(i = 0; i < num_lines; i++)
    71     {
    72         if(!SDLVisualTest_RWHelperReadLine(rw, line, MAX_SUTOPTION_LINE_LENGTH,
    73                                            &buffer, '#'))
    74         {
    75             SDLTest_LogError("SDLVisualTest_RWHelperReadLine() failed");
    76             SDL_free(config->options);
    77             SDL_RWclose(rw);
    78             return 0;
    79         }
    80 
    81         /* parse name */
    82         token_ptr = strtok(line, ", ");
    83         if(!token_ptr)
    84         {
    85             SDLTest_LogError("Could not parse line %d", i + 1);
    86             SDL_free(config->options);
    87             SDL_RWclose(rw);
    88             return 0;
    89         }
    90         token_len = SDL_strlen(token_ptr) + 1;
    91         SDL_strlcpy(config->options[i].name, token_ptr, token_len);
    92 
    93         /* parse type */
    94         token_ptr = strtok(NULL, ", ");
    95         if(!token_ptr)
    96         {
    97             SDLTest_LogError("Could not parse line %d", i + 1);
    98             SDL_free(config->options);
    99             SDL_RWclose(rw);
   100             return 0;
   101         }
   102         if(SDL_strcmp(token_ptr, "string") == 0)
   103             config->options[i].type = SDL_SUT_OPTIONTYPE_STRING;
   104         else if(SDL_strcmp(token_ptr, "integer") == 0)
   105             config->options[i].type = SDL_SUT_OPTIONTYPE_INT;
   106         else if(SDL_strcmp(token_ptr, "enum") == 0)
   107             config->options[i].type = SDL_SUT_OPTIONTYPE_ENUM;
   108         else if(SDL_strcmp(token_ptr, "boolean") == 0)
   109             config->options[i].type = SDL_SUT_OPTIONTYPE_BOOL;
   110         else
   111         {
   112             SDLTest_LogError("Could not parse type token at line %d", i + 1);
   113             SDL_free(config->options);
   114             SDL_RWclose(rw);
   115             return 0;
   116         }
   117 
   118         /* parse values */
   119         token_ptr = strtok(NULL, "]");
   120         if(!token_ptr)
   121         {
   122             SDLTest_LogError("Could not parse line %d", i + 1);
   123             SDL_free(config->options);
   124             SDL_RWclose(rw);
   125             return 0;
   126         }
   127         token_ptr = SDL_strchr(token_ptr, '[');
   128         if(!token_ptr)
   129         {
   130             SDLTest_LogError("Could not parse enum token at line %d", i + 1);
   131             SDL_free(config->options);
   132             SDL_RWclose(rw);
   133             return 0;
   134         }
   135         token_ptr++;
   136         if(config->options[i].type == SDL_SUT_OPTIONTYPE_INT)
   137         {
   138             if(SDL_sscanf(token_ptr, "%d %d", &config->options[i].data.range.min,
   139                           &config->options[i].data.range.max) != 2)
   140             {
   141                 config->options[i].data.range.min = INT_MIN;
   142                 config->options[i].data.range.max = INT_MAX;
   143             }
   144         }
   145         else if(config->options[i].type == SDL_SUT_OPTIONTYPE_ENUM)
   146         {
   147             config->options[i].data.enum_values = SDLVisualTest_Tokenize(token_ptr,
   148                                                   MAX_SUTOPTION_ENUMVAL_LEN);
   149             if(!config->options[i].data.enum_values)
   150             {
   151                 SDLTest_LogError("Could not parse enum token at line %d", i + 1);
   152                 SDL_free(config->options);
   153                 SDL_RWclose(rw);
   154                 return 0;
   155             }
   156         }
   157 
   158         /* parse required */
   159         token_ptr = strtok(NULL, ", ");
   160         if(!token_ptr)
   161         {
   162             SDLTest_LogError("Could not parse line %d", i + 1);
   163             SDL_free(config->options);
   164             SDL_RWclose(rw);
   165             return 0;
   166         }
   167 
   168         if(SDL_strcmp(token_ptr, "true") == 0)
   169             config->options[i].required = SDL_TRUE;
   170         else if(SDL_strcmp(token_ptr, "false") == 0)
   171             config->options[i].required = SDL_FALSE;
   172         else
   173         {
   174             SDLTest_LogError("Could not parse required token at line %d", i + 1);
   175             SDL_free(config->options);
   176             SDL_RWclose(rw);
   177             return 0;
   178         }
   179 
   180         /* parse categories */
   181         token_ptr = strtok(NULL, ",");
   182         if(!token_ptr)
   183         {
   184             SDLTest_LogError("Could not parse line %d", i + 1);
   185             SDL_free(config->options);
   186             SDL_RWclose(rw);
   187             return 0;
   188         }
   189         token_ptr = SDL_strchr(token_ptr, '[');
   190         if(!token_ptr)
   191         {
   192             SDLTest_LogError("Could not parse enum token at line %d", i + 1);
   193             SDL_free(config->options);
   194             SDL_RWclose(rw);
   195             return 0;
   196         }
   197         token_ptr++;
   198         token_end = SDL_strchr(token_ptr, ']');
   199         *token_end = '\0';
   200         if(!token_end)
   201         {
   202             SDLTest_LogError("Could not parse enum token at line %d", i + 1);
   203             SDL_free(config->options);
   204             SDL_RWclose(rw);
   205             return 0;
   206         }
   207         config->options[i].categories = SDLVisualTest_Tokenize(token_ptr,
   208                                         MAX_SUTOPTION_CATEGORY_LEN);
   209     }
   210     SDL_RWclose(rw);
   211     return 1;
   212 }
   213 
   214 void
   215 SDLVisualTest_FreeSUTConfig(SDLVisualTest_SUTConfig* config)
   216 {
   217     if(config && config->options)
   218     {
   219         SDLVisualTest_SUTOption* option;
   220         for(option = config->options;
   221             option != config->options + config->num_options; option++)
   222         {
   223             if(option->categories)
   224                 SDL_free(option->categories);
   225             if(option->type == SDL_SUT_OPTIONTYPE_ENUM && option->data.enum_values)
   226                 SDL_free(option->data.enum_values);
   227         }
   228         SDL_free(config->options);
   229         config->options = NULL;
   230         config->num_options = 0;
   231     }
   232 }