mirror of
https://github.com/pgpointcloud/pointcloud.git
synced 2025-12-08 20:36:04 +00:00
194 lines
3.8 KiB
C
194 lines
3.8 KiB
C
/***********************************************************************
|
|
* pc_mem.c
|
|
*
|
|
* Memory and message management routines.
|
|
* Allow this library to be used both inside and outside a
|
|
* PgSQL backend.
|
|
*
|
|
* PgSQL Pointcloud is free and open source software provided
|
|
* by the Government of Canada
|
|
* Copyright (c) 2013 Natural Resources Canada
|
|
*
|
|
***********************************************************************/
|
|
|
|
#include <stdarg.h>
|
|
#include "pc_api_internal.h"
|
|
|
|
struct pc_context_t
|
|
{
|
|
pc_allocator alloc;
|
|
pc_reallocator realloc;
|
|
pc_deallocator free;
|
|
pc_message_handler err;
|
|
pc_message_handler warn;
|
|
pc_message_handler info;
|
|
};
|
|
|
|
static struct pc_context_t pc_context;
|
|
|
|
/*
|
|
* Default allocators
|
|
*
|
|
* We include some default allocators that use malloc/free/realloc
|
|
* along with stdout/stderr since this is the most common use case
|
|
*
|
|
*/
|
|
|
|
static void *
|
|
default_allocator(size_t size)
|
|
{
|
|
return malloc(size);
|
|
}
|
|
|
|
static void
|
|
default_freeor(void *mem)
|
|
{
|
|
free(mem);
|
|
}
|
|
|
|
static void *
|
|
default_reallocator(void *mem, size_t size)
|
|
{
|
|
return realloc(mem, size);
|
|
}
|
|
|
|
static void
|
|
default_msg_handler(const char *label, const char *fmt, va_list ap)
|
|
{
|
|
char newfmt[1024] = {0};
|
|
snprintf(newfmt, 1024, "%s%s\n", label, fmt);
|
|
newfmt[1023] = '\0';
|
|
vprintf(newfmt, ap);
|
|
}
|
|
|
|
static void
|
|
default_info_handler(const char *fmt, va_list ap)
|
|
{
|
|
default_msg_handler("INFO: ", fmt, ap);
|
|
}
|
|
|
|
static void
|
|
default_warn_handler(const char *fmt, va_list ap)
|
|
{
|
|
default_msg_handler("WARNING: ", fmt, ap);
|
|
}
|
|
|
|
static void
|
|
default_error_handler(const char *fmt, va_list ap)
|
|
{
|
|
default_msg_handler("ERROR: ", fmt, ap);
|
|
va_end(ap);
|
|
exit(1);
|
|
}
|
|
|
|
|
|
void pc_install_default_handlers(void)
|
|
{
|
|
pc_context.alloc = default_allocator;
|
|
pc_context.realloc = default_reallocator;
|
|
pc_context.free = default_freeor;
|
|
pc_context.err = default_error_handler;
|
|
pc_context.info = default_info_handler;
|
|
pc_context.warn = default_warn_handler;
|
|
|
|
#ifdef HAVE_LIBGHT
|
|
ght_set_handlers(
|
|
(void *)default_allocator, (void *)default_reallocator,
|
|
(void *)default_freeor, (void *)default_error_handler,
|
|
(void *)default_info_handler, (void *)default_warn_handler
|
|
);
|
|
#endif
|
|
|
|
}
|
|
|
|
void pc_set_handlers(
|
|
pc_allocator allocator, pc_reallocator reallocator,
|
|
pc_deallocator deallocator, pc_message_handler error_handler,
|
|
pc_message_handler info_handler, pc_message_handler warn_handler)
|
|
{
|
|
if ( ! allocator ) allocator = pc_context.alloc;
|
|
if ( ! reallocator ) reallocator = pc_context.realloc;
|
|
if ( ! deallocator ) deallocator = pc_context.free;
|
|
if ( ! error_handler ) error_handler = pc_context.err;
|
|
if ( ! warn_handler ) warn_handler = pc_context.warn;
|
|
if ( ! info_handler ) info_handler = pc_context.info;
|
|
|
|
pc_context.alloc = allocator;
|
|
pc_context.realloc = reallocator;
|
|
pc_context.free = deallocator;
|
|
pc_context.err = error_handler;
|
|
pc_context.warn = warn_handler;
|
|
pc_context.info = info_handler;
|
|
|
|
#ifdef HAVE_LIBGHT
|
|
ght_set_handlers(
|
|
(void *)allocator, (void *)reallocator,
|
|
(void *)deallocator, (void *)error_handler,
|
|
(void *)info_handler, (void *)warn_handler
|
|
);
|
|
#endif
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
void *
|
|
pcalloc(size_t size)
|
|
{
|
|
void *mem;
|
|
if ( ! size ) return NULL;
|
|
mem = pc_context.alloc(size);
|
|
memset(mem, 0, size); /* Always clean memory */
|
|
return mem;
|
|
}
|
|
|
|
char *
|
|
pcstrdup(const char *str)
|
|
{
|
|
size_t len = strlen(str);
|
|
char *newstr = pcalloc(len + 1);
|
|
memcpy(newstr, str, len + 1);
|
|
return newstr;
|
|
}
|
|
|
|
void *
|
|
pcrealloc(void * mem, size_t size)
|
|
{
|
|
return pc_context.realloc(mem, size);
|
|
}
|
|
|
|
void
|
|
pcfree(void * mem)
|
|
{
|
|
pc_context.free(mem);
|
|
}
|
|
|
|
void
|
|
pcerror(const char *fmt, ...)
|
|
{
|
|
va_list ap;
|
|
va_start(ap, fmt);
|
|
(*pc_context.err)(fmt, ap);
|
|
va_end(ap);
|
|
}
|
|
|
|
void
|
|
pcinfo(const char *fmt, ...)
|
|
{
|
|
va_list ap;
|
|
va_start(ap, fmt);
|
|
(*pc_context.info)(fmt, ap);
|
|
va_end(ap);
|
|
}
|
|
|
|
void
|
|
pcwarn(const char *fmt, ...)
|
|
{
|
|
va_list ap;
|
|
va_start(ap, fmt);
|
|
(*pc_context.warn)(fmt, ap);
|
|
va_end(ap);
|
|
}
|
|
|