/* -*- Mode: c; c-basic-offset: 2 -*- * * rasqal_general.c - Rasqal library startup, shutdown and factories * * $Id: rasqal_general.c 11378 2006-10-06 05:14:12Z dajobe $ * * Copyright (C) 2004-2006, David Beckett http://purl.org/net/dajobe/ * Copyright (C) 2004-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 #ifdef HAVE_STDLIB_H #include #endif #include #include "rasqal.h" #include "rasqal_internal.h" /* prototypes for helper functions */ static void rasqal_delete_query_engine_factories(void); /* statics */ static int rasqal_initialised=0; static int rasqal_initialising=0; static int rasqal_finishing=0; /* list of query factories */ static rasqal_query_engine_factory* query_engines=NULL; const char * const rasqal_short_copyright_string = "Copyright 2003-2006 David Beckett. Copyright 2003-2005 University of Bristol"; const char * const rasqal_copyright_string = "Copyright (C) 2003-2006 David Beckett - http://purl.org/net/dajobe/\nCopyright 2003-2005 University of Bristol - http://www.bristol.ac.uk/"; /** * rasqal_version_string: * * Library full version as a string. * * See also #rasqal_version_decimal. */ const char * const rasqal_version_string = VERSION; /** * rasqal_version_major: * * Library major version number as a decimal integer. */ const unsigned int rasqal_version_major = RASQAL_VERSION_MAJOR; /** * rasqal_version_minor: * * Library minor version number as a decimal integer. */ const unsigned int rasqal_version_minor = RASQAL_VERSION_MINOR; /** * rasqal_version_release: * * Library release version number as a decimal integer. */ const unsigned int rasqal_version_release = RASQAL_VERSION_RELEASE; /** * rasqal_version_decimal: * * Library full version as a decimal integer. * * See also #rasqal_version_string. */ const unsigned int rasqal_version_decimal = RASQAL_VERSION_DECIMAL; /** * rasqal_init: * * Initialise the rasqal library. * * MUST be called before using any of the rasqal APIs. **/ void rasqal_init(void) { if(rasqal_initialised || rasqal_initialising) return; rasqal_initialising=1; raptor_init(); rasqal_uri_init(); /* last one declared is the default - RDQL */ #ifdef RASQAL_QUERY_RDQL rasqal_init_query_engine_rdql(); #endif #ifdef RASQAL_QUERY_SPARQL rasqal_init_query_engine_sparql(); #endif #ifdef RAPTOR_TRIPLES_SOURCE_RAPTOR rasqal_raptor_init(); #endif #ifdef RAPTOR_TRIPLES_SOURCE_REDLAND rasqal_redland_init(); #endif rasqal_init_query_results(); rasqal_initialising=0; rasqal_initialised=1; rasqal_finishing=0; } /** * rasqal_finish: * * Terminate the rasqal library. * * Must be called to clean up any resources used by the library. **/ void rasqal_finish(void) { if(!rasqal_initialised || rasqal_finishing) return; rasqal_finishing=1; rasqal_finish_query_results(); rasqal_delete_query_engine_factories(); #ifdef RAPTOR_TRIPLES_SOURCE_REDLAND rasqal_redland_finish(); #endif rasqal_uri_finish(); raptor_finish(); rasqal_initialising=0; rasqal_initialised=0; rasqal_finishing=0; } /* helper functions */ /* * rasqal_delete_query_engine_factories - helper function to delete all the registered query engine factories */ static void rasqal_delete_query_engine_factories(void) { rasqal_query_engine_factory *factory, *next; for(factory=query_engines; factory; factory=next) { next=factory->next; if(factory->finish_factory) factory->finish_factory(factory); RASQAL_FREE(rasqal_query_engine_factory, (void*)factory->name); RASQAL_FREE(rasqal_query_engine_factory, (void*)factory->label); if(factory->alias) RASQAL_FREE(rasqal_query_engine_factory, (void*)factory->alias); if(factory->uri_string) RASQAL_FREE(rasqal_query_engine_factory, (void*)factory->uri_string); RASQAL_FREE(rasqal_query_engine_factory, factory); } query_engines=NULL; } /* class methods */ /* * rasqal_query_engine_register_factory - Register a syntax handled by a query factory * @name: the short syntax name * @label: readable label for syntax * @uri_string: URI string of the syntax (or NULL) * @factory: pointer to function to call to register the factory * * INTERNAL * **/ void rasqal_query_engine_register_factory(const char *name, const char *label, const char *alias, const unsigned char *uri_string, void (*factory) (rasqal_query_engine_factory*)) { rasqal_query_engine_factory *query, *h; char *name_copy, *label_copy, *alias_copy; unsigned char *uri_string_copy; #if defined(RASQAL_DEBUG) && RASQAL_DEBUG > 1 RASQAL_DEBUG4("Received registration for syntax %s '%s' with alias '%s'\n", name, label, (alias ? alias : "none")); RASQAL_DEBUG2("URI %s\n", (uri_string ? (const char*)uri_string : (const char*)"none")); #endif query=(rasqal_query_engine_factory*)RASQAL_CALLOC(rasqal_query_engine_factory, 1, sizeof(rasqal_query_engine_factory)); if(!query) RASQAL_FATAL1("Out of memory\n"); for(h = query_engines; h; h = h->next ) { if(!strcmp(h->name, name) || (alias && !strcmp(h->name, alias))) { RASQAL_FATAL2("query %s already registered\n", h->name); } } name_copy=(char*)RASQAL_CALLOC(cstring, strlen(name)+1, 1); if(!name_copy) { RASQAL_FREE(rasqal_query, query); RASQAL_FATAL1("Out of memory\n"); } strcpy(name_copy, name); query->name=name_copy; label_copy=(char*)RASQAL_CALLOC(cstring, strlen(label)+1, 1); if(!label_copy) { RASQAL_FREE(rasqal_query, query); RASQAL_FATAL1("Out of memory\n"); } strcpy(label_copy, label); query->label=label_copy; if(uri_string) { uri_string_copy=(unsigned char*)RASQAL_CALLOC(cstring, strlen((const char*)uri_string)+1, 1); if(!uri_string_copy) { RASQAL_FREE(rasqal_query, query); RASQAL_FATAL1("Out of memory\n"); } strcpy((char*)uri_string_copy, (const char*)uri_string); query->uri_string=uri_string_copy; } if(alias) { alias_copy=(char*)RASQAL_CALLOC(cstring, strlen(alias)+1, 1); if(!alias_copy) { RASQAL_FREE(rasqal_query, query); RASQAL_FATAL1("Out of memory\n"); } strcpy(alias_copy, alias); query->alias=alias_copy; } /* Call the query registration function on the new object */ (*factory)(query); #if defined(RASQAL_DEBUG) && RASQAL_DEBUG > 1 RASQAL_DEBUG3("%s has context size %d\n", name, (int)query->context_length); #endif query->next = query_engines; query_engines = query; } /** * rasqal_get_query_engine_factory: * @name: the factory name or NULL for the default factory * @uri: the query syntax URI or NULL * * Get a query factory by name. * * Return value: the factory object or NULL if there is no such factory **/ rasqal_query_engine_factory* rasqal_get_query_engine_factory (const char *name, const unsigned char *uri) { rasqal_query_engine_factory *factory; /* return 1st query if no particular one wanted - why? */ if(!name && !uri) { factory=query_engines; if(!factory) { RASQAL_DEBUG1("No (default) query_engines registered\n"); return NULL; } } else { for(factory=query_engines; factory; factory=factory->next) { if((name && !strcmp(factory->name, name)) || (factory->alias && !strcmp(factory->alias, name))) break; if(uri && !strcmp((const char*)factory->uri_string, (const char*)uri)) break; } /* else FACTORY name not found */ if(!factory) { RASQAL_DEBUG2("No query language with name %s found\n", name); return NULL; } } return factory; } /** * rasqal_languages_enumerate: * @counter: index into the list of syntaxes * @name: pointer to store the name of the syntax (or NULL) * @label: pointer to store syntax readable label (or NULL) * @uri_string: pointer to store syntax URI string (or NULL) * * Get information on query languages. * * Return value: non 0 on failure of if counter is out of range **/ int rasqal_languages_enumerate(const unsigned int counter, const char **name, const char **label, const unsigned char **uri_string) { unsigned int i; rasqal_query_engine_factory *factory=query_engines; if(!factory) return 1; for(i=0; factory && i<=counter ; i++, factory=factory->next) { if(i == counter) { if(name) *name=factory->name; if(label) *label=factory->label; if(uri_string) *uri_string=factory->uri_string; return 0; } } return 1; } /** * rasqal_language_name_check: * @name: the query language name * * Check name of a query language. * * Return value: non 0 if name is a known query language */ int rasqal_language_name_check(const char *name) { return (rasqal_get_query_engine_factory(name, NULL) != NULL); } /* * rasqal_query_fatal_error - Fatal Error from a query - Internal **/ void rasqal_query_fatal_error(rasqal_query* query, const char *message, ...) { va_list arguments; va_start(arguments, message); rasqal_query_fatal_error_varargs(query, message, arguments); va_end(arguments); } /* * rasqal_query_fatal_error_varargs - Fatal Error from a query - Internal **/ void rasqal_query_fatal_error_varargs(rasqal_query* query, const char *message, va_list arguments) { query->failed=1; if(query->fatal_error_handler) { char *buffer=raptor_vsnprintf(message, arguments); if(!buffer) { fprintf(stderr, "rasqal_query_fatal_error_varargs: Out of memory\n"); return; } query->fatal_error_handler(query->fatal_error_user_data, &query->locator, buffer); RASQAL_FREE(cstring, buffer); abort(); } raptor_print_locator(stderr, &query->locator); fprintf(stderr, " rasqal fatal error - "); vfprintf(stderr, message, arguments); fputc('\n', stderr); abort(); } /* * rasqal_query_error - Error from a query - Internal **/ void rasqal_query_error(rasqal_query* query, const char *message, ...) { va_list arguments; va_start(arguments, message); rasqal_query_error_varargs(query, message, arguments); va_end(arguments); } /* * rasqal_query_simple_error - Error from a query - Internal * * Matches the rasqal_simple_message_handler API but same as * rasqal_query_error **/ void rasqal_query_simple_error(void* query, const char *message, ...) { va_list arguments; va_start(arguments, message); rasqal_query_error_varargs((rasqal_query*)query, message, arguments); va_end(arguments); } /* * rasqal_query_error_varargs - Error from a query - Internal **/ void rasqal_query_error_varargs(rasqal_query* query, const char *message, va_list arguments) { query->failed=1; if(query->error_handler) { char *buffer=raptor_vsnprintf(message, arguments); if(!buffer) { fprintf(stderr, "rasqal_query_error_varargs: Out of memory\n"); return; } query->error_handler(query->error_user_data, &query->locator, buffer); RASQAL_FREE(cstring, buffer); return; } raptor_print_locator(stderr, &query->locator); fprintf(stderr, " rasqal error - "); vfprintf(stderr, message, arguments); fputc('\n', stderr); } /* * rasqal_query_warning - Warning from a query - Internal **/ void rasqal_query_warning(rasqal_query* query, const char *message, ...) { va_list arguments; va_start(arguments, message); rasqal_query_warning_varargs(query, message, arguments); va_end(arguments); } /* * rasqal_query_warning - Warning from a query - Internal **/ void rasqal_query_warning_varargs(rasqal_query* query, const char *message, va_list arguments) { if(query->warning_handler) { char *buffer=raptor_vsnprintf(message, arguments); if(!buffer) { fprintf(stderr, "rasqal_query_warning_varargs: Out of memory\n"); return; } query->warning_handler(query->warning_user_data, &query->locator, buffer); RASQAL_FREE(cstring, buffer); return; } raptor_print_locator(stderr, &query->locator); fprintf(stderr, " rasqal warning - "); vfprintf(stderr, message, arguments); fputc('\n', stderr); } /* wrapper */ const char* rasqal_basename(const char *name) { char *p; if((p=strrchr(name, '/'))) name=p+1; else if((p=strrchr(name, '\\'))) name=p+1; return name; } /** * rasqal_escaped_name_to_utf8_string: * @src: source name string * @len: length of source name string * @dest_lenp: pointer to store result string (or NULL) * @error_handler: error handling function * @error_data: data for error handle * * Get a UTF-8 and/or \u-escaped name as UTF-8. * * If dest_lenp is not NULL, the length of the resulting string is * stored at the pointed size_t. * * Return value: new UTF-8 string or NULL on failure. */ unsigned char* rasqal_escaped_name_to_utf8_string(const unsigned char *src, size_t len, size_t *dest_lenp, raptor_simple_message_handler error_handler, void *error_data) { const unsigned char *p=src; size_t ulen=0; unsigned long unichar=0; unsigned char *result; unsigned char *dest; int n; result=(unsigned char*)RASQAL_MALLOC(cstring, len+1); if(!result) return NULL; dest=result; /* find end of string, fixing backslashed characters on the way */ while(len > 0) { unsigned char c=*p; if(c > 0x7f) { /* just copy the UTF-8 bytes through */ size_t unichar_len=raptor_utf8_to_unicode_char(NULL, (const unsigned char*)p, len+1); if(unichar_len > len) { if(error_handler) error_handler(error_data, "UTF-8 encoding error at character %d (0x%02X) found.", c, c); /* UTF-8 encoding had an error or ended in the middle of a string */ RASQAL_FREE(cstring, result); return NULL; } memcpy(dest, p, unichar_len); dest+= unichar_len; p += unichar_len; len -= unichar_len; continue; } p++; len--; if(c != '\\') { /* not an escape - store and move on */ *dest++=c; continue; } if(!len) { RASQAL_FREE(cstring, result); return NULL; } c = *p++; len--; switch(c) { case '"': case '\\': *dest++=c; break; case 'u': case 'U': ulen=(c == 'u') ? 4 : 8; if(len < ulen) { if(error_handler) error_handler(error_data, "%c over end of line", c); RASQAL_FREE(cstring, result); return 0; } n=sscanf((const char*)p, ((ulen == 4) ? "%04lx" : "%08lx"), &unichar); if(n != 1) { if(error_handler) error_handler(error_data, "Bad %c escape", c); break; } p+=ulen; len-=ulen; if(unichar > 0x10ffff) { if(error_handler) error_handler(error_data, "Illegal Unicode character with code point #x%lX.", unichar); break; } dest+=raptor_unicode_char_to_utf8(unichar, dest); break; default: if(error_handler) error_handler(error_data, "Illegal string escape \\%c in \"%s\"", c, src); RASQAL_FREE(cstring, result); return 0; } } /* end while */ /* terminate dest, can be shorter than source */ *dest='\0'; if(dest_lenp) *dest_lenp=dest-result; return result; } raptor_uri* rasqal_xsd_namespace_uri=NULL; raptor_uri* rasqal_xsd_integer_uri=NULL; raptor_uri* rasqal_xsd_double_uri=NULL; raptor_uri* rasqal_xsd_float_uri=NULL; raptor_uri* rasqal_xsd_boolean_uri=NULL; raptor_uri* rasqal_xsd_decimal_uri=NULL; raptor_uri* rasqal_xsd_datetime_uri=NULL; raptor_uri* rasqal_xsd_string_uri=NULL; raptor_uri* rasqal_rdf_namespace_uri=NULL; raptor_uri* rasqal_rdf_first_uri=NULL; raptor_uri* rasqal_rdf_rest_uri=NULL; raptor_uri* rasqal_rdf_nil_uri=NULL; void rasqal_uri_init(void) { rasqal_xsd_namespace_uri=raptor_new_uri(raptor_xmlschema_datatypes_namespace_uri); rasqal_xsd_integer_uri=raptor_new_uri_from_uri_local_name(rasqal_xsd_namespace_uri, (const unsigned char*)"integer"); rasqal_xsd_double_uri=raptor_new_uri_from_uri_local_name(rasqal_xsd_namespace_uri, (const unsigned char*)"double"); rasqal_xsd_float_uri=raptor_new_uri_from_uri_local_name(rasqal_xsd_namespace_uri, (const unsigned char*)"float"); rasqal_xsd_boolean_uri=raptor_new_uri_from_uri_local_name(rasqal_xsd_namespace_uri, (const unsigned char*)"boolean"); rasqal_xsd_decimal_uri=raptor_new_uri_from_uri_local_name(rasqal_xsd_namespace_uri, (const unsigned char*)"decimal"); rasqal_xsd_datetime_uri=raptor_new_uri_from_uri_local_name(rasqal_xsd_namespace_uri, (const unsigned char*)"dateTime"); rasqal_xsd_string_uri=raptor_new_uri_from_uri_local_name(rasqal_xsd_namespace_uri, (const unsigned char*)"string"); rasqal_rdf_namespace_uri=raptor_new_uri(raptor_rdf_namespace_uri); rasqal_rdf_first_uri=raptor_new_uri_from_uri_local_name(rasqal_rdf_namespace_uri, (const unsigned char*)"first"); rasqal_rdf_rest_uri=raptor_new_uri_from_uri_local_name(rasqal_rdf_namespace_uri, (const unsigned char*)"rest"); rasqal_rdf_nil_uri=raptor_new_uri_from_uri_local_name(rasqal_rdf_namespace_uri, (const unsigned char*)"nil"); } void rasqal_uri_finish(void) { if(rasqal_xsd_integer_uri) raptor_free_uri(rasqal_xsd_integer_uri); if(rasqal_xsd_double_uri) raptor_free_uri(rasqal_xsd_double_uri); if(rasqal_xsd_float_uri) raptor_free_uri(rasqal_xsd_float_uri); if(rasqal_xsd_boolean_uri) raptor_free_uri(rasqal_xsd_boolean_uri); if(rasqal_xsd_decimal_uri) raptor_free_uri(rasqal_xsd_decimal_uri); if(rasqal_xsd_datetime_uri) raptor_free_uri(rasqal_xsd_datetime_uri); if(rasqal_xsd_string_uri) raptor_free_uri(rasqal_xsd_string_uri); if(rasqal_xsd_namespace_uri) raptor_free_uri(rasqal_xsd_namespace_uri); if(rasqal_rdf_first_uri) raptor_free_uri(rasqal_rdf_first_uri); if(rasqal_rdf_rest_uri) raptor_free_uri(rasqal_rdf_rest_uri); if(rasqal_rdf_nil_uri) raptor_free_uri(rasqal_rdf_nil_uri); if(rasqal_rdf_namespace_uri) raptor_free_uri(rasqal_rdf_namespace_uri); } /** * rasqal_query_set_default_generate_bnodeid_parameters - Set default bnodeid generation parameters * @rdf_query: #rasqal_query object * @prefix: prefix string * @base: integer base identifier * * Sets the parameters for the default algorithm used to generate * blank node IDs. The default algorithm uses both @prefix and @base * to generate a new identifier. The exact identifier generated is * not guaranteed to be a strict concatenation of @prefix and @base * but will use both parts. * * For finer control of the generated identifiers, use * rasqal_set_default_generate_bnodeid_handler() * * If prefix is NULL, the default prefix is used (currently "bnodeid") * If base is less than 1, it is initialised to 1. * **/ void rasqal_query_set_default_generate_bnodeid_parameters(rasqal_query* rdf_query, char *prefix, int base) { char *prefix_copy=NULL; size_t length=0; if(--base<0) base=0; if(prefix) { length=strlen(prefix); prefix_copy=(char*)RASQAL_MALLOC(cstring, length+1); if(!prefix_copy) return; strcpy(prefix_copy, prefix); } if(rdf_query->default_generate_bnodeid_handler_prefix) RASQAL_FREE(cstring, rdf_query->default_generate_bnodeid_handler_prefix); rdf_query->default_generate_bnodeid_handler_prefix=prefix_copy; rdf_query->default_generate_bnodeid_handler_prefix_length=length; rdf_query->default_generate_bnodeid_handler_base=base; } /** * rasqal_query_set_generate_bnodeid_handler: * @query: #rasqal_query query object * @user_data: user data pointer for callback * @handler: generate blank ID callback function * * Set the generate blank node ID handler function for the query. * * Sets the function to generate blank node IDs for the query. * The handler is called with a pointer to the rasqal_query, the * @user_data pointer and a user_bnodeid which is the value of * a user-provided blank node identifier (may be NULL). * It can either be returned directly as the generated value when present or * modified. The passed in value must be free()d if it is not used. * * If handler is NULL, the default method is used * **/ void rasqal_query_set_generate_bnodeid_handler(rasqal_query* query, void *user_data, rasqal_generate_bnodeid_handler handler) { query->generate_bnodeid_handler_user_data=user_data; query->generate_bnodeid_handler=handler; } static unsigned char* rasqal_default_generate_bnodeid_handler(void *user_data, unsigned char *user_bnodeid) { rasqal_query *rdf_query=(rasqal_query *)user_data; int id; unsigned char *buffer; int length; int tmpid; if(user_bnodeid) return user_bnodeid; id=++rdf_query->default_generate_bnodeid_handler_base; tmpid=id; length=2; /* min length 1 + \0 */ while(tmpid/=10) length++; if(rdf_query->default_generate_bnodeid_handler_prefix) length += rdf_query->default_generate_bnodeid_handler_prefix_length; else length += 7; /* bnodeid */ buffer=(unsigned char*)RASQAL_MALLOC(cstring, length); if(!buffer) return NULL; if(rdf_query->default_generate_bnodeid_handler_prefix) { strncpy((char*)buffer, rdf_query->default_generate_bnodeid_handler_prefix, rdf_query->default_generate_bnodeid_handler_prefix_length); sprintf((char*)buffer + rdf_query->default_generate_bnodeid_handler_prefix_length, "%d", id); } else sprintf((char*)buffer, "bnodeid%d", id); return buffer; } /* * rasqal_query_generate_bnodeid - Default generate id - internal */ unsigned char* rasqal_query_generate_bnodeid(rasqal_query* rdf_query, unsigned char *user_bnodeid) { if(rdf_query->generate_bnodeid_handler) return rdf_query->generate_bnodeid_handler(rdf_query, rdf_query->generate_bnodeid_handler_user_data, user_bnodeid); else return rasqal_default_generate_bnodeid_handler(rdf_query, user_bnodeid); } /** * rasqal_free_memory: * @ptr: memory pointer * * Free memory allocated inside rasqal. * * Some systems require memory allocated in a library to * be deallocated in that library. This function allows * memory allocated by rasqal to be freed. * **/ void rasqal_free_memory(void *ptr) { RASQAL_FREE(void, ptr); } /** * rasqal_alloc_memory: * @size: size of memory to allocate * * Allocate memory inside rasqal. * * Some systems require memory allocated in a library to * be deallocated in that library. This function allows * memory to be allocated inside the rasqal shared library * that can be freed inside rasqal either internally or via * rasqal_free_memory(). * * Return value: the address of the allocated memory or NULL on failure * **/ void* rasqal_alloc_memory(size_t size) { return RASQAL_MALLOC(void, size); } /** * rasqal_calloc_memory: * @nmemb: number of members * @size: size of item * * Allocate zeroed array of items inside rasqal. * * Some systems require memory allocated in a library to * be deallocated in that library. This function allows * memory to be allocated inside the rasqal shared library * that can be freed inside rasqal either internally or via * rasqal_free_memory(). * * Return value: the address of the allocated memory or NULL on failure * **/ void* rasqal_calloc_memory(size_t nmemb, size_t size) { return RASQAL_CALLOC(void, nmemb, size); } #if defined (RASQAL_DEBUG) && defined(RASQAL_MEMORY_SIGN) void* rasqal_sign_malloc(size_t size) { int *p; size += sizeof(int); p=(int*)malloc(size); *p++ = RASQAL_SIGN_KEY; return p; } void* rasqal_sign_calloc(size_t nmemb, size_t size) { int *p; /* turn into bytes */ size = nmemb*size + sizeof(int); p=(int*)calloc(1, size); *p++ = RASQAL_SIGN_KEY; return p; } void* rasqal_sign_realloc(void *ptr, size_t size) { int *p; if(!ptr) return rasqal_sign_malloc(size); p=(int*)ptr; p--; if(*p != RASQAL_SIGN_KEY) RASQAL_FATAL3("memory signature %08X != %08X", *p, RASQAL_SIGN_KEY); size += sizeof(int); p=(int*)realloc(p, size); *p++= RASQAL_SIGN_KEY; return p; } void rasqal_sign_free(void *ptr) { int *p; if(!ptr) return; p=(int*)ptr; p--; if(*p != RASQAL_SIGN_KEY) RASQAL_FATAL3("memory signature %08X != %08X", *p, RASQAL_SIGN_KEY); free(p); } #endif #if defined (RASQAL_DEBUG) && defined(HAVE_DMALLOC_H) && defined(RASQAL_MEMORY_DEBUG_DMALLOC) #undef malloc void* rasqal_system_malloc(size_t size) { return malloc(size); } #undef free void rasqal_system_free(void *ptr) { return free(ptr); } #endif