summaryrefslogtreecommitdiff
path: root/src/util/config.h
diff options
context:
space:
mode:
authornavewindre <boneyaard@gmail.com>2025-09-03 20:10:09 +0200
committernavewindre <boneyaard@gmail.com>2025-09-03 20:10:09 +0200
commitf8b92ce3aa08b1445c9f956d8166830946562d12 (patch)
tree94e63a5aec9f8f52b577f56799e0c9201fd976a5 /src/util/config.h
a
Diffstat (limited to 'src/util/config.h')
-rw-r--r--src/util/config.h166
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, ... );