diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2013-02-26 16:14:37 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2013-02-26 16:35:53 +0200 |
commit | 487e2cfa988d6c3a5232011ab83897ef23bdb88a (patch) | |
tree | 2db411004be434327162149356d9e04e84c786d8 /src | |
parent | 5596f7cdcdc1983021185c5e0900d5fcba7f3282 (diff) | |
download | grecs-487e2cfa988d6c3a5232011ab83897ef23bdb88a.tar.gz grecs-487e2cfa988d6c3a5232011ab83897ef23bdb88a.tar.bz2 |
Introduce an alternative callback function calling convention.
Depending on the tree-api option to the GRECS_SETUP macro,
the signature of callback functions changes. If the option
is supplied, a pointer to grecs_node_t is passwd to callback
functions as an argument instead of pointers to the value and
locus.
* am/grecs.m4 (GRECS_SETUP): New option tree-api.
* src/.gitignore: Add grecs.h
* src/Make.am: Build grecs.h
* src/grecs.h: Rename to src/grecs.hin
(GRECS_TREE_API): New define
(grecs_callback_fn): Provide two alternative
signatures depending on the value of GRECS_TREE_API.
All uses updated.
* src/tree.c (fake_callback): Update signature.
(grecs_process_ident)
(stmt_begin,stmt_end): Update calls to callback.
* tests/gcfset.c: Likewise.
Diffstat (limited to 'src')
-rw-r--r-- | src/.gitignore | 1 | ||||
-rw-r--r-- | src/Make.am | 7 | ||||
-rw-r--r-- | src/grecs.hin (renamed from src/grecs.h) | 13 | ||||
-rw-r--r-- | src/tree.c | 48 | ||||
-rw-r--r-- | src/wordsplit.c | 4 |
5 files changed, 63 insertions, 10 deletions
diff --git a/src/.gitignore b/src/.gitignore index 6e859b1..322178c 100644 --- a/src/.gitignore +++ b/src/.gitignore | |||
@@ -14,6 +14,7 @@ bind-gram.c | |||
14 | bind-gram.h | 14 | bind-gram.h |
15 | bind-gram.output | 15 | bind-gram.output |
16 | bind-lex.c | 16 | bind-lex.c |
17 | grecs.h | ||
17 | Make-inst.in | 18 | Make-inst.in |
18 | Make-shared.in | 19 | Make-shared.in |
19 | Make-static.in | 20 | Make-static.in |
diff --git a/src/Make.am b/src/Make.am index 6482d28..7ded902 100644 --- a/src/Make.am +++ b/src/Make.am | |||
@@ -71,12 +71,19 @@ noinst_HEADERS = grecs-locus.h | |||
71 | 71 | ||
72 | EXTRA_DIST=\ | 72 | EXTRA_DIST=\ |
73 | grecs-gram.h\ | 73 | grecs-gram.h\ |
74 | grecs.hin\ | ||
74 | $(GRECS_EXTRA_BIND)\ | 75 | $(GRECS_EXTRA_BIND)\ |
75 | $(GRECS_EXTRA_DHCPD)\ | 76 | $(GRECS_EXTRA_DHCPD)\ |
76 | $(GRECS_EXTRA_META1)\ | 77 | $(GRECS_EXTRA_META1)\ |
77 | $(PP_SETUP_FILE)\ | 78 | $(PP_SETUP_FILE)\ |
78 | Make.am Make-inst.am Make-shared.am Make-static.am | 79 | Make.am Make-inst.am Make-shared.am Make-static.am |
79 | 80 | ||
81 | BUILT_SOURCES=grecs.h | ||
82 | |||
83 | grecs.h: $(abs_srcdir)/grecs.hin | ||
84 | $(AM_V_GEN)sed 's/@''GRECS_TREE_API''@/@GRECS_TREE_API@/g' \ | ||
85 | $(abs_srcdir)/grecs.hin > grecs.h | ||
86 | |||
80 | AM_CPPFLAGS = \ | 87 | AM_CPPFLAGS = \ |
81 | -I$(srcdir)\ | 88 | -I$(srcdir)\ |
82 | -I$(top_srcdir)/@GRECS_SUBDIR@\ | 89 | -I$(top_srcdir)/@GRECS_SUBDIR@\ |
diff --git a/src/grecs.h b/src/grecs.hin index ab9e0a8..e83b855 100644 --- a/src/grecs.h +++ b/src/grecs.hin | |||
@@ -1,5 +1,5 @@ | |||
1 | /* grecs - Gray's Extensible Configuration System | 1 | /* grecs - Gray's Extensible Configuration System -*- c -*- |
2 | Copyright (C) 2007-2012 Sergey Poznyakoff | 2 | Copyright (C) 2007-2013 Sergey Poznyakoff |
3 | 3 | ||
4 | Grecs is free software; you can redistribute it and/or modify it | 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 | 5 | under the terms of the GNU General Public License as published by the |
@@ -40,6 +40,8 @@ | |||
40 | #define GRECS_VERSION_MAJOR 1 | 40 | #define GRECS_VERSION_MAJOR 1 |
41 | #define GRECS_VERSION_MINOR 0 | 41 | #define GRECS_VERSION_MINOR 0 |
42 | 42 | ||
43 | #define GRECS_TREE_API @GRECS_TREE_API@ | ||
44 | |||
43 | struct grecs_version_info { | 45 | struct grecs_version_info { |
44 | const char *package; | 46 | const char *package; |
45 | const char *version; | 47 | const char *version; |
@@ -161,11 +163,18 @@ typedef struct grecs_node { | |||
161 | } grecs_node_t; | 163 | } grecs_node_t; |
162 | 164 | ||
163 | typedef int (*grecs_callback_fn)( | 165 | typedef int (*grecs_callback_fn)( |
166 | #if GRECS_TREE_API | ||
167 | enum grecs_callback_command cmd, | ||
168 | grecs_node_t * /* node */, | ||
169 | void * /* varptr */, | ||
170 | void * /* cb_data */ | ||
171 | #else | ||
164 | enum grecs_callback_command cmd, | 172 | enum grecs_callback_command cmd, |
165 | grecs_locus_t * /* locus */, | 173 | grecs_locus_t * /* locus */, |
166 | void * /* varptr */, | 174 | void * /* varptr */, |
167 | grecs_value_t * /* value */, | 175 | grecs_value_t * /* value */, |
168 | void * /* cb_data */ | 176 | void * /* cb_data */ |
177 | #endif | ||
169 | ); | 178 | ); |
170 | 179 | ||
171 | struct grecs_keyword { | 180 | struct grecs_keyword { |
@@ -253,11 +253,20 @@ grecs_tree_free(struct grecs_node *node) | |||
253 | 253 | ||
254 | 254 | ||
255 | static int | 255 | static int |
256 | fake_callback(enum grecs_callback_command cmd, | 256 | fake_callback( |
257 | grecs_locus_t *locus, | 257 | #if GRECS_TREE_API |
258 | void *varptr, | 258 | enum grecs_callback_command cmd, |
259 | grecs_value_t *value, | 259 | grecs_node_t *node, |
260 | void *cb_data) | 260 | void *varptr, |
261 | void *cb_data | ||
262 | #else | ||
263 | enum grecs_callback_command cmd, | ||
264 | grecs_locus_t *locus, | ||
265 | void *varptr, | ||
266 | grecs_value_t *value, | ||
267 | void *cb_data | ||
268 | #endif | ||
269 | ) | ||
261 | { | 270 | { |
262 | return 0; | 271 | return 0; |
263 | } | 272 | } |
@@ -692,13 +701,24 @@ grecs_process_ident(struct grecs_keyword *kwp, grecs_value_t *value, | |||
692 | 701 | ||
693 | target = target_ptr(kwp, (char *) base); | 702 | target = target_ptr(kwp, (char *) base); |
694 | 703 | ||
695 | if (kwp->callback) | 704 | if (kwp->callback) { |
705 | #if GRECS_TREE_API | ||
706 | struct grecs_node node = { 0 }; | ||
707 | node.locus = *locus; | ||
708 | node.v.value = value; | ||
709 | node.ident = (char*) kwp->ident; | ||
710 | kwp->callback(grecs_callback_set_value, | ||
711 | &node, | ||
712 | target, | ||
713 | &kwp->callback_data); | ||
714 | #else | ||
696 | kwp->callback(grecs_callback_set_value, | 715 | kwp->callback(grecs_callback_set_value, |
697 | locus, | 716 | locus, |
698 | target, | 717 | target, |
699 | value, | 718 | value, |
700 | &kwp->callback_data); | 719 | &kwp->callback_data); |
701 | else if (kwp->type == grecs_type_void || target == NULL) | 720 | #endif |
721 | } else if (kwp->type == grecs_type_void || target == NULL) | ||
702 | return; | 722 | return; |
703 | else if (!value) { | 723 | else if (!value) { |
704 | grecs_error(locus, 0, "%s has no value", kwp->ident); | 724 | grecs_error(locus, 0, "%s has no value", kwp->ident); |
@@ -815,11 +835,18 @@ stmt_begin(struct nodeproc_closure *clos, | |||
815 | target = target_ptr(kwp, CURRENT_BASE(clos)); | 835 | target = target_ptr(kwp, CURRENT_BASE(clos)); |
816 | clos->cursect = kwp; | 836 | clos->cursect = kwp; |
817 | if (kwp->callback) { | 837 | if (kwp->callback) { |
838 | #if GRECS_TREE_API | ||
839 | if (kwp->callback(grecs_callback_section_begin, | ||
840 | node, | ||
841 | target, | ||
842 | &kwp->callback_data)) | ||
843 | #else | ||
818 | if (kwp->callback(grecs_callback_section_begin, | 844 | if (kwp->callback(grecs_callback_section_begin, |
819 | &node->locus, | 845 | &node->locus, |
820 | target, | 846 | target, |
821 | node->v.value, | 847 | node->v.value, |
822 | &kwp->callback_data)) | 848 | &kwp->callback_data)) |
849 | #endif | ||
823 | clos->cursect = &fake; | 850 | clos->cursect = &fake; |
824 | } else | 851 | } else |
825 | kwp->callback_data = target; | 852 | kwp->callback_data = target; |
@@ -844,11 +871,18 @@ stmt_end(struct nodeproc_closure *clos, struct grecs_node *node) | |||
844 | if (!clos->cursect) | 871 | if (!clos->cursect) |
845 | abort(); | 872 | abort(); |
846 | if (callback) | 873 | if (callback) |
874 | #if GRECS_TREE_API | ||
875 | callback(grecs_callback_section_end, | ||
876 | node, | ||
877 | kwp ? target_ptr(kwp, CURRENT_BASE(clos)) : NULL, | ||
878 | dataptr); | ||
879 | #else | ||
847 | callback(grecs_callback_section_end, | 880 | callback(grecs_callback_section_end, |
848 | &node->locus, | 881 | &node->locus, |
849 | kwp ? target_ptr(kwp, CURRENT_BASE(clos)) : NULL, | 882 | kwp ? target_ptr(kwp, CURRENT_BASE(clos)) : NULL, |
850 | NULL, | 883 | NULL, |
851 | dataptr); | 884 | dataptr); |
885 | #endif | ||
852 | if (kwp) | 886 | if (kwp) |
853 | kwp->callback_data = NULL; | 887 | kwp->callback_data = NULL; |
854 | } | 888 | } |
diff --git a/src/wordsplit.c b/src/wordsplit.c index 4fe8d6f..9047369 100644 --- a/src/wordsplit.c +++ b/src/wordsplit.c | |||
@@ -437,7 +437,8 @@ coalesce_segment (struct wordsplit *wsp, struct wordsplit_node *node) | |||
437 | { | 437 | { |
438 | len += wsnode_len (p); | 438 | len += wsnode_len (p); |
439 | } | 439 | } |
440 | len += wsnode_len (p); | 440 | if (p) |
441 | len += wsnode_len (p); | ||
441 | end = p; | 442 | end = p; |
442 | 443 | ||
443 | buf = malloc (len + 1); | 444 | buf = malloc (len + 1); |
@@ -1578,6 +1579,7 @@ wordsplit_perror (struct wordsplit *wsp) | |||
1578 | 1579 | ||
1579 | case WRDSE_NOSUPP: | 1580 | case WRDSE_NOSUPP: |
1580 | wsp->ws_error (_("command substitution is not yet supported")); | 1581 | wsp->ws_error (_("command substitution is not yet supported")); |
1582 | break; | ||
1581 | 1583 | ||
1582 | case WRDSE_USAGE: | 1584 | case WRDSE_USAGE: |
1583 | wsp->ws_error (_("invalid wordsplit usage")); | 1585 | wsp->ws_error (_("invalid wordsplit usage")); |