diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Make.am | 1 | ||||
-rw-r--r-- | src/assert.c | 58 | ||||
-rw-r--r-- | src/format.c | 22 | ||||
-rw-r--r-- | src/tree.c | 63 |
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 @@ -48,2 +48,3 @@ GRECS_SRC = \ asprintf.c\ + assert.c\ cidr.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 @@ -32,6 +32,6 @@ grecs_data_type_string(enum grecs_data_type type) case grecs_type_void: - return "void"; + return N_("void"); case grecs_type_string: - return "string"; + return N_("string"); @@ -45,27 +45,27 @@ grecs_data_type_string(enum grecs_data_type type) /*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"); } @@ -64,2 +64,15 @@ grecs_value_free(struct grecs_value *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 * @@ -288,10 +301,28 @@ static struct grecs_keyword 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 { @@ -917,7 +948,5 @@ nodeproc(enum grecs_tree_recurse_op op, struct grecs_node *node, void *data) 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), @@ -927,7 +956,5 @@ nodeproc(enum grecs_tree_recurse_op op, struct grecs_node *node, void *data) 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); @@ -1138,9 +1165,5 @@ reduceproc(enum grecs_tree_recurse_op op, struct grecs_node *node, void *data) 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) |