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