/* -*- Mode: c; c-basic-offset: 2 -*- * * raptor_general.c - Raptor general routines * * Copyright (C) 2000-2006, David Beckett http://purl.org/net/dajobe/ * Copyright (C) 2000-2005, University of Bristol, UK http://www.bristol.ac.uk/ * * This package is Free Software and part of Redland http://librdf.org/ * * It is licensed under the following three licenses as alternatives: * 1. GNU Lesser General Public License (LGPL) V2.1 or any newer version * 2. GNU General Public License (GPL) V2 or any newer version * 3. Apache License, V2.0 or any newer version * * You may not use this file except in compliance with at least one of * the above three licenses. * * See LICENSE.html or LICENSE.txt at the top of this package for the * complete terms and further detail along with the license texts for * the licenses in COPYING.LIB, COPYING and LICENSE-2.0.txt respectively. * * */ #ifdef HAVE_CONFIG_H #include #endif #ifdef WIN32 #include #endif #include #include #include #include #ifdef HAVE_ERRNO_H #include #endif #ifdef HAVE_STDLIB_H #include #endif /* Raptor includes */ #include "raptor.h" #include "raptor_internal.h" /* prototypes for helper functions */ static void raptor_print_statement_part_as_ntriples(FILE* stream, const void *term, raptor_identifier_type type, raptor_uri* literal_datatype, const unsigned char *literal_language); /* statics */ static int raptor_initialised=0; const char * const raptor_short_copyright_string = "Copyright 2000-2006 David Beckett. Copyright 2000-2005 University of Bristol"; const char * const raptor_copyright_string = "Copyright (C) 2000-2006 David Beckett - http://purl.org/net/dajobe/\nCopyright (C) 2000-2005 University of Bristol - http://www.bristol.ac.uk/"; /** * raptor_version_string: * * Library full version as a string. * * See also #raptor_version_decimal. */ const char * const raptor_version_string = VERSION; /** * raptor_version_major: * * Library major version number as a decimal integer. */ const unsigned int raptor_version_major = RAPTOR_VERSION_MAJOR; /** * raptor_version_minor: * * Library minor version number as a decimal integer. */ const unsigned int raptor_version_minor = RAPTOR_VERSION_MINOR; /** * raptor_version_release: * * Library release version number as a decimal integer. */ const unsigned int raptor_version_release = RAPTOR_VERSION_RELEASE; /** * raptor_version_decimal: * * Library full version as a decimal integer. * * See also #raptor_version_string. */ const unsigned int raptor_version_decimal = RAPTOR_VERSION_DECIMAL; /** * raptor_init: * * Initialise the raptor library. * * This function MUST be called before using any of the raptor APIs. **/ void raptor_init(void) { if(raptor_initialised) return; raptor_sax2_init(); raptor_parsers_init(); raptor_serializers_init(); raptor_uri_init(); raptor_www_init(); raptor_initialised=1; } /** * raptor_finish: * * Terminate the raptor library. * * Cleans up state of the library. If called, must be used after * all other objects are destroyed with their destructor. **/ void raptor_finish(void) { if(!raptor_initialised) return; raptor_www_finish(); raptor_parsers_finish(); raptor_serializers_finish(); raptor_sax2_finish(); raptor_initialised=0; } /* * Thanks to the patch in this Debian bug for the solution * to the crash inside vsnprintf on some architectures. * * "reuse of args inside the while(1) loop is in violation of the * specs and only happens to work by accident on other systems." * * http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=104325 */ #ifndef va_copy #ifdef __va_copy #define va_copy(dest,src) __va_copy(dest,src) #else #define va_copy(dest,src) (dest) = (src) #endif #endif /** * raptor_vsnprintf: * @message: printf-style format string * @arguments: variable arguments list * * Format output for a variable arguments list. * * This is a wrapper around system versions of vsnprintf with * different call and return conventions. * * Return value: a newly allocated string as the format result or NULL on failure **/ char* raptor_vsnprintf(const char *message, va_list arguments) { char empty_buffer[1]; int len; char *buffer=NULL; va_list args_copy; #ifdef HAVE_C99_VSNPRINTF /* copy for re-use */ va_copy(args_copy, arguments); len=vsnprintf(empty_buffer, 1, message, args_copy)+1; va_end(args_copy); if(len<=0) return NULL; buffer=(char*)RAPTOR_MALLOC(cstring, len); if(buffer) { /* copy for re-use */ va_copy(args_copy, arguments); vsnprintf(buffer, len, message, args_copy); va_end(args_copy); } #else /* This vsnprintf doesn't return number of bytes required */ int size=2; while(1) { buffer=(char*)RAPTOR_MALLOC(cstring, size+1); if(!buffer) break; /* copy for re-use */ va_copy(args_copy, arguments); len=vsnprintf(buffer, size, message, args_copy); va_end(args_copy); if(len>=0) break; RAPTOR_FREE(cstring, buffer); size+=4; } #endif return buffer; } /** * raptor_basename: * @name: path * * Get the basename of a path * * Return value: filename part of a pathname **/ const char* raptor_basename(const char *name) { char *p; if((p=strrchr(name, '/'))) name=p+1; else if((p=strrchr(name, '\\'))) name=p+1; return name; } const unsigned char * const raptor_xml_literal_datatype_uri_string=(const unsigned char *)"http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral"; const unsigned int raptor_xml_literal_datatype_uri_string_len=53; /** * raptor_statement_copy: * @statement: statement to copy * * Copy a raptor_statemnt * * Return value: a new #raptor_statement or NULL on error */ raptor_statement* raptor_statement_copy(const raptor_statement *statement) { raptor_statement *s; s=(raptor_statement*)RAPTOR_CALLOC(raptor_statement, 1, sizeof(raptor_statement)); if(!s) return NULL; s->subject_type=statement->subject_type; if(statement->subject_type == RAPTOR_IDENTIFIER_TYPE_ANONYMOUS) { unsigned char *new_blank=(unsigned char*)RAPTOR_MALLOC(cstring, strlen((char*)statement->subject)+1); strcpy((char*)new_blank, (const char*)statement->subject); s->subject=new_blank; } else if(statement->subject_type == RAPTOR_IDENTIFIER_TYPE_ORDINAL) { s->subject=raptor_new_uri_from_rdf_ordinal(*((int*)statement->subject)); s->subject_type=RAPTOR_IDENTIFIER_TYPE_RESOURCE; } else s->subject=raptor_uri_copy((raptor_uri*)statement->subject); s->predicate_type=RAPTOR_IDENTIFIER_TYPE_RESOURCE; if(statement->predicate_type == RAPTOR_IDENTIFIER_TYPE_ORDINAL) s->predicate=raptor_new_uri_from_rdf_ordinal(*((int*)statement->predicate)); else s->predicate=raptor_uri_copy((raptor_uri*)statement->predicate); s->object_type=statement->object_type; if(statement->object_type == RAPTOR_IDENTIFIER_TYPE_LITERAL || statement->object_type == RAPTOR_IDENTIFIER_TYPE_XML_LITERAL) { unsigned char *string; char *language=NULL; raptor_uri *uri=NULL; string=(unsigned char*)RAPTOR_MALLOC(cstring, strlen((char*)statement->object)+1); strcpy((char*)string, (const char*)statement->object); s->object=string; if(statement->object_literal_language) { language=(char*)RAPTOR_MALLOC(cstring, strlen((const char*)statement->object_literal_language)+1); strcpy(language, (const char*)statement->object_literal_language); s->object_literal_language=(const unsigned char*)language; } if(statement->object_type == RAPTOR_IDENTIFIER_TYPE_XML_LITERAL) { /* nop */ } else if(statement->object_literal_datatype) { uri=raptor_uri_copy((raptor_uri*)statement->object_literal_datatype); s->object_literal_datatype=uri; } } else if(statement->object_type == RAPTOR_IDENTIFIER_TYPE_ANONYMOUS) { char *blank=(char*)statement->object; unsigned char *new_blank=(unsigned char*)RAPTOR_MALLOC(cstring, strlen(blank)+1); strcpy((char*)new_blank, (const char*)blank); s->object=new_blank; } else if(statement->object_type == RAPTOR_IDENTIFIER_TYPE_ORDINAL) { s->object=raptor_new_uri_from_rdf_ordinal(*((int*)statement->object)); s->object_type=RAPTOR_IDENTIFIER_TYPE_RESOURCE; } else { raptor_uri *uri=raptor_uri_copy((raptor_uri*)statement->object); s->object=uri; } return s; } /** * raptor_free_statement: * @statement: statement * * Destructor */ void raptor_free_statement(raptor_statement *statement) { if(statement->subject) { if(statement->subject_type == RAPTOR_IDENTIFIER_TYPE_RESOURCE) raptor_free_uri((raptor_uri*)statement->subject); else RAPTOR_FREE(cstring, (void*)statement->subject); } if(statement->predicate) { if(statement->predicate_type == RAPTOR_IDENTIFIER_TYPE_PREDICATE || statement->predicate_type == RAPTOR_IDENTIFIER_TYPE_RESOURCE) raptor_free_uri((raptor_uri*)statement->predicate); else RAPTOR_FREE(cstring, (void*)statement->predicate); } if(statement->object_type == RAPTOR_IDENTIFIER_TYPE_RESOURCE) { if(statement->object) raptor_free_uri((raptor_uri*)statement->object); } else { if(statement->object) RAPTOR_FREE(cstring, (void*)statement->object); if(statement->object_literal_language) RAPTOR_FREE(cstring, (void*)statement->object_literal_language); if(statement->object_literal_datatype) raptor_free_uri((raptor_uri*)statement->object_literal_datatype); } RAPTOR_FREE(raptor_statement, statement); } /** * raptor_print_statement: * @statement: #raptor_statement object to print * @stream: #FILE* stream * * Print a raptor_statement to a stream. * **/ void raptor_print_statement(const raptor_statement * statement, FILE *stream) { fputc('[', stream); if(statement->subject_type == RAPTOR_IDENTIFIER_TYPE_ANONYMOUS) { fputs((const char*)statement->subject, stream); } else { #ifdef RAPTOR_DEBUG if(!statement->subject) RAPTOR_FATAL1("Statement has NULL subject URI\n"); #endif fputs((const char*)raptor_uri_as_string((raptor_uri*)statement->subject), stream); } fputs(", ", stream); if(statement->predicate_type == RAPTOR_IDENTIFIER_TYPE_ORDINAL) fprintf(stream, "[rdf:_%d]", *((int*)statement->predicate)); else { #ifdef RAPTOR_DEBUG if(!statement->predicate) RAPTOR_FATAL1("Statement has NULL predicate URI\n"); #endif fputs((const char*)raptor_uri_as_string((raptor_uri*)statement->predicate), stream); } fputs(", ", stream); if(statement->object_type == RAPTOR_IDENTIFIER_TYPE_LITERAL || statement->object_type == RAPTOR_IDENTIFIER_TYPE_XML_LITERAL) { if(statement->object_type == RAPTOR_IDENTIFIER_TYPE_XML_LITERAL) { fputc('<', stream); fputs((const char*)raptor_xml_literal_datatype_uri_string, stream); fputc('>', stream); } else if(statement->object_literal_datatype) { fputc('<', stream); fputs((const char*)raptor_uri_as_string((raptor_uri*)statement->object_literal_datatype), stream); fputc('>', stream); } fputc('"', stream); fputs((const char*)statement->object, stream); fputc('"', stream); } else if(statement->object_type == RAPTOR_IDENTIFIER_TYPE_ANONYMOUS) fputs((const char*)statement->object, stream); else if(statement->object_type == RAPTOR_IDENTIFIER_TYPE_ORDINAL) fprintf(stream, "[rdf:_%d]", *((int*)statement->object)); else { #ifdef RAPTOR_DEBUG if(!statement->object) RAPTOR_FATAL1("Statement has NULL object URI\n"); #endif fputs((const char*)raptor_uri_as_string((raptor_uri*)statement->object), stream); } fputc(']', stream); } /** * raptor_print_statement_detailed: * @statement: #raptor_statement object to print * @detailed: unused * @stream: #FILE* stream * * Print a raptor_statement to a stream in a detailed fashion. * * No current difference from calling raptor_print_statement(). * **/ void raptor_print_statement_detailed(const raptor_statement * statement, int detailed, FILE *stream) { raptor_print_statement(statement, stream); } /** * raptor_print_ntriples_string: * @stream: FILE* stream to print to * @string: UTF-8 string to print * @delim: Delimiter character for string (such as ") or \0 for no delim * escaping. * * Print an UTF-8 string using N-Triples escapes. * * Return value: non-0 on failure such as bad UTF-8 encoding. **/ int raptor_print_ntriples_string(FILE *stream, const unsigned char *string, const char delim) { unsigned char c; size_t len=strlen((const char*)string); int unichar_len; unsigned long unichar; for(; (c=*string); string++, len--) { if((delim && c == delim) || c == '\\') { fprintf(stream, "\\%c", c); continue; } /* Note: NTriples is ASCII */ if(c == 0x09) { fputs("\\t", stream); continue; } else if(c == 0x0a) { fputs("\\n", stream); continue; } else if(c == 0x0d) { fputs("\\r", stream); continue; } else if(c < 0x20|| c == 0x7f) { fprintf(stream, "\\u%04X", c); continue; } else if(c < 0x80) { fputc(c, stream); continue; } /* It is unicode */ unichar_len=raptor_utf8_to_unicode_char(NULL, string, len); if(unichar_len < 0 || unichar_len > (int)len) /* UTF-8 encoding had an error or ended in the middle of a string */ return 1; unichar_len=raptor_utf8_to_unicode_char(&unichar, string, len); if(unichar < 0x10000) fprintf(stream, "\\u%04lX", unichar); else fprintf(stream, "\\U%08lX", unichar); unichar_len--; /* since loop does len-- */ string += unichar_len; len -= unichar_len; } return 0; } /** * raptor_statement_part_as_counted_string: * @term: #raptor_statement part (subject, predicate, object) * @type: #raptor_statement part type * @literal_datatype: #raptor_statement part datatype * @literal_language: #raptor_statement part language * @len_p: Pointer to location to store length of new string (if not NULL) * * Turns part of raptor statement into a N-Triples format counted string. * * Turns the given @term into an N-Triples escaped string using all the * escapes as defined in http://www.w3.org/TR/rdf-testcases/#ntriples * * The part (subject, predicate, object) of the raptor_statement is * typically passed in as @term, the part type (subject_type, * predicate_type, object_type) is passed in as @type. When the part * is a literal, the @literal_datatype and @literal_language fields * are set, otherwise NULL (usually object_datatype, * object_literal_language). * * Return value: the new string or NULL on failure. The length of * the new string is returned in *@len_p if len_p is not NULL. **/ unsigned char* raptor_statement_part_as_counted_string(const void *term, raptor_identifier_type type, raptor_uri* literal_datatype, const unsigned char *literal_language, size_t* len_p) { size_t len, term_len, uri_len; size_t language_len=0; unsigned char *s, *buffer; unsigned char *uri_string=NULL; switch(type) { case RAPTOR_IDENTIFIER_TYPE_LITERAL: case RAPTOR_IDENTIFIER_TYPE_XML_LITERAL: term_len=strlen((const char*)term); len=2+term_len; if(literal_language && type == RAPTOR_IDENTIFIER_TYPE_LITERAL) { language_len=strlen((const char*)literal_language); len+= language_len+1; } if(type == RAPTOR_IDENTIFIER_TYPE_XML_LITERAL) len += 4+raptor_xml_literal_datatype_uri_string_len; else if(literal_datatype) { uri_string=raptor_uri_as_counted_string((raptor_uri*)literal_datatype, &uri_len); len += 4+uri_len; } buffer=(unsigned char*)RAPTOR_MALLOC(cstring, len+1); if(!buffer) return NULL; s=buffer; *s++ ='"'; /* raptor_print_ntriples_string(stream, (const char*)term, '"'); */ strcpy((char*)s, (const char*)term); s+= term_len; *s++ ='"'; if(literal_language && type == RAPTOR_IDENTIFIER_TYPE_LITERAL) { *s++ ='@'; strcpy((char*)s, (const char*)literal_language); s+= language_len; } if(type == RAPTOR_IDENTIFIER_TYPE_XML_LITERAL) { *s++ ='^'; *s++ ='^'; *s++ ='<'; strcpy((char*)s, (const char*)raptor_xml_literal_datatype_uri_string); s+= raptor_xml_literal_datatype_uri_string_len; *s++ ='>'; } else if(literal_datatype) { *s++ ='^'; *s++ ='^'; *s++ ='<'; strcpy((char*)s, (const char*)uri_string); s+= uri_len; *s++ ='>'; } *s++ ='\0'; break; case RAPTOR_IDENTIFIER_TYPE_ANONYMOUS: len=2+strlen((const char*)term); buffer=(unsigned char*)RAPTOR_MALLOC(cstring, len+1); if(!buffer) return NULL; s=buffer; *s++ ='_'; *s++ =':'; strcpy((char*)s, (const char*)term); break; case RAPTOR_IDENTIFIER_TYPE_ORDINAL: len=raptor_rdf_namespace_uri_len + 13; buffer=(unsigned char*)RAPTOR_MALLOC(cstring, len+1); if(!buffer) return NULL; sprintf((char*)buffer, "<%s_%d>", raptor_rdf_namespace_uri, *((int*)term)); break; case RAPTOR_IDENTIFIER_TYPE_RESOURCE: case RAPTOR_IDENTIFIER_TYPE_PREDICATE: uri_string=raptor_uri_as_counted_string((raptor_uri*)term, &uri_len); len=2+uri_len; buffer=(unsigned char*)RAPTOR_MALLOC(cstring, len+1); if(!buffer) return NULL; s=buffer; *s++ ='<'; /* raptor_print_ntriples_string(stream, raptor_uri_as_string((raptor_uri*)term), '\0'); */ strcpy((char*)s, (const char*)uri_string); s+= uri_len; *s++ ='>'; *s++ ='\0'; break; case RAPTOR_IDENTIFIER_TYPE_UNKNOWN: default: RAPTOR_FATAL2("Unknown type %d", type); } if(len_p) *len_p=len; return buffer; } /** * raptor_statement_part_as_string: * @term: #raptor_statement part (subject, predicate, object) * @type: #raptor_statement part type * @literal_datatype: #raptor_statement part datatype * @literal_language: #raptor_statement part language * * Turns part of raptor statement into a N-Triples format string. * * Turns the given @term into an N-Triples escaped string using all the * escapes as defined in http://www.w3.org/TR/rdf-testcases/#ntriples * * The part (subject, predicate, object) of the raptor_statement is * typically passed in as @term, the part type (subject_type, * predicate_type, object_type) is passed in as @type. When the part * is a literal, the @literal_datatype and @literal_language fields * are set, otherwise NULL (usually object_datatype, * object_literal_language). * * Return value: the new string or NULL on failure. **/ unsigned char* raptor_statement_part_as_string(const void *term, raptor_identifier_type type, raptor_uri* literal_datatype, const unsigned char *literal_language) { return raptor_statement_part_as_counted_string(term, type, literal_datatype, literal_language, NULL); } static void raptor_print_statement_part_as_ntriples(FILE* stream, const void *term, raptor_identifier_type type, raptor_uri* literal_datatype, const unsigned char *literal_language) { switch(type) { case RAPTOR_IDENTIFIER_TYPE_LITERAL: case RAPTOR_IDENTIFIER_TYPE_XML_LITERAL: fputc('"', stream); raptor_print_ntriples_string(stream, (const unsigned char*)term, '"'); fputc('"', stream); if(literal_language && type == RAPTOR_IDENTIFIER_TYPE_LITERAL) { fputc('@', stream); fputs((const char*)literal_language, stream); } if(type == RAPTOR_IDENTIFIER_TYPE_XML_LITERAL) { fputs("^^<", stream); fputs((const char*)raptor_xml_literal_datatype_uri_string, stream); fputc('>', stream); } else if(literal_datatype) { fputs("^^<", stream); fputs((const char*)raptor_uri_as_string((raptor_uri*)literal_datatype), stream); fputc('>', stream); } break; case RAPTOR_IDENTIFIER_TYPE_ANONYMOUS: fputs("_:", stream); fputs((const char*)term, stream); break; case RAPTOR_IDENTIFIER_TYPE_ORDINAL: fprintf(stream, "<%s_%d>", raptor_rdf_namespace_uri, *((int*)term)); break; case RAPTOR_IDENTIFIER_TYPE_RESOURCE: case RAPTOR_IDENTIFIER_TYPE_PREDICATE: fputc('<', stream); raptor_print_ntriples_string(stream, raptor_uri_as_string((raptor_uri*)term), '\0'); fputc('>', stream); break; case RAPTOR_IDENTIFIER_TYPE_UNKNOWN: default: RAPTOR_FATAL2("Unknown type %d", type); } } /** * raptor_print_statement_as_ntriples: * @statement: #raptor_statement to print * @stream: #FILE* stream * * Print a raptor_statement in N-Triples form. * **/ void raptor_print_statement_as_ntriples(const raptor_statement * statement, FILE *stream) { raptor_print_statement_part_as_ntriples(stream, statement->subject, statement->subject_type, NULL, NULL); fputc(' ', stream); raptor_print_statement_part_as_ntriples(stream, statement->predicate, statement->predicate_type, NULL, NULL); fputc(' ', stream); raptor_print_statement_part_as_ntriples(stream, statement->object, statement->object_type, statement->object_literal_datatype, statement->object_literal_language); fputs(" .", stream); } /** * raptor_check_ordinal: * @name: ordinal string * * Check an RDF property ordinal, the n in rdf:_n * * Return value: ordinal integer or <0 if string is not a valid ordinal */ int raptor_check_ordinal(const unsigned char *name) { int ordinal= -1; unsigned char c; while((c=*name++)) { if(c < '0' || c > '9') return -1; if(ordinal <0) ordinal=0; ordinal *= 10; ordinal += (c - '0'); } return ordinal; } /** * raptor_invoke_simple_message_varargs: * @type: string type "warning" or "error" for messages * @handler: simple message handler * @user_data; message handler data * @message: message format string and arguments * * Call message handler/data with varargs - Internal * * Calls a function matching the raptor_simple_message_handler API but * allows variable arguments */ void raptor_invoke_simple_message_varargs(const char *type, raptor_simple_message_handler handler, void* user_data, const char *message, va_list arguments) { char *buffer; size_t length; buffer=raptor_vsnprintf(message, arguments); if(!buffer) { fprintf(stderr, "raptor_invoke_simple_message: Out of memory\n"); fprintf(stderr, "raptor %s - ", type); vfprintf(stderr, message, arguments); fputc('\n', stderr); } else { if(handler) { length=strlen(buffer); if(buffer[length-1]=='\n') buffer[length-1]='\0'; handler(user_data, buffer); } else { fprintf(stderr, " raptor %s - ", type); fputs(buffer, stderr); fputc('\n', stderr); } RAPTOR_FREE(cstring, buffer); } } /** * raptor_invoke_message: * @type: string type "warning" or "error" for messages * @handler: simple message handler * @user_data; message handler data * @locator: raptor_locator * @message: message format string and arguments * * Call message handler/data with varargs - Internal * * Calls a function matching the raptor_message_handler API but * allows variable arguments */ void raptor_invoke_message_varargs(const char *type, raptor_message_handler handler, void* user_data, raptor_locator* locator, const char *message, va_list arguments) { char *buffer; size_t length; buffer=raptor_vsnprintf(message, arguments); if(!buffer) { fprintf(stderr, "raptor_invoke_message: Out of memory\n"); fprintf(stderr, "raptor %s - ", type); vfprintf(stderr, message, arguments); fputc('\n', stderr); } else { if(handler) { length=strlen(buffer); if(buffer[length-1]=='\n') buffer[length-1]='\0'; handler(user_data, locator, buffer); } else { if(locator) raptor_print_locator(stderr, locator); fprintf(stderr, " raptor %s - ", type); fputs(buffer, stderr); fputc('\n', stderr); } RAPTOR_FREE(cstring, buffer); } } /** * raptor_free_memory: * @ptr: memory pointer * * Free memory allocated inside raptor. * * Some systems require memory allocated in a library to * be deallocated in that library. This function allows * memory allocated by raptor to be freed. * * Examples include the result of the '_to_' methods that returns * allocated memory such as raptor_uri_filename_to_uri_string, * raptor_uri_filename_to_uri_string * and raptor_uri_uri_string_to_filename_fragment * **/ void raptor_free_memory(void *ptr) { RAPTOR_FREE(void, ptr); } /** * raptor_alloc_memory: * @size: size of memory to allocate * * Allocate memory inside raptor. * * Some systems require memory allocated in a library to * be deallocated in that library. This function allows * memory to be allocated inside the raptor shared library * that can be freed inside raptor either internally or via * raptor_free_memory. * * Examples include using this in the raptor_generate_id handler * code to create new strings that will be used internally * as short identifiers and freed later on by the parsers. * * Return value: the address of the allocated memory or NULL on failure * **/ void* raptor_alloc_memory(size_t size) { return RAPTOR_MALLOC(void, size); } /** * raptor_calloc_memory: * @nmemb: number of members * @size: size of item * * Allocate zeroed array of items inside raptor. * * Some systems require memory allocated in a library to * be deallocated in that library. This function allows * memory to be allocated inside the raptor shared library * that can be freed inside raptor either internally or via * raptor_free_memory. * * Examples include using this in the raptor_generate_id handler * code to create new strings that will be used internally * as short identifiers and freed later on by the parsers. * * Return value: the address of the allocated memory or NULL on failure * **/ void* raptor_calloc_memory(size_t nmemb, size_t size) { return RAPTOR_CALLOC(void, nmemb, size); } #if defined (RAPTOR_DEBUG) && defined(RAPTOR_MEMORY_SIGN) void* raptor_sign_malloc(size_t size) { int *p; size += sizeof(int); p=(int*)malloc(size); *p++ = RAPTOR_SIGN_KEY; return p; } void* raptor_sign_calloc(size_t nmemb, size_t size) { int *p; /* turn into bytes */ size = nmemb*size + sizeof(int); p=(int*)calloc(1, size); *p++ = RAPTOR_SIGN_KEY; return p; } void* raptor_sign_realloc(void *ptr, size_t size) { int *p; if(!ptr) return raptor_sign_malloc(size); p=(int*)ptr; p--; if(*p != RAPTOR_SIGN_KEY) RAPTOR_FATAL3("memory signature %08X != %08X", *p, RAPTOR_SIGN_KEY); size += sizeof(int); p=(int*)realloc(p, size); *p++= RAPTOR_SIGN_KEY; return p; } void raptor_sign_free(void *ptr) { int *p; if(!ptr) return; p=(int*)ptr; p--; if(*p != RAPTOR_SIGN_KEY) RAPTOR_FATAL3("memory signature %08X != %08X", *p, RAPTOR_SIGN_KEY); free(p); } #endif #if defined (RAPTOR_DEBUG) && defined(HAVE_DMALLOC_H) && defined(RAPTOR_MEMORY_DEBUG_DMALLOC) #undef malloc void* raptor_system_malloc(size_t size) { return malloc(size); } #undef free void raptor_system_free(void *ptr) { free(ptr); } #endif