aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Make.am1
-rw-r--r--src/assert.c58
-rw-r--r--src/format.c22
-rw-r--r--src/tree.c63
4 files changed, 113 insertions, 31 deletions
diff --git a/src/Make.am b/src/Make.am
index 227973e..9fa7688 100644
--- a/src/Make.am
+++ b/src/Make.am
@@ -43,12 +43,13 @@ if GRECS_COND_JSON
GRECS_JSON = json-gram.y json-lex.l jsonfmt.c
GRECS_EXTRA_JSON = json-gram.h
endif
GRECS_SRC = \
asprintf.c\
+ assert.c\
cidr.c\
diag.c\
format.c\
grecs-gram.y\
grecs-lex.l\
ipstr.c\
diff --git a/src/assert.c b/src/assert.c
new file mode 100644
index 0000000..0577768
--- /dev/null
+++ b/src/assert.c
@@ -0,0 +1,58 @@
+/* grecs - Gray's Extensible Configuration System
+ Copyright (C) 2007-2019 Sergey Poznyakoff
+
+ Grecs is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+ Grecs is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with Grecs. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <errno.h>
+#include <grecs.h>
+
+int
+grecs_assert_value_type(const grecs_value_t *value, int type,
+ grecs_locus_t *refloc)
+{
+ if (GRECS_VALUE_EMPTY_P(value)) {
+ grecs_error(refloc, 0, _("expected %s"),
+ gettext(grecs_value_type_string(type)));
+ return 1;
+ }
+ if (value->type != type) {
+ grecs_error(&value->locus, 0, _("expected %s, but found %s"),
+ gettext(grecs_value_type_string(type)),
+ gettext(grecs_value_type_string(value->type)));
+ return 1;
+ }
+ return 0;
+}
+
+int
+grecs_assert_scalar_stmt(grecs_locus_t *locus, enum grecs_callback_command cmd)
+{
+ if (cmd != grecs_callback_set_value) {
+ grecs_error(locus, 0, _("unexpected block statement"));
+ return 1;
+ }
+ return 0;
+}
+
+int
+grecs_assert_node_value_type(enum grecs_callback_command cmd,
+ grecs_node_t *node, int type)
+{
+ return grecs_assert_scalar_stmt(&node->locus, cmd)
+ && grecs_assert_value_type(node->v.value, type,
+ &node->locus);
+}
diff --git a/src/format.c b/src/format.c
index af87329..d7cdb0f 100644
--- a/src/format.c
+++ b/src/format.c
@@ -27,50 +27,50 @@
const char *
grecs_data_type_string(enum grecs_data_type type)
{
switch (type) {
case grecs_type_void:
- return "void";
+ return N_("void");
case grecs_type_string:
- return "string";
+ return N_("string");
case grecs_type_short:
case grecs_type_ushort:
case grecs_type_int:
case grecs_type_uint:
case grecs_type_long:
case grecs_type_ulong:
case grecs_type_size:
/*FIXME case grecs_type_off:*/
- return "number";
+ return N_("number");
case grecs_type_time:
- return "time";
+ return N_("time");
case grecs_type_bool:
- return "boolean";
+ return N_("boolean");
case grecs_type_ipv4:
- return "IPv4";
+ return N_("IPv4");
case grecs_type_cidr:
- return "CIDR";
+ return N_("CIDR");
case grecs_type_host:
- return "hostname";
+ return N_("hostname");
case grecs_type_sockaddr:
- return "sockaddr";
+ return N_("sockaddr");
case grecs_type_section:
- return "section";
+ return N_("section");
case grecs_type_null:
- return "null";
+ return N_("null");
}
return "UNKNOWN?";
}
static void
format_level(unsigned level, FILE *stream)
diff --git a/src/tree.c b/src/tree.c
index e25c6a5..27a6f21 100644
--- a/src/tree.c
+++ b/src/tree.c
@@ -59,12 +59,25 @@ void
grecs_value_free(struct grecs_value *val)
{
grecs_value_free_content(val);
grecs_free(val);
}
+const char *
+grecs_value_type_string(int t)
+{
+ static const char *types[] = {
+ [GRECS_TYPE_STRING] = N_("string"),
+ [GRECS_TYPE_LIST] = N_("list"),
+ [GRECS_TYPE_ARRAY] = N_("one or more arguments")
+ };
+ if (t >= 0 && t < sizeof(types) / sizeof(types[0]))
+ return types[t];
+ return N_("unrecognized type; please report");
+}
+
struct grecs_node *
grecs_node_create(enum grecs_node_type type, grecs_locus_t *loc)
{
struct grecs_node *np = grecs_zalloc(sizeof(*np));
np->type = type;
if (loc)
@@ -283,20 +296,38 @@ static struct grecs_keyword fake = {
fake_callback,
NULL,
&fake
};
static struct grecs_keyword *
-find_keyword(struct grecs_keyword *cursect, const char *ident)
+find_keyword(struct grecs_keyword *cursect, grecs_node_t *node)
{
- struct grecs_keyword *kwp;
-
if (cursect && cursect->kwd && cursect != &fake) {
- for (kwp = cursect->kwd; kwp->ident; kwp++)
- if (strcmp(kwp->ident, ident) == 0)
- return kwp;
+ struct grecs_keyword *found = NULL, *kwp;
+ char const *msg;
+
+ for (kwp = cursect->kwd; kwp->ident; kwp++) {
+ if (strcmp(kwp->ident, node->ident) == 0) {
+ found = kwp;
+ if (kwp->callback
+ || node->down
+ ? kwp->type == grecs_type_section
+ : kwp->type != grecs_type_section)
+ return kwp;
+ }
+ }
+ if (found) {
+ if (found->type == grecs_type_section) {
+ msg = N_("section keyword used as a scalar");
+ } else {
+ msg = N_("scalar keyword used as a section");
+ }
+ } else {
+ msg = N_("unknown keyword");
+ }
+ grecs_error(&node->idloc, 0, "%s", gettext(msg));
} else {
return &fake;
}
return NULL;
}
@@ -912,27 +943,23 @@ nodeproc(enum grecs_tree_recurse_op op, struct grecs_node *node, void *data)
{
struct nodeproc_closure *clos = data;
struct grecs_keyword *kwp;
switch (op) {
case grecs_tree_recurse_set:
- kwp = find_keyword(clos->cursect, node->ident);
- if (!kwp) {
- grecs_error(&node->idloc, 0, _("Unknown keyword"));
+ kwp = find_keyword(clos->cursect, node);
+ if (!kwp)
return grecs_tree_recurse_skip;
- }
grecs_process_ident(kwp, node->v.value, CURRENT_BASE(clos),
&node->idloc);
break;
case grecs_tree_recurse_pre:
- kwp = find_keyword(clos->cursect, node->ident);
- if (!kwp) {
- grecs_error(&node->locus, 0, _("Unknown keyword"));
+ kwp = find_keyword(clos->cursect, node);
+ if (!kwp)
return grecs_tree_recurse_skip;
- }
stmt_begin(clos, kwp, node);
break;
case grecs_tree_recurse_post:
stmt_end(clos, node);
break;
@@ -1133,19 +1160,15 @@ reduceproc(enum grecs_tree_recurse_op op, struct grecs_node *node, void *data)
if (clos->sections)
clos->cursect = (struct grecs_keyword *)
grecs_list_pop(clos->sections);
} else {
struct grecs_keyword *kwp = NULL;
if (clos->cursect) {
- kwp = find_keyword(clos->cursect, node->ident);
- if (!kwp) {
- grecs_error(&node->locus, 0,
- _("%s: unknown keyword"),
- node->ident);
+ kwp = find_keyword(clos->cursect, node);
+ if (!kwp)
return grecs_tree_recurse_skip;
- }
if (kwp->flags & GRECS_INAC)
return grecs_tree_recurse_skip;
if (!(kwp->flags & GRECS_MULT) &&
node_reduce(node, kwp, clos->flags))
return grecs_tree_recurse_skip;
if (op == grecs_tree_recurse_pre) {

Return to:

Send suggestions and report system problems to the System administrator.