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