Annotation of parser3/src/main/pa_globals.C, revision 1.182
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.182 ! misha 8: static const char * const IDENT_GLOBALS_C="$Date: 2005/12/19 14:22:01 $";
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.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.162 paf 25: #include "pa_xml_io.h"
1.163 paf 26: #include "pa_common.h"
1.70 parser 27:
1.164 paf 28: #include "pa_cache_managers.h"
29:
1.182 ! misha 30: namespace PCRE {
! 31: #include "pcre.h"
! 32: };
! 33:
1.157 paf 34: // defines
1.155 paf 35:
1.157 paf 36: //#define PA_DEBUG_XML_GC_MEMORY
1.95 paf 37:
1.178 paf 38: //20051130 trying to remove this, author claims that fixed a lot there // 20040920 for now both workarounds needed. wait for new libxml/xsl versions
39: // // there is a problem with testcase, it's unstable.
40: // // see paf@six/bug20040920/cgi-bin/t for it-showed-bug-on-20040920-day
41: // #define PA_WORKAROUND_BUGGY_FREE_IN_LIBXML_GC_MEMORY
42: // #define PA_WORKAROUND_BUGGY_MALLOCATOMIC_IN_LIBXML_GC_MEMORY
1.175 paf 43:
1.157 paf 44: // globals
1.32 paf 45:
1.5 paf 46: short hex_value[0x100];
1.111 paf 47:
1.5 paf 48: static void setup_hex_value() {
1.68 parser 49: memset(hex_value, 0, sizeof(hex_value));
1.5 paf 50: hex_value['0'] = 0;
51: hex_value['1'] = 1;
52: hex_value['2'] = 2;
53: hex_value['3'] = 3;
54: hex_value['4'] = 4;
55: hex_value['5'] = 5;
56: hex_value['6'] = 6;
57: hex_value['7'] = 7;
58: hex_value['8'] = 8;
59: hex_value['9'] = 9;
60: hex_value['A'] = 10;
61: hex_value['B'] = 11;
62: hex_value['C'] = 12;
63: hex_value['D'] = 13;
64: hex_value['E'] = 14;
65: hex_value['F'] = 15;
66: hex_value['a'] = 10;
67: hex_value['b'] = 11;
68: hex_value['c'] = 12;
69: hex_value['d'] = 13;
70: hex_value['e'] = 14;
71: hex_value['f'] = 15;
72: }
1.1 paf 73:
1.162 paf 74:
75: Hash<pa_thread_t, Request*> thread_request;
76: void pa_register_thread_request(Request& r) {
77: thread_request.put(pa_get_thread_id(), &r);
78: }
79: /// retrives request set by pa_set_request function, useful in contextless places [slow]
80: Request& pa_thread_request() {
81: return *thread_request.get(pa_get_thread_id());
82: }
1.176 paf 83:
84: #ifdef PA_RELEASE_ASSERTS
85: void pa_release_assert(const char* str, const char* file, int line) {
86: SAPI::die("%s at %s:%d", str, file, line);
87: }
88: #endif
89:
1.162 paf 90:
1.99 paf 91: #ifdef XML
1.101 paf 92:
1.157 paf 93: class XML_Generic_error_info {
1.173 paf 94: public:/*internal, actually*/
1.166 paf 95: char buf[MAX_STRING*5];
1.157 paf 96: size_t used;
97: public:
98: XML_Generic_error_info() {
99: buf[used=0]=0;
100: }
1.173 paf 101: const char* get() {
102: return used? buf: 0;
1.157 paf 103: }
1.162 paf 104: };
1.101 paf 105:
1.172 paf 106: static Hash<pa_thread_t, XML_Generic_error_info*> xml_generic_error_infos;
1.101 paf 107:
1.162 paf 108: static void xmlParserGenericErrorFunc(void * /*ctx*/, const char* msg, ...) {
109: //_asm int 3;
1.157 paf 110: pa_thread_t thread_id=pa_get_thread_id();
1.101 paf 111:
1.172 paf 112: XML_Generic_error_info* p;
113: {
1.101 paf 114: SYNCHRONIZED; // find+fill blocked
115:
116: // first try to get existing for this thread_id
1.172 paf 117: p=xml_generic_error_infos.get(thread_id);
1.162 paf 118: if(!p) // occupy empty one
119: xml_generic_error_infos.put(thread_id, (p=new(PointerFreeGC) XML_Generic_error_info));
1.172 paf 120: }
1.101 paf 121:
1.172 paf 122: va_list args;
123: va_start(args, msg);
124: p->used+=vsnprintf(p->buf+p->used, sizeof(p->buf)-p->used, msg, args);
125: va_end(args);
1.101 paf 126: }
127:
1.102 paf 128: bool xmlHaveGenericErrors() {
1.157 paf 129: pa_thread_t thread_id=pa_get_thread_id();
1.102 paf 130:
131: SYNCHRONIZED; // find blocked
132:
1.162 paf 133: return xml_generic_error_infos.get(thread_id)!=0;
1.102 paf 134: }
135:
1.157 paf 136: const char* xmlGenericErrors() {
137: pa_thread_t thread_id=pa_get_thread_id();
1.101 paf 138:
139: SYNCHRONIZED; // find+free blocked
140:
1.173 paf 141: if(XML_Generic_error_info *p=xml_generic_error_infos.get(thread_id)) {
142: xml_generic_error_infos.remove(thread_id);
143: return p->get();
144: }
1.110 paf 145:
1.162 paf 146: return 0; // no errors for our thread_id registered
1.150 paf 147: }
148:
1.99 paf 149: #endif
150:
1.83 parser 151: void pa_globals_destroy(void *) {
1.180 paf 152: /*
1.83 parser 153: try {
1.96 paf 154: #ifdef XML
155: #endif
1.180 paf 156: } catch(.../*const Exception& e* /) {
1.160 paf 157: // SAPI::abort("pa_globals_destroy failed: %s", e.comment());
1.83 parser 158: }
1.180 paf 159: */
1.83 parser 160: }
161:
162:
1.157 paf 163: #ifdef XML
164:
165: static char *pa_GC_strdup(const char *s) {
166: if(!s)
167: return 0;
168:
169: size_t size=strlen(s)+1;
1.170 paf 170: char *result=(char *)GC_MALLOC_ATOMIC(size);
1.159 paf 171: if(!result)
172: SAPI::abort("out of memory (while duplicating XML string [size=%d])", size);
173:
1.157 paf 174: memcpy(result, s, size);
1.170 paf 175: #ifdef PA_DEBUG_XML_GC_MEMORY
176: fprintf(stderr, "pa_GC_strdup(%p=%s, length=%d)=0x%p\n", s, s, size, result);
177: #endif
1.157 paf 178: return result;
179: }
180:
181: #ifdef PA_DEBUG_XML_GC_MEMORY
1.175 paf 182: void *pa_look_for[]={(void*)0x84ba980,(void*)0x8969460,(void*)0x0,(void*)0x0,
1.157 paf 183: (void*)0x0,(void*)0x0,(void*)0x0,(void*)0x0};
184: bool pa_looked(void*p) {
185: for(int i=0; i<8; i++)
1.175 paf 186: if(pa_look_for[i]==p) {
187: __asm__("int $3");
1.157 paf 188: return true;
1.175 paf 189: }
190: if((((int)p)&~0xFF)==0x89a7700) {
191: __asm__("int $3");
192: return true;
193: }
1.157 paf 194: return false;
195: }
196: static void* pa_gc_malloc_log(size_t size){
197: void *p=pa_gc_malloc(size);
198: fprintf(stderr, "pa_gc_malloc_log(%d)=0x%p\n", size, p);
1.175 paf 199: if(pa_looked(p))
200: fprintf(stderr,"catched debug malloc(%d)=0x%p\n", size, p);
1.157 paf 201: return p;
202:
203: }
204: static void* pa_gc_malloc_atomic_log(size_t size){
1.175 paf 205: #ifdef PA_WORKAROUND_BUGGY_MALLOCATOMIC_IN_LIBXML_GC_MEMORY
206: void *p=pa_gc_malloc(size);
207: fprintf(stderr, "pa_gc_malloc_atomicFAKE_log(%d)=0x%p\n", size, p);
208: #else
1.157 paf 209: void *p=pa_gc_malloc_atomic(size);
210: fprintf(stderr, "pa_gc_malloc_atomic_log(%d)=0x%p\n", size, p);
1.175 paf 211: #endif
212: if(pa_looked(p))
213: fprintf(stderr,"catched debug malloc atomic(%d)=0x%p\n", size, p);
1.157 paf 214: return p;
215: }
216: static void* pa_gc_realloc_log(void *ptr, size_t size){
217: void *p=pa_gc_realloc(ptr, size);
218: fprintf(stderr, "pa_gc_realloc_log(0x%p, %d)=0x%p\n", ptr, size, p);
1.175 paf 219: if(pa_looked(p))
220: fprintf(stderr,"catched debug realloc(%d)=0x%p\n", size, p);
1.157 paf 221: return p;
222: }
223: static void pa_gc_free_log(void *p){
1.175 paf 224: #ifdef PA_WORKAROUND_BUGGY_FREE_IN_LIBXML_GC_MEMORY
225: fprintf(stderr, "pa_gc_freeIGNORE_log(0x%p)\n", p);
226: #else
1.157 paf 227: fprintf(stderr, "pa_gc_free_log(0x%p)\n", p);
1.175 paf 228: #endif
229: if(pa_looked(p))
230: fprintf(stderr,"catched debug free(0x%p)\n", p);
231: #ifndef PA_WORKAROUND_BUGGY_FREE_IN_LIBXML_GC_MEMORY
1.157 paf 232: pa_gc_free(p);
1.175 paf 233: #endif
1.157 paf 234: }
1.159 paf 235: #else
236:
237: inline void *check(void *result, const char *where, size_t size) {
238: if(!result)
239: SAPI::abort("out of memory (while %s [size=%d])", where, size);
240:
241: return result;
242: }
243: static void* pa_gc_malloc_nonull(size_t size) {
244: return check(pa_gc_malloc(size), "allocating XML compsite memory", size);
245: }
246: static void* pa_gc_malloc_atomic_nonull(size_t size) {
1.175 paf 247: #ifdef PA_WORKAROUND_BUGGY_MALLOCATOMIC_IN_LIBXML_GC_MEMORY
248: return check(pa_gc_malloc(size), "allocating XML composite memory (asked atomic)", size);
249: #else
1.159 paf 250: return check(pa_gc_malloc_atomic(size), "allocating XML atomic memory", size);
1.175 paf 251: #endif
1.159 paf 252: }
253: static void* pa_gc_realloc_nonull(void* ptr, size_t size) {
254: return check(pa_gc_realloc(ptr, size), "reallocating XML memory", size);
255: }
256:
1.175 paf 257: static void pa_gc_free_maybeignore(
258: void*
259: #ifndef PA_WORKAROUND_BUGGY_FREE_IN_LIBXML_GC_MEMORY
260: ptr
261: #endif
262: ) {
263: #ifndef PA_WORKAROUND_BUGGY_FREE_IN_LIBXML_GC_MEMORY
264: pa_gc_free(ptr);
265: #endif
266: }
267:
1.157 paf 268: #endif
269: #endif
270:
271: void pa_CORD_oom_fn(void) {
272: SAPI::abort("out of memory (while expanding string)");
273: }
274:
275: /**
276: @todo gc: libltdl: substitute lt_dlmalloc & co
277: */
278: static void gc_substitute_memory_management_functions() {
279: // in libxml & libxslt
280: #ifdef XML
281: // asking to use GC memory
282: #if LIBXML_VERSION >= 20507
283: #ifdef PA_DEBUG_XML_GC_MEMORY
284: xmlGcMemSetup(
285: /*xmlFreeFunc */pa_gc_free_log,
286: /*xmlMallocFunc */pa_gc_malloc_log,
287: /*xmlMallocFunc */pa_gc_malloc_atomic_log,
288: /*xmlReallocFunc */pa_gc_realloc_log,
289: /*xmlStrdupFunc */pa_GC_strdup);
290: #else
291: xmlGcMemSetup(
1.175 paf 292: /*xmlFreeFunc */pa_gc_free_maybeignore,
1.159 paf 293: /*xmlMallocFunc */pa_gc_malloc_nonull,
294: /*xmlMallocFunc */pa_gc_malloc_atomic_nonull,
295: /*xmlReallocFunc */pa_gc_realloc_nonull,
1.157 paf 296: /*xmlStrdupFunc */pa_GC_strdup);
297: #endif
1.32 paf 298:
1.157 paf 299: #else
300: xmlMemSetup(
1.175 paf 301: /*xmlFreeFunc */pa_gc_free_maybeignore,
1.157 paf 302: /*xmlMallocFunc */pa_gc_malloc,
303: /*xmlReallocFunc */pa_gc_realloc,
304: /*xmlStrdupFunc */pa_GC_strdup);
305: #endif
1.5 paf 306:
1.157 paf 307: #endif
1.141 paf 308:
1.157 paf 309: // pcre
1.182 ! misha 310: PCRE::pcre_malloc=pa_gc_malloc;
! 311: PCRE::pcre_free=pa_gc_free;
1.135 paf 312:
1.1 paf 313:
1.157 paf 314: // cord
315: CORD_oom_fn=pa_CORD_oom_fn;
316: }
1.88 paf 317:
1.157 paf 318: /**
319: @test hint on one should call this for each thread xmlSubstituteEntitiesDefault(1);
320: */
321: void pa_globals_init() {
1.164 paf 322: // global variables
323: cache_managers=new Cache_managers;
324:
325:
1.157 paf 326: // in various libraries
327: gc_substitute_memory_management_functions();
1.101 paf 328:
1.157 paf 329: // hex value
330: setup_hex_value();
1.74 parser 331:
1.76 parser 332: #ifdef XML
1.96 paf 333: // initializing xml libs
334:
1.157 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.157 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:
1.162 paf 379: pa_xml_io_init();
1.157 paf 380: #endif
1.174 paf 381: }
382:
383: void pa_globals_done() {
384: delete cache_managers; cache_managers=0;
1.157 paf 385: }
386:
387: #ifdef _MSC_VER
388:
389: #ifndef PA_DEBUG_DISABLE_GC
390: # define GC_LIB "../../../../win32/gc"
391: # ifdef _DEBUG
392: # pragma comment(lib, GC_LIB "/Debug/gc.lib")
393: # else
394: # pragma comment(lib, GC_LIB "/Release/gc.lib")
395: # endif
1.96 paf 396:
1.76 parser 397: #endif
398:
1.181 paf 399: #define GNOME_LIBS "../../../../win32/gnome"
400:
401: #ifdef WITH_MAILRECEIVE
402: # pragma comment(lib, GNOME_LIBS "/glib/lib/libglib-1.3-11.lib")
403: #endif
404:
1.157 paf 405: #ifdef XML
1.76 parser 406: # ifdef _DEBUG
1.157 paf 407:
408: # ifdef LIBXML_STATIC
1.168 paf 409: # pragma comment(lib, GNOME_LIBS "/libxml2-x.x.x/win32/debug/lib/libxml2_a.lib")
1.157 paf 410: # else
1.168 paf 411: # pragma comment(lib, GNOME_LIBS "/libxml2-x.x.x/win32/debug/lib/libxml2.lib")
1.157 paf 412: # endif
413:
414: # ifdef LIBXSLT_STATIC
1.168 paf 415: # pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/debug/lib/libxslt_a.lib")
1.157 paf 416: # else
1.168 paf 417: # pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/debug/lib/libxslt.lib")
1.157 paf 418: # endif
419: # ifdef LIBEXSLT_STATIC
1.168 paf 420: # pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/debug/lib/libexslt_a.lib")
1.157 paf 421: # else
1.168 paf 422: # pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/debug/lib/libexslt.lib")
1.157 paf 423: # endif
424:
425: #else
426:
427: # ifdef LIBXML_STATIC
1.168 paf 428: # pragma comment(lib, GNOME_LIBS "/libxml2-x.x.x/win32/release/lib/libxml2_a.lib")
1.157 paf 429: # else
1.168 paf 430: # pragma comment(lib, GNOME_LIBS "/libxml2-x.x.x/win32/release/lib/libxml2.lib")
1.157 paf 431: # endif
432:
433: # ifdef LIBXSLT_STATIC
1.168 paf 434: # pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/release/lib/libxslt_a.lib")
1.157 paf 435: # else
1.168 paf 436: # pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/release/lib/libxslt.lib")
1.157 paf 437: # endif
438: # ifdef LIBEXSLT_STATIC
1.168 paf 439: # pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/release/lib/libexslt_a.lib")
1.157 paf 440: # else
1.168 paf 441: # pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/release/lib/libexslt.lib")
1.157 paf 442: # endif
443:
1.85 paf 444: # endif
1.157 paf 445: #endif
446:
1.85 paf 447: #endif
E-mail: