aboutsummaryrefslogtreecommitdiff
path: root/pathologist/src/minixml/mxml-private.c
diff options
context:
space:
mode:
Diffstat (limited to 'pathologist/src/minixml/mxml-private.c')
-rw-r--r--pathologist/src/minixml/mxml-private.c331
1 files changed, 331 insertions, 0 deletions
diff --git a/pathologist/src/minixml/mxml-private.c b/pathologist/src/minixml/mxml-private.c
new file mode 100644
index 0000000..72f3e23
--- /dev/null
+++ b/pathologist/src/minixml/mxml-private.c
@@ -0,0 +1,331 @@
1/*
2 * "$Id: mxml-private.c 422 2010-11-07 22:55:11Z mike $"
3 *
4 * Private functions for Mini-XML, a small XML-like file parsing library.
5 *
6 * Copyright 2003-2010 by Michael R Sweet.
7 *
8 * These coded instructions, statements, and computer programs are the
9 * property of Michael R Sweet and are protected by Federal copyright
10 * law. Distribution and use rights are outlined in the file "COPYING"
11 * which should have been included with this file. If this file is
12 * missing or damaged, see the license at:
13 *
14 * http://www.minixml.org/
15 *
16 * Contents:
17 *
18 * mxml_error() - Display an error message.
19 * mxml_integer_cb() - Default callback for integer values.
20 * mxml_opaque_cb() - Default callback for opaque values.
21 * mxml_real_cb() - Default callback for real number values.
22 * _mxml_global() - Get global data.
23 */
24
25/*
26 * Include necessary headers...
27 */
28
29#include "mxml-private.h"
30
31
32/*
33 * Some crazy people think that unloading a shared object is a good or safe
34 * thing to do. Unfortunately, most objects are simply *not* safe to unload
35 * and bad things *will* happen.
36 *
37 * The following mess of conditional code allows us to provide a destructor
38 * function in Mini-XML for our thread-global storage so that it can possibly
39 * be unloaded safely, although since there is no standard way to do so I
40 * can't even provide any guarantees that you can do it safely on all platforms.
41 *
42 * This code currently supports AIX, HP-UX, Linux, Mac OS X, Solaris, and
43 * Windows. It might work on the BSDs and IRIX, but I haven't tested that.
44 */
45
46#if defined(__sun) || defined(_AIX)
47# pragma fini(_mxml_fini)
48# define _MXML_FINI _mxml_fini
49#elif defined(__hpux)
50# pragma FINI _mxml_fini
51# define _MXML_FINI _mxml_fini
52#elif defined(__GNUC__) /* Linux and Mac OS X */
53# define _MXML_FINI __attribute((destructor)) _mxml_fini
54#else
55# define _MXML_FINI _fini
56#endif /* __sun */
57
58
59/*
60 * 'mxml_error()' - Display an error message.
61 */
62
63void
64mxml_error(const char *format, /* I - Printf-style format string */
65 ...) /* I - Additional arguments as needed */
66{
67 va_list ap; /* Pointer to arguments */
68 char s[1024]; /* Message string */
69 _mxml_global_t *global = _mxml_global();
70 /* Global data */
71
72
73 /*
74 * Range check input...
75 */
76
77 if (!format)
78 return;
79
80 /*
81 * Format the error message string...
82 */
83
84 va_start(ap, format);
85
86 vsnprintf(s, sizeof(s), format, ap);
87
88 va_end(ap);
89
90 /*
91 * And then display the error message...
92 */
93
94 if (global->error_cb)
95 (*global->error_cb)(s);
96 else
97 fprintf(stderr, "mxml: %s\n", s);
98}
99
100
101/*
102 * 'mxml_ignore_cb()' - Default callback for ignored values.
103 */
104
105mxml_type_t /* O - Node type */
106mxml_ignore_cb(mxml_node_t *node) /* I - Current node */
107{
108 (void)node;
109
110 return (MXML_IGNORE);
111}
112
113
114/*
115 * 'mxml_integer_cb()' - Default callback for integer values.
116 */
117
118mxml_type_t /* O - Node type */
119mxml_integer_cb(mxml_node_t *node) /* I - Current node */
120{
121 (void)node;
122
123 return (MXML_INTEGER);
124}
125
126
127/*
128 * 'mxml_opaque_cb()' - Default callback for opaque values.
129 */
130
131mxml_type_t /* O - Node type */
132mxml_opaque_cb(mxml_node_t *node) /* I - Current node */
133{
134 (void)node;
135
136 return (MXML_OPAQUE);
137}
138
139
140/*
141 * 'mxml_real_cb()' - Default callback for real number values.
142 */
143
144mxml_type_t /* O - Node type */
145mxml_real_cb(mxml_node_t *node) /* I - Current node */
146{
147 (void)node;
148
149 return (MXML_REAL);
150}
151
152
153#ifdef HAVE_PTHREAD_H /**** POSIX threading ****/
154# include <pthread.h>
155
156static pthread_key_t _mxml_key = -1; /* Thread local storage key */
157static pthread_once_t _mxml_key_once = PTHREAD_ONCE_INIT;
158 /* One-time initialization object */
159static void _mxml_init(void);
160static void _mxml_destructor(void *g);
161
162
163/*
164 * '_mxml_destructor()' - Free memory used for globals...
165 */
166
167static void
168_mxml_destructor(void *g) /* I - Global data */
169{
170 free(g);
171}
172
173
174/*
175 * '_mxml_fini()' - Clean up when unloaded.
176 */
177
178static void
179_MXML_FINI(void)
180{
181 _mxml_global_t *global; /* Global data */
182
183
184 if (_mxml_key != -1)
185 {
186 if ((global = (_mxml_global_t *)pthread_getspecific(_mxml_key)) != NULL)
187 _mxml_destructor(global);
188
189 pthread_key_delete(_mxml_key);
190 _mxml_key = -1;
191 }
192}
193
194
195/*
196 * '_mxml_global()' - Get global data.
197 */
198
199_mxml_global_t * /* O - Global data */
200_mxml_global(void)
201{
202 _mxml_global_t *global; /* Global data */
203
204
205 pthread_once(&_mxml_key_once, _mxml_init);
206
207 if ((global = (_mxml_global_t *)pthread_getspecific(_mxml_key)) == NULL)
208 {
209 global = (_mxml_global_t *)calloc(1, sizeof(_mxml_global_t));
210 pthread_setspecific(_mxml_key, global);
211
212 global->num_entity_cbs = 1;
213 global->entity_cbs[0] = _mxml_entity_cb;
214 global->wrap = 72;
215 }
216
217 return (global);
218}
219
220
221/*
222 * '_mxml_init()' - Initialize global data...
223 */
224
225static void
226_mxml_init(void)
227{
228 pthread_key_create(&_mxml_key, _mxml_destructor);
229}
230
231
232#elif defined(WIN32) && defined(MXML1_EXPORTS) /**** WIN32 threading ****/
233# include <windows.h>
234
235static DWORD _mxml_tls_index; /* Index for global storage */
236
237
238/*
239 * 'DllMain()' - Main entry for library.
240 */
241
242BOOL WINAPI /* O - Success/failure */
243DllMain(HINSTANCE hinst, /* I - DLL module handle */
244 DWORD reason, /* I - Reason */
245 LPVOID reserved) /* I - Unused */
246{
247 _mxml_global_t *global; /* Global data */
248
249
250 (void)hinst;
251 (void)reserved;
252
253 switch (reason)
254 {
255 case DLL_PROCESS_ATTACH : /* Called on library initialization */
256 if ((_mxml_tls_index = TlsAlloc()) == TLS_OUT_OF_INDEXES)
257 return (FALSE);
258 break;
259
260 case DLL_THREAD_DETACH : /* Called when a thread terminates */
261 if ((global = (_mxml_global_t *)TlsGetValue(_mxml_tls_index)) != NULL)
262 free(global);
263 break;
264
265 case DLL_PROCESS_DETACH : /* Called when library is unloaded */
266 if ((global = (_mxml_global_t *)TlsGetValue(_mxml_tls_index)) != NULL)
267 free(global);
268
269 TlsFree(_mxml_tls_index);
270 break;
271
272 default:
273 break;
274 }
275
276 return (TRUE);
277}
278
279
280/*
281 * '_mxml_global()' - Get global data.
282 */
283
284_mxml_global_t * /* O - Global data */
285_mxml_global(void)
286{
287 _mxml_global_t *global; /* Global data */
288
289
290 if ((global = (_mxml_global_t *)TlsGetValue(_mxml_tls_index)) == NULL)
291 {
292 global = (_mxml_global_t *)calloc(1, sizeof(_mxml_global_t));
293
294 global->num_entity_cbs = 1;
295 global->entity_cbs[0] = _mxml_entity_cb;
296 global->wrap = 72;
297
298 TlsSetValue(_mxml_tls_index, (LPVOID)global);
299 }
300
301 return (global);
302}
303
304
305#else /**** No threading ****/
306/*
307 * '_mxml_global()' - Get global data.
308 */
309
310_mxml_global_t * /* O - Global data */
311_mxml_global(void)
312{
313 static _mxml_global_t global = /* Global data */
314 {
315 NULL, /* error_cb */
316 1, /* num_entity_cbs */
317 { _mxml_entity_cb }, /* entity_cbs */
318 72, /* wrap */
319 NULL, /* custom_load_cb */
320 NULL /* custom_save_cb */
321 };
322
323
324 return (&global);
325}
326#endif /* HAVE_PTHREAD_H */
327
328
329/*
330 * End of "$Id: mxml-private.c 422 2010-11-07 22:55:11Z mike $".
331 */