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