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 = §->vars.data[vari]; + free(var->name); + } + free(sect->name); + VLB_FREE(sect->vars); + } + VLB_FREE(state->sects); +}