summaryrefslogtreecommitdiffabout
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--include/grecs/node.h2
-rw-r--r--include/grecs/tree.h8
-rw-r--r--include/grecs/value.h1
-rw-r--r--src/Make.am1
-rw-r--r--src/assert.c58
-rw-r--r--src/format.c22
-rw-r--r--src/tree.c63
-rw-r--r--tests/set.at4
8 files changed, 125 insertions, 34 deletions
diff --git a/include/grecs/node.h b/include/grecs/node.h
index 2d879ad..752b002 100644
--- a/include/grecs/node.h
+++ b/include/grecs/node.h
@@ -35,7 +35,7 @@ typedef struct grecs_node {
35 struct grecs_node *next; 35 struct grecs_node *next;
36 struct grecs_node *prev; 36 struct grecs_node *prev;
37 char *ident; 37 char *ident;
38 grecs_locus_t idloc; 38 grecs_locus_t idloc; /* Location of the identifier */
39 union { 39 union {
40 grecs_value_t *value; 40 grecs_value_t *value;
41 grecs_symtab_ptr_t texttab; 41 grecs_symtab_ptr_t texttab;
diff --git a/include/grecs/tree.h b/include/grecs/tree.h
index 2fb26dd..f13a74b 100644
--- a/include/grecs/tree.h
+++ b/include/grecs/tree.h
@@ -67,5 +67,13 @@ struct grecs_node *grecs_match_buf_get_node(grecs_match_buf_t buf);
67size_t grecs_match_buf_get_args(grecs_match_buf_t buf, char ***argv); 67size_t grecs_match_buf_get_args(grecs_match_buf_t buf, char ***argv);
68struct grecs_node *grecs_match_buf_get_root(grecs_match_buf_t buf); 68struct grecs_node *grecs_match_buf_get_root(grecs_match_buf_t buf);
69void grecs_match_buf_set_root(grecs_match_buf_t buf, struct grecs_node *root); 69void grecs_match_buf_set_root(grecs_match_buf_t buf, struct grecs_node *root);
70
71/* Assertions */
72int grecs_assert_value_type(const grecs_value_t *value, int type,
73 grecs_locus_t *refloc);
74int grecs_assert_scalar_stmt(grecs_locus_t *locus,
75 enum grecs_callback_command cmd);
76int grecs_assert_node_value_type(enum grecs_callback_command cmd,
77 grecs_node_t *node, int type);
70 78
71#endif 79#endif
diff --git a/include/grecs/value.h b/include/grecs/value.h
index 8cd2800..480db9d 100644
--- a/include/grecs/value.h
+++ b/include/grecs/value.h
@@ -44,6 +44,7 @@ typedef struct grecs_value {
44void grecs_value_free(struct grecs_value *val); 44void grecs_value_free(struct grecs_value *val);
45void grecs_value_free_content(struct grecs_value *val); 45void grecs_value_free_content(struct grecs_value *val);
46grecs_value_t *grecs_value_ptr_from_static(grecs_value_t *input); 46grecs_value_t *grecs_value_ptr_from_static(grecs_value_t *input);
47const char *grecs_value_type_string(int t);
47 48
48int grecs_value_eq(struct grecs_value *a, struct grecs_value *b); 49int grecs_value_eq(struct grecs_value *a, struct grecs_value *b);
49int grecs_value_match(struct grecs_value *pat, struct grecs_value *b, 50int grecs_value_match(struct grecs_value *pat, struct grecs_value *b,
diff --git a/src/Make.am b/src/Make.am
index 227973e..9fa7688 100644
--- a/src/Make.am
+++ b/src/Make.am
@@ -46,6 +46,7 @@ endif
46 46
47GRECS_SRC = \ 47GRECS_SRC = \
48 asprintf.c\ 48 asprintf.c\
49 assert.c\
49 cidr.c\ 50 cidr.c\
50 diag.c\ 51 diag.c\
51 format.c\ 52 format.c\
diff --git a/src/assert.c b/src/assert.c
new file mode 100644
index 0000000..0577768
--- a/dev/null
+++ b/src/assert.c
@@ -0,0 +1,58 @@
1/* grecs - Gray's Extensible Configuration System
2 Copyright (C) 2007-2019 Sergey Poznyakoff
3
4 Grecs is free software; you can redistribute it and/or modify it
5 under the terms of the GNU General Public License as published by the
6 Free Software Foundation; either version 3 of the License, or (at your
7 option) any later version.
8
9 Grecs is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License along
15 with Grecs. If not, see <http://www.gnu.org/licenses/>. */
16
17#ifdef HAVE_CONFIG_H
18# include <config.h>
19#endif
20#include <errno.h>
21#include <grecs.h>
22
23int
24grecs_assert_value_type(const grecs_value_t *value, int type,
25 grecs_locus_t *refloc)
26{
27 if (GRECS_VALUE_EMPTY_P(value)) {
28 grecs_error(refloc, 0, _("expected %s"),
29 gettext(grecs_value_type_string(type)));
30 return 1;
31 }
32 if (value->type != type) {
33 grecs_error(&value->locus, 0, _("expected %s, but found %s"),
34 gettext(grecs_value_type_string(type)),
35 gettext(grecs_value_type_string(value->type)));
36 return 1;
37 }
38 return 0;
39}
40
41int
42grecs_assert_scalar_stmt(grecs_locus_t *locus, enum grecs_callback_command cmd)
43{
44 if (cmd != grecs_callback_set_value) {
45 grecs_error(locus, 0, _("unexpected block statement"));
46 return 1;
47 }
48 return 0;
49}
50
51int
52grecs_assert_node_value_type(enum grecs_callback_command cmd,
53 grecs_node_t *node, int type)
54{
55 return grecs_assert_scalar_stmt(&node->locus, cmd)
56 && grecs_assert_value_type(node->v.value, type,
57 &node->locus);
58}
diff --git a/src/format.c b/src/format.c
index af87329..d7cdb0f 100644
--- a/src/format.c
+++ b/src/format.c
@@ -30,10 +30,10 @@ grecs_data_type_string(enum grecs_data_type type)
30{ 30{
31 switch (type) { 31 switch (type) {
32 case grecs_type_void: 32 case grecs_type_void:
33 return "void"; 33 return N_("void");
34 34
35 case grecs_type_string: 35 case grecs_type_string:
36 return "string"; 36 return N_("string");
37 37
38 case grecs_type_short: 38 case grecs_type_short:
39 case grecs_type_ushort: 39 case grecs_type_ushort:
@@ -43,31 +43,31 @@ grecs_data_type_string(enum grecs_data_type type)
43 case grecs_type_ulong: 43 case grecs_type_ulong:
44 case grecs_type_size: 44 case grecs_type_size:
45 /*FIXME case grecs_type_off:*/ 45 /*FIXME case grecs_type_off:*/
46 return "number"; 46 return N_("number");
47 47
48 case grecs_type_time: 48 case grecs_type_time:
49 return "time"; 49 return N_("time");
50 50
51 case grecs_type_bool: 51 case grecs_type_bool:
52 return "boolean"; 52 return N_("boolean");
53 53
54 case grecs_type_ipv4: 54 case grecs_type_ipv4:
55 return "IPv4"; 55 return N_("IPv4");
56 56
57 case grecs_type_cidr: 57 case grecs_type_cidr:
58 return "CIDR"; 58 return N_("CIDR");
59 59
60 case grecs_type_host: 60 case grecs_type_host:
61 return "hostname"; 61 return N_("hostname");
62 62
63 case grecs_type_sockaddr: 63 case grecs_type_sockaddr:
64 return "sockaddr"; 64 return N_("sockaddr");
65 65
66 case grecs_type_section: 66 case grecs_type_section:
67 return "section"; 67 return N_("section");
68 68
69 case grecs_type_null: 69 case grecs_type_null:
70 return "null"; 70 return N_("null");
71 } 71 }
72 return "UNKNOWN?"; 72 return "UNKNOWN?";
73} 73}
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)
62 grecs_free(val); 62 grecs_free(val);
63} 63}
64 64
65const char *
66grecs_value_type_string(int t)
67{
68 static const char *types[] = {
69 [GRECS_TYPE_STRING] = N_("string"),
70 [GRECS_TYPE_LIST] = N_("list"),
71 [GRECS_TYPE_ARRAY] = N_("one or more arguments")
72 };
73 if (t >= 0 && t < sizeof(types) / sizeof(types[0]))
74 return types[t];
75 return N_("unrecognized type; please report");
76}
77
65struct grecs_node * 78struct grecs_node *
66grecs_node_create(enum grecs_node_type type, grecs_locus_t *loc) 79grecs_node_create(enum grecs_node_type type, grecs_locus_t *loc)
67{ 80{
@@ -286,14 +299,32 @@ static struct grecs_keyword fake = {
286}; 299};
287 300
288static struct grecs_keyword * 301static struct grecs_keyword *
289find_keyword(struct grecs_keyword *cursect, const char *ident) 302find_keyword(struct grecs_keyword *cursect, grecs_node_t *node)
290{ 303{
291 struct grecs_keyword *kwp;
292
293 if (cursect && cursect->kwd && cursect != &fake) { 304 if (cursect && cursect->kwd && cursect != &fake) {
294 for (kwp = cursect->kwd; kwp->ident; kwp++) 305 struct grecs_keyword *found = NULL, *kwp;
295 if (strcmp(kwp->ident, ident) == 0) 306 char const *msg;
296 return kwp; 307
308 for (kwp = cursect->kwd; kwp->ident; kwp++) {
309 if (strcmp(kwp->ident, node->ident) == 0) {
310 found = kwp;
311 if (kwp->callback
312 || node->down
313 ? kwp->type == grecs_type_section
314 : kwp->type != grecs_type_section)
315 return kwp;
316 }
317 }
318 if (found) {
319 if (found->type == grecs_type_section) {
320 msg = N_("section keyword used as a scalar");
321 } else {
322 msg = N_("scalar keyword used as a section");
323 }
324 } else {
325 msg = N_("unknown keyword");
326 }
327 grecs_error(&node->idloc, 0, "%s", gettext(msg));
297 } else { 328 } else {
298 return &fake; 329 return &fake;
299 } 330 }
@@ -915,21 +946,17 @@ nodeproc(enum grecs_tree_recurse_op op, struct grecs_node *node, void *data)
915 946
916 switch (op) { 947 switch (op) {
917 case grecs_tree_recurse_set: 948 case grecs_tree_recurse_set:
918 kwp = find_keyword(clos->cursect, node->ident); 949 kwp = find_keyword(clos->cursect, node);
919 if (!kwp) { 950 if (!kwp)
920 grecs_error(&node->idloc, 0, _("Unknown keyword"));
921 return grecs_tree_recurse_skip; 951 return grecs_tree_recurse_skip;
922 }
923 grecs_process_ident(kwp, node->v.value, CURRENT_BASE(clos), 952 grecs_process_ident(kwp, node->v.value, CURRENT_BASE(clos),
924 &node->idloc); 953 &node->idloc);
925 break; 954 break;
926 955
927 case grecs_tree_recurse_pre: 956 case grecs_tree_recurse_pre:
928 kwp = find_keyword(clos->cursect, node->ident); 957 kwp = find_keyword(clos->cursect, node);
929 if (!kwp) { 958 if (!kwp)
930 grecs_error(&node->locus, 0, _("Unknown keyword"));
931 return grecs_tree_recurse_skip; 959 return grecs_tree_recurse_skip;
932 }
933 stmt_begin(clos, kwp, node); 960 stmt_begin(clos, kwp, node);
934 break; 961 break;
935 962
@@ -1136,13 +1163,9 @@ reduceproc(enum grecs_tree_recurse_op op, struct grecs_node *node, void *data)
1136 } else { 1163 } else {
1137 struct grecs_keyword *kwp = NULL; 1164 struct grecs_keyword *kwp = NULL;
1138 if (clos->cursect) { 1165 if (clos->cursect) {
1139 kwp = find_keyword(clos->cursect, node->ident); 1166 kwp = find_keyword(clos->cursect, node);
1140 if (!kwp) { 1167 if (!kwp)
1141 grecs_error(&node->locus, 0,
1142 _("%s: unknown keyword"),
1143 node->ident);
1144 return grecs_tree_recurse_skip; 1168 return grecs_tree_recurse_skip;
1145 }
1146 if (kwp->flags & GRECS_INAC) 1169 if (kwp->flags & GRECS_INAC)
1147 return grecs_tree_recurse_skip; 1170 return grecs_tree_recurse_skip;
1148 if (!(kwp->flags & GRECS_MULT) && 1171 if (!(kwp->flags & GRECS_MULT) &&
diff --git a/tests/set.at b/tests/set.at
index 7daad18..c1cb0b0 100644
--- a/tests/set.at
+++ b/tests/set.at
@@ -32,7 +32,7 @@ Program bar:
32scalar = 25 32scalar = 25
33logging: 0/local2/baz/0 33logging: 0/local2/baz/0
34], 34],
35[:25.1-8: Unknown keyword 35[:25.1-8: unknown keyword
36]) 36])
37 37
38AT_CLEANUP \ No newline at end of file 38AT_CLEANUP

Return to:

Send suggestions and report system problems to the System administrator.