ConfIO

commit dc5b0299996acae631f4d434b7e745bbef8cb556

Author: PQCraft <0456523@gmail.com>

Design improvements and initial work

 Makefile | 4 
 include/confio/confio.h | 83 +++++++++++++++++++++++++---------------
 include/confio/handlers.h | 22 +++++-----
 src/confio.c | 46 ++++++++++++++++++++++


diff --git a/Makefile b/Makefile
index 3669c25fbb6f9bd3184275bcddc91fa492278c3a..fad560f6254d1dcfa196f46cc40a595ebe48f705 100644
--- a/Makefile
+++ b/Makefile
@@ -117,8 +117,8 @@
 $(TARGET_DYNAMIC): $(OBJECTS_DYNAMIC) | $(OUTDIR)
 	@echo Linking $@...
 	@$(_LD) $(_LDFLAGS) -shared $^ $(_LDLIBS) -o $@
-	-@cd $(OUTDIR) && ln -s $(BIN_DYNAMIC).$(VER) $(BIN_DYNAMIC).$(VER_MAJOR)
-	-@cd $(OUTDIR) && ln -s $(BIN_DYNAMIC).$(VER_MAJOR) $(BIN_DYNAMIC)
+	-@cd -- $(OUTDIR) && [ -e $(BIN_DYNAMIC).$(VER_MAJOR) ] || ln -s -- $(BIN_DYNAMIC).$(VER) $(BIN_DYNAMIC).$(VER_MAJOR)
+	-@cd -- $(OUTDIR) && [ -e $(BIN_DYNAMIC) ] || ln -s -- $(BIN_DYNAMIC).$(VER_MAJOR) $(BIN_DYNAMIC)
 	@echo Linked $@
 
 clean:




diff --git a/include/confio/confio.h b/include/confio/confio.h
index 861489a09a161d93fb32c29cf4d27ead710a2ec4..4595a61520f2b95cb37d2df858420ee847f91506 100644
--- a/include/confio/confio.h
+++ b/include/confio/confio.h
@@ -1,53 +1,72 @@
 #ifndef CONFIO_H
 #define CONFIO_H
 
-#include <stdio.h> /* TODO: 'NO_STDIO' option */
-#include <stdbool.h>
+#include <stddef.h>
 
 #include "version.h"
 
-// Get the version (useless for static linking, slightly useful for dynamic linking)
-// - returns a pointer to {major, minor, patch}
-const unsigned* ConfIO_GetVersion(void);
+typedef struct ConfIO ConfIO;
+
+typedef unsigned ConfIO_Bool;
+typedef unsigned char ConfIO_SmallBool;
 
-// Called when a var is being read in
-// - return false to indicate an error
-typedef bool ConfIO_ReadVarFunc(void* ctx, const char* val, size_t len);
-typedef ConfIO_ReadVarFunc* ConfIO_ReadVar;
-// Called when a var is being written out
+// Called when a var is being read in or set
+// - Return false to indicate an error
+typedef ConfIO_Bool ConfIO_SetterFunc(void* ctx, size_t len, const char* val);
+typedef ConfIO_SetterFunc* ConfIO_Setter;
+// Called when a var is being written out or queried
 // - *len is initialized to -1 which indicates that strlen() should be called on the return value if it is non-NULL
-// - return NULL to indicate an error
-typedef const char* ConfIO_WriteVarFunc(void* ctx, size_t* len);
-typedef ConfIO_WriteVarFunc* ConfIO_WriteVar;
+// - Return NULL to indicate an error
+typedef const char* ConfIO_GetterFunc(void* ctx, size_t* len);
+typedef ConfIO_GetterFunc* ConfIO_Getter;
+
+// Callback to read config file text
+// - Return the amount read, 0 when done, or -1 on error
+typedef size_t (*ConfIO_Reader)(void* ctx, size_t len, void* data);
+// Callback to write config file text
+// - Return the amount written, or -1 on error
+typedef size_t (*ConfIO_Writer)(void* ctx, size_t len, const void* data);
 
-typedef struct ConfIO ConfIO;
+// Get the version (useless for static linking, slightly useful for dynamic linking)
+// - Returns a pointer to {major, minor, patch}
+const unsigned* ConfIO_GetVersion(void);
 
+// Create a ConfIO context
+// - Returns NULL on failure
 ConfIO* ConfIO_New(void);
+// Destroy a ConfIO context
 void ConfIO_Del(ConfIO*);
 
 // Set the handlers for a variable
-// - if 'sectLen' is -1, use strlen() to get the length of 'sect'
-// - if 'varLen' is -1, use strlen() to get the length of 'var'
-bool ConfIO_SetHandlers(
-	ConfIO*, char* sect, size_t sectLen, char* var, size_t varLen,
-	ConfIO_ReadVar, void* readVarCtx, ConfIO_WriteVar, void* writeVarCtx
+// - If 'sectLen' is -1, use strlen() to get the length of 'sect'
+// - If 'varLen' is -1, use strlen() to get the length of 'var'
+// - NULL can be given for 'setter' and 'getter' to assign none
+ConfIO_Bool ConfIO_SetHandlers(
+	ConfIO*,
+	size_t sectLen, char* sect, size_t varLen, char* var,
+	ConfIO_Setter setter, void* setterCtx, ConfIO_Getter getter, void* getterCtx
 );
 
-// Read in a file
-bool ConfIO_ReadFile(ConfIO*, FILE*);
-// Write out a file
-bool ConfIO_WriteFile(ConfIO*, FILE*);
-// TODO: ReadStream and WriteStream
+// Read in a config
+ConfIO_Bool ConfIO_ReadConfig(ConfIO*, ConfIO_Reader, void* ctx);
+// Write out a config
+ConfIO_Bool ConfIO_WriteConfig(ConfIO*, ConfIO_Writer, void* ctx);
+#ifndef CONFIO_NO_STDIO
+    // Read in a config file (wrapper around ReadConfig)
+    ConfIO_Bool ConfIO_ReadFile(ConfIO*, const char* path);
+    // Write out a config file (wrapper around WriteConfig)
+    ConfIO_Bool ConfIO_WriteFile(ConfIO*, const char* path);
+#endif
 
-// Set a variable by calling its ReadVar handler
-// - if 'sectLen' is -1, use strlen() to get the length of 'sect'
-// - if 'varLen' is -1, use strlen() to get the length of 'var'
-// - returns false if no ReadVar handler is set, or the handler indicates an error
-bool ConfIO_SetVar(ConfIO*, char* sect, size_t sectLen, char* var, size_t varLen, const char* val, size_t valLen);
-// Get a variable by calling its WriteVar handler
+// Set a variable by calling its setter
+// - If 'sectLen' is -1, use strlen() to get the length of 'sect'
+// - If 'varLen' is -1, use strlen() to get the length of 'var'
+// - Returns false if no setter is assigned, or the handler indicates an error
+ConfIO_Bool ConfIO_SetVar(ConfIO*, size_t sectLen, char* sect, size_t varLen, char* var, size_t valLen, const char* val);
+// Get a variable by calling its getter
 // - 'valLen' can be NULL if you do not want strlen() to be called if the handler outputs a 'len' of -1
-// - returns NULL if no WriteVar handler is set, or the handler indicates an error
-const char* ConfIO_GetVar(ConfIO*, char* sect, size_t sectLen, char* var, size_t varLen, size_t* valLen);
+// - Returns NULL if no getter is assigned, or the handler indicates an error
+const char* ConfIO_GetVar(ConfIO*, size_t sectLen, char* sect, size_t varLen, char* var, size_t* valLen);
 
 #ifndef CONFIO_NO_DEFAULT_HANDLERS
 	// Includes the default ConfIO_{Read|Write}Var_... handlers




diff --git a/include/confio/handlers.h b/include/confio/handlers.h
index 7a9e035a3852251ea94d172d3b612448f945c0ed..d4b211a5b85d9439dde572a9ab738db3926eea0b 100644
--- a/include/confio/handlers.h
+++ b/include/confio/handlers.h
@@ -6,26 +6,26 @@
 #include <stdint.h>
 
 // Convenience macro for ConfIO_SetHandlers
-#define CONFIO_HANDLERS(TYPE, VAR) ConfIO_ReadVar_##TYPE, &VAR, ConfIO_WriteVar_##TYPE, &VAR
+#define CONFIO_HANDLERS(TYPE, VAR) ConfIO_Setter_##TYPE, &VAR, ConfIO_Getter_##TYPE, &VAR
 
 // char, short, int, long, long long
-ConfIO_ReadVarFunc ConfIO_ReadVar_C, ConfIO_ReadVar_SI, ConfIO_ReadVar_I, ConfIO_ReadVar_LI, ConfIO_ReadVar_LLI;
-ConfIO_WriteVarFunc ConfIO_WriteVar_C, ConfIO_WriteVar_SI, ConfIO_WriteVar_I, ConfIO_WriteVar_LI, ConfIO_WriteVar_LLI;
+ConfIO_SetterFunc ConfIO_Setter_C, ConfIO_Setter_SI, ConfIO_Setter_I, ConfIO_Setter_LI, ConfIO_Setter_LLI;
+ConfIO_GetterFunc ConfIO_Getter_C, ConfIO_Getter_SI, ConfIO_Getter_I, ConfIO_Getter_LI, ConfIO_Getter_LLI;
 
 // unsigned char, short unsigned, unsigned, long unsigned, long long unsigned
-ConfIO_ReadVarFunc ConfIO_ReadVar_UC, ConfIO_ReadVar_SU, ConfIO_ReadVar_U, ConfIO_ReadVar_LU, ConfIO_ReadVar_LLU;
-ConfIO_WriteVarFunc ConfIO_WriteVar_UC, ConfIO_WriteVar_SU, ConfIO_WriteVar_U, ConfIO_WriteVar_LU, ConfIO_WriteVar_LLU;
+ConfIO_SetterFunc ConfIO_Setter_UC, ConfIO_Setter_SU, ConfIO_Setter_U, ConfIO_Setter_LU, ConfIO_Setter_LLU;
+ConfIO_GetterFunc ConfIO_Getter_UC, ConfIO_Getter_SU, ConfIO_Getter_U, ConfIO_Getter_LU, ConfIO_Getter_LLU;
 
 // float, double, long double
-ConfIO_ReadVarFunc ConfIO_ReadVar_F, ConfIO_ReadVar_D, ConfIO_ReadVar_LD;
-ConfIO_WriteVarFunc ConfIO_WriteVar_F, ConfIO_WriteVar_D, ConfIO_WriteVar_LD;
+ConfIO_SetterFunc ConfIO_Setter_F, ConfIO_Setter_D, ConfIO_Setter_LD;
+ConfIO_GetterFunc ConfIO_Getter_F, ConfIO_Getter_D, ConfIO_Getter_LD;
 
 // int8_t, int16_t, int32_t, int64_t
-ConfIO_ReadVarFunc ConfIO_ReadVar_I8, ConfIO_ReadVar_I16, ConfIO_ReadVar_I32, ConfIO_ReadVar_I64;
-ConfIO_WriteVarFunc ConfIO_WriteVar_I8, ConfIO_WriteVar_I16, ConfIO_WriteVar_I32, ConfIO_WriteVar_I64;
+ConfIO_SetterFunc ConfIO_Setter_I8, ConfIO_Setter_I16, ConfIO_Setter_I32, ConfIO_Setter_I64;
+ConfIO_GetterFunc ConfIO_Getter_I8, ConfIO_Getter_I16, ConfIO_Getter_I32, ConfIO_Getter_I64;
 
 // uint8_t, uint16_t, uint32_t, uint64_t
-ConfIO_ReadVarFunc ConfIO_ReadVar_U8, ConfIO_ReadVar_U16, ConfIO_ReadVar_U32, ConfIO_ReadVar_U64;
-ConfIO_WriteVarFunc ConfIO_WriteVar_U8, ConfIO_WriteVar_U16, ConfIO_WriteVar_U32, ConfIO_WriteVar_U64;
+ConfIO_SetterFunc ConfIO_Setter_U8, ConfIO_Setter_U16, ConfIO_Setter_U32, ConfIO_Setter_U64;
+ConfIO_GetterFunc ConfIO_Getter_U8, ConfIO_Getter_U16, ConfIO_Getter_U32, ConfIO_Getter_U64;
 
 #endif




diff --git a/src/confio.c b/src/confio.c
index 1f143d3d1a86907d0694a7e2350c34836787b66a..a16e99c69b0a1d7396212d39d393490c7dabecad 100644
--- a/src/confio.c
+++ b/src/confio.c
@@ -1,5 +1,28 @@
 #include <confio/confio.h>
 
+#include <stdint.h>
+
+#include "vlb.h"
+
+typedef struct {
+    char* name;
+    size_t nameLen;
+    uint32_t nameCrc;
+    ConfIO_Setter setter;
+    void* setterCtx;
+    ConfIO_Getter getter;
+    void* getterCtx;
+} ConfIO_VarData;
+typedef struct {
+    char* name;
+    size_t nameLen;
+    uint32_t nameCrc;
+    struct VLB(ConfIO_VarData) vars;
+} ConfIO_SectData;
+struct ConfIO {
+    struct VLB(ConfIO_SectData) sects;
+};
+
 const unsigned* ConfIO_GetVersion(void) {
 	static const unsigned ver[3] = {
 		CONFIO_VER_MAJOR,
@@ -8,3 +31,26 @@ 		CONFIO_VER_PATCH
 	};
 	return ver;
 }
+
+ConfIO* ConfIO_New(void) {
+    #if 1 /* Fast */
+        return calloc(1, sizeof(ConfIO));
+    #else /* Proper (for if there are fields in the state that need to be init to a non-zero value) */
+        ConfIO* state = malloc(sizeof(*state));
+        if (!state) return NULL;
+        VLB_ZINIT(state->sects);
+        return state;
+    #endif
+}
+void ConfIO_Del(ConfIO* state) {
+    for (size_t secti = 0; secti < state->sects.len; ++secti) {
+        ConfIO_SectData* sect = &state->sects.data[secti];
+        for (size_t vari = 0; vari < sect->vars.len; ++vari) {
+            ConfIO_VarData* var = &sect->vars.data[vari];
+            free(var->name);
+        }
+        free(sect->name);
+        VLB_FREE(sect->vars);
+    }
+    VLB_FREE(state->sects);
+}