diff options
Diffstat (limited to 'pathologist/src/minixml/mxml-private.c')
-rw-r--r-- | pathologist/src/minixml/mxml-private.c | 331 |
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 | |||
63 | void | ||
64 | mxml_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 | |||
105 | mxml_type_t /* O - Node type */ | ||
106 | mxml_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 | |||
118 | mxml_type_t /* O - Node type */ | ||
119 | mxml_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 | |||
131 | mxml_type_t /* O - Node type */ | ||
132 | mxml_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 | |||
144 | mxml_type_t /* O - Node type */ | ||
145 | mxml_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 | |||
156 | static pthread_key_t _mxml_key = -1; /* Thread local storage key */ | ||
157 | static pthread_once_t _mxml_key_once = PTHREAD_ONCE_INIT; | ||
158 | /* One-time initialization object */ | ||
159 | static void _mxml_init(void); | ||
160 | static void _mxml_destructor(void *g); | ||
161 | |||
162 | |||
163 | /* | ||
164 | * '_mxml_destructor()' - Free memory used for globals... | ||
165 | */ | ||
166 | |||
167 | static 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 | |||
178 | static 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 | |||
225 | static 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 | |||
235 | static DWORD _mxml_tls_index; /* Index for global storage */ | ||
236 | |||
237 | |||
238 | /* | ||
239 | * 'DllMain()' - Main entry for library. | ||
240 | */ | ||
241 | |||
242 | BOOL WINAPI /* O - Success/failure */ | ||
243 | DllMain(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 | */ | ||