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 @@ -11,9 +11,10 @@ meta1-gram.h meta1-gram.output meta1-lex.c 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 @@ -68,18 +68,25 @@ GRECS_SRC = \ $(GRECS_PARSER_META1) 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@\ @GRECS_INCLUDES@\ @GRECS_HOST_PROJECT_INCLUDES@\ $(PARSER_DEFS) diff --git a/src/grecs.h b/src/grecs.hin index ab9e0a8..e83b855 100644 --- a/src/grecs.h +++ b/src/grecs.hin @@ -1,8 +1,8 @@ -/* 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 Free Software Foundation; either version 3 of the License, or (at your option) any later version. @@ -37,12 +37,14 @@ # define N_(s) s #endif #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; const char *id; int major; int minor; @@ -158,17 +160,24 @@ typedef struct grecs_node { struct grecs_value *value; struct grecs_symtab *texttab; } v; } 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 { const char *ident; const char *argname; const char *docstring; @@ -250,17 +250,26 @@ grecs_tree_free(struct grecs_node *node) return 0; } 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; } static struct grecs_keyword fake = { "*", @@ -689,19 +698,30 @@ grecs_process_ident(struct grecs_keyword *kwp, grecs_value_t *value, if (!kwp) return; 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); return; } else if (value->type == GRECS_TYPE_ARRAY) { grecs_error(locus, 0, @@ -812,17 +832,24 @@ stmt_begin(struct nodeproc_closure *clos, grecs_list_push(clos->sections, clos->cursect); if (kwp) { 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; } else /* install an "ignore-all" section */ clos->cursect = kwp; @@ -841,17 +868,24 @@ stmt_end(struct nodeproc_closure *clos, struct grecs_node *node) } clos->cursect = (struct grecs_keyword *)grecs_list_pop(clos->sections); 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; } static enum grecs_tree_recurse_res nodeproc(enum grecs_tree_recurse_op op, struct grecs_node *node, void *data) diff --git a/src/wordsplit.c b/src/wordsplit.c index 4fe8d6f..9047369 100644 --- a/src/wordsplit.c +++ b/src/wordsplit.c @@ -434,13 +434,14 @@ coalesce_segment (struct wordsplit *wsp, struct wordsplit_node *node) int stop; for (p = node; p && (p->flags & _WSNF_JOIN); p = p->next) { len += wsnode_len (p); } - len += wsnode_len (p); + if (p) + len += wsnode_len (p); end = p; buf = malloc (len + 1); if (!buf) return _wsplt_nomem (wsp); cur = buf; @@ -1575,12 +1576,13 @@ wordsplit_perror (struct wordsplit *wsp) case WRDSE_NOSPACE: wsp->ws_error (_("memory exhausted")); break; case WRDSE_NOSUPP: wsp->ws_error (_("command substitution is not yet supported")); + break; case WRDSE_USAGE: wsp->ws_error (_("invalid wordsplit usage")); break; case WRDSE_CBRACE: |