From: Mark Cave-Ayland Date: Tue, 23 Sep 2008 19:44:57 +0000 (+0000) Subject: Refactor the memory management routines to account for the fact that variadic functio... X-Git-Tag: 1.4.0b1~713 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b53c6b8ebb40d100aa280604d2ab034c12132ba1;p=postgis Refactor the memory management routines to account for the fact that variadic functions can't be called directly from the initial allocators. Also solve issues related to differences between the system vasprintf() (if supplied) and the liblwgeom vasprintf() by renaming to lw_vasprintf() and using it throughout PostGIS. With all this in place, GBT#54 is fixed which is very useful when debugging ;) git-svn-id: http://svn.osgeo.org/postgis/trunk@2995 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/liblwgeom/liblwgeom.h b/liblwgeom/liblwgeom.h index e2992a7ee..5e3a532be 100644 --- a/liblwgeom/liblwgeom.h +++ b/liblwgeom/liblwgeom.h @@ -2,8 +2,8 @@ #define _LIBLWGEOM_H 1 #include "../postgis_config.h" +#include #include -/* #include "compat.h" */ #define INTEGRITY_CHECKS 1 @@ -30,7 +30,10 @@ extern void lwgeom_install_default_allocators(void); typedef void* (*lwallocator)(size_t size); typedef void* (*lwreallocator)(void *mem, size_t size); typedef void (*lwfreeor)(void* mem); -typedef void (*lwreporter)(const char* fmt, ...); +typedef void (*lwreporter)(const char* fmt, va_list ap); + +void lwnotice(const char *fmt, ...); +void lwerror(const char *fmt, ...); #ifndef C_H @@ -52,15 +55,17 @@ typedef int int32; void *default_allocator(size_t size); void *default_reallocator(void *mem, size_t size); void default_freeor(void *ptr); -void default_errorreporter(const char *fmt, ...); -void default_noticereporter(const char *fmt, ...); +void default_errorreporter(const char *fmt, va_list ap); +void default_noticereporter(const char *fmt, va_list ap); /* globals */ extern lwreallocator lwrealloc_var; extern lwallocator lwalloc_var; extern lwfreeor lwfree_var; -extern lwreporter lwerror; -extern lwreporter lwnotice; +extern lwreporter lwerror_var; +extern lwreporter lwnotice_var; + +extern int lw_vasprintf (char **result, const char *format, va_list args); /* Debug macros */ #if POSTGIS_DEBUG_LEVEL > 0 diff --git a/liblwgeom/lwutil.c b/liblwgeom/lwutil.c index 95206089c..be991acd7 100644 --- a/liblwgeom/lwutil.c +++ b/liblwgeom/lwutil.c @@ -11,14 +11,14 @@ void *init_allocator(size_t size); void init_freeor(void *mem); void *init_reallocator(void *mem, size_t size); -void init_noticereporter(const char *fmt, ...); -void init_errorreporter(const char *fmt, ...); +void init_noticereporter(const char *fmt, va_list ap); +void init_errorreporter(const char *fmt, va_list ap); lwallocator lwalloc_var = init_allocator; lwreallocator lwrealloc_var = init_reallocator; lwfreeor lwfree_var = init_freeor; -lwreporter lwerror = init_errorreporter; -lwreporter lwnotice = init_noticereporter; +lwreporter lwnotice_var = init_noticereporter; +lwreporter lwerror_var = init_errorreporter; static char *lwgeomTypeName[] = { "Unknown", @@ -40,6 +40,40 @@ static char *lwgeomTypeName[] = { }; +/* + * lwnotice/lwerror handlers + * + * Since variadic functions cannot pass their parameters directly, we need + * wrappers for these functions to convert the arguments into a va_list + * structure. + */ + +void +lwnotice(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + + /* Call the supplied function */ + (*lwnotice_var)(fmt, ap); + + va_end(ap); +} + +void +lwerror(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + + /* Call the supplied function */ + (*lwerror_var)(fmt, ap); + + va_end(ap); +} + /* * Initialisation allocators * @@ -75,27 +109,19 @@ init_reallocator(void *mem, size_t size) } void -init_noticereporter(const char *fmt, ...) +init_noticereporter(const char *fmt, va_list ap) { - va_list ap; - lwgeom_init_allocators(); - va_start(ap, fmt); - lwnotice(fmt, ap); - va_end(ap); + (*lwnotice_var)(fmt, ap); } void -init_errorreporter(const char *fmt, ...) +init_errorreporter(const char *fmt, va_list ap) { - va_list ap; - lwgeom_init_allocators(); - va_start(ap, fmt); - lwerror(fmt, ap); - va_end(ap); + (*lwerror_var)(fmt, ap); } @@ -128,46 +154,38 @@ default_reallocator(void *mem, size_t size) } void -default_noticereporter(const char *fmt, ...) +default_noticereporter(const char *fmt, va_list ap) { char *msg; - va_list ap; - - va_start (ap, fmt); /* * This is a GNU extension. * Dunno how to handle errors here. */ - if (!vasprintf (&msg, fmt, ap)) + if (!lw_vasprintf (&msg, fmt, ap)) { va_end (ap); return; } printf("%s\n", msg); - va_end(ap); free(msg); } void -default_errorreporter(const char *fmt, ...) +default_errorreporter(const char *fmt, va_list ap) { char *msg; - va_list ap; - - va_start (ap, fmt); /* * This is a GNU extension. * Dunno how to handle errors here. */ - if (!vasprintf (&msg, fmt, ap)) + if (!lw_vasprintf (&msg, fmt, ap)) { va_end (ap); return; } fprintf(stderr, "%s\n", msg); - va_end(ap); free(msg); exit(1); } @@ -183,8 +201,8 @@ void lwgeom_install_default_allocators(void) lwalloc_var = default_allocator; lwrealloc_var = default_reallocator; lwfree_var = default_freeor; - lwerror = default_errorreporter; - lwnotice = default_noticereporter; + lwerror_var = default_errorreporter; + lwnotice_var = default_noticereporter; } diff --git a/liblwgeom/vsprintf.c b/liblwgeom/vsprintf.c index ded821490..a183b5fb2 100644 --- a/liblwgeom/vsprintf.c +++ b/liblwgeom/vsprintf.c @@ -36,6 +36,18 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ int global_total_width; #endif + +int lw_vasprintf (char **result, const char *format, va_list args); +int lw_asprintf +#if __STDC__ + (char **result, const char *format, ...); +#else + (result, va_alist); + char **result; + va_dcl +#endif + + static int int_vasprintf (result, format, args) char **result; @@ -127,16 +139,16 @@ int_vasprintf (result, format, args) } int -vasprintf (result, format, args) +lw_vasprintf (result, format, args) char **result; const char *format; va_list args; { - return int_vasprintf (result, format, &args); + return int_vasprintf (result, format, args); } int -asprintf +lw_asprintf #if __STDC__ (char **result, const char *format, ...) #else @@ -155,7 +167,7 @@ asprintf va_start (args); format = va_arg (args, char *); #endif - done = vasprintf (result, format, args); + done = lw_vasprintf (result, format, args); va_end (args); return done; diff --git a/lwgeom/lwgeom_functions_analytic.c b/lwgeom/lwgeom_functions_analytic.c index e28416fde..48884719f 100644 --- a/lwgeom/lwgeom_functions_analytic.c +++ b/lwgeom/lwgeom_functions_analytic.c @@ -505,7 +505,7 @@ Datum LWGEOM_snaptogrid(PG_FUNCTION_ARGS); Datum LWGEOM_snaptogrid_pointoff(PG_FUNCTION_ARGS); static int grid_isNull(const gridspec *grid); #if POSTGIS_DEBUG_LEVEL > 0 -static void grid_print(const gridspec *grid, lwreporter printer); +static void grid_print(const gridspec *grid); #endif /* A NULL grid is a grid in which size in all dimensions is 0 */ @@ -522,9 +522,9 @@ grid_isNull(const gridspec *grid) #if POSTGIS_DEBUG_LEVEL > 0 /* Print grid using given reporter */ static void -grid_print(const gridspec *grid, lwreporter printer) +grid_print(const gridspec *grid) { - printer("GRID(%g %g %g %g, %g %g %g %g)", + lwnotice("GRID(%g %g %g %g, %g %g %g %g)", grid->ipx, grid->ipy, grid->ipz, grid->ipm, grid->xsize, grid->ysize, grid->zsize, grid->msize); } @@ -869,7 +869,7 @@ Datum LWGEOM_snaptogrid_pointoff(PG_FUNCTION_ARGS) else grid.ipm=0; #if POSTGIS_DEBUG_LEVEL >= 4 - grid_print(&grid, lwnotice); + grid_print(&grid); #endif /* Return input geometry if grid is null */ diff --git a/lwgeom/lwgeom_pg.c b/lwgeom/lwgeom_pg.c index 4b8bb9546..8afe0969d 100644 --- a/lwgeom/lwgeom_pg.c +++ b/lwgeom/lwgeom_pg.c @@ -59,40 +59,33 @@ pg_free(void *ptr) } void -pg_error(const char *fmt, ...) +pg_error(const char *fmt, va_list ap) { #define ERRMSG_MAXLEN 256 char errmsg[ERRMSG_MAXLEN+1]; - va_list ap; - va_start (ap, fmt); vsnprintf (errmsg, ERRMSG_MAXLEN, fmt, ap); - va_end (ap); errmsg[ERRMSG_MAXLEN]='\0'; ereport(ERROR, (errmsg_internal("%s", errmsg))); } void -pg_notice(const char *fmt, ...) +pg_notice(const char *fmt, va_list ap) { char *msg; - va_list ap; - - va_start (ap, fmt); /* * This is a GNU extension. * Dunno how to handle errors here. */ - if (!vasprintf (&msg, fmt, ap)) + if (!lw_vasprintf (&msg, fmt, ap)) { va_end (ap); return; } ereport(NOTICE, (errmsg_internal("%s", msg))); - va_end(ap); free(msg); } @@ -103,8 +96,8 @@ lwgeom_init_allocators(void) lwalloc_var = pg_alloc; lwrealloc_var = pg_realloc; lwfree_var = pg_free; - lwerror = pg_error; - lwnotice = pg_notice; + lwerror_var = pg_error; + lwnotice_var = pg_notice; } PG_LWGEOM * diff --git a/lwgeom/lwgeom_pg.h b/lwgeom/lwgeom_pg.h index b6aa9a464..ce8f19f94 100644 --- a/lwgeom/lwgeom_pg.h +++ b/lwgeom/lwgeom_pg.h @@ -11,8 +11,8 @@ void *pg_alloc(size_t size); void *pg_realloc(void *ptr, size_t size); void pg_free(void *ptr); -void pg_error(const char *msg, ...); -void pg_notice(const char *msg, ...); +void pg_error(const char *msg, va_list vp); +void pg_notice(const char *msg, va_list vp); /* Debugging macros */