mirror of
				https://github.com/libsdl-org/SDL.git
				synced 2025-11-04 01:34:38 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			233 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			233 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* See LICENSE.txt for the full license governing this code. */
 | 
						|
/**
 | 
						|
 * \file sut_configparser.c
 | 
						|
 *
 | 
						|
 * Source file for the parser for SUT config files.
 | 
						|
 */
 | 
						|
 | 
						|
#include <limits.h>
 | 
						|
#include <string.h>
 | 
						|
#include <SDL_test.h>
 | 
						|
#include <SDL_rwops.h>
 | 
						|
#include "SDL_visualtest_sut_configparser.h"
 | 
						|
#include "SDL_visualtest_parsehelper.h"
 | 
						|
#include "SDL_visualtest_rwhelper.h"
 | 
						|
 | 
						|
int
 | 
						|
SDLVisualTest_ParseSUTConfig(char* file, SDLVisualTest_SUTConfig* config)
 | 
						|
{
 | 
						|
    char line[MAX_SUTOPTION_LINE_LENGTH];
 | 
						|
    SDLVisualTest_RWHelperBuffer buffer;
 | 
						|
    char* token_ptr;
 | 
						|
    char* token_end;
 | 
						|
    int num_lines, i, token_len;
 | 
						|
    SDL_RWops* rw;
 | 
						|
 | 
						|
    if(!file)
 | 
						|
    {
 | 
						|
        SDLTest_LogError("file argument cannot be NULL");
 | 
						|
        return 0;
 | 
						|
    }
 | 
						|
    if(!config)
 | 
						|
    {
 | 
						|
        SDLTest_LogError("config argument cannot be NULL");
 | 
						|
        return 0;
 | 
						|
    }
 | 
						|
 | 
						|
    /* count the number of lines */
 | 
						|
    rw = SDL_RWFromFile(file, "r");
 | 
						|
    if(!rw)
 | 
						|
    {
 | 
						|
        SDLTest_LogError("SDL_RWFromFile() failed");
 | 
						|
        return 0;
 | 
						|
    }
 | 
						|
    SDLVisualTest_RWHelperResetBuffer(&buffer);
 | 
						|
    num_lines = SDLVisualTest_RWHelperCountNonEmptyLines(rw, &buffer, '#');
 | 
						|
    if(num_lines == -1)
 | 
						|
        return 0;
 | 
						|
    else if(num_lines == 0)
 | 
						|
    {
 | 
						|
        config->options = NULL;
 | 
						|
        config->num_options = 0;
 | 
						|
        SDL_RWclose(rw);
 | 
						|
        return 1;
 | 
						|
    }
 | 
						|
 | 
						|
    /* allocate memory */
 | 
						|
    SDL_RWseek(rw, 0, RW_SEEK_SET);
 | 
						|
    SDLVisualTest_RWHelperResetBuffer(&buffer);
 | 
						|
    config->num_options = num_lines;
 | 
						|
    config->options = (SDLVisualTest_SUTOption*)SDL_malloc(num_lines * 
 | 
						|
                      sizeof(SDLVisualTest_SUTOption));
 | 
						|
    if(!config->options)
 | 
						|
    {
 | 
						|
        SDLTest_LogError("SDL_malloc() failed");
 | 
						|
        SDL_RWclose(rw);
 | 
						|
        return 0;
 | 
						|
    }
 | 
						|
 | 
						|
    /* actually parse the options */
 | 
						|
    for(i = 0; i < num_lines; i++)
 | 
						|
    {
 | 
						|
        if(!SDLVisualTest_RWHelperReadLine(rw, line, MAX_SUTOPTION_LINE_LENGTH,
 | 
						|
                                           &buffer, '#'))
 | 
						|
        {
 | 
						|
            SDLTest_LogError("SDLVisualTest_RWHelperReadLine() failed");
 | 
						|
            SDL_free(config->options);
 | 
						|
            SDL_RWclose(rw);
 | 
						|
            return 0;
 | 
						|
        }
 | 
						|
 | 
						|
        /* parse name */
 | 
						|
        token_ptr = strtok(line, ", ");
 | 
						|
        if(!token_ptr)
 | 
						|
        {
 | 
						|
            SDLTest_LogError("Could not parse line %d", i + 1);
 | 
						|
            SDL_free(config->options);
 | 
						|
            SDL_RWclose(rw);
 | 
						|
            return 0;
 | 
						|
        }
 | 
						|
        token_len = SDL_strlen(token_ptr) + 1;
 | 
						|
        SDL_strlcpy(config->options[i].name, token_ptr, token_len);
 | 
						|
 | 
						|
        /* parse type */
 | 
						|
        token_ptr = strtok(NULL, ", ");
 | 
						|
        if(!token_ptr)
 | 
						|
        {
 | 
						|
            SDLTest_LogError("Could not parse line %d", i + 1);
 | 
						|
            SDL_free(config->options);
 | 
						|
            SDL_RWclose(rw);
 | 
						|
            return 0;
 | 
						|
        }
 | 
						|
        if(SDL_strcmp(token_ptr, "string") == 0)
 | 
						|
            config->options[i].type = SDL_SUT_OPTIONTYPE_STRING;
 | 
						|
        else if(SDL_strcmp(token_ptr, "integer") == 0)
 | 
						|
            config->options[i].type = SDL_SUT_OPTIONTYPE_INT;
 | 
						|
        else if(SDL_strcmp(token_ptr, "enum") == 0)
 | 
						|
            config->options[i].type = SDL_SUT_OPTIONTYPE_ENUM;
 | 
						|
        else if(SDL_strcmp(token_ptr, "boolean") == 0)
 | 
						|
            config->options[i].type = SDL_SUT_OPTIONTYPE_BOOL;
 | 
						|
        else
 | 
						|
        {
 | 
						|
            SDLTest_LogError("Could not parse type token at line %d", i + 1);
 | 
						|
            SDL_free(config->options);
 | 
						|
            SDL_RWclose(rw);
 | 
						|
            return 0;
 | 
						|
        }
 | 
						|
 | 
						|
        /* parse values */
 | 
						|
        token_ptr = strtok(NULL, "]");
 | 
						|
        if(!token_ptr)
 | 
						|
        {
 | 
						|
            SDLTest_LogError("Could not parse line %d", i + 1);
 | 
						|
            SDL_free(config->options);
 | 
						|
            SDL_RWclose(rw);
 | 
						|
            return 0;
 | 
						|
        }
 | 
						|
        token_ptr = SDL_strchr(token_ptr, '[');
 | 
						|
        if(!token_ptr)
 | 
						|
        {
 | 
						|
            SDLTest_LogError("Could not parse enum token at line %d", i + 1);
 | 
						|
            SDL_free(config->options);
 | 
						|
            SDL_RWclose(rw);
 | 
						|
            return 0;
 | 
						|
        }
 | 
						|
        token_ptr++;
 | 
						|
        if(config->options[i].type == SDL_SUT_OPTIONTYPE_INT)
 | 
						|
        {
 | 
						|
            if(SDL_sscanf(token_ptr, "%d %d", &config->options[i].data.range.min,
 | 
						|
                          &config->options[i].data.range.max) != 2)
 | 
						|
            {
 | 
						|
                config->options[i].data.range.min = INT_MIN;
 | 
						|
                config->options[i].data.range.max = INT_MAX;
 | 
						|
            }
 | 
						|
        }
 | 
						|
        else if(config->options[i].type == SDL_SUT_OPTIONTYPE_ENUM)
 | 
						|
        {
 | 
						|
            config->options[i].data.enum_values = SDLVisualTest_Tokenize(token_ptr,
 | 
						|
                                                  MAX_SUTOPTION_ENUMVAL_LEN);
 | 
						|
            if(!config->options[i].data.enum_values)
 | 
						|
            {
 | 
						|
                SDLTest_LogError("Could not parse enum token at line %d", i + 1);
 | 
						|
                SDL_free(config->options);
 | 
						|
                SDL_RWclose(rw);
 | 
						|
                return 0;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        /* parse required */
 | 
						|
        token_ptr = strtok(NULL, ", ");
 | 
						|
        if(!token_ptr)
 | 
						|
        {
 | 
						|
            SDLTest_LogError("Could not parse line %d", i + 1);
 | 
						|
            SDL_free(config->options);
 | 
						|
            SDL_RWclose(rw);
 | 
						|
            return 0;
 | 
						|
        }
 | 
						|
 | 
						|
        if(SDL_strcmp(token_ptr, "true") == 0)
 | 
						|
            config->options[i].required = SDL_TRUE;
 | 
						|
        else if(SDL_strcmp(token_ptr, "false") == 0)
 | 
						|
            config->options[i].required = SDL_FALSE;
 | 
						|
        else
 | 
						|
        {
 | 
						|
            SDLTest_LogError("Could not parse required token at line %d", i + 1);
 | 
						|
            SDL_free(config->options);
 | 
						|
            SDL_RWclose(rw);
 | 
						|
            return 0;
 | 
						|
        }
 | 
						|
 | 
						|
        /* parse categories */
 | 
						|
        token_ptr = strtok(NULL, ",");
 | 
						|
        if(!token_ptr)
 | 
						|
        {
 | 
						|
            SDLTest_LogError("Could not parse line %d", i + 1);
 | 
						|
            SDL_free(config->options);
 | 
						|
            SDL_RWclose(rw);
 | 
						|
            return 0;
 | 
						|
        }
 | 
						|
        token_ptr = SDL_strchr(token_ptr, '[');
 | 
						|
        if(!token_ptr)
 | 
						|
        {
 | 
						|
            SDLTest_LogError("Could not parse enum token at line %d", i + 1);
 | 
						|
            SDL_free(config->options);
 | 
						|
            SDL_RWclose(rw);
 | 
						|
            return 0;
 | 
						|
        }
 | 
						|
        token_ptr++;
 | 
						|
        token_end = SDL_strchr(token_ptr, ']');
 | 
						|
        *token_end = '\0';
 | 
						|
        if(!token_end)
 | 
						|
        {
 | 
						|
            SDLTest_LogError("Could not parse enum token at line %d", i + 1);
 | 
						|
            SDL_free(config->options);
 | 
						|
            SDL_RWclose(rw);
 | 
						|
            return 0;
 | 
						|
        }
 | 
						|
        config->options[i].categories = SDLVisualTest_Tokenize(token_ptr,
 | 
						|
                                        MAX_SUTOPTION_CATEGORY_LEN);
 | 
						|
    }
 | 
						|
    SDL_RWclose(rw);
 | 
						|
    return 1;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
SDLVisualTest_FreeSUTConfig(SDLVisualTest_SUTConfig* config)
 | 
						|
{
 | 
						|
    if(config && config->options)
 | 
						|
    {
 | 
						|
        SDLVisualTest_SUTOption* option;
 | 
						|
        for(option = config->options;
 | 
						|
            option != config->options + config->num_options; option++)
 | 
						|
        {
 | 
						|
            if(option->categories)
 | 
						|
                SDL_free(option->categories);
 | 
						|
            if(option->type == SDL_SUT_OPTIONTYPE_ENUM && option->data.enum_values)
 | 
						|
                SDL_free(option->data.enum_values);
 | 
						|
        }
 | 
						|
        SDL_free(config->options);
 | 
						|
        config->options = NULL;
 | 
						|
        config->num_options = 0;
 | 
						|
    }
 | 
						|
}
 |