diff options
| author | navewindre <boneyaard@gmail.com> | 2025-09-03 20:10:09 +0200 |
|---|---|---|
| committer | navewindre <boneyaard@gmail.com> | 2025-09-03 20:10:09 +0200 |
| commit | f8b92ce3aa08b1445c9f956d8166830946562d12 (patch) | |
| tree | 94e63a5aec9f8f52b577f56799e0c9201fd976a5 /src/util/config.h | |
a
Diffstat (limited to 'src/util/config.h')
| -rw-r--r-- | src/util/config.h | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/src/util/config.h b/src/util/config.h new file mode 100644 index 0000000..7973db0 --- /dev/null +++ b/src/util/config.h @@ -0,0 +1,166 @@ +#pragma once +#include <stdio.h> + +#include "allocator.h" +#include "vector.h" +#include "color.h" + +// config parsers and serializers go here + +struct CFG_NODE; +struct CFG_SECTION; + +struct CFG_PARSER; +struct CFG_SERIALIZER; + +enum CfgNodeType_t { + CFGT_SECTION, + CFGT_BYTES, + CFGT_STR, + CFGT_FLOAT, + CFGT_INT, + CFGT_VEC2, + CFGT_VEC3, + CFGT_CLR +}; + +// ===================================== [ definitions ] =========================================== + +using CFG_PARSEFN = std::function<void( CFG_PARSER*, CFG_SECTION*, char* )>; +using CFG_SERIALIZEFN = std::function<void( CFG_SERIALIZER*, CFG_NODE*, char* )>; + +struct CFG_TYPE { + U8 type; + const char* def; + CFG_PARSEFN parser; + CFG_SERIALIZEFN serializer; +}; + +struct CFG_NODE { + char name[64]; + CFG_NODE* parent; + U8 type; +}; + +struct CFG_SECTION : CFG_NODE { + LIST<CFG_NODE*> children; +}; + +struct CFG_BYTES : CFG_NODE { U8* bytes; U32 size; }; +struct CFG_STR : CFG_NODE { char* str; U32 len; }; +struct CFG_INT : CFG_NODE { I32 value; }; +struct CFG_FLOAT : CFG_NODE { F32 value; }; +struct CFG_VEC2 : CFG_NODE { VEC2 value; }; +struct CFG_VEC3 : CFG_NODE { VEC3 value; }; +struct CFG_CLR : CFG_NODE { CLR value; }; + +// ======================================= [ parsers ] ============================================= + +extern STAT cfg_parser_bytes( CFG_PARSER* parser, CFG_SECTION* section, char* name ); +extern STAT cfg_parser_str( CFG_PARSER* parser, CFG_SECTION* section, char* name ); +extern STAT cfg_parser_int( CFG_PARSER* parser, CFG_SECTION* section, char* name ); +extern STAT cfg_parser_float( CFG_PARSER* parser, CFG_SECTION* section, char* name ); +extern STAT cfg_parser_vec2( CFG_PARSER* parser, CFG_SECTION* section, char* name ); +extern STAT cfg_parser_vec3( CFG_PARSER* parser, CFG_SECTION* section, char* name ); +extern STAT cfg_parser_clr( CFG_PARSER* parser, CFG_SECTION* section, char* name ); + +// ====================================== [ serializers ] ========================================== + +extern void cfg_serialize_section( CFG_SERIALIZER* serializer, CFG_NODE* section, char* buf ); +extern void cfg_serialize_bytes( CFG_SERIALIZER* serializer, CFG_NODE* node, char* buf ); +extern void cfg_serialize_str( CFG_SERIALIZER* serializer, CFG_NODE* node, char* buf ); +extern void cfg_serialize_float( CFG_SERIALIZER* serializer, CFG_NODE* node, char* buf ); +extern void cfg_serialize_int( CFG_SERIALIZER* serializer, CFG_NODE* node, char* buf ); +extern void cfg_serialize_vec2( CFG_SERIALIZER* serializer, CFG_NODE* node, char* buf ); +extern void cfg_serialize_vec3( CFG_SERIALIZER* serializer, CFG_NODE* node, char* buf ); +extern void cfg_serialize_clr( CFG_SERIALIZER* serializer, CFG_NODE* node, char* buf ); + +// ========================================= [ config ] ============================================ + +static const CFG_TYPE cfg_types[] = { + { CFGT_SECTION, "DEF" , 0, &cfg_serialize_section }, // section + { CFGT_BYTES , "U8" , &cfg_parser_bytes, &cfg_serialize_bytes }, + { CFGT_STR , "STR" , &cfg_parser_str , &cfg_serialize_str }, + { CFGT_FLOAT , "F32" , &cfg_parser_float, &cfg_serialize_float }, + { CFGT_INT , "I32" , &cfg_parser_int , &cfg_serialize_int }, + { CFGT_VEC2 , "VEC2", &cfg_parser_vec2 , &cfg_serialize_vec2 }, + { CFGT_VEC3 , "VEC3", &cfg_parser_vec3 , &cfg_serialize_vec3 }, + { CFGT_CLR , "CLR" , &cfg_parser_clr , &cfg_serialize_clr }, +}; +// ========================================= [ io ] ================================================ + +extern CFG_SECTION* cfg_load( const char* path ); +extern STAT cfg_save( CFG_SECTION* root, const char* path ); +static void cfg_free( CFG_NODE* n ); + +// =================================== [ getters/setters ] ========================================= + +// cfg_section_get( CFG_SECTION*, const char* ) -- retrieve function +extern CFG_SECTION* cfg_section( CFG_SECTION* parent, const char* name ); +// cfg_str_get( CFG_SECTION*, const char* ) -- retrieve function +extern CFG_STR* cfg_str( CFG_SECTION* section, const char* name ); +// cfg_bytes_get( CFG_SECTION*, const char* ) -- retrieve function +extern CFG_BYTES* cfg_bytes( CFG_SECTION* section, const char* name ); +// cfg_float_get( CFG_SECTION*, const char* ) -- retrieve function +extern CFG_FLOAT* cfg_float( CFG_SECTION* section, const char* name ); +// cfg_int_get( CFG_SECTION*, const char* ) -- retrieve function +extern CFG_INT* cfg_int( CFG_SECTION* section, const char* name ); +// cfg_vec2_get( CFG_SECTION*, const char* ) -- retrieve function +extern CFG_VEC2* cfg_vec2( CFG_SECTION* section, const char* name ); +// cfg_vec3_get( CFG_SECTION*, const char* ) -- retrieve function +extern CFG_VEC3* cfg_vec3( CFG_SECTION* section, const char* name ); +// cfg_clr_get( CFG_SECTION*, const char* ) -- retrieve function for +extern CFG_CLR* cfg_clr( CFG_SECTION* section, const char* name ); + +// cfg_section_new( const char*, CFG_NODE*, I32 ) -- create function +extern CFG_SECTION* cfg_section_new( const char* name, CFG_NODE* parent ); +// cfg_str_new( const char*, CFG_NODE*, const char*, U32 ) -- create function +extern CFG_STR* cfg_str( const char* name, CFG_NODE* section, const char* value, U32 len ); +// cfg_bytes_new( const char*, CFG_NODE*, U8*, U32 ) -- create function +extern CFG_BYTES* cfg_bytes( const char* name, CFG_NODE* section, U8* value, U32 size ); +// cfg_float_new( const char*, CFG_NODE*, F32 ) -- create function +extern CFG_FLOAT* cfg_float( const char* name, CFG_NODE* section, F32 value ); +// cfg_int_new( const char*, CFG_NODE*, I32 ) -- create function +extern CFG_INT* cfg_int( const char* name, CFG_NODE* section, I32 value ); +// cfg_vec2_new( const char*, CFG_NODE*, VEC2 ) -- create function +extern CFG_VEC2* cfg_vec2( const char* name, CFG_NODE* section, VEC2 value ); +// cfg_vec3_new( const char*, CFG_NODE*, VEC3 ) -- create function +extern CFG_VEC3* cfg_vec3( const char* name, CFG_NODE* section, VEC3 value ); +// cfg_clr_new( const char*, CFG_NODE*, CLR ) -- create function +extern CFG_CLR* cfg_clr( const char* name, CFG_NODE* section, CLR value ); + +// ================================================================================================= + +struct CFG_PARSER { + FILE* file; + CFG_SECTION* root; + char err[256]; + U32 linen; + U8 iserr; +}; + +struct CFG_SERIALIZER { + FILE* f; + U8 iserr; + char err[256]; + U32 tabc; +}; + +static void cfg_free( CFG_NODE* n ) { + if( n->type == CFGT_STR ) { + CFG_STR* str = (CFG_STR*)n; + free( str->str ); + } + else if( n->type == CFGT_BYTES ) { + CFG_BYTES* bytes = (CFG_BYTES*)n; + free( bytes->bytes ); + } + else if( n->type == CFGT_SECTION ) { + CFG_SECTION* s = (CFG_SECTION*)n; + s->children.each( fn( CFG_NODE** child ) { cfg_free( *child ); } ); + } + + delete n; +} + +extern void cfg_seterr( CFG_PARSER* p, const char* fmt, ... ); |
