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