File: pa_globals.C

package info (click to toggle)
parser 3.4.5-4
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 7,552 kB
  • sloc: cpp: 32,375; sh: 11,487; ansic: 10,849; yacc: 1,361; makefile: 248; awk: 5
file content (365 lines) | stat: -rw-r--r-- 8,508 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
/** @file
	Parser: globals.

	Copyright (c) 2001-2017 Art. Lebedev Studio (http://www.artlebedev.com)
	Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
*/

#include "pa_config_includes.h"

#ifdef XML
#include "libxml/xmlversion.h"
#include "libxslt/extensions.h"
#include "libxslt/xsltutils.h"
extern "C" {
#include "libexslt/exslt.h"
}
#endif

#include "pa_globals.h"
#include "pa_sapi.h"
#include "pa_threads.h"
#include "pa_xml_io.h"
#include "pa_common.h"
#include "pa_symbols.h"

#include "pa_cache_managers.h"

#include "ltdl.h"
#include "pcre.h"

volatile const char * IDENT_PA_GLOBALS_C="$Id: pa_globals.C,v 1.198 2017/02/07 22:00:43 moko Exp $" IDENT_PA_GLOBALS_H IDENT_PA_SAPI_H;

// defines

//#define PA_DEBUG_XML_GC_MEMORY

// globals

short hex_value[0x100]={0};

static void setup_hex_value() {
	hex_value['0'] = 0;
	hex_value['1'] = 1;
	hex_value['2'] = 2;
	hex_value['3'] = 3;
	hex_value['4'] = 4;
	hex_value['5'] = 5;
	hex_value['6'] = 6;
	hex_value['7'] = 7;
	hex_value['8'] = 8;
	hex_value['9'] = 9;
	hex_value['A'] = 10;
	hex_value['B'] = 11;
	hex_value['C'] = 12;
	hex_value['D'] = 13;
	hex_value['E'] = 14;
	hex_value['F'] = 15;
	hex_value['a'] = 10;
	hex_value['b'] = 11;
	hex_value['c'] = 12;
	hex_value['d'] = 13;
	hex_value['e'] = 14;
	hex_value['f'] = 15;
}

THREAD_LOCAL Request* thread_request=NULL;

void pa_register_thread_request(Request& r) {
	thread_request=&r;
}
/// retrives request set by pa_set_request function, useful in contextless places [slow]
Request& pa_thread_request() {
	return *thread_request;
}


#ifdef XML

class XML_Generic_error_info {
public:/*internal, actually*/
	char buf[MAX_STRING*5];
	size_t used;
public:
	XML_Generic_error_info() {
		buf[used=0]=0;
	}
	const char* get() {
		return used? buf: 0;
	}
};

THREAD_LOCAL XML_Generic_error_info* xml_generic_error_info = NULL;

static void xmlParserGenericErrorFunc(void *  /*ctx*/, const char* msg, ...) { 
	XML_Generic_error_info* p;
	
	if(!(p=xml_generic_error_info)) // occupy empty one
		p=xml_generic_error_info=new(PointerFreeGC) XML_Generic_error_info;
		
	va_list args;
	va_start(args, msg);
	p->used+=vsnprintf(p->buf+p->used, sizeof(p->buf)-p->used, msg, args);
	va_end(args);
}

bool xmlHaveGenericErrors() {
	return xml_generic_error_info!=0;
}

const char* xmlGenericErrors() {
	if(XML_Generic_error_info *p=xml_generic_error_info) {
		xml_generic_error_info=0;
		return p->get();
	}

	return 0; // no errors for our thread_id registered
}

#endif // XML

#ifdef XML

static char *pa_GC_strdup(const char *s) {
	if(!s)
		return 0;

	size_t size=strlen(s)+1;
	char *result=(char *)pa_gc_malloc_atomic(size);

	if(!result)
		pa_fail_alloc("duplicate XML string",size);

	memcpy(result, s, size);
#ifdef PA_DEBUG_XML_GC_MEMORY
	fprintf(stderr, "pa_GC_strdup(%p=%s, length=%d)=0x%p\n", s, s, size, result);
#endif
	return result;
}

#ifdef PA_DEBUG_XML_GC_MEMORY

static void* pa_gc_malloc_log(size_t size){
	void *p=pa_gc_malloc(size);
        fprintf(stderr, "pa_gc_malloc_log(%d)=0x%p\n", size, p);
	return p;
        
}

static void* pa_gc_malloc_atomic_log(size_t size){
	void *p=pa_gc_malloc_atomic(size);
        fprintf(stderr, "pa_gc_malloc_atomic_log(%d)=0x%p\n", size, p);
	return p;
}

static void* pa_gc_realloc_log(void *ptr, size_t size){
	void *p=pa_gc_realloc(ptr, size);
        fprintf(stderr, "pa_gc_realloc_log(0x%p, %d)=0x%p\n", ptr, size, p);
	return p;
}

static void pa_gc_free_log(void *p){
        fprintf(stderr, "pa_gc_free_log(0x%p)\n", p);
        pa_gc_free(p);
}

#else

inline void *check(void *result, const char *where, size_t size) {
	if(!result)
		pa_fail_alloc(where, size);
	return result;
}

static void* pa_gc_malloc_nonull(size_t size) { 
	return check(pa_gc_malloc(size), "allocate XML compsite memory", size);
}

static void* pa_gc_malloc_atomic_nonull(size_t size) { 
	return check(pa_gc_malloc_atomic(size), "allocate XML atomic memory", size);
}

static void* pa_gc_realloc_nonull(void* ptr, size_t size) { 
	return check(pa_gc_realloc(ptr, size), "reallocate XML memory", size);
}

static void pa_gc_free_maybeignore(void* ptr) {
	pa_gc_free(ptr);
}

#endif

#endif // XML

void pa_CORD_oom_fn(void) {
	pa_fail_alloc("expand string", 0);
}

/**
	@todo gc: libltdl: substitute lt_dlmalloc & co
*/
static void gc_substitute_memory_management_functions() {
	// in libxml & libxslt
#ifdef XML
	// asking to use GC memory
#ifdef PA_DEBUG_XML_GC_MEMORY
	xmlGcMemSetup(
		/*xmlFreeFunc */pa_gc_free_log,
		/*xmlMallocFunc */pa_gc_malloc_log,
		/*xmlMallocFunc */pa_gc_malloc_atomic_log,
		/*xmlReallocFunc */pa_gc_realloc_log,
		/*xmlStrdupFunc */pa_GC_strdup);
#else
	xmlGcMemSetup(
		/*xmlFreeFunc */pa_gc_free_maybeignore,
		/*xmlMallocFunc */pa_gc_malloc_nonull,
		/*xmlMallocFunc */pa_gc_malloc_atomic_nonull,
		/*xmlReallocFunc */pa_gc_realloc_nonull,
		/*xmlStrdupFunc */pa_GC_strdup);
#endif

#endif

	// pcre
	pcre_malloc=pa_gc_malloc;
	pcre_free=pa_gc_free;

	// cord
	CORD_oom_fn=pa_CORD_oom_fn;
}

/**
	@test hint on one should call this for each thread xmlSubstituteEntitiesDefault(1);
*/
void pa_globals_init() {
	// global variables 
	cache_managers=new Cache_managers;

	// in various libraries
	gc_substitute_memory_management_functions();

	// hex value
	setup_hex_value();

#ifdef SYMBOLS_CACHING
	// symbols cache
	Symbols::init();
#endif

#ifdef XML
	// initializing xml libs

	// Register the EXSLT extensions and the test module
	exsltRegisterAll();
	xsltRegisterTestModule();
	xmlDefaultSAXHandlerInit();

	// disable CDATA from being built in the document tree
	// never added yet  xmlDefaultSAXHandler.cdataBlock = NULL;
	
	// Initialization function for the XML parser. This is not reentrant. 
	// Call once before processing in case of use in multithreaded programs.
	xmlInitParser();

	// 1. this is needed for proper parsing of stylesheets
	// there were a situation where honest entity ruined innocent xpath compilation
	// doc says "you sould turn it on on stylesheet load" without deepening into details
	// 2. when dom tree with entites goes under transform text nodes 
	// got [erroreosly] cut on first entity occurance
	// --
	// that is why this is:
	xmlSubstituteEntitiesDefault(1);
	
	// Bit in the loadsubset context field to tell to do ID/REFs lookups 
	xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
	// Bit in the loadsubset context field to tell to do complete the elements attributes lists 
	// with the ones defaulted from the DTDs 
	xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;

	// validate each document after load/create (?)
	// xmlDoValidityCheckingDefaultValue = 1;

	// regretfully this not only replaces entities on parse, but also on generate	xmlSubstituteEntitiesDefault(1);
	// never switched this on xmlIndentTreeOutput=1;

	xmlSetGenericErrorFunc(0, xmlParserGenericErrorFunc);
	xsltSetGenericErrorFunc(0, xmlParserGenericErrorFunc);

//	FILE *f=fopen("xslt.log", "wt");
//	xsltSetGenericDebugFunc(f/*stderr*/, 0);

	pa_xml_io_init();
#endif
}

static bool is_dlinited=false;

void pa_globals_done() {
	delete cache_managers;
	cache_managers=0;

	if(is_dlinited)
		lt_dlexit();
}

void pa_dlinit() {
	if(!is_dlinited){
		if(lt_dlinit())
			throw Exception(0,0,"preparation for dynamic library loading failed, %s", lt_dlerror());
		is_dlinited=true;
	}
}

#ifdef _MSC_VER

#ifndef PA_DEBUG_DISABLE_GC

#define GC_LIB "../../../../win32/gc"
#ifdef _DEBUG
#pragma comment(lib, GC_LIB "/Debug/gc.lib")
#else
#pragma comment(lib, GC_LIB "/Release/gc.lib")
#endif

#endif // PA_DEBUG_DISABLE_GC


#ifdef XML

#define GNOME_LIBS "../../../../win32/gnome"

#ifdef _DEBUG
#define LIB_XML GNOME_LIBS "/libxml2-x.x.x/win32/debug/lib/"
#define LIB_XSLT GNOME_LIBS "/libxslt-x.x.x/win32/debug/lib/"
#else
#define LIB_XML GNOME_LIBS "/libxml2-x.x.x/win32/release/lib/"
#define LIB_XSLT GNOME_LIBS "/libxslt-x.x.x/win32/release/lib/"
#endif

#ifdef LIBXML_STATIC
#pragma comment(lib, LIB_XML "libxml2_a.lib")
#else
#pragma comment(lib, LIB_XML "libxml2.lib")
#endif

#ifdef LIBXSLT_STATIC
#pragma comment(lib, LIB_XSLT "libxslt_a.lib")
#else
#pragma comment(lib, LIB_XSLT "libxslt.lib")
#endif

#ifdef LIBEXSLT_STATIC
#pragma comment(lib, LIB_XSLT "libexslt_a.lib")
#else
#pragma comment(lib, LIB_XSLT "libexslt.lib")
#endif

#endif // XML

// defines for VS2015 to link with gc/xml libs compiled in the previous VS versions
#if _MSC_VER >= 1900
#pragma comment(lib,"legacy_stdio_definitions.lib")
extern "C" { FILE _iob[3] = { *stdin, *stdout, *stderr }; }
#endif

#endif // _MSC_VER