Пример #1
0
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;
}
Пример #2
0
static struct config_node *_section(struct parser *p)
{
	/* IDENTIFIER SECTION_B_CHAR VALUE* SECTION_E_CHAR */
	struct config_node *root, *n, *l = NULL;
	if (!(root = _create_node(p->mem)))
		return_0;

	if (!(root->key = _dup_tok(p)))
		return_0;

	match(TOK_IDENTIFIER);

	if (p->t == TOK_SECTION_B) {
		match(TOK_SECTION_B);
		while (p->t != TOK_SECTION_E) {
			if (!(n = _section(p)))
				return_0;

			if (!root->child)
				root->child = n;
			else
				l->sib = n;
			n->parent = root;
			l = n;
		}
		match(TOK_SECTION_E);
	} else {
		match(TOK_EQ);
		if (!(root->v = _value(p)))
			return_0;
	}

	return root;
}
Пример #3
0
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;
}
Пример #4
0
static struct dm_config_node *_section(struct parser *p, struct dm_config_node *parent)
{
	/* IDENTIFIER SECTION_B_CHAR VALUE* SECTION_E_CHAR */

	struct dm_config_node *root;
	struct dm_config_value *value;
	char *str;

	if (p->t == TOK_STRING_ESCAPED) {
		if (!(str = _dup_string_tok(p)))
			return_NULL;
		dm_unescape_double_quotes(str);

		match(TOK_STRING_ESCAPED);
	} else if (p->t == TOK_STRING) {
		if (!(str = _dup_string_tok(p)))
			return_NULL;

		match(TOK_STRING);
	} else {
		if (!(str = _dup_tok(p)))
			return_NULL;

		match(TOK_IDENTIFIER);
	}

	if (!strlen(str)) {
		log_error("Parse error at byte %" PRIptrdiff_t " (line %d): empty section identifier",
			  p->tb - p->fb + 1, p->line);
		return NULL;
	}

	root = _find_or_make_node(p->mem, parent, str);

	if (p->t == TOK_SECTION_B) {
		match(TOK_SECTION_B);
		while (p->t != TOK_SECTION_E) {
			if (!(_section(p, root)))
				return_NULL;
		}
		match(TOK_SECTION_E);
	} else {
		match(TOK_EQ);
		if (!(value = _value(p)))
			return_NULL;
		if (root->v)
			log_warn("WARNING: Ignoring duplicate"
				 " config value: %s", str);
		root->v = value;
	}

	return root;
}
Пример #5
0
static int _write_node(const struct dm_config_node *cn, int only_one,
		       dm_putline_fn putline,
		       const struct dm_config_node_out_spec *out_spec,
		       void *baton)
{
	struct config_output out = {
		.mem = dm_pool_create("config_output", 1024),
		.putline = putline,
		.spec = out_spec,
		.baton = baton
	};

	if (!out.mem)
		return_0;

	if (!_write_config(cn, only_one, &out, 0)) {
		dm_pool_destroy(out.mem);
		return_0;
	}
	dm_pool_destroy(out.mem);
	return 1;
}

int dm_config_write_one_node(const struct dm_config_node *cn, dm_putline_fn putline, void *baton)
{
	return _write_node(cn, 1, putline, NULL, baton);
}

int dm_config_write_node(const struct dm_config_node *cn, dm_putline_fn putline, void *baton)
{
	return _write_node(cn, 0, putline, NULL, baton);
}

int dm_config_write_one_node_out(const struct dm_config_node *cn,
				 const struct dm_config_node_out_spec *out_spec,
				 void *baton)
{
	return _write_node(cn, 1, NULL, out_spec, baton);
}

int dm_config_write_node_out(const struct dm_config_node *cn,
			     const struct dm_config_node_out_spec *out_spec,
			     void *baton)
{
	return _write_node(cn, 0, NULL, out_spec, baton);
}

/*
 * parser
 */
static char *_dup_string_tok(struct parser *p)
{
	char *str;

	p->tb++, p->te--;	/* strip "'s */

	if (p->te < p->tb) {
		log_error("Parse error at byte %" PRIptrdiff_t " (line %d): "
			  "expected a string token.",
			  p->tb - p->fb + 1, p->line);
		return NULL;
	}

	if (!(str = _dup_tok(p)))
		return_NULL;

	p->te++;

	return str;
}