📄 scconf.c
字号:
while (list) { len++; list = list->next; } return len;}int scconf_list_strings_length(const scconf_list * list){ int len = 0; while (list && list->data) { len += strlen(list->data) + 1; list = list->next; } return len;}char *scconf_list_strdup(const scconf_list * list, const char *filler){ char *buf = NULL; int len = 0; if (!list) { return NULL; } len = scconf_list_strings_length(list); if (filler) { len += scconf_list_array_length(list) * (strlen(filler) + 1); } buf = (char *) malloc(len); if (!buf) { return NULL; } memset(buf, 0, len); while (list && list->data) { strcat(buf, list->data); if (filler) { strcat(buf, filler); } list = list->next; } if (filler) buf[strlen(buf) - strlen(filler)] = '\0'; return buf;}static scconf_block **getblocks(const scconf_context * config, const scconf_block * block, scconf_entry * entry){ scconf_block **blocks = NULL; blocks = scconf_find_blocks(config, block, entry->name, NULL); if (blocks) { if (blocks[0] != NULL) { if (config->debug) { fprintf(stderr, "block found (%s)\n", entry->name); } return blocks; } free(blocks); blocks = NULL; } if (scconf_find_list(block, entry->name) != NULL) { if (config->debug) { fprintf(stderr, "list found (%s)\n", entry->name); } blocks = (scconf_block **) realloc(blocks, sizeof(scconf_block *) * 2); if (!blocks) return NULL; blocks[0] = (scconf_block *) block; blocks[1] = NULL; } return blocks;}static int parse_entries(const scconf_context * config, const scconf_block * block, scconf_entry * entry, int depth);static int parse_type(const scconf_context * config, const scconf_block * block, scconf_entry * entry, int depth){ void *parm = entry->parm; size_t *len = (size_t *) entry->arg; int (*callback_func) (const scconf_context * config, const scconf_block * block, scconf_entry * entry, int depth) = (int (*)(const scconf_context *, const scconf_block *, scconf_entry *, int)) parm; int r = 0; if (config->debug) { fprintf(stderr, "decoding '%s'\n", entry->name); } switch (entry->type) { case SCCONF_CALLBACK: if (parm) { r = callback_func(config, block, entry, depth); } break; case SCCONF_BLOCK: if (parm) { r = parse_entries(config, block, (scconf_entry *) parm, depth + 1); } break; case SCCONF_LIST: { const scconf_list *val = scconf_find_list(block, entry->name); if (!val) { r = 1; break; } if (parm) { if (entry->flags & SCCONF_ALLOC) { scconf_list *dest = NULL; for (; val != NULL; val = val->next) { if (!scconf_list_add(&dest, val->data)) { r = 1; break; } } *((scconf_list **) parm) = dest; } else { *((const scconf_list **) parm) = val; } } if (entry->flags & SCCONF_VERBOSE) { char *buf = scconf_list_strdup(val, ", "); printf("%s = %s\n", entry->name, buf); free(buf); } } break; case SCCONF_BOOLEAN: { int val = scconf_get_bool(block, entry->name, 0); if (parm) { *((int *) parm) = val; } if (entry->flags & SCCONF_VERBOSE) { printf("%s = %s\n", entry->name, val == 0 ? "false" : "true"); } } break; case SCCONF_INTEGER: { int val = scconf_get_int(block, entry->name, 0); if (parm) { *((int *) parm) = val; } if (entry->flags & SCCONF_VERBOSE) { printf("%s = %i\n", entry->name, val); } } break; case SCCONF_STRING: { const char *val = scconf_get_str(block, entry->name, NULL); int vallen = val ? strlen(val) : 0; if (!vallen) { r = 1; break; } if (parm) { if (entry->flags & SCCONF_ALLOC) { char **buf = (char **) parm; *buf = (char *) malloc(vallen + 1); if (*buf == NULL) { r = 1; break; } memset(*buf, 0, vallen + 1); if (len) { *len = vallen; } parm = *buf; } memcpy((char *) parm, val, vallen); } if (entry->flags & SCCONF_VERBOSE) { printf("%s = %s\n", entry->name, val); } } break; default: fprintf(stderr, "invalid configuration type: %d\n", entry->type); } if (r) { fprintf(stderr, "decoding of configuration entry '%s' failed.\n", entry->name); return r; } entry->flags |= SCCONF_PRESENT; return 0;}static int parse_entries(const scconf_context * config, const scconf_block * block, scconf_entry * entry, int depth){ int r, i, idx; scconf_entry *e; scconf_block **blocks = NULL; if (config->debug) { fprintf(stderr, "parse_entries called, depth %d\n", depth); } for (idx = 0; entry[idx].name; idx++) { e = &entry[idx]; r = 0; blocks = getblocks(config, block, e); if (!blocks) { if (!(e->flags & SCCONF_MANDATORY)) { if (config->debug) fprintf(stderr, "optional configuration entry '%s' not present\n", e->name); continue; } fprintf(stderr, "mandatory configuration entry '%s' not found\n", e->name); return 1; } for (i = 0; blocks[i]; i++) { r = parse_type(config, blocks[i], e, depth); if (r) { free(blocks); return r; } if (!(e->flags & SCCONF_ALL_BLOCKS)) break; } free(blocks); } return 0;}int scconf_parse_entries(const scconf_context * config, const scconf_block * block, scconf_entry * entry){ if (!entry) return 1; if (!block) block = config->root; return parse_entries(config, block, entry, 0);}static int write_entries(scconf_context * config, scconf_block * block, scconf_entry * entry, int depth);static int write_type(scconf_context * config, scconf_block * block, scconf_entry * entry, int depth){ void *parm = entry->parm; void *arg = entry->arg; int (*callback_func) (scconf_context * config, scconf_block * block, scconf_entry * entry, int depth) = (int (*)(scconf_context *, scconf_block *, scconf_entry *, int)) parm; int r = 0; if (config->debug) { fprintf(stderr, "encoding '%s'\n", entry->name); } switch (entry->type) { case SCCONF_CALLBACK: if (parm) { r = callback_func(config, block, entry, depth); } break; case SCCONF_BLOCK: if (parm) { scconf_block *subblock; const scconf_list *name = (const scconf_list *) arg; subblock = scconf_block_add(config, block, entry->name, name); r = write_entries(config, subblock, (scconf_entry *) parm, depth + 1); } break; case SCCONF_LIST: if (parm) { const scconf_list *val = (const scconf_list *) parm; scconf_item_add(config, block, NULL, SCCONF_ITEM_TYPE_VALUE, entry->name, val); if (entry->flags & SCCONF_VERBOSE) { char *buf = scconf_list_strdup(val, ", "); printf("%s = %s\n", entry->name, buf); free(buf); } } break; case SCCONF_BOOLEAN: if (parm) { const int val = parm ? (int) parm : 0; scconf_put_bool(block, entry->name, val); if (entry->flags & SCCONF_VERBOSE) { printf("%s = %s\n", entry->name, val == 0 ? "false" : "true"); } } break; case SCCONF_INTEGER: if (parm) { const int val = parm ? (int) parm : 0; scconf_put_int(block, entry->name, val); if (entry->flags & SCCONF_VERBOSE) { printf("%s = %i\n", entry->name, val); } } break; case SCCONF_STRING: if (parm) { const char *val = parm ? (const char *) parm : ""; scconf_put_str(block, entry->name, val); if (entry->flags & SCCONF_VERBOSE) { printf("%s = %s\n", entry->name, val); } } break; default: fprintf(stderr, "invalid configuration type: %d\n", entry->type); } if (r) { fprintf(stderr, "encoding of configuration entry '%s' failed.\n", entry->name); return r; } entry->flags |= SCCONF_PRESENT; return 0;}static int write_entries(scconf_context * config, scconf_block * block, scconf_entry * entry, int depth){ int r, idx; scconf_entry *e; if (config->debug) { fprintf(stderr, "write_entries called, depth %d\n", depth); } for (idx = 0; entry[idx].name; idx++) { e = &entry[idx]; r = 0; r = write_type(config, block, e, depth); if (r) { return r; } } return 0;}int scconf_write_entries(scconf_context * config, scconf_block * block, scconf_entry * entry){ if (!entry) return 1; if (!block) block = config->root; return write_entries(config, block, entry, 0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -