1 /* -*- Mode: c; c-basic-offset: 2 -*-
2 *
3 * raptor_general.c - Raptor general routines
4 *
5 * Copyright (C) 2000-2010, David Beckett http://www.dajobe.org/
6 * Copyright (C) 2000-2005, University of Bristol, UK http://www.bristol.ac.uk/
7 *
8 * This package is Free Software and part of Redland http://librdf.org/
9 *
10 * It is licensed under the following three licenses as alternatives:
11 * 1. GNU Lesser General Public License (LGPL) V2.1 or any newer version
12 * 2. GNU General Public License (GPL) V2 or any newer version
13 * 3. Apache License, V2.0 or any newer version
14 *
15 * You may not use this file except in compliance with at least one of
16 * the above three licenses.
17 *
18 * See LICENSE.html or LICENSE.txt at the top of this package for the
19 * complete terms and further detail along with the license texts for
20 * the licenses in COPYING.LIB, COPYING and LICENSE-2.0.txt respectively.
21 *
22 *
23 */
24
25
26 #ifdef HAVE_CONFIG_H
27 #include <raptor_config.h>
28 #endif
29
30 #ifdef WIN32
31 #include <win32_raptor_config.h>
32 #endif
33
34
35 #include <stdio.h>
36 #include <string.h>
37 #include <ctype.h>
38 #include <stdarg.h>
39 #ifdef HAVE_ERRNO_H
40 #include <errno.h>
41 #endif
42 #ifdef HAVE_STDLIB_H
43 #include <stdlib.h>
44 #endif
45
46 /* Raptor includes */
47 #include "raptor.h"
48 #include "raptor_internal.h"
49
50
51 /* statics */
52 #ifndef RAPTOR_DISABLE_V1
53 static raptor_world* Raptor_World=NULL;
54 #endif
55
56
57 const char * const raptor_short_copyright_string = "Copyright 2000-2010 David Beckett. Copyright 2000-2005 University of Bristol";
58
59 const char * const raptor_copyright_string = "Copyright (C) 2000-2010 David Beckett - http://www.dajobe.org/\nCopyright (C) 2000-2005 University of Bristol - http://www.bristol.ac.uk/";
60
61 const char * const raptor_license_string = "LGPL 2.1 or newer, GPL 2 or newer, Apache 2.0 or newer.\nSee http://librdf.org/raptor/LICENSE.html for full terms.";
62
63 const char * const raptor_home_url_string = "http://librdf.org/raptor/";
64
65 /**
66 * raptor_version_string:
67 *
68 * Library full version as a string.
69 *
70 * See also #raptor_version_decimal.
71 */
72 const char * const raptor_version_string = VERSION;
73
74 /**
75 * raptor_version_major:
76 *
77 * Library major version number as a decimal integer.
78 */
79 const unsigned int raptor_version_major = RAPTOR_VERSION_MAJOR;
80
81 /**
82 * raptor_version_minor:
83 *
84 * Library minor version number as a decimal integer.
85 */
86 const unsigned int raptor_version_minor = RAPTOR_VERSION_MINOR;
87
88 /**
89 * raptor_version_release:
90 *
91 * Library release version number as a decimal integer.
92 */
93 const unsigned int raptor_version_release = RAPTOR_VERSION_RELEASE;
94
95 /**
96 * raptor_version_decimal:
97 *
98 * Library full version as a decimal integer.
99 *
100 * See also #raptor_version_string.
101 */
102 const unsigned int raptor_version_decimal = RAPTOR_VERSION_DECIMAL;
103
104
105 /**
106 * raptor_new_world:
107 *
108 * Allocate a new raptor_world object.
109 *
110 * The raptor_world is initialized with raptor_world_open().
111 * Allocation and initialization are decoupled to allow
112 * changing settings on the world object before init.
113 *
114 * Return value: uninitialized raptor_world object or NULL on failure
115 */
116 raptor_world *
raptor_new_world(void)117 raptor_new_world(void)
118 {
119 raptor_world *world;
120
121 world = (raptor_world*)RAPTOR_CALLOC(raptor_world, sizeof(raptor_world), 1);
122 if(world) {
123 /* set default libxml flags - can be updated by
124 * raptor_world_set_libxml_flags() and raptor_set_libxml_flags()
125 */
126
127 /* unset: RAPTOR_LIBXML_FLAGS_GENERIC_ERROR_SAVE
128 * unset: RAPTOR_LIBXML_FLAGS_STRUCTURED_ERROR_SAVE
129 */
130 world->libxml_flags = 0;
131 }
132
133 return world;
134 }
135
136
137 /**
138 * raptor_world_open:
139 * @world: raptor_world object
140 *
141 * Initialise the raptor library.
142 *
143 * Initializes a #raptor_world object created by raptor_new_world().
144 * Allocation and initialization are decoupled to allow
145 * changing settings on the world object before init.
146 *
147 * The initialized world object is used with subsequent raptor API calls.
148 *
149 * Return value: non-0 on failure
150 */
151 int
raptor_world_open(raptor_world * world)152 raptor_world_open(raptor_world* world)
153 {
154 int rc;
155
156 if(!world)
157 return -1;
158
159 if(world->opened)
160 return 0; /* not an error */
161
162 rc = raptor_parsers_init(world);
163 if(rc)
164 return rc;
165
166 rc = raptor_serializers_init(world);
167 if(rc)
168 return rc;
169
170 rc = raptor_uri_init(world);
171 if(rc)
172 return rc;
173
174 rc = raptor_sax2_init(world);
175 if(rc)
176 return rc;
177
178 rc = raptor_www_init_v2(world);
179 if(rc)
180 return rc;
181
182 world->opened = 1;
183
184 return 0;
185 }
186
187
188 /**
189 * raptor_free_world:
190 * @world: raptor_world object
191 *
192 * Terminate the raptor library.
193 *
194 * Destroys the raptor_world object and all related information.
195 */
196 void
raptor_free_world(raptor_world * world)197 raptor_free_world(raptor_world* world)
198 {
199 RAPTOR_ASSERT_OBJECT_POINTER_RETURN(world, raptor_world);
200
201 raptor_www_finish_v2(world);
202
203 raptor_sax2_finish(world);
204
205 raptor_serializers_finish(world);
206
207 raptor_parsers_finish(world);
208
209 RAPTOR_FREE(raptor_world, world);
210 }
211
212
213 #ifndef RAPTOR_DISABLE_V1
214 /**
215 * raptor_init:
216 *
217 * Initialise the raptor library.
218 *
219 * This function MUST be called before using any of the raptor APIs.
220 **/
221 void
raptor_init(void)222 raptor_init(void)
223 {
224 if(Raptor_World) {
225 Raptor_World->static_usage++;
226 return;
227 }
228
229 Raptor_World=raptor_new_world();
230 if(!Raptor_World)
231 goto failure;
232 if(raptor_world_open(Raptor_World))
233 goto failure;
234 Raptor_World->static_usage=1;
235
236 return;
237
238 failure:
239 raptor_finish();
240 RAPTOR_FATAL1("raptor_init() failed");
241 }
242
243
244 /**
245 * raptor_finish:
246 *
247 * Terminate the raptor library.
248 *
249 * Cleans up state of the library. If called, must be used after
250 * all other objects are destroyed with their destructor.
251 **/
252 void
raptor_finish(void)253 raptor_finish(void)
254 {
255 if(!Raptor_World || --Raptor_World->static_usage)
256 return;
257
258 raptor_free_world(Raptor_World);
259 Raptor_World=NULL;
260 }
261
262
263 /*
264 * raptor_world_instance:
265 * Accessor for static raptor_world object.
266 *
267 * INTERNAL
268 *
269 * Return value: raptor_world object or NULL if not initialized
270 */
271 raptor_world*
raptor_world_instance(void)272 raptor_world_instance(void)
273 {
274 return Raptor_World;
275 }
276 #endif
277
278
279 /**
280 * raptor_world_set_libxslt_security_preferences:
281 * @world: world
282 * @security_preferences: security preferences (an #xsltSecurityPrefsPtr)
283 *
284 * Set libxslt security preferences policy object
285 *
286 * The @security_preferences object will NOT become owned by
287 * #raptor_world
288 *
289 * If libxslt is compiled into the library, @security_preferences
290 * should be an #xsltSecurityPrefsPtr and will be used to call
291 * xsltSetCtxtSecurityPrefs() when an XSLT engine is initialised.
292 *
293 * If libxslt is not compiled in, the object set here is not used.
294 */
295 void
raptor_world_set_libxslt_security_preferences(raptor_world * world,void * security_preferences)296 raptor_world_set_libxslt_security_preferences(raptor_world *world,
297 void *security_preferences)
298 {
299 RAPTOR_ASSERT_OBJECT_POINTER_RETURN(world, raptor_world);
300
301 world->xslt_security_preferences = security_preferences;
302 }
303
304
305 #ifndef RAPTOR_DISABLE_V1
306 /**
307 * raptor_set_libxslt_security_preferences:
308 * @security_preferences: security preferences (an #xsltSecurityPrefsPtr)
309 *
310 * Set libxslt security preferences policy object
311 *
312 * The @security_preferences object will NOT become owned by Raptor
313 *
314 * If libxslt is compiled into the library, @security_preferences
315 * should be an #xsltSecurityPrefsPtr and will be used to call
316 * xsltSetCtxtSecurityPrefs() when an XSLT engine is initialised.
317 *
318 * If libxslt is not compiled in, the object set here is not used.
319 */
320 void
raptor_set_libxslt_security_preferences(void * security_preferences)321 raptor_set_libxslt_security_preferences(void *security_preferences)
322 {
323 raptor_world* world = raptor_world_instance();
324 if(world)
325 raptor_world_set_libxslt_security_preferences(world, security_preferences);
326 }
327 #endif
328
329
330 /**
331 * raptor_world_set_libxml_flags:
332 * @world: world
333 * @flags: libxml flags
334 *
335 * Set common libxml library flags
336 *
337 * If libxml is compiled into the library, @flags is a bitmask
338 * taking an OR of values defined in #raptor_libxml_flags
339 *
340 * See the #raptor_libxml_flags documentation for full details of
341 * what the flags mean.
342 *
343 */
344 void
raptor_world_set_libxml_flags(raptor_world * world,int flags)345 raptor_world_set_libxml_flags(raptor_world *world, int flags)
346 {
347 RAPTOR_ASSERT_OBJECT_POINTER_RETURN(world, raptor_world);
348
349 world->libxml_flags = flags;
350 }
351
352
353 #ifndef RAPTOR_DISABLE_V1
354 /**
355 * raptor_set_libxml_flags:
356 * @flags: flags
357 *
358 * Set common libxml library flags
359 *
360 * If libxml is compiled into the library, @flags is a bitmask
361 * taking an OR of values defined in #raptor_libxml_flags
362 *
363 * See the #raptor_libxml_flags documentation for full details of
364 * what the flags mean.
365 *
366 */
367 void
raptor_set_libxml_flags(int flags)368 raptor_set_libxml_flags(int flags)
369 {
370 raptor_world* world = raptor_world_instance();
371 if(world)
372 raptor_world_set_libxml_flags(world, flags);
373 }
374 #endif
375
376
377 /*
378 * Thanks to the patch in this Debian bug for the solution
379 * to the crash inside vsnprintf on some architectures.
380 *
381 * "reuse of args inside the while(1) loop is in violation of the
382 * specs and only happens to work by accident on other systems."
383 *
384 * http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=104325
385 */
386
387 #ifndef va_copy
388 #ifdef __va_copy
389 #define va_copy(dest,src) __va_copy(dest,src)
390 #else
391 #define va_copy(dest,src) (dest) = (src)
392 #endif
393 #endif
394
395
396 #ifdef CHECK_VSNPRINTF_RUNTIME
397 static int vsnprintf_checked = -1;
398
399 static int
vsnprint_check_is_c99(const char * s,...)400 vsnprint_check_is_c99(const char *s, ...)
401 {
402 char buffer[32];
403 va_list args;
404 int r;
405 va_start(args, s);
406 r = vsnprintf(buffer, 5, s, args);
407 va_end(args);
408
409 return (r == 7);
410 }
411
412 static int
vsnprintf_is_c99(void)413 vsnprintf_is_c99(void)
414 {
415 if(vsnprintf_checked < 0)
416 vsnprintf_checked = vsnprint_check_is_c99("1234567");
417 return vsnprintf_checked;
418 }
419 #endif
420
421
422 #define VSNPRINTF_C99_BLOCK \
423 do { \
424 /* copy for re-use */ \
425 va_copy(args_copy, arguments); \
426 len = vsnprintf(empty_buffer, 1, message, args_copy)+1; \
427 va_end(args_copy); \
428 \
429 if(len <= 0) \
430 return NULL; \
431 \
432 buffer = (char*)RAPTOR_MALLOC(cstring, len); \
433 if(buffer) { \
434 /* copy for re-use */ \
435 va_copy(args_copy, arguments); \
436 vsnprintf(buffer, len, message, args_copy); \
437 va_end(args_copy); \
438 } \
439 } while(0)
440
441 #define VSNPRINTF_NOT_C99_BLOCK \
442 do { \
443 /* This vsnprintf doesn't return number of bytes required */ \
444 int size = 2; \
445 \
446 while(1) { \
447 buffer = (char*)RAPTOR_MALLOC(cstring, size+1); \
448 if(!buffer) \
449 break; \
450 \
451 /* copy for re-use */ \
452 va_copy(args_copy, arguments); \
453 len = vsnprintf(buffer, size, message, args_copy); \
454 va_end(args_copy); \
455 \
456 /* On windows, vsnprintf() returns -1 if the buffer does not fit. \
457 * If the buffer exactly fits the string without a NULL \
458 * terminator, it returns the string length and it ends up with \
459 * an unterminated string. The added check makes sure the string \
460 * returned is terminated - otherwise more buffer space is \
461 * allocated and the while() loop retries. \
462 */ \
463 if((len >= 0) && (buffer[len] == '\0')) \
464 break; \
465 RAPTOR_FREE(cstring, buffer); \
466 size += 4; \
467 } \
468 } while(0)
469
470
471 /**
472 * raptor_vsnprintf:
473 * @message: printf-style format string
474 * @arguments: variable arguments list
475 *
476 * Format output for a variable arguments list.
477 *
478 * This is a wrapper around system versions of vsnprintf with
479 * different call and return conventions.
480 *
481 * Return value: a newly allocated string as the format result or NULL on failure
482 **/
483 char*
raptor_vsnprintf(const char * message,va_list arguments)484 raptor_vsnprintf(const char *message, va_list arguments)
485 {
486 char empty_buffer[1];
487 int len;
488 char *buffer = NULL;
489 va_list args_copy;
490
491 #ifdef CHECK_VSNPRINTF_RUNTIME
492 if(vsnprintf_is_c99())
493 VSNPRINTF_C99_BLOCK ;
494 else
495 VSNPRINTF_NOT_C99_BLOCK ;
496 #else
497 #ifdef HAVE_C99_VSNPRINTF
498 VSNPRINTF_C99_BLOCK ;
499 #else
500 VSNPRINTF_NOT_C99_BLOCK ;
501 #endif
502 #endif
503
504 return buffer;
505 }
506
507
508 /**
509 * raptor_basename:
510 * @name: path
511 *
512 * Get the basename of a path
513 *
514 * Return value: filename part of a pathname
515 **/
516 const char*
raptor_basename(const char * name)517 raptor_basename(const char *name)
518 {
519 char *p;
520 if((p=strrchr(name, '/')))
521 name=p+1;
522 else if((p=strrchr(name, '\\')))
523 name=p+1;
524
525 return name;
526 }
527
528
529 const unsigned char * const raptor_xml_literal_datatype_uri_string=(const unsigned char *)"http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral";
530 const unsigned int raptor_xml_literal_datatype_uri_string_len=53;
531
532 /**
533 * raptor_print_ntriples_string:
534 * @stream: FILE* stream to print to
535 * @string: UTF-8 string to print
536 * @delim: Delimiter character for string (such as ") or \0 for no delim
537 * escaping.
538 *
539 * Print an UTF-8 string using N-Triples escapes.
540 *
541 * Return value: non-0 on failure such as bad UTF-8 encoding.
542 **/
543 int
raptor_print_ntriples_string(FILE * stream,const unsigned char * string,const char delim)544 raptor_print_ntriples_string(FILE *stream,
545 const unsigned char *string,
546 const char delim)
547 {
548 unsigned char c;
549 size_t len=strlen((const char*)string);
550 int unichar_len;
551 raptor_unichar unichar;
552
553 for(; (c=*string); string++, len--) {
554 if((delim && c == delim) || c == '\\') {
555 fprintf(stream, "\\%c", c);
556 continue;
557 }
558
559 /* Note: NTriples is ASCII */
560 if(c == 0x09) {
561 fputs("\\t", stream);
562 continue;
563 } else if(c == 0x0a) {
564 fputs("\\n", stream);
565 continue;
566 } else if(c == 0x0d) {
567 fputs("\\r", stream);
568 continue;
569 } else if(c < 0x20|| c == 0x7f) {
570 fprintf(stream, "\\u%04X", c);
571 continue;
572 } else if(c < 0x80) {
573 fputc(c, stream);
574 continue;
575 }
576
577 /* It is unicode */
578
579 unichar_len=raptor_utf8_to_unicode_char(NULL, string, len);
580 if(unichar_len < 0 || unichar_len > (int)len)
581 /* UTF-8 encoding had an error or ended in the middle of a string */
582 return 1;
583
584 unichar_len=raptor_utf8_to_unicode_char(&unichar, string, len);
585
586 if(unichar < 0x10000)
587 fprintf(stream, "\\u%04lX", unichar);
588 else
589 fprintf(stream, "\\U%08lX", unichar);
590
591 unichar_len--; /* since loop does len-- */
592 string += unichar_len; len -= unichar_len;
593
594 }
595
596 return 0;
597 }
598
599
600 /**
601 * raptor_check_ordinal:
602 * @name: ordinal string
603 *
604 * Check an RDF property ordinal, the n in rdf:_n
605 *
606 * Return value: ordinal integer or <0 if string is not a valid ordinal
607 */
608 int
raptor_check_ordinal(const unsigned char * name)609 raptor_check_ordinal(const unsigned char *name) {
610 int ordinal= -1;
611 unsigned char c;
612
613 while((c=*name++)) {
614 if(c < '0' || c > '9')
615 return -1;
616 if(ordinal <0)
617 ordinal=0;
618 ordinal *= 10;
619 ordinal += (c - '0');
620 }
621 return ordinal;
622 }
623
624
625 #ifndef RAPTOR_DISABLE_V1
626 /**
627 * raptor_error_handlers_init:
628 * @error_handlers: error handlers object
629 *
630 * Initialize #raptor_error_handlers object statically.
631 *
632 * raptor_init() MUST have been called before calling this function.
633 * Use raptor_error_handlers_init_v2() if using raptor_world APIs.
634 */
635 void
raptor_error_handlers_init(raptor_error_handlers * error_handlers)636 raptor_error_handlers_init(raptor_error_handlers* error_handlers)
637 {
638 raptor_error_handlers_init_v2(raptor_world_instance(), error_handlers);
639 }
640 #endif
641
642
643 /**
644 * raptor_error_handlers_init_v2:
645 * @world: raptor_world object
646 * @error_handlers: error handlers object
647 *
648 * Initialize #raptor_error_handlers object statically.
649 *
650 */
651 void
raptor_error_handlers_init_v2(raptor_world * world,raptor_error_handlers * error_handlers)652 raptor_error_handlers_init_v2(raptor_world *world, raptor_error_handlers* error_handlers)
653 {
654 error_handlers->magic=RAPTOR_ERROR_HANDLER_MAGIC;
655 error_handlers->world=world;
656 }
657
658
659 static const char* const raptor_log_level_labels[RAPTOR_LOG_LEVEL_LAST+1]={
660 "none",
661 "fatal error",
662 "error",
663 "warning"
664 };
665
666
667 /* internal */
668 void
raptor_log_error_to_handlers(raptor_world * world,raptor_error_handlers * error_handlers,raptor_log_level level,raptor_locator * locator,const char * message)669 raptor_log_error_to_handlers(raptor_world* world,
670 raptor_error_handlers* error_handlers,
671 raptor_log_level level,
672 raptor_locator* locator, const char* message)
673 {
674 if(level == RAPTOR_LOG_LEVEL_NONE)
675 return;
676
677 raptor_log_error(world, level, error_handlers->handlers[level].handler,
678 error_handlers->handlers[level].user_data,
679 locator, message);
680 }
681
682
683 void
raptor_log_error_varargs(raptor_world * world,raptor_log_level level,raptor_message_handler handler,void * handler_data,raptor_locator * locator,const char * message,va_list arguments)684 raptor_log_error_varargs(raptor_world* world,
685 raptor_log_level level,
686 raptor_message_handler handler, void* handler_data,
687 raptor_locator* locator,
688 const char* message, va_list arguments)
689 {
690 char *buffer;
691 size_t length;
692
693 if(level == RAPTOR_LOG_LEVEL_NONE)
694 return;
695
696 buffer=raptor_vsnprintf(message, arguments);
697 if(!buffer) {
698 if(locator && world) {
699 raptor_print_locator_v2(world, stderr, locator);
700 fputc(' ', stderr);
701 }
702 fputs("raptor ", stderr);
703 fputs(raptor_log_level_labels[level], stderr);
704 fputs(" - ", stderr);
705 vfprintf(stderr, message, arguments);
706 fputc('\n', stderr);
707 return;
708 }
709
710 length=strlen(buffer);
711 if(buffer[length-1]=='\n')
712 buffer[length-1]='\0';
713
714 raptor_log_error(world, level, handler, handler_data, locator, buffer);
715
716 RAPTOR_FREE(cstring, buffer);
717 }
718
719
720 /* internal */
721 void
raptor_log_error(raptor_world * world,raptor_log_level level,raptor_message_handler handler,void * handler_data,raptor_locator * locator,const char * message)722 raptor_log_error(raptor_world* world,
723 raptor_log_level level,
724 raptor_message_handler handler, void* handler_data,
725 raptor_locator* locator, const char* message)
726 {
727 if(level == RAPTOR_LOG_LEVEL_NONE)
728 return;
729
730 if(handler)
731 /* This is the place in raptor that MOST of the user error handler
732 * functions are called. Not all, since things that use
733 * raptor_simple_message_handler are called in their respective codes.
734 *
735 * FIXME: In future, this should be the only place but it requires
736 * a public API change such as e.g. raptor_new_qname()
737 */
738 handler(handler_data, locator, message);
739 else {
740 if(locator && world) {
741 raptor_print_locator_v2(world, stderr, locator);
742 fputc(' ', stderr);
743 }
744 fputs("raptor ", stderr);
745 fputs(raptor_log_level_labels[level], stderr);
746 fputs(" - ", stderr);
747 fputs(message, stderr);
748 fputc('\n', stderr);
749 }
750 }
751
752
753
754 /**
755 * raptor_free_memory:
756 * @ptr: memory pointer
757 *
758 * Free memory allocated inside raptor.
759 *
760 * Some systems require memory allocated in a library to
761 * be deallocated in that library. This function allows
762 * memory allocated by raptor to be freed.
763 *
764 * Examples include the result of the '_to_' methods that returns
765 * allocated memory such as raptor_uri_filename_to_uri_string,
766 * raptor_uri_filename_to_uri_string
767 * and raptor_uri_uri_string_to_filename_fragment
768 *
769 **/
770 void
raptor_free_memory(void * ptr)771 raptor_free_memory(void *ptr)
772 {
773 RAPTOR_ASSERT_OBJECT_POINTER_RETURN(ptr, memory);
774
775 RAPTOR_FREE(void, ptr);
776 }
777
778
779 /**
780 * raptor_alloc_memory:
781 * @size: size of memory to allocate
782 *
783 * Allocate memory inside raptor.
784 *
785 * Some systems require memory allocated in a library to
786 * be deallocated in that library. This function allows
787 * memory to be allocated inside the raptor shared library
788 * that can be freed inside raptor either internally or via
789 * raptor_free_memory.
790 *
791 * Examples include using this in the raptor_parser_generate_id() handler
792 * code to create new strings that will be used internally
793 * as short identifiers and freed later on by the parsers.
794 *
795 * Return value: the address of the allocated memory or NULL on failure
796 *
797 **/
798 void*
raptor_alloc_memory(size_t size)799 raptor_alloc_memory(size_t size)
800 {
801 return RAPTOR_MALLOC(void, size);
802 }
803
804
805 /**
806 * raptor_calloc_memory:
807 * @nmemb: number of members
808 * @size: size of item
809 *
810 * Allocate zeroed array of items inside raptor.
811 *
812 * Some systems require memory allocated in a library to
813 * be deallocated in that library. This function allows
814 * memory to be allocated inside the raptor shared library
815 * that can be freed inside raptor either internally or via
816 * raptor_free_memory.
817 *
818 * Examples include using this in the raptor_parser_generate_id() handler
819 * code to create new strings that will be used internally
820 * as short identifiers and freed later on by the parsers.
821 *
822 * Return value: the address of the allocated memory or NULL on failure
823 *
824 **/
825 void*
raptor_calloc_memory(size_t nmemb,size_t size)826 raptor_calloc_memory(size_t nmemb, size_t size)
827 {
828 return RAPTOR_CALLOC(void, nmemb, size);
829 }
830
831
832 #if defined (RAPTOR_DEBUG) && defined(RAPTOR_MEMORY_SIGN)
833 void*
raptor_sign_malloc(size_t size)834 raptor_sign_malloc(size_t size)
835 {
836 int *p;
837
838 size += sizeof(int);
839
840 p=(int*)malloc(size);
841 *p++ = RAPTOR_SIGN_KEY;
842 return p;
843 }
844
845 void*
raptor_sign_calloc(size_t nmemb,size_t size)846 raptor_sign_calloc(size_t nmemb, size_t size)
847 {
848 int *p;
849
850 /* turn into bytes */
851 size = nmemb*size + sizeof(int);
852
853 p=(int*)calloc(1, size);
854 *p++ = RAPTOR_SIGN_KEY;
855 return p;
856 }
857
858 void*
raptor_sign_realloc(void * ptr,size_t size)859 raptor_sign_realloc(void *ptr, size_t size)
860 {
861 int *p;
862
863 if(!ptr)
864 return raptor_sign_malloc(size);
865
866 p=(int*)ptr;
867 p--;
868
869 if(*p != RAPTOR_SIGN_KEY)
870 RAPTOR_FATAL3("memory signature %08X != %08X", *p, RAPTOR_SIGN_KEY);
871
872 size += sizeof(int);
873
874 p=(int*)realloc(p, size);
875 *p++= RAPTOR_SIGN_KEY;
876 return p;
877 }
878
879 void
raptor_sign_free(void * ptr)880 raptor_sign_free(void *ptr)
881 {
882 int *p;
883
884 if(!ptr)
885 return;
886
887 p=(int*)ptr;
888 p--;
889
890 if(*p != RAPTOR_SIGN_KEY)
891 RAPTOR_FATAL3("memory signature %08X != %08X", *p, RAPTOR_SIGN_KEY);
892
893 free(p);
894 }
895 #endif
896
897
898 #if defined (RAPTOR_DEBUG) && defined(HAVE_DMALLOC_H) && defined(RAPTOR_MEMORY_DEBUG_DMALLOC)
899
900 #undef malloc
901 void*
raptor_system_malloc(size_t size)902 raptor_system_malloc(size_t size)
903 {
904 return malloc(size);
905 }
906
907 #undef free
908 void
raptor_system_free(void * ptr)909 raptor_system_free(void *ptr)
910 {
911 free(ptr);
912 }
913
914 #endif
915