Annotation of parser3/src/main/pa_globals.C, revision 1.152.2.19.2.16
1.15 paf 1: /** @file
1.16 paf 2: Parser: globals.
3:
1.152.2.10 paf 4: Copyright (c) 2001-2003 ArtLebedev Group (http://www.artlebedev.com)
1.113 paf 5: Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
1.133 paf 6: */
1.16 paf 7:
1.152.2.19.2. 6(paf 8:3): static const char* IDENT_GLOBALS_C="$Date: 2003/04/09 08:40:25 $";
1.1 paf 9:
1.102 paf 10: #include "pa_config_includes.h"
11:
12: #ifdef XML
1.152.2.19.2. 6(paf 13:3): #include "libxml/xmlversion.h"
1.102 paf 14: #include "libxslt/extensions.h"
15: #include "libxslt/xsltutils.h"
1.116 paf 16: extern "C" {
1.102 paf 17: #include "libexslt/exslt.h"
1.116 paf 18: };
1.102 paf 19: #endif
20:
1.1 paf 21: #include "pa_globals.h"
1.32 paf 22: #include "pa_string.h"
1.83 parser 23: #include "pa_sapi.h"
1.101 paf 24: #include "pa_threads.h"
1.152.2.2 paf 25:
1.152.2.19.2. (paf 26:):
27:): // defines
28:):
29:): #define PA_DEBUG_XML_GC_MEMORY
30:):
31:): // globals
32:):
1.5 paf 33: short hex_value[0x100];
1.111 paf 34:
35: #ifdef XML
36: GdomeDOMImplementation *domimpl;
37: #endif
1.5 paf 38:
39: static void setup_hex_value() {
1.68 parser 40: memset(hex_value, 0, sizeof(hex_value));
1.5 paf 41: hex_value['0'] = 0;
42: hex_value['1'] = 1;
43: hex_value['2'] = 2;
44: hex_value['3'] = 3;
45: hex_value['4'] = 4;
46: hex_value['5'] = 5;
47: hex_value['6'] = 6;
48: hex_value['7'] = 7;
49: hex_value['8'] = 8;
50: hex_value['9'] = 9;
51: hex_value['A'] = 10;
52: hex_value['B'] = 11;
53: hex_value['C'] = 12;
54: hex_value['D'] = 13;
55: hex_value['E'] = 14;
56: hex_value['F'] = 15;
57: hex_value['a'] = 10;
58: hex_value['b'] = 11;
59: hex_value['c'] = 12;
60: hex_value['d'] = 13;
61: hex_value['e'] = 14;
62: hex_value['f'] = 15;
63: }
1.1 paf 64:
1.99 paf 65: #ifdef XML
1.101 paf 66:
67: const int MAX_CONCURRENT_XML_GENERIC_ERROR_THREADS=10;
68:
1.152.2.17 paf 69: class XML_Generic_error_info {
70: public:
1.101 paf 71: pa_thread_t thread_id;
1.152.2.17 paf 72: char buf[MAX_STRING];
73: size_t used;
74: public:
75: XML_Generic_error_info() {
76: reset();
77: }
78: void reset() {
79: thread_id=0;
80: buf[used=0]=0;
81: }
1.152.2.19.2. 0(paf 82:3): const char* getnd_reset() {
(paf 83:): char* result=new(PointerFreeGC) char[used+1];
84:): memcpy(result, buf, used+1);
1.152.2.17 paf 85: reset();
86: return result;
87: }
1.101 paf 88: } xml_generic_error_infos[MAX_CONCURRENT_XML_GENERIC_ERROR_THREADS];
89:
90: XML_Generic_error_info *xml_generic_error_info(pa_thread_t thread_id) {
91: for(int i=0; i<MAX_CONCURRENT_XML_GENERIC_ERROR_THREADS; i++) {
92: XML_Generic_error_info *p=xml_generic_error_infos+i;
93: if(p->thread_id==thread_id)
94: return p;
95: }
96: return 0;
97: }
98:
1.99 paf 99: static void
1.152.2.10 paf 100: xmlParserGenericErrorFunc(void *ctx, const char* msg, ...) {
1.101 paf 101: pa_thread_t thread_id=pa_get_thread_id();
102:
103: // infinitely looking for free slot to fill it
104: while(true) {
105: SYNCHRONIZED; // find+fill blocked
106:
107: // first try to get existing for this thread_id
108: XML_Generic_error_info *p=xml_generic_error_info(thread_id);
109: if(!p) { // occupy empty one
110: p=xml_generic_error_info(0);
111: if(!p) // wait for empty for it to appear
112: continue;
113: }
114:
1.102 paf 115: p->thread_id=thread_id;
1.101 paf 116:
117: va_list args;
118: va_start(args, msg);
1.152.2.19 paf 119: p->used+=vsnprintf(p->buf+p->used, sizeof(p->buf)-p->used, msg, args);
1.101 paf 120: va_end(args);
121:
122: break;
123: }
124: }
125:
1.102 paf 126: bool xmlHaveGenericErrors() {
127: pa_thread_t thread_id=pa_get_thread_id();
128:
129: SYNCHRONIZED; // find blocked
130:
131: return xml_generic_error_info(thread_id)!=0;
132: }
133:
1.152.2.19.2. (paf 134:): const char* xmlGenericErrors() {
1.101 paf 135: pa_thread_t thread_id=pa_get_thread_id();
136:
137: SYNCHRONIZED; // find+free blocked
138:
139: XML_Generic_error_info *p=xml_generic_error_info(thread_id);
140: if(!p) // no errors for our thread_id registered
1.152.2.19.2. (paf 141:): return 0;
1.101 paf 142:
1.152.2.19.2. 0(paf 143:3): return p->getnd_reset();
1.99 paf 144: }
1.110 paf 145:
146: /**
147: * xmlFileMatchWithLocalhostEqDocumentRoot:
148: * filename: the URI for matching
149: *
150: * check if the URI matches an HTTP one
151: *
152: * Returns 1 if matches, 0 otherwise
153: */
154: static int
1.152.2.10 paf 155: xmlFileMatchLocalhost(const char* filename) {
1.110 paf 156: if (!strncmp(filename, "http://localhost", 16))
157: return(1);
158: return(0);
159: }
160:
161:
162: /**
163: * xmlFileOpenHttpLocalhost :
164: * filename: the URI for matching
165: *
166: * http://localhost/abc -> $ENV{DOCUMENT_ROOT}/abc | ./abc
167: *
168: * input from FILE *, supports compressed input
169: * if filename is " " then the standard input is used
170: *
171: * Returns an I/O context or NULL in case of error
172: */
173: static void *
1.152.2.10 paf 174: xmlFileOpenLocalhost (const char* filename) {
1.110 paf 175: FILE *fd;
176: const char* documentRoot;
177: char path[1000];
178:
179: path[0]=0;
180: strcat(path, (documentRoot=getenv("DOCUMENT_ROOT"))?documentRoot:".");
181: strcat(path, &filename[16]);
182:
183: #ifdef WIN32
184: fd = fopen(path, "rb");
185: #else
186: fd = fopen(path, "r");
187: #endif /* WIN32 */
188: return((void *) fd);
189: }
190:
1.150 paf 191: /**
192: * xmlFileRead:
193: * @context: the I/O context
194: * @buffer: where to drop data
195: * @len: number of bytes to write
196: *
197: * Read @len bytes to @buffer from the I/O channel.
198: *
199: * Returns the number of bytes written
200: */
201: static int
202: pa_xmlFileRead (void * context, char * buffer, int len) {
203: return(fread(&buffer[0], 1, len, (FILE *) context));
204: }
205:
206: /**
207: * xmlFileClose:
208: * @context: the I/O context
209: *
210: * Close an I/O channel
211: */
212: static int
213: pa_xmlFileClose (void * context) {
214: return ( ( fclose((FILE *) context) == EOF ) ? -1 : 0 );
215: }
216:
1.99 paf 217: #endif
218:
1.83 parser 219: void pa_globals_destroy(void *) {
220: try {
1.96 paf 221: #ifdef XML
222: GdomeException exc;
223: gdome_di_unref (domimpl, &exc);
224: #endif
1.83 parser 225: } catch(const Exception& e) {
1.152.2.16 paf 226: SAPI::abort("pa_globals_destroy failed: %s", e.comment());
1.83 parser 227: }
228: }
229:
230:
1.152.2.19.2. (paf 231:): #ifdef XML
232:): static char *pa_GC_strdup(const char *s) {
233:): if(!s)
234:): return 0;
235:):
236:): size_t size=strlen(s)+1;
237:): char *result=(char *)GC_malloc_atomic(size);
238:): memcpy(result, s, size);
239:): return result;
240:): }
241:): #endif
242:):
3(paf 243:3): void pa_CORD_oom_fn(void) {
244:3): SAPI::abort("out of memory (while expanding string)");
245:3): }
1.74 parser 246:
1.152.2.19.2. 3(paf 247:3): /**
248:3): @todo gc: pcre: substitute pcre_malloc &co
249:3): @todo gc: libltdl: substitute lt_dlmalloc & co
250:3): @todo gc: figure out how to substitute glib memory allocator
251:3): */
4(paf 252:3): static void gc_substitute_memory_management_functions() {
3(paf 253:3): // in libxml & libxslt
1.76 parser 254: #ifdef XML
1.152.2.19.2. (paf 255:): // asking to use GC memory
6(paf 256:3): #if LIBXML_VERSION >= 20506
257:3): xmlGcMemSetup(
258:3): /*xmlFreeFunc */pa_gc_free,
259:3): /*xmlMallocFunc */pa_gc_malloc,
260:3): /*xmlMallocFunc */pa_gc_malloc_atomic,
261:3): /*xmlReallocFunc */pa_gc_realloc,
262:3): /*xmlStrdupFunc */pa_GC_strdup);
263:3): #else
(paf 264:): xmlMemSetup(
2(paf 265:3): /*xmlFreeFunc */pa_gc_free,
266:3): /*xmlMallocFunc */pa_gc_malloc,
267:3): /*xmlReallocFunc */pa_gc_realloc,
(paf 268:): /*xmlStrdupFunc */pa_GC_strdup);
6(paf 269:3): #endif
270:3):
(paf 271:): #endif
3(paf 272:3):
273:3): CORD_oom_fn=pa_CORD_oom_fn;
274:3): }
275:3):
276:3): /**
277:3): @test hint on one should call this for each thread xmlSubstituteEntitiesDefault(1);
278:3): */
279:3): void pa_globals_init() {
280:3): // in various libraries
281:3): gc_substitute_memory_management_functions();
282:3):
283:3): // hex value
284:3): setup_hex_value();
285:3):
286:3): #ifdef XML
287:3): // initializing xml libs
(paf 288:):
289:): /* First get a DOMImplementation reference */
1.96 paf 290: domimpl = gdome_di_mkref ();
1.152.2.19.2. (paf 291:): /*
292:): * Register the EXSLT extensions and the test module
293:): */
294:): exsltRegisterAll();
295:): xsltRegisterTestModule();
296:): xmlDefaultSAXHandlerInit();
297:): /*
298:): * disable CDATA from being built in the document tree
299:): */
300:): // never added yet xmlDefaultSAXHandler.cdataBlock = NULL;
301:):
1.99 paf 302: /*
303: * Initialization function for the XML parser.
304: * This is not reentrant. Call once before processing in case of
305: * use in multithreaded programs.
306: */
307: xmlInitParser();
1.107 paf 308:
309: // 1. this is needed for proper parsing of stylesheets
310: // there were a situation where honest entity ruined innocent xpath compilation
311: // doc says "you sould turn it on on stylesheet load" without deepening into details
312: // 2. when dom tree with entites goes under transform text nodes
313: // got [erroreosly] cut on first entity occurance
1.109 paf 314: // --
1.107 paf 315: // that is why this is:
316: xmlSubstituteEntitiesDefault(1);
1.100 paf 317:
318: // Bit in the loadsubset context field to tell to do ID/REFs lookups
319: xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
320: // Bit in the loadsubset context field to tell to do complete the elements attributes lists
321: // with the ones defaulted from the DTDs
1.152.2.19.2. (paf 322:): xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;
1.138 paf 323:
324: // validate each document after load/create (?)
325: //xmlDoValidityCheckingDefaultValue = 1;
1.99 paf 326:
1.104 paf 327: //regretfully this not only replaces entities on parse, but also on generate xmlSubstituteEntitiesDefault(1);
1.105 paf 328: // never switched this on xmlIndentTreeOutput=1;
1.104 paf 329:
1.101 paf 330: xmlSetGenericErrorFunc(0, xmlParserGenericErrorFunc);
1.102 paf 331: xsltSetGenericErrorFunc(0, xmlParserGenericErrorFunc);
1.105 paf 332: // FILE *f=fopen("y:\\xslt.log", "wt");
333: // xsltSetGenericDebugFunc(f/*stderr*/, 0);
1.110 paf 334:
335: // http://localhost/abc -> $ENV{DOCUMENT_ROOT}/abc | ./abc
336: xmlRegisterInputCallbacks(
337: xmlFileMatchLocalhost, xmlFileOpenLocalhost,
1.150 paf 338: pa_xmlFileRead, pa_xmlFileClose);
1.76 parser 339: #endif
1.1 paf 340: }
1.76 parser 341:
1.152.2.19.2. 0(paf 342:3): #ifdef _MSC_VER
343:3):
344:3): #ifndef PA_DEBUG_DISABLE_GC
345:3): # define GC_LIB "/parser3project/win32/gc"
346:3): # ifdef _DEBUG
347:3): # pragma comment(lib, GC_LIB "/Debug/gc.lib")
348:3): # else
349:3): # pragma comment(lib, GC_LIB "/Release/gc.lib")
350:3): # endif
351:3):
352:3): #endif
353:3):
354:3): #ifdef XML
1.132 paf 355: # define GNOME_LIBS "/parser3project/win32xml/win32/gnome"
1.131 paf 356: # pragma comment(lib, GNOME_LIBS "/glib/lib/libglib-1.3-11.lib")
1.76 parser 357: # ifdef _DEBUG
1.152.2.19.2. 0(paf 358:3):
359:3): # ifdef LIBXML_STATIC
360:3): # pragma comment(lib, GNOME_LIBS "/gnome-xml/win32/dsp/libxml2_DebugStatic/libxml2.lib")
361:3): # else
362:3): # pragma comment(lib, GNOME_LIBS "/gnome-xml/win32/dsp/libxml2_DebugDynamic/libxml2.lib")
363:3): # endif
364:3):
365:3): # ifdef LIBXSLT_STATIC
366:3): # pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/dsp/libxslt_DebugStatic/libxslt.lib")
367:3): # else
368:3): # pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/dsp/libxslt_DebugDynamic/libxslt.lib")
369:3): # endif
370:3): # ifdef LIBEXSLT_STATIC
371:3): # pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/dsp/libexslt_DebugStatic/libexslt.lib")
372:3): # else
373:3): # pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/dsp/libexslt_DebugDynamic/libexslt.lib")
374:3): # endif
375:3):
376:3): # ifdef LIBGDOME_STATIC
377:3): # pragma comment(lib, GNOME_LIBS "/gdome2-x.x.x/win32/dsp/libgdome_DebugStatic/libgdome.lib")
378:3): # else
379:3): # pragma comment(lib, GNOME_LIBS "/gdome2-x.x.x/win32/dsp/libgdome_DebugDynamic/libgdome.lib")
380:3): # endif
381:3):
382:3): #else
383:3):
384:3): # ifdef LIBXML_STATIC
385:3): # pragma comment(lib, GNOME_LIBS "/gnome-xml/win32/dsp/libxml2_ReleaseStatic/libxml2.lib")
386:3): # else
5(paf 387:3): # pragma comment(lib, GNOME_LIBS "/gnome-xml/win32/dsp/libxml2_ReleaseDynamic/libxml2.lib")
0(paf 388:3): # endif
389:3):
390:3): # ifdef LIBXSLT_STATIC
391:3): # pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/dsp/libxslt_ReleaseStatic/libxslt.lib")
392:3): # else
393:3): # pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/dsp/libxslt_ReleaseDynamic/libxslt.lib")
394:3): # endif
395:3): # ifdef LIBEXSLT_STATIC
396:3): # pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/dsp/libexslt_ReleaseStatic/libexslt.lib")
397:3): # else
398:3): # pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/dsp/libexslt_ReleaseDynamic/libexslt.lib")
399:3): # endif
400:3):
401:3): # ifdef LIBGDOME_STATIC
402:3): # pragma comment(lib, GNOME_LIBS "/gdome2-x.x.x/win32/dsp/libgdome_ReleaseStatic/libgdome.lib")
403:3): # else
404:3): # pragma comment(lib, GNOME_LIBS "/gdome2-x.x.x/win32/dsp/libgdome_ReleaseDynamic/libgdome.lib")
405:3): # endif
406:3):
1.85 paf 407: # endif
1.152.2.19.2. 0(paf 408:3): #endif
409:3):
1.85 paf 410: #endif
E-mail: