config and string reworked, hashtable updated to use arc_errno
This commit is contained in:
parent
0bbce28469
commit
f8d987da8e
12 changed files with 1121 additions and 657 deletions
|
|
@ -13,6 +13,11 @@ extern "C" {
|
|||
*/
|
||||
typedef struct ARC_ECS ARC_ECS;
|
||||
|
||||
/**
|
||||
* @brief entity type for ARC_ECS
|
||||
*/
|
||||
typedef uint64_t ARC_ECSEntity;
|
||||
|
||||
/**
|
||||
* @brief creates ARC_Config type
|
||||
*
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* @brief a type that holds an array of data and its size
|
||||
*/
|
||||
typedef struct ARC_Array {
|
||||
uint32_t *size;
|
||||
void *data;
|
||||
|
|
|
|||
|
|
@ -9,10 +9,6 @@ extern "C" {
|
|||
#include "arc/std/string.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef ARC_HOME_PATH
|
||||
#define ARC_HOME_PATH "./res/"
|
||||
#endif //ARC_HOME_PATH
|
||||
|
||||
#define ARC_KEY_BUCKET_SIZE 0x20
|
||||
#define ARC_GROUP_BUCKET_SIZE 0x20
|
||||
#define ARC_GROUP_DATA_BUCKET_SIZE 0x20
|
||||
|
|
@ -25,56 +21,85 @@ typedef struct ARC_Config ARC_Config;
|
|||
/**
|
||||
* @brief a function to read a key from string to a ARC_ConfigTypeTemplate
|
||||
*
|
||||
* @param config ARC_Config to store data to
|
||||
* @param data string of what is to be read in
|
||||
* @param subdata location of stubstring in data for what is to be read in
|
||||
* @param value value of read in variable
|
||||
* @param config ARC_Config to store data to
|
||||
* @param string ARC_String of data that is being read in
|
||||
* @param value value that is read in
|
||||
*
|
||||
* @note use ARC_Config_StoreValue(ARC_Config *config, ARC_String *name, void *value); to store a value to the config
|
||||
* if there is an error, set arc_errno
|
||||
*
|
||||
* @return 0 if value not a reference, 1 if value is a reference
|
||||
*/
|
||||
typedef int32_t (* ARC_ConfigKeyRead)(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value);
|
||||
typedef uint8_t (* ARC_ConfigKeyRead)(ARC_Config* config, ARC_String *string, void **value);
|
||||
|
||||
/**
|
||||
* @brief a function to delete a value from a key in ARC_Config
|
||||
*
|
||||
* @param config ARC_Config that can be used to check for references in data
|
||||
* @param data string of what is going to be deleted (used to check if value is a reference)
|
||||
* @param subdata location of substring in data for what is going to be deleted (used to check if value is a reference)
|
||||
* @param value pointer of data to be deleted
|
||||
*
|
||||
* @note this function can be NULL if memory does not need to be cleaned for this type
|
||||
* if there is an error, set arc_errno
|
||||
*/
|
||||
typedef int32_t (* ARC_ConfigKeyDelete)(ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value);
|
||||
typedef void (* ARC_ConfigKeyDelete)(ARC_Config* config, void *value);
|
||||
|
||||
/**
|
||||
* @brief adds a usable key to ARC_Config
|
||||
*
|
||||
* @param config ARC_Config we are adding keys to
|
||||
* @param config ARC_Config to add keys to
|
||||
* @param type string of key type
|
||||
* @param keyRead function for reading/creating key from string
|
||||
* @param keyDelete function for deleting stored key
|
||||
*
|
||||
* @return 0 on sucess, ARC_ERRNO_ on fail
|
||||
*/
|
||||
int32_t ARC_ConfigKey_Add(ARC_Config *config, char *type, ARC_ConfigKeyRead keyRead, ARC_ConfigKeyDelete keyDelete);
|
||||
void ARC_Config_AddKey(ARC_Config *config, ARC_String *type, ARC_ConfigKeyRead keyRead, ARC_ConfigKeyDelete keyDelete);
|
||||
|
||||
/**
|
||||
* @brief adds a key from a cstring
|
||||
* @param config ARC_Config to add keys to
|
||||
* @param type cstring of key type
|
||||
* @param length length of cstring
|
||||
* @param keyRead function for reading/creating key from string
|
||||
* @param keyDelete function for deleting stored key
|
||||
*/
|
||||
void ARC_Config_AddKeyCString(ARC_Config *config, const char *type, uint64_t length, ARC_ConfigKeyRead keyRead, ARC_ConfigKeyDelete keyDelete);
|
||||
|
||||
/**
|
||||
* @brief external callback to add keys to config
|
||||
*/
|
||||
typedef int32_t (* ARC_ConfigKey_AddFunc)(ARC_Config *config);
|
||||
typedef void (* ARC_ConfigKey_AddFunc)(ARC_Config *config);
|
||||
|
||||
/**
|
||||
* @brief creates ARC_Config type
|
||||
*
|
||||
* @param config ARC_Config we are initializing
|
||||
* @param keysAdd callback to add ConfigKeys to config->keys, can be NULL
|
||||
*
|
||||
* @return 0 on sucess, ARC_ERRNO_ on fail
|
||||
* @param config ARC_Config to initialize
|
||||
*/
|
||||
int32_t ARC_Config_Create(ARC_Config **config, ARC_ConfigKey_AddFunc keysAdd);
|
||||
void ARC_Config_Create(ARC_Config **config);
|
||||
|
||||
/**
|
||||
* @brief destroys ARC_Config type
|
||||
*
|
||||
* @return 0 on sucess, ARC_ERRNO_ on fail
|
||||
*/
|
||||
int32_t ARC_Config_Destroy(ARC_Config *config);
|
||||
void ARC_Config_Destroy(ARC_Config *config);
|
||||
|
||||
/**
|
||||
* @brief sets current group in config
|
||||
*
|
||||
* @note ARC_Config_Get will use this set group
|
||||
*
|
||||
* @param config ARC_Config we are setting current group in
|
||||
* @param groupname name of group that will be set
|
||||
*/
|
||||
void ARC_Config_SetGroup(ARC_Config *config, ARC_String *groupname);
|
||||
|
||||
/**
|
||||
* @brief get a value from a given keyname
|
||||
*
|
||||
* @note name may be prefaced with <group>:: to specify group
|
||||
*
|
||||
* @param config ARC_Config to get value from
|
||||
* @param keyname name of key to get from config
|
||||
* @param value data retrieved from config
|
||||
*/
|
||||
void ARC_Config_Get(ARC_Config *config, ARC_String *keyname, void **value);
|
||||
|
||||
/**
|
||||
* @brief commands that can be used in ARC_Config_FileIO
|
||||
|
|
@ -87,48 +112,8 @@ int32_t ARC_Config_Destroy(ARC_Config *config);
|
|||
*
|
||||
* @param config ARC_Config where io operations will take place
|
||||
* @param path file path for io
|
||||
*
|
||||
* @return 0 on sucess, ARC_ERRNO_ on fail
|
||||
*/
|
||||
int32_t ARC_Config_FileIO(ARC_Config *config, const char *path, uint8_t command);
|
||||
|
||||
/**
|
||||
* @brief sets current group in config
|
||||
*
|
||||
* @note ARC_Config_Get will use this set group
|
||||
*
|
||||
* @param config ARC_Config we are setting current group in
|
||||
* @param groupname name of group that will be set
|
||||
*
|
||||
* @return 0 on sucess, ARC_ERRNO_ on fail
|
||||
*/
|
||||
int32_t ARC_Config_SetGroup(ARC_Config *config, char *groupname);
|
||||
|
||||
/**
|
||||
* @brief get a value from a given keyname
|
||||
*
|
||||
* @note name may be prefaced with <group>:: to specify group
|
||||
*
|
||||
* @param config ARC_Config to get value from
|
||||
* @param keyname name of key to get from config
|
||||
* @param value data retrieved from config
|
||||
*
|
||||
* @return 0 on sucess, ARC_ERRNO_ on fail
|
||||
*/
|
||||
int32_t ARC_Config_Get(ARC_Config *config, char *keyname, void **value);
|
||||
|
||||
/**
|
||||
* @brief get a reference value from a given substring
|
||||
*
|
||||
* @note this function is meant to help with creation and deletion functions for types
|
||||
*
|
||||
* @param config ARC_Config to get value from
|
||||
* @param data string that holds the substring that will be used
|
||||
* @param subdata location of stubstring in data for what is to be read in
|
||||
*
|
||||
* @return a valid pointer on sucess, NULL on fail
|
||||
*/
|
||||
void *ARC_Config_GetReference(ARC_Config *config, char *data, ARC_StringSubstr *subdata);
|
||||
void ARC_Config_FileIO(ARC_Config *config, ARC_String *path, uint8_t command);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,35 +11,35 @@ extern "C" {
|
|||
#include "arc/std/string.h"
|
||||
|
||||
typedef struct ARC_Config ARC_Config;
|
||||
int32_t ARC_Defaults_ConfigKey_Create(ARC_Config *config);
|
||||
void ARC_Defaults_ConfigKey_Create(ARC_Config *config);
|
||||
|
||||
int32_t ARC_ConfigKey_Read_Uint8_t (ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value);
|
||||
int32_t ARC_ConfigKey_Read_Int8_t (ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value);
|
||||
//int32_t ARC_ConfigKey_Read_Char (ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value);
|
||||
int32_t ARC_ConfigKey_Read_Uint16_t (ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value);
|
||||
int32_t ARC_ConfigKey_Read_Int16_t (ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value);
|
||||
int32_t ARC_ConfigKey_Read_Uint32_t (ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value);
|
||||
int32_t ARC_ConfigKey_Read_Int32_t (ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value);
|
||||
int32_t ARC_ConfigKey_Read_Int (ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value);
|
||||
int32_t ARC_ConfigKey_Read_Uint64_t (ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value);
|
||||
int32_t ARC_ConfigKey_Read_Int64_t (ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value);
|
||||
int32_t ARC_ConfigKey_Read_Long (ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value);
|
||||
int32_t ARC_ConfigKey_Read_String (ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value);
|
||||
int32_t ARC_ConfigKey_Read_StringArray(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value);
|
||||
uint8_t ARC_ConfigKey_Read_Uint8_t (ARC_Config *config, ARC_String *string, void **value);
|
||||
uint8_t ARC_ConfigKey_Read_Int8_t (ARC_Config *config, ARC_String *string, void **value);
|
||||
uint8_t ARC_ConfigKey_Read_Char (ARC_Config *config, ARC_String *string, void **value);
|
||||
uint8_t ARC_ConfigKey_Read_Uint16_t (ARC_Config *config, ARC_String *string, void **value);
|
||||
uint8_t ARC_ConfigKey_Read_Int16_t (ARC_Config *config, ARC_String *string, void **value);
|
||||
uint8_t ARC_ConfigKey_Read_Uint32_t (ARC_Config *config, ARC_String *string, void **value);
|
||||
uint8_t ARC_ConfigKey_Read_Int32_t (ARC_Config *config, ARC_String *string, void **value);
|
||||
uint8_t ARC_ConfigKey_Read_Int (ARC_Config *config, ARC_String *string, void **value);
|
||||
uint8_t ARC_ConfigKey_Read_Uint64_t (ARC_Config *config, ARC_String *string, void **value);
|
||||
uint8_t ARC_ConfigKey_Read_Int64_t (ARC_Config *config, ARC_String *string, void **value);
|
||||
uint8_t ARC_ConfigKey_Read_Long (ARC_Config *config, ARC_String *string, void **value);
|
||||
uint8_t ARC_ConfigKey_Read_String (ARC_Config *config, ARC_String *string, void **value);
|
||||
uint8_t ARC_ConfigKey_Read_StringArray(ARC_Config *config, ARC_String *string, void **value);
|
||||
|
||||
int32_t ARC_ConfigKey_Delete_Uint8_t (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value);
|
||||
int32_t ARC_ConfigKey_Delete_Int8_t (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value);
|
||||
int32_t ARC_ConfigKey_Delete_Char (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value);
|
||||
int32_t ARC_ConfigKey_Delete_Uint16_t (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value);
|
||||
int32_t ARC_ConfigKey_Delete_Int16_t (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value);
|
||||
int32_t ARC_ConfigKey_Delete_Uint32_t (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value);
|
||||
int32_t ARC_ConfigKey_Delete_Int32_t (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value);
|
||||
int32_t ARC_ConfigKey_Delete_Int (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value);
|
||||
int32_t ARC_ConfigKey_Delete_Uint64_t (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value);
|
||||
int32_t ARC_ConfigKey_Delete_Int64_t (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value);
|
||||
int32_t ARC_ConfigKey_Delete_Long (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value);
|
||||
int32_t ARC_ConfigKey_Delete_String (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value);
|
||||
int32_t ARC_ConfigKey_Delete_StringArray(ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value);
|
||||
void ARC_ConfigKey_Delete_Uint8_t (ARC_Config *config, void *value);
|
||||
void ARC_ConfigKey_Delete_Int8_t (ARC_Config *config, void *value);
|
||||
void ARC_ConfigKey_Delete_Char (ARC_Config *config, void *value);
|
||||
void ARC_ConfigKey_Delete_Uint16_t (ARC_Config *config, void *value);
|
||||
void ARC_ConfigKey_Delete_Int16_t (ARC_Config *config, void *value);
|
||||
void ARC_ConfigKey_Delete_Uint32_t (ARC_Config *config, void *value);
|
||||
void ARC_ConfigKey_Delete_Int32_t (ARC_Config *config, void *value);
|
||||
void ARC_ConfigKey_Delete_Int (ARC_Config *config, void *value);
|
||||
void ARC_ConfigKey_Delete_Uint64_t (ARC_Config *config, void *value);
|
||||
void ARC_ConfigKey_Delete_Int64_t (ARC_Config *config, void *value);
|
||||
void ARC_ConfigKey_Delete_Long (ARC_Config *config, void *value);
|
||||
void ARC_ConfigKey_Delete_String (ARC_Config *config, void *value);
|
||||
void ARC_ConfigKey_Delete_StringArray(ARC_Config *config, void *value);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,10 +31,8 @@ struct ARC_HashtableNode {
|
|||
* @param key value to hash
|
||||
* @param keysize should be sizeof(key) before key is a void ptr
|
||||
* @param hashval value of hash, does not need to be within range of buckets
|
||||
*
|
||||
* @return 0 on sucess, ARC_ERRNO_ on fail
|
||||
*/
|
||||
typedef int32_t (* ARC_Hashtable_Hash)(void *key, size_t *keysize, uint32_t *hashval);
|
||||
typedef void (* ARC_Hashtable_Hash)(void *key, size_t *keysize, uint32_t *hashval);
|
||||
|
||||
/**
|
||||
* @brief key comparison function ptr
|
||||
|
|
@ -42,19 +40,17 @@ typedef int32_t (* ARC_Hashtable_Hash)(void *key, size_t *keysize, uint32_t *has
|
|||
* @param key1 first key
|
||||
* @param key2 second key
|
||||
*
|
||||
* @return 0 on sucess
|
||||
* @return 0 when keys match
|
||||
*/
|
||||
typedef int32_t (* ARC_Hashtable_KeyCompare)(void *key1, size_t *key1size, void *key2, size_t *key2size);
|
||||
typedef int8_t (* ARC_Hashtable_KeyCompare)(void *key1, size_t *key1size, void *key2, size_t *key2size);
|
||||
|
||||
/**
|
||||
* @brief callback to allow memory freeing of nodes
|
||||
*
|
||||
* @param node node to be destroyed
|
||||
* @param userdata any data the user wants to access in the callback
|
||||
*
|
||||
* @return 0 on sucess, ARC_ERRNO_ on fail
|
||||
*/
|
||||
typedef int32_t (* ARC_HashtableNode_DestroyExternal)(ARC_HashtableNode *node, void *userdata);
|
||||
typedef void (* ARC_HashtableNode_DestroyExternal)(ARC_HashtableNode *node, void *userdata);
|
||||
|
||||
/**
|
||||
* @brief cteates ARC_Hashtable type
|
||||
|
|
@ -72,10 +68,8 @@ void ARC_Hashtable_Create(ARC_Hashtable **htable, uint32_t bucketsize, ARC_Hasht
|
|||
* @param htable htable that will be destroyed
|
||||
* @param external function to allow external freeing of nodes, can be NULL
|
||||
* @param userdata any data the user wants access to in the callback
|
||||
*
|
||||
* @return 0 on sucess, ARC_ERRNO_ on fail
|
||||
*/
|
||||
int32_t ARC_Hashtable_Destroy(ARC_Hashtable *htable, ARC_HashtableNode_DestroyExternal external, void *userdata);
|
||||
void ARC_Hashtable_Destroy(ARC_Hashtable *htable, ARC_HashtableNode_DestroyExternal external, void *userdata);
|
||||
|
||||
/**
|
||||
* @brief adds value to hastable
|
||||
|
|
@ -84,10 +78,8 @@ int32_t ARC_Hashtable_Destroy(ARC_Hashtable *htable, ARC_HashtableNode_DestroyEx
|
|||
* @param key key for node that is being added
|
||||
* @param keysize sizeof key before it is passed into a void *
|
||||
* @param data data for node that is being added
|
||||
*
|
||||
* @return 0 on sucess, ARC_ERRNO_ on fail
|
||||
*/
|
||||
int32_t ARC_Hashtable_Add(ARC_Hashtable *htable, void *key, size_t keysize, void *data);
|
||||
void ARC_Hashtable_Add(ARC_Hashtable *htable, void *key, size_t keysize, void *data);
|
||||
|
||||
/**
|
||||
* @brief gets value from hashtable by key
|
||||
|
|
@ -96,10 +88,8 @@ int32_t ARC_Hashtable_Add(ARC_Hashtable *htable, void *key, size_t keysize, void
|
|||
* @param key key to get value from table
|
||||
* @param keysize sizeof key before it is passed into a void *
|
||||
* @param data data retrieved from table
|
||||
*
|
||||
* @return 0 on sucess, ARC_ERRNO_ on fail
|
||||
*/
|
||||
int32_t ARC_Hashtable_Get(ARC_Hashtable *htable, void *key, size_t keysize, void **data);
|
||||
void ARC_Hashtable_Get(ARC_Hashtable *htable, void *key, size_t keysize, void **data);
|
||||
|
||||
/**
|
||||
* @brief removes value from hashtable
|
||||
|
|
@ -109,10 +99,8 @@ int32_t ARC_Hashtable_Get(ARC_Hashtable *htable, void *key, size_t keysize, void
|
|||
* @param keysize sizeof key before it is passed into a void *
|
||||
* @param external function to allow external freeing of data, can be NULL
|
||||
* @param userdata any data the user wants access to in the callback
|
||||
*
|
||||
* @return 0 on sucess, ARC_ERRNO_ on fail
|
||||
*/
|
||||
int32_t ARC_Hashtable_Remove(ARC_Hashtable *htable, void *key, size_t keysize, ARC_HashtableNode_DestroyExternal external, void *userdata);
|
||||
void ARC_Hashtable_Remove(ARC_Hashtable *htable, void *key, size_t keysize, ARC_HashtableNode_DestroyExternal external, void *userdata);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include "arc/std/string.h"
|
||||
|
||||
/**
|
||||
* @brief get string and size from file
|
||||
|
|
@ -13,11 +14,8 @@ extern "C" {
|
|||
* @param path a string to path of target file
|
||||
* @param data pointer to where string will be created
|
||||
* this will need to be freed once done using it
|
||||
* @param size size of string
|
||||
*
|
||||
* @return int 0 on success, ARC_ERRNO_ on fail
|
||||
*/
|
||||
int32_t ARC_IO_FileToStr(const char *path, char **data, uint64_t *size);
|
||||
void ARC_IO_FileToStr(ARC_String *path, ARC_String **data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,92 +10,168 @@ extern "C" {
|
|||
/**
|
||||
* @brief substring position within a string
|
||||
*/
|
||||
typedef struct ARC_StringSubstr {
|
||||
uint64_t index;
|
||||
uint64_t length;
|
||||
} ARC_StringSubstr;
|
||||
typedef struct ARC_String {
|
||||
char *data;
|
||||
uint64_t length;
|
||||
} ARC_String;
|
||||
|
||||
/**
|
||||
* @brief substring position within a string, stored as 4 bytes
|
||||
*/
|
||||
typedef struct ARC_StringSubstr32_t {
|
||||
uint32_t index;
|
||||
uint32_t length;
|
||||
} ARC_StringSubstr32_t;
|
||||
* @brief creates ARC_String type
|
||||
*
|
||||
* @param string ARC_String to create
|
||||
* @param data cstring that will be stored in ARC_String
|
||||
* @param length length of ARC_String
|
||||
*/
|
||||
void ARC_String_Create(ARC_String **string, char *data, uint64_t length);
|
||||
|
||||
/**
|
||||
* @brief substring position within a string, stored as 1 byte
|
||||
* @brief destroys ARC_String type
|
||||
*
|
||||
* @param string string that will be destroyed
|
||||
*/
|
||||
void ARC_String_Destroy(ARC_String *string);
|
||||
|
||||
/**
|
||||
* @brief copy a ARC_String
|
||||
*
|
||||
* @param copy copy of oldString, will be set to NULL on error
|
||||
* @param original original string that is being copied
|
||||
*/
|
||||
typedef struct ARC_StringSubstr8_t {
|
||||
uint8_t index;
|
||||
uint8_t length;
|
||||
} ARC_StringSubstr8_t;
|
||||
void ARC_String_Copy(ARC_String **copy, ARC_String *original);
|
||||
|
||||
/**
|
||||
* @brief copy a subtring from a givin ARC_String
|
||||
*
|
||||
* @param substring new coppied substring, will be null on error
|
||||
* @param original string to copy substring from
|
||||
* @param start starting index in relation on original
|
||||
* @param length length of substring that is being created
|
||||
*/
|
||||
void ARC_String_CopySubstring(ARC_String **substring, ARC_String *original, uint64_t start, uint64_t length);
|
||||
|
||||
/**
|
||||
* @brief copy a subtring from a givin ARC_String
|
||||
*
|
||||
* @param newString string that doesn't have substring in it, will be null on error
|
||||
* @param original string to remove substring from
|
||||
* @param substring substring to remove
|
||||
*/
|
||||
void ARC_String_RemoveSubstring(ARC_String **newString, ARC_String *original, ARC_String *substring);
|
||||
|
||||
/**
|
||||
* @brief checks if two strings are the same
|
||||
*
|
||||
* @param first string to check against second
|
||||
* @param second string to check against first
|
||||
*
|
||||
* @return 1 if match, 0 if they don't match
|
||||
*/
|
||||
uint8_t ARC_String_Equals(ARC_String *first, ARC_String *second);
|
||||
|
||||
/**
|
||||
* @brief check if ARC_String and cstring match
|
||||
*
|
||||
* @param string ARC_string to check
|
||||
* @param cstring cstring to check
|
||||
* @param length length of cstring
|
||||
*/
|
||||
uint8_t ARC_String_EqualsCString(ARC_String *string, const char *cstring, uint64_t length);
|
||||
|
||||
/**
|
||||
* @brief checks if string is alphabetic
|
||||
*
|
||||
* @param val string to check
|
||||
* @param length length of string to check
|
||||
* @param string string to check
|
||||
*
|
||||
* @return 1 if alphabetic, 0 if not alphabetic
|
||||
*/
|
||||
uint8_t ARC_String_Alpha(char *val, uint64_t length);
|
||||
uint8_t ARC_String_Alpha(ARC_String *string);
|
||||
|
||||
/**
|
||||
* @brief converst substring from string to uint64_t
|
||||
*
|
||||
* @param data string to get substring from
|
||||
* @param substr substring to convert to long
|
||||
* @param string string to convert to long
|
||||
*
|
||||
* @return uint64_t converted number
|
||||
*/
|
||||
uint64_t ARC_String_ToUint64_t(const char *data, ARC_StringSubstr *substr);
|
||||
uint64_t ARC_String_ToUint64_t(ARC_String *string);
|
||||
|
||||
/**
|
||||
* @brief takes a given string, and assigns index and length for position of first matching substring
|
||||
*
|
||||
* @param data the string to find substring in
|
||||
* @param substr the string to find
|
||||
* @param index the index of substring within the string will be ~uint64_t if not found
|
||||
* @param string the string that will be searched
|
||||
* @param substr substring to find within string
|
||||
*
|
||||
* @return int ARC_ERRNO_ error code
|
||||
* @return ~(uint64_t)0 on error, anything else on success
|
||||
*/
|
||||
int32_t ARC_String_Find(char *data, char *substr, uint64_t *index);
|
||||
uint64_t ARC_String_Find(ARC_String *string, ARC_String *substring);
|
||||
|
||||
/**
|
||||
* @brief takes given cstring and gives position of first matching
|
||||
*
|
||||
* @param string the string that will be searched
|
||||
* @param cstring the cstring to find within string
|
||||
* @param length the length of cstring
|
||||
*
|
||||
* @return ~(uint64_t)0 on error, anything else on success
|
||||
*/
|
||||
uint64_t ARC_String_FindCString(ARC_String *string, const char *cstring, uint64_t length);
|
||||
|
||||
/**
|
||||
* @brief takes a given string, and assigns index and length for position of last matching substring
|
||||
*
|
||||
* @param data the string to find substring in
|
||||
* @param substr the string to find
|
||||
* @param index the index of substring within the string will be ~uint64_t if not found
|
||||
* @param string the string that will be searched
|
||||
* @param substr substring to find within string
|
||||
*
|
||||
* @return int ARC_ERRNO_ error code
|
||||
* @return ~(uint64_t)0 on error, anything else on success
|
||||
*/
|
||||
int32_t ARC_String_FindBack(char *data, char *substr, uint64_t *index);
|
||||
uint64_t ARC_String_FindBack(ARC_String *string, ARC_String *substring);
|
||||
|
||||
/**
|
||||
* @brief strips the ends based on a given substing
|
||||
* @brief strips the ends based on a given char
|
||||
*
|
||||
* @param data the string to find the substring in
|
||||
* @param substr the substring to strip ends by, defaults to " " if NULL
|
||||
* @param subdata the substring of data, will use given substring data, or strlen if length == 0
|
||||
* also will hold the return values
|
||||
*
|
||||
* @return int ARC_ERRNO_ error code
|
||||
* @param original the string which whill have the matching char stripped from
|
||||
* @param stripped where to store the string which has witespace stripped
|
||||
* will be null if there is an error
|
||||
* @param charToStrip the char that will be stripped from the ends
|
||||
*/
|
||||
int32_t ARC_StringSubstr_StripEnds(char *data, char *substr, ARC_StringSubstr *subdata);
|
||||
void ARC_String_StripEnds(ARC_String *original, ARC_String **stripped, char charToStrip);
|
||||
|
||||
/**
|
||||
* @brief strips the ends based on a given substing
|
||||
* @brief strips whitespace from a ARC_String
|
||||
*
|
||||
* @param data the string to find the substring in
|
||||
* @param substr the substring to strip ends by, defaults to " " if NULL
|
||||
* @param subdata the substring of data, will use given substring data, or strlen if length == 0
|
||||
* also will hold the return values
|
||||
*
|
||||
* @return int ARC_ERRNO_ error code
|
||||
* @param original the string which whill have whitespace stripped from
|
||||
* @param stripped where to store the string which has witespace stripped
|
||||
* will be null if there is an error
|
||||
*/
|
||||
int32_t ARC_StringSubstr_StripWhitespaceEnds(char *data, ARC_StringSubstr *subdata);
|
||||
void ARC_String_StripWhitespace(ARC_String *original, ARC_String **stripped);
|
||||
|
||||
/**
|
||||
* @brief strips the whitespace from the ends of a string
|
||||
*
|
||||
* @param original the string which whill have the whitespace stripped from its ends
|
||||
* @param stripped where to store the string which has witespace stripped from the ends
|
||||
* will be null if there is an error
|
||||
*/
|
||||
void ARC_String_StripEndsWhitespace(ARC_String *original, ARC_String **stripped);
|
||||
|
||||
/**
|
||||
* @brief merges two strings together
|
||||
*
|
||||
* @param first first part of string to combine
|
||||
* @param second second part of string to combine
|
||||
* @param combined new ARC_String of combined strings frist + second
|
||||
*/
|
||||
void ARC_String_Merge(ARC_String *first, ARC_String *second, ARC_String **combined);
|
||||
|
||||
/**
|
||||
* @brief copy a subtring from a givin ARC_String
|
||||
*
|
||||
* @param newString new string without specified section, will be NULL on error
|
||||
* @param original string to remove section from
|
||||
* @param removeIndex starting index in relation on original of what is to be removed
|
||||
* @param removeLength length of section that is being removed
|
||||
*/
|
||||
void ARC_String_RemoveSection(ARC_String **newString, ARC_String *original, uint64_t removeIndex, uint64_t removeLength);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
752
src/std/config.c
752
src/std/config.c
|
|
@ -1,8 +1,11 @@
|
|||
#include "arc/std/config.h"
|
||||
|
||||
#include "arc/std/errno.h"
|
||||
#include "arc/std/hashtable.h"
|
||||
#include "arc/std/io.h"
|
||||
#include "arc/std/string.h"
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
|
@ -20,72 +23,48 @@ typedef struct ARC_ConfigKey {
|
|||
} ARC_ConfigKey;
|
||||
|
||||
typedef struct ARC_ConfigTypeTemplate {
|
||||
ARC_ConfigKey *key;
|
||||
ARC_ConfigKeyDelete Delete;
|
||||
|
||||
void *data;
|
||||
} ARC_ConfigTypeTemplate;
|
||||
|
||||
typedef struct ARC_DeleteUserData {
|
||||
ARC_Config *config;
|
||||
int8_t ARC_Config_KeyComp(void *key1, size_t *key1size, void *key2, size_t *key2size);
|
||||
|
||||
const char* data;
|
||||
ARC_StringSubstr *subdata;
|
||||
} ARC_DeleteUserData;
|
||||
void ARC_Config_CreateGroup(ARC_Config *config, ARC_String *name);
|
||||
void ARC_Config_DestroyGroup(ARC_HashtableNode *group, void *userdata);
|
||||
|
||||
int32_t ARC_Config_KeyComp(void *key1, size_t *key1size, void *key2, size_t *key2size){
|
||||
if(*key1size - *key2size){ return -1; }
|
||||
return strncmp((const char *)key1, (const char *)key2, *key1size);
|
||||
void ARC_Config_DestroyGroupNode(ARC_HashtableNode *node , void *userdata);
|
||||
|
||||
void ARC_Config_RemoveKey(ARC_HashtableNode *node, void *userdata);
|
||||
|
||||
void ARC_Config_AddKey(ARC_Config *config, ARC_String *type, ARC_ConfigKeyRead keyRead, ARC_ConfigKeyDelete keyDelete){
|
||||
ARC_ConfigKey *newKey = (ARC_ConfigKey *)malloc(sizeof(ARC_ConfigKey));
|
||||
newKey->Read = keyRead;
|
||||
newKey->Delete = keyDelete;
|
||||
|
||||
char *typeval = (char *)malloc(sizeof(char) * type->length);
|
||||
strncpy(typeval, type->data, type->length);
|
||||
ARC_Hashtable_Add(config->keys, (void *)typeval, type->length, newKey);
|
||||
}
|
||||
|
||||
int32_t ARC_ConfigKey_Add(ARC_Config *config, char *type, ARC_ConfigKeyRead keyRead, ARC_ConfigKeyDelete keyDelete){
|
||||
ARC_ConfigKey *temp = (ARC_ConfigKey *)malloc(sizeof(ARC_ConfigKey));
|
||||
temp->Read = keyRead;
|
||||
temp->Delete = keyDelete;
|
||||
return ARC_Hashtable_Add(config->keys, (void *)type, strlen(type), (void *)temp);
|
||||
void ARC_Config_AddKeyCString(ARC_Config *config, const char *type, uint64_t length, ARC_ConfigKeyRead keyRead, ARC_ConfigKeyDelete keyDelete){
|
||||
ARC_ConfigKey *newKey = (ARC_ConfigKey *)malloc(sizeof(ARC_ConfigKey));
|
||||
newKey->Read = keyRead;
|
||||
newKey->Delete = keyDelete;
|
||||
|
||||
char *typeval = (char *)malloc(sizeof(char) * length);
|
||||
strncpy(typeval, type, length);
|
||||
ARC_Hashtable_Add(config->keys, (void *)typeval, length, newKey);
|
||||
}
|
||||
|
||||
int32_t ARC_ConfigKey_Destroy(ARC_HashtableNode *node, void *userdata){
|
||||
if(!node->data){ return ARC_ERRNO_NULL; }
|
||||
free((ARC_ConfigKey *)node->data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t ARC_ConfigGroup_Create(ARC_Config *config, const char *name){
|
||||
ARC_Hashtable *data;
|
||||
ARC_Hashtable_Create(&data, ARC_GROUP_DATA_BUCKET_SIZE, NULL, ARC_Config_KeyComp);
|
||||
|
||||
char *group = (char *) malloc(sizeof(char) * strlen(name));
|
||||
strncpy(group, name, strlen(name));
|
||||
|
||||
return ARC_Hashtable_Add(config->groups, (void *)group, strlen(name), (void *)data);
|
||||
}
|
||||
|
||||
int32_t ARC_ConfigGroupNode_Destroy(ARC_HashtableNode *node, void *userdata){
|
||||
free((char *)node->key);
|
||||
|
||||
ARC_ConfigTypeTemplate *temp = (ARC_ConfigTypeTemplate *)node->data;
|
||||
if(temp->key){
|
||||
ARC_DeleteUserData *deldata = (ARC_DeleteUserData *)userdata;
|
||||
temp->key->Delete(deldata->config, deldata->data, deldata->subdata, temp->data);
|
||||
}
|
||||
|
||||
free(temp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t ARC_ConfigGroup_Destroy(ARC_HashtableNode *group, void *userdata){
|
||||
free((char *)group->key);
|
||||
return ARC_Hashtable_Destroy((ARC_Hashtable *)group->data, ARC_ConfigGroupNode_Destroy, userdata);
|
||||
}
|
||||
|
||||
int32_t ARC_Config_Create(ARC_Config **config, ARC_ConfigKey_AddFunc keysAdd){
|
||||
*config = (ARC_Config *) malloc(sizeof(ARC_Config));
|
||||
void ARC_Config_Create(ARC_Config **config){
|
||||
*config = (ARC_Config *)malloc(sizeof(ARC_Config));
|
||||
(*config)->currgroup = NULL;
|
||||
|
||||
ARC_Hashtable *groups;
|
||||
ARC_Hashtable_Create(&groups, ARC_GROUP_BUCKET_SIZE, NULL, ARC_Config_KeyComp);
|
||||
(*config)->groups = groups;
|
||||
ARC_ConfigGroup_Create(*config, "");
|
||||
ARC_Config_CreateGroup(*config, NULL);
|
||||
|
||||
ARC_Hashtable *keys;
|
||||
ARC_Hashtable_Create(&keys, ARC_KEY_BUCKET_SIZE, NULL, ARC_Config_KeyComp);
|
||||
|
|
@ -94,323 +73,474 @@ int32_t ARC_Config_Create(ARC_Config **config, ARC_ConfigKey_AddFunc keysAdd){
|
|||
#ifdef ARC_DEFAULT_CONFIG
|
||||
ARC_Defaults_ConfigKey_Create(*config);
|
||||
#endif
|
||||
|
||||
if(keysAdd){ keysAdd(*config); }
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t ARC_Config_Destroy(ARC_Config *config){
|
||||
ARC_DeleteUserData deldata = { .config = config, .data = NULL, .subdata = NULL };
|
||||
int32_t err = ARC_Hashtable_Destroy(config->groups, ARC_ConfigGroup_Destroy, (void *)&deldata);
|
||||
if(err){ return err; }
|
||||
|
||||
err = ARC_Hashtable_Destroy(config->keys, ARC_ConfigKey_Destroy, NULL);
|
||||
if(err){ return err; }
|
||||
|
||||
void ARC_Config_Destroy(ARC_Config *config){
|
||||
ARC_Hashtable_Destroy(config->groups, ARC_Config_DestroyGroup, (void *)&config);
|
||||
ARC_Hashtable_Destroy(config->keys , ARC_Config_RemoveKey , NULL );
|
||||
free(config);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t ARC_Config_Get(ARC_Config *config, char *keyname, void **value){
|
||||
uint64_t len = 0;
|
||||
ARC_ConfigTypeTemplate *temp;
|
||||
|
||||
int32_t err = ARC_String_Find(keyname, (char *)"::", &len);
|
||||
if(err){ return err; }
|
||||
|
||||
if(len != ~((uint64_t)0)){
|
||||
char group[len + 1];
|
||||
strncpy(group, keyname, len);
|
||||
group[len] = '\0';
|
||||
|
||||
ARC_Hashtable *currgroup = config->currgroup;
|
||||
err = ARC_Config_SetGroup(config, group);
|
||||
if(err){ return err; }
|
||||
|
||||
char *namestr = (len + 2) + keyname;
|
||||
char name[strlen(namestr)];
|
||||
strcpy(name, namestr);
|
||||
|
||||
err = ARC_Hashtable_Get(config->currgroup, (void *)name, strlen(name), (void **)&temp);
|
||||
if(err){ return err; }
|
||||
|
||||
config->currgroup = currgroup;
|
||||
*value = temp->data;
|
||||
return 0;
|
||||
}
|
||||
|
||||
err = ARC_Hashtable_Get(config->currgroup, (void *)keyname, strlen(keyname), (void **)&temp);
|
||||
if(err){ return err; }
|
||||
|
||||
*value = temp->data;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t ARC_Config_Remove(ARC_Config *config, const char *keyname, const char* data, ARC_StringSubstr *subdata){
|
||||
ARC_DeleteUserData deldata = { .config = config, .data = data, .subdata = subdata };
|
||||
return ARC_Hashtable_Remove(config->currgroup, (void *)keyname, strlen(keyname), ARC_ConfigGroupNode_Destroy, (void *)&deldata);
|
||||
}
|
||||
|
||||
int32_t ARC_Config_SetGroup(ARC_Config *config, char *groupstr){
|
||||
int err = ARC_Hashtable_Get(config->groups, groupstr, strlen(groupstr), (void **)&(config->currgroup));
|
||||
if(err && err != ARC_ERRNO_NULL){ return err; }
|
||||
|
||||
if(!(config->currgroup)){
|
||||
err = ARC_ConfigGroup_Create(config, groupstr);
|
||||
if(err){ return err; }
|
||||
|
||||
err = ARC_Hashtable_Get(config->groups, groupstr, strlen(groupstr), (void **)&(config->currgroup));
|
||||
if(err){ return err; }
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ARC_ConfigPath_Create(char *data, ARC_StringSubstr *subpath, char **path){
|
||||
if(*(data + subpath->index) == '~'){
|
||||
*path = (char *) malloc(sizeof(char) * (subpath->length + strlen(ARC_HOME_PATH) + 1));
|
||||
strcpy(*path, ARC_HOME_PATH);
|
||||
strncpy((*path) + strlen(ARC_HOME_PATH) - 1, data + subpath->index, subpath->length);
|
||||
(*path)[subpath->length + strlen(ARC_HOME_PATH)] = '\0';
|
||||
void ARC_Config_SetGroup(ARC_Config *config, ARC_String *groupname){
|
||||
if(groupname == NULL){
|
||||
ARC_Hashtable_Get(config->groups, (void *)" ", 1, (void **)&(config->currgroup));
|
||||
return;
|
||||
}
|
||||
|
||||
*path = (char *) malloc(sizeof(char) * (subpath->length + 1));
|
||||
strncpy(*path, data + subpath->index, subpath->length);
|
||||
(*path)[subpath->length] = '\0';
|
||||
}
|
||||
|
||||
void ARC_ConfigPath_Destroy(char *url){
|
||||
free(url);
|
||||
}
|
||||
|
||||
int32_t ARC_Config_Recurse(ARC_Config *config, char *data, uint64_t *size, char *groupstr, ARC_StringSubstr *subkey, uint8_t *command);
|
||||
|
||||
int32_t ARC_ConfigKey_Command(ARC_Config *config, char *data, uint64_t *size, ARC_StringSubstr *subkey){
|
||||
ARC_StringSubstr subcommand = { subkey->index + 1, 0 };
|
||||
int32_t err = ARC_String_Find(data + subcommand.index, " ", &(subcommand.length));
|
||||
if(err){ return err; }
|
||||
if(subcommand.length == ~((uint64_t)0)){ return ARC_ERRNO_DATA; }
|
||||
subkey->index += subcommand.length + 1;
|
||||
|
||||
ARC_StringSubstr_StripEnds(data, NULL, &subcommand);
|
||||
if(strncmp("load", data + subcommand.index, strlen("load")) && strncmp("unload", data + subcommand.index, strlen("unload"))){ return ARC_ERRNO_DATA; }
|
||||
|
||||
ARC_StringSubstr subpath = { subkey->index, 0 };
|
||||
err = ARC_String_Find(data + subpath.index, (char *)"\"", &(subpath.index));
|
||||
if(err){ return err; }
|
||||
if(subpath.length == ~((uint64_t)0)){ return ARC_ERRNO_DATA; }
|
||||
subkey->index += subpath.length + 2; //we want to skip over the first \" that is why it is 2 not 1
|
||||
|
||||
subpath = (ARC_StringSubstr) { subkey->index, 0 };
|
||||
err = ARC_String_Find(data + subpath.index, (char *)"\"", &(subpath.length));
|
||||
if(err){ return err; }
|
||||
if(subpath.length == ~((uint64_t)0)){ return ARC_ERRNO_DATA; }
|
||||
subkey->index += subpath.length + 1;
|
||||
|
||||
char *path;
|
||||
ARC_ConfigPath_Create(data, &subpath, &path);
|
||||
|
||||
if (!strncmp( "load", data + subcommand.index, strlen( "load"))){ err = ARC_Config_FileIO(config, path, ARC_CONFIG_FILE_IO_LOAD ); }
|
||||
else if(!strncmp("unload", data + subcommand.index, strlen("unload"))){ err = ARC_Config_FileIO(config, path, ARC_CONFIG_FILE_IO_UNLOAD); }
|
||||
else { return ARC_ERRNO_DATA; }
|
||||
|
||||
ARC_ConfigPath_Destroy(path);
|
||||
return err;
|
||||
}
|
||||
|
||||
int32_t ARC_ConfigKey_Comment(ARC_Config *config, char *data, uint64_t *size, ARC_StringSubstr *subkey){
|
||||
uint64_t commentlen = 0;
|
||||
if(data[subkey->index + 1] == '*'){
|
||||
int32_t err = ARC_String_Find(data + subkey->index, (char *)"*/", &commentlen);
|
||||
if(err){ return err; }
|
||||
|
||||
subkey->index += commentlen + 1;
|
||||
return 0;
|
||||
ARC_Hashtable_Get(config->groups, (void *)groupname->data, groupname->length, (void **)&(config->currgroup));
|
||||
if(arc_errno && arc_errno != ARC_ERRNO_NULL){
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t err = ARC_String_Find(data + subkey->index, (char *)"\n", &commentlen);
|
||||
if(err){ return err; }
|
||||
if(config->currgroup){
|
||||
return;
|
||||
}
|
||||
|
||||
subkey->index += commentlen + 1;
|
||||
return 0;
|
||||
ARC_Config_CreateGroup(config, groupname);
|
||||
if(arc_errno){
|
||||
return;
|
||||
}
|
||||
|
||||
ARC_Hashtable_Get(config->groups, (void *)groupname->data, groupname->length, (void **)&(config->currgroup));
|
||||
}
|
||||
|
||||
int32_t ARC_ConfigKey_Group(ARC_Config *config, char *data, uint64_t *size, ARC_StringSubstr *subkey, uint8_t *command){
|
||||
ARC_StringSubstr subgroup = { subkey->index, 0 };
|
||||
int32_t err = ARC_String_Find(data + subgroup.index, "{", &(subgroup.length));
|
||||
if(err){ return err; }
|
||||
if(subgroup.length == ~((uint64_t)0)){ return ARC_ERRNO_DATA; }
|
||||
subkey->index += subgroup.length + 1;
|
||||
void ARC_Config_Get(ARC_Config *config, ARC_String *keyname, void **value){
|
||||
ARC_ConfigTypeTemplate *temp;
|
||||
|
||||
ARC_StringSubstr_StripEnds(data, NULL, &subgroup);
|
||||
ARC_String *separator;
|
||||
ARC_String_Create(&separator, "::", 2);
|
||||
uint64_t length = ARC_String_Find(keyname, separator);
|
||||
|
||||
char groupstr[subgroup.length + 1];
|
||||
strncpy(groupstr, data + subgroup.index, subgroup.length);
|
||||
groupstr[subgroup.length] = '\0';
|
||||
if(arc_errno){
|
||||
//TODO: Debug info here
|
||||
*value = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
return ARC_Config_Recurse(config, data, size, groupstr, subkey, command);
|
||||
if(length != ~((uint64_t)0)){
|
||||
ARC_String *group;
|
||||
ARC_String_CopySubstring(&group, keyname, 0, length);
|
||||
|
||||
ARC_Hashtable *currgroup = config->currgroup;
|
||||
ARC_Config_SetGroup(config, group);
|
||||
if(arc_errno){
|
||||
ARC_String_Destroy(group);
|
||||
*value = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
ARC_String *name;
|
||||
ARC_String_CopySubstring(&name, keyname, length + 2, keyname->length - (length + 2));
|
||||
|
||||
ARC_Hashtable_Get(config->currgroup, (void *)name->data, name->length, (void **)&temp);
|
||||
|
||||
config->currgroup = currgroup;
|
||||
*value = temp->data;
|
||||
return;
|
||||
}
|
||||
|
||||
ARC_Hashtable_Get(config->currgroup, (void *)keyname->data, keyname->length, (void **)&temp);
|
||||
if(arc_errno || temp == NULL){
|
||||
*value = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
*value = temp->data;
|
||||
}
|
||||
|
||||
int32_t ARC_ConfigKey_Load(ARC_Config *config, char *data, uint64_t *size, char *keyname, ARC_StringSubstr *subkey){
|
||||
void ARC_Config_Recurse(ARC_Config *config, ARC_String **data, ARC_String *groupstr, uint8_t *command);
|
||||
|
||||
void ARC_Config_SetKeyGroup(ARC_Config *config, ARC_String **data, uint8_t *command){
|
||||
uint64_t index = ARC_String_FindCString(*data, " ", 1);
|
||||
uint64_t nextIndex = ARC_String_FindCString(*data, "{", 1);
|
||||
if(index == ~(uint64_t)0 || nextIndex == ~(uint64_t)0){
|
||||
arc_errno = ARC_ERRNO_DATA;
|
||||
}
|
||||
|
||||
if(arc_errno){
|
||||
return;
|
||||
}
|
||||
|
||||
ARC_String *name, *temp;
|
||||
ARC_String_CopySubstring(&temp, *data, index, nextIndex);
|
||||
ARC_String_StripEndsWhitespace(temp, &name);
|
||||
ARC_String_Destroy(temp);
|
||||
|
||||
temp = *data;
|
||||
ARC_String_RemoveSection(data, temp, nextIndex + 1, (*data)->length - (nextIndex + 1));
|
||||
ARC_String_Destroy(temp);
|
||||
|
||||
ARC_Config_Recurse(config, data, name, command);
|
||||
ARC_String_Destroy(name);
|
||||
}
|
||||
|
||||
void ARC_Config_LoadFromKey(ARC_Config *config, ARC_String *keyType, ARC_String *name, ARC_String *value){
|
||||
ARC_ConfigKey *key;
|
||||
int32_t err = ARC_Hashtable_Get(config->keys, (void *)keyname, strlen(keyname), (void **)&key);
|
||||
if(err){ return err; }
|
||||
|
||||
ARC_StringSubstr subname = { subkey->index, 0 };
|
||||
err = ARC_String_Find(data + subname.index, (char *)"=", &(subname.length));
|
||||
if(err){ return err; }
|
||||
if(subname.length == ~((uint64_t)0)){ return ARC_ERRNO_DATA; }
|
||||
subkey->index += subname.length + 1;
|
||||
|
||||
ARC_StringSubstr_StripEnds(data, NULL, &subname);
|
||||
|
||||
ARC_StringSubstr subvalue = { subkey->index, 0 };
|
||||
err = ARC_String_Find(data + subvalue.index, (char *)";", &(subvalue.length));
|
||||
if(err){ return err; }
|
||||
if(subvalue.length == ~((uint64_t)0)){ return ARC_ERRNO_DATA; }
|
||||
subkey->index += subvalue.length + 1;
|
||||
|
||||
ARC_StringSubstr_StripEnds(data, NULL, &subvalue);
|
||||
ARC_ConfigTypeTemplate *templateVal = NULL;
|
||||
|
||||
char *name = malloc(sizeof(char) * subname.length + 1);
|
||||
strncpy(name, data + subname.index, sizeof(char) * subname.length);
|
||||
name[subname.length] = '\0';
|
||||
|
||||
templateVal = (ARC_ConfigTypeTemplate *) malloc(sizeof(ARC_ConfigTypeTemplate));
|
||||
templateVal->key = NULL;
|
||||
templateVal->data = ARC_Config_GetReference(config, data, &subvalue);
|
||||
|
||||
if(!templateVal->data){
|
||||
err = key->Read(config, data, &subvalue, &(templateVal->data));
|
||||
if(err){ return err; }
|
||||
templateVal->key = key;
|
||||
ARC_Hashtable_Get(config->keys, keyType->data, keyType->length, (void **)&key);
|
||||
if(key == NULL){
|
||||
arc_errno = ARC_ERRNO_DATA;
|
||||
}
|
||||
|
||||
return ARC_Hashtable_Add(config->currgroup, (void *)name, strlen(name), (void *)templateVal);
|
||||
if(arc_errno){
|
||||
return;
|
||||
}
|
||||
|
||||
ARC_ConfigTypeTemplate *templateVal = (ARC_ConfigTypeTemplate *) malloc(sizeof(ARC_ConfigTypeTemplate));
|
||||
templateVal->Delete = NULL;
|
||||
|
||||
uint8_t reference = key->Read(config, value, &(templateVal->data));
|
||||
if(!reference){
|
||||
templateVal->Delete = key->Delete;
|
||||
}
|
||||
|
||||
if(arc_errno){
|
||||
return;
|
||||
}
|
||||
|
||||
char *nameval = (char *)malloc(sizeof(char) * name->length);
|
||||
strncpy(nameval, name->data, name->length);
|
||||
ARC_Hashtable_Add(config->currgroup, nameval, name->length, (void *)templateVal);
|
||||
}
|
||||
|
||||
int32_t ARC_ConfigKey_Unload(ARC_Config *config, char *data, uint64_t *size, char *keyname, ARC_StringSubstr *subkey){
|
||||
ARC_StringSubstr subname = { subkey->index, 0 };
|
||||
int32_t err = ARC_String_Find(data + subname.index, (char *)"=", &(subname.length));
|
||||
if(err){ return err; }
|
||||
if(subname.length == ~((uint64_t)0)){ return ARC_ERRNO_DATA; }
|
||||
subkey->index += subname.length + 1;
|
||||
|
||||
ARC_StringSubstr_StripEnds(data, NULL, &subname);
|
||||
char name[subname.length + 1];
|
||||
strncpy(name, data + subname.index, subname.length);
|
||||
name[subname.length] = '\0';
|
||||
|
||||
subname = (ARC_StringSubstr){ subkey->index, 0 };
|
||||
err = ARC_String_Find(data + subname.index, (char *)";", &(subname.length));
|
||||
if(err){ return err; }
|
||||
if(subname.length == ~((uint64_t)0)){ return ARC_ERRNO_DATA; }
|
||||
subkey->index += subname.length + 1;
|
||||
|
||||
return ARC_Config_Remove(config, name, data, &subname);
|
||||
void ARC_Config_UnloadFromKey(ARC_Config *config, ARC_String *keyType, ARC_String *name){
|
||||
ARC_Hashtable_Remove(config->currgroup, name->data, name->length, ARC_Config_DestroyGroupNode, &config);
|
||||
}
|
||||
|
||||
int32_t ARC_Config_Recurse(ARC_Config *config, char *data, uint64_t *size, char *groupstr, ARC_StringSubstr *subkey, uint8_t *command){
|
||||
int32_t err = ARC_Config_SetGroup(config, groupstr);
|
||||
if(err){ return err; }
|
||||
void ARC_Config_GetNameAndValue(ARC_String *data, ARC_String **name, ARC_String **value){
|
||||
uint64_t index = ARC_String_FindCString(data, "=", 1);
|
||||
if(arc_errno || index == ~(uint64_t)0){
|
||||
*name = NULL;
|
||||
*value = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
ARC_String_CopySubstring(name, data, 0, index - 1);
|
||||
index++;
|
||||
|
||||
ARC_String *dataTemp = *name;
|
||||
ARC_String_StripEndsWhitespace(dataTemp, name);
|
||||
ARC_String_Destroy(dataTemp);
|
||||
|
||||
ARC_String_CopySubstring(value, data, index, data->length - index);
|
||||
}
|
||||
|
||||
void ARC_Config_Recurse(ARC_Config *config, ARC_String **data, ARC_String *groupstr, uint8_t *command){
|
||||
ARC_Config_SetGroup(config, groupstr);
|
||||
if(arc_errno){
|
||||
return;
|
||||
}
|
||||
|
||||
ARC_Hashtable *group = config->currgroup;
|
||||
|
||||
while(subkey->index < *size){
|
||||
if(data[subkey->index] == ' ' || data[subkey->index] == '\n' || data[subkey->index] == '\t' || data[subkey->index] == '\r'){
|
||||
subkey->index++;
|
||||
continue;
|
||||
}
|
||||
while(*data && (*data)->length){
|
||||
ARC_String *dataTemp = *data;
|
||||
ARC_String_StripEndsWhitespace(dataTemp, data);
|
||||
ARC_String_Destroy(dataTemp);
|
||||
|
||||
if(data[subkey->index] == '}'){
|
||||
// break out of current group
|
||||
if((*data)->data[0] == '}'){
|
||||
config->currgroup = NULL;
|
||||
subkey->index++;
|
||||
return 0;
|
||||
|
||||
dataTemp = *data;
|
||||
ARC_String_CopySubstring(data, dataTemp, 1, dataTemp->length - 1);
|
||||
ARC_String_Destroy(dataTemp);
|
||||
return;
|
||||
}
|
||||
|
||||
if(data[subkey->index] == '#'){
|
||||
err = ARC_ConfigKey_Command(config, data, size, subkey);
|
||||
if(err){ return err; }
|
||||
continue;
|
||||
}
|
||||
|
||||
if(data[subkey->index] == '/'){
|
||||
err = ARC_ConfigKey_Comment(config, data, size, subkey);
|
||||
if(err){ return err; }
|
||||
continue;
|
||||
}
|
||||
|
||||
err = ARC_String_Find(data + subkey->index, (char *)" ", &(subkey->length));
|
||||
if(err){ return err; }
|
||||
if(subkey->length == ~((uint64_t)0)){ return 0; }
|
||||
|
||||
// set group
|
||||
if(!(config->currgroup)){
|
||||
config->currgroup = group;
|
||||
}
|
||||
|
||||
char keyname[subkey->length + 1];
|
||||
strncpy(keyname, data + subkey->index, subkey->length);
|
||||
keyname[subkey->length] = '\0';
|
||||
subkey->index += subkey->length + 1;
|
||||
// get keys type
|
||||
uint64_t index = ARC_String_FindCString(*data, " ", 1);
|
||||
if(arc_errno || index == ~(uint64_t)0){
|
||||
return;
|
||||
}
|
||||
|
||||
ARC_String *keyType, *keyTypeTemp;
|
||||
ARC_String_CopySubstring(&keyTypeTemp, *data, 0, index);
|
||||
ARC_String_StripEndsWhitespace(keyTypeTemp, &keyType);
|
||||
ARC_String_Destroy(keyTypeTemp);
|
||||
|
||||
if(ARC_String_EqualsCString(keyType, "group", 5)){
|
||||
ARC_Config_SetKeyGroup(config, data, command);
|
||||
if(arc_errno){
|
||||
ARC_String_Destroy(keyType);
|
||||
return;
|
||||
}
|
||||
|
||||
if(subkey->length == strlen("group") && !strcmp(keyname, "group")){
|
||||
err = ARC_ConfigKey_Group(config, data, size, subkey, command);
|
||||
if(err){ return err; }
|
||||
continue;
|
||||
}
|
||||
|
||||
// get and copy up to the ;
|
||||
ARC_String *nameAndValue;
|
||||
uint64_t nextIndex = ARC_String_FindCString(*data, ";", 1);
|
||||
if(nextIndex == ~(uint64_t)0){
|
||||
arc_errno = ARC_ERRNO_DATA;
|
||||
}
|
||||
|
||||
if(arc_errno){
|
||||
ARC_String_Destroy(keyType);
|
||||
return;
|
||||
}
|
||||
|
||||
ARC_String_CopySubstring(&nameAndValue, *data, index, nextIndex - (index + 1));
|
||||
if(arc_errno){
|
||||
ARC_String_Destroy(keyType);
|
||||
return;
|
||||
}
|
||||
|
||||
// remove up to the ; from data string
|
||||
dataTemp = *data;
|
||||
ARC_String_CopySubstring(data, dataTemp, nextIndex, (*data)->length - nextIndex);
|
||||
ARC_String_Destroy(dataTemp);
|
||||
if(arc_errno){
|
||||
ARC_String_Destroy(keyType);
|
||||
ARC_String_Destroy(nameAndValue);
|
||||
return;
|
||||
}
|
||||
|
||||
// get name and value of string
|
||||
ARC_String *name, *value;
|
||||
ARC_Config_GetNameAndValue(nameAndValue, &name, &value);
|
||||
ARC_String_Destroy(nameAndValue);
|
||||
if(arc_errno){
|
||||
ARC_String_Destroy(keyType);
|
||||
return;
|
||||
}
|
||||
|
||||
// load from key
|
||||
if(*command == ARC_CONFIG_FILE_IO_LOAD){
|
||||
err = ARC_ConfigKey_Load(config, data, size, keyname, subkey);
|
||||
if(err){ return err; }
|
||||
ARC_Config_LoadFromKey(config, keyType, name, value);
|
||||
if(arc_errno){
|
||||
ARC_String_Destroy(keyType);
|
||||
ARC_String_Destroy(name );
|
||||
ARC_String_Destroy(value );
|
||||
return;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// unload from key
|
||||
if(*command == ARC_CONFIG_FILE_IO_UNLOAD){
|
||||
err = ARC_ConfigKey_Unload(config, data, size, keyname, subkey);
|
||||
if(err){ return err;}
|
||||
ARC_Config_UnloadFromKey(config, keyType, name);
|
||||
if(arc_errno){
|
||||
ARC_String_Destroy(keyType);
|
||||
ARC_String_Destroy(name );
|
||||
ARC_String_Destroy(value );
|
||||
return;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
return ARC_ERRNO_DATA;
|
||||
// config file wasn't loaded correctly
|
||||
ARC_String_Destroy(keyType);
|
||||
ARC_String_Destroy(name );
|
||||
ARC_String_Destroy(value );
|
||||
arc_errno = ARC_ERRNO_DATA;
|
||||
return;
|
||||
}
|
||||
|
||||
config->currgroup = group;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t ARC_Config_FileIO(ARC_Config *config, const char *pathstr, uint8_t command){
|
||||
char *path, *data;
|
||||
uint64_t size;
|
||||
ARC_StringSubstr subpath = { 0, strlen(pathstr) };
|
||||
ARC_ConfigPath_Create((char *)pathstr, &subpath, &path);
|
||||
void ARC_Config_StripComment(ARC_String *original, ARC_String **stripped, ARC_String *lineStart, ARC_String *lineEnd){
|
||||
ARC_String *current;
|
||||
ARC_String_Copy(¤t, original);
|
||||
|
||||
int32_t err = ARC_IO_FileToStr(path, &data, &size);
|
||||
if(err){
|
||||
ARC_DEBUG_LOG(err, "ARC_IO_FileToStr(%s, &data, &size);\n", path);
|
||||
ARC_ConfigPath_Destroy(path);
|
||||
return err;
|
||||
uint64_t index = ARC_String_Find(current, lineStart);
|
||||
while(index != ~(uint64_t)0){
|
||||
|
||||
uint64_t endIndex = ARC_String_Find(current, lineEnd);
|
||||
if(endIndex == ~(uint64_t)0){
|
||||
ARC_DEBUG_ERR("ARC_Config_RemoveComments(original, commentRemoved); No newline found when stripping single line comment");
|
||||
arc_errno = ARC_ERRNO_DATA;
|
||||
*stripped = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
ARC_String *currentTemp = current;
|
||||
ARC_String_RemoveSection(¤t, currentTemp, index, endIndex - index);
|
||||
ARC_String_Destroy(currentTemp);
|
||||
|
||||
index = ARC_String_Find(current, lineStart);
|
||||
}
|
||||
|
||||
ARC_ConfigPath_Destroy(path);
|
||||
|
||||
ARC_StringSubstr subkey = { 0, 0 };
|
||||
err = ARC_Config_Recurse(config, data, &size, "", &subkey, &command);
|
||||
if(err){ return err; }
|
||||
|
||||
free(data);
|
||||
return 0;
|
||||
*stripped = current;
|
||||
}
|
||||
|
||||
void *ARC_Config_GetReference(ARC_Config *config, char *data, ARC_StringSubstr *subdata){
|
||||
if(ARC_String_Alpha(data + subdata->index, 1) && *(data + subdata->index) != ':'){ return NULL; }
|
||||
void ARC_Config_RemoveComments(ARC_String *original, ARC_String **commentRemoved){
|
||||
ARC_String *lineStart, *lineEnd;
|
||||
|
||||
char refname[subdata->length + 1];
|
||||
strncpy(refname, data + subdata->index, subdata->length);
|
||||
refname[subdata->length] = 0;
|
||||
//Single Line Comment
|
||||
ARC_String_Create(&lineStart, "//", 2);
|
||||
ARC_String_Create(&lineEnd , "\n", 1);
|
||||
|
||||
void *value;
|
||||
int32_t err = ARC_Config_Get(config, refname, &value);
|
||||
return (err)? NULL : value;
|
||||
ARC_String *singleLineStripped;
|
||||
ARC_Config_StripComment(original, &singleLineStripped, lineStart, lineEnd);
|
||||
|
||||
ARC_String_Destroy(lineStart);
|
||||
ARC_String_Destroy(lineEnd );
|
||||
|
||||
if(arc_errno){
|
||||
commentRemoved = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
//Multi Line Comment
|
||||
ARC_String_Create(&lineStart, "/*", 2);
|
||||
ARC_String_Create(&lineEnd , "*/", 2);
|
||||
|
||||
ARC_Config_StripComment(singleLineStripped, commentRemoved, lineStart, lineEnd);
|
||||
ARC_String_Destroy(singleLineStripped);
|
||||
|
||||
ARC_String_Destroy(lineStart);
|
||||
ARC_String_Destroy(lineEnd );
|
||||
}
|
||||
|
||||
void ARC_Config_RunCommand(ARC_Config *config, ARC_String *command){
|
||||
ARC_String *space;
|
||||
ARC_String_Create(&space, " " , 1);
|
||||
|
||||
uint64_t index = ARC_String_Find(command, space);
|
||||
if(index == ~(uint64_t)0){
|
||||
arc_errno = ARC_ERRNO_DATA;
|
||||
ARC_String_Destroy(space);
|
||||
return;
|
||||
}
|
||||
|
||||
ARC_String *commandOpt;
|
||||
ARC_String_CopySubstring(&commandOpt, command, 0, index);
|
||||
|
||||
ARC_String *commandArgTemp, *commandArg;
|
||||
ARC_String_CopySubstring(&commandArgTemp, command, index + space->length, command->length - (index + space->length));
|
||||
ARC_String_StripWhitespace(commandArgTemp, &commandArg);
|
||||
ARC_String_Destroy(commandArgTemp);
|
||||
|
||||
if(ARC_String_EqualsCString(command, "load", 4)){
|
||||
ARC_Config_FileIO(config, commandArg, ARC_CONFIG_FILE_IO_LOAD);
|
||||
}
|
||||
else if(ARC_String_EqualsCString(command, "unload", 6)){
|
||||
ARC_Config_FileIO(config, commandArg, ARC_CONFIG_FILE_IO_UNLOAD);
|
||||
}
|
||||
else {
|
||||
arc_errno = ARC_ERRNO_DATA;
|
||||
}
|
||||
|
||||
ARC_String_Destroy(commandOpt);
|
||||
ARC_String_Destroy(commandArg);
|
||||
ARC_String_Destroy(space );
|
||||
}
|
||||
|
||||
void ARC_Config_RemoveAndRunCommands(ARC_Config *config, ARC_String *original, ARC_String **commandRemoved){
|
||||
ARC_String *current;
|
||||
ARC_String_Copy(¤t, original);
|
||||
|
||||
ARC_String *lineStart, *lineEnd;
|
||||
ARC_String_Create(&lineStart, "#" , 1);
|
||||
ARC_String_Create(&lineEnd , "\n", 1);
|
||||
|
||||
uint64_t index = ARC_String_Find(current, lineStart);
|
||||
|
||||
while(index != ~(uint64_t)0){
|
||||
uint64_t endIndex = ARC_String_Find(current, lineEnd);
|
||||
if(endIndex == ~(uint64_t)0){
|
||||
arc_errno = ARC_ERRNO_DATA;
|
||||
ARC_String_Destroy(current );
|
||||
ARC_String_Destroy(lineStart);
|
||||
ARC_String_Destroy(lineEnd );
|
||||
*commandRemoved = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
ARC_String *command;
|
||||
ARC_String_CopySubstring(&command, current, index + lineStart->length, endIndex - (index + lineStart->length));
|
||||
ARC_Config_RunCommand(config, command);
|
||||
|
||||
ARC_String *currentTemp = current;
|
||||
ARC_String_RemoveSubstring(¤t, currentTemp, command);
|
||||
ARC_String_Destroy(command);
|
||||
ARC_String_Destroy(currentTemp);
|
||||
}
|
||||
|
||||
ARC_String_Destroy(lineStart);
|
||||
ARC_String_Destroy(lineEnd );
|
||||
|
||||
*commandRemoved = current;
|
||||
}
|
||||
|
||||
void ARC_Config_FileIO(ARC_Config *config, ARC_String *path, uint8_t command){
|
||||
ARC_String *data;
|
||||
ARC_IO_FileToStr(path, &data);
|
||||
if(arc_errno){
|
||||
ARC_DEBUG_LOG(arc_errno, "ARC_IO_FileToStr(%s, &data, &size);\n", path->data);
|
||||
return;
|
||||
}
|
||||
|
||||
ARC_String *noCommentData;
|
||||
ARC_Config_RemoveComments(data, &noCommentData);
|
||||
ARC_String_Destroy(data);
|
||||
|
||||
ARC_String *noCommandData;
|
||||
ARC_Config_RemoveAndRunCommands(config, noCommentData, &noCommandData);
|
||||
ARC_String_Destroy(noCommentData);
|
||||
|
||||
ARC_Config_Recurse(config, &noCommandData, NULL, &command);
|
||||
if(noCommandData){
|
||||
ARC_String_Destroy(noCommandData);
|
||||
}
|
||||
}
|
||||
|
||||
int8_t ARC_Config_KeyComp(void *key1, size_t *key1size, void *key2, size_t *key2size){
|
||||
if(*key1size - *key2size){ return -1; }
|
||||
return strncmp((const char *)key1, (const char *)key2, *key1size);
|
||||
}
|
||||
|
||||
void ARC_Config_CreateGroup(ARC_Config *config, ARC_String *name){
|
||||
ARC_Hashtable *data;
|
||||
ARC_Hashtable_Create(&data, ARC_GROUP_DATA_BUCKET_SIZE, NULL, ARC_Config_KeyComp);
|
||||
|
||||
if(name){
|
||||
char *nameval = (char *)malloc(sizeof(char) * name->length);
|
||||
strncpy(nameval, name->data, name->length);
|
||||
ARC_Hashtable_Add(config->groups, nameval, name->length, (void *)data);
|
||||
return;
|
||||
}
|
||||
|
||||
char *emptyGroup = (char *)malloc(sizeof(char));
|
||||
emptyGroup[0] = ' ';
|
||||
ARC_Hashtable_Add(config->groups, emptyGroup, 1, (void *)data);
|
||||
}
|
||||
|
||||
void ARC_Config_DestroyGroup(ARC_HashtableNode *group, void *userdata){
|
||||
free((char *)group->key);
|
||||
return ARC_Hashtable_Destroy((ARC_Hashtable *)group->data, ARC_Config_DestroyGroupNode, userdata);
|
||||
}
|
||||
|
||||
void ARC_Config_DestroyGroupNode(ARC_HashtableNode *node, void *userdata){
|
||||
free((char *)node->key);
|
||||
|
||||
ARC_ConfigTypeTemplate *temp = (ARC_ConfigTypeTemplate *)node->data;
|
||||
if(temp->Delete && temp->data && userdata){
|
||||
ARC_Config *config = (ARC_Config *)userdata;
|
||||
|
||||
temp->Delete(config, temp->data);
|
||||
}
|
||||
|
||||
free(temp);
|
||||
node->data = NULL;
|
||||
}
|
||||
|
||||
void ARC_Config_RemoveKey(ARC_HashtableNode *node, void *userdata){
|
||||
free((char *)node->key);
|
||||
|
||||
if(!node->data){
|
||||
arc_errno = ARC_ERRNO_NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
free((ARC_ConfigKey *)node->data);
|
||||
}
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
#include "arc/std/string.h"
|
||||
#ifdef ARC_DEFAULT_CONFIG
|
||||
|
||||
#include "arc/std/defaults/config.h"
|
||||
|
|
@ -9,103 +10,102 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
int32_t ARC_Defaults_ConfigKey_Create(ARC_Config *config){
|
||||
ARC_ConfigKey_Add(config, "uint8_t" , ARC_ConfigKey_Read_Uint8_t , ARC_ConfigKey_Delete_Uint8_t );
|
||||
ARC_ConfigKey_Add(config, "int8_t" , ARC_ConfigKey_Read_Int8_t , ARC_ConfigKey_Delete_Int8_t );
|
||||
// ARC_ConfigKey_Add(config, "char" , ARC_ConfigKey_Read_Char , ARC_ConfigKey_Delete_Char );
|
||||
ARC_ConfigKey_Add(config, "uint16_t", ARC_ConfigKey_Read_Uint16_t , ARC_ConfigKey_Delete_Uint16_t );
|
||||
ARC_ConfigKey_Add(config, "int16_t" , ARC_ConfigKey_Read_Int16_t , ARC_ConfigKey_Delete_Int16_t );
|
||||
ARC_ConfigKey_Add(config, "uint32_t", ARC_ConfigKey_Read_Uint32_t , ARC_ConfigKey_Delete_Uint32_t );
|
||||
ARC_ConfigKey_Add(config, "int32_t" , ARC_ConfigKey_Read_Int32_t , ARC_ConfigKey_Delete_Int32_t );
|
||||
ARC_ConfigKey_Add(config, "int" , ARC_ConfigKey_Read_Int , ARC_ConfigKey_Delete_Int );
|
||||
ARC_ConfigKey_Add(config, "uint64_t", ARC_ConfigKey_Read_Uint64_t , ARC_ConfigKey_Delete_Uint64_t );
|
||||
ARC_ConfigKey_Add(config, "int64_t" , ARC_ConfigKey_Read_Int64_t , ARC_ConfigKey_Delete_Int64_t );
|
||||
ARC_ConfigKey_Add(config, "long" , ARC_ConfigKey_Read_Long , ARC_ConfigKey_Delete_Long );
|
||||
ARC_ConfigKey_Add(config, "string" , ARC_ConfigKey_Read_String , ARC_ConfigKey_Delete_String );
|
||||
ARC_ConfigKey_Add(config, "string[]", ARC_ConfigKey_Read_StringArray, ARC_ConfigKey_Delete_StringArray);
|
||||
return 0;
|
||||
void ARC_Defaults_ConfigKey_Create(ARC_Config *config){
|
||||
|
||||
ARC_Config_AddKeyCString(config, "uint8_t" , 7, ARC_ConfigKey_Read_Uint8_t , ARC_ConfigKey_Delete_Uint8_t );
|
||||
// ARC_Config_AddKeyCString(config, "int8_t" , ARC_ConfigKey_Read_Int8_t , ARC_ConfigKey_Delete_Int8_t );
|
||||
// ARC_Config_AddKeyCString(config, "char" , ARC_ConfigKey_Read_Char , ARC_ConfigKey_Delete_Char );
|
||||
// ARC_Config_AddKeyCString(config, "uint16_t", ARC_ConfigKey_Read_Uint16_t , ARC_ConfigKey_Delete_Uint16_t );
|
||||
// ARC_Config_AddKeyCString(config, "int16_t" , ARC_ConfigKey_Read_Int16_t , ARC_ConfigKey_Delete_Int16_t );
|
||||
// ARC_Config_AddKeyCString(config, "uint32_t", ARC_ConfigKey_Read_Uint32_t , ARC_ConfigKey_Delete_Uint32_t );
|
||||
// ARC_Config_AddKeyCString(config, "int32_t" , ARC_ConfigKey_Read_Int32_t , ARC_ConfigKey_Delete_Int32_t );
|
||||
// ARC_Config_AddKeyCString(config, "int" , ARC_ConfigKey_Read_Int , ARC_ConfigKey_Delete_Int );
|
||||
// ARC_Config_AddKeyCString(config, "uint64_t", ARC_ConfigKey_Read_Uint64_t , ARC_ConfigKey_Delete_Uint64_t );
|
||||
// ARC_Config_AddKeyCString(config, "int64_t" , ARC_ConfigKey_Read_Int64_t , ARC_ConfigKey_Delete_Int64_t );
|
||||
// ARC_Config_AddKeyCString(config, "long" , ARC_ConfigKey_Read_Long , ARC_ConfigKey_Delete_Long );
|
||||
// ARC_Config_AddKeyCString(config, "string" , ARC_ConfigKey_Read_String , ARC_ConfigKey_Delete_String );
|
||||
// ARC_Config_AddKeyCString(config, "string[]", ARC_ConfigKey_Read_StringArray, ARC_ConfigKey_Delete_StringArray);
|
||||
}
|
||||
|
||||
int32_t ARC_ConfigKey_Read_Uint8_t(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){
|
||||
uint8_t ARC_ConfigKey_Read_Uint8_t(ARC_Config* config, ARC_String *string, void **value){
|
||||
ARC_String *current;
|
||||
ARC_String_StripEndsWhitespace(string, ¤t);
|
||||
|
||||
ARC_Config_Get(config, current, value);
|
||||
if(*value){
|
||||
return 1;
|
||||
}
|
||||
|
||||
*value = (uint8_t *) malloc(sizeof(uint8_t));
|
||||
*((uint8_t *)(*value)) = (uint8_t) ARC_String_ToUint64_t(data, subdata);
|
||||
*((uint8_t *)(*value)) = (uint8_t) ARC_String_ToUint64_t(string);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t ARC_ConfigKey_Read_Int8_t(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){
|
||||
/*
|
||||
|
||||
void ARC_ConfigKey_Read_Int8_t(ARC_Config* config, ARC_String *string, void **value){
|
||||
*value = (int8_t *) malloc(sizeof(int8_t));
|
||||
*((int8_t *)(*value)) = (int8_t) ARC_String_ToUint64_t(data, subdata);
|
||||
return 0;
|
||||
*((int8_t *)(*value)) = (int8_t) ARC_String_ToUint64_t(string);
|
||||
}
|
||||
|
||||
int32_t ARC_ConfigKey_Read_Char(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){
|
||||
void ARC_ConfigKey_Read_Char(ARC_Config* config, ARC_String *string, void **value){
|
||||
*value = (char *) malloc(sizeof(char));
|
||||
*((char *)(* value)) = (char) *(data + subdata->index);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t ARC_ConfigKey_Read_Uint16_t(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){
|
||||
void ARC_ConfigKey_Read_Uint16_t(ARC_Config* config, ARC_String *string, void **value){
|
||||
*value = (uint16_t *) malloc(sizeof(uint16_t));
|
||||
*((uint16_t *)(*value)) = (uint16_t) ARC_String_ToUint64_t(data, subdata);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t ARC_ConfigKey_Read_Int16_t(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){
|
||||
void ARC_ConfigKey_Read_Int16_t(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){
|
||||
*value = (int16_t *) malloc(sizeof(int16_t));
|
||||
*((int16_t *)(*value)) = (int16_t) ARC_String_ToUint64_t(data, subdata);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t ARC_ConfigKey_Read_Uint32_t(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){
|
||||
void ARC_ConfigKey_Read_Uint32_t(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){
|
||||
*value = (uint32_t *) malloc(sizeof(uint32_t));
|
||||
*((uint32_t *)(*value)) = (uint32_t) ARC_String_ToUint64_t(data, subdata);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t ARC_ConfigKey_Read_Int32_t(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){
|
||||
void ARC_ConfigKey_Read_Int32_t(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){
|
||||
*value = (int32_t *) malloc(sizeof(int32_t));
|
||||
*((int32_t *)(*value)) = (int32_t) ARC_String_ToUint64_t(data, subdata);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t ARC_ConfigKey_Read_Int(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){
|
||||
void ARC_ConfigKey_Read_Int(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){
|
||||
*value = (int *) malloc(sizeof(int));
|
||||
*((int *)(*value)) = (int) ARC_String_ToUint64_t(data, subdata);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t ARC_ConfigKey_Read_Uint64_t(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){
|
||||
void ARC_ConfigKey_Read_Uint64_t(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){
|
||||
*value = (uint64_t *) malloc(sizeof(uint64_t));
|
||||
*((uint64_t *)(*value)) = ARC_String_ToUint64_t(data, subdata);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t ARC_ConfigKey_Read_Int64_t(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){
|
||||
void ARC_ConfigKey_Read_Int64_t(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){
|
||||
*value = (int64_t *) malloc(sizeof(int64_t));
|
||||
*((int64_t *)(*value)) = (int64_t) ARC_String_ToUint64_t(data, subdata);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t ARC_ConfigKey_Read_Long(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){
|
||||
void ARC_ConfigKey_Read_Long(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){
|
||||
*value = (long *) malloc(sizeof(long));
|
||||
*((long *)(*value)) = (long) ARC_String_ToUint64_t(data, subdata);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t ARC_ConfigKey_Read_String(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){
|
||||
void ARC_ConfigKey_Read_String(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){
|
||||
ARC_StringSubstr_StripWhitespaceEnds((char *)data, subdata);
|
||||
if(data[subdata->index] != '"' || data[subdata->index + subdata->length - 1] != '"'){
|
||||
arc_errno = ARC_ERRNO_DATA;
|
||||
return arc_errno;
|
||||
return;
|
||||
}
|
||||
ARC_StringSubstr_StripEnds((char *)data, (char *)"\"", subdata);
|
||||
*value = (char *) malloc(sizeof(char) * (subdata->length + 1));
|
||||
strncpy((char *)(*value), data + subdata->index, subdata->length);
|
||||
((char *)(*value))[subdata->length] = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t ARC_ConfigKey_Read_StringArray(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){
|
||||
void ARC_ConfigKey_Read_StringArray(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){
|
||||
ARC_StringSubstr_StripWhitespaceEnds((char *)data, subdata);
|
||||
if(data[subdata->index] != '{' || data[subdata->index + subdata->length - 1] != '}'){ return ARC_ERRNO_DATA; }
|
||||
subdata->index++;
|
||||
|
|
@ -173,19 +173,23 @@ int32_t ARC_ConfigKey_Read_StringArray(ARC_Config* config, const char *data, ARC
|
|||
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
int32_t ARC_ConfigKey_Delete_Uint8_t (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){ if((uint8_t *)value){ free((uint8_t *)value); } return 0; }
|
||||
int32_t ARC_ConfigKey_Delete_Int8_t (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){ if((int8_t *)value){ free((int8_t *)value); } return 0; }
|
||||
int32_t ARC_ConfigKey_Delete_Char (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){ if((char *)value){ free((char *)value); } return 0; }
|
||||
int32_t ARC_ConfigKey_Delete_Uint16_t (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){ if((uint16_t *)value){ free((uint16_t *)value); } return 0; }
|
||||
int32_t ARC_ConfigKey_Delete_Int16_t (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){ if((int16_t *)value){ free((int16_t *)value); } return 0; }
|
||||
int32_t ARC_ConfigKey_Delete_Uint32_t (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){ if((uint32_t *)value){ free((uint32_t *)value); } return 0; }
|
||||
int32_t ARC_ConfigKey_Delete_Int32_t (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){ if((int32_t *)value){ free((int32_t *)value); } return 0; }
|
||||
int32_t ARC_ConfigKey_Delete_Int (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){ if((int *)value){ free((int *)value); } return 0; }
|
||||
int32_t ARC_ConfigKey_Delete_Uint64_t (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){ if((uint64_t *)value){ free((uint64_t *)value); } return 0; }
|
||||
int32_t ARC_ConfigKey_Delete_Int64_t (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){ if((int64_t *)value){ free((int64_t *)value); } return 0; }
|
||||
int32_t ARC_ConfigKey_Delete_Long (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){ if((long *)value){ free((long *)value); } return 0; }
|
||||
int32_t ARC_ConfigKey_Delete_String (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){ if((char *)value){ free((char *)value); } return 0; }
|
||||
int32_t ARC_ConfigKey_Delete_StringArray(ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){ if((ARC_Array *)value){ free((ARC_Array *)value); } return 0; }
|
||||
void ARC_ConfigKey_Delete_Uint8_t(ARC_Config* config, void *value){
|
||||
free((uint8_t *)value);
|
||||
}
|
||||
|
||||
// void ARC_ConfigKey_Delete_Int8_t (ARC_Config* config, void *value){ if((int8_t *)value){ free((int8_t *)value); } }
|
||||
// void ARC_ConfigKey_Delete_Char (ARC_Config* config, void *value){ if((char *)value){ free((char *)value); } }
|
||||
// void ARC_ConfigKey_Delete_Uint16_t (ARC_Config* config, void *value){ if((uint16_t *)value){ free((uint16_t *)value); } }
|
||||
// void ARC_ConfigKey_Delete_Int16_t (ARC_Config* config, void *value){ if((int16_t *)value){ free((int16_t *)value); } }
|
||||
// void ARC_ConfigKey_Delete_Uint32_t (ARC_Config* config, void *value){ if((uint32_t *)value){ free((uint32_t *)value); } }
|
||||
// void ARC_ConfigKey_Delete_Int32_t (ARC_Config* config, void *value){ if((int32_t *)value){ free((int32_t *)value); } }
|
||||
// void ARC_ConfigKey_Delete_Int (ARC_Config* config, void *value){ if((int *)value){ free((int *)value); } }
|
||||
// void ARC_ConfigKey_Delete_Uint64_t (ARC_Config* config, void *value){ if((uint64_t *)value){ free((uint64_t *)value); } }
|
||||
// void ARC_ConfigKey_Delete_Int64_t (ARC_Config* config, void *value){ if((int64_t *)value){ free((int64_t *)value); } }
|
||||
// void ARC_ConfigKey_Delete_Long (ARC_Config* config, void *value){ if((long *)value){ free((long *)value); } }
|
||||
// void ARC_ConfigKey_Delete_String (ARC_Config* config, void *value){ if((char *)value){ free((char *)value); } }
|
||||
// void ARC_ConfigKey_Delete_StringArray(ARC_Config* config, void *value){ if((ARC_Array *)value){ free((ARC_Array *)value); } }
|
||||
|
||||
#endif //ARC_DEFAULT_CONFIG
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ struct ARC_Hashtable {
|
|||
ARC_Hashtable_KeyCompare compare;
|
||||
};
|
||||
|
||||
int32_t CRC32(void *key, size_t *keysize, uint32_t *hashval){
|
||||
void CRC32(void *key, size_t *keysize, uint32_t *hashval){
|
||||
*hashval = 0xffffffff;
|
||||
|
||||
for(size_t i = 0; i < *keysize; i++){
|
||||
|
|
@ -25,10 +25,9 @@ int32_t CRC32(void *key, size_t *keysize, uint32_t *hashval){
|
|||
}
|
||||
|
||||
*hashval = ~*hashval;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t ARC_Default_Key_Compare(void *key1, size_t *key1size, void *key2, size_t *key2size){
|
||||
int8_t ARC_Default_Key_Compare(void *key1, size_t *key1size, void *key2, size_t *key2size){
|
||||
return key1 - key2;
|
||||
}
|
||||
|
||||
|
|
@ -40,17 +39,18 @@ void ARC_HashtableNode_Create(ARC_HashtableNode **node, void *key, size_t *keysi
|
|||
(*node)->node = NULL;
|
||||
}
|
||||
|
||||
int32_t ARC_HashtableNode_Destroy(ARC_HashtableNode *node, ARC_HashtableNode_DestroyExternal external, void *userdata){
|
||||
if(node == NULL){ return 0; }
|
||||
void ARC_HashtableNode_Destroy(ARC_HashtableNode *node, ARC_HashtableNode_DestroyExternal external, void *userdata){
|
||||
if(node == NULL){
|
||||
return;
|
||||
}
|
||||
|
||||
ARC_HashtableNode_Destroy(node->node, external, userdata);
|
||||
|
||||
if(external){
|
||||
int32_t err = external(node, userdata);
|
||||
if(err){ return err; }
|
||||
external(node, userdata);
|
||||
}
|
||||
|
||||
free(node);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ARC_Hashtable_Create(ARC_Hashtable **htable, uint32_t bucketsize, ARC_Hashtable_Hash hash, ARC_Hashtable_KeyCompare compare){
|
||||
|
|
@ -61,89 +61,93 @@ void ARC_Hashtable_Create(ARC_Hashtable **htable, uint32_t bucketsize, ARC_Hasht
|
|||
(*htable)->compare = (compare)? compare : ARC_Default_Key_Compare;
|
||||
}
|
||||
|
||||
int32_t ARC_Hashtable_Destroy(ARC_Hashtable *htable, ARC_HashtableNode_DestroyExternal external, void *userdata){
|
||||
void ARC_Hashtable_Destroy(ARC_Hashtable *htable, ARC_HashtableNode_DestroyExternal external, void *userdata){
|
||||
for(uint32_t i = 0; i < htable->size; i++){
|
||||
if(htable->nodes[i]){
|
||||
int32_t err = ARC_HashtableNode_Destroy(htable->nodes[i], external, userdata);
|
||||
if(err){ return err; }
|
||||
ARC_HashtableNode_Destroy(htable->nodes[i], external, userdata);
|
||||
}
|
||||
}
|
||||
|
||||
free(htable->nodes);
|
||||
free(htable);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t ARC_Hashtable_Add(ARC_Hashtable *htable, void *key, size_t keysize, void *data){
|
||||
void ARC_Hashtable_Add(ARC_Hashtable *htable, void *key, size_t keysize, void *data){
|
||||
uint32_t size = 0;
|
||||
int32_t err = htable->hash(key, &keysize, &size);
|
||||
if(err){ return err; }
|
||||
htable->hash(key, &keysize, &size);
|
||||
|
||||
ARC_HashtableNode *bucket = htable->nodes[size % htable->size];
|
||||
if(!bucket){
|
||||
ARC_HashtableNode_Create(&bucket, key, &keysize, data);
|
||||
htable->nodes[size % htable->size] = bucket;
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if(!htable->compare(bucket->key, &bucket->keysize, key, &keysize)){ return ARC_ERRNO_EXISTS; }
|
||||
if(!htable->compare(bucket->key, &bucket->keysize, key, &keysize)){
|
||||
arc_errno = ARC_ERRNO_EXISTS;
|
||||
return;
|
||||
}
|
||||
|
||||
while(bucket->node){
|
||||
if(!htable->compare(bucket->node->key, &bucket->node->keysize, key, &keysize)){ return ARC_ERRNO_EXISTS; }
|
||||
if(!htable->compare(bucket->node->key, &bucket->node->keysize, key, &keysize)){
|
||||
arc_errno = ARC_ERRNO_EXISTS;
|
||||
return;
|
||||
}
|
||||
|
||||
bucket = bucket->node;
|
||||
}
|
||||
|
||||
ARC_HashtableNode_Create(&(bucket->node), key, &keysize, data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t ARC_Hashtable_Get(ARC_Hashtable *htable, void *key, size_t keysize, void **data){
|
||||
void ARC_Hashtable_Get(ARC_Hashtable *htable, void *key, size_t keysize, void **data){
|
||||
uint32_t size = 0;
|
||||
int32_t err = htable->hash(key, &keysize, &size);
|
||||
if(err){ return err; }
|
||||
htable->hash(key, &keysize, &size);
|
||||
|
||||
ARC_HashtableNode *bucket = htable->nodes[size % htable->size];
|
||||
if(!bucket){
|
||||
*data = NULL;
|
||||
return ARC_ERRNO_NULL;
|
||||
arc_errno = ARC_ERRNO_NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if(!htable->compare(bucket->key, &bucket->keysize, key, &keysize)){
|
||||
*data = bucket->data;
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
while(bucket->node){
|
||||
if(!htable->compare(bucket->node->key, &bucket->node->keysize, key, &keysize)){
|
||||
*data = bucket->node->data;
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
bucket = bucket->node;
|
||||
}
|
||||
|
||||
return ARC_ERRNO_NULL;
|
||||
arc_errno = ARC_ERRNO_NULL;
|
||||
}
|
||||
|
||||
int32_t ARC_Hashtable_Remove(ARC_Hashtable *htable, void *key, size_t keysize, ARC_HashtableNode_DestroyExternal external, void *userdata){
|
||||
void ARC_Hashtable_Remove(ARC_Hashtable *htable, void *key, size_t keysize, ARC_HashtableNode_DestroyExternal external, void *userdata){
|
||||
uint32_t size = 0;
|
||||
int32_t err = htable->hash(key, &keysize, &size);
|
||||
if(err){ return err; }
|
||||
htable->hash(key, &keysize, &size);
|
||||
|
||||
ARC_HashtableNode *bucket = htable->nodes[size % htable->size];
|
||||
if(!bucket){ return ARC_ERRNO_NULL; }
|
||||
if(!bucket){
|
||||
arc_errno = ARC_ERRNO_NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if(!htable->compare(bucket->key, &bucket->keysize, key, &keysize)){
|
||||
ARC_HashtableNode *temp = bucket;
|
||||
htable->nodes[size % htable->size] = bucket->node;
|
||||
|
||||
if(external){
|
||||
err = external(temp, userdata);
|
||||
if(err){ return err; }
|
||||
external(temp, userdata);
|
||||
}
|
||||
|
||||
free(temp);
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
while(bucket->node){
|
||||
|
|
@ -152,16 +156,15 @@ int32_t ARC_Hashtable_Remove(ARC_Hashtable *htable, void *key, size_t keysize, A
|
|||
bucket->node = bucket->node->node;
|
||||
|
||||
if(external){
|
||||
err = external(temp, userdata);
|
||||
if(err){ return err; }
|
||||
external(temp, userdata);
|
||||
}
|
||||
|
||||
free(temp);
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
bucket = bucket->node;
|
||||
}
|
||||
|
||||
return ARC_ERRNO_NULL;
|
||||
arc_errno = ARC_ERRNO_NULL;
|
||||
}
|
||||
|
|
|
|||
44
src/std/io.c
44
src/std/io.c
|
|
@ -1,28 +1,36 @@
|
|||
#include "arc/std/io.h"
|
||||
|
||||
#include "arc/std/errno.h"
|
||||
#include "arc/std/string.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int32_t ARC_IO_FileToStr(const char *path, char **data, uint64_t *size){
|
||||
FILE *file = fopen(path, "rb");
|
||||
if(!file){ return ARC_ERRNO_NULL; }
|
||||
void ARC_IO_FileToStr(ARC_String *path, ARC_String **data){
|
||||
FILE *file = fopen(path->data, "rb");
|
||||
if(!file){
|
||||
return;
|
||||
arc_errno = ARC_ERRNO_NULL;
|
||||
}
|
||||
|
||||
fseek(file, 0L, SEEK_END);
|
||||
*size = ftell(file);
|
||||
rewind(file);
|
||||
fseek(file, 0L, SEEK_END);
|
||||
uint64_t length = ftell(file);
|
||||
rewind(file);
|
||||
|
||||
char *fileData = (char *) calloc(1, length + 1);
|
||||
if(fileData == NULL){
|
||||
fclose(file);
|
||||
arc_errno = ARC_ERRNO_NULL;
|
||||
*data = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if(1 != fread(fileData, length, 1, file)){
|
||||
fclose(file);
|
||||
arc_errno = ARC_ERRNO_COPY;
|
||||
*data = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
*data = (char *) calloc(1, *size + 1);
|
||||
if(!*data){
|
||||
fclose(file);
|
||||
return ARC_ERRNO_NULL;
|
||||
}
|
||||
|
||||
if(1 != fread(*data, *size, 1, file)){
|
||||
fclose(file);
|
||||
return ARC_ERRNO_COPY;
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
return 0;
|
||||
ARC_String_Create(data, fileData, length);
|
||||
}
|
||||
|
|
|
|||
402
src/std/string.c
402
src/std/string.c
|
|
@ -1,115 +1,379 @@
|
|||
#include "arc/std/string.h"
|
||||
|
||||
#include "arc/std/errno.h"
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
uint8_t ARC_String_Alpha(char *val, uint64_t length){
|
||||
for(; length; length--){
|
||||
if(val[length - 1] >= 'a' && val[length - 1] <= 'z'){ continue; }
|
||||
if(val[length - 1] >= 'A' && val[length - 1] <= 'Z'){ continue; }
|
||||
void ARC_String_Create(ARC_String **string, char *data, uint64_t length){
|
||||
*string = (ARC_String *)malloc(sizeof(ARC_String));
|
||||
(*string)->data = (char *)malloc(length + 1);
|
||||
(*string)->length = length;
|
||||
|
||||
strncpy((*string)->data, data, length);
|
||||
(*string)->data[length] = '\0';
|
||||
}
|
||||
|
||||
void ARC_String_Destroy(ARC_String *string){
|
||||
free(string->data);
|
||||
free(string);
|
||||
}
|
||||
|
||||
void ARC_String_Copy(ARC_String **copy, ARC_String *original){
|
||||
if(!original){
|
||||
arc_errno = ARC_ERRNO_NULL;
|
||||
*copy = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
ARC_String_Create(copy, original->data, original->length);
|
||||
}
|
||||
|
||||
void ARC_String_CopySubstring(ARC_String **substring, ARC_String *original, uint64_t start, uint64_t length){
|
||||
if(!original){
|
||||
arc_errno = ARC_ERRNO_NULL;
|
||||
*substring = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if(length == 0){
|
||||
*substring = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if(start + length > original->length){
|
||||
arc_errno = ARC_ERRNO_DATA;
|
||||
*substring = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
char data[length];
|
||||
for(uint32_t i = 0; i < length; i++){
|
||||
data[i] = 0;
|
||||
}
|
||||
|
||||
strncpy(data, original->data + start, length);
|
||||
|
||||
ARC_String_Create(substring, data, length);
|
||||
}
|
||||
|
||||
void ARC_String_RemoveSubstring(ARC_String **newString, ARC_String *original, ARC_String *substring){
|
||||
uint64_t index = ARC_String_Find(original, substring);
|
||||
if(arc_errno){
|
||||
newString = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
ARC_String_RemoveSection(newString, original, index, original->length);
|
||||
}
|
||||
|
||||
uint8_t ARC_String_Equals(ARC_String *first, ARC_String *second){
|
||||
if(first->length != second->length){
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(strncmp(first->data, second->data, first->length)){
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t ARC_String_EqualsCString(ARC_String *string, const char *cstring, uint64_t length){
|
||||
if(string->length != length){
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(strncmp(string->data, cstring, string->length)){
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t ARC_String_Alpha(ARC_String *string){
|
||||
for(uint64_t length = string->length; length; length--){
|
||||
if(string->data[length - 1] >= 'a' && string->data[length - 1] <= 'z'){
|
||||
continue;
|
||||
}
|
||||
|
||||
if(string->data[length - 1] >= 'A' && string->data[length - 1] <= 'Z'){
|
||||
continue;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t ARC_String_ToUint64_t(const char *data, ARC_StringSubstr *substr){
|
||||
char temp[substr->length + 1];
|
||||
strncpy(temp, data + substr->index, substr->length);
|
||||
temp[substr->length] = '\0';
|
||||
uint64_t ARC_String_ToUint64_t(ARC_String *string){
|
||||
char temp[string->length + 1];
|
||||
strncpy(temp, string->data, string->length);
|
||||
temp[string->length] = '\0';
|
||||
|
||||
return (uint64_t) strtoul(temp, NULL, 10);
|
||||
}
|
||||
|
||||
int32_t ARC_String_Find(char *data, char *substr, uint64_t *index){
|
||||
if(!data || !substr){ return ARC_ERRNO_NULL; }
|
||||
uint64_t ARC_String_Find(ARC_String *string, ARC_String *substring){
|
||||
if(!string || !substring){
|
||||
arc_errno = ARC_ERRNO_NULL;
|
||||
return ~(uint64_t)0;
|
||||
}
|
||||
|
||||
uint64_t max = strlen(data);
|
||||
uint64_t sub = strlen(substr);
|
||||
if(!max || !sub || sub > max){ return ARC_ERRNO_DATA; }
|
||||
if(substring->length > string->length){
|
||||
return ~(uint64_t)0;
|
||||
}
|
||||
|
||||
max -= sub - 1;
|
||||
uint64_t max = string->length - (substring->length - 1);
|
||||
for(uint64_t i = 0; max; i++, max--){
|
||||
if(!strncmp(data + i, substr, sub)){
|
||||
*index = i;
|
||||
return 0;
|
||||
if(!strncmp(string->data + i, substring->data, substring->length)){
|
||||
return i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
*index = ~((uint64_t)0);
|
||||
return 0;
|
||||
return ~(uint64_t)0;
|
||||
}
|
||||
|
||||
int32_t ARC_String_FindBack(char *data, char *substr, uint64_t *index){
|
||||
if(!data || !substr){ return ARC_ERRNO_NULL; }
|
||||
uint64_t ARC_String_FindCString(ARC_String *string, const char *cstring, uint64_t length){
|
||||
if(!string || !cstring){
|
||||
arc_errno = ARC_ERRNO_NULL;
|
||||
return ~(uint64_t)0;
|
||||
}
|
||||
|
||||
uint64_t max = strlen(data);
|
||||
uint64_t sub = strlen(substr);
|
||||
if(!max || !sub || sub > max){ return ARC_ERRNO_DATA; }
|
||||
if(string->length < length){
|
||||
return ~(uint64_t)0;
|
||||
}
|
||||
|
||||
max -= sub - 1;
|
||||
for(; max; max--){
|
||||
if(!strncmp(data + (max - 1), substr, sub)){
|
||||
*index = max;
|
||||
return 0;
|
||||
uint64_t max = string->length - (length - 1);
|
||||
for(uint64_t i = 0; i < max; i++){
|
||||
if(!strncmp(string->data + i, cstring, length)){
|
||||
return i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
*index = ~((uint64_t)0);
|
||||
return 0;
|
||||
return ~(uint64_t)0;
|
||||
}
|
||||
|
||||
int32_t ARC_StringSubstr_StripEnds(char *data, char *substr, ARC_StringSubstr *subdata){
|
||||
if(!subdata){ return ARC_ERRNO_NULL; }
|
||||
if(!substr){ substr = (char *)" "; }
|
||||
uint64_t ARC_String_FindBack(ARC_String *string, ARC_String *substring){
|
||||
if(!string || !substring){
|
||||
arc_errno = ARC_ERRNO_NULL;
|
||||
return ~(uint64_t)0;
|
||||
}
|
||||
|
||||
subdata->length = (subdata->length)? subdata->length : strlen(data);
|
||||
uint64_t max = subdata->length;
|
||||
uint64_t sub = strlen(substr);
|
||||
if(!max || !sub || sub > max){ return ARC_ERRNO_DATA; }
|
||||
if(substring->length > string->length){
|
||||
return ~(uint64_t)0;
|
||||
}
|
||||
|
||||
max -= sub - 1;
|
||||
uint64_t max = string->length - (substring->length - 1);
|
||||
for(; max; max--){
|
||||
if(strncmp(data + subdata->index + (max - 1), substr, sub)){
|
||||
subdata->length = max;
|
||||
if(!strncmp(string->data + (max - 1), substring->data, substring->length)){
|
||||
return max;
|
||||
}
|
||||
}
|
||||
|
||||
return ~(uint64_t)0;
|
||||
}
|
||||
|
||||
void ARC_String_StripEnds(ARC_String *original, ARC_String **stripped, char charToStrip){
|
||||
if(!original){
|
||||
arc_errno = ARC_ERRNO_NULL;
|
||||
*stripped = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if(!original->length){
|
||||
arc_errno = ARC_ERRNO_DATA;
|
||||
*stripped = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t length = original->length - 1;
|
||||
for(; length; length--){
|
||||
if(strncmp(original->data + (length - 1), &charToStrip, 1)){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
max = subdata->length - (sub - 1);
|
||||
for(uint64_t i = 0; max; i++, max--){
|
||||
if(strncmp(data + subdata->index + i, substr, sub)){
|
||||
subdata->index += i;
|
||||
subdata->length -= i;
|
||||
return 0;
|
||||
}
|
||||
if(!length){
|
||||
arc_errno = ARC_ERRNO_DATA;
|
||||
*stripped = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t ARC_StringSubstr_StripWhitespaceEnds(char *data, ARC_StringSubstr *subdata){
|
||||
if(!subdata){ return ARC_ERRNO_NULL; }
|
||||
|
||||
subdata->length = (subdata->length)? subdata->length : strlen(data);
|
||||
uint64_t max = subdata->length;
|
||||
if(!max){ return ARC_ERRNO_DATA; }
|
||||
|
||||
for(; max; max--){
|
||||
if(data[subdata->index + (max - 1)] != ' ' && data[subdata->index + (max - 1)] != '\n' && data[subdata->index + (max - 1)] != '\t' && data[subdata->index + (max - 1)] != '\r'){
|
||||
subdata->length = max;
|
||||
uint64_t start = 0;
|
||||
for(; start <= length; start++){
|
||||
if(strncmp(original->data + start, &charToStrip, 1)){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
max = subdata->length;
|
||||
for(uint64_t i = 0; max; i++, max--){
|
||||
if(data[subdata->index + i] != ' ' && data[subdata->index + i] != '\n' && data[subdata->index + i] != '\t' && data[subdata->index + i] != '\r'){
|
||||
subdata->index += i;
|
||||
subdata->length -= i;
|
||||
return 0;
|
||||
}
|
||||
if(start == length){
|
||||
arc_errno = ARC_ERRNO_DATA;
|
||||
*stripped = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
return 0;
|
||||
length -= start;
|
||||
ARC_String_Create(stripped, original->data + start, length);
|
||||
}
|
||||
|
||||
void ARC_String_StripWhitespace(ARC_String *original, ARC_String **stripped){
|
||||
if(!original){
|
||||
arc_errno = ARC_ERRNO_NULL;
|
||||
*stripped = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if(!original->length){
|
||||
arc_errno = ARC_ERRNO_DATA;
|
||||
*stripped = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t length = 0;
|
||||
for(uint64_t i = 0; i < original->length; i++){
|
||||
if(original->data[i] == ' '){
|
||||
continue;
|
||||
}
|
||||
|
||||
if(original->data[i] == '\n'){
|
||||
continue;
|
||||
}
|
||||
|
||||
if(original->data[i] == '\t'){
|
||||
continue;
|
||||
}
|
||||
|
||||
if(original->data[i] == '\r'){
|
||||
continue;
|
||||
}
|
||||
|
||||
length++;
|
||||
}
|
||||
|
||||
if(!length){
|
||||
arc_errno = ARC_ERRNO_DATA;
|
||||
*stripped = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
length++;
|
||||
char data[length];
|
||||
for(uint32_t i = 0; i < length; i++){
|
||||
data[i] = 0;
|
||||
}
|
||||
|
||||
uint64_t start = 0;
|
||||
for(uint64_t i = 0; i < length; i++){
|
||||
if(original->data[i] == ' '){
|
||||
continue;
|
||||
}
|
||||
|
||||
if(original->data[i] == '\n'){
|
||||
continue;
|
||||
}
|
||||
|
||||
if(original->data[i] == '\t'){
|
||||
continue;
|
||||
}
|
||||
|
||||
if(original->data[i] == '\r'){
|
||||
continue;
|
||||
}
|
||||
|
||||
data[start] = original->data[i];
|
||||
start++;
|
||||
}
|
||||
|
||||
ARC_String_Create(stripped, data, length);
|
||||
}
|
||||
|
||||
|
||||
void ARC_String_StripEndsWhitespace(ARC_String *original, ARC_String **stripped){
|
||||
uint64_t index;
|
||||
for(uint64_t i = 0; i < original->length; i++){
|
||||
if(original->data[i] == ' '){
|
||||
continue;
|
||||
}
|
||||
|
||||
if(original->data[i] == '\n'){
|
||||
continue;
|
||||
}
|
||||
|
||||
if(original->data[i] == '\t'){
|
||||
continue;
|
||||
}
|
||||
|
||||
if(original->data[i] == '\r'){
|
||||
continue;
|
||||
}
|
||||
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
|
||||
uint64_t endIndex;
|
||||
for(uint64_t i = original->length; i > 0; i--){
|
||||
if(original->data[i - 1] == ' '){
|
||||
continue;
|
||||
}
|
||||
|
||||
if(original->data[i - 1] == '\n'){
|
||||
continue;
|
||||
}
|
||||
|
||||
if(original->data[i - 1] == '\t'){
|
||||
continue;
|
||||
}
|
||||
|
||||
if(original->data[i - 1] == '\r'){
|
||||
continue;
|
||||
}
|
||||
|
||||
endIndex = i;
|
||||
break;
|
||||
}
|
||||
|
||||
ARC_String_CopySubstring(stripped, original, index, endIndex - index);
|
||||
}
|
||||
|
||||
void ARC_String_Merge(ARC_String *first, ARC_String *second, ARC_String **combined){
|
||||
char data[first->length + second->length];
|
||||
for(uint32_t i = 0; i < first->length; i++){
|
||||
data[i] = first->data[i];
|
||||
}
|
||||
|
||||
for(uint32_t i = 0; i < second->length; i++){
|
||||
data[i + first->length] = second->data[i];
|
||||
}
|
||||
|
||||
ARC_String_Create(combined, data, first->length + second->length);
|
||||
}
|
||||
|
||||
|
||||
void ARC_String_RemoveSection(ARC_String **newString, ARC_String *original, uint64_t removeIndex, uint64_t removeLength){
|
||||
if(removeIndex == 0 && removeIndex + removeLength >= original->length){
|
||||
ARC_String_Copy(newString, original);
|
||||
return;
|
||||
}
|
||||
|
||||
if(removeIndex == 0){
|
||||
ARC_String_CopySubstring(newString, original, removeLength, original->length - removeLength);
|
||||
return;
|
||||
}
|
||||
|
||||
if(removeIndex + removeLength >= original->length){
|
||||
ARC_String_CopySubstring(newString, original, 0, removeIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
ARC_String *first, *second;
|
||||
ARC_String_CopySubstring(&first , original, 0 , removeIndex );
|
||||
ARC_String_CopySubstring(&second, original, removeIndex + removeLength, original->length - (removeIndex + removeLength));
|
||||
|
||||
ARC_String_Merge(first, second, newString);
|
||||
|
||||
ARC_String_Destroy(first );
|
||||
ARC_String_Destroy(second);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue