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