Annotation of parser3/src/main/pa_globals.C, revision 1.152.2.19.2.18
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. 8(paf 8:3): static const char* IDENT_GLOBALS_C="$Date: 2003/04/21 12:11:30 $";
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:):
31:): #define PA_DEBUG_XML_GC_MEMORY
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
246:3): static void *pa_look_for=(void*)0x01db2000;
247:3): static void* pa_gc_malloc_log(size_t size){
248:3): //fprintf(stderr, "pa_gc_free_log(0x%p)\n", p);
249:3): void *p=pa_gc_malloc(size);
250:3): if(p==pa_look_for)
251:3): fprintf(stderr,"catched debug free");
252:3): return p;
253:3):
254:3): }
255:3): static void* pa_gc_malloc_atomic_log(size_t size){
256:3): //fprintf(stderr, "pa_gc_free_log(0x%p)\n", p);
257:3): void *p=pa_gc_malloc_atomic(size);
258:3): if(p==pa_look_for)
259:3): fprintf(stderr,"catched debug free");
260:3): return p;
261:3): }
262:3): //static void pa_gc_free_ignore(void *){}
263:3): static void pa_gc_free_log(void *p){
264:3): //fprintf(stderr, "pa_gc_free_log(0x%p)\n", p);
265:3): if(p==pa_look_for)
266:3): fprintf(stderr,"catched debug free");
267:3): pa_gc_free(p);
268:3): }
269:3): #endif
(paf 270:): #endif
271:):
3(paf 272:3): void pa_CORD_oom_fn(void) {
273:3): SAPI::abort("out of memory (while expanding string)");
274:3): }
1.74 parser 275:
1.152.2.19.2. 3(paf 276:3): /**
7(paf 277:3): @todo LIBXML_VERSION with xmlGcMemSetup will be 2.5.7
3(paf 278:3): @todo gc: libltdl: substitute lt_dlmalloc & co
279:3): */
4(paf 280:3): static void gc_substitute_memory_management_functions() {
3(paf 281:3): // in libxml & libxslt
1.76 parser 282: #ifdef XML
1.152.2.19.2. (paf 283:): // asking to use GC memory
8(paf 284:3): #if LIBXML_VERSION >= 20507
285:3): #ifdef PA_DEBUG_XML_GC_MEMORY
286:3): xmlGcMemSetup(
287:3): /*xmlFreeFunc */pa_gc_free_log,
288:3): /*xmlMallocFunc */pa_gc_malloc_log,
289:3): /*xmlMallocFunc */pa_gc_malloc_atomic_log,
290:3): /*xmlReallocFunc */pa_gc_realloc,
291:3): /*xmlStrdupFunc */pa_GC_strdup);
292:3): #else
6(paf 293:3): xmlGcMemSetup(
294:3): /*xmlFreeFunc */pa_gc_free,
295:3): /*xmlMallocFunc */pa_gc_malloc,
296:3): /*xmlMallocFunc */pa_gc_malloc_atomic,
297:3): /*xmlReallocFunc */pa_gc_realloc,
298:3): /*xmlStrdupFunc */pa_GC_strdup);
8(paf 299:3): #endif
300:3):
6(paf 301:3): #else
(paf 302:): xmlMemSetup(
2(paf 303:3): /*xmlFreeFunc */pa_gc_free,
304:3): /*xmlMallocFunc */pa_gc_malloc,
305:3): /*xmlReallocFunc */pa_gc_realloc,
(paf 306:): /*xmlStrdupFunc */pa_GC_strdup);
6(paf 307:3): #endif
308:3):
(paf 309:): #endif
3(paf 310:3):
7(paf 311:3): // pcre
312:3): pcre_malloc=pa_gc_malloc;
313:3): pcre_free=pa_gc_free;
314:3):
315:3):
316:3): // cord
3(paf 317:3): CORD_oom_fn=pa_CORD_oom_fn;
318:3): }
319:3):
320:3): /**
321:3): @test hint on one should call this for each thread xmlSubstituteEntitiesDefault(1);
322:3): */
323:3): void pa_globals_init() {
324:3): // in various libraries
325:3): gc_substitute_memory_management_functions();
326:3):
327:3): // hex value
328:3): setup_hex_value();
329:3):
330:3): #ifdef XML
331:3): // initializing xml libs
(paf 332:):
333:): /* First get a DOMImplementation reference */
1.96 paf 334: domimpl = gdome_di_mkref ();
1.152.2.19.2. (paf 335:): /*
336:): * Register the EXSLT extensions and the test module
337:): */
338:): exsltRegisterAll();
339:): xsltRegisterTestModule();
340:): xmlDefaultSAXHandlerInit();
341:): /*
342:): * disable CDATA from being built in the document tree
343:): */
344:): // never added yet xmlDefaultSAXHandler.cdataBlock = NULL;
345:):
1.99 paf 346: /*
347: * Initialization function for the XML parser.
348: * This is not reentrant. Call once before processing in case of
349: * use in multithreaded programs.
350: */
351: xmlInitParser();
1.107 paf 352:
353: // 1. this is needed for proper parsing of stylesheets
354: // there were a situation where honest entity ruined innocent xpath compilation
355: // doc says "you sould turn it on on stylesheet load" without deepening into details
356: // 2. when dom tree with entites goes under transform text nodes
357: // got [erroreosly] cut on first entity occurance
1.109 paf 358: // --
1.107 paf 359: // that is why this is:
360: xmlSubstituteEntitiesDefault(1);
1.100 paf 361:
362: // Bit in the loadsubset context field to tell to do ID/REFs lookups
363: xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
364: // Bit in the loadsubset context field to tell to do complete the elements attributes lists
365: // with the ones defaulted from the DTDs
1.152.2.19.2. (paf 366:): xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;
1.138 paf 367:
368: // validate each document after load/create (?)
369: //xmlDoValidityCheckingDefaultValue = 1;
1.99 paf 370:
1.104 paf 371: //regretfully this not only replaces entities on parse, but also on generate xmlSubstituteEntitiesDefault(1);
1.105 paf 372: // never switched this on xmlIndentTreeOutput=1;
1.104 paf 373:
1.101 paf 374: xmlSetGenericErrorFunc(0, xmlParserGenericErrorFunc);
1.102 paf 375: xsltSetGenericErrorFunc(0, xmlParserGenericErrorFunc);
1.105 paf 376: // FILE *f=fopen("y:\\xslt.log", "wt");
377: // xsltSetGenericDebugFunc(f/*stderr*/, 0);
1.110 paf 378:
379: // http://localhost/abc -> $ENV{DOCUMENT_ROOT}/abc | ./abc
380: xmlRegisterInputCallbacks(
381: xmlFileMatchLocalhost, xmlFileOpenLocalhost,
1.150 paf 382: pa_xmlFileRead, pa_xmlFileClose);
1.76 parser 383: #endif
1.1 paf 384: }
1.76 parser 385:
1.152.2.19.2. 0(paf 386:3): #ifdef _MSC_VER
387:3):
388:3): #ifndef PA_DEBUG_DISABLE_GC
389:3): # define GC_LIB "/parser3project/win32/gc"
390:3): # ifdef _DEBUG
391:3): # pragma comment(lib, GC_LIB "/Debug/gc.lib")
392:3): # else
393:3): # pragma comment(lib, GC_LIB "/Release/gc.lib")
394:3): # endif
395:3):
396:3): #endif
397:3):
398:3): #ifdef XML
1.132 paf 399: # define GNOME_LIBS "/parser3project/win32xml/win32/gnome"
1.131 paf 400: # pragma comment(lib, GNOME_LIBS "/glib/lib/libglib-1.3-11.lib")
1.76 parser 401: # ifdef _DEBUG
1.152.2.19.2. 0(paf 402:3):
403:3): # ifdef LIBXML_STATIC
8(paf 404:3): # pragma comment(lib, GNOME_LIBS "/gnome-xml/win32/binaries/libxml2_a.lib")
0(paf 405:3): # else
8(paf 406:3): # pragma comment(lib, GNOME_LIBS "/gnome-xml/win32/binaries/libxml2.lib")
0(paf 407:3): # endif
408:3):
409:3): # ifdef LIBXSLT_STATIC
410:3): # pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/dsp/libxslt_DebugStatic/libxslt.lib")
411:3): # else
412:3): # pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/dsp/libxslt_DebugDynamic/libxslt.lib")
413:3): # endif
414:3): # ifdef LIBEXSLT_STATIC
415:3): # pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/dsp/libexslt_DebugStatic/libexslt.lib")
416:3): # else
417:3): # pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/dsp/libexslt_DebugDynamic/libexslt.lib")
418:3): # endif
419:3):
420:3): # ifdef LIBGDOME_STATIC
421:3): # pragma comment(lib, GNOME_LIBS "/gdome2-x.x.x/win32/dsp/libgdome_DebugStatic/libgdome.lib")
422:3): # else
423:3): # pragma comment(lib, GNOME_LIBS "/gdome2-x.x.x/win32/dsp/libgdome_DebugDynamic/libgdome.lib")
424:3): # endif
425:3):
426:3): #else
427:3):
428:3): # ifdef LIBXML_STATIC
429:3): # pragma comment(lib, GNOME_LIBS "/gnome-xml/win32/dsp/libxml2_ReleaseStatic/libxml2.lib")
430:3): # else
5(paf 431:3): # pragma comment(lib, GNOME_LIBS "/gnome-xml/win32/dsp/libxml2_ReleaseDynamic/libxml2.lib")
0(paf 432:3): # endif
433:3):
434:3): # ifdef LIBXSLT_STATIC
435:3): # pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/dsp/libxslt_ReleaseStatic/libxslt.lib")
436:3): # else
437:3): # pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/dsp/libxslt_ReleaseDynamic/libxslt.lib")
438:3): # endif
439:3): # ifdef LIBEXSLT_STATIC
440:3): # pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/dsp/libexslt_ReleaseStatic/libexslt.lib")
441:3): # else
442:3): # pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/dsp/libexslt_ReleaseDynamic/libexslt.lib")
443:3): # endif
444:3):
445:3): # ifdef LIBGDOME_STATIC
446:3): # pragma comment(lib, GNOME_LIBS "/gdome2-x.x.x/win32/dsp/libgdome_ReleaseStatic/libgdome.lib")
447:3): # else
448:3): # pragma comment(lib, GNOME_LIBS "/gdome2-x.x.x/win32/dsp/libgdome_ReleaseDynamic/libgdome.lib")
449:3): # endif
450:3):
1.85 paf 451: # endif
1.152.2.19.2. 0(paf 452:3): #endif
453:3):
1.85 paf 454: #endif
E-mail: