aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2013-02-26 16:14:37 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2013-02-26 16:35:53 +0200
commit487e2cfa988d6c3a5232011ab83897ef23bdb88a (patch)
tree2db411004be434327162149356d9e04e84c786d8
parent5596f7cdcdc1983021185c5e0900d5fcba7f3282 (diff)
downloadgrecs-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.
-rw-r--r--am/grecs.m48
-rw-r--r--src/.gitignore1
-rw-r--r--src/Make.am7
-rw-r--r--src/grecs.hin (renamed from src/grecs.h)13
-rw-r--r--src/tree.c48
-rw-r--r--src/wordsplit.c4
-rw-r--r--tests/gcfset.c34
7 files changed, 94 insertions, 21 deletions
diff --git a/am/grecs.m4 b/am/grecs.m4
index 36ecf8f..2787563 100644
--- a/am/grecs.m4
+++ b/am/grecs.m4
@@ -65,6 +65,9 @@ AC_DEFUN([_GRECS_SET_OPTIONS],
# shared Build shared (convenience) library.
# install-headers [with "shared"] Install Grecs headers to
# GRECS_INCLUDE_DIR.
+# tree-api Use alternative signature of callback functions,
+# passing a pointer to grecs_node_t as an argument,
+# instead of pointers to the value and locus.
#
# The pp-setup-file argument supplies the pathname of the preprocessor
# setup file in the source tree. It is ignored if std-pp-setup option is
@@ -171,7 +174,10 @@ AC_DEFUN([GRECS_SETUP],[
[false]))
AM_CONDITIONAL([GRECS_COND_INSTALLHEADERS],
_GRECS_IF_OPTION_SET([install-headers],[true],[false]))
-
+
+ AC_SUBST([GRECS_TREE_API])
+ _GRECS_IF_OPTION_SET([tree-api],[GRECS_TREE_API=1],[GRECS_TREE_API=0])
+
AC_SUBST([GRECS_SRCDIR],$1)
AC_SUBST([GRECS_BUILD_AUX])
AC_SUBST([GRECS_INCLUDES])
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
bind-gram.h
bind-gram.output
bind-lex.c
+grecs.h
Make-inst.in
Make-shared.in
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
EXTRA_DIST=\
grecs-gram.h\
+ grecs.hin\
$(GRECS_EXTRA_BIND)\
$(GRECS_EXTRA_DHCPD)\
$(GRECS_EXTRA_META1)\
$(PP_SETUP_FILE)\
Make.am Make-inst.am Make-shared.am Make-static.am
+BUILT_SOURCES=grecs.h
+
+grecs.h: $(abs_srcdir)/grecs.hin
+ $(AM_V_GEN)sed 's/@''GRECS_TREE_API''@/@GRECS_TREE_API@/g' \
+ $(abs_srcdir)/grecs.hin > grecs.h
+
AM_CPPFLAGS = \
-I$(srcdir)\
-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 @@
-/* grecs - Gray's Extensible Configuration System
- Copyright (C) 2007-2012 Sergey Poznyakoff
+/* grecs - Gray's Extensible Configuration System -*- c -*-
+ Copyright (C) 2007-2013 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
@@ -40,6 +40,8 @@
#define GRECS_VERSION_MAJOR 1
#define GRECS_VERSION_MINOR 0
+#define GRECS_TREE_API @GRECS_TREE_API@
+
struct grecs_version_info {
const char *package;
const char *version;
@@ -161,11 +163,18 @@ typedef struct grecs_node {
} grecs_node_t;
typedef int (*grecs_callback_fn)(
+#if GRECS_TREE_API
+ enum grecs_callback_command cmd,
+ grecs_node_t * /* node */,
+ void * /* varptr */,
+ void * /* cb_data */
+#else
enum grecs_callback_command cmd,
grecs_locus_t * /* locus */,
void * /* varptr */,
grecs_value_t * /* value */,
void * /* cb_data */
+#endif
);
struct grecs_keyword {
diff --git a/src/tree.c b/src/tree.c
index abf170e..a0f8736 100644
--- a/src/tree.c
+++ b/src/tree.c
@@ -253,11 +253,20 @@ grecs_tree_free(struct grecs_node *node)
static int
-fake_callback(enum grecs_callback_command cmd,
- grecs_locus_t *locus,
- void *varptr,
- grecs_value_t *value,
- void *cb_data)
+fake_callback(
+#if GRECS_TREE_API
+ enum grecs_callback_command cmd,
+ grecs_node_t *node,
+ void *varptr,
+ void *cb_data
+#else
+ enum grecs_callback_command cmd,
+ grecs_locus_t *locus,
+ void *varptr,
+ grecs_value_t *value,
+ void *cb_data
+#endif
+ )
{
return 0;
}
@@ -692,13 +701,24 @@ grecs_process_ident(struct grecs_keyword *kwp, grecs_value_t *value,
target = target_ptr(kwp, (char *) base);
- if (kwp->callback)
+ if (kwp->callback) {
+#if GRECS_TREE_API
+ struct grecs_node node = { 0 };
+ node.locus = *locus;
+ node.v.value = value;
+ node.ident = (char*) kwp->ident;
+ kwp->callback(grecs_callback_set_value,
+ &node,
+ target,
+ &kwp->callback_data);
+#else
kwp->callback(grecs_callback_set_value,
locus,
target,
value,
&kwp->callback_data);
- else if (kwp->type == grecs_type_void || target == NULL)
+#endif
+ } else if (kwp->type == grecs_type_void || target == NULL)
return;
else if (!value) {
grecs_error(locus, 0, "%s has no value", kwp->ident);
@@ -815,11 +835,18 @@ stmt_begin(struct nodeproc_closure *clos,
target = target_ptr(kwp, CURRENT_BASE(clos));
clos->cursect = kwp;
if (kwp->callback) {
+#if GRECS_TREE_API
+ if (kwp->callback(grecs_callback_section_begin,
+ node,
+ target,
+ &kwp->callback_data))
+#else
if (kwp->callback(grecs_callback_section_begin,
&node->locus,
target,
node->v.value,
&kwp->callback_data))
+#endif
clos->cursect = &fake;
} else
kwp->callback_data = target;
@@ -844,11 +871,18 @@ stmt_end(struct nodeproc_closure *clos, struct grecs_node *node)
if (!clos->cursect)
abort();
if (callback)
+#if GRECS_TREE_API
+ callback(grecs_callback_section_end,
+ node,
+ kwp ? target_ptr(kwp, CURRENT_BASE(clos)) : NULL,
+ dataptr);
+#else
callback(grecs_callback_section_end,
&node->locus,
kwp ? target_ptr(kwp, CURRENT_BASE(clos)) : NULL,
NULL,
dataptr);
+#endif
if (kwp)
kwp->callback_data = NULL;
}
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)
{
len += wsnode_len (p);
}
- len += wsnode_len (p);
+ if (p)
+ len += wsnode_len (p);
end = p;
buf = malloc (len + 1);
@@ -1578,6 +1579,7 @@ wordsplit_perror (struct wordsplit *wsp)
case WRDSE_NOSUPP:
wsp->ws_error (_("command substitution is not yet supported"));
+ break;
case WRDSE_USAGE:
wsp->ws_error (_("invalid wordsplit usage"));
diff --git a/tests/gcfset.c b/tests/gcfset.c
index bb54876..14b57cb 100644
--- a/tests/gcfset.c
+++ b/tests/gcfset.c
@@ -45,13 +45,30 @@ struct program {
struct grecs_list *proglist;
+#if GRECS_TREE_API
+# define GRECS_CB_ARGS \
+ enum grecs_callback_command cmd,\
+ grecs_node_t *node,\
+ void *varptr,\
+ void *cb_data
+# define GRECS_CB_AUTO \
+ grecs_locus_t *locus = &node->locus;\
+ grecs_value_t *value = node->v.value;
+#else
+# define GRECS_CB_ARGS \
+ enum grecs_callback_command cmd,\
+ grecs_locus_t *locus,\
+ void *varptr,\
+ grecs_value_t *value,\
+ void *cb_data
+# define GRECS_CB_AUTO
+#endif
+
static int
-cb_logging_facility(enum grecs_callback_command cmd,
- grecs_locus_t *locus,
- void *varptr,
- grecs_value_t *value,
- void *cb_data)
+cb_logging_facility(GRECS_CB_ARGS)
{
+ GRECS_CB_AUTO
+
if (cmd != grecs_callback_set_value) {
grecs_error(locus, 0, _("Unexpected block statement"));
return 1;
@@ -102,14 +119,11 @@ static struct grecs_keyword program_kwtab[] = {
};
static int
-cb_program(enum grecs_callback_command cmd,
- grecs_locus_t *locus,
- void *varptr,
- grecs_value_t *value,
- void *cb_data)
+cb_program(GRECS_CB_ARGS)
{
struct program *prog;
void **pdata = cb_data;
+ GRECS_CB_AUTO
switch (cmd) {
case grecs_callback_section_begin:

Return to:

Send suggestions and report system problems to the System administrator.