Compare commits
10 commits
3fbccd9752
...
6085d22df4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6085d22df4 | ||
|
|
c078ce907f | ||
|
|
ba09aff914 | ||
|
|
ccf13ba470 | ||
|
|
04c89e46fe | ||
|
|
30e8d94805 | ||
|
|
67c69dac8d | ||
|
|
990c22d27d | ||
|
|
e698fb54a2 | ||
|
|
ba467ac6b6 |
18 changed files with 1774 additions and 1638 deletions
|
|
@ -62,7 +62,8 @@ set(ARCHEUS_LINK_LIBRARIES
|
||||||
|
|
||||||
# ~ ARCHEUS_SOURCES ~ #
|
# ~ ARCHEUS_SOURCES ~ #
|
||||||
set(ARCHEUS_SOURCES
|
set(ARCHEUS_SOURCES
|
||||||
src/std/chemical.c
|
src/std/config.c
|
||||||
|
src/std/entity.c
|
||||||
src/std/errno.c
|
src/std/errno.c
|
||||||
src/std/handler.c
|
src/std/handler.c
|
||||||
src/std/hashtable.c
|
src/std/hashtable.c
|
||||||
|
|
@ -77,6 +78,7 @@ set(ARCHEUS_SOURCES
|
||||||
src/std/string.c
|
src/std/string.c
|
||||||
src/std/time.c
|
src/std/time.c
|
||||||
src/std/vector.c
|
src/std/vector.c
|
||||||
|
src/std/vector/inline.c
|
||||||
|
|
||||||
src/math/circle.c
|
src/math/circle.c
|
||||||
src/math/obround.c
|
src/math/obround.c
|
||||||
|
|
@ -128,13 +130,15 @@ if(ARCHEUS_TESTS)
|
||||||
add_executable(tests
|
add_executable(tests
|
||||||
tests/test.c
|
tests/test.c
|
||||||
|
|
||||||
tests/std/chemical.c
|
#tests/std/config.c
|
||||||
|
#tests/std/entity.c
|
||||||
#tests/std/hashtable.c
|
#tests/std/hashtable.c
|
||||||
#tests/std/lexer.c
|
#tests/std/lexer.c
|
||||||
#tests/std/parser.c
|
#tests/std/parser.c
|
||||||
#tests/std/parser/csv.c
|
#tests/std/parser/csv.c
|
||||||
#tests/std/parser/parserlang.c
|
#tests/std/parser/parserlang.c
|
||||||
#tests/std/vector.c
|
#tests/std/vector.c
|
||||||
|
tests/std/vector/inline.c
|
||||||
|
|
||||||
${ARCHEUS_SOURCES}
|
${ARCHEUS_SOURCES}
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,204 +0,0 @@
|
||||||
#ifndef ARC_STD_PARSER_CHEMICAL_H_
|
|
||||||
#define ARC_STD_PARSER_CHEMICAL_H_
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "arc/std/parser.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief the config type for archeus, loads in a config file which syntax is specified in the documentation
|
|
||||||
* @TODO: add documentation link here
|
|
||||||
*/
|
|
||||||
typedef struct ARC_Chemical ARC_Chemical;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief a function callback to create a type stored within a config
|
|
||||||
*/
|
|
||||||
typedef void (* ARC_ChemicalType_CopyFn)(void **type, ARC_ParserTagToken *parsedData, ARC_Chemical *chemical);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief a function callback to destroy a type
|
|
||||||
*/
|
|
||||||
typedef void (* ARC_ChemicalType_DestroyFn)(void *type);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief the functions for used for loading and unloading a type, the name will be the key of a hashtable
|
|
||||||
*/
|
|
||||||
typedef struct ARC_ChemicalType {
|
|
||||||
ARC_ChemicalType_CopyFn copyFn;
|
|
||||||
ARC_ChemicalType_DestroyFn destroyFn;
|
|
||||||
} ARC_ChemicalType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief creates the arc config type (a type that loads in chemical files and can have types added to it)
|
|
||||||
*/
|
|
||||||
void ARC_Chemical_Create(ARC_Chemical **chemical);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief destroys an ARC_Chemical type
|
|
||||||
*/
|
|
||||||
void ARC_Chemical_Destroy(ARC_Chemical *chemical);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief adds creation and destruction functions for a new user provided type will be used for chemical load and unload functions
|
|
||||||
*
|
|
||||||
* @note this function uses ARC_Chemical_RegisterTypeWithCStr so it shares error messages with that function
|
|
||||||
*
|
|
||||||
* @param[in] chemical the ARC_Chemical to set the new type into
|
|
||||||
* @param[in] typeName the name of the type like "uint32" or "ARC_Rect" that will be read in from a chemical file
|
|
||||||
* @param[in] type the copy and destroy functions for the type used on load and unload
|
|
||||||
*/
|
|
||||||
void ARC_Chemical_RegisterType(ARC_Chemical *chemical, ARC_String *typeName, ARC_ChemicalType type);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief adds creation and destruction functions for a new user provided type
|
|
||||||
*
|
|
||||||
* @param[in] chemical the ARC_Chemical to set the new type into
|
|
||||||
* @param[in] typeName the name of the type like "uint32" or "ARC_Rect" that will be read in from a chemical file
|
|
||||||
* @param[in] type the copy and destroy functions for the type used on load and unload
|
|
||||||
*/
|
|
||||||
void ARC_Chemical_RegisterTypeWithCStr(ARC_Chemical *chemical, const char *typeNameCStr, ARC_ChemicalType type);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief sets current group in config
|
|
||||||
*
|
|
||||||
* @note ARC_Chemical_Get will use this set group
|
|
||||||
* @note this function uses ARC_Chemical_SetGroupWithCStr so it shares error messages with that function
|
|
||||||
*
|
|
||||||
* @param[in] chemical ARC_Config we are setting current group in
|
|
||||||
* @param[in] groupname name of group that will be set
|
|
||||||
*/
|
|
||||||
void ARC_Chemical_SetGroup(ARC_Chemical *chemical, ARC_String *groupName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief sets current group in config
|
|
||||||
*
|
|
||||||
* @note ARC_Chemical_Get will use this set group
|
|
||||||
*
|
|
||||||
* @param[in] chemical ARC_Config we are setting current group in
|
|
||||||
* @param[in] groupname name of group that will be set
|
|
||||||
*/
|
|
||||||
void ARC_Chemical_SetGroupWithCStr(ARC_Chemical *chemical, const char *groupName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief get a value from a given keyname
|
|
||||||
*
|
|
||||||
* @note name may be prefaced with <group>:: to specify group
|
|
||||||
*
|
|
||||||
* @param[in] chemical ARC_Chemical to get value from
|
|
||||||
* @param[in] element name of a variable that has been read in
|
|
||||||
*
|
|
||||||
* @return the stored element on success, or NULL on failure
|
|
||||||
*/
|
|
||||||
void *ARC_Chemical_Get(ARC_Chemical *chemical, ARC_String *element);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief get a value from a given keyname
|
|
||||||
*
|
|
||||||
* @note name may be prefaced with <group>:: to specify group
|
|
||||||
* @note this function uses ARC_Chemical_Get so it shares error messages with that function
|
|
||||||
*
|
|
||||||
* @param[in] chemical ARC_Chemical to get value from
|
|
||||||
* @param[in] element name of a variable that has been read in
|
|
||||||
*
|
|
||||||
* @return the stored element on success, or NULL on failure
|
|
||||||
*/
|
|
||||||
void *ARC_Chemical_GetWithCStr(ARC_Chemical *chemical, const char *element);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief TODO: write this
|
|
||||||
*/
|
|
||||||
void ARC_Chemical_LoadFromString(ARC_Chemical *chemical, ARC_String **string);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief TODO: write this
|
|
||||||
*/
|
|
||||||
void ARC_Chemical_LoadFromFile(ARC_Chemical *chemical, ARC_String *path);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief TODO: write this
|
|
||||||
*/
|
|
||||||
void ARC_Chemical_UnloadFromString(ARC_Chemical *chemical, ARC_String **string);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief TODO: write this
|
|
||||||
*/
|
|
||||||
void ARC_Chemical_UnloadFromFile(ARC_Chemical *chemical, ARC_String *data);
|
|
||||||
|
|
||||||
#define ARC_CHEMICAL_DEFAULT_GROUP " "
|
|
||||||
#define ARC_CHEMICAL_GROUP_TAG_NAME "group"
|
|
||||||
#define ARC_CHEMICAL_GROUP_SEPARATOR "::"
|
|
||||||
|
|
||||||
//the grouping is based on the ascii table, but the ids are sequential to make finding tokens quicker (look at the lexer continious for more explanation)
|
|
||||||
#define ARC_CHEMICAL_TAB 0x01
|
|
||||||
#define ARC_CHEMICAL_NEWLINE 0x02
|
|
||||||
|
|
||||||
#define ARC_CHEMICAL_SPACE 0x03
|
|
||||||
#define ARC_CHEMICAL_BANG 0x04
|
|
||||||
#define ARC_CHEMICAL_QUOTE 0x05
|
|
||||||
#define ARC_CHEMICAL_HASH 0x06
|
|
||||||
#define ARC_CHEMICAL_DOLLAR 0x07
|
|
||||||
#define ARC_CHEMICAL_PERCENT 0x08
|
|
||||||
#define ARC_CHEMICAL_AMPERSAND 0x09
|
|
||||||
#define ARC_CHEMICAL_SINGLE_QUOTE 0x0A
|
|
||||||
#define ARC_CHEMICAL_OPEN_PAREN 0x0B
|
|
||||||
#define ARC_CHEMICAL_CLOSE_PAREN 0x0C
|
|
||||||
#define ARC_CHEMICAL_ASTERISK 0x0D
|
|
||||||
#define ARC_CHEMICAL_PLUS 0x0E
|
|
||||||
#define ARC_CHEMICAL_COMMA 0x0F
|
|
||||||
#define ARC_CHEMICAL_MINUS 0x10
|
|
||||||
#define ARC_CHEMICAL_PERIOD 0x11
|
|
||||||
#define ARC_CHEMICAL_SLASH 0x12
|
|
||||||
#define ARC_CHEMICAL_NUMBER 0x13
|
|
||||||
|
|
||||||
#define ARC_CHEMICAL_COLON 0x14
|
|
||||||
#define ARC_CHEMICAL_SEMICOLON 0x15
|
|
||||||
#define ARC_CHEMICAL_LESS_THAN 0x16
|
|
||||||
#define ARC_CHEMICAL_GREATER_THAN 0x17
|
|
||||||
#define ARC_CHEMICAL_EQUAL 0x18
|
|
||||||
#define ARC_CHEMICAL_QUESTION_MARK 0x19
|
|
||||||
#define ARC_CHEMICAL_AT 0x1A
|
|
||||||
#define ARC_CHEMICAL_ALPHA_UPPER_CHAR 0x1B
|
|
||||||
|
|
||||||
#define ARC_CHEMICAL_OPEN_BRACKET 0x1C
|
|
||||||
#define ARC_CHEMICAL_BACKSLASH 0x1D
|
|
||||||
#define ARC_CHEMICAL_CLOSE_BRACKET 0x1E
|
|
||||||
#define ARC_CHEMICAL_CARET 0x1F
|
|
||||||
#define ARC_CHEMICAL_UNDERSCORE 0x20
|
|
||||||
#define ARC_CHEMICAL_GRAVE 0x21
|
|
||||||
#define ARC_CHEMICAL_ALPHA_LOWER_CHAR 0x22
|
|
||||||
|
|
||||||
#define ARC_CHEMICAL_OPEN_CURLY_BRACE 0x23
|
|
||||||
#define ARC_CHEMICAL_VERTICAL_LINE 0x24
|
|
||||||
#define ARC_CHEMICAL_CLOSE_CURLY_BRACE 0x25
|
|
||||||
#define ARC_CHEMICAL_TILDE 0x26
|
|
||||||
|
|
||||||
#define ARC_CHEMICAL_LANGUAGE 0x27
|
|
||||||
#define ARC_CHEMICAL_GROUP 0x28
|
|
||||||
#define ARC_CHEMICAL_GROUP_NAME 0x29
|
|
||||||
#define ARC_CHEMICAL_GROUP_ARGS 0x2A
|
|
||||||
#define ARC_CHEMICAL_VARIABLE_LINES 0x2B
|
|
||||||
#define ARC_CHEMICAL_VARIABLE_LINE 0x2C
|
|
||||||
#define ARC_CHEMICAL_ALLOW_SPACE 0x2D
|
|
||||||
#define ARC_CHEMICAL_TYPE 0x2E
|
|
||||||
#define ARC_CHEMICAL_VALUE 0x2F
|
|
||||||
#define ARC_CHEMICAL_NESTED_VALUE 0x30
|
|
||||||
#define ARC_CHEMICAL_VALUE_ARGS 0x31
|
|
||||||
#define ARC_CHEMICAL_VARIABLE 0x32
|
|
||||||
#define ARC_CHEMICAL_VARIABLE_NAME 0x33
|
|
||||||
#define ARC_CHEMICAL_VARIABLE_CHAR 0x34
|
|
||||||
#define ARC_CHEMICAL_STRING 0x35
|
|
||||||
#define ARC_CHEMICAL_STRING_CHARS 0x36
|
|
||||||
#define ARC_CHEMICAL_STRING_CHAR 0x37
|
|
||||||
#define ARC_CHEMICAL_ESCAPE_CHAR 0x38
|
|
||||||
#define ARC_CHEMICAL_WHITESPACE 0x39
|
|
||||||
#define ARC_CHEMICAL_NUMBER_TAG 0x3A
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif //ARC_STD_PARSER_CHEMICAL_H_
|
|
||||||
|
|
@ -5,122 +5,201 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "arc/std/hashtable.h"
|
|
||||||
#include "arc/std/string.h"
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include "arc/std/parser.h"
|
||||||
#define ARC_KEY_BUCKET_SIZE 0x20
|
|
||||||
#define ARC_GROUP_BUCKET_SIZE 0x20
|
|
||||||
#define ARC_GROUP_DATA_BUCKET_SIZE 0x20
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief a type that keeps permanice of data for when loading and unloading config files
|
* @brief the config type for archeus, loads in a config file which syntax is specified in the documentation
|
||||||
|
* @TODO: add documentation link here
|
||||||
*/
|
*/
|
||||||
typedef struct ARC_Config ARC_Config;
|
typedef struct ARC_Config ARC_Config;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief a function to read a key from string to a ARC_ConfigTypeTemplate
|
* @brief a function callback to create a type stored within a config
|
||||||
*
|
|
||||||
* @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 uint8_t (* ARC_ConfigKeyRead)(ARC_Config* config, ARC_String *string, void **value);
|
typedef void (* ARC_ConfigType_CopyFn)(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief a function to delete a value from a key in ARC_Config
|
* @brief a function callback to destroy a type
|
||||||
*
|
|
||||||
* @param config ARC_Config that can be used to check for references in data
|
|
||||||
* @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 void (* ARC_ConfigKeyDelete)(ARC_Config* config, ARC_String *string, void *value);
|
typedef void (* ARC_ConfigType_DestroyFn)(void *type);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief adds a usable key to ARC_Config
|
* @brief the functions for used for loading and unloading a type, the name will be the key of a hashtable
|
||||||
*
|
|
||||||
* @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
|
|
||||||
*/
|
*/
|
||||||
void ARC_Config_AddKey(ARC_Config *config, ARC_String *type, ARC_ConfigKeyRead keyRead, ARC_ConfigKeyDelete keyDelete);
|
typedef struct ARC_ConfigType {
|
||||||
|
ARC_ConfigType_CopyFn copyFn;
|
||||||
|
ARC_ConfigType_DestroyFn destroyFn;
|
||||||
|
} ARC_ConfigType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief adds a key from a cstring
|
* @brief creates the arc config type (a type that loads in config files and can have types added to it)
|
||||||
* @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 void (* ARC_ConfigKey_AddFunc)(ARC_Config *config);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief creates ARC_Config type
|
|
||||||
*
|
|
||||||
* @param config ARC_Config to initialize
|
|
||||||
*/
|
*/
|
||||||
void ARC_Config_Create(ARC_Config **config);
|
void ARC_Config_Create(ARC_Config **config);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief destroys ARC_Config type
|
* @brief destroys an ARC_Config type
|
||||||
*/
|
*/
|
||||||
void ARC_Config_Destroy(ARC_Config *config);
|
void ARC_Config_Destroy(ARC_Config *config);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief adds creation and destruction functions for a new user provided type will be used for config load and unload functions
|
||||||
|
*
|
||||||
|
* @note this function uses ARC_Config_RegisterTypeWithCStr so it shares error messages with that function
|
||||||
|
*
|
||||||
|
* @param[in] config the ARC_Config to set the new type into
|
||||||
|
* @param[in] typeName the name of the type like "uint32" or "ARC_Rect" that will be read in from a config file
|
||||||
|
* @param[in] type the copy and destroy functions for the type used on load and unload
|
||||||
|
*/
|
||||||
|
void ARC_Config_RegisterType(ARC_Config *config, ARC_String *typeName, ARC_ConfigType type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief adds creation and destruction functions for a new user provided type
|
||||||
|
*
|
||||||
|
* @param[in] config the ARC_Config to set the new type into
|
||||||
|
* @param[in] typeName the name of the type like "uint32" or "ARC_Rect" that will be read in from a config file
|
||||||
|
* @param[in] type the copy and destroy functions for the type used on load and unload
|
||||||
|
*/
|
||||||
|
void ARC_Config_RegisterTypeWithCStr(ARC_Config *config, const char *typeNameCStr, ARC_ConfigType type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief sets current group in config
|
||||||
|
*
|
||||||
|
* @note ARC_Config_Get will use this set group
|
||||||
|
* @note this function uses ARC_Config_SetGroupWithCStr so it shares error messages with that function
|
||||||
|
*
|
||||||
|
* @param[in] config ARC_Config we are setting current group in
|
||||||
|
* @param[in] groupname name of group that will be set
|
||||||
|
*/
|
||||||
|
void ARC_Config_SetGroup(ARC_Config *config, ARC_String *groupName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief sets current group in config
|
* @brief sets current group in config
|
||||||
*
|
*
|
||||||
* @note ARC_Config_Get will use this set group
|
* @note ARC_Config_Get will use this set group
|
||||||
*
|
*
|
||||||
* @param config ARC_Config we are setting current group in
|
* @param[in] config ARC_Config we are setting current group in
|
||||||
* @param groupname name of group that will be set
|
* @param[in] groupname name of group that will be set
|
||||||
*/
|
*/
|
||||||
void ARC_Config_SetGroup(ARC_Config *config, ARC_String *groupname);
|
void ARC_Config_SetGroupWithCStr(ARC_Config *config, const char *groupName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief get a value from a given name
|
||||||
|
*
|
||||||
|
* @note name should be prefaced with <group>:: to specify group
|
||||||
|
*
|
||||||
|
* @param[in] config ARC_Config to get value from
|
||||||
|
* @param[in] name name of a variable that has been read in
|
||||||
|
*
|
||||||
|
* @return the stored element on success, or NULL on failure
|
||||||
|
*/
|
||||||
|
void *ARC_Config_Get(ARC_Config *config, ARC_String *name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief get a value from a given keyname
|
* @brief get a value from a given keyname
|
||||||
*
|
*
|
||||||
* @note name may be prefaced with <group>:: to specify group
|
* @note name should be prefaced with <group>:: to specify group
|
||||||
|
* @note this function uses ARC_Config_Get so it shares error messages with that function
|
||||||
*
|
*
|
||||||
* @param config ARC_Config to get value from
|
* @param[in] config ARC_Config to get value from
|
||||||
* @param keyname name of key to get from config
|
* @param[in] name name of a variable that has been read in
|
||||||
* @param value data retrieved from config
|
*
|
||||||
|
* @return the stored element on success, or NULL on failure
|
||||||
*/
|
*/
|
||||||
//void ARC_Config_Get(ARC_Config *config, ARC_String *keyname, void **value);
|
void *ARC_Config_GetWithCStr(ARC_Config *config, const char *name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief commands that can be used in ARC_Config_FileIO
|
* @brief TODO: write this
|
||||||
*/
|
*/
|
||||||
#define ARC_CONFIG_FILE_IO_LOAD 0x00
|
void ARC_Config_LoadFromString(ARC_Config *config, ARC_String **string);
|
||||||
#define ARC_CONFIG_FILE_IO_UNLOAD 0x01
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief handles file io for ARC_Config Type
|
* @brief TODO: write this
|
||||||
*
|
|
||||||
* @param config ARC_Config where io operations will take place
|
|
||||||
* @param path file path for io
|
|
||||||
*/
|
*/
|
||||||
void ARC_Config_FileIO(ARC_Config *config, ARC_String *path, uint8_t command);
|
void ARC_Config_LoadFromFile(ARC_Config *config, ARC_String *path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief TODO: write this
|
||||||
|
*/
|
||||||
|
void ARC_Config_UnloadFromString(ARC_Config *config, ARC_String **string);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief TODO: write this
|
||||||
|
*/
|
||||||
|
void ARC_Config_UnloadFromFile(ARC_Config *config, ARC_String *data);
|
||||||
|
|
||||||
|
#define ARC_CONFIG_DEFAULT_GROUP " "
|
||||||
|
#define ARC_CONFIG_GROUP_TAG_NAME "group"
|
||||||
|
#define ARC_CONFIG_GROUP_SEPARATOR "::"
|
||||||
|
|
||||||
|
//the grouping is based on the ascii table, but the ids are sequential to make finding tokens quicker (look at the lexer continious for more explanation)
|
||||||
|
#define ARC_CONFIG_TAB 0x01
|
||||||
|
#define ARC_CONFIG_NEWLINE 0x02
|
||||||
|
|
||||||
|
#define ARC_CONFIG_SPACE 0x03
|
||||||
|
#define ARC_CONFIG_BANG 0x04
|
||||||
|
#define ARC_CONFIG_QUOTE 0x05
|
||||||
|
#define ARC_CONFIG_HASH 0x06
|
||||||
|
#define ARC_CONFIG_DOLLAR 0x07
|
||||||
|
#define ARC_CONFIG_PERCENT 0x08
|
||||||
|
#define ARC_CONFIG_AMPERSAND 0x09
|
||||||
|
#define ARC_CONFIG_SINGLE_QUOTE 0x0A
|
||||||
|
#define ARC_CONFIG_OPEN_PAREN 0x0B
|
||||||
|
#define ARC_CONFIG_CLOSE_PAREN 0x0C
|
||||||
|
#define ARC_CONFIG_ASTERISK 0x0D
|
||||||
|
#define ARC_CONFIG_PLUS 0x0E
|
||||||
|
#define ARC_CONFIG_COMMA 0x0F
|
||||||
|
#define ARC_CONFIG_MINUS 0x10
|
||||||
|
#define ARC_CONFIG_PERIOD 0x11
|
||||||
|
#define ARC_CONFIG_SLASH 0x12
|
||||||
|
#define ARC_CONFIG_NUMBER 0x13
|
||||||
|
|
||||||
|
#define ARC_CONFIG_COLON 0x14
|
||||||
|
#define ARC_CONFIG_SEMICOLON 0x15
|
||||||
|
#define ARC_CONFIG_LESS_THAN 0x16
|
||||||
|
#define ARC_CONFIG_GREATER_THAN 0x17
|
||||||
|
#define ARC_CONFIG_EQUAL 0x18
|
||||||
|
#define ARC_CONFIG_QUESTION_MARK 0x19
|
||||||
|
#define ARC_CONFIG_AT 0x1A
|
||||||
|
#define ARC_CONFIG_ALPHA_UPPER_CHAR 0x1B
|
||||||
|
|
||||||
|
#define ARC_CONFIG_OPEN_BRACKET 0x1C
|
||||||
|
#define ARC_CONFIG_BACKSLASH 0x1D
|
||||||
|
#define ARC_CONFIG_CLOSE_BRACKET 0x1E
|
||||||
|
#define ARC_CONFIG_CARET 0x1F
|
||||||
|
#define ARC_CONFIG_UNDERSCORE 0x20
|
||||||
|
#define ARC_CONFIG_GRAVE 0x21
|
||||||
|
#define ARC_CONFIG_ALPHA_LOWER_CHAR 0x22
|
||||||
|
|
||||||
|
#define ARC_CONFIG_OPEN_CURLY_BRACE 0x23
|
||||||
|
#define ARC_CONFIG_VERTICAL_LINE 0x24
|
||||||
|
#define ARC_CONFIG_CLOSE_CURLY_BRACE 0x25
|
||||||
|
#define ARC_CONFIG_TILDE 0x26
|
||||||
|
|
||||||
|
#define ARC_CONFIG_LANGUAGE 0x27
|
||||||
|
#define ARC_CONFIG_GROUP 0x28
|
||||||
|
#define ARC_CONFIG_GROUP_NAME 0x29
|
||||||
|
#define ARC_CONFIG_GROUP_ARGS 0x2A
|
||||||
|
#define ARC_CONFIG_VARIABLE_LINES 0x2B
|
||||||
|
#define ARC_CONFIG_VARIABLE_LINE 0x2C
|
||||||
|
#define ARC_CONFIG_ALLOW_SPACE 0x2D
|
||||||
|
#define ARC_CONFIG_TYPE 0x2E
|
||||||
|
#define ARC_CONFIG_VALUE 0x2F
|
||||||
|
#define ARC_CONFIG_NESTED_VALUE 0x30
|
||||||
|
#define ARC_CONFIG_VALUE_ARGS 0x31
|
||||||
|
#define ARC_CONFIG_VARIABLE 0x32
|
||||||
|
#define ARC_CONFIG_VARIABLE_NAME 0x33
|
||||||
|
#define ARC_CONFIG_VARIABLE_CHAR 0x34
|
||||||
|
#define ARC_CONFIG_STRING 0x35
|
||||||
|
#define ARC_CONFIG_STRING_CHARS 0x36
|
||||||
|
#define ARC_CONFIG_STRING_CHAR 0x37
|
||||||
|
#define ARC_CONFIG_ESCAPE_CHAR 0x38
|
||||||
|
#define ARC_CONFIG_NUMBER_SIGN 0x39
|
||||||
|
#define ARC_CONFIG_NUMBER_TAG 0x3A
|
||||||
|
#define ARC_CONFIG_WHITESPACE 0x3B
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif //ARC_STD_CONFIG_H_
|
#endif //ARC_STD_CONFIG_H_
|
||||||
|
|
||||||
#ifdef ARC_DEFAULT_CONFIG
|
|
||||||
#include "defaults/config.h"
|
|
||||||
#endif //ARC_DEFAULT_CONFIG
|
|
||||||
|
|
|
||||||
98
include/arc/std/entity.h
Normal file
98
include/arc/std/entity.h
Normal file
|
|
@ -0,0 +1,98 @@
|
||||||
|
#ifndef ARC_STD_ENTITY_H_
|
||||||
|
#define ARC_STD_ENTITY_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "arc/std/array.h"
|
||||||
|
#include "arc/std/bool.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief an entity component system type
|
||||||
|
*/
|
||||||
|
typedef struct ARC_EntitySystem ARC_EntitySystem;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief an entity component system type
|
||||||
|
*/
|
||||||
|
typedef uint32_t ARC_Entity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief an entity component system type
|
||||||
|
*/
|
||||||
|
typedef enum ARC_EntityFlags {
|
||||||
|
ARC_ENTITY_DEAD = 0,
|
||||||
|
ARC_ENTITY_ALIVE = 1
|
||||||
|
} ARC_EntityFlags;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief an entity component system type
|
||||||
|
*/
|
||||||
|
typedef uint32_t ARC_EntityComponent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
*/
|
||||||
|
typedef void (* ARC_EntityCoponent_CreateEmptyFn)(void **type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
*/
|
||||||
|
void ARC_EntitySystem_Create(ARC_EntitySystem **entitySystem);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief destroys an ARC_EntitySystem
|
||||||
|
*
|
||||||
|
* @param[in] entitySystem ARC_EntitySystem to free
|
||||||
|
*/
|
||||||
|
void ARC_EntitySystem_Destroy(ARC_EntitySystem *entitySystem);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief registers space for a component and an id for the compenent within the entity system
|
||||||
|
*
|
||||||
|
* @note this function will set arc_errno if the components run out of space
|
||||||
|
*
|
||||||
|
* @param[in] entitySystem the entity system to register the component to
|
||||||
|
* @param[in] componentSize the size of the component to register
|
||||||
|
*
|
||||||
|
* @return an id for for the component
|
||||||
|
*/
|
||||||
|
uint32_t ARC_EntitySystem_RegisterComponent(ARC_EntitySystem *entitySystem, uint32_t componentSize);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
*/
|
||||||
|
ARC_Entity ARC_EntitySystem_InitEntity(ARC_EntitySystem *entitySystem);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
*/
|
||||||
|
void ARC_EntitySystem_ReleaseEntity(ARC_EntitySystem *entitySystem, ARC_Entity entity);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
*/
|
||||||
|
void ARC_EntitySystem_AddComponent(ARC_EntitySystem *entitySystem, ARC_Entity entity, ARC_EntityComponent component, void *data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
*/
|
||||||
|
ARC_Bool ARC_EntitySystem_HasComponent(ARC_EntitySystem *entitySystem, ARC_Entity entity, ARC_EntityComponent component);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
*/
|
||||||
|
void *ARC_EntitySystem_GetComponentData(ARC_EntitySystem *entitySystem, ARC_Entity entity, ARC_EntityComponent component);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
*/
|
||||||
|
ARC_Array ARC_EntitySystem_QueryComponentsData(ARC_EntitySystem *entitySystem, ARC_Array components);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // !ARC_STD_ENTITY_H_
|
||||||
|
|
@ -104,6 +104,15 @@ void ARC_Hashtable_Clear(ARC_Hashtable *hashtable);
|
||||||
*/
|
*/
|
||||||
void *ARC_Hashtable_Get(ARC_Hashtable *hashtable, void *key);
|
void *ARC_Hashtable_Get(ARC_Hashtable *hashtable, void *key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief gets the number of elements stored in the hashtable
|
||||||
|
*
|
||||||
|
* @param[in] hashtable the hashtable to get number of elements from
|
||||||
|
*
|
||||||
|
* @return the size of the vector
|
||||||
|
*/
|
||||||
|
uint32_t ARC_Hashtable_GetSize(ARC_Hashtable *hashtable);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief iterates through a hashtable passing available key value pairs to a callback
|
* @brief iterates through a hashtable passing available key value pairs to a callback
|
||||||
*
|
*
|
||||||
|
|
|
||||||
121
include/arc/std/vector/inline.h
Normal file
121
include/arc/std/vector/inline.h
Normal file
|
|
@ -0,0 +1,121 @@
|
||||||
|
#ifndef ARC_STD_VECTOR_INLINE_H_
|
||||||
|
#define ARC_STD_VECTOR_INLINE_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "arc/std/array.h"
|
||||||
|
#include "arc/std/vector.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief a dynamic array type that stores elements next to eachother
|
||||||
|
*/
|
||||||
|
typedef struct ARC_VectorInline ARC_VectorInline;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief creates an ARC_VectorInline which is an "expandable" array, this version allocates an array with set length for segments instead of void pointers for the data
|
||||||
|
*
|
||||||
|
* @note this vector relies on correct casting to not have errors, and is a lot less safe than "arc/std/vector.h",
|
||||||
|
* it is recommended that you use "arc/std/vector.h" if you don't have a specific reason to use this type
|
||||||
|
* @note to avoid writing a ton of callback types, this will use callback types defined in "arc/std/vector.h"
|
||||||
|
* @note for this basic implementation, the array will double in size every time the capacity is hit
|
||||||
|
* @note the array will also half in size when the array is only half filled
|
||||||
|
*
|
||||||
|
* @param[out] vectorInline ARC_VectorInline to initialize
|
||||||
|
* @param[in] typeSize the size of the type to store within the inline vector
|
||||||
|
* @param[in] compareDataFn a callback that checks if data stored in the array matches,
|
||||||
|
* if set to NULL and ARC_VectorIndex_Remove is called, an error will be thrown
|
||||||
|
* @param[in] destroyDataFn a callback that frees an item on remove or clear, can be set to NULL to do nothing
|
||||||
|
*/
|
||||||
|
void ARC_VectorInline_Create(ARC_VectorInline **vectorInline, uint32_t typeSize, ARC_Vector_CompareDataFn *compareDataFn, ARC_Vector_DestroyDataFn *destroyDataFn);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief destroys an ARC_VectorInline
|
||||||
|
*
|
||||||
|
* @note this will only free the items if destroyDataFn is passed in on creation
|
||||||
|
*
|
||||||
|
* @param[in] vector ARC_VectorInline to free
|
||||||
|
*/
|
||||||
|
void ARC_VectorInline_Destroy(ARC_VectorInline *vectorInline);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief adds an item to an ARC_VectorInline
|
||||||
|
*
|
||||||
|
* @note this will error if you add more than 4,294,967,295 items (the max value of an unsigned int 32)
|
||||||
|
*
|
||||||
|
* @param[in] vector ARC_VectorInline to add to
|
||||||
|
* @param[in] data data that is being added
|
||||||
|
*/
|
||||||
|
void ARC_VectorInline_Add(ARC_VectorInline *vectorInline, void *data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief removes an item from a matching item in an ARC_VectorInline
|
||||||
|
*
|
||||||
|
* @note this function uses the ARC_Vector_CompareDataFn that the ARC_VectorInline was created with
|
||||||
|
* @note this function will not throw an error if there is no match
|
||||||
|
* @note this function will call ARC_VectorInline_RemoveIndex, so it's notes are also applicable to this function
|
||||||
|
*
|
||||||
|
* @param[in] vectorInline ARC_VectorInline to remove from
|
||||||
|
* @param[in] data matching data to remove
|
||||||
|
*/
|
||||||
|
void ARC_VectorInline_Remove(ARC_VectorInline *vectorInline, void *data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief removes an item from an ARC_VectorInline at an index
|
||||||
|
*
|
||||||
|
* @note this function will error if trying to remove an index that is outside the bounds of the ARC_VectorInline
|
||||||
|
* @note this function will use ARC_Vector_DeleteDataFn if it was set in the ARC_VectorInline_Create function
|
||||||
|
*
|
||||||
|
* @param[in] vectorInline ARC_VectorInline to remove from
|
||||||
|
* @param[in] index position of data to remove
|
||||||
|
*/
|
||||||
|
void ARC_VectorInline_RemoveIndex(ARC_VectorInline *vectorInline, uint32_t index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief clears all items from a vector
|
||||||
|
*
|
||||||
|
* @note this function will call ARC_VectorInline_RemoveIndex, so it's notes are also applicable to this function
|
||||||
|
*
|
||||||
|
* @param[in] vector ARC_VectorInline to clear
|
||||||
|
*/
|
||||||
|
void ARC_VectorInline_Clear(ARC_VectorInline *vectorInline);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief gets the current size of an ARC_VectorInline as an unsigned 32 bit integer
|
||||||
|
*
|
||||||
|
* @param[in] vector ARC_VectorInline to get current size from
|
||||||
|
*
|
||||||
|
* @return the current size as a unsigned 32 bit integer
|
||||||
|
*/
|
||||||
|
uint32_t ARC_VectorInline_GetSize(ARC_VectorInline *vectorInline);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief gets an item from an ARC_VectorInline at a position index
|
||||||
|
*
|
||||||
|
* @note this function will error if trying to get an index that is outside the bounds of the ARC_VectorInline
|
||||||
|
*
|
||||||
|
* @param[in] vectorInline ARC_VectorInline to get data from
|
||||||
|
* @param[in] index position of data to get
|
||||||
|
*
|
||||||
|
* @return a void * item, or NULL on error
|
||||||
|
*/
|
||||||
|
void *ARC_VectorInline_Get(ARC_VectorInline *vectorInline, uint32_t index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief gets the data from the vector as an ARC_Array
|
||||||
|
*
|
||||||
|
* @note this function will does not copy the data it returns, so changes will affect the contents of the vector inline
|
||||||
|
*
|
||||||
|
* @param[in] vectorInline ARC_VectorInline to get data from
|
||||||
|
*
|
||||||
|
* @return an ARC_Array that holds the current contents of the vector inline
|
||||||
|
*/
|
||||||
|
ARC_Array ARC_VectorInline_GetData(ARC_VectorInline *vectorInline);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // !ARC_STD_VECTOR_INLINE_H_
|
||||||
|
|
@ -1,706 +0,0 @@
|
||||||
#include "arc/std/chemical.h"
|
|
||||||
#include "arc/std/parser/helpers.h"
|
|
||||||
#include "arc/std/bool.h"
|
|
||||||
#include "arc/std/errno.h"
|
|
||||||
#include "arc/std/hashtable.h"
|
|
||||||
#include "arc/std/parser.h"
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
struct ARC_Chemical {
|
|
||||||
ARC_Parser *parser;
|
|
||||||
|
|
||||||
ARC_Hashtable *types;
|
|
||||||
|
|
||||||
ARC_Hashtable *groups;
|
|
||||||
ARC_Hashtable *currentGroup;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct ARC_ChemicalTypeData {
|
|
||||||
void *data;
|
|
||||||
ARC_ChemicalType_DestroyFn destroyFn;
|
|
||||||
} ARC_ChemicalTypeData;
|
|
||||||
|
|
||||||
void ARC_Chemical_InitLexerRulesFn(ARC_Lexer *lexer){
|
|
||||||
ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_CHEMICAL_TAB , '\t'));
|
|
||||||
ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_CHEMICAL_NEWLINE, '\n'));
|
|
||||||
|
|
||||||
ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_CHEMICAL_SPACE , ' ' ));
|
|
||||||
ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_CHEMICAL_BANG , '!' ));
|
|
||||||
ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_CHEMICAL_QUOTE , '"' ));
|
|
||||||
ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_CHEMICAL_HASH , '#' ));
|
|
||||||
ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_CHEMICAL_DOLLAR , '$' ));
|
|
||||||
ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_CHEMICAL_PERCENT , '%' ));
|
|
||||||
ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_CHEMICAL_AMPERSAND , '&' ));
|
|
||||||
ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_CHEMICAL_SINGLE_QUOTE, '\''));
|
|
||||||
ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_CHEMICAL_OPEN_PAREN , '(' ));
|
|
||||||
ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_CHEMICAL_CLOSE_PAREN , ')' ));
|
|
||||||
ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_CHEMICAL_ASTERISK , '*' ));
|
|
||||||
ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_CHEMICAL_PLUS , '+' ));
|
|
||||||
ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_CHEMICAL_COMMA , ',' ));
|
|
||||||
ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_CHEMICAL_MINUS , '-' ));
|
|
||||||
ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_CHEMICAL_PERIOD , '.' ));
|
|
||||||
ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_CHEMICAL_SLASH , '/' ));
|
|
||||||
|
|
||||||
ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharOrBetween(ARC_CHEMICAL_NUMBER , '0', '9'));
|
|
||||||
|
|
||||||
ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_CHEMICAL_COLON , ':'));
|
|
||||||
ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_CHEMICAL_SEMICOLON , ';'));
|
|
||||||
ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_CHEMICAL_LESS_THAN , '<'));
|
|
||||||
ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_CHEMICAL_GREATER_THAN , '>'));
|
|
||||||
ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_CHEMICAL_EQUAL , '='));
|
|
||||||
ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_CHEMICAL_QUESTION_MARK, '?'));
|
|
||||||
ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_CHEMICAL_AT , '@'));
|
|
||||||
|
|
||||||
ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharOrBetween(ARC_CHEMICAL_ALPHA_UPPER_CHAR, 'A', 'Z'));
|
|
||||||
|
|
||||||
ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_CHEMICAL_OPEN_BRACKET , '[' ));
|
|
||||||
ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_CHEMICAL_BACKSLASH , '\\'));
|
|
||||||
ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_CHEMICAL_CLOSE_BRACKET, ']' ));
|
|
||||||
ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_CHEMICAL_CARET , '^' ));
|
|
||||||
ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_CHEMICAL_UNDERSCORE , '_' ));
|
|
||||||
ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_CHEMICAL_GRAVE , '`' ));
|
|
||||||
|
|
||||||
ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharOrBetween(ARC_CHEMICAL_ALPHA_LOWER_CHAR, 'a', 'z'));
|
|
||||||
|
|
||||||
ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_CHEMICAL_OPEN_CURLY_BRACE , '{'));
|
|
||||||
ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_CHEMICAL_VERTICAL_LINE , '|'));
|
|
||||||
ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_CHEMICAL_CLOSE_CURLY_BRACE, '}'));
|
|
||||||
ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_CHEMICAL_TILDE , '~'));
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t ARC_Chemical_GetStringIdFn(ARC_String *string){
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "LAMBDA")){
|
|
||||||
return ARC_PARSER_TAG_LAMBDA;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "TAB")){
|
|
||||||
return ARC_CHEMICAL_TAB;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "NEWLINE")){
|
|
||||||
return ARC_CHEMICAL_NEWLINE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "SPACE")){
|
|
||||||
return ARC_CHEMICAL_SPACE;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "BANG")){
|
|
||||||
return ARC_CHEMICAL_BANG;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "QUOTE")){
|
|
||||||
return ARC_CHEMICAL_QUOTE;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "HASH")){
|
|
||||||
return ARC_CHEMICAL_HASH;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "DOLLAR")){
|
|
||||||
return ARC_CHEMICAL_DOLLAR;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "PERCENT")){
|
|
||||||
return ARC_CHEMICAL_PERCENT;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "AMPERSAND")){
|
|
||||||
return ARC_CHEMICAL_AMPERSAND;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "SINGLE_QUOTE")){
|
|
||||||
return ARC_CHEMICAL_SINGLE_QUOTE;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "OPEN_PAREN")){
|
|
||||||
return ARC_CHEMICAL_OPEN_PAREN;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "CLOSE_PAREN")){
|
|
||||||
return ARC_CHEMICAL_CLOSE_PAREN;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "ASTERISK")){
|
|
||||||
return ARC_CHEMICAL_ASTERISK;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "PLUS")){
|
|
||||||
return ARC_CHEMICAL_PLUS;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "COMMA")){
|
|
||||||
return ARC_CHEMICAL_COMMA;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "MINUS")){
|
|
||||||
return ARC_CHEMICAL_MINUS;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "PERIOD")){
|
|
||||||
return ARC_CHEMICAL_PERIOD;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "SLASH")){
|
|
||||||
return ARC_CHEMICAL_SLASH;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "NUMBER")){
|
|
||||||
return ARC_CHEMICAL_NUMBER;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "COLON")){
|
|
||||||
return ARC_CHEMICAL_COLON;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "SEMICOLON")){
|
|
||||||
return ARC_CHEMICAL_SEMICOLON;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "LESS_THAN")){
|
|
||||||
return ARC_CHEMICAL_LESS_THAN;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "GREATER_THAN")){
|
|
||||||
return ARC_CHEMICAL_GREATER_THAN;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "EQUAL")){
|
|
||||||
return ARC_CHEMICAL_EQUAL;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "QUESTION_MARK")){
|
|
||||||
return ARC_CHEMICAL_QUESTION_MARK;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "AT")){
|
|
||||||
return ARC_CHEMICAL_AT;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "ALPHA_UPPER_CHAR")){
|
|
||||||
return ARC_CHEMICAL_ALPHA_UPPER_CHAR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "OPEN_BRACKET")){
|
|
||||||
return ARC_CHEMICAL_OPEN_BRACKET;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "BACKSLASH")){
|
|
||||||
return ARC_CHEMICAL_BACKSLASH;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "CLOSE_BRACKET")){
|
|
||||||
return ARC_CHEMICAL_CLOSE_BRACKET;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "CARET")){
|
|
||||||
return ARC_CHEMICAL_CARET;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "UNDERSCORE")){
|
|
||||||
return ARC_CHEMICAL_UNDERSCORE;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "GRAVE")){
|
|
||||||
return ARC_CHEMICAL_GRAVE;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "ALPHA_LOWER_CHAR")){
|
|
||||||
return ARC_CHEMICAL_ALPHA_LOWER_CHAR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "OPEN_CURLY_BRACE")){
|
|
||||||
return ARC_CHEMICAL_OPEN_CURLY_BRACE;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "VERTICAL_LINE")){
|
|
||||||
return ARC_CHEMICAL_VERTICAL_LINE;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "CLOSE_CURLY_BRACE")){
|
|
||||||
return ARC_CHEMICAL_CLOSE_CURLY_BRACE;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "TILDE")){
|
|
||||||
return ARC_CHEMICAL_TILDE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "<language>")){
|
|
||||||
return ARC_CHEMICAL_LANGUAGE;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "<group>")){
|
|
||||||
return ARC_CHEMICAL_GROUP;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "<groupName>")){
|
|
||||||
return ARC_CHEMICAL_GROUP_NAME;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "<groupArgs>")){
|
|
||||||
return ARC_CHEMICAL_GROUP_ARGS;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "<variableLines>")){
|
|
||||||
return ARC_CHEMICAL_VARIABLE_LINES;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "<variableLine>")){
|
|
||||||
return ARC_CHEMICAL_VARIABLE_LINE;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "<allowSpace>")){
|
|
||||||
return ARC_CHEMICAL_ALLOW_SPACE;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "<type>")){
|
|
||||||
return ARC_CHEMICAL_TYPE;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "<value>")){
|
|
||||||
return ARC_CHEMICAL_VALUE;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "<nestedValue>")){
|
|
||||||
return ARC_CHEMICAL_NESTED_VALUE;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "<valueArgs>")){
|
|
||||||
return ARC_CHEMICAL_VALUE_ARGS;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "<variable>")){
|
|
||||||
return ARC_CHEMICAL_VARIABLE;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "<variableName>")){
|
|
||||||
return ARC_CHEMICAL_VARIABLE_NAME;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "<variableChar>")){
|
|
||||||
return ARC_CHEMICAL_VARIABLE_CHAR;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "<string>")){
|
|
||||||
return ARC_CHEMICAL_STRING;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "<stringChars>")){
|
|
||||||
return ARC_CHEMICAL_STRING_CHARS;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "<stringChar>")){
|
|
||||||
return ARC_CHEMICAL_STRING_CHAR;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "<escapeChar>")){
|
|
||||||
return ARC_CHEMICAL_ESCAPE_CHAR;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "<number>")){
|
|
||||||
return ARC_CHEMICAL_NUMBER_TAG;
|
|
||||||
}
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(string, "<whitespace>")){
|
|
||||||
return ARC_CHEMICAL_WHITESPACE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ~(uint32_t)0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//private function to check hashtable keys used by chemical
|
|
||||||
ARC_Bool ARC_Chemical_HashtableKeyCompareFn(void *key1, void *key2){
|
|
||||||
return (ARC_Bool)strcmp((const char *)key1, (const char *)key2) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//private function to clean up types
|
|
||||||
void ARC_Chemical_TypeHashtableDestroyKeyValueFn(void *key, void *value){
|
|
||||||
free((char *)key);
|
|
||||||
free((ARC_ChemicalType *)value);
|
|
||||||
}
|
|
||||||
|
|
||||||
//private function to clean up groups
|
|
||||||
void ARC_Chemical_GroupHashtableDestroyKeyValueFn(void *key, void *value){
|
|
||||||
free((char *)key);
|
|
||||||
ARC_Hashtable_Destroy((ARC_Hashtable *)value);
|
|
||||||
}
|
|
||||||
|
|
||||||
//private function to clean up goup data
|
|
||||||
void ARC_Chemical_GroupDataHashtableDestroyKeyValueFn(void *key, void *value){
|
|
||||||
free((char *)key);
|
|
||||||
|
|
||||||
ARC_ChemicalTypeData *typeData = (ARC_ChemicalTypeData *)value;
|
|
||||||
typeData->destroyFn(typeData->data);
|
|
||||||
free(typeData);
|
|
||||||
}
|
|
||||||
|
|
||||||
//<variableLine> -> <whitespace> <type> <whitespace> <variable> <whitespace> EQUAL <whitespace> <value> <whitespace> SEMICOLON
|
|
||||||
void ARC_ChemicalData_RunVariableLineTag(ARC_ParserTagToken *tagToken, ARC_Chemical *chemical){
|
|
||||||
//skip whitespace and check for group name
|
|
||||||
ARC_ParserTagToken *childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(tagToken->tagTokens, 1);
|
|
||||||
|
|
||||||
//get the type
|
|
||||||
ARC_String *typeString;
|
|
||||||
ARC_String_Create(&typeString, NULL, 0);
|
|
||||||
ARC_ParserData_HelperRecurseStringAdd(&typeString, childTagToken);
|
|
||||||
|
|
||||||
//check if type exists in the types hashtable
|
|
||||||
ARC_ChemicalType *type = (ARC_ChemicalType *)ARC_Hashtable_Get(chemical->types, typeString->data);
|
|
||||||
if(type == NULL){
|
|
||||||
//throw an error and return
|
|
||||||
arc_errno = ARC_ERRNO_DATA;
|
|
||||||
ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("ARC_ChemicalData_RunVariableLineTag(tagToken, chemical), type \"%s\" was not registered to chemical", typeString->data);
|
|
||||||
ARC_String_Destroy(typeString);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//cleanup
|
|
||||||
ARC_String_Destroy(typeString);
|
|
||||||
|
|
||||||
//get the variable
|
|
||||||
childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(tagToken->tagTokens, 3);
|
|
||||||
ARC_String *variableString;
|
|
||||||
ARC_String_Create(&variableString, NULL, 0);
|
|
||||||
ARC_ParserData_HelperRecurseStringAdd(&variableString, childTagToken);
|
|
||||||
|
|
||||||
//check to see if the current variable is already in the current group hashtable
|
|
||||||
ARC_ChemicalTypeData *typeData = (ARC_ChemicalTypeData *)ARC_Hashtable_Get(chemical->currentGroup, variableString->data);
|
|
||||||
if(typeData != NULL){
|
|
||||||
//there is already a value so throw an error and return
|
|
||||||
arc_errno = ARC_ERRNO_DATA;
|
|
||||||
ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("ARC_ChemicalData_RunVariableLineTag(tagToken, chemical), variable \"%s\" already registered to the current group", variableString->data);
|
|
||||||
ARC_String_Destroy(variableString);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//copy the string into a cstring that will be stored in the hashtable
|
|
||||||
char *elementVariableCStr = malloc(sizeof(char) * (variableString->length + 1));
|
|
||||||
strncpy(elementVariableCStr, variableString->data, variableString->length);
|
|
||||||
elementVariableCStr[variableString->length] = '\0';
|
|
||||||
ARC_String_Destroy(variableString);
|
|
||||||
|
|
||||||
//get <value>
|
|
||||||
childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(tagToken->tagTokens, 7);
|
|
||||||
|
|
||||||
//check if <value> is a reference
|
|
||||||
ARC_String *valueString;
|
|
||||||
ARC_String_Create(&valueString, NULL, 0);
|
|
||||||
ARC_ParserData_HelperRecurseStringAdd(&valueString, childTagToken);
|
|
||||||
void *value = ARC_Hashtable_Get(chemical->currentGroup, valueString);
|
|
||||||
ARC_String_Destroy(valueString);
|
|
||||||
|
|
||||||
//create where to store either the reference or type data
|
|
||||||
typeData = (ARC_ChemicalTypeData *)malloc(sizeof(ARC_ChemicalTypeData));
|
|
||||||
if(value != NULL){
|
|
||||||
//point to the already stored data
|
|
||||||
typeData->data = value;
|
|
||||||
typeData->destroyFn = NULL;
|
|
||||||
|
|
||||||
//add to the current group hashtable
|
|
||||||
ARC_Hashtable_Add(chemical->currentGroup, (void *)elementVariableCStr, (void *)typeData);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//passed the parsed value into the copy type function and set the destroy function
|
|
||||||
type->copyFn(&(typeData->data), childTagToken, chemical);
|
|
||||||
typeData->destroyFn = type->destroyFn;
|
|
||||||
|
|
||||||
//add to the current group hashtable
|
|
||||||
ARC_Hashtable_Add(chemical->currentGroup, (void *)elementVariableCStr, (void *)typeData);
|
|
||||||
}
|
|
||||||
|
|
||||||
//<variableLines> -> <variableLine> <whitespace> <variableLines> | <variableLine>
|
|
||||||
void ARC_ChemicalData_RunVariableLinesTag(ARC_ParserTagToken *tagToken, ARC_Chemical *chemical){
|
|
||||||
//loop through the tags either going to the next line or the next body
|
|
||||||
for(uint32_t index = 0; index < ARC_Vector_GetSize(tagToken->tagTokens); index++){
|
|
||||||
ARC_ParserTagToken *childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(tagToken->tagTokens, index);
|
|
||||||
|
|
||||||
switch(childTagToken->id){
|
|
||||||
//recuse to run the next line
|
|
||||||
case ARC_CHEMICAL_VARIABLE_LINES:
|
|
||||||
ARC_ChemicalData_RunVariableLinesTag(childTagToken, chemical);
|
|
||||||
if(arc_errno != 0){
|
|
||||||
ARC_DEBUG_LOG_ERROR("ARC_ChemicalData_RunVariableLinesTag(tagToken, chemical), chemical errored when trying to used parsed data for variable lines");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
|
|
||||||
//recurse into a variable line tag
|
|
||||||
case ARC_CHEMICAL_VARIABLE_LINE:
|
|
||||||
ARC_ChemicalData_RunVariableLineTag(childTagToken, chemical);
|
|
||||||
if(arc_errno != 0){
|
|
||||||
ARC_DEBUG_LOG_ERROR("ARC_ChemicalData_RunVariableLinesTag(tagToken, chemical), chemical errored when trying to used parsed data for variable line");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
|
|
||||||
//this is for whitespace and any oddities
|
|
||||||
default:
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//<group> -> <whitespace> <groupName> <whitespace> <variable> <whitespace> OPEN_CURLY_BRACE <groupArgs> <whitespace> CLOSE_CURLY_BRACE
|
|
||||||
void ARC_ChemicalData_RunGroupTag(ARC_ParserTagToken *tagToken, ARC_Chemical *chemical){
|
|
||||||
//skip whitespace and check for group name
|
|
||||||
ARC_ParserTagToken *childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(tagToken->tagTokens, 1);
|
|
||||||
|
|
||||||
/* ~ <groupName> ~ */
|
|
||||||
//get the group name and check if it is named "group"
|
|
||||||
//NOTE: this check may be usedful in the future if there is different functionality for group like tag names
|
|
||||||
ARC_String *groupName;
|
|
||||||
ARC_String_Create(&groupName, NULL, 0);
|
|
||||||
ARC_ParserData_HelperRecurseStringAdd(&groupName, childTagToken);
|
|
||||||
if(ARC_String_EqualsCStringWithStrlen(groupName, ARC_CHEMICAL_GROUP_TAG_NAME) == ARC_False){
|
|
||||||
//throw an error and return
|
|
||||||
arc_errno = ARC_ERRNO_DATA;
|
|
||||||
ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("ARC_ChemicalData_RunGroupTag(tagToken, chemical), chemical contained keyword \"%s\" instead of using the correct keyword: \"%s\" ", groupName->data, ARC_CHEMICAL_GROUP_TAG_NAME);
|
|
||||||
ARC_String_Destroy(groupName);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//cleanup
|
|
||||||
ARC_String_Destroy(groupName);
|
|
||||||
|
|
||||||
/* ~ <variable> ~ */
|
|
||||||
//get the group's variable name
|
|
||||||
childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(tagToken->tagTokens, 3);
|
|
||||||
ARC_String *groupVariable;
|
|
||||||
ARC_String_Create(&groupVariable, NULL, 0);
|
|
||||||
ARC_ParserData_HelperRecurseStringAdd(&groupVariable, childTagToken);
|
|
||||||
|
|
||||||
//get the needed hashtable or create it from the groups hashtable
|
|
||||||
ARC_Hashtable *groupHashtable = ARC_Hashtable_Get(chemical->groups, (void *)groupVariable->data);
|
|
||||||
if(groupHashtable == NULL){
|
|
||||||
//copy the string into a cstring that will be stored in the hashtable
|
|
||||||
char *groupVariableCStr = malloc(sizeof(char) * (groupVariable->length + 1));
|
|
||||||
strncpy(groupVariableCStr, groupVariable->data, groupVariable->length);
|
|
||||||
groupVariableCStr[groupVariable->length] = '\0';
|
|
||||||
|
|
||||||
//create the hashtable with the given group name key
|
|
||||||
ARC_Hashtable_KeyCompareFn keyCompareFn = ARC_Chemical_HashtableKeyCompareFn;
|
|
||||||
ARC_Hashtable_DestroyKeyValueFn groupDataDestroyKeyValueFn = ARC_Chemical_GroupDataHashtableDestroyKeyValueFn;
|
|
||||||
ARC_Hashtable_Create(&groupHashtable, NULL, &keyCompareFn, &groupDataDestroyKeyValueFn);
|
|
||||||
ARC_Hashtable_Add(chemical->groups, (void *)groupVariableCStr, (void *)groupHashtable);
|
|
||||||
}
|
|
||||||
|
|
||||||
//cleanup
|
|
||||||
ARC_String_Destroy(groupVariable);
|
|
||||||
|
|
||||||
//set the current group to the group just created or found
|
|
||||||
chemical->currentGroup = groupHashtable;
|
|
||||||
|
|
||||||
/* ~ <groupArgs> ~ */
|
|
||||||
childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(tagToken->tagTokens, 6);
|
|
||||||
|
|
||||||
//<groupArgs> -> <whitespace> <variableLines> | LAMBDA
|
|
||||||
if(childTagToken->token == NULL && ARC_Vector_GetSize(childTagToken->tagTokens) == 2){
|
|
||||||
ARC_ParserTagToken *variableLines = (ARC_ParserTagToken *)ARC_Vector_Get(childTagToken->tagTokens, 1);
|
|
||||||
ARC_ChemicalData_RunVariableLinesTag(variableLines, chemical);
|
|
||||||
|
|
||||||
//log error if it happens, but as setting the group back is the last thing we shouldn't return
|
|
||||||
if(arc_errno != 0){
|
|
||||||
ARC_DEBUG_LOG_ERROR("ARC_ChemicalData_RunGroupTag(tagToken, chemical), chemical errored when trying to used parsed data for variable lines");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ~ reset current group ~ */
|
|
||||||
chemical->currentGroup = ARC_Hashtable_Get(chemical->groups, (void *)ARC_CHEMICAL_DEFAULT_GROUP);
|
|
||||||
}
|
|
||||||
|
|
||||||
//<language> -> <group> <language> | <variableLines> <language> | <whitespace>
|
|
||||||
void ARC_ChemicalData_RunLanguageTag(ARC_ParserTagToken *tagToken, ARC_Chemical *chemical){
|
|
||||||
//loop through the tags either going to the next language, group, or variable lines
|
|
||||||
for(uint32_t index = 0; index < ARC_Vector_GetSize(tagToken->tagTokens); index++){
|
|
||||||
ARC_ParserTagToken *childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(tagToken->tagTokens, index);
|
|
||||||
|
|
||||||
switch(childTagToken->id){
|
|
||||||
//recuse to run the next line
|
|
||||||
case ARC_CHEMICAL_LANGUAGE:
|
|
||||||
ARC_ChemicalData_RunLanguageTag(childTagToken, chemical);
|
|
||||||
continue;
|
|
||||||
|
|
||||||
//recurse into a group tag
|
|
||||||
case ARC_CHEMICAL_GROUP:
|
|
||||||
ARC_ChemicalData_RunGroupTag(childTagToken, chemical);
|
|
||||||
if(arc_errno != 0){
|
|
||||||
ARC_DEBUG_LOG_ERROR("ARC_ChemicalData_RunLanguageTag(tagToken, chemical), chemical errored when trying to used parsed data for a group");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
|
|
||||||
//recurse through variable lines
|
|
||||||
case ARC_CHEMICAL_VARIABLE_LINES:
|
|
||||||
ARC_ChemicalData_RunVariableLinesTag(childTagToken, chemical);
|
|
||||||
ARC_ChemicalData_RunGroupTag(childTagToken, chemical);
|
|
||||||
if(arc_errno != 0){
|
|
||||||
ARC_DEBUG_LOG_ERROR("ARC_ChemicalData_RunLanguageTag(tagToken, chemical), chemical errored when trying to used parsed data for variable lines");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
|
|
||||||
//this is for whitespace and any oddities
|
|
||||||
default:
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ARC_ChemicalData_CreateFn(void **data, ARC_ParserTagToken *parsedData, void *userData){
|
|
||||||
*data = NULL;
|
|
||||||
if(parsedData == NULL || userData == NULL){
|
|
||||||
//TODO: error here?
|
|
||||||
*data = NULL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ARC_ChemicalData_RunLanguageTag(parsedData, (ARC_Chemical *)userData);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ARC_ChemicalData_DestroyFn(void *data, ARC_Bool clear, void *userData){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ARC_Chemical_Create(ARC_Chemical **chemical){
|
|
||||||
*chemical = (ARC_Chemical *)malloc(sizeof(ARC_Chemical));
|
|
||||||
|
|
||||||
/* ~ define the language as a string ~ */
|
|
||||||
char *languageCString =
|
|
||||||
"<language> -> <group> <language> | <variableLines> <language> | <whitespace>\n"
|
|
||||||
|
|
||||||
"<group> -> <whitespace> <groupName> <whitespace> <variable> <whitespace> OPEN_CURLY_BRACE <groupArgs> <whitespace> CLOSE_CURLY_BRACE\n"
|
|
||||||
"<groupName> -> <variable>\n"
|
|
||||||
"<groupArgs> -> <whitespace> <variableLines> | LAMBDA\n"
|
|
||||||
|
|
||||||
"<variableLines> -> <variableLine> <whitespace> <variableLines> | <variableLine>\n"
|
|
||||||
"<variableLine> -> <whitespace> <type> <whitespace> <variable> <whitespace> EQUAL <whitespace> <value> <whitespace> SEMICOLON\n"
|
|
||||||
"<allowSpace> -> SPACE <allowSpace> | TAB <allowSpace> | LAMBDA\n"
|
|
||||||
|
|
||||||
"<type> -> <variable>\n"
|
|
||||||
"<value> -> <variable> | <number> | <string> | <nestedValue>\n"
|
|
||||||
"<nestedValue> -> OPEN_CURLY_BRACE <whitespace> <valueArgs> <whitespace> CLOSE_CURLY_BRACE\n"
|
|
||||||
"<valueArgs> -> <value> COMMA <valueArgs> | <value>\n"
|
|
||||||
|
|
||||||
"<variable> -> ALPHA_UPPER_CHAR <variableName> | ALPHA_LOWER_CHAR <variableName> | UNDERSCORE <variableName>\n"
|
|
||||||
"<variableName> -> <variableChar> <variableName> | LAMBDA\n"
|
|
||||||
"<variableChar> -> ALPHA_UPPER_CHAR | ALPHA_LOWER_CHAR | UNDERSCORE | NUMBER\n"
|
|
||||||
|
|
||||||
"<string> -> QUOTE <stringChars> QUOTE\n"
|
|
||||||
"<stringChars> -> <stringChar> <stringChars> | <escapeChar> <stringChars> | LAMBDA\n"
|
|
||||||
"<stringChar> -> TAB | SPACE | BANG | HASH | DOLLAR | PERCENT | AMPERSAND | SINGLE_QUOTE | OPEN_PAREN | CLOSE_PAREN | ASTERISK | PLUS | COMMA | MINUS | PERIOD | SLASH | NUMBER | COLON | SEMICOLON | LESS_THAN | GREATER_THAN | EQUAL | QUESTION_MARK | AT | ALPHA_UPPER_CHAR | OPEN_BRACKET | CLOSE_BRACKET | CARET | UNDERSCORE | GRAVE | ALPHA_LOWER_CHAR | OPEN_CURLY_BRACE | VERTICAL_LINE | CLOSE_CURLY_BRACE | TILDE\n"
|
|
||||||
"<escapeChar> -> BACKSLASH BACKSLASH | BACKSLASH QUOTE | BACKSLASH ALPHA_UPPER_CHAR | BACKSLASH ALPHA_LOWER_CHAR\n"
|
|
||||||
|
|
||||||
"<number> -> NUMBER <number> | NUMBER\n"
|
|
||||||
|
|
||||||
"<whitespace> -> SPACE <whitespace> | TAB <whitespace> | NEWLINE <whitespace> | LAMBDA\n";
|
|
||||||
|
|
||||||
/* ~ define the language as a string ~ */
|
|
||||||
ARC_String *languageString;
|
|
||||||
ARC_String_CreateWithStrlen(&languageString, languageCString);
|
|
||||||
|
|
||||||
/* ~ set chemical as userdata ~ */
|
|
||||||
void *userdata = *chemical;
|
|
||||||
|
|
||||||
/* ~ create the language ~ */
|
|
||||||
ARC_ParserData_CreateFn createCharFn = ARC_ChemicalData_CreateFn;
|
|
||||||
ARC_ParserData_DestroyFn destroyCharFn = ARC_ChemicalData_DestroyFn;
|
|
||||||
ARC_Parser_CreateFromString(&((*chemical)->parser), languageString, ARC_Chemical_InitLexerRulesFn, ARC_Chemical_GetStringIdFn, &createCharFn, &destroyCharFn, userdata);
|
|
||||||
|
|
||||||
/* ~ init types ~ */
|
|
||||||
ARC_Hashtable_KeyCompareFn keyCompareFn = ARC_Chemical_HashtableKeyCompareFn;
|
|
||||||
ARC_Hashtable_DestroyKeyValueFn typeDestroyKeyValueFn = ARC_Chemical_TypeHashtableDestroyKeyValueFn;
|
|
||||||
ARC_Hashtable_Create(&((*chemical)->types), NULL, &keyCompareFn, &typeDestroyKeyValueFn);
|
|
||||||
|
|
||||||
/* ~ init groups ~ */
|
|
||||||
ARC_Hashtable_DestroyKeyValueFn groupDestroyKeyValueFn = ARC_Chemical_GroupHashtableDestroyKeyValueFn;
|
|
||||||
ARC_Hashtable_Create(&((*chemical)->groups), NULL, &keyCompareFn, &groupDestroyKeyValueFn);
|
|
||||||
|
|
||||||
//add the default/empty group into the groups
|
|
||||||
ARC_Hashtable_DestroyKeyValueFn groupDataDestroyKeyValueFn = ARC_Chemical_GroupDataHashtableDestroyKeyValueFn;
|
|
||||||
|
|
||||||
//copy empty group cstring (to be freed by hashtable on cleanup, passing directly would cause a segfault)
|
|
||||||
char *emptyCStr = (char *)malloc(sizeof(char) * (strlen(ARC_CHEMICAL_DEFAULT_GROUP) + 1));
|
|
||||||
strcpy(emptyCStr, ARC_CHEMICAL_DEFAULT_GROUP);
|
|
||||||
|
|
||||||
//set the current group as empty, then add that into the groups hashtable
|
|
||||||
ARC_Hashtable_Create(&((*chemical)->currentGroup), NULL, &keyCompareFn, &groupDataDestroyKeyValueFn);
|
|
||||||
ARC_Hashtable_Add((*chemical)->groups, (void *)emptyCStr, (*chemical)->currentGroup);
|
|
||||||
|
|
||||||
//cleanup
|
|
||||||
ARC_String_Destroy(languageString);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ARC_Chemical_Destroy(ARC_Chemical *chemical){
|
|
||||||
ARC_Parser_Destroy(chemical->parser);
|
|
||||||
//NOTE: chemical->currentGroup does not need to be freed as it is stored in chemical->groups
|
|
||||||
ARC_Hashtable_Destroy(chemical->groups);
|
|
||||||
ARC_Hashtable_Destroy(chemical->types);
|
|
||||||
free(chemical);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ARC_Chemical_RegisterType(ARC_Chemical *chemical, ARC_String *typeName, ARC_ChemicalType type){
|
|
||||||
ARC_Chemical_RegisterTypeWithCStr(chemical, typeName->data, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ARC_Chemical_RegisterTypeWithCStr(ARC_Chemical *chemical, const char *typeNameCStr, ARC_ChemicalType type){
|
|
||||||
//check if the type key already exists and error if it does
|
|
||||||
if(ARC_Hashtable_Get(chemical->types, (void *)typeNameCStr) != NULL){
|
|
||||||
arc_errno = ARC_ERRNO_EXISTS;
|
|
||||||
ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("ARC_Chemical_RegisterTypeWithCStr(chemical, typeName, type), type \"%s\" has already been registered", typeNameCStr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//copy the string into a cstring for long term storage
|
|
||||||
uint64_t typeNameCopyLength = strlen(typeNameCStr) + 1;
|
|
||||||
char *typeNameCopy = (char *)malloc(sizeof(char) * typeNameCopyLength);
|
|
||||||
strncpy(typeNameCopy, typeNameCStr, typeNameCopyLength);
|
|
||||||
typeNameCopy[strlen(typeNameCStr)] = '\0';
|
|
||||||
|
|
||||||
//copy the type for long term storage
|
|
||||||
ARC_ChemicalType *typeCopy = (ARC_ChemicalType *)malloc(sizeof(ARC_ChemicalType));
|
|
||||||
*typeCopy = type;
|
|
||||||
|
|
||||||
//add the type to a hashtable containing all the types
|
|
||||||
ARC_Hashtable_Add(chemical->types, typeNameCopy, typeCopy);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ARC_Chemical_SetGroup(ARC_Chemical *chemical, ARC_String *groupName){
|
|
||||||
ARC_Chemical_SetGroupWithCStr(chemical, groupName->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ARC_Chemical_SetGroupWithCStr(ARC_Chemical *chemical, const char *groupName){
|
|
||||||
//try to get the current group
|
|
||||||
void *currentGroup = ARC_Hashtable_Get(chemical->groups, (void *)groupName);
|
|
||||||
|
|
||||||
//error if the current group does not exist
|
|
||||||
if(currentGroup == NULL){
|
|
||||||
arc_errno = ARC_ERRNO_NULL;
|
|
||||||
ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("ARC_Chemical_SetGroupWithCStr(chemical, groupName), no group with name \"%s\"", groupName);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//set the current group
|
|
||||||
chemical->currentGroup = currentGroup;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *ARC_Chemical_Get(ARC_Chemical *chemical, ARC_String *element){
|
|
||||||
//check if the group separator exists
|
|
||||||
uint64_t startSeparatorIndex = ARC_String_FindCStringWithStrlen(element, ARC_CHEMICAL_GROUP_SEPARATOR);
|
|
||||||
if(startSeparatorIndex == ~(uint64_t)0){
|
|
||||||
//use empty group
|
|
||||||
chemical->currentGroup = ARC_Hashtable_Get(chemical->groups, (void *)ARC_CHEMICAL_DEFAULT_GROUP);
|
|
||||||
|
|
||||||
//get the typeData and pass back the data without the cleanup function
|
|
||||||
ARC_ChemicalTypeData *typeData = (ARC_ChemicalTypeData *)ARC_Hashtable_Get(chemical->currentGroup, (void *)element->data);
|
|
||||||
if(typeData == NULL){
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return typeData->data;
|
|
||||||
}
|
|
||||||
|
|
||||||
//get the group
|
|
||||||
startSeparatorIndex--;
|
|
||||||
ARC_String *groupString;
|
|
||||||
ARC_String_CopySubstring(&groupString, element, 0, startSeparatorIndex);
|
|
||||||
|
|
||||||
//set the group
|
|
||||||
chemical->currentGroup = ARC_Hashtable_Get(chemical->groups, (void *)groupString->data);
|
|
||||||
|
|
||||||
//cleanup
|
|
||||||
ARC_String_Destroy(groupString);
|
|
||||||
|
|
||||||
//get the element
|
|
||||||
ARC_String *elementString;
|
|
||||||
startSeparatorIndex += strlen(ARC_CHEMICAL_GROUP_SEPARATOR);
|
|
||||||
ARC_String_CopySubstring(&elementString, element, startSeparatorIndex, element->length - startSeparatorIndex);
|
|
||||||
|
|
||||||
//this will either return the value or NULL
|
|
||||||
ARC_ChemicalTypeData *typeData = (ARC_ChemicalTypeData *)ARC_Hashtable_Get(chemical->currentGroup, (void *)elementString->data);
|
|
||||||
ARC_String_Destroy(elementString);
|
|
||||||
if(typeData == NULL){
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return typeData->data;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *ARC_Chemical_GetWithCStr(ARC_Chemical *chemical, const char *element){
|
|
||||||
//create and copy into ARC_String
|
|
||||||
ARC_String *elementString;
|
|
||||||
ARC_String_CreateWithStrlen(&elementString, (char *)element);
|
|
||||||
|
|
||||||
//get the return value
|
|
||||||
void *returnValue = ARC_Chemical_Get(chemical, elementString);
|
|
||||||
|
|
||||||
//cleanup
|
|
||||||
ARC_String_Destroy(elementString);
|
|
||||||
|
|
||||||
return returnValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ARC_Chemical_LoadFromString(ARC_Chemical *chemical, ARC_String **string){
|
|
||||||
ARC_Parser_Parse(chemical->parser, string);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ARC_Chemical_LoadFromFile(ARC_Chemical *chemical, ARC_String *path){
|
|
||||||
ARC_Parser_ParseFile(chemical->parser, path);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ARC_Chemical_UnloadFromString(ARC_Chemical *chemical, ARC_String **string){
|
|
||||||
}
|
|
||||||
|
|
||||||
void ARC_Chemical_UnloadFromFile(ARC_Chemical *chemical, ARC_String *data){
|
|
||||||
}
|
|
||||||
|
|
||||||
1262
src/std/config.c
1262
src/std/config.c
File diff suppressed because it is too large
Load diff
213
src/std/entity.c
Normal file
213
src/std/entity.c
Normal file
|
|
@ -0,0 +1,213 @@
|
||||||
|
#include "arc/std/entity.h"
|
||||||
|
#include "arc/std/array.h"
|
||||||
|
#include "arc/std/errno.h"
|
||||||
|
#include "arc/std/bool.h"
|
||||||
|
#include "arc/std/vector/inline.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
//TODO: might want to change how vector holds data for speed
|
||||||
|
struct ARC_EntitySystem {
|
||||||
|
//entity data
|
||||||
|
ARC_VectorInline *flagVector;
|
||||||
|
ARC_VectorInline *maskVector;
|
||||||
|
|
||||||
|
//component data
|
||||||
|
ARC_VectorInline *offsetVector;
|
||||||
|
ARC_VectorInline *sizeVector;
|
||||||
|
|
||||||
|
//stored component data
|
||||||
|
ARC_VectorInline *data;
|
||||||
|
|
||||||
|
//TODO: this would probs be better to use a queue
|
||||||
|
ARC_VectorInline *freeEntities;
|
||||||
|
|
||||||
|
//temporary array for the query function
|
||||||
|
ARC_Entity *query;
|
||||||
|
};
|
||||||
|
|
||||||
|
void ARC_EntitySystem_Create(ARC_EntitySystem **entitySystem){
|
||||||
|
*entitySystem = (ARC_EntitySystem *)malloc(sizeof(ARC_EntitySystem));
|
||||||
|
|
||||||
|
ARC_VectorInline_Create(&((*entitySystem)->flagVector) , sizeof(uint8_t) , NULL, NULL);
|
||||||
|
ARC_VectorInline_Create(&((*entitySystem)->maskVector) , sizeof(uint32_t), NULL, NULL);
|
||||||
|
ARC_VectorInline_Create(&((*entitySystem)->offsetVector), sizeof(uint32_t), NULL, NULL);
|
||||||
|
ARC_VectorInline_Create(&((*entitySystem)->sizeVector) , sizeof(uint32_t), NULL, NULL);
|
||||||
|
|
||||||
|
//can't create the data vector because no components have been registered
|
||||||
|
(*entitySystem)->data = NULL;
|
||||||
|
|
||||||
|
//TODO: this would probs be better to use a queue
|
||||||
|
ARC_VectorInline_Create(&((*entitySystem)->freeEntities), sizeof(ARC_Entity), NULL, NULL);
|
||||||
|
|
||||||
|
//init an empty query
|
||||||
|
(*entitySystem)->query = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ARC_EntitySystem_Destroy(ARC_EntitySystem *entitySystem){
|
||||||
|
if(entitySystem->query != NULL){
|
||||||
|
free(entitySystem->query);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(entitySystem->data != NULL){
|
||||||
|
ARC_VectorInline_Destroy(entitySystem->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
ARC_VectorInline_Destroy(entitySystem->sizeVector);
|
||||||
|
ARC_VectorInline_Destroy(entitySystem->offsetVector);
|
||||||
|
ARC_VectorInline_Destroy(entitySystem->maskVector);
|
||||||
|
ARC_VectorInline_Destroy(entitySystem->flagVector);
|
||||||
|
|
||||||
|
free(entitySystem);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ARC_EntitySystem_RegisterComponent(ARC_EntitySystem *entitySystem, uint32_t componentSize){
|
||||||
|
//error if componentSize is zero, it must have been an error because a component is a type, and types have size
|
||||||
|
if(componentSize == 0){
|
||||||
|
arc_errno = ARC_ERRNO_NULL;
|
||||||
|
ARC_DEBUG_LOG_ERROR("ARC_EntitySystem_RegisterComponent(entitySystem, componentSize), cannot add a component that does not have a size");
|
||||||
|
return ~(uint32_t)0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if data exists, free it to recreate it with the new size
|
||||||
|
if(entitySystem->data != NULL){
|
||||||
|
ARC_VectorInline_Destroy(entitySystem->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
//get the total component size
|
||||||
|
uint32_t offsetEndIndex = ARC_VectorInline_GetSize(entitySystem->offsetVector);
|
||||||
|
uint32_t totalSize = *(uint32_t *)ARC_VectorInline_Get(entitySystem->offsetVector, offsetEndIndex);
|
||||||
|
|
||||||
|
//if the new component size would overflow, throw an error
|
||||||
|
if(totalSize > (~(uint32_t)0) - componentSize){
|
||||||
|
arc_errno = ARC_ERRNO_NULL;
|
||||||
|
ARC_DEBUG_LOG_ERROR("ARC_EntitySystem_RegisterComponent(entitySystem, componentSize), cannot add a component because combined size with all the other components is bigger than a uint32_t max val");
|
||||||
|
return ~(uint32_t)0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//add the component size to the total size and the offset vector array
|
||||||
|
ARC_VectorInline_Add(entitySystem->offsetVector, &totalSize);
|
||||||
|
ARC_VectorInline_Add(entitySystem->sizeVector , &componentSize);
|
||||||
|
totalSize += componentSize;
|
||||||
|
|
||||||
|
//create the resized data vector that can now house the registered component
|
||||||
|
ARC_VectorInline_Create(&(entitySystem->data), totalSize, NULL, NULL);
|
||||||
|
|
||||||
|
//get the id (last index) in the offset vector
|
||||||
|
return ARC_VectorInline_GetSize(entitySystem->offsetVector) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ARC_Entity ARC_EntitySystem_InitEntity(ARC_EntitySystem *entitySystem){
|
||||||
|
//check if there is a free id to use
|
||||||
|
if(ARC_VectorInline_GetSize(entitySystem->freeEntities) != 0){
|
||||||
|
//get the next free entity and remove the used id from the free entities
|
||||||
|
ARC_Entity entity = *(ARC_Entity *)ARC_VectorInline_Get(entitySystem->freeEntities, 0);
|
||||||
|
ARC_VectorInline_RemoveIndex(entitySystem->freeEntities, 0);
|
||||||
|
|
||||||
|
//set the flag to make the current entity alive
|
||||||
|
uint8_t *flagData = (uint8_t *)ARC_VectorInline_Get(entitySystem->flagVector, (uint32_t)entity);
|
||||||
|
*flagData = (uint8_t)ARC_ENTITY_ALIVE;
|
||||||
|
|
||||||
|
//reset the mask data to clear all the components
|
||||||
|
uint8_t *maskData = (uint8_t *)ARC_VectorInline_Get(entitySystem->maskVector, (uint32_t)entity);
|
||||||
|
*maskData = 0;
|
||||||
|
|
||||||
|
//return the entity
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
//get the next free entity
|
||||||
|
ARC_Entity entity = (ARC_Entity)ARC_VectorInline_GetSize(entitySystem->data);
|
||||||
|
//TODO: check if this works
|
||||||
|
ARC_VectorInline_Add(entitySystem->data, NULL);
|
||||||
|
|
||||||
|
//set the flag to make the current entity alive
|
||||||
|
uint8_t *flagData = (uint8_t *)ARC_VectorInline_Get(entitySystem->flagVector, (uint32_t)entity);
|
||||||
|
*flagData = (uint8_t)ARC_ENTITY_ALIVE;
|
||||||
|
|
||||||
|
//reset the mask data to clear all the components
|
||||||
|
uint8_t *maskData = (uint8_t *)ARC_VectorInline_Get(entitySystem->maskVector, (uint32_t)entity);
|
||||||
|
*maskData = 0;
|
||||||
|
|
||||||
|
//return the entity
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ARC_EntitySystem_ReleaseEntity(ARC_EntitySystem *entitySystem, ARC_Entity entity){
|
||||||
|
//set the flag to make the current entity dead
|
||||||
|
uint8_t *flagData = (uint8_t *)ARC_VectorInline_Get(entitySystem->flagVector, (uint32_t)entity);
|
||||||
|
*flagData = (uint8_t)ARC_ENTITY_DEAD;
|
||||||
|
|
||||||
|
//add the entity to the free entities vector
|
||||||
|
ARC_VectorInline_Add(entitySystem->freeEntities, &entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ARC_EntitySystem_AddComponent(ARC_EntitySystem *entitySystem, ARC_Entity entity, ARC_EntityComponent component, void *data){
|
||||||
|
//get the component data to set
|
||||||
|
uint32_t componentSize = *(uint32_t *)ARC_VectorInline_Get(entitySystem->sizeVector, (uint32_t)component);
|
||||||
|
void *componentData = ARC_EntitySystem_GetComponentData(entitySystem, entity, component);
|
||||||
|
|
||||||
|
//set the component in the entity mask
|
||||||
|
uint32_t *maskData = (uint32_t *)ARC_VectorInline_Get(entitySystem->maskVector, (uint32_t)entity);
|
||||||
|
*maskData |= 1 << (uint32_t)component;
|
||||||
|
|
||||||
|
//copy the data into the component
|
||||||
|
memcpy(componentData, data, componentSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
ARC_Bool ARC_EntitySystem_HasComponent(ARC_EntitySystem *entitySystem, ARC_Entity entity, ARC_EntityComponent component){
|
||||||
|
//get the mask, then check if it holds a component
|
||||||
|
uint32_t *maskData = (uint32_t *)ARC_VectorInline_Get(entitySystem->maskVector, (uint32_t)entity);
|
||||||
|
return (ARC_Bool)((*maskData & (1 << (uint32_t)component)) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *ARC_EntitySystem_GetComponentData(ARC_EntitySystem *entitySystem, ARC_Entity entity, ARC_EntityComponent component){
|
||||||
|
//get the entity row, then offset that for the component to get the component data
|
||||||
|
void *data = ARC_VectorInline_Get(entitySystem->data, (uint32_t)entity);
|
||||||
|
return data + *(int32_t *)ARC_VectorInline_Get(entitySystem->offsetVector, (uint32_t)component);
|
||||||
|
}
|
||||||
|
|
||||||
|
ARC_Array ARC_EntitySystem_QueryComponentsData(ARC_EntitySystem *entitySystem, ARC_Array components){
|
||||||
|
//get the mask for all the components
|
||||||
|
ARC_EntityComponent componentsMask = 0;
|
||||||
|
for(uint32_t index = 0; index < components.size; index++){
|
||||||
|
componentsMask |= (1 << ((ARC_EntityComponent *)components.data)[index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//setup teh components data and get a return size
|
||||||
|
uint32_t maxEntitySize = ARC_VectorInline_GetSize(entitySystem->data) - ARC_VectorInline_GetSize(entitySystem->freeEntities);
|
||||||
|
|
||||||
|
//clear the query if it already exists
|
||||||
|
if(entitySystem->query != NULL){
|
||||||
|
free(entitySystem->query);
|
||||||
|
}
|
||||||
|
|
||||||
|
//reserve space for the query
|
||||||
|
entitySystem->query = (ARC_Entity *)malloc(sizeof(ARC_Entity) * maxEntitySize);
|
||||||
|
|
||||||
|
//get all the alive entities that match the components
|
||||||
|
uint32_t queryIndex = 0;
|
||||||
|
for(uint32_t index = 0; index < ARC_VectorInline_GetSize(entitySystem->data); index++){
|
||||||
|
uint8_t entityFlag = *(uint8_t *)ARC_VectorInline_Get(entitySystem->flagVector, index);
|
||||||
|
if((entityFlag & ARC_ENTITY_DEAD) != 0){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if the entity's component mask matches the components passed in
|
||||||
|
uint32_t entityComponentMask = *(uint32_t *)ARC_VectorInline_Get(entitySystem->maskVector, index);
|
||||||
|
if((entityComponentMask & componentsMask) == componentsMask){
|
||||||
|
//set the value at the queryIndex
|
||||||
|
entitySystem->query[queryIndex] = index;
|
||||||
|
queryIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//set components data to the query array
|
||||||
|
ARC_Array componentsData = {
|
||||||
|
queryIndex,
|
||||||
|
entitySystem->query
|
||||||
|
};
|
||||||
|
|
||||||
|
//return the ids that hold all the components
|
||||||
|
return componentsData;
|
||||||
|
}
|
||||||
|
|
@ -406,6 +406,25 @@ void *ARC_Hashtable_Get(ARC_Hashtable *hashtable, void *key){
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t ARC_Hashtable_GetSize(ARC_Hashtable *hashtable){
|
||||||
|
uint32_t size = 0;
|
||||||
|
|
||||||
|
//loop through the vector and add iterate the size when the value is not null
|
||||||
|
for(uint32_t index = 0; index < hashtable->currentCapacity; index++){
|
||||||
|
//get the current node
|
||||||
|
ARC_HashtableNode node = hashtable->nodes[index];
|
||||||
|
|
||||||
|
//skip past NULL keys
|
||||||
|
if(node.key == NULL){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
size++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
void ARC_Hashtable_RunIteration(ARC_Hashtable *hashtable, ARC_Hashtable_IteratorFn iteratorFn, void *userData){
|
void ARC_Hashtable_RunIteration(ARC_Hashtable *hashtable, ARC_Hashtable_IteratorFn iteratorFn, void *userData){
|
||||||
//pass each non NULL nodes into an iteratorFn callback
|
//pass each non NULL nodes into an iteratorFn callback
|
||||||
for(uint32_t index = 0; index < hashtable->currentCapacity; index++){
|
for(uint32_t index = 0; index < hashtable->currentCapacity; index++){
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
#include "arc/std/vector.h"
|
#include "arc/std/vector.h"
|
||||||
|
|
||||||
#include "arc/std/bool.h"
|
#include "arc/std/bool.h"
|
||||||
|
|
|
||||||
176
src/std/vector/inline.c
Normal file
176
src/std/vector/inline.c
Normal file
|
|
@ -0,0 +1,176 @@
|
||||||
|
#include "arc/std/vector/inline.h"
|
||||||
|
|
||||||
|
#include "arc/std/array.h"
|
||||||
|
#include "arc/std/bool.h"
|
||||||
|
#include "arc/std/errno.h"
|
||||||
|
#include "arc/std/vector.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
struct ARC_VectorInline {
|
||||||
|
uint32_t currentCapacity;
|
||||||
|
uint32_t currentSize;
|
||||||
|
uint32_t typeSize;
|
||||||
|
|
||||||
|
void *data;
|
||||||
|
|
||||||
|
ARC_Vector_CompareDataFn compareDataFn;
|
||||||
|
ARC_Vector_DestroyDataFn *destroyDataFn;
|
||||||
|
};
|
||||||
|
|
||||||
|
void ARC_VectorInline_Create(ARC_VectorInline **vectorInline, uint32_t typeSize, ARC_Vector_CompareDataFn *compareDataFn, ARC_Vector_DestroyDataFn *destroyDataFn){
|
||||||
|
//error if no type size was provided
|
||||||
|
if(typeSize == 0){
|
||||||
|
arc_errno = ARC_ERRNO_NULL;
|
||||||
|
ARC_DEBUG_LOG_ERROR("ARC_VectorInline_Create(vectorInline, typeSize, compareDataFn, destroyDataFn), vector inline could not be created with typeSize 0");
|
||||||
|
*vectorInline = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//create the vector
|
||||||
|
*vectorInline = (ARC_VectorInline *)malloc(sizeof(ARC_VectorInline));
|
||||||
|
|
||||||
|
//initialize all the values stored in the vector
|
||||||
|
(*vectorInline)->data = (void *)malloc(typeSize);
|
||||||
|
(*vectorInline)->currentCapacity = 1;
|
||||||
|
(*vectorInline)->currentSize = 0;
|
||||||
|
(*vectorInline)->typeSize = typeSize;
|
||||||
|
|
||||||
|
//set a default for compareDataFn, then override it if it is passed in through parameters
|
||||||
|
(*vectorInline)->compareDataFn = NULL;
|
||||||
|
if(compareDataFn != NULL){
|
||||||
|
(*vectorInline)->compareDataFn = *compareDataFn;
|
||||||
|
}
|
||||||
|
|
||||||
|
//set NULL as a default for deleteDataFn, then copy the delete data function callback if it exists
|
||||||
|
(*vectorInline)->destroyDataFn = NULL;
|
||||||
|
if(destroyDataFn != NULL){
|
||||||
|
(*vectorInline)->destroyDataFn = (ARC_Vector_DestroyDataFn *)malloc(sizeof(ARC_Vector_DestroyDataFn));
|
||||||
|
*((*vectorInline)->destroyDataFn) = *destroyDataFn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ARC_VectorInline_Destroy(ARC_VectorInline *vectorInline){
|
||||||
|
//remove all the contents before destroying the vector
|
||||||
|
ARC_VectorInline_Clear(vectorInline);
|
||||||
|
|
||||||
|
//free the delete data function if it exists
|
||||||
|
if(vectorInline->destroyDataFn != NULL){
|
||||||
|
free(vectorInline->destroyDataFn);
|
||||||
|
}
|
||||||
|
|
||||||
|
//free everything stored in the vector
|
||||||
|
free(vectorInline->data);
|
||||||
|
|
||||||
|
//free the vector
|
||||||
|
free(vectorInline);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ARC_VectorInline_Add(ARC_VectorInline *vectorInline, void *data){
|
||||||
|
//check to see if the current size is the same as a max uint32_t and if so it will overflow so throw an error
|
||||||
|
if(vectorInline->currentSize == ~((uint32_t)0)){
|
||||||
|
arc_errno = ARC_ERRNO_OVERFLOW;
|
||||||
|
ARC_DEBUG_LOG_ERROR("ARC_VectorInline_Add(vectorInline, data), vector inline at max capacity tried adding another value");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//check if we are at the max of the current capacity
|
||||||
|
if(vectorInline->currentSize == vectorInline->currentCapacity){
|
||||||
|
//increase the current capacity by double
|
||||||
|
vectorInline->currentCapacity <<= 1;
|
||||||
|
|
||||||
|
//if for some reason the capacity is 0, we should set it to one so we do not error on realloc
|
||||||
|
if(vectorInline->currentCapacity != 0){
|
||||||
|
vectorInline->currentCapacity++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//resize the vectors array and copy the contents at the same time
|
||||||
|
vectorInline->data = (void *)realloc(vectorInline->data, vectorInline->typeSize * vectorInline->currentCapacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
//add to the vectors array and increase its current size
|
||||||
|
memcpy(vectorInline->data + (vectorInline->currentSize * vectorInline->typeSize), data, vectorInline->typeSize);
|
||||||
|
vectorInline->currentSize++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ARC_VectorInline_Remove(ARC_VectorInline *vectorInline, void *data){
|
||||||
|
//error if return function was never set
|
||||||
|
if(vectorInline->compareDataFn == NULL){
|
||||||
|
arc_errno = ARC_ERRNO_NULL;
|
||||||
|
ARC_DEBUG_LOG_ERROR("ARC_VectorInline_Remove(vectorInline, data), vector inline did not have a compare data function set on creation");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//iterate through every item to check to see if it exists
|
||||||
|
for(uint32_t index = 0; index < vectorInline->currentSize; index++){
|
||||||
|
//keep the code cleaner by pulling the current index data into a temp variable
|
||||||
|
void *dataB = vectorInline->data + (vectorInline->typeSize * index);
|
||||||
|
|
||||||
|
//check if the data matches, and if so remove by index
|
||||||
|
if(vectorInline->compareDataFn(data, dataB) == ARC_True){
|
||||||
|
ARC_VectorInline_RemoveIndex(vectorInline, index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ARC_VectorInline_RemoveIndex(ARC_VectorInline *vectorInline, uint32_t index){
|
||||||
|
//check to make sure the given index is in bounds of the vector
|
||||||
|
if(index >= vectorInline->currentSize){
|
||||||
|
arc_errno = ARC_ERRNO_DATA;
|
||||||
|
ARC_DEBUG_LOG_ERROR("ARC_VectorInline_Add(vectorInline, data), vector at max capacity tried adding another value");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//call delete data to clean up item if delete data function exists
|
||||||
|
if(vectorInline->destroyDataFn != NULL){
|
||||||
|
(*(vectorInline->destroyDataFn))(vectorInline->data + index);
|
||||||
|
}
|
||||||
|
|
||||||
|
//we will be using index to iterate as we will not use it again, so we can skip the first part of the for loop
|
||||||
|
for(; index + 1 < vectorInline->currentSize; index++){
|
||||||
|
//override the data from index to the end by shifting it back one
|
||||||
|
memcpy(vectorInline->data + (index * vectorInline->typeSize), vectorInline->data + ((index + 1) * vectorInline->typeSize), vectorInline->typeSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
//we have removed the item so we can decrease the current size
|
||||||
|
vectorInline->currentSize--;
|
||||||
|
|
||||||
|
//if the current size is half the current capacity or the current capacity is at the smallest limit, we do not need to do anything else
|
||||||
|
if(vectorInline->currentSize != vectorInline->currentCapacity >> 1 || vectorInline->currentCapacity == 1){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//half the capacity and copy it into a smaller array
|
||||||
|
vectorInline->currentCapacity >>= 1;
|
||||||
|
vectorInline->data = (void *)realloc(vectorInline->data, vectorInline->typeSize * vectorInline->currentCapacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ARC_VectorInline_Clear(ARC_VectorInline *vectorInline){
|
||||||
|
//remove each item in the vector untill the vector is empty
|
||||||
|
while(ARC_VectorInline_GetSize(vectorInline) != 0){
|
||||||
|
ARC_VectorInline_RemoveIndex(vectorInline, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ARC_VectorInline_GetSize(ARC_VectorInline *vectorInline){
|
||||||
|
return vectorInline->currentSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *ARC_VectorInline_Get(ARC_VectorInline *vectorInline, uint32_t index){
|
||||||
|
//check to make sure the given index is in bounds of the vector
|
||||||
|
if(index >= vectorInline->currentSize){
|
||||||
|
arc_errno = ARC_ERRNO_DATA;
|
||||||
|
ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("ARC_VectorInline_Get(vectorInline, %u), index %u bounds", index, index);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (vectorInline->data + (vectorInline->typeSize * index));
|
||||||
|
}
|
||||||
|
|
||||||
|
ARC_Array ARC_VectorInline_GetData(ARC_VectorInline *vectorInline){
|
||||||
|
return (ARC_Array){
|
||||||
|
vectorInline->currentSize,
|
||||||
|
vectorInline->data
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
group test {
|
group test {
|
||||||
int32 test = 5;
|
int32 test = 5;
|
||||||
|
|
||||||
|
int32 test1 = -7;
|
||||||
}
|
}
|
||||||
|
|
@ -1,87 +0,0 @@
|
||||||
#include "../test.h"
|
|
||||||
#include "arc/std/errno.h"
|
|
||||||
#include "arc/std/chemical.h"
|
|
||||||
#include "arc/std/parser.h"
|
|
||||||
#include "arc/std/parser/helpers.h"
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
static const char *testType = "int32";
|
|
||||||
|
|
||||||
void TEST_ChemicalType_CopyInt32Fn(void **type, ARC_ParserTagToken *parsedData, ARC_Chemical *chemical){
|
|
||||||
ARC_String *int32String;
|
|
||||||
ARC_String_Create(&int32String, NULL, 0);
|
|
||||||
|
|
||||||
ARC_ParserData_HelperRecurseStringAdd(&int32String, parsedData);
|
|
||||||
|
|
||||||
//set the max character size 2,147,483,647 (10 characters) or -2,147,483,648 (11 characters)
|
|
||||||
uint32_t maxInt32Size = 10;
|
|
||||||
if(int32String->data[0] == '-'){
|
|
||||||
maxInt32Size++;
|
|
||||||
}
|
|
||||||
|
|
||||||
//if the string is bigger than the possible size return NULL and error
|
|
||||||
if(int32String->length > maxInt32Size){
|
|
||||||
arc_errno = ARC_ERRNO_DATA;
|
|
||||||
ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("TEST_ChemicalType_CopyInt32Fn(type, parsedData, chemical), size \"%s\" was bigger or smaller than the max 2,147,483,647 or min -2,147,483,648", int32String->data);
|
|
||||||
*type = NULL;
|
|
||||||
ARC_String_Destroy(int32String);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(int32String->length == maxInt32Size){
|
|
||||||
char maxint32CStr[10] = "2147483647";
|
|
||||||
|
|
||||||
//offset starting index and last number if there is a negative
|
|
||||||
uint8_t stringIndex = 0;
|
|
||||||
if(int32String->data[0] == '-'){
|
|
||||||
stringIndex++;
|
|
||||||
maxint32CStr[9]++;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(uint8_t index = 0; index < 10; index++, stringIndex++){
|
|
||||||
if(int32String->data[stringIndex] > maxint32CStr[index]){
|
|
||||||
arc_errno = ARC_ERRNO_DATA;
|
|
||||||
ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("TEST_ChemicalType_CopyInt32Fn(type, parsedData, chemical), size \"%s\" was bigger or smaller than the max 2,147,483,647 or min -2,147,483,648", int32String->data);
|
|
||||||
*type = NULL;
|
|
||||||
ARC_String_Destroy(int32String);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//copy the int32_t
|
|
||||||
*type = malloc(sizeof(int32_t));
|
|
||||||
*(int32_t *)(*type) = (int32_t)ARC_String_ToInt64_t(int32String);
|
|
||||||
|
|
||||||
//cleanup
|
|
||||||
ARC_String_Destroy(int32String);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TEST_ChemicalType_DestroyInt32Fn(void *type){
|
|
||||||
free((int32_t *)type);
|
|
||||||
}
|
|
||||||
|
|
||||||
ARC_TEST(Chemical_BasicTest){
|
|
||||||
ARC_Chemical *chemical;
|
|
||||||
ARC_Chemical_Create(&chemical);
|
|
||||||
|
|
||||||
ARC_CHECK(arc_errno == 0);
|
|
||||||
|
|
||||||
ARC_ChemicalType int32Type = {
|
|
||||||
TEST_ChemicalType_CopyInt32Fn,
|
|
||||||
TEST_ChemicalType_DestroyInt32Fn
|
|
||||||
};
|
|
||||||
ARC_Chemical_RegisterTypeWithCStr(chemical, testType, int32Type);
|
|
||||||
|
|
||||||
char *tempCString = "tests/res/std/chemical/first.chemical";
|
|
||||||
ARC_String *tempString;
|
|
||||||
ARC_String_CreateWithStrlen(&tempString, tempCString);
|
|
||||||
ARC_Chemical_LoadFromFile(chemical, tempString);
|
|
||||||
|
|
||||||
int32_t testVal = *(int32_t *)ARC_Chemical_GetWithCStr(chemical, "test::test");
|
|
||||||
ARC_CHECK(testVal == 5);
|
|
||||||
|
|
||||||
//cleanup
|
|
||||||
ARC_String_Destroy(tempString);
|
|
||||||
ARC_Chemical_Destroy(chemical);
|
|
||||||
}
|
|
||||||
108
tests/std/config.c
Normal file
108
tests/std/config.c
Normal file
|
|
@ -0,0 +1,108 @@
|
||||||
|
#include "../test.h"
|
||||||
|
#include "arc/std/errno.h"
|
||||||
|
#include "arc/std/config.h"
|
||||||
|
#include "arc/std/parser.h"
|
||||||
|
#include "arc/std/parser/helpers.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
static const char *testType = "int32";
|
||||||
|
|
||||||
|
void TEST_configType_CopyInt32Fn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config){
|
||||||
|
//go into the <numberSign> tag
|
||||||
|
ARC_ParserTagToken *childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(parsedData->tagTokens, 0);
|
||||||
|
if(childTagToken->id != ARC_CONFIG_NUMBER_SIGN){
|
||||||
|
arc_errno = ARC_ERRNO_DATA;
|
||||||
|
ARC_DEBUG_LOG_ERROR("TEST_configType_CopyInt32Fn(type, parsedData, config), parsed data was not a <numberSign>");
|
||||||
|
*type = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//check if the first tag is a minus sign and create a string starting with that if it is
|
||||||
|
childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(childTagToken->tagTokens, 0);
|
||||||
|
ARC_String *int32String;
|
||||||
|
ARC_String_Create(&int32String, NULL, 0);
|
||||||
|
if(childTagToken->id == ARC_CONFIG_MINUS){
|
||||||
|
ARC_String_AppendCStringWithStrlen(&int32String, "-");
|
||||||
|
}
|
||||||
|
|
||||||
|
ARC_ParserData_HelperRecurseStringAdd(&int32String, parsedData);
|
||||||
|
|
||||||
|
//set the max character size 2,147,483,647 (10 characters) or -2,147,483,648 (11 characters)
|
||||||
|
uint32_t maxInt32Size = 10;
|
||||||
|
if(int32String->data[0] == '-'){
|
||||||
|
maxInt32Size++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if the string is bigger than the possible size return NULL and error
|
||||||
|
if(int32String->length > maxInt32Size){
|
||||||
|
arc_errno = ARC_ERRNO_DATA;
|
||||||
|
ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("TEST_configType_CopyInt32Fn(type, parsedData, config), size \"%s\" was bigger or smaller than the max 2,147,483,647 or min -2,147,483,648", int32String->data);
|
||||||
|
*type = NULL;
|
||||||
|
ARC_String_Destroy(int32String);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(int32String->length == maxInt32Size){
|
||||||
|
char maxint32CStr[10] = "2147483647";
|
||||||
|
|
||||||
|
//offset starting index and last number if there is a negative
|
||||||
|
uint8_t stringIndex = 0;
|
||||||
|
if(int32String->data[0] == '-'){
|
||||||
|
stringIndex++;
|
||||||
|
maxint32CStr[9]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(uint8_t index = 0; index < 10; index++, stringIndex++){
|
||||||
|
if(int32String->data[stringIndex] > maxint32CStr[index]){
|
||||||
|
arc_errno = ARC_ERRNO_DATA;
|
||||||
|
ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("TEST_configType_CopyInt32Fn(type, parsedData, config), size \"%s\" was bigger or smaller than the max 2,147,483,647 or min -2,147,483,648", int32String->data);
|
||||||
|
*type = NULL;
|
||||||
|
ARC_String_Destroy(int32String);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//copy the int32_t
|
||||||
|
*type = malloc(sizeof(int32_t));
|
||||||
|
*(int32_t *)(*type) = (int32_t)ARC_String_ToInt64_t(int32String);
|
||||||
|
|
||||||
|
//cleanup
|
||||||
|
ARC_String_Destroy(int32String);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TEST_configType_DestroyInt32Fn(void *type){
|
||||||
|
free((int32_t *)type);
|
||||||
|
}
|
||||||
|
|
||||||
|
ARC_TEST(config_BasicTest){
|
||||||
|
ARC_Config *config;
|
||||||
|
ARC_Config_Create(&config);
|
||||||
|
|
||||||
|
ARC_CHECK(arc_errno == 0);
|
||||||
|
|
||||||
|
ARC_ConfigType int32Type = {
|
||||||
|
TEST_configType_CopyInt32Fn,
|
||||||
|
TEST_configType_DestroyInt32Fn
|
||||||
|
};
|
||||||
|
ARC_Config_RegisterTypeWithCStr(config, testType, int32Type);
|
||||||
|
|
||||||
|
char *tempCString = "tests/res/std/config/first.chemical";
|
||||||
|
ARC_String *tempString;
|
||||||
|
ARC_String_CreateWithStrlen(&tempString, tempCString);
|
||||||
|
ARC_Config_LoadFromFile(config, tempString);
|
||||||
|
|
||||||
|
int32_t testVal = *(int32_t *)ARC_Config_GetWithCStr(config, "test::test");
|
||||||
|
ARC_CHECK(testVal == 5);
|
||||||
|
testVal = *(int32_t *)ARC_Config_GetWithCStr(config, "test::test1");
|
||||||
|
ARC_CHECK(testVal == -7);
|
||||||
|
|
||||||
|
ARC_Config_UnloadFromFile(config, tempString);
|
||||||
|
|
||||||
|
void *nullVal = ARC_Config_GetWithCStr(config, "test::test");
|
||||||
|
ARC_CHECK(nullVal == NULL);
|
||||||
|
|
||||||
|
//cleanup
|
||||||
|
ARC_String_Destroy(tempString);
|
||||||
|
ARC_Config_Destroy(config);
|
||||||
|
}
|
||||||
5
tests/std/entity.c
Normal file
5
tests/std/entity.c
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
#include "../test.h"
|
||||||
|
#include "arc/std/entity.h"
|
||||||
|
|
||||||
|
ARC_TEST(Entity_Init){
|
||||||
|
}
|
||||||
|
|
@ -83,7 +83,6 @@ ARC_TEST(Hashtable_Add_Get_Remove){
|
||||||
ARC_CHECK(5 == *(int32_t *)ARC_Hashtable_Get(hashtable, (void *)"key7"));
|
ARC_CHECK(5 == *(int32_t *)ARC_Hashtable_Get(hashtable, (void *)"key7"));
|
||||||
ARC_CHECK(6 == *(int32_t *)ARC_Hashtable_Get(hashtable, (void *)"key8"));
|
ARC_CHECK(6 == *(int32_t *)ARC_Hashtable_Get(hashtable, (void *)"key8"));
|
||||||
|
|
||||||
TEST_Hashtable_Print(hashtable);
|
|
||||||
ARC_Hashtable_Remove(hashtable, (void *)"key2");
|
ARC_Hashtable_Remove(hashtable, (void *)"key2");
|
||||||
|
|
||||||
ARC_CHECK(2 == *(int32_t *)ARC_Hashtable_Get(hashtable, (void *)"key0"));
|
ARC_CHECK(2 == *(int32_t *)ARC_Hashtable_Get(hashtable, (void *)"key0"));
|
||||||
|
|
|
||||||
159
tests/std/vector/inline.c
Normal file
159
tests/std/vector/inline.c
Normal file
|
|
@ -0,0 +1,159 @@
|
||||||
|
#include "../../test.h"
|
||||||
|
#include "arc/std/bool.h"
|
||||||
|
#include "arc/std/errno.h"
|
||||||
|
#include "arc/std/vector/inline.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
ARC_Bool TEST_VectorInline_CompareDataFn(void *dataA, void *dataB){
|
||||||
|
if(*(int32_t *)dataA == *(int32_t *)dataB){
|
||||||
|
return ARC_True;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ARC_False;
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: more tests with destroy data fn added
|
||||||
|
void TEST_VectorInline_DestroyDataFn(void *data){
|
||||||
|
free((int32_t *)data);
|
||||||
|
}
|
||||||
|
|
||||||
|
ARC_TEST(VectorInline_Add_RemoveIndex_Get){
|
||||||
|
ARC_VectorInline *vectorInline;
|
||||||
|
ARC_VectorInline_Create(&vectorInline, sizeof(int32_t), NULL, NULL);
|
||||||
|
|
||||||
|
int32_t val0 = 0;
|
||||||
|
int32_t val1 = 1;
|
||||||
|
int32_t val2 = 2;
|
||||||
|
int32_t val3 = 3;
|
||||||
|
int32_t val4 = 4;
|
||||||
|
|
||||||
|
ARC_VectorInline_Add(vectorInline, &val0);
|
||||||
|
ARC_VectorInline_Add(vectorInline, &val1);
|
||||||
|
ARC_VectorInline_Add(vectorInline, &val2);
|
||||||
|
ARC_VectorInline_Add(vectorInline, &val3);
|
||||||
|
ARC_VectorInline_Add(vectorInline, &val4);
|
||||||
|
|
||||||
|
ARC_CHECK(0 == *(int32_t *)ARC_VectorInline_Get(vectorInline, 0));
|
||||||
|
ARC_CHECK(1 == *(int32_t *)ARC_VectorInline_Get(vectorInline, 1));
|
||||||
|
ARC_CHECK(2 == *(int32_t *)ARC_VectorInline_Get(vectorInline, 2));
|
||||||
|
ARC_CHECK(3 == *(int32_t *)ARC_VectorInline_Get(vectorInline, 3));
|
||||||
|
ARC_CHECK(4 == *(int32_t *)ARC_VectorInline_Get(vectorInline, 4));
|
||||||
|
ARC_VectorInline_RemoveIndex(vectorInline, 0);
|
||||||
|
|
||||||
|
ARC_CHECK(1 == *(int32_t *)ARC_VectorInline_Get(vectorInline, 0));
|
||||||
|
ARC_CHECK(2 == *(int32_t *)ARC_VectorInline_Get(vectorInline, 1));
|
||||||
|
ARC_CHECK(3 == *(int32_t *)ARC_VectorInline_Get(vectorInline, 2));
|
||||||
|
ARC_CHECK(4 == *(int32_t *)ARC_VectorInline_Get(vectorInline, 3));
|
||||||
|
ARC_VectorInline_RemoveIndex(vectorInline, 3);
|
||||||
|
|
||||||
|
ARC_CHECK(1 == *(int32_t *)ARC_VectorInline_Get(vectorInline, 0));
|
||||||
|
ARC_CHECK(2 == *(int32_t *)ARC_VectorInline_Get(vectorInline, 1));
|
||||||
|
ARC_CHECK(3 == *(int32_t *)ARC_VectorInline_Get(vectorInline, 2));
|
||||||
|
ARC_VectorInline_RemoveIndex(vectorInline, 1);
|
||||||
|
|
||||||
|
ARC_CHECK(1 == *(int32_t *)ARC_VectorInline_Get(vectorInline, 0));
|
||||||
|
ARC_CHECK(3 == *(int32_t *)ARC_VectorInline_Get(vectorInline, 1));
|
||||||
|
ARC_VectorInline_RemoveIndex(vectorInline, 1);
|
||||||
|
|
||||||
|
ARC_CHECK(1 == *(int32_t *)ARC_VectorInline_Get(vectorInline, 0));
|
||||||
|
ARC_VectorInline_RemoveIndex(vectorInline, 0);
|
||||||
|
|
||||||
|
ARC_VectorInline_Destroy(vectorInline);
|
||||||
|
}
|
||||||
|
|
||||||
|
ARC_TEST(VectorInline_Add_Remove_Get){
|
||||||
|
ARC_VectorInline *vectorInline;
|
||||||
|
ARC_Vector_CompareDataFn testCompareDataFn = TEST_VectorInline_CompareDataFn;
|
||||||
|
ARC_VectorInline_Create(&vectorInline, sizeof(int32_t), &testCompareDataFn, NULL);
|
||||||
|
|
||||||
|
int32_t val0 = 0;
|
||||||
|
int32_t val1 = 1;
|
||||||
|
int32_t val2 = 2;
|
||||||
|
int32_t val3 = 3;
|
||||||
|
int32_t val4 = 4;
|
||||||
|
|
||||||
|
ARC_VectorInline_Add(vectorInline, &val0);
|
||||||
|
ARC_VectorInline_Add(vectorInline, &val1);
|
||||||
|
ARC_VectorInline_Add(vectorInline, &val2);
|
||||||
|
ARC_VectorInline_Add(vectorInline, &val3);
|
||||||
|
ARC_VectorInline_Add(vectorInline, &val4);
|
||||||
|
|
||||||
|
ARC_CHECK(0 == *(int32_t *)ARC_VectorInline_Get(vectorInline, 0));
|
||||||
|
ARC_CHECK(1 == *(int32_t *)ARC_VectorInline_Get(vectorInline, 1));
|
||||||
|
ARC_CHECK(2 == *(int32_t *)ARC_VectorInline_Get(vectorInline, 2));
|
||||||
|
ARC_CHECK(3 == *(int32_t *)ARC_VectorInline_Get(vectorInline, 3));
|
||||||
|
ARC_CHECK(4 == *(int32_t *)ARC_VectorInline_Get(vectorInline, 4));
|
||||||
|
ARC_VectorInline_Remove(vectorInline, &val0);
|
||||||
|
|
||||||
|
ARC_CHECK(1 == *(int32_t *)ARC_VectorInline_Get(vectorInline, 0));
|
||||||
|
ARC_CHECK(2 == *(int32_t *)ARC_VectorInline_Get(vectorInline, 1));
|
||||||
|
ARC_CHECK(3 == *(int32_t *)ARC_VectorInline_Get(vectorInline, 2));
|
||||||
|
ARC_CHECK(4 == *(int32_t *)ARC_VectorInline_Get(vectorInline, 3));
|
||||||
|
ARC_VectorInline_Remove(vectorInline, &val4);
|
||||||
|
|
||||||
|
ARC_CHECK(1 == *(int32_t *)ARC_VectorInline_Get(vectorInline, 0));
|
||||||
|
ARC_CHECK(2 == *(int32_t *)ARC_VectorInline_Get(vectorInline, 1));
|
||||||
|
ARC_CHECK(3 == *(int32_t *)ARC_VectorInline_Get(vectorInline, 2));
|
||||||
|
ARC_VectorInline_Remove(vectorInline, &val2);
|
||||||
|
|
||||||
|
ARC_CHECK(1 == *(int32_t *)ARC_VectorInline_Get(vectorInline, 0));
|
||||||
|
ARC_CHECK(3 == *(int32_t *)ARC_VectorInline_Get(vectorInline, 1));
|
||||||
|
ARC_VectorInline_Remove(vectorInline, &val1);
|
||||||
|
|
||||||
|
ARC_CHECK(3 == *(int32_t *)ARC_VectorInline_Get(vectorInline, 0));
|
||||||
|
ARC_VectorInline_Remove(vectorInline, &val3);
|
||||||
|
|
||||||
|
ARC_VectorInline_Destroy(vectorInline);
|
||||||
|
}
|
||||||
|
|
||||||
|
ARC_TEST(VectorInline_Add_RemoveIndex_GetSize){
|
||||||
|
ARC_VectorInline *vectorInline;
|
||||||
|
ARC_VectorInline_Create(&vectorInline, sizeof(int32_t), NULL, NULL);
|
||||||
|
|
||||||
|
int32_t val0 = 0;
|
||||||
|
int32_t val1 = 1;
|
||||||
|
int32_t val2 = 2;
|
||||||
|
int32_t val3 = 3;
|
||||||
|
int32_t val4 = 4;
|
||||||
|
|
||||||
|
ARC_VectorInline_Add(vectorInline, &val0);
|
||||||
|
ARC_VectorInline_Add(vectorInline, &val1);
|
||||||
|
ARC_VectorInline_Add(vectorInline, &val2);
|
||||||
|
ARC_VectorInline_Add(vectorInline, &val3);
|
||||||
|
ARC_VectorInline_Add(vectorInline, &val4);
|
||||||
|
|
||||||
|
ARC_CHECK(5 == ARC_VectorInline_GetSize(vectorInline));
|
||||||
|
ARC_VectorInline_RemoveIndex(vectorInline, 0);
|
||||||
|
|
||||||
|
ARC_CHECK(4 == ARC_VectorInline_GetSize(vectorInline));
|
||||||
|
ARC_VectorInline_RemoveIndex(vectorInline, 0);
|
||||||
|
|
||||||
|
ARC_CHECK(3 == ARC_VectorInline_GetSize(vectorInline));
|
||||||
|
ARC_VectorInline_RemoveIndex(vectorInline, 0);
|
||||||
|
|
||||||
|
ARC_CHECK(2 == ARC_VectorInline_GetSize(vectorInline));
|
||||||
|
ARC_VectorInline_RemoveIndex(vectorInline, 0);
|
||||||
|
|
||||||
|
ARC_CHECK(1 == ARC_VectorInline_GetSize(vectorInline));
|
||||||
|
ARC_VectorInline_RemoveIndex(vectorInline, 0);
|
||||||
|
|
||||||
|
ARC_CHECK(0 == ARC_VectorInline_GetSize(vectorInline));
|
||||||
|
|
||||||
|
ARC_VectorInline_Destroy(vectorInline);
|
||||||
|
}
|
||||||
|
|
||||||
|
ARC_TEST(VectorInline_Add_RemoveIndex_Get_Try_Out_Of_Bounds){
|
||||||
|
ARC_Vector *vector;
|
||||||
|
ARC_Vector_Create(&vector, NULL, NULL);
|
||||||
|
|
||||||
|
int32_t val0 = 0;
|
||||||
|
|
||||||
|
ARC_Vector_Add(vector, &val0);
|
||||||
|
ARC_CHECK(NULL == ARC_Vector_Get(vector, 1));
|
||||||
|
arc_errno = 0;
|
||||||
|
|
||||||
|
ARC_Vector_RemoveIndex(vector, 0);
|
||||||
|
|
||||||
|
ARC_Vector_Destroy(vector);
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue