static struct config_value *_value(struct parser *p) { /* '[' TYPE* ']' | TYPE */ struct config_value *h = NULL, *l, *ll = NULL; if (p->t == TOK_ARRAY_B) { match(TOK_ARRAY_B); while (p->t != TOK_ARRAY_E) { if (!(l = _type(p))) return_0; if (!h) h = l; else ll->next = l; ll = l; if (p->t == TOK_COMMA) match(TOK_COMMA); } match(TOK_ARRAY_E); /* * Special case for an empty array. */ if (!h) { if (!(h = _create_value(p->mem))) return NULL; h->type = CFG_EMPTY_ARRAY; } } else h = _type(p); return h; }
static struct config_value *_clone_config_value(struct dm_pool *mem, const struct config_value *v) { struct config_value *new_cv; if (!v) return NULL; if (!(new_cv = _create_value(mem))) { log_error("Failed to clone config value."); return NULL; } new_cv->type = v->type; if (v->type == CFG_STRING) { if (!(new_cv->v.str = dm_pool_strdup(mem, v->v.str))) { log_error("Failed to clone config string value."); return NULL; } } else new_cv->v = v->v; if (v->next && !(new_cv->next = _clone_config_value(mem, v->next))) return_NULL; return new_cv; }
static struct dm_config_value *_type(struct parser *p) { /* [+-]{0,1}[0-9]+ | [0-9]*\.[0-9]* | ".*" */ struct dm_config_value *v = _create_value(p->mem); char *str; if (!v) { log_error("Failed to allocate type value"); return NULL; } switch (p->t) { case TOK_INT: v->type = DM_CFG_INT; v->v.i = strtoll(p->tb, NULL, 0); /* FIXME: check error */ match(TOK_INT); break; case TOK_FLOAT: v->type = DM_CFG_FLOAT; v->v.f = strtod(p->tb, NULL); /* FIXME: check error */ match(TOK_FLOAT); break; case TOK_STRING: v->type = DM_CFG_STRING; if (!(v->v.str = _dup_string_tok(p))) return_NULL; match(TOK_STRING); break; case TOK_STRING_BARE: v->type = DM_CFG_STRING; if (!(v->v.str = _dup_tok(p))) return_NULL; match(TOK_STRING_BARE); break; case TOK_STRING_ESCAPED: v->type = DM_CFG_STRING; if (!(str = _dup_string_tok(p))) return_NULL; dm_unescape_double_quotes(str); v->v.str = str; match(TOK_STRING_ESCAPED); break; default: log_error("Parse error at byte %" PRIptrdiff_t " (line %d): expected a value", p->tb - p->fb + 1, p->line); return NULL; } return v; }
static struct config_value *_type(struct parser *p) { /* [+-]{0,1}[0-9]+ | [0-9]*\.[0-9]* | ".*" */ struct config_value *v = _create_value(p->mem); char *str; if (!v) return NULL; switch (p->t) { case TOK_INT: v->type = CFG_INT; v->v.i = strtoll(p->tb, NULL, 0); /* FIXME: check error */ match(TOK_INT); break; case TOK_FLOAT: v->type = CFG_FLOAT; v->v.r = strtod(p->tb, NULL); /* FIXME: check error */ match(TOK_FLOAT); break; case TOK_STRING: v->type = CFG_STRING; p->tb++, p->te--; /* strip "'s */ if (!(v->v.str = _dup_tok(p))) return_0; p->te++; match(TOK_STRING); break; case TOK_STRING_ESCAPED: v->type = CFG_STRING; p->tb++, p->te--; /* strip "'s */ if (!(str = _dup_tok(p))) return_0; unescape_double_quotes(str); v->v.str = str; p->te++; match(TOK_STRING_ESCAPED); break; default: log_error("Parse error at byte %" PRIptrdiff_t " (line %d): expected a value", p->tb - p->fb + 1, p->line); return 0; } return v; }
struct config_node *create_config_node(struct config_tree *cft, const char *key) { struct cs *c = (struct cs *) cft; struct config_node *cn; if (!(cn = _create_node(c->mem))) { log_error("Failed to create config node."); return NULL; } if (!(cn->key = dm_pool_strdup(c->mem, key))) { log_error("Failed to create config node's key."); return NULL; } if (!(cn->v = _create_value(c->mem))) { log_error("Failed to create config node's value."); return NULL; } cn->parent = NULL; cn->v->type = CFG_INT; cn->v->v.i = 0; cn->v->next = NULL; return cn; }
struct config_value *create_config_value(struct config_tree *cft) { struct cs *c = (struct cs *) cft; return _create_value(c->mem); }
struct dm_config_value *dm_config_create_value(struct dm_config_tree *cft) { return _create_value(cft->mem); }