diff --git a/include/arc/std/config.h b/include/arc/std/config.h index 526e756..a15c64d 100644 --- a/include/arc/std/config.h +++ b/include/arc/std/config.h @@ -67,6 +67,58 @@ void ARC_Config_RegisterType(ARC_Config *config, ARC_String *typeName, ARC_Confi */ void ARC_Config_RegisterTypeWithCStr(ARC_Config *config, const char *typeNameCStr, ARC_ConfigType type); +/** + * @brief add a value with a given keyname + * + * @note name should be prefaced with :: to specify group, or just the name if it is in the default group + * @note not specifying the group will use the current group + * @note this function uses ARC_Config_AddWithCStr so it shares error messages with that function + * @note value will be freed on cleanup or remove + * + * @param[in] config ARC_Config to add value to + * @param[in] type the type of a variable to add to specified group + * @param[in] name name of a variable to add to specified group + * @param[in] value the value of the variable to add, will be freed +*/ +void ARC_Config_Add(ARC_Config *config, ARC_String *type, ARC_String *name, void *value); + +/** + * @brief add a value with a given keyname + * + * @note name should be prefaced with :: to specify group, or just the name if it is in the default group + * @note not specifying the group will use the current group + * @note value will be freed on cleanup or remove + * + * @param[in] config ARC_Config to add value to + * @param[in] type the type of a variable to add to specified group + * @param[in] name name of a variable to add to specified group + * @param[in] value the value of the variable to add, will be freed +*/ +void ARC_Config_AddWithCStr(ARC_Config *config, const char *type, const char *name, void *value); + +/** + * @brief remove a value with a given keyname + * + * @note name should be prefaced with :: to specify group, or just the name if it is in the default group + * @note not specifying the group will use the current group + * @note this function uses ARC_Config_RemoveWithCStr so it shares error messages with that function + * + * @param[in] config ARC_Config to remove value from + * @param[in] name name of a variable to remove to specified group +*/ +void ARC_Config_Remove(ARC_Config *config, ARC_String *name); + +/** + * @brief remove a value with a given keyname + * + * @note name should be prefaced with :: to specify group, or just the name if it is in the default group + * @note not specifying the group will use the current group + * + * @param[in] config ARC_Config to remove value from + * @param[in] name name of a variable to remove to specified group +*/ +void ARC_Config_RemoveWithCStr(ARC_Config *config, const char *name); + /** * @brief sets current group in config * @@ -75,7 +127,7 @@ void ARC_Config_RegisterTypeWithCStr(ARC_Config *config, const char *typeNameCSt * * @param[in] config ARC_Config we are setting current group in * @param[in] groupname name of group that will be set - */ +*/ void ARC_Config_SetGroup(ARC_Config *config, ARC_String *groupName); /** @@ -85,32 +137,32 @@ void ARC_Config_SetGroup(ARC_Config *config, ARC_String *groupName); * * @param[in] config ARC_Config we are setting current group in * @param[in] groupname name of group that will be set - */ +*/ void ARC_Config_SetGroupWithCStr(ARC_Config *config, const char *groupName); /** * @brief get a value from a given name * - * @note name should be prefaced with :: to specify group + * @note name should be prefaced with :: to specify group, or just the name if it is in the default group * * @param[in] config ARC_Config to get value from * @param[in] name name of a variable that has been read in * * @return the stored element on success, or NULL on failure - */ +*/ void *ARC_Config_Get(ARC_Config *config, ARC_String *name); /** * @brief get a value from a given keyname * - * @note name should be prefaced with :: to specify group + * @note name should be prefaced with :: to specify group, or just the name if it is in the default group * @note this function uses ARC_Config_Get so it shares error messages with that function * * @param[in] config ARC_Config to get value from * @param[in] name name of a variable that has been read in * * @return the stored element on success, or NULL on failure - */ +*/ void *ARC_Config_GetWithCStr(ARC_Config *config, const char *name); /** @@ -205,15 +257,16 @@ void ARC_Config_UnloadFromFile(ARC_Config *config, ARC_String *data); #define ARC_CONFIG_STRING_CHARS 0x37 #define ARC_CONFIG_STRING_CHAR 0x38 #define ARC_CONFIG_ESCAPE_CHAR 0x39 -#define ARC_CONFIG_NUMBER_SIGN 0x3A -#define ARC_CONFIG_NUMBER_TAG 0x3B -#define ARC_CONFIG_WHITESPACE 0x3C -#define ARC_CONFIG_COMMENT 0x3D -#define ARC_CONFIG_LINE_COMMENT 0x3E -#define ARC_CONFIG_MULTI_LINE_COMMENT 0x3F -#define ARC_CONFIG_LINE_CHARS 0x40 -#define ARC_CONFIG_MULTI_LINE_CHARS 0x41 -#define ARC_CONFIG_COMMENT_CHAR 0x42 +#define ARC_CONFIG_FLOAT 0x3A +#define ARC_CONFIG_NUMBER_SIGN 0x3B +#define ARC_CONFIG_NUMBER_TAG 0x3C +#define ARC_CONFIG_WHITESPACE 0x3D +#define ARC_CONFIG_COMMENT 0x3E +#define ARC_CONFIG_LINE_COMMENT 0x3F +#define ARC_CONFIG_MULTI_LINE_COMMENT 0x40 +#define ARC_CONFIG_LINE_CHARS 0x41 +#define ARC_CONFIG_MULTI_LINE_CHARS 0x42 +#define ARC_CONFIG_COMMENT_CHAR 0x43 /** * @brief TODO: write this diff --git a/src/std/config.c b/src/std/config.c index 823da15..e449d20 100644 --- a/src/std/config.c +++ b/src/std/config.c @@ -256,6 +256,9 @@ uint32_t ARC_Config_GetStringIdFn(ARC_String *string){ if(ARC_String_EqualsCStringWithStrlen(string, "")){ return ARC_CONFIG_ESCAPE_CHAR; } + if(ARC_String_EqualsCStringWithStrlen(string, "")){ + return ARC_CONFIG_FLOAT; + } if(ARC_String_EqualsCStringWithStrlen(string, "")){ return ARC_CONFIG_NUMBER_SIGN; } @@ -666,7 +669,7 @@ void ARC_Config_Create(ARC_Config **config){ " -> SPACE | TAB | LAMBDA\n" " -> | \n" - " -> | | | \n" + " -> | | | | \n" " -> OPEN_CURLY_BRACE CLOSE_CURLY_BRACE\n" " -> COMMA | \n" @@ -680,6 +683,7 @@ void ARC_Config_Create(ARC_Config **config){ " -> 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" " -> BACKSLASH BACKSLASH | BACKSLASH QUOTE | BACKSLASH ALPHA_UPPER_CHAR | BACKSLASH ALPHA_LOWER_CHAR\n" + " -> PERIOD | PERIOD | PERIOD \n" " -> MINUS | \n" " -> NUMBER | NUMBER\n" @@ -764,6 +768,156 @@ void ARC_Config_RegisterTypeWithCStr(ARC_Config *config, const char *typeNameCSt ARC_Hashtable_Add(config->types, typeNameCopy, typeCopy); } +void ARC_Config_Add(ARC_Config *config, ARC_String *type, ARC_String *name, void *value){ + //check if type exists in the types hashtable + ARC_ConfigType *typeValue = (ARC_ConfigType *)ARC_Hashtable_Get(config->types, name->data); + if(type == NULL){ + //throw an error and return + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("ARC_Config_Add(config, type, name, value), type \"%s\" was not registered to config", type->data); + return; + } + + //check if the group separator exists + uint64_t startSeparatorIndex = ARC_String_FindCStringWithStrlen(name, ARC_CONFIG_GROUP_SEPARATOR); + if(startSeparatorIndex == ~(uint64_t)0){ + //check to see if the current variable is already in the current group hashtable + ARC_ConfigTypeData *typeData = (ARC_ConfigTypeData *)ARC_Hashtable_Get(config->currentGroup, name->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", name->data); + return; + } + + //create where to store either the type data + typeData = (ARC_ConfigTypeData *)malloc(sizeof(ARC_ConfigTypeData)); + typeData->destroyFn = typeValue->destroyFn; + typeData->data = value; + + //copy the name into a cstring that will be stored in the hashtable + char *nameVariableCStr = malloc(sizeof(char) * (name->length + 1)); + strncpy(nameVariableCStr, name->data, name->length); + nameVariableCStr[name->length] = '\0'; + + //add to the current group hashtable + ARC_Hashtable_Add(config->currentGroup, (void *)nameVariableCStr, (void *)typeData); + return; + } + + //reset the group the the default group + config->currentGroup = ARC_Hashtable_Get(config->groups, (void *)ARC_CONFIG_DEFAULT_GROUP); + + if(startSeparatorIndex != 0){ + //get the group + startSeparatorIndex--; + ARC_String *groupString; + ARC_String_CopySubstring(&groupString, name, 0, startSeparatorIndex); + + //set the group + config->currentGroup = ARC_Hashtable_Get(config->groups, (void *)groupString->data); + + //cleanup + ARC_String_Destroy(groupString); + } + + //get the name + ARC_String *nameString; + startSeparatorIndex += strlen(ARC_CONFIG_GROUP_SEPARATOR); + ARC_String_CopySubstring(&nameString, name, startSeparatorIndex, name->length - startSeparatorIndex); + + //check to see if the current variable is already in the current group hashtable + ARC_ConfigTypeData *typeData = (ARC_ConfigTypeData *)ARC_Hashtable_Get(config->currentGroup, nameString->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", name->data); + return; + } + + //create where to store either the type data + typeData = (ARC_ConfigTypeData *)malloc(sizeof(ARC_ConfigTypeData)); + typeData->destroyFn = typeValue->destroyFn; + typeData->data = value; + + //copy the name into a cstring that will be stored in the hashtable + char *nameVariableCStr = malloc(sizeof(char) * (name->length + 1)); + strncpy(nameVariableCStr, name->data, name->length); + nameVariableCStr[name->length] = '\0'; + + //add to the current group hashtable + ARC_Hashtable_Add(config->currentGroup, (void *)nameVariableCStr, (void *)typeData); +} + +void ARC_Config_AddWithCStr(ARC_Config *config, const char *type, const char *name, void *value){ + //create and copy strings + ARC_String *typeString; + ARC_String *nameString; + ARC_String_CreateWithStrlen(&typeString, (char *)type); + ARC_String_CreateWithStrlen(&nameString, (char *)name); + + //add as an ARC_String + ARC_Config_Add(config, typeString, nameString, value); + + //cleanup + ARC_String_Destroy(nameString); + ARC_String_Destroy(typeString); +} + +void ARC_Config_Remove(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){ + //remove the value from the hashtable if it exists + ARC_ConfigTypeData *typeData = (ARC_ConfigTypeData *)ARC_Hashtable_Get(config->currentGroup, (void *)name->data); + if(typeData != NULL){ + ARC_Hashtable_Remove(config->currentGroup, (void *)name->data); + } + + return; + } + + //reset the group the the default group + config->currentGroup = ARC_Hashtable_Get(config->groups, (void *)ARC_CONFIG_DEFAULT_GROUP); + + if(startSeparatorIndex != 0){ + //get the group + startSeparatorIndex--; + ARC_String *groupString; + ARC_String_CopySubstring(&groupString, name, 0, startSeparatorIndex); + + //set the group + config->currentGroup = ARC_Hashtable_Get(config->groups, (void *)groupString->data); + + //cleanup + ARC_String_Destroy(groupString); + } + + //get the name + ARC_String *nameString; + startSeparatorIndex += strlen(ARC_CONFIG_GROUP_SEPARATOR); + ARC_String_CopySubstring(&nameString, name, startSeparatorIndex, name->length - startSeparatorIndex); + + //remove the value from the hashtable if it exists + ARC_ConfigTypeData *typeData = (ARC_ConfigTypeData *)ARC_Hashtable_Get(config->currentGroup, (void *)name->data); + if(typeData != NULL){ + ARC_Hashtable_Remove(config->currentGroup, (void *)name->data); + } + ARC_String_Destroy(nameString); +} + +void ARC_Config_RemoveWithCStr(ARC_Config *config, const char *name){ + //create and copy strings + ARC_String *nameString; + ARC_String_CreateWithStrlen(&nameString, (char *)name); + + //add as an ARC_String + ARC_Config_Remove(config, nameString); + + //cleanup + ARC_String_Destroy(nameString); +} + void ARC_Config_SetGroup(ARC_Config *config, ARC_String *groupName){ ARC_Config_SetGroupWithCStr(config, groupName->data); } @@ -799,16 +953,21 @@ void *ARC_Config_Get(ARC_Config *config, ARC_String *name){ return typeData->data; } - //get the group - startSeparatorIndex--; - ARC_String *groupString; - ARC_String_CopySubstring(&groupString, name, 0, startSeparatorIndex); + //reset the group the the default group + config->currentGroup = ARC_Hashtable_Get(config->groups, (void *)ARC_CONFIG_DEFAULT_GROUP); - //set the group - config->currentGroup = ARC_Hashtable_Get(config->groups, (void *)groupString->data); + if(startSeparatorIndex != 0){ + //get the group + startSeparatorIndex--; + ARC_String *groupString; + ARC_String_CopySubstring(&groupString, name, 0, startSeparatorIndex); - //cleanup - ARC_String_Destroy(groupString); + //set the group + config->currentGroup = ARC_Hashtable_Get(config->groups, (void *)groupString->data); + + //cleanup + ARC_String_Destroy(groupString); + } //get the name ARC_String *nameString; @@ -880,8 +1039,8 @@ void ARC_Config_InitStd(ARC_Config *config){ ARC_Config_RegisterTypeWithCStr(config, "uint32" , (ARC_ConfigType){ ARC_ConfigType_Uint32CopyFn, ARC_ConfigType_Uint32DestroyFn, NULL }); ARC_Config_RegisterTypeWithCStr(config, "int64" , (ARC_ConfigType){ ARC_ConfigType_Int64CopyFn , ARC_ConfigType_Int64DestroyFn , NULL }); ARC_Config_RegisterTypeWithCStr(config, "uint64" , (ARC_ConfigType){ ARC_ConfigType_Uint64CopyFn, ARC_ConfigType_Uint64DestroyFn, NULL }); - //ARC_Config_RegisterTypeWithCStr(config, "float" , (ARC_ConfigType){ ARC_ConfigType_FloatCopyFn , ARC_ConfigType_FloatDestroyFn , NULL }); - //ARC_Config_RegisterTypeWithCStr(config, "double" , (ARC_ConfigType){ ARC_ConfigType_DoubleCopyFn, ARC_ConfigType_DoubleDestroyFn, NULL }); + ARC_Config_RegisterTypeWithCStr(config, "float" , (ARC_ConfigType){ ARC_ConfigType_FloatCopyFn , ARC_ConfigType_FloatDestroyFn , NULL }); + ARC_Config_RegisterTypeWithCStr(config, "double" , (ARC_ConfigType){ ARC_ConfigType_DoubleCopyFn, ARC_ConfigType_DoubleDestroyFn, NULL }); ARC_Config_RegisterTypeWithCStr(config, "ARC_String", (ARC_ConfigType){ ARC_ConfigType_StringCopyFn, ARC_ConfigType_StringDestroyFn, NULL }); } @@ -890,7 +1049,7 @@ void ARC_ConfigType_BoolCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_ ARC_ParserTagToken *childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(parsedData->tagTokens, 0); if(childTagToken->id != ARC_CONFIG_VARIABLE){ arc_errno = ARC_ERRNO_DATA; - ARC_DEBUG_LOG_ERROR("ARC_ConfigType_BoolNumberHelperCopyFn(type, parsedData, config), parsed data was not a "); + ARC_DEBUG_LOG_ERROR("ARC_ConfigType_BoolNumberHelperCopyFn(type, parsedData, config, userdata), parsed data was not a "); *type = NULL; return; } @@ -920,7 +1079,7 @@ void ARC_ConfigType_BoolCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_ //error if true or false was not passed in arc_errno = ARC_ERRNO_DATA; - ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("ARC_ConfigType_BoolNumberHelperCopyFn(type, parsedData, config), bool can only be \"true\" or \"false\" but was given \"%s\"", value->data); + ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("ARC_ConfigType_BoolNumberHelperCopyFn(type, parsedData, config, userdata), bool can only be \"true\" or \"false\" but was given \"%s\"", value->data); ARC_String_Destroy(value); *type = NULL; } @@ -935,7 +1094,7 @@ void ARC_ConfigType_IntNumberHelperCopyFn(void **type, ARC_ParserTagToken *parse ARC_ParserTagToken *childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(parsedData->tagTokens, 0); if(childTagToken->id != ARC_CONFIG_NUMBER_SIGN){ arc_errno = ARC_ERRNO_DATA; - ARC_DEBUG_LOG_ERROR("ARC_ConfigType_IntNumberHelperCopyFn(type, parsedData, config), parsed data was not a "); + ARC_DEBUG_LOG_ERROR("ARC_ConfigType_IntNumberHelperCopyFn(type, parsedData, maxSize), parsed data was not a "); *type = NULL; return; } @@ -972,7 +1131,7 @@ void ARC_ConfigType_IntNumberHelperCopyFn(void **type, ARC_ParserTagToken *parse //if the string is bigger than the possible size return NULL and error if(intString->length > maxSizeLength){ arc_errno = ARC_ERRNO_DATA; - ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("ARC_ConfigType_IntNumberHelperCopyFn(type, parsedData, config), size \"%s\" was bigger or smaller than than the max %lu or min %lu", intString->data, maxPositiveSize, (maxPositiveSize * -1) - 1); + ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("ARC_ConfigType_IntNumberHelperCopyFn(type, parsedData, maxSize), size \"%s\" was bigger or smaller than than the max %lu or min %lu", intString->data, maxPositiveSize, (maxPositiveSize * -1) - 1); *type = NULL; ARC_String_Destroy(intString); return; @@ -989,7 +1148,7 @@ void ARC_ConfigType_IntNumberHelperCopyFn(void **type, ARC_ParserTagToken *parse for(int8_t index = maxSize + 1; index >= 0; index--, stringIndex--){ if(intString->data[stringIndex] > maxintCStr[index]){ arc_errno = ARC_ERRNO_DATA; - ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("ARC_ConfigType_IntNumberHelperCopyFn(type, parsedData, config), size \"%s\" was bigger than the max of the signed value %lu", intString->data, maxSize); + ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("ARC_ConfigType_IntNumberHelperCopyFn(type, parsedData, maxSize), size \"%s\" was bigger than the max of the signed value %lu", intString->data, maxSize); *type = NULL; ARC_String_Destroy(intString); return; @@ -1017,14 +1176,14 @@ void ARC_ConfigType_UintNumberHelperCopyFn(void **type, ARC_ParserTagToken *pars ARC_ParserTagToken *childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(parsedData->tagTokens, 0); if(childTagToken->id != ARC_CONFIG_NUMBER_SIGN){ arc_errno = ARC_ERRNO_DATA; - ARC_DEBUG_LOG_ERROR("ARC_ConfigType_UintNumberHelperCopyFn(type, parsedData, config), parsed data was not a "); + ARC_DEBUG_LOG_ERROR("ARC_ConfigType_UintNumberHelperCopyFn(type, parsedData, maxSize), parsed data was not a "); *type = NULL; return; } if(childTagToken->id == ARC_CONFIG_MINUS){ arc_errno = ARC_ERRNO_DATA; - ARC_DEBUG_LOG_ERROR("ARC_ConfigType_UintNumberHelperCopyFn(type, parsedData, config), parsed data had a minus sign, uint numbers must be positive"); + ARC_DEBUG_LOG_ERROR("ARC_ConfigType_UintNumberHelperCopyFn(type, parsedData, maxSize), parsed data had a minus sign, uint numbers must be positive"); *type = NULL; return; } @@ -1047,7 +1206,7 @@ void ARC_ConfigType_UintNumberHelperCopyFn(void **type, ARC_ParserTagToken *pars //if the string is bigger than the possible size return NULL and error if(uintString->length > maxSizeLength){ arc_errno = ARC_ERRNO_DATA; - ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("ARC_ConfigType_UintNumberHelperCopyFn(type, parsedData, config), size \"%s\" was bigger than the max %lu", uintString->data, maxSize); + ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("ARC_ConfigType_UintNumberHelperCopyFn(type, parsedData, maxSize), size \"%s\" was bigger than the max %lu", uintString->data, maxSize); *type = NULL; ARC_String_Destroy(uintString); return; @@ -1063,7 +1222,7 @@ void ARC_ConfigType_UintNumberHelperCopyFn(void **type, ARC_ParserTagToken *pars for(int8_t index = maxSize + 1; index >= 0; index--, stringIndex--){ if(uintString->data[stringIndex] > maxuintCStr[index]){ arc_errno = ARC_ERRNO_DATA; - ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("ARC_ConfigType_UintNumberHelperCopyFn(type, parsedData, config), size \"%s\" was bigger than the max %lu", uintString->data, maxSize); + ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("ARC_ConfigType_UintNumberHelperCopyFn(type, parsedData, maxSize), size \"%s\" was bigger than the max %lu", uintString->data, maxSize); *type = NULL; ARC_String_Destroy(uintString); return; @@ -1150,19 +1309,94 @@ void ARC_ConfigType_Uint64DestroyFn(void *type){ } void ARC_ConfigType_FloatCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata){ - //TODO: write this + //go into the tag + ARC_ParserTagToken *childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(parsedData->tagTokens, 0); + if(childTagToken->id != ARC_CONFIG_FLOAT && childTagToken->id != ARC_CONFIG_NUMBER_SIGN){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR("ARC_ConfigType_FloatCopyFn(type, parsedData, config, userdata), parsed data was not a or "); + *type = NULL; + return; + } + + //get the float as a string + ARC_String *floatString; + ARC_String_Create(&floatString, NULL, 0); + ARC_ParserData_HelperRecurseStringAdd(&floatString, parsedData); + + //get the value as a float + char *endptr; + float value = strtof(floatString->data, &endptr); + + //error check + if(floatString->data == endptr){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("ARC_ConfigType_FloatCopyFn(type, parsedData, config, userdata), parsed data \"%s\" was not a or ", floatString->data); + + //cleanup + ARC_String_Destroy(floatString); + + //set the type to NULL + *type = NULL; + return; + } + + //cleanup + ARC_String_Destroy(floatString); + + //copy the value into a new double, then pass it out through type + float *valuePointer = malloc(sizeof(float)); + *valuePointer = value; + *type = valuePointer; } void ARC_ConfigType_FloatDestroyFn(void *type){ - //TODO: write this + free((float *)type); } void ARC_ConfigType_DoubleCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata){ - //TODO: write this + //go into the tag + //note the float tag means floating point number in this context, and a double does have a flating point + ARC_ParserTagToken *childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(parsedData->tagTokens, 0); + if(childTagToken->id != ARC_CONFIG_FLOAT && childTagToken->id != ARC_CONFIG_NUMBER_SIGN){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR("ARC_ConfigType_FloatCopyFn(type, parsedData, config, userdata), parsed data was not a or "); + *type = NULL; + return; + } + + //get the double as a string + ARC_String *doubleString; + ARC_String_Create(&doubleString, NULL, 0); + ARC_ParserData_HelperRecurseStringAdd(&doubleString, parsedData); + + //get the value as a double + char *endptr; + double value = strtod(doubleString->data, &endptr); + + //error check + if(doubleString->data == endptr){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("ARC_ConfigType_FloatCopyFn(type, parsedData, config, userdata), parsed data \"%s\" was not a or ", doubleString->data); + + //cleanup + ARC_String_Destroy(doubleString); + + //set the type to NULL + *type = NULL; + return; + } + + //cleanup + ARC_String_Destroy(doubleString); + + //copy the value into a new double, then pass it out through type + double *valuePointer = malloc(sizeof(double)); + *valuePointer = value; + *type = valuePointer; } void ARC_ConfigType_DoubleDestroyFn(void *type){ - //TODO: write this + free((double *)type); } void ARC_ConfigType_StringCopyFn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata){