Annotation of parser3/src/main/pa_globals.C, revision 1.179
1.15 paf 1: /** @file
1.16 paf 2: Parser: globals.
3:
1.177 paf 4: Copyright (c) 2001-2005 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.179 ! paf 8: static const char * const IDENT_GLOBALS_C="$Date: 2005/12/08 10:02:45 $";
1.1 paf 9:
1.102 paf 10: #include "pa_config_includes.h"
11:
12: #ifdef XML
1.157 paf 13: #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.157 paf 21: #include "pcre.h"
22:
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.162 paf 27: #include "pa_xml_io.h"
1.163 paf 28: #include "pa_common.h"
1.70 parser 29:
1.164 paf 30: #include "pa_cache_managers.h"
31:
1.157 paf 32: // defines
1.155 paf 33:
1.157 paf 34: //#define PA_DEBUG_XML_GC_MEMORY
1.95 paf 35:
1.178 paf 36: //20051130 trying to remove this, author claims that fixed a lot there // 20040920 for now both workarounds needed. wait for new libxml/xsl versions
37: // // there is a problem with testcase, it's unstable.
38: // // see paf@six/bug20040920/cgi-bin/t for it-showed-bug-on-20040920-day
39: // #define PA_WORKAROUND_BUGGY_FREE_IN_LIBXML_GC_MEMORY
40: // #define PA_WORKAROUND_BUGGY_MALLOCATOMIC_IN_LIBXML_GC_MEMORY
1.175 paf 41:
1.157 paf 42: // globals
1.32 paf 43:
1.5 paf 44: short hex_value[0x100];
1.111 paf 45:
46: #ifdef XML
47: GdomeDOMImplementation *domimpl;
48: #endif
1.5 paf 49:
50: static void setup_hex_value() {
1.68 parser 51: memset(hex_value, 0, sizeof(hex_value));
1.5 paf 52: hex_value['0'] = 0;
53: hex_value['1'] = 1;
54: hex_value['2'] = 2;
55: hex_value['3'] = 3;
56: hex_value['4'] = 4;
57: hex_value['5'] = 5;
58: hex_value['6'] = 6;
59: hex_value['7'] = 7;
60: hex_value['8'] = 8;
61: hex_value['9'] = 9;
62: hex_value['A'] = 10;
63: hex_value['B'] = 11;
64: hex_value['C'] = 12;
65: hex_value['D'] = 13;
66: hex_value['E'] = 14;
67: hex_value['F'] = 15;
68: hex_value['a'] = 10;
69: hex_value['b'] = 11;
70: hex_value['c'] = 12;
71: hex_value['d'] = 13;
72: hex_value['e'] = 14;
73: hex_value['f'] = 15;
74: }
1.1 paf 75:
1.162 paf 76:
77: Hash<pa_thread_t, Request*> thread_request;
78: void pa_register_thread_request(Request& r) {
79: thread_request.put(pa_get_thread_id(), &r);
80: }
81: /// retrives request set by pa_set_request function, useful in contextless places [slow]
82: Request& pa_thread_request() {
83: return *thread_request.get(pa_get_thread_id());
84: }
1.176 paf 85:
86: #ifdef PA_RELEASE_ASSERTS
87: void pa_release_assert(const char* str, const char* file, int line) {
88: SAPI::die("%s at %s:%d", str, file, line);
89: }
90: #endif
91:
1.162 paf 92:
1.99 paf 93: #ifdef XML
1.101 paf 94:
1.157 paf 95: class XML_Generic_error_info {
1.173 paf 96: public:/*internal, actually*/
1.166 paf 97: char buf[MAX_STRING*5];
1.157 paf 98: size_t used;
99: public:
100: XML_Generic_error_info() {
101: buf[used=0]=0;
102: }
1.173 paf 103: const char* get() {
104: return used? buf: 0;
1.157 paf 105: }
1.162 paf 106: };
1.101 paf 107:
1.172 paf 108: static Hash<pa_thread_t, XML_Generic_error_info*> xml_generic_error_infos;
1.101 paf 109:
1.162 paf 110: static void xmlParserGenericErrorFunc(void * /*ctx*/, const char* msg, ...) {
111: //_asm int 3;
1.157 paf 112: pa_thread_t thread_id=pa_get_thread_id();
1.101 paf 113:
1.172 paf 114: XML_Generic_error_info* p;
115: {
1.101 paf 116: SYNCHRONIZED; // find+fill blocked
117:
118: // first try to get existing for this thread_id
1.172 paf 119: p=xml_generic_error_infos.get(thread_id);
1.162 paf 120: if(!p) // occupy empty one
121: xml_generic_error_infos.put(thread_id, (p=new(PointerFreeGC) XML_Generic_error_info));
1.172 paf 122: }
1.101 paf 123:
1.172 paf 124: va_list args;
125: va_start(args, msg);
126: p->used+=vsnprintf(p->buf+p->used, sizeof(p->buf)-p->used, msg, args);
127: va_end(args);
1.101 paf 128: }
129:
1.102 paf 130: bool xmlHaveGenericErrors() {
1.157 paf 131: pa_thread_t thread_id=pa_get_thread_id();
1.102 paf 132:
133: SYNCHRONIZED; // find blocked
134:
1.162 paf 135: return xml_generic_error_infos.get(thread_id)!=0;
1.102 paf 136: }
137:
1.157 paf 138: const char* xmlGenericErrors() {
139: pa_thread_t thread_id=pa_get_thread_id();
1.101 paf 140:
141: SYNCHRONIZED; // find+free blocked
142:
1.173 paf 143: if(XML_Generic_error_info *p=xml_generic_error_infos.get(thread_id)) {
144: xml_generic_error_infos.remove(thread_id);
145: return p->get();
146: }
1.110 paf 147:
1.162 paf 148: return 0; // no errors for our thread_id registered
1.150 paf 149: }
150:
1.99 paf 151: #endif
152:
1.83 parser 153: void pa_globals_destroy(void *) {
154: try {
1.96 paf 155: #ifdef XML
156: GdomeException exc;
157: gdome_di_unref (domimpl, &exc);
1.160 paf 158: // uncomment SAPI::abort below if adding potential-throw code here
1.96 paf 159: #endif
1.179 ! paf 160: } catch(.../*const Exception& e*/) {
1.160 paf 161: // SAPI::abort("pa_globals_destroy failed: %s", e.comment());
1.83 parser 162: }
163: }
164:
165:
1.157 paf 166: #ifdef XML
167:
168: static char *pa_GC_strdup(const char *s) {
169: if(!s)
170: return 0;
171:
172: size_t size=strlen(s)+1;
1.170 paf 173: char *result=(char *)GC_MALLOC_ATOMIC(size);
1.159 paf 174: if(!result)
175: SAPI::abort("out of memory (while duplicating XML string [size=%d])", size);
176:
1.157 paf 177: memcpy(result, s, size);
1.170 paf 178: #ifdef PA_DEBUG_XML_GC_MEMORY
179: fprintf(stderr, "pa_GC_strdup(%p=%s, length=%d)=0x%p\n", s, s, size, result);
180: #endif
1.157 paf 181: return result;
182: }
183:
184: #ifdef PA_DEBUG_XML_GC_MEMORY
1.175 paf 185: void *pa_look_for[]={(void*)0x84ba980,(void*)0x8969460,(void*)0x0,(void*)0x0,
1.157 paf 186: (void*)0x0,(void*)0x0,(void*)0x0,(void*)0x0};
187: bool pa_looked(void*p) {
188: for(int i=0; i<8; i++)
1.175 paf 189: if(pa_look_for[i]==p) {
190: __asm__("int $3");
1.157 paf 191: return true;
1.175 paf 192: }
193: if((((int)p)&~0xFF)==0x89a7700) {
194: __asm__("int $3");
195: return true;
196: }
1.157 paf 197: return false;
198: }
199: static void* pa_gc_malloc_log(size_t size){
200: void *p=pa_gc_malloc(size);
201: fprintf(stderr, "pa_gc_malloc_log(%d)=0x%p\n", size, p);
1.175 paf 202: if(pa_looked(p))
203: fprintf(stderr,"catched debug malloc(%d)=0x%p\n", size, p);
1.157 paf 204: return p;
205:
206: }
207: static void* pa_gc_malloc_atomic_log(size_t size){
1.175 paf 208: #ifdef PA_WORKAROUND_BUGGY_MALLOCATOMIC_IN_LIBXML_GC_MEMORY
209: void *p=pa_gc_malloc(size);
210: fprintf(stderr, "pa_gc_malloc_atomicFAKE_log(%d)=0x%p\n", size, p);
211: #else
1.157 paf 212: void *p=pa_gc_malloc_atomic(size);
213: fprintf(stderr, "pa_gc_malloc_atomic_log(%d)=0x%p\n", size, p);
1.175 paf 214: #endif
215: if(pa_looked(p))
216: fprintf(stderr,"catched debug malloc atomic(%d)=0x%p\n", size, p);
1.157 paf 217: return p;
218: }
219: static void* pa_gc_realloc_log(void *ptr, size_t size){
220: void *p=pa_gc_realloc(ptr, size);
221: fprintf(stderr, "pa_gc_realloc_log(0x%p, %d)=0x%p\n", ptr, size, p);
1.175 paf 222: if(pa_looked(p))
223: fprintf(stderr,"catched debug realloc(%d)=0x%p\n", size, p);
1.157 paf 224: return p;
225: }
226: static void pa_gc_free_log(void *p){
1.175 paf 227: #ifdef PA_WORKAROUND_BUGGY_FREE_IN_LIBXML_GC_MEMORY
228: fprintf(stderr, "pa_gc_freeIGNORE_log(0x%p)\n", p);
229: #else
1.157 paf 230: fprintf(stderr, "pa_gc_free_log(0x%p)\n", p);
1.175 paf 231: #endif
232: if(pa_looked(p))
233: fprintf(stderr,"catched debug free(0x%p)\n", p);
234: #ifndef PA_WORKAROUND_BUGGY_FREE_IN_LIBXML_GC_MEMORY
1.157 paf 235: pa_gc_free(p);
1.175 paf 236: #endif
1.157 paf 237: }
1.159 paf 238: #else
239:
240: inline void *check(void *result, const char *where, size_t size) {
241: if(!result)
242: SAPI::abort("out of memory (while %s [size=%d])", where, size);
243:
244: return result;
245: }
246: static void* pa_gc_malloc_nonull(size_t size) {
247: return check(pa_gc_malloc(size), "allocating XML compsite memory", size);
248: }
249: static void* pa_gc_malloc_atomic_nonull(size_t size) {
1.175 paf 250: #ifdef PA_WORKAROUND_BUGGY_MALLOCATOMIC_IN_LIBXML_GC_MEMORY
251: return check(pa_gc_malloc(size), "allocating XML composite memory (asked atomic)", size);
252: #else
1.159 paf 253: return check(pa_gc_malloc_atomic(size), "allocating XML atomic memory", size);
1.175 paf 254: #endif
1.159 paf 255: }
256: static void* pa_gc_realloc_nonull(void* ptr, size_t size) {
257: return check(pa_gc_realloc(ptr, size), "reallocating XML memory", size);
258: }
259:
1.175 paf 260: static void pa_gc_free_maybeignore(
261: void*
262: #ifndef PA_WORKAROUND_BUGGY_FREE_IN_LIBXML_GC_MEMORY
263: ptr
264: #endif
265: ) {
266: #ifndef PA_WORKAROUND_BUGGY_FREE_IN_LIBXML_GC_MEMORY
267: pa_gc_free(ptr);
268: #endif
269: }
270:
1.157 paf 271: #endif
272: #endif
273:
274: void pa_CORD_oom_fn(void) {
275: SAPI::abort("out of memory (while expanding string)");
276: }
277:
278: /**
279: @todo gc: libltdl: substitute lt_dlmalloc & co
280: */
281: static void gc_substitute_memory_management_functions() {
282: // in libxml & libxslt
283: #ifdef XML
284: // asking to use GC memory
285: #if LIBXML_VERSION >= 20507
286: #ifdef PA_DEBUG_XML_GC_MEMORY
287: xmlGcMemSetup(
288: /*xmlFreeFunc */pa_gc_free_log,
289: /*xmlMallocFunc */pa_gc_malloc_log,
290: /*xmlMallocFunc */pa_gc_malloc_atomic_log,
291: /*xmlReallocFunc */pa_gc_realloc_log,
292: /*xmlStrdupFunc */pa_GC_strdup);
293: #else
294: xmlGcMemSetup(
1.175 paf 295: /*xmlFreeFunc */pa_gc_free_maybeignore,
1.159 paf 296: /*xmlMallocFunc */pa_gc_malloc_nonull,
297: /*xmlMallocFunc */pa_gc_malloc_atomic_nonull,
298: /*xmlReallocFunc */pa_gc_realloc_nonull,
1.157 paf 299: /*xmlStrdupFunc */pa_GC_strdup);
300: #endif
1.32 paf 301:
1.157 paf 302: #else
303: xmlMemSetup(
1.175 paf 304: /*xmlFreeFunc */pa_gc_free_maybeignore,
1.157 paf 305: /*xmlMallocFunc */pa_gc_malloc,
306: /*xmlReallocFunc */pa_gc_realloc,
307: /*xmlStrdupFunc */pa_GC_strdup);
308: #endif
1.5 paf 309:
1.157 paf 310: #endif
1.141 paf 311:
1.157 paf 312: // pcre
313: pcre_malloc=pa_gc_malloc;
314: pcre_free=pa_gc_free;
1.135 paf 315:
1.1 paf 316:
1.157 paf 317: // cord
318: CORD_oom_fn=pa_CORD_oom_fn;
319: }
1.88 paf 320:
1.157 paf 321: /**
322: @test hint on one should call this for each thread xmlSubstituteEntitiesDefault(1);
323: */
324: void pa_globals_init() {
1.164 paf 325: // global variables
326: cache_managers=new Cache_managers;
327:
328:
1.157 paf 329: // in various libraries
330: gc_substitute_memory_management_functions();
1.101 paf 331:
1.157 paf 332: // hex value
333: setup_hex_value();
1.74 parser 334:
1.76 parser 335: #ifdef XML
1.96 paf 336: // initializing xml libs
337:
1.157 paf 338: /* First get a DOMImplementation reference */
1.96 paf 339: domimpl = gdome_di_mkref ();
1.157 paf 340: /*
341: * Register the EXSLT extensions and the test module
342: */
343: exsltRegisterAll();
344: xsltRegisterTestModule();
345: xmlDefaultSAXHandlerInit();
346: /*
347: * disable CDATA from being built in the document tree
348: */
349: // never added yet xmlDefaultSAXHandler.cdataBlock = NULL;
350:
1.99 paf 351: /*
352: * Initialization function for the XML parser.
353: * This is not reentrant. Call once before processing in case of
354: * use in multithreaded programs.
355: */
356: xmlInitParser();
1.107 paf 357:
358: // 1. this is needed for proper parsing of stylesheets
359: // there were a situation where honest entity ruined innocent xpath compilation
360: // doc says "you sould turn it on on stylesheet load" without deepening into details
361: // 2. when dom tree with entites goes under transform text nodes
362: // got [erroreosly] cut on first entity occurance
1.109 paf 363: // --
1.107 paf 364: // that is why this is:
365: xmlSubstituteEntitiesDefault(1);
1.100 paf 366:
367: // Bit in the loadsubset context field to tell to do ID/REFs lookups
368: xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
369: // Bit in the loadsubset context field to tell to do complete the elements attributes lists
370: // with the ones defaulted from the DTDs
1.157 paf 371: xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;
1.138 paf 372:
373: // validate each document after load/create (?)
374: //xmlDoValidityCheckingDefaultValue = 1;
1.99 paf 375:
1.104 paf 376: //regretfully this not only replaces entities on parse, but also on generate xmlSubstituteEntitiesDefault(1);
1.105 paf 377: // never switched this on xmlIndentTreeOutput=1;
1.104 paf 378:
1.101 paf 379: xmlSetGenericErrorFunc(0, xmlParserGenericErrorFunc);
1.102 paf 380: xsltSetGenericErrorFunc(0, xmlParserGenericErrorFunc);
1.105 paf 381: // FILE *f=fopen("y:\\xslt.log", "wt");
382: // xsltSetGenericDebugFunc(f/*stderr*/, 0);
1.110 paf 383:
1.162 paf 384: pa_xml_io_init();
1.157 paf 385: #endif
1.174 paf 386: }
387:
388: void pa_globals_done() {
389: delete cache_managers; cache_managers=0;
1.157 paf 390: }
391:
392: #ifdef _MSC_VER
393:
394: #ifndef PA_DEBUG_DISABLE_GC
395: # define GC_LIB "../../../../win32/gc"
396: # ifdef _DEBUG
397: # pragma comment(lib, GC_LIB "/Debug/gc.lib")
398: # else
399: # pragma comment(lib, GC_LIB "/Release/gc.lib")
400: # endif
1.96 paf 401:
1.76 parser 402: #endif
403:
1.157 paf 404: #ifdef XML
1.158 paf 405: # define GNOME_LIBS "../../../../win32/gnome"
1.131 paf 406: # pragma comment(lib, GNOME_LIBS "/glib/lib/libglib-1.3-11.lib")
1.76 parser 407: # ifdef _DEBUG
1.157 paf 408:
409: # ifdef LIBXML_STATIC
1.168 paf 410: # pragma comment(lib, GNOME_LIBS "/libxml2-x.x.x/win32/debug/lib/libxml2_a.lib")
1.157 paf 411: # else
1.168 paf 412: # pragma comment(lib, GNOME_LIBS "/libxml2-x.x.x/win32/debug/lib/libxml2.lib")
1.157 paf 413: # endif
414:
415: # ifdef LIBXSLT_STATIC
1.168 paf 416: # pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/debug/lib/libxslt_a.lib")
1.157 paf 417: # else
1.168 paf 418: # pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/debug/lib/libxslt.lib")
1.157 paf 419: # endif
420: # ifdef LIBEXSLT_STATIC
1.168 paf 421: # pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/debug/lib/libexslt_a.lib")
1.157 paf 422: # else
1.168 paf 423: # pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/debug/lib/libexslt.lib")
1.157 paf 424: # endif
425:
426: # ifdef LIBGDOME_STATIC
1.169 paf 427: # pragma comment(lib, GNOME_LIBS "/gdome2-x.x.x/win32/DebugStatic/libgdome.lib")
1.157 paf 428: # else
1.169 paf 429: # pragma comment(lib, GNOME_LIBS "/gdome2-x.x.x/win32/DebugDynamic/libgdome.lib")
1.157 paf 430: # endif
431:
432: #else
433:
434: # ifdef LIBXML_STATIC
1.168 paf 435: # pragma comment(lib, GNOME_LIBS "/libxml2-x.x.x/win32/release/lib/libxml2_a.lib")
1.157 paf 436: # else
1.168 paf 437: # pragma comment(lib, GNOME_LIBS "/libxml2-x.x.x/win32/release/lib/libxml2.lib")
1.157 paf 438: # endif
439:
440: # ifdef LIBXSLT_STATIC
1.168 paf 441: # pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/release/lib/libxslt_a.lib")
1.157 paf 442: # else
1.168 paf 443: # pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/release/lib/libxslt.lib")
1.157 paf 444: # endif
445: # ifdef LIBEXSLT_STATIC
1.168 paf 446: # pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/release/lib/libexslt_a.lib")
1.157 paf 447: # else
1.168 paf 448: # pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/release/lib/libexslt.lib")
1.157 paf 449: # endif
450:
451: # ifdef LIBGDOME_STATIC
1.169 paf 452: # pragma comment(lib, GNOME_LIBS "/gdome2-x.x.x/win32/ReleaseStatic/libgdome.lib")
1.157 paf 453: # else
1.169 paf 454: # pragma comment(lib, GNOME_LIBS "/gdome2-x.x.x/win32/ReleaseDynamic/libgdome.lib")
1.157 paf 455: # endif
456:
1.85 paf 457: # endif
1.157 paf 458: #endif
459:
1.85 paf 460: #endif
E-mail: