summaryrefslogtreecommitdiffabout
path: root/src/tree.c
Side-by-side diff
Diffstat (limited to 'src/tree.c') (more/less context) (ignore whitespace changes)
-rw-r--r--src/tree.c63
1 files changed, 43 insertions, 20 deletions
diff --git a/src/tree.c b/src/tree.c
index e25c6a5..27a6f21 100644
--- a/src/tree.c
+++ b/src/tree.c
@@ -62,6 +62,19 @@ grecs_value_free(struct grecs_value *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)
{
@@ -286,14 +299,32 @@ 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 {
return &fake;
}
@@ -915,21 +946,17 @@ nodeproc(enum grecs_tree_recurse_op op, struct grecs_node *node, void *data)
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;
@@ -1136,13 +1163,9 @@ reduceproc(enum grecs_tree_recurse_op op, struct grecs_node *node, void *data)
} 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) &&

Return to:

Send suggestions and report system problems to the System administrator.