2022-10-27 15:16:54 -06:00
# include "arc/std/config.h"
2025-03-11 00:41:17 -06:00
# include "arc/std/parser/helpers.h"
# include "arc/std/bool.h"
2022-10-27 15:16:54 -06:00
# include "arc/std/errno.h"
2023-01-17 01:59:08 -07:00
# include "arc/std/hashtable.h"
2025-03-11 00:41:17 -06:00
# include "arc/std/parser.h"
# include <stddef.h>
2023-01-17 01:59:08 -07:00
# include <stdint.h>
2022-10-27 15:16:54 -06:00
# include <stdlib.h>
# include <string.h>
struct ARC_Config {
2025-03-11 00:41:17 -06:00
ARC_Parser * parser ;
2022-10-27 15:16:54 -06:00
2025-03-11 00:41:17 -06:00
ARC_Hashtable * types ;
2022-10-27 15:16:54 -06:00
2025-03-11 00:41:17 -06:00
ARC_Hashtable * groups ;
ARC_Hashtable * currentGroup ;
2022-10-27 15:16:54 -06:00
2025-03-11 00:41:17 -06:00
ARC_Bool load ;
} ;
2022-10-27 15:16:54 -06:00
2025-03-11 00:41:17 -06:00
typedef struct ARC_ConfigTypeData {
2022-10-27 15:16:54 -06:00
void * data ;
2025-03-11 00:41:17 -06:00
ARC_ConfigType_DestroyFn destroyFn ;
} ARC_ConfigTypeData ;
void ARC_Config_InitLexerRulesFn ( ARC_Lexer * lexer ) {
ARC_Lexer_RegisterTokenRule ( lexer , ARC_LexerTokenRule_CreateAndReturnMatchCharRule ( ARC_CONFIG_TAB , ' \t ' ) ) ;
ARC_Lexer_RegisterTokenRule ( lexer , ARC_LexerTokenRule_CreateAndReturnMatchCharRule ( ARC_CONFIG_NEWLINE , ' \n ' ) ) ;
ARC_Lexer_RegisterTokenRule ( lexer , ARC_LexerTokenRule_CreateAndReturnMatchCharRule ( ARC_CONFIG_SPACE , ' ' ) ) ;
ARC_Lexer_RegisterTokenRule ( lexer , ARC_LexerTokenRule_CreateAndReturnMatchCharRule ( ARC_CONFIG_BANG , ' ! ' ) ) ;
ARC_Lexer_RegisterTokenRule ( lexer , ARC_LexerTokenRule_CreateAndReturnMatchCharRule ( ARC_CONFIG_QUOTE , ' " ' ) ) ;
ARC_Lexer_RegisterTokenRule ( lexer , ARC_LexerTokenRule_CreateAndReturnMatchCharRule ( ARC_CONFIG_HASH , ' # ' ) ) ;
ARC_Lexer_RegisterTokenRule ( lexer , ARC_LexerTokenRule_CreateAndReturnMatchCharRule ( ARC_CONFIG_DOLLAR , ' $ ' ) ) ;
ARC_Lexer_RegisterTokenRule ( lexer , ARC_LexerTokenRule_CreateAndReturnMatchCharRule ( ARC_CONFIG_PERCENT , ' % ' ) ) ;
ARC_Lexer_RegisterTokenRule ( lexer , ARC_LexerTokenRule_CreateAndReturnMatchCharRule ( ARC_CONFIG_AMPERSAND , ' & ' ) ) ;
ARC_Lexer_RegisterTokenRule ( lexer , ARC_LexerTokenRule_CreateAndReturnMatchCharRule ( ARC_CONFIG_SINGLE_QUOTE , ' \' ' ) ) ;
ARC_Lexer_RegisterTokenRule ( lexer , ARC_LexerTokenRule_CreateAndReturnMatchCharRule ( ARC_CONFIG_OPEN_PAREN , ' ( ' ) ) ;
ARC_Lexer_RegisterTokenRule ( lexer , ARC_LexerTokenRule_CreateAndReturnMatchCharRule ( ARC_CONFIG_CLOSE_PAREN , ' ) ' ) ) ;
ARC_Lexer_RegisterTokenRule ( lexer , ARC_LexerTokenRule_CreateAndReturnMatchCharRule ( ARC_CONFIG_ASTERISK , ' * ' ) ) ;
ARC_Lexer_RegisterTokenRule ( lexer , ARC_LexerTokenRule_CreateAndReturnMatchCharRule ( ARC_CONFIG_PLUS , ' + ' ) ) ;
ARC_Lexer_RegisterTokenRule ( lexer , ARC_LexerTokenRule_CreateAndReturnMatchCharRule ( ARC_CONFIG_COMMA , ' , ' ) ) ;
ARC_Lexer_RegisterTokenRule ( lexer , ARC_LexerTokenRule_CreateAndReturnMatchCharRule ( ARC_CONFIG_MINUS , ' - ' ) ) ;
ARC_Lexer_RegisterTokenRule ( lexer , ARC_LexerTokenRule_CreateAndReturnMatchCharRule ( ARC_CONFIG_PERIOD , ' . ' ) ) ;
ARC_Lexer_RegisterTokenRule ( lexer , ARC_LexerTokenRule_CreateAndReturnMatchCharRule ( ARC_CONFIG_SLASH , ' / ' ) ) ;
ARC_Lexer_RegisterTokenRule ( lexer , ARC_LexerTokenRule_CreateAndReturnMatchCharOrBetween ( ARC_CONFIG_NUMBER , ' 0 ' , ' 9 ' ) ) ;
ARC_Lexer_RegisterTokenRule ( lexer , ARC_LexerTokenRule_CreateAndReturnMatchCharRule ( ARC_CONFIG_COLON , ' : ' ) ) ;
ARC_Lexer_RegisterTokenRule ( lexer , ARC_LexerTokenRule_CreateAndReturnMatchCharRule ( ARC_CONFIG_SEMICOLON , ' ; ' ) ) ;
ARC_Lexer_RegisterTokenRule ( lexer , ARC_LexerTokenRule_CreateAndReturnMatchCharRule ( ARC_CONFIG_LESS_THAN , ' < ' ) ) ;
ARC_Lexer_RegisterTokenRule ( lexer , ARC_LexerTokenRule_CreateAndReturnMatchCharRule ( ARC_CONFIG_GREATER_THAN , ' > ' ) ) ;
ARC_Lexer_RegisterTokenRule ( lexer , ARC_LexerTokenRule_CreateAndReturnMatchCharRule ( ARC_CONFIG_EQUAL , ' = ' ) ) ;
ARC_Lexer_RegisterTokenRule ( lexer , ARC_LexerTokenRule_CreateAndReturnMatchCharRule ( ARC_CONFIG_QUESTION_MARK , ' ? ' ) ) ;
ARC_Lexer_RegisterTokenRule ( lexer , ARC_LexerTokenRule_CreateAndReturnMatchCharRule ( ARC_CONFIG_AT , ' @ ' ) ) ;
ARC_Lexer_RegisterTokenRule ( lexer , ARC_LexerTokenRule_CreateAndReturnMatchCharOrBetween ( ARC_CONFIG_ALPHA_UPPER_CHAR , ' A ' , ' Z ' ) ) ;
ARC_Lexer_RegisterTokenRule ( lexer , ARC_LexerTokenRule_CreateAndReturnMatchCharRule ( ARC_CONFIG_OPEN_BRACKET , ' [ ' ) ) ;
ARC_Lexer_RegisterTokenRule ( lexer , ARC_LexerTokenRule_CreateAndReturnMatchCharRule ( ARC_CONFIG_BACKSLASH , ' \\ ' ) ) ;
ARC_Lexer_RegisterTokenRule ( lexer , ARC_LexerTokenRule_CreateAndReturnMatchCharRule ( ARC_CONFIG_CLOSE_BRACKET , ' ] ' ) ) ;
ARC_Lexer_RegisterTokenRule ( lexer , ARC_LexerTokenRule_CreateAndReturnMatchCharRule ( ARC_CONFIG_CARET , ' ^ ' ) ) ;
ARC_Lexer_RegisterTokenRule ( lexer , ARC_LexerTokenRule_CreateAndReturnMatchCharRule ( ARC_CONFIG_UNDERSCORE , ' _ ' ) ) ;
ARC_Lexer_RegisterTokenRule ( lexer , ARC_LexerTokenRule_CreateAndReturnMatchCharRule ( ARC_CONFIG_GRAVE , ' ` ' ) ) ;
ARC_Lexer_RegisterTokenRule ( lexer , ARC_LexerTokenRule_CreateAndReturnMatchCharOrBetween ( ARC_CONFIG_ALPHA_LOWER_CHAR , ' a ' , ' z ' ) ) ;
ARC_Lexer_RegisterTokenRule ( lexer , ARC_LexerTokenRule_CreateAndReturnMatchCharRule ( ARC_CONFIG_OPEN_CURLY_BRACE , ' { ' ) ) ;
ARC_Lexer_RegisterTokenRule ( lexer , ARC_LexerTokenRule_CreateAndReturnMatchCharRule ( ARC_CONFIG_VERTICAL_LINE , ' | ' ) ) ;
ARC_Lexer_RegisterTokenRule ( lexer , ARC_LexerTokenRule_CreateAndReturnMatchCharRule ( ARC_CONFIG_CLOSE_CURLY_BRACE , ' } ' ) ) ;
ARC_Lexer_RegisterTokenRule ( lexer , ARC_LexerTokenRule_CreateAndReturnMatchCharRule ( ARC_CONFIG_TILDE , ' ~ ' ) ) ;
}
2022-10-27 15:16:54 -06:00
2025-03-11 00:41:17 -06:00
uint32_t ARC_Config_GetStringIdFn ( ARC_String * string ) {
if ( ARC_String_EqualsCStringWithStrlen ( string , " LAMBDA " ) ) {
return ARC_PARSER_TAG_LAMBDA ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " TAB " ) ) {
return ARC_CONFIG_TAB ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " NEWLINE " ) ) {
return ARC_CONFIG_NEWLINE ;
}
2023-01-20 22:38:29 -07:00
2025-03-11 00:41:17 -06:00
if ( ARC_String_EqualsCStringWithStrlen ( string , " SPACE " ) ) {
return ARC_CONFIG_SPACE ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " BANG " ) ) {
return ARC_CONFIG_BANG ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " QUOTE " ) ) {
return ARC_CONFIG_QUOTE ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " HASH " ) ) {
return ARC_CONFIG_HASH ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " DOLLAR " ) ) {
return ARC_CONFIG_DOLLAR ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " PERCENT " ) ) {
return ARC_CONFIG_PERCENT ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " AMPERSAND " ) ) {
return ARC_CONFIG_AMPERSAND ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " SINGLE_QUOTE " ) ) {
return ARC_CONFIG_SINGLE_QUOTE ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " OPEN_PAREN " ) ) {
return ARC_CONFIG_OPEN_PAREN ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " CLOSE_PAREN " ) ) {
return ARC_CONFIG_CLOSE_PAREN ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " ASTERISK " ) ) {
return ARC_CONFIG_ASTERISK ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " PLUS " ) ) {
return ARC_CONFIG_PLUS ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " COMMA " ) ) {
return ARC_CONFIG_COMMA ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " MINUS " ) ) {
return ARC_CONFIG_MINUS ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " PERIOD " ) ) {
return ARC_CONFIG_PERIOD ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " SLASH " ) ) {
return ARC_CONFIG_SLASH ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " NUMBER " ) ) {
return ARC_CONFIG_NUMBER ;
}
2022-10-27 15:16:54 -06:00
2025-03-11 00:41:17 -06:00
if ( ARC_String_EqualsCStringWithStrlen ( string , " COLON " ) ) {
return ARC_CONFIG_COLON ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " SEMICOLON " ) ) {
return ARC_CONFIG_SEMICOLON ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " LESS_THAN " ) ) {
return ARC_CONFIG_LESS_THAN ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " GREATER_THAN " ) ) {
return ARC_CONFIG_GREATER_THAN ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " EQUAL " ) ) {
return ARC_CONFIG_EQUAL ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " QUESTION_MARK " ) ) {
return ARC_CONFIG_QUESTION_MARK ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " AT " ) ) {
return ARC_CONFIG_AT ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " ALPHA_UPPER_CHAR " ) ) {
return ARC_CONFIG_ALPHA_UPPER_CHAR ;
}
2022-10-27 15:16:54 -06:00
2025-03-11 00:41:17 -06:00
if ( ARC_String_EqualsCStringWithStrlen ( string , " OPEN_BRACKET " ) ) {
return ARC_CONFIG_OPEN_BRACKET ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " BACKSLASH " ) ) {
return ARC_CONFIG_BACKSLASH ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " CLOSE_BRACKET " ) ) {
return ARC_CONFIG_CLOSE_BRACKET ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " CARET " ) ) {
return ARC_CONFIG_CARET ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " UNDERSCORE " ) ) {
return ARC_CONFIG_UNDERSCORE ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " GRAVE " ) ) {
return ARC_CONFIG_GRAVE ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " ALPHA_LOWER_CHAR " ) ) {
return ARC_CONFIG_ALPHA_LOWER_CHAR ;
}
2022-10-27 15:16:54 -06:00
2025-03-11 00:41:17 -06:00
if ( ARC_String_EqualsCStringWithStrlen ( string , " OPEN_CURLY_BRACE " ) ) {
return ARC_CONFIG_OPEN_CURLY_BRACE ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " VERTICAL_LINE " ) ) {
return ARC_CONFIG_VERTICAL_LINE ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " CLOSE_CURLY_BRACE " ) ) {
return ARC_CONFIG_CLOSE_CURLY_BRACE ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " TILDE " ) ) {
return ARC_CONFIG_TILDE ;
}
2022-10-27 15:16:54 -06:00
2025-03-11 00:41:17 -06:00
if ( ARC_String_EqualsCStringWithStrlen ( string , " <language> " ) ) {
return ARC_CONFIG_LANGUAGE ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " <group> " ) ) {
return ARC_CONFIG_GROUP ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " <groupName> " ) ) {
return ARC_CONFIG_GROUP_NAME ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " <groupArgs> " ) ) {
return ARC_CONFIG_GROUP_ARGS ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " <variableLines> " ) ) {
return ARC_CONFIG_VARIABLE_LINES ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " <variableLine> " ) ) {
return ARC_CONFIG_VARIABLE_LINE ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " <allowSpace> " ) ) {
return ARC_CONFIG_ALLOW_SPACE ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " <type> " ) ) {
return ARC_CONFIG_TYPE ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " <value> " ) ) {
return ARC_CONFIG_VALUE ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " <nestedValue> " ) ) {
return ARC_CONFIG_NESTED_VALUE ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " <valueArgs> " ) ) {
return ARC_CONFIG_VALUE_ARGS ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " <variable> " ) ) {
return ARC_CONFIG_VARIABLE ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " <variableName> " ) ) {
return ARC_CONFIG_VARIABLE_NAME ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " <variableChar> " ) ) {
return ARC_CONFIG_VARIABLE_CHAR ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " <string> " ) ) {
return ARC_CONFIG_STRING ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " <stringChars> " ) ) {
return ARC_CONFIG_STRING_CHARS ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " <stringChar> " ) ) {
return ARC_CONFIG_STRING_CHAR ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " <escapeChar> " ) ) {
return ARC_CONFIG_ESCAPE_CHAR ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " <numberSign> " ) ) {
return ARC_CONFIG_NUMBER_SIGN ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " <number> " ) ) {
return ARC_CONFIG_NUMBER_TAG ;
}
if ( ARC_String_EqualsCStringWithStrlen ( string , " <whitespace> " ) ) {
return ARC_CONFIG_WHITESPACE ;
}
2022-10-27 15:16:54 -06:00
2025-03-11 00:41:17 -06:00
return ~ ( uint32_t ) 0 ;
2022-10-27 15:16:54 -06:00
}
2025-03-11 00:41:17 -06:00
//private function to check hashtable keys used by config
ARC_Bool ARC_Config_HashtableKeyCompareFn ( void * key1 , void * key2 ) {
return ( ARC_Bool ) strcmp ( ( const char * ) key1 , ( const char * ) key2 ) = = 0 ;
2022-10-27 15:16:54 -06:00
}
2025-03-11 00:41:17 -06:00
//private function to clean up types
void ARC_Config_TypeHashtableDestroyKeyValueFn ( void * key , void * value ) {
free ( ( char * ) key ) ;
free ( ( ARC_ConfigType * ) value ) ;
}
2022-10-27 15:16:54 -06:00
2025-03-11 00:41:17 -06:00
//private function to clean up groups
void ARC_Config_GroupHashtableDestroyKeyValueFn ( void * key , void * value ) {
free ( ( char * ) key ) ;
ARC_Hashtable_Destroy ( ( ARC_Hashtable * ) value ) ;
2023-01-17 01:59:08 -07:00
}
2022-10-27 15:16:54 -06:00
2025-03-11 00:41:17 -06:00
//private function to clean up goup data
void ARC_Config_GroupDataHashtableDestroyKeyValueFn ( void * key , void * value ) {
free ( ( char * ) key ) ;
2023-01-20 22:38:29 -07:00
2025-03-11 00:41:17 -06:00
ARC_ConfigTypeData * typeData = ( ARC_ConfigTypeData * ) value ;
typeData - > destroyFn ( typeData - > data ) ;
free ( typeData ) ;
2022-10-27 15:16:54 -06:00
}
2025-03-11 00:41:17 -06:00
//<variableLine> -> <whitespace> <type> <whitespace> <variable> <whitespace> EQUAL <whitespace> <value> <whitespace> SEMICOLON
void ARC_ConfigData_RunVariableLineTag ( ARC_ParserTagToken * tagToken , ARC_Config * config ) {
//skip whitespace and check for group name
ARC_ParserTagToken * childTagToken = ( ARC_ParserTagToken * ) ARC_Vector_Get ( tagToken - > tagTokens , 1 ) ;
//get the type
ARC_String * typeString ;
ARC_String_Create ( & typeString , NULL , 0 ) ;
ARC_ParserData_HelperRecurseStringAdd ( & typeString , childTagToken ) ;
2023-01-20 22:38:29 -07:00
2025-03-11 00:41:17 -06:00
//check if type exists in the types hashtable
ARC_ConfigType * type = ( ARC_ConfigType * ) ARC_Hashtable_Get ( config - > types , typeString - > data ) ;
if ( type = = NULL ) {
//throw an error and return
arc_errno = ARC_ERRNO_DATA ;
ARC_DEBUG_LOG_ERROR_WITH_VARIABLES ( " ARC_ConfigData_RunVariableLineTag(tagToken, config), type \" %s \" was not registered to config " , typeString - > data ) ;
ARC_String_Destroy ( typeString ) ;
2023-01-17 01:59:08 -07:00
return ;
}
2025-03-11 00:41:17 -06:00
//cleanup
ARC_String_Destroy ( typeString ) ;
2024-08-28 02:57:29 -06:00
2025-03-11 00:41:17 -06:00
//get the variable
childTagToken = ( ARC_ParserTagToken * ) ARC_Vector_Get ( tagToken - > tagTokens , 3 ) ;
ARC_String * variableString ;
ARC_String_Create ( & variableString , NULL , 0 ) ;
ARC_ParserData_HelperRecurseStringAdd ( & variableString , childTagToken ) ;
2022-10-27 15:16:54 -06:00
2025-03-11 00:41:17 -06:00
//check if removing
if ( config - > load = = ARC_False ) {
ARC_Hashtable_Remove ( config - > currentGroup , ( void * ) variableString - > data ) ;
ARC_String_Destroy ( variableString ) ;
2023-01-17 01:59:08 -07:00
return ;
}
2022-10-27 15:16:54 -06:00
2025-03-11 00:41:17 -06:00
//check to see if the current variable is already in the current group hashtable
ARC_ConfigTypeData * typeData = ( ARC_ConfigTypeData * ) ARC_Hashtable_Get ( config - > currentGroup , variableString - > data ) ;
if ( typeData ! = NULL ) {
//there is already a value so throw an error and return
arc_errno = ARC_ERRNO_DATA ;
ARC_DEBUG_LOG_ERROR_WITH_VARIABLES ( " ARC_ConfigData_RunVariableLineTag(tagToken, config), variable \" %s \" already registered to the current group " , variableString - > data ) ;
ARC_String_Destroy ( variableString ) ;
2023-01-17 01:59:08 -07:00
return ;
}
2025-03-11 00:41:17 -06:00
//copy the string into a cstring that will be stored in the hashtable
char * nameVariableCStr = malloc ( sizeof ( char ) * ( variableString - > length + 1 ) ) ;
strncpy ( nameVariableCStr , variableString - > data , variableString - > length ) ;
nameVariableCStr [ variableString - > length ] = ' \0 ' ;
ARC_String_Destroy ( variableString ) ;
//get <value>
childTagToken = ( ARC_ParserTagToken * ) ARC_Vector_Get ( tagToken - > tagTokens , 7 ) ;
//check if <value> is a reference
ARC_String * valueString ;
ARC_String_Create ( & valueString , NULL , 0 ) ;
ARC_ParserData_HelperRecurseStringAdd ( & valueString , childTagToken ) ;
void * value = ARC_Hashtable_Get ( config - > currentGroup , valueString ) ;
ARC_String_Destroy ( valueString ) ;
//create where to store either the reference or type data
typeData = ( ARC_ConfigTypeData * ) malloc ( sizeof ( ARC_ConfigTypeData ) ) ;
if ( value ! = NULL ) {
//point to the already stored data
typeData - > data = value ;
typeData - > destroyFn = NULL ;
//add to the current group hashtable
ARC_Hashtable_Add ( config - > currentGroup , ( void * ) nameVariableCStr , ( void * ) typeData ) ;
2023-01-17 01:59:08 -07:00
return ;
}
2025-03-11 00:41:17 -06:00
//passed the parsed value into the copy type function and set the destroy function
type - > copyFn ( & ( typeData - > data ) , childTagToken , config ) ;
typeData - > destroyFn = type - > destroyFn ;
2023-01-20 22:38:29 -07:00
2025-03-11 00:41:17 -06:00
//add to the current group hashtable
ARC_Hashtable_Add ( config - > currentGroup , ( void * ) nameVariableCStr , ( void * ) typeData ) ;
}
2022-10-27 15:16:54 -06:00
2025-03-11 00:41:17 -06:00
//<variableLines> -> <variableLine> <whitespace> <variableLines> | <variableLine>
void ARC_ConfigData_RunVariableLinesTag ( ARC_ParserTagToken * tagToken , ARC_Config * config ) {
//loop through the tags either going to the next line or the next body
for ( uint32_t index = 0 ; index < ARC_Vector_GetSize ( tagToken - > tagTokens ) ; index + + ) {
ARC_ParserTagToken * childTagToken = ( ARC_ParserTagToken * ) ARC_Vector_Get ( tagToken - > tagTokens , index ) ;
switch ( childTagToken - > id ) {
//recuse to run the next line
case ARC_CONFIG_VARIABLE_LINES :
ARC_ConfigData_RunVariableLinesTag ( childTagToken , config ) ;
if ( arc_errno ! = 0 ) {
ARC_DEBUG_LOG_ERROR ( " ARC_ConfigData_RunVariableLinesTag(tagToken, config), config errored when trying to used parsed data for variable lines " ) ;
return ;
}
continue ;
//recurse into a variable line tag
case ARC_CONFIG_VARIABLE_LINE :
ARC_ConfigData_RunVariableLineTag ( childTagToken , config ) ;
if ( arc_errno ! = 0 ) {
ARC_DEBUG_LOG_ERROR ( " ARC_ConfigData_RunVariableLinesTag(tagToken, config), config errored when trying to used parsed data for variable line " ) ;
return ;
}
continue ;
//this is for whitespace and any oddities
default :
continue ;
2023-01-17 01:59:08 -07:00
}
2025-03-11 00:41:17 -06:00
}
}
2022-10-27 15:16:54 -06:00
2025-03-11 00:41:17 -06:00
//<group> -> <whitespace> <groupName> <whitespace> <variable> <whitespace> OPEN_CURLY_BRACE <groupArgs> <whitespace> CLOSE_CURLY_BRACE
void ARC_ConfigData_RunGroupTag ( ARC_ParserTagToken * tagToken , ARC_Config * config ) {
//skip whitespace and check for group name
ARC_ParserTagToken * childTagToken = ( ARC_ParserTagToken * ) ARC_Vector_Get ( tagToken - > tagTokens , 1 ) ;
/* ~ <groupName> ~ */
//get the group name and check if it is named "group"
//NOTE: this check may be usedful in the future if there is different functionality for group like tag names
ARC_String * groupName ;
ARC_String_Create ( & groupName , NULL , 0 ) ;
ARC_ParserData_HelperRecurseStringAdd ( & groupName , childTagToken ) ;
if ( ARC_String_EqualsCStringWithStrlen ( groupName , ARC_CONFIG_GROUP_TAG_NAME ) = = ARC_False ) {
//throw an error and return
arc_errno = ARC_ERRNO_DATA ;
ARC_DEBUG_LOG_ERROR_WITH_VARIABLES ( " ARC_ConfigData_RunGroupTag(tagToken, config), config contained keyword \" %s \" instead of using the correct keyword: \" %s \" " , groupName - > data , ARC_CONFIG_GROUP_TAG_NAME ) ;
ARC_String_Destroy ( groupName ) ;
return ;
}
2022-10-27 15:16:54 -06:00
2025-03-11 00:41:17 -06:00
//cleanup
ARC_String_Destroy ( groupName ) ;
/* ~ <variable> ~ */
//get the group's variable name
childTagToken = ( ARC_ParserTagToken * ) ARC_Vector_Get ( tagToken - > tagTokens , 3 ) ;
ARC_String * groupVariable ;
ARC_String_Create ( & groupVariable , NULL , 0 ) ;
ARC_ParserData_HelperRecurseStringAdd ( & groupVariable , childTagToken ) ;
//check if removing
if ( config - > load = = ARC_False ) {
/* ~ <groupArgs> ~ */
childTagToken = ( ARC_ParserTagToken * ) ARC_Vector_Get ( tagToken - > tagTokens , 6 ) ;
//<groupArgs> -> <whitespace> <variableLines> | LAMBDA
if ( childTagToken - > token = = NULL & & ARC_Vector_GetSize ( childTagToken - > tagTokens ) = = 2 ) {
ARC_ParserTagToken * variableLines = ( ARC_ParserTagToken * ) ARC_Vector_Get ( childTagToken - > tagTokens , 1 ) ;
ARC_ConfigData_RunVariableLinesTag ( variableLines , config ) ;
//log error if it happens
if ( arc_errno ! = 0 ) {
ARC_DEBUG_LOG_ERROR ( " ARC_ConfigData_RunGroupTag(tagToken, config), config errored when trying to used parsed data for variable lines " ) ;
}
2023-01-20 22:38:29 -07:00
}
2023-02-23 00:07:18 -07:00
2025-03-11 00:41:17 -06:00
//remove an empty hashtable if it is now empty
if ( ARC_Hashtable_GetSize ( config - > groups ) ) {
ARC_String_Destroy ( groupVariable ) ;
2023-02-23 00:07:18 -07:00
}
2023-01-17 01:59:08 -07:00
return ;
2022-10-27 15:16:54 -06:00
}
2025-03-11 00:41:17 -06:00
//get the needed hashtable or create it from the groups hashtable
ARC_Hashtable * groupHashtable = ARC_Hashtable_Get ( config - > groups , ( void * ) groupVariable - > data ) ;
if ( groupHashtable = = NULL ) {
//copy the string into a cstring that will be stored in the hashtable
char * groupVariableCStr = malloc ( sizeof ( char ) * ( groupVariable - > length + 1 ) ) ;
strncpy ( groupVariableCStr , groupVariable - > data , groupVariable - > length ) ;
groupVariableCStr [ groupVariable - > length ] = ' \0 ' ;
//create the hashtable with the given group name key
ARC_Hashtable_KeyCompareFn keyCompareFn = ARC_Config_HashtableKeyCompareFn ;
ARC_Hashtable_DestroyKeyValueFn groupDataDestroyKeyValueFn = ARC_Config_GroupDataHashtableDestroyKeyValueFn ;
ARC_Hashtable_Create ( & groupHashtable , NULL , & keyCompareFn , & groupDataDestroyKeyValueFn ) ;
ARC_Hashtable_Add ( config - > groups , ( void * ) groupVariableCStr , ( void * ) groupHashtable ) ;
2023-01-20 22:38:29 -07:00
}
2025-03-11 00:41:17 -06:00
//cleanup
ARC_String_Destroy ( groupVariable ) ;
2022-10-27 15:16:54 -06:00
2025-03-11 00:41:17 -06:00
//set the current group to the group just created or found
config - > currentGroup = groupHashtable ;
2022-10-27 15:16:54 -06:00
2025-03-11 00:41:17 -06:00
/* ~ <groupArgs> ~ */
childTagToken = ( ARC_ParserTagToken * ) ARC_Vector_Get ( tagToken - > tagTokens , 6 ) ;
2022-10-27 15:16:54 -06:00
2025-03-11 00:41:17 -06:00
//<groupArgs> -> <whitespace> <variableLines> | LAMBDA
if ( childTagToken - > token = = NULL & & ARC_Vector_GetSize ( childTagToken - > tagTokens ) = = 2 ) {
ARC_ParserTagToken * variableLines = ( ARC_ParserTagToken * ) ARC_Vector_Get ( childTagToken - > tagTokens , 1 ) ;
ARC_ConfigData_RunVariableLinesTag ( variableLines , config ) ;
2022-10-27 15:16:54 -06:00
2025-03-11 00:41:17 -06:00
//log error if it happens, but as setting the group back is the last thing we shouldn't return
if ( arc_errno ! = 0 ) {
ARC_DEBUG_LOG_ERROR ( " ARC_ConfigData_RunGroupTag(tagToken, config), config errored when trying to used parsed data for variable lines " ) ;
}
2022-10-27 15:16:54 -06:00
}
2025-03-11 00:41:17 -06:00
/* ~ reset current group ~ */
config - > currentGroup = ARC_Hashtable_Get ( config - > groups , ( void * ) ARC_CONFIG_DEFAULT_GROUP ) ;
2023-01-17 01:59:08 -07:00
}
2022-10-27 15:16:54 -06:00
2025-03-11 00:41:17 -06:00
//<language> -> <group> <language> | <variableLines> <language> | <whitespace>
void ARC_ConfigData_RunLanguageTag ( ARC_ParserTagToken * tagToken , ARC_Config * config ) {
//loop through the tags either going to the next language, group, or variable lines
for ( uint32_t index = 0 ; index < ARC_Vector_GetSize ( tagToken - > tagTokens ) ; index + + ) {
ARC_ParserTagToken * childTagToken = ( ARC_ParserTagToken * ) ARC_Vector_Get ( tagToken - > tagTokens , index ) ;
switch ( childTagToken - > id ) {
//recuse to run the next line
case ARC_CONFIG_LANGUAGE :
ARC_ConfigData_RunLanguageTag ( childTagToken , config ) ;
continue ;
//recurse into a group tag
case ARC_CONFIG_GROUP :
ARC_ConfigData_RunGroupTag ( childTagToken , config ) ;
if ( arc_errno ! = 0 ) {
ARC_DEBUG_LOG_ERROR ( " ARC_ConfigData_RunLanguageTag(tagToken, config), config errored when trying to used parsed data for a group " ) ;
return ;
}
continue ;
//recurse through variable lines
case ARC_CONFIG_VARIABLE_LINES :
ARC_ConfigData_RunVariableLinesTag ( childTagToken , config ) ;
ARC_ConfigData_RunGroupTag ( childTagToken , config ) ;
if ( arc_errno ! = 0 ) {
ARC_DEBUG_LOG_ERROR ( " ARC_ConfigData_RunLanguageTag(tagToken, config), config errored when trying to used parsed data for variable lines " ) ;
return ;
}
continue ;
//this is for whitespace and any oddities
default :
continue ;
}
2023-01-17 01:59:08 -07:00
}
2025-03-11 00:41:17 -06:00
}
2022-10-27 15:16:54 -06:00
2025-03-11 00:41:17 -06:00
void ARC_ConfigData_CreateFn ( void * * data , ARC_ParserTagToken * parsedData , void * userData ) {
* data = NULL ;
if ( parsedData = = NULL | | userData = = NULL ) {
//TODO: error here?
* data = NULL ;
2023-01-17 01:59:08 -07:00
return ;
2022-10-27 15:16:54 -06:00
}
2025-03-11 00:41:17 -06:00
ARC_ConfigData_RunLanguageTag ( parsedData , ( ARC_Config * ) userData ) ;
2023-01-17 01:59:08 -07:00
}
2022-10-27 15:16:54 -06:00
2025-03-11 00:41:17 -06:00
void ARC_ConfigData_DestroyFn ( void * data , ARC_Bool clear , void * userData ) {
return ;
2022-10-27 15:16:54 -06:00
}
2025-03-11 00:41:17 -06:00
void ARC_Config_Create ( ARC_Config * * config ) {
* config = ( ARC_Config * ) malloc ( sizeof ( ARC_Config ) ) ;
2022-10-27 15:16:54 -06:00
2025-03-11 00:41:17 -06:00
/* ~ define the language as a string ~ */
char * languageCString =
" <language> -> <group> <language> | <variableLines> <language> | <whitespace> \n "
2022-10-27 15:16:54 -06:00
2025-03-11 00:41:17 -06:00
" <group> -> <whitespace> <groupName> <whitespace> <variable> <whitespace> OPEN_CURLY_BRACE <groupArgs> <whitespace> CLOSE_CURLY_BRACE \n "
" <groupName> -> <variable> \n "
" <groupArgs> -> <whitespace> <variableLines> | LAMBDA \n "
2022-10-27 15:16:54 -06:00
2025-03-11 00:41:17 -06:00
" <variableLines> -> <variableLine> <whitespace> <variableLines> | <variableLine> \n "
" <variableLine> -> <whitespace> <type> <whitespace> <variable> <whitespace> EQUAL <whitespace> <value> <whitespace> SEMICOLON \n "
" <allowSpace> -> SPACE <allowSpace> | TAB <allowSpace> | LAMBDA \n "
2022-10-27 15:16:54 -06:00
2025-03-11 00:41:17 -06:00
" <type> -> <variable> \n "
" <value> -> <variable> | <numberSign> | <string> | <nestedValue> \n "
" <nestedValue> -> OPEN_CURLY_BRACE <whitespace> <valueArgs> <whitespace> CLOSE_CURLY_BRACE \n "
" <valueArgs> -> <value> COMMA <valueArgs> | <value> \n "
2022-10-27 15:16:54 -06:00
2025-03-11 00:41:17 -06:00
" <variable> -> ALPHA_UPPER_CHAR <variableName> | ALPHA_LOWER_CHAR <variableName> | UNDERSCORE <variableName> \n "
" <variableName> -> <variableChar> <variableName> | LAMBDA \n "
" <variableChar> -> ALPHA_UPPER_CHAR | ALPHA_LOWER_CHAR | UNDERSCORE | NUMBER \n "
2022-10-27 15:16:54 -06:00
2025-03-11 00:41:17 -06:00
" <string> -> QUOTE <stringChars> QUOTE \n "
" <stringChars> -> <stringChar> <stringChars> | <escapeChar> <stringChars> | LAMBDA \n "
" <stringChar> -> TAB | SPACE | BANG | HASH | DOLLAR | PERCENT | AMPERSAND | SINGLE_QUOTE | OPEN_PAREN | CLOSE_PAREN | ASTERISK | PLUS | COMMA | MINUS | PERIOD | SLASH | NUMBER | COLON | SEMICOLON | LESS_THAN | GREATER_THAN | EQUAL | QUESTION_MARK | AT | ALPHA_UPPER_CHAR | OPEN_BRACKET | CLOSE_BRACKET | CARET | UNDERSCORE | GRAVE | ALPHA_LOWER_CHAR | OPEN_CURLY_BRACE | VERTICAL_LINE | CLOSE_CURLY_BRACE | TILDE \n "
" <escapeChar> -> BACKSLASH BACKSLASH | BACKSLASH QUOTE | BACKSLASH ALPHA_UPPER_CHAR | BACKSLASH ALPHA_LOWER_CHAR \n "
2022-10-27 15:16:54 -06:00
2025-03-11 00:41:17 -06:00
" <numberSign> -> MINUS <number> | <number> \n "
" <number> -> NUMBER <number> | NUMBER \n "
2022-10-27 15:16:54 -06:00
2025-03-11 00:41:17 -06:00
" <whitespace> -> SPACE <whitespace> | TAB <whitespace> | NEWLINE <whitespace> | LAMBDA \n " ;
2023-01-17 01:59:08 -07:00
2025-03-11 00:41:17 -06:00
/* ~ define the language as a string ~ */
ARC_String * languageString ;
ARC_String_CreateWithStrlen ( & languageString , languageCString ) ;
2022-10-27 15:16:54 -06:00
2025-03-11 00:41:17 -06:00
/* ~ set config as userdata ~ */
void * userdata = * config ;
2022-10-27 15:16:54 -06:00
2025-03-11 00:41:17 -06:00
/* ~ create the language ~ */
ARC_ParserData_CreateFn createCharFn = ARC_ConfigData_CreateFn ;
ARC_ParserData_DestroyFn destroyCharFn = ARC_ConfigData_DestroyFn ;
ARC_Parser_CreateFromString ( & ( ( * config ) - > parser ) , languageString , ARC_Config_InitLexerRulesFn , ARC_Config_GetStringIdFn , & createCharFn , & destroyCharFn , userdata ) ;
2022-10-27 15:16:54 -06:00
2025-03-11 00:41:17 -06:00
/* ~ init types ~ */
ARC_Hashtable_KeyCompareFn keyCompareFn = ARC_Config_HashtableKeyCompareFn ;
ARC_Hashtable_DestroyKeyValueFn typeDestroyKeyValueFn = ARC_Config_TypeHashtableDestroyKeyValueFn ;
ARC_Hashtable_Create ( & ( ( * config ) - > types ) , NULL , & keyCompareFn , & typeDestroyKeyValueFn ) ;
2022-10-27 15:16:54 -06:00
2025-03-11 00:41:17 -06:00
/* ~ init groups ~ */
ARC_Hashtable_DestroyKeyValueFn groupDestroyKeyValueFn = ARC_Config_GroupHashtableDestroyKeyValueFn ;
ARC_Hashtable_Create ( & ( ( * config ) - > groups ) , NULL , & keyCompareFn , & groupDestroyKeyValueFn ) ;
2022-10-27 15:16:54 -06:00
2025-03-11 00:41:17 -06:00
//add the default/empty group into the groups
ARC_Hashtable_DestroyKeyValueFn groupDataDestroyKeyValueFn = ARC_Config_GroupDataHashtableDestroyKeyValueFn ;
2023-01-17 02:57:57 -07:00
2025-03-11 00:41:17 -06:00
//copy empty group cstring (to be freed by hashtable on cleanup, passing directly would cause a segfault)
char * emptyCStr = ( char * ) malloc ( sizeof ( char ) * ( strlen ( ARC_CONFIG_DEFAULT_GROUP ) + 1 ) ) ;
strcpy ( emptyCStr , ARC_CONFIG_DEFAULT_GROUP ) ;
2023-01-17 02:57:57 -07:00
2025-03-11 00:41:17 -06:00
//set the current group as empty, then add that into the groups hashtable
ARC_Hashtable_Create ( & ( ( * config ) - > currentGroup ) , NULL , & keyCompareFn , & groupDataDestroyKeyValueFn ) ;
ARC_Hashtable_Add ( ( * config ) - > groups , ( void * ) emptyCStr , ( * config ) - > currentGroup ) ;
2022-10-27 15:16:54 -06:00
2025-03-11 00:41:17 -06:00
( * config ) - > load = ARC_True ;
2023-01-17 02:57:57 -07:00
2025-03-11 00:41:17 -06:00
//cleanup
ARC_String_Destroy ( languageString ) ;
}
2023-01-17 02:57:57 -07:00
2025-03-11 00:41:17 -06:00
void ARC_Config_Destroy ( ARC_Config * config ) {
ARC_Parser_Destroy ( config - > parser ) ;
//NOTE: config->currentGroup does not need to be freed as it is stored in config->groups
ARC_Hashtable_Destroy ( config - > groups ) ;
ARC_Hashtable_Destroy ( config - > types ) ;
free ( config ) ;
}
2023-01-17 01:59:08 -07:00
2025-03-11 00:41:17 -06:00
void ARC_Config_RegisterType ( ARC_Config * config , ARC_String * typeName , ARC_ConfigType type ) {
ARC_Config_RegisterTypeWithCStr ( config , typeName - > data , type ) ;
}
2022-10-27 15:16:54 -06:00
2025-03-11 00:41:17 -06:00
void ARC_Config_RegisterTypeWithCStr ( ARC_Config * config , const char * typeNameCStr , ARC_ConfigType type ) {
//check if the type key already exists and error if it does
if ( ARC_Hashtable_Get ( config - > types , ( void * ) typeNameCStr ) ! = NULL ) {
arc_errno = ARC_ERRNO_EXISTS ;
ARC_DEBUG_LOG_ERROR_WITH_VARIABLES ( " ARC_Config_RegisterTypeWithCStr(config, typeName, type), type \" %s \" has already been registered " , typeNameCStr ) ;
2023-01-17 01:59:08 -07:00
return ;
2022-10-27 15:16:54 -06:00
}
2025-03-11 00:41:17 -06:00
//copy the string into a cstring for long term storage
uint64_t typeNameCopyLength = strlen ( typeNameCStr ) + 1 ;
char * typeNameCopy = ( char * ) malloc ( sizeof ( char ) * typeNameCopyLength ) ;
strncpy ( typeNameCopy , typeNameCStr , typeNameCopyLength ) ;
typeNameCopy [ strlen ( typeNameCStr ) ] = ' \0 ' ;
2023-01-17 01:59:08 -07:00
2025-03-11 00:41:17 -06:00
//copy the type for long term storage
ARC_ConfigType * typeCopy = ( ARC_ConfigType * ) malloc ( sizeof ( ARC_ConfigType ) ) ;
* typeCopy = type ;
2022-10-27 15:16:54 -06:00
2025-03-11 00:41:17 -06:00
//add the type to a hashtable containing all the types
ARC_Hashtable_Add ( config - > types , typeNameCopy , typeCopy ) ;
2023-01-17 01:59:08 -07:00
}
2025-03-11 00:41:17 -06:00
void ARC_Config_SetGroup ( ARC_Config * config , ARC_String * groupName ) {
ARC_Config_SetGroupWithCStr ( config , groupName - > data ) ;
}
2023-01-17 01:59:08 -07:00
2025-03-11 00:41:17 -06:00
void ARC_Config_SetGroupWithCStr ( ARC_Config * config , const char * groupName ) {
//try to get the current group
void * currentGroup = ARC_Hashtable_Get ( config - > groups , ( void * ) groupName ) ;
2023-01-17 01:59:08 -07:00
2025-03-11 00:41:17 -06:00
//error if the current group does not exist
if ( currentGroup = = NULL ) {
arc_errno = ARC_ERRNO_NULL ;
ARC_DEBUG_LOG_ERROR_WITH_VARIABLES ( " ARC_Config_SetGroupWithCStr(config, groupName), no group with name \" %s \" " , groupName ) ;
2023-01-17 01:59:08 -07:00
return ;
}
2022-10-27 15:16:54 -06:00
2025-03-11 00:41:17 -06:00
//set the current group
config - > currentGroup = currentGroup ;
2022-10-27 15:16:54 -06:00
}
2025-03-11 00:41:17 -06:00
void * ARC_Config_Get ( ARC_Config * config , ARC_String * name ) {
//check if the group separator exists
uint64_t startSeparatorIndex = ARC_String_FindCStringWithStrlen ( name , ARC_CONFIG_GROUP_SEPARATOR ) ;
if ( startSeparatorIndex = = ~ ( uint64_t ) 0 ) {
//use empty group
config - > currentGroup = ARC_Hashtable_Get ( config - > groups , ( void * ) ARC_CONFIG_DEFAULT_GROUP ) ;
//get the typeData and pass back the data without the cleanup function
ARC_ConfigTypeData * typeData = ( ARC_ConfigTypeData * ) ARC_Hashtable_Get ( config - > currentGroup , ( void * ) name - > data ) ;
if ( typeData = = NULL ) {
return NULL ;
}
2023-01-17 01:59:08 -07:00
2025-03-11 00:41:17 -06:00
return typeData - > data ;
2023-01-17 01:59:08 -07:00
}
2025-03-11 00:41:17 -06:00
//get the group
startSeparatorIndex - - ;
ARC_String * groupString ;
ARC_String_CopySubstring ( & groupString , name , 0 , startSeparatorIndex ) ;
2022-10-27 15:16:54 -06:00
2025-03-11 00:41:17 -06:00
//set the group
config - > currentGroup = ARC_Hashtable_Get ( config - > groups , ( void * ) groupString - > data ) ;
2022-10-27 15:16:54 -06:00
2025-03-11 00:41:17 -06:00
//cleanup
ARC_String_Destroy ( groupString ) ;
2023-01-17 01:59:08 -07:00
2025-03-11 00:41:17 -06:00
//get the name
ARC_String * nameString ;
startSeparatorIndex + = strlen ( ARC_CONFIG_GROUP_SEPARATOR ) ;
ARC_String_CopySubstring ( & nameString , name , startSeparatorIndex , name - > length - startSeparatorIndex ) ;
2023-01-17 01:59:08 -07:00
2025-03-11 00:41:17 -06:00
//this will either return the value or NULL
ARC_ConfigTypeData * typeData = ( ARC_ConfigTypeData * ) ARC_Hashtable_Get ( config - > currentGroup , ( void * ) nameString - > data ) ;
ARC_String_Destroy ( nameString ) ;
if ( typeData = = NULL ) {
return NULL ;
2023-01-17 01:59:08 -07:00
}
2025-03-11 00:41:17 -06:00
return typeData - > data ;
2023-01-17 01:59:08 -07:00
}
2025-03-11 00:41:17 -06:00
void * ARC_Config_GetWithCStr ( ARC_Config * config , const char * name ) {
//create and copy into ARC_String
ARC_String * nameString ;
ARC_String_CreateWithStrlen ( & nameString , ( char * ) name ) ;
2023-01-17 02:57:57 -07:00
2025-03-11 00:41:17 -06:00
//get the return value
void * returnValue = ARC_Config_Get ( config , nameString ) ;
2023-01-17 01:59:08 -07:00
2025-03-11 00:41:17 -06:00
//cleanup
ARC_String_Destroy ( nameString ) ;
2023-01-17 02:57:57 -07:00
2025-03-11 00:41:17 -06:00
return returnValue ;
2023-01-17 01:59:08 -07:00
}
2025-03-11 00:41:17 -06:00
void ARC_Config_LoadFromString ( ARC_Config * config , ARC_String * * string ) {
config - > load = ARC_True ;
ARC_Parser_Parse ( config - > parser , string ) ;
2023-01-17 01:59:08 -07:00
}
2025-03-11 00:41:17 -06:00
void ARC_Config_LoadFromFile ( ARC_Config * config , ARC_String * path ) {
config - > load = ARC_True ;
ARC_Parser_ParseFile ( config - > parser , path ) ;
2023-01-17 01:59:08 -07:00
}
2025-03-11 00:41:17 -06:00
void ARC_Config_UnloadFromString ( ARC_Config * config , ARC_String * * string ) {
config - > load = ARC_False ;
ARC_Parser_Parse ( config - > parser , string ) ;
2023-01-17 01:59:08 -07:00
}
2025-03-11 00:41:17 -06:00
void ARC_Config_UnloadFromFile ( ARC_Config * config , ARC_String * path ) {
config - > load = ARC_False ;
ARC_Parser_ParseFile ( config - > parser , path ) ;
2023-01-17 01:59:08 -07:00
}