config.c (2691B)
1 #include <string.h> 2 3 #include "lq/err.h" 4 #include "lq/mem.h" 5 #include "lq/config.h" 6 7 static const int config_core_typs[] = { 8 LQ_TYP_STR, 9 LQ_TYP_STR, 10 LQ_TYP_STR, 11 LQ_TYP_STR, 12 }; 13 14 static const char *config_core_name[] = { 15 "BASEDIR", 16 "CONFIGDIR", 17 "DATADIR", 18 "CACHEDIR", 19 }; 20 21 static char **config_idx; 22 23 static struct config_t { 24 void *mem; ///< Config data memory. 25 void **members; ///< Member pointer. 26 enum lq_typ_e *typs; ///< Member type. 27 size_t last; ///< Last registered members index. 28 size_t cap; ///< Bytes allocated for config content. 29 size_t len; ///< Bytes currently used for content. 30 } config; 31 32 static int core_register() { 33 int i; 34 int r; 35 36 for (i = 0; i < LQ_CFG_LAST; i++) { 37 r = lq_config_register(config_core_typs[i], config_core_name[i]); 38 if (r == -1) { 39 return ERR_INIT; 40 } 41 } 42 return ERR_OK; 43 } 44 45 int lq_config_init() { 46 config.mem = lq_alloc(LQ_CONFIG_MEMCAP); 47 if (config.mem == NULL) { 48 return ERR_MEM; 49 } 50 config.members = lq_alloc(LQ_CONFIG_MAX * sizeof(void**)); 51 if (config.members == NULL) { 52 lq_free(config.mem); 53 return ERR_MEM; 54 } 55 config.typs = lq_alloc(LQ_CONFIG_MAX * sizeof(void*)); 56 if (config.typs == NULL) { 57 lq_free(config.members); 58 lq_free(config.mem); 59 return ERR_MEM; 60 } 61 config_idx = lq_alloc(LQ_CONFIG_MAX * sizeof(char**)); 62 config.last = 0; 63 config.len = 0; 64 config.cap = LQ_CONFIG_MEMCAP; 65 *config.members = config.mem; 66 return core_register(); 67 } 68 69 int lq_config_register(enum lq_typ_e typ, const char *name) { 70 size_t l; 71 72 switch (typ) { 73 case LQ_TYP_VOID: 74 l = sizeof(void*); 75 break; 76 case LQ_TYP_STR: 77 l = sizeof(char*); 78 break; 79 case LQ_TYP_NUM: 80 l = sizeof(long*); 81 break; 82 default: 83 l = 0; 84 } 85 86 if (!l) { 87 return -1; 88 } 89 *(config.typs+config.last) = typ; 90 *(config_idx + config.last) = (char*)name; // name must survive, or NULL for no reverse. 91 l = config.last; 92 config.last++; 93 94 return (int)l; 95 } 96 97 int lq_config_set(int k, void *v) { 98 void *p; 99 size_t l; 100 101 if (k >= config.last) { 102 return ERR_OVERFLOW; 103 } 104 105 switch (*(config.typs+k)) { 106 case LQ_TYP_VOID: 107 l = sizeof(void*); 108 break; 109 case LQ_TYP_STR: 110 l = strlen((char*)v) + 1; 111 break; 112 case LQ_TYP_NUM: 113 l = sizeof(long*); 114 break; 115 default: 116 l = 0; 117 } 118 119 if (config.len + l > config.cap) { 120 return ERR_OVERFLOW; 121 } 122 123 p = config.mem + config.len; 124 *(config.members + k) = p; 125 p = lq_cpy(p, v, l); 126 if (p == NULL) { 127 return ERR_WRITE; 128 } 129 config.len += l; 130 return ERR_OK; 131 } 132 133 int lq_config_get(int k, void **r) { 134 if (k >= config.last) { 135 return ERR_OVERFLOW; 136 } 137 138 *r = *(config.members + k); 139 140 return ERR_OK; 141 } 142 143 void lq_config_free() { 144 lq_free(config_idx); 145 lq_free(config.typs); 146 lq_free(config.members); 147 lq_free(config.mem); 148 }