File: pc_mem.c

package info (click to toggle)
pgpointcloud 1.2.5-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 4,892 kB
  • sloc: sql: 40,767; ansic: 11,045; xml: 935; makefile: 297; cpp: 282; perl: 248; python: 178; sh: 92
file content (156 lines) | stat: -rw-r--r-- 3,592 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/***********************************************************************
 * 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 "pc_api_internal.h"
#include <stdarg.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;
}

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;
  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);
}