diff --git a/ChangeLog b/ChangeLog index 5e9bc8e9..8fa6975d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +Fri Sep 3 00:01:08 CEST 1999 Daniel Veillard + + * xmlmemory.[ch] Makefile.am :added a memory wrapper to chase + not deallocated memory blocks + * *.c : replaces all calls to malloc() free() and realloc() to + the wrapper functions/macros + * tree.c : removed memory leaks dues to calling xmlFreeNode() + instead of xmlFreeNodeList() + Wed Sep 1 14:15:09 CEST 1999 Daniel Veillard * HTMLparser.c: corrected a stupid bug leading to core dump at diff --git a/HTMLparser.c b/HTMLparser.c index d45b6cde..adfa2d99 100644 --- a/HTMLparser.c +++ b/HTMLparser.c @@ -27,6 +27,7 @@ #include #endif +#include "xmlmemory.h" #include "tree.h" #include "HTMLparser.h" #include "entities.h" @@ -54,7 +55,7 @@ int html##name##Push(htmlParserCtxtPtr ctxt, type value) { \ if (ctxt->name##Nr >= ctxt->name##Max) { \ ctxt->name##Max *= 2; \ - ctxt->name##Tab = (void *) realloc(ctxt->name##Tab, \ + ctxt->name##Tab = (void *) xmlRealloc(ctxt->name##Tab, \ ctxt->name##Max * sizeof(ctxt->name##Tab[0])); \ if (ctxt->name##Tab == NULL) { \ fprintf(stderr, "realloc failed !\n"); \ @@ -766,7 +767,7 @@ htmlEntityDesc html40EntitiesTable[] = { */ #define growBuffer(buffer) { \ buffer##_size *= 2; \ - buffer = (CHAR *) realloc(buffer, buffer##_size * sizeof(CHAR)); \ + buffer = (CHAR *) xmlRealloc(buffer, buffer##_size * sizeof(CHAR)); \ if (buffer == NULL) { \ perror("realloc failed"); \ exit(1); \ @@ -834,7 +835,7 @@ htmlDecodeEntities(htmlParserCtxtPtr ctxt, int len, * allocate a translation buffer. */ buffer_size = 1000; - buffer = (CHAR *) malloc(buffer_size * sizeof(CHAR)); + buffer = (CHAR *) xmlMalloc(buffer_size * sizeof(CHAR)); if (buffer == NULL) { perror("htmlDecodeEntities: malloc failed"); return(NULL); @@ -881,7 +882,7 @@ htmlDecodeEntities(htmlParserCtxtPtr ctxt, int len, } } nbchars += 2 + xmlStrlen(name); - free(name); + xmlFree(name); } } } else { @@ -1114,7 +1115,7 @@ htmlNewDoc(const CHAR *URI, const CHAR *ExternalID) { /* * Allocate a new document and fill the fields. */ - cur = (xmlDocPtr) malloc(sizeof(xmlDoc)); + cur = (xmlDocPtr) xmlMalloc(sizeof(xmlDoc)); if (cur == NULL) { fprintf(stderr, "xmlNewDoc : malloc failed\n"); return(NULL); @@ -1340,7 +1341,7 @@ htmlParseEntityRef(htmlParserCtxtPtr ctxt, CHAR **str) { ctxt->sax->characters(ctxt->userData, BAD_CAST "&", 1); ctxt->sax->characters(ctxt->userData, name, xmlStrlen(name)); } - free(name); + xmlFree(name); } } } @@ -1674,7 +1675,7 @@ htmlParseComment(htmlParserCtxtPtr ctxt, int create) { val = xmlStrndup(start, q - start); if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL)) ctxt->sax->comment(ctxt->userData, val); - free(val); + xmlFree(val); } } } @@ -1817,9 +1818,9 @@ htmlParseDocTypeDecl(htmlParserCtxtPtr ctxt) { /* * Cleanup, since we don't use all those identifiers */ - if (URI != NULL) free(URI); - if (ExternalID != NULL) free(ExternalID); - if (name != NULL) free(name); + if (URI != NULL) xmlFree(URI); + if (ExternalID != NULL) xmlFree(ExternalID); + if (name != NULL) xmlFree(name); } /** @@ -1945,8 +1946,8 @@ htmlParseStartTag(htmlParserCtxtPtr ctxt) { ctxt->sax->error(ctxt->userData, "Attribute %s redefined\n", name); ctxt->wellFormed = 0; - free(attname); - free(attvalue); + xmlFree(attname); + xmlFree(attvalue); break; } } @@ -1956,7 +1957,7 @@ htmlParseStartTag(htmlParserCtxtPtr ctxt) { */ if (atts == NULL) { maxatts = 10; - atts = (const CHAR **) malloc(maxatts * sizeof(CHAR *)); + atts = (const CHAR **) xmlMalloc(maxatts * sizeof(CHAR *)); if (atts == NULL) { fprintf(stderr, "malloc of %ld byte failed\n", maxatts * (long)sizeof(CHAR *)); @@ -1964,7 +1965,7 @@ htmlParseStartTag(htmlParserCtxtPtr ctxt) { } } else if (nbatts + 2 < maxatts) { maxatts *= 2; - atts = (const CHAR **) realloc(atts, maxatts * sizeof(CHAR *)); + atts = (const CHAR **) xmlRealloc(atts, maxatts * sizeof(CHAR *)); if (atts == NULL) { fprintf(stderr, "realloc of %ld byte failed\n", maxatts * (long)sizeof(CHAR *)); @@ -1994,8 +1995,8 @@ htmlParseStartTag(htmlParserCtxtPtr ctxt) { ctxt->sax->startElement(ctxt->userData, name, atts); if (atts != NULL) { - for (i = 0;i < nbatts;i++) free((CHAR *) atts[i]); - free(atts); + for (i = 0;i < nbatts;i++) xmlFree((CHAR *) atts[i]); + xmlFree(atts); } return(name); } @@ -2054,7 +2055,7 @@ htmlParseEndTag(htmlParserCtxtPtr ctxt, const CHAR *tagname) { ctxt->sax->error(ctxt->userData, "htmlParseEndTag: unexpected close for tag %s\n", tagname); - free(name); + xmlFree(name); ctxt->wellFormed = 0; return; } @@ -2087,7 +2088,7 @@ htmlParseEndTag(htmlParserCtxtPtr ctxt, const CHAR *tagname) { ctxt->sax->endElement(ctxt->userData, name); if (name != NULL) - free(name); + xmlFree(name); return; } @@ -2132,7 +2133,7 @@ htmlParseReference(htmlParserCtxtPtr ctxt) { if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL)) ctxt->sax->characters(ctxt->userData, out, 1); } - free(name); + xmlFree(name); } } @@ -2261,7 +2262,7 @@ htmlParseElement(htmlParserCtxtPtr ctxt) { SKIP(2); if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL)) ctxt->sax->endElement(ctxt->userData, name); - free(name); + xmlFree(name); return; } @@ -2277,7 +2278,7 @@ htmlParseElement(htmlParserCtxtPtr ctxt) { * end of parsing of this node. */ nodePop(ctxt); - free(name); + xmlFree(name); /* * Capture end position and add node @@ -2298,7 +2299,7 @@ htmlParseElement(htmlParserCtxtPtr ctxt) { if ((info != NULL) && (info->empty)) { if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL)) ctxt->sax->endElement(ctxt->userData, name); - free(name); + xmlFree(name); return; } @@ -2313,7 +2314,7 @@ htmlParseElement(htmlParserCtxtPtr ctxt) { * on start tag */ if (currentNode != ctxt->node) { - free(name); + xmlFree(name); return; } @@ -2327,11 +2328,11 @@ htmlParseElement(htmlParserCtxtPtr ctxt) { * end of parsing of this node. */ nodePop(ctxt); - free(name); + xmlFree(name); return; } - free(name); + xmlFree(name); /* * Capture end position and add node @@ -2439,13 +2440,13 @@ htmlInitParserCtxt(htmlParserCtxtPtr ctxt) { htmlSAXHandler *sax; - sax = (htmlSAXHandler *) malloc(sizeof(htmlSAXHandler)); + sax = (htmlSAXHandler *) xmlMalloc(sizeof(htmlSAXHandler)); if (sax == NULL) { fprintf(stderr, "htmlInitParserCtxt: out of memory\n"); } /* Allocate the Input stack */ - ctxt->inputTab = (htmlParserInputPtr *) malloc(5 * sizeof(htmlParserInputPtr)); + ctxt->inputTab = (htmlParserInputPtr *) xmlMalloc(5 * sizeof(htmlParserInputPtr)); ctxt->inputNr = 0; ctxt->inputMax = 5; ctxt->input = NULL; @@ -2454,7 +2455,7 @@ htmlInitParserCtxt(htmlParserCtxtPtr ctxt) ctxt->standalone = -1; /* Allocate the Node stack */ - ctxt->nodeTab = (htmlNodePtr *) malloc(10 * sizeof(htmlNodePtr)); + ctxt->nodeTab = (htmlNodePtr *) xmlMalloc(10 * sizeof(htmlNodePtr)); ctxt->nodeNr = 0; ctxt->nodeMax = 10; ctxt->node = NULL; @@ -2492,12 +2493,12 @@ htmlFreeParserCtxt(htmlParserCtxtPtr ctxt) xmlFreeInputStream(input); } - if (ctxt->nodeTab != NULL) free(ctxt->nodeTab); - if (ctxt->inputTab != NULL) free(ctxt->inputTab); - if (ctxt->version != NULL) free((char *) ctxt->version); + if (ctxt->nodeTab != NULL) xmlFree(ctxt->nodeTab); + if (ctxt->inputTab != NULL) xmlFree(ctxt->inputTab); + if (ctxt->version != NULL) xmlFree((char *) ctxt->version); if ((ctxt->sax != NULL) && (ctxt->sax != &htmlDefaultSAXHandler)) - free(ctxt->sax); - free(ctxt); + xmlFree(ctxt->sax); + xmlFree(ctxt); } /** @@ -2515,16 +2516,16 @@ htmlCreateDocParserCtxt(CHAR *cur, const char *encoding) { htmlParserInputPtr input; /* htmlCharEncoding enc; */ - ctxt = (htmlParserCtxtPtr) malloc(sizeof(htmlParserCtxt)); + ctxt = (htmlParserCtxtPtr) xmlMalloc(sizeof(htmlParserCtxt)); if (ctxt == NULL) { perror("malloc"); return(NULL); } htmlInitParserCtxt(ctxt); - input = (htmlParserInputPtr) malloc(sizeof(htmlParserInput)); + input = (htmlParserInputPtr) xmlMalloc(sizeof(htmlParserInput)); if (input == NULL) { perror("malloc"); - free(ctxt); + xmlFree(ctxt); return(NULL); } @@ -2632,20 +2633,20 @@ htmlCreateFileParserCtxt(const char *filename, const char *encoding) buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE); if (buf == NULL) return(NULL); - ctxt = (htmlParserCtxtPtr) malloc(sizeof(htmlParserCtxt)); + ctxt = (htmlParserCtxtPtr) xmlMalloc(sizeof(htmlParserCtxt)); if (ctxt == NULL) { perror("malloc"); return(NULL); } htmlInitParserCtxt(ctxt); - inputStream = (htmlParserInputPtr) malloc(sizeof(htmlParserInput)); + inputStream = (htmlParserInputPtr) xmlMalloc(sizeof(htmlParserInput)); if (inputStream == NULL) { perror("malloc"); - free(ctxt); + xmlFree(ctxt); return(NULL); } - inputStream->filename = strdup(filename); + inputStream->filename = xmlMemStrdup(filename); inputStream->line = 1; inputStream->col = 1; inputStream->buf = buf; diff --git a/HTMLtree.c b/HTMLtree.c index 2a05b3ed..87363ec4 100644 --- a/HTMLtree.c +++ b/HTMLtree.c @@ -12,6 +12,7 @@ #include #include /* for memset() only ! */ +#include "xmlmemory.h" #include "HTMLparser.h" #include "HTMLtree.h" #include "entities.h" @@ -70,7 +71,7 @@ htmlAttrDump(xmlBufferPtr buf, xmlDocPtr doc, xmlAttrPtr cur) { if (value) { xmlBufferWriteChar(buf, "="); xmlBufferWriteQuotedString(buf, value); - free(value); + xmlFree(value); } else { xmlBufferWriteChar(buf, "=\"\""); } @@ -146,7 +147,7 @@ htmlNodeDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur) { buffer = xmlEncodeEntitiesReentrant(doc, cur->content); if (buffer != NULL) { xmlBufferWriteCHAR(buf, buffer); - free(buffer); + xmlFree(buffer); } } return; @@ -207,7 +208,7 @@ htmlNodeDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur) { buffer = xmlEncodeEntitiesReentrant(doc, cur->content); if (buffer != NULL) { xmlBufferWriteCHAR(buf, buffer); - free(buffer); + xmlFree(buffer); } } if (cur->childs != NULL) { @@ -277,7 +278,7 @@ htmlDocDumpMemory(xmlDocPtr cur, CHAR**mem, int *size) { *mem = buf->content; *size = buf->use; memset(buf, -1, sizeof(xmlBuffer)); - free(buf); + xmlFree(buf); } diff --git a/Makefile.am b/Makefile.am index 36fde35d..c9f228d6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -26,6 +26,7 @@ libxml_la_SOURCES = \ tree.c \ xpath.c \ xmlIO.c \ + xmlmemory.c \ valid.c xmlincdir = $(includedir)/gnome-xml @@ -41,6 +42,7 @@ xmlinc_HEADERS = \ tree.h \ xpath.h \ xmlIO.h \ + xmlmemory.h \ valid.h DEPS = $(top_builddir)/libxml.la diff --git a/SAX.c b/SAX.c index 60e6ff85..57443edf 100644 --- a/SAX.c +++ b/SAX.c @@ -8,6 +8,7 @@ #include #include +#include "xmlmemory.h" #include "tree.h" #include "parser.h" #include "parserInternals.h" @@ -536,16 +537,16 @@ attribute(void *ctx, const CHAR *fullname, const CHAR *value) /* a default namespace definition */ xmlNewNs(ctxt->node, value, NULL); if (name != NULL) - free(name); + xmlFree(name); return; } if ((ns != NULL) && (ns[0] == 'x') && (ns[1] == 'm') && (ns[2] == 'l') && (ns[3] == 'n') && (ns[4] == 's') && (ns[5] == 0)) { /* a standard namespace definition */ xmlNewNs(ctxt->node, value, name); - free(ns); + xmlFree(ns); if (name != NULL) - free(name); + xmlFree(name); return; } @@ -574,9 +575,9 @@ attribute(void *ctx, const CHAR *fullname, const CHAR *value) } if (name != NULL) - free(name); + xmlFree(name); if (ns != NULL) - free(ns); + xmlFree(ns); } /** @@ -697,9 +698,9 @@ startElement(void *ctx, const CHAR *fullname, const CHAR **atts) xmlSetNs(ret, ns); if (prefix != NULL) - free(prefix); + xmlFree(prefix); if (name != NULL) - free(name); + xmlFree(name); } diff --git a/encoding.c b/encoding.c index 3d65469e..e72577ed 100644 --- a/encoding.c +++ b/encoding.c @@ -23,13 +23,11 @@ #include #include #include -#ifdef HAVE_MALLOC_H -#include -#endif #include "encoding.h" #ifdef HAVE_UNICODE_H #include #endif +#include "xmlmemory.h" #ifdef HAVE_UNICODE_H @@ -374,7 +372,7 @@ xmlNewCharEncodingHandler(const char *name, xmlCharEncodingInputFunc input, if (upper[i] == 0) break; } upper[i] = 0; - up = strdup(upper); + up = xmlMemStrdup(upper); if (up == NULL) { fprintf(stderr, "xmlNewCharEncodingHandler : out of memory !\n"); return(NULL); @@ -384,7 +382,7 @@ xmlNewCharEncodingHandler(const char *name, xmlCharEncodingInputFunc input, * allocate and fill-up an handler block. */ handler = (xmlCharEncodingHandlerPtr) - malloc(sizeof(xmlCharEncodingHandler)); + xmlMalloc(sizeof(xmlCharEncodingHandler)); if (handler == NULL) { fprintf(stderr, "xmlNewCharEncodingHandler : out of memory !\n"); return(NULL); @@ -413,7 +411,7 @@ xmlInitCharEncodingHandlers(void) { if (handlers != NULL) return; handlers = (xmlCharEncodingHandlerPtr *) - malloc(MAX_ENCODING_HANDLERS * sizeof(xmlCharEncodingHandlerPtr)); + xmlMalloc(MAX_ENCODING_HANDLERS * sizeof(xmlCharEncodingHandlerPtr)); if (handlers == NULL) { fprintf(stderr, "xmlInitCharEncodingHandlers : out of memory !\n"); diff --git a/entities.c b/entities.c index 54be393d..24c770c0 100644 --- a/entities.c +++ b/entities.c @@ -9,6 +9,7 @@ #include #include #include +#include "xmlmemory.h" #include "entities.h" /* @@ -36,15 +37,15 @@ void xmlFreeEntity(xmlEntityPtr entity) { if (entity == NULL) return; if (entity->name != NULL) - free((char *) entity->name); + xmlFree((char *) entity->name); if (entity->ExternalID != NULL) - free((char *) entity->ExternalID); + xmlFree((char *) entity->ExternalID); if (entity->SystemID != NULL) - free((char *) entity->SystemID); + xmlFree((char *) entity->SystemID); if (entity->content != NULL) - free((char *) entity->content); + xmlFree((char *) entity->content); if (entity->orig != NULL) - free((char *) entity->orig); + xmlFree((char *) entity->orig); memset(entity, -1, sizeof(xmlEntity)); } @@ -85,7 +86,7 @@ xmlAddEntity(xmlEntitiesTablePtr table, const CHAR *name, int type, */ table->max_entities *= 2; table->table = (xmlEntityPtr) - realloc(table->table, table->max_entities * sizeof(xmlEntity)); + xmlRealloc(table->table, table->max_entities * sizeof(xmlEntity)); if (table->table == NULL) { perror("realloc failed"); return; @@ -365,7 +366,7 @@ static CHAR *buffer = NULL; void growBuffer(void) { buffer_size *= 2; - buffer = (CHAR *) realloc(buffer, buffer_size * sizeof(CHAR)); + buffer = (CHAR *) xmlRealloc(buffer, buffer_size * sizeof(CHAR)); if (buffer == NULL) { perror("realloc failed"); exit(1); @@ -404,7 +405,7 @@ xmlEncodeEntities(xmlDocPtr doc, const CHAR *input) { if (input == NULL) return(NULL); if (buffer == NULL) { buffer_size = 1000; - buffer = (CHAR *) malloc(buffer_size * sizeof(CHAR)); + buffer = (CHAR *) xmlMalloc(buffer_size * sizeof(CHAR)); if (buffer == NULL) { perror("malloc failed"); exit(1); @@ -500,7 +501,7 @@ xmlEncodeEntities(xmlDocPtr doc, const CHAR *input) { */ #define growBufferReentrant() { \ buffer_size *= 2; \ - buffer = (CHAR *) realloc(buffer, buffer_size * sizeof(CHAR)); \ + buffer = (CHAR *) xmlRealloc(buffer, buffer_size * sizeof(CHAR)); \ if (buffer == NULL) { \ perror("realloc failed"); \ exit(1); \ @@ -536,7 +537,7 @@ xmlEncodeEntitiesReentrant(xmlDocPtr doc, const CHAR *input) { * allocate an translation buffer. */ buffer_size = 1000; - buffer = (CHAR *) malloc(buffer_size * sizeof(CHAR)); + buffer = (CHAR *) xmlMalloc(buffer_size * sizeof(CHAR)); if (buffer == NULL) { perror("malloc failed"); exit(1); @@ -639,20 +640,20 @@ xmlCreateEntitiesTable(void) { xmlEntitiesTablePtr ret; ret = (xmlEntitiesTablePtr) - malloc(sizeof(xmlEntitiesTable)); + xmlMalloc(sizeof(xmlEntitiesTable)); if (ret == NULL) { - fprintf(stderr, "xmlCreateEntitiesTable : malloc(%ld) failed\n", + fprintf(stderr, "xmlCreateEntitiesTable : xmlMalloc(%ld) failed\n", (long)sizeof(xmlEntitiesTable)); return(NULL); } ret->max_entities = XML_MIN_ENTITIES_TABLE; ret->nb_entities = 0; ret->table = (xmlEntityPtr ) - malloc(ret->max_entities * sizeof(xmlEntity)); + xmlMalloc(ret->max_entities * sizeof(xmlEntity)); if (ret == NULL) { - fprintf(stderr, "xmlCreateEntitiesTable : malloc(%ld) failed\n", + fprintf(stderr, "xmlCreateEntitiesTable : xmlMalloc(%ld) failed\n", ret->max_entities * (long)sizeof(xmlEntity)); - free(ret); + xmlFree(ret); return(NULL); } return(ret); @@ -673,8 +674,8 @@ xmlFreeEntitiesTable(xmlEntitiesTablePtr table) { for (i = 0;i < table->nb_entities;i++) { xmlFreeEntity(&table->table[i]); } - free(table->table); - free(table); + xmlFree(table->table); + xmlFree(table); } /** @@ -691,16 +692,16 @@ xmlCopyEntitiesTable(xmlEntitiesTablePtr table) { xmlEntityPtr cur, ent; int i; - ret = (xmlEntitiesTablePtr) malloc(sizeof(xmlEntitiesTable)); + ret = (xmlEntitiesTablePtr) xmlMalloc(sizeof(xmlEntitiesTable)); if (ret == NULL) { fprintf(stderr, "xmlCopyEntitiesTable: out of memory !\n"); return(NULL); } - ret->table = (xmlEntityPtr) malloc(table->max_entities * + ret->table = (xmlEntityPtr) xmlMalloc(table->max_entities * sizeof(xmlEntity)); if (ret->table == NULL) { fprintf(stderr, "xmlCopyEntitiesTable: out of memory !\n"); - free(ret); + xmlFree(ret); return(NULL); } ret->max_entities = table->max_entities; diff --git a/include/libxml/parser.h b/include/libxml/parser.h index 34a65f1c..aab35530 100644 --- a/include/libxml/parser.h +++ b/include/libxml/parser.h @@ -238,7 +238,8 @@ typedef struct xmlSAXHandler { typedef xmlSAXHandler *xmlSAXHandlerPtr; /** - * Global variables: just the default SAX interface tables and XML version infos. + * Global variables: just the default SAX interface tables and XML + * version infos. */ extern const char *xmlParserVersion; @@ -246,6 +247,13 @@ extern xmlSAXLocator xmlDefaultSAXLocator; extern xmlSAXHandler xmlDefaultSAXHandler; extern xmlSAXHandler htmlDefaultSAXHandler; +/** + * entity substitution default behaviour. + */ + +extern int xmlSubstituteEntitiesDefaultValue; + + #include "entities.h" #include "xml-error.h" diff --git a/include/libxml/parserInternals.h b/include/libxml/parserInternals.h index 413c26c6..13ea1362 100644 --- a/include/libxml/parserInternals.h +++ b/include/libxml/parserInternals.h @@ -508,12 +508,6 @@ typedef unsigned char CHARVAL; #define MOVETO_STARTTAG(p) \ while (IS_CHAR(*p) && (*(p) != '<')) (p)++ -/** - * entity substitution default behaviour. - */ - -int xmlSubstituteEntitiesDefaultValue; - /** * Parser context */ diff --git a/include/libxml/xmlmemory.h b/include/libxml/xmlmemory.h new file mode 100644 index 00000000..d28b526c --- /dev/null +++ b/include/libxml/xmlmemory.h @@ -0,0 +1,66 @@ +/* + * memory.h: interface for the memory allocation debug. + * + * Daniel.Veillard@w3.org + */ + + +#ifndef _DEBUG_MEMORY_ALLOC_ +#define _DEBUG_MEMORY_ALLOC_ + +#define NO_DEBUG_MEMORY + +#ifdef NO_DEBUG_MEMORY +#ifdef HAVE_MALLOC_H +#include +#endif + +#define xmlFree(x) free((x)) +#define xmlMalloc(x) malloc(x) +#define xmlRealloc(p, x) realloc((p), (x)) +#define xmlMemStrdup(x) strdup((x)) +#define xmlInitMemory() +#define xmlMemUsed() +#define xmlInitMemory() +#define xmlMemoryDump() +#define xmlMemDisplay(x) + +#else /* ! NO_DEBUG_MEMORY */ +#include + +/* #define DEBUG_MEMORY */ /* */ + +#define DEBUG_MEMORY_LOCATION + +#ifdef DEBUG +#ifndef DEBUG_MEMORY +#define DEBUG_MEMORY +#endif +#endif + +#define MEM_LIST /* keep a list of all the allocated memory blocks */ + +int xmlInitMemory (void); +void * xmlMalloc (int size); +void * xmlRealloc (void *ptr, + int size); +void xmlFree (void *ptr); +char * xmlMemStrdup (const char *str); +int xmlMemUsed (void); +void xmlMemDisplay (FILE *fp); +void xmlMemoryDump (void); +int xmlInitMemory (void); + +#ifdef DEBUG_MEMORY_LOCATION +#define xmlMalloc(x) xmlMallocLoc((x), __FILE__, __LINE__) +#define xmlRealloc(p, x) xmlReallocLoc((p), (x), __FILE__, __LINE__) +#define xmlMemStrdup(x) xmlMemStrdupLoc((x), __FILE__, __LINE__) + +extern void * xmlMallocLoc(int size, const char *file, int line); +extern void * xmlReallocLoc(void *ptr,int size, const char *file, int line); +extern char * xmlMemStrdupLoc(const char *str, const char *file, int line); +#endif /* DEBUG_MEMORY_LOCATION */ +#endif /* ! NO_DEBUG_MEMORY */ + +#endif /* _DEBUG_MEMORY_ALLOC_ */ + diff --git a/parser.c b/parser.c index 0a0b3965..0f3e7cfa 100644 --- a/parser.c +++ b/parser.c @@ -27,6 +27,7 @@ #include #endif +#include "xmlmemory.h" #include "tree.h" #include "parser.h" #include "entities.h" @@ -235,7 +236,7 @@ int xmlDoValidityCheckingDefaultValue = 0; extern int name##Push(xmlParserCtxtPtr ctxt, type value) { \ if (ctxt->name##Nr >= ctxt->name##Max) { \ ctxt->name##Max *= 2; \ - ctxt->name##Tab = (void *) realloc(ctxt->name##Tab, \ + ctxt->name##Tab = (void *) xmlRealloc(ctxt->name##Tab, \ ctxt->name##Max * sizeof(ctxt->name##Tab[0])); \ if (ctxt->name##Tab == NULL) { \ fprintf(stderr, "realloc failed !\n"); \ @@ -378,14 +379,14 @@ void xmlFreeInputStream(xmlParserInputPtr input) { if (input == NULL) return; - if (input->filename != NULL) free((char *) input->filename); - if (input->directory != NULL) free((char *) input->directory); + if (input->filename != NULL) xmlFree((char *) input->filename); + if (input->directory != NULL) xmlFree((char *) input->directory); if ((input->free != NULL) && (input->base != NULL)) input->free((CHAR *) input->base); if (input->buf != NULL) xmlFreeParserInputBuffer(input->buf); memset(input, -1, sizeof(xmlParserInput)); - free(input); + xmlFree(input); } /** @@ -399,7 +400,7 @@ xmlParserInputPtr xmlNewInputStream(xmlParserCtxtPtr ctxt) { xmlParserInputPtr input; - input = (xmlParserInputPtr) malloc(sizeof(xmlParserInput)); + input = (xmlParserInputPtr) xmlMalloc(sizeof(xmlParserInput)); if (input == NULL) { if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) ctxt->sax->error(ctxt->userData, "malloc: couldn't allocate a new input stream\n"); @@ -532,7 +533,7 @@ xmlNewInputFromFile(xmlParserCtxtPtr ctxt, const char *filename) { buf = xmlParserInputBufferCreateFilename(name, XML_CHAR_ENCODING_NONE); if (buf != NULL) - directory = strdup(ctxt->input->directory); + directory = xmlMemStrdup(ctxt->input->directory); } if ((buf == NULL) && (ctxt->directory != NULL)) { #ifdef WIN32 @@ -543,7 +544,7 @@ xmlNewInputFromFile(xmlParserCtxtPtr ctxt, const char *filename) { buf = xmlParserInputBufferCreateFilename(name, XML_CHAR_ENCODING_NONE); if (buf != NULL) - directory = strdup(ctxt->directory); + directory = xmlMemStrdup(ctxt->directory); } if (buf == NULL) return(NULL); @@ -553,11 +554,11 @@ xmlNewInputFromFile(xmlParserCtxtPtr ctxt, const char *filename) { inputStream = xmlNewInputStream(ctxt); if (inputStream == NULL) { - if (directory != NULL) free((char *) directory); + if (directory != NULL) xmlFree((char *) directory); return(NULL); } - inputStream->filename = strdup(filename); + inputStream->filename = xmlMemStrdup(filename); inputStream->directory = directory; inputStream->buf = buf; @@ -586,13 +587,13 @@ xmlInitParserCtxt(xmlParserCtxtPtr ctxt) { xmlSAXHandler *sax; - sax = (xmlSAXHandler *) malloc(sizeof(xmlSAXHandler)); + sax = (xmlSAXHandler *) xmlMalloc(sizeof(xmlSAXHandler)); if (sax == NULL) { fprintf(stderr, "xmlInitParserCtxt: out of memory\n"); } /* Allocate the Input stack */ - ctxt->inputTab = (xmlParserInputPtr *) malloc(5 * sizeof(xmlParserInputPtr)); + ctxt->inputTab = (xmlParserInputPtr *) xmlMalloc(5 * sizeof(xmlParserInputPtr)); ctxt->inputNr = 0; ctxt->inputMax = 5; ctxt->input = NULL; @@ -608,7 +609,7 @@ xmlInitParserCtxt(xmlParserCtxtPtr ctxt) ctxt->directory = NULL; /* Allocate the Node stack */ - ctxt->nodeTab = (xmlNodePtr *) malloc(10 * sizeof(xmlNodePtr)); + ctxt->nodeTab = (xmlNodePtr *) xmlMalloc(10 * sizeof(xmlNodePtr)); ctxt->nodeNr = 0; ctxt->nodeMax = 10; ctxt->node = NULL; @@ -650,14 +651,14 @@ xmlFreeParserCtxt(xmlParserCtxtPtr ctxt) xmlFreeInputStream(input); } - if (ctxt->nodeTab != NULL) free(ctxt->nodeTab); - if (ctxt->inputTab != NULL) free(ctxt->inputTab); - if (ctxt->version != NULL) free((char *) ctxt->version); - if (ctxt->encoding != NULL) free((char *) ctxt->encoding); + if (ctxt->nodeTab != NULL) xmlFree(ctxt->nodeTab); + if (ctxt->inputTab != NULL) xmlFree(ctxt->inputTab); + if (ctxt->version != NULL) xmlFree((char *) ctxt->version); + if (ctxt->encoding != NULL) xmlFree((char *) ctxt->encoding); if ((ctxt->sax != NULL) && (ctxt->sax != &xmlDefaultSAXHandler)) - free(ctxt->sax); - if (ctxt->directory != NULL) free((char *) ctxt->directory); - free(ctxt); + xmlFree(ctxt->sax); + if (ctxt->directory != NULL) xmlFree((char *) ctxt->directory); + xmlFree(ctxt); } /** @@ -673,7 +674,7 @@ xmlNewParserCtxt() { xmlParserCtxtPtr ctxt; - ctxt = (xmlParserCtxtPtr) malloc(sizeof(xmlParserCtxt)); + ctxt = (xmlParserCtxtPtr) xmlMalloc(sizeof(xmlParserCtxt)); if (ctxt == NULL) { fprintf(stderr, "xmlNewParserCtxt : cannot allocate context\n"); perror("malloc"); @@ -942,7 +943,7 @@ xmlParserHandleReference(xmlParserCtxtPtr ctxt) { "Entity reference: ';' expected\n"); ctxt->wellFormed = 0; ctxt->token = '&'; - free(name); + xmlFree(name); return; } SKIP(xmlStrlen(name) + 1); @@ -965,7 +966,7 @@ xmlParserHandleReference(xmlParserCtxtPtr ctxt) { "Entity reference: entity %s not declared\n", name); ctxt->wellFormed = 0; - free(name); + xmlFree(name); return; } @@ -982,12 +983,12 @@ xmlParserHandleReference(xmlParserCtxtPtr ctxt) { if (ent->type == XML_INTERNAL_PREDEFINED_ENTITY) { ctxt->token = ent->content[0]; - free(name); + xmlFree(name); return; } input = xmlNewEntityInputStream(ctxt, ent); xmlPushInput(ctxt, input); - free(name); + xmlFree(name); return; } @@ -1143,7 +1144,7 @@ xmlParserHandlePEReference(xmlParserCtxtPtr ctxt) { "xmlHandlePEReference: expecting ';'\n"); ctxt->wellFormed = 0; } - free(name); + xmlFree(name); } } @@ -1152,7 +1153,7 @@ xmlParserHandlePEReference(xmlParserCtxtPtr ctxt) { */ #define growBuffer(buffer) { \ buffer##_size *= 2; \ - buffer = (CHAR *) realloc(buffer, buffer##_size * sizeof(CHAR)); \ + buffer = (CHAR *) xmlRealloc(buffer, buffer##_size * sizeof(CHAR)); \ if (buffer == NULL) { \ perror("realloc failed"); \ exit(1); \ @@ -1192,7 +1193,7 @@ xmlDecodeEntities(xmlParserCtxtPtr ctxt, int len, int what, * allocate a translation buffer. */ buffer_size = 1000; - buffer = (CHAR *) malloc(buffer_size * sizeof(CHAR)); + buffer = (CHAR *) xmlMalloc(buffer_size * sizeof(CHAR)); if (buffer == NULL) { perror("xmlDecodeEntities: malloc failed"); return(NULL); @@ -1428,7 +1429,7 @@ xmlSwitchEncoding(xmlParserCtxtPtr ctxt, xmlCharEncoding enc) */ CHAR * xmlStrndup(const CHAR *cur, int len) { - CHAR *ret = malloc((len + 1) * sizeof(CHAR)); + CHAR *ret = xmlMalloc((len + 1) * sizeof(CHAR)); if (ret == NULL) { fprintf(stderr, "malloc of %ld byte failed\n", @@ -1469,7 +1470,7 @@ xmlStrdup(const CHAR *cur) { CHAR * xmlCharStrndup(const char *cur, int len) { int i; - CHAR *ret = malloc((len + 1) * sizeof(CHAR)); + CHAR *ret = xmlMalloc((len + 1) * sizeof(CHAR)); if (ret == NULL) { fprintf(stderr, "malloc of %ld byte failed\n", @@ -1663,7 +1664,7 @@ xmlStrncat(CHAR *cur, const CHAR *add, int len) { return(xmlStrndup(add, len)); size = xmlStrlen(cur); - ret = realloc(cur, (size + len + 1) * sizeof(CHAR)); + ret = xmlRealloc(cur, (size + len + 1) * sizeof(CHAR)); if (ret == NULL) { fprintf(stderr, "xmlStrncat: realloc of %ld byte failed\n", (size + len + 1) * (long)sizeof(CHAR)); @@ -2106,8 +2107,8 @@ xmlParseNamespace(xmlParserCtxtPtr ctxt) { ctxt->sax->globalNamespace(ctxt->userData, href, prefix); */ - if (prefix != NULL) free(prefix); - if (href != NULL) free(href); + if (prefix != NULL) xmlFree(prefix); + if (href != NULL) xmlFree(href); } /************************************************************************ @@ -2324,12 +2325,12 @@ xmlParseEntityValue(xmlParserCtxtPtr ctxt, CHAR **orig) { break; } if ((temp[0] == 0) && (tst == CUR_PTR)) { - free((char *)temp); + xmlFree((char *)temp); ret = xmlStrndup((CHAR *) "", 0); break; } ret = xmlStrcat(ret, temp); - if (temp != NULL) free((char *)temp); + if (temp != NULL) xmlFree((char *)temp); GROW; } if (CUR != '"') { @@ -2383,12 +2384,12 @@ xmlParseEntityValue(xmlParserCtxtPtr ctxt, CHAR **orig) { break; } if ((temp[0] == 0) && (tst == CUR_PTR)) { - free((char *)temp); + xmlFree((char *)temp); ret = xmlStrndup((CHAR *) "", 0); break; } ret = xmlStrcat(ret, temp); - if (temp != NULL) free((char *)temp); + if (temp != NULL) xmlFree((char *)temp); GROW; } if (CUR != '\'') { @@ -2794,7 +2795,7 @@ xmlParseComment(xmlParserCtxtPtr ctxt) { val = xmlStrndup(start, q - start); if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL)) ctxt->sax->comment(ctxt->userData, val); - free(val); + xmlFree(val); } } @@ -2884,9 +2885,9 @@ xmlParsePI(xmlParserCtxtPtr ctxt) { (ctxt->sax->processingInstruction != NULL)) ctxt->sax->processingInstruction(ctxt->userData, target, data); - free(data); + xmlFree(data); } - free(target); + xmlFree(target); } else { if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) ctxt->sax->error(ctxt->userData, @@ -2965,9 +2966,9 @@ xmlParseNotationDecl(xmlParserCtxtPtr ctxt) { "'>' required to close NOTATION declaration\n"); ctxt->wellFormed = 0; } - free(name); - if (Systemid != NULL) free(Systemid); - if (Pubid != NULL) free(Pubid); + xmlFree(name); + if (Systemid != NULL) xmlFree(Systemid); + if (Pubid != NULL) xmlFree(Pubid); } } @@ -3129,17 +3130,17 @@ xmlParseEntityDecl(xmlParserCtxtPtr ctxt) { } if (cur != NULL) { if (cur->orig != NULL) - free(orig); + xmlFree(orig); else cur->orig = orig; } else - free(orig); + xmlFree(orig); } - if (name != NULL) free(name); - if (value != NULL) free(value); - if (URI != NULL) free(URI); - if (literal != NULL) free(literal); - if (ndata != NULL) free(ndata); + if (name != NULL) xmlFree(name); + if (value != NULL) xmlFree(value); + if (URI != NULL) xmlFree(URI); + if (literal != NULL) xmlFree(literal); + if (ndata != NULL) xmlFree(ndata); } } @@ -3259,7 +3260,7 @@ xmlParseNotationType(xmlParserCtxtPtr ctxt) { return(ret); } cur = xmlCreateEnumeration(name); - free(name); + xmlFree(name); if (cur == NULL) return(ret); if (last == NULL) ret = last = cur; else { @@ -3319,7 +3320,7 @@ xmlParseEnumerationType(xmlParserCtxtPtr ctxt) { return(ret); } cur = xmlCreateEnumeration(name); - free(name); + xmlFree(name); if (cur == NULL) return(ret); if (last == NULL) ret = last = cur; else { @@ -3568,15 +3569,15 @@ xmlParseAttributeListDecl(xmlParserCtxtPtr ctxt) { ctxt->sax->attributeDecl(ctxt->userData, elemName, attrName, type, def, defaultValue, tree); if (attrName != NULL) - free(attrName); + xmlFree(attrName); if (defaultValue != NULL) - free(defaultValue); + xmlFree(defaultValue); GROW; } if (CUR == '>') NEXT; - free(elemName); + xmlFree(elemName); } } @@ -3633,7 +3634,7 @@ xmlParseElementMixedContentDecl(xmlParserCtxtPtr ctxt) { n->c1 = xmlNewElementContent(elem, XML_ELEMENT_CONTENT_ELEMENT); cur->c2 = n; cur = n; - free(elem); + xmlFree(elem); } SKIP_BLANKS; elem = xmlParseName(ctxt); @@ -3652,12 +3653,12 @@ xmlParseElementMixedContentDecl(xmlParserCtxtPtr ctxt) { if (elem != NULL) { cur->c2 = xmlNewElementContent(elem, XML_ELEMENT_CONTENT_ELEMENT); - free(elem); + xmlFree(elem); } ret->ocur = XML_ELEMENT_CONTENT_MULT; SKIP(2); } else { - if (elem != NULL) free(elem); + if (elem != NULL) xmlFree(elem); if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) ctxt->sax->error(ctxt->userData, "xmlParseElementMixedContentDecl : '|' or ')*' expected\n"); @@ -3743,7 +3744,7 @@ xmlParseElementChildrenContentDecl(xmlParserCtxtPtr ctxt) { } else { cur->ocur = XML_ELEMENT_CONTENT_ONCE; } - free(elem); + xmlFree(elem); GROW; } SKIP_BLANKS; @@ -3841,7 +3842,7 @@ xmlParseElementChildrenContentDecl(xmlParserCtxtPtr ctxt) { return(NULL); } last = xmlNewElementContent(elem, XML_ELEMENT_CONTENT_ELEMENT); - free(elem); + xmlFree(elem); if (CUR == '?') { last->ocur = XML_ELEMENT_CONTENT_OPT; NEXT; @@ -4012,7 +4013,7 @@ xmlParseElementDecl(xmlParserCtxtPtr ctxt) { "xmlParseElementDecl: 'EMPTY', 'ANY' or '(' expected\n"); } ctxt->wellFormed = 0; - if (name != NULL) free(name); + if (name != NULL) xmlFree(name); return(-1); } SKIP_BLANKS; @@ -4031,7 +4032,7 @@ xmlParseElementDecl(xmlParserCtxtPtr ctxt) { xmlFreeElementContent(content); } if (name != NULL) { - free(name); + xmlFree(name); } } return(ret); @@ -4112,7 +4113,7 @@ xmlParseTextDecl(xmlParserCtxtPtr ctxt) { if (version == NULL) version = xmlCharStrdup(XML_DEFAULT_VERSION); ctxt->version = xmlStrdup(version); - free(version); + xmlFree(version); /* * We must have the encoding declaration @@ -4466,7 +4467,7 @@ xmlParseEntityRef(xmlParserCtxtPtr ctxt) { "xmlParseEntityRef: expecting ';'\n"); ctxt->wellFormed = 0; } - free(name); + xmlFree(name); } } return(ent); @@ -4571,7 +4572,7 @@ xmlParsePEReference(xmlParserCtxtPtr ctxt) { "xmlParsePEReference: expecting ';'\n"); ctxt->wellFormed = 0; } - free(name); + xmlFree(name); } } } @@ -4683,9 +4684,9 @@ xmlParseDocTypeDecl(xmlParserCtxtPtr ctxt) { /* * Cleanup */ - if (URI != NULL) free(URI); - if (ExternalID != NULL) free(ExternalID); - if (name != NULL) free(name); + if (URI != NULL) xmlFree(URI); + if (ExternalID != NULL) xmlFree(ExternalID); + if (name != NULL) xmlFree(name); } /** @@ -4832,8 +4833,8 @@ xmlParseStartTag(xmlParserCtxtPtr ctxt) { "Attribute %s redefined\n", attname); ctxt->wellFormed = 0; - free(attname); - free(attvalue); + xmlFree(attname); + xmlFree(attvalue); goto failed; } } @@ -4843,7 +4844,7 @@ xmlParseStartTag(xmlParserCtxtPtr ctxt) { */ if (atts == NULL) { maxatts = 10; - atts = (const CHAR **) malloc(maxatts * sizeof(CHAR *)); + atts = (const CHAR **) xmlMalloc(maxatts * sizeof(CHAR *)); if (atts == NULL) { fprintf(stderr, "malloc of %ld byte failed\n", maxatts * (long)sizeof(CHAR *)); @@ -4851,7 +4852,7 @@ xmlParseStartTag(xmlParserCtxtPtr ctxt) { } } else if (nbatts + 2 < maxatts) { maxatts *= 2; - atts = (const CHAR **) realloc(atts, maxatts * sizeof(CHAR *)); + atts = (const CHAR **) xmlRealloc(atts, maxatts * sizeof(CHAR *)); if (atts == NULL) { fprintf(stderr, "realloc of %ld byte failed\n", maxatts * (long)sizeof(CHAR *)); @@ -4883,8 +4884,8 @@ failed: ctxt->sax->startElement(ctxt->userData, name, atts); if (atts != NULL) { - for (i = 0;i < nbatts;i++) free((CHAR *) atts[i]); - free(atts); + for (i = 0;i < nbatts;i++) xmlFree((CHAR *) atts[i]); + xmlFree(atts); } return(name); } @@ -4950,7 +4951,7 @@ xmlParseEndTag(xmlParserCtxtPtr ctxt, CHAR *tagname) { ctxt->sax->endElement(ctxt->userData, name); if (name != NULL) - free(name); + xmlFree(name); return; } @@ -5177,7 +5178,7 @@ xmlParseElement(xmlParserCtxtPtr ctxt) { SKIP(2); if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL)) ctxt->sax->endElement(ctxt->userData, name); - free(name); + xmlFree(name); return; } if (CUR == '>') { @@ -5192,7 +5193,7 @@ xmlParseElement(xmlParserCtxtPtr ctxt) { * end of parsing of this node. */ nodePop(ctxt); - free(name); + xmlFree(name); /* * Capture end position and add node @@ -5221,7 +5222,7 @@ xmlParseElement(xmlParserCtxtPtr ctxt) { * end of parsing of this node. */ nodePop(ctxt); - free(name); + xmlFree(name); return; } @@ -5229,7 +5230,7 @@ xmlParseElement(xmlParserCtxtPtr ctxt) { * parse the end of tag: 'version = xmlStrdup(version); - free(version); + xmlFree(version); /* * We may have the encoding declaration @@ -5885,7 +5886,7 @@ xmlSAXParseDTD(xmlSAXHandlerPtr sax, const CHAR *ExternalID, if (ctxt == NULL) return(NULL); if (sax != NULL) { if (ctxt->sax != NULL) - free(ctxt->sax); + xmlFree(ctxt->sax); ctxt->sax = sax; ctxt->userData = NULL; } @@ -6000,7 +6001,7 @@ xmlCreateFileParserCtxt(const char *filename) return(NULL); } - inputStream->filename = strdup(filename); + inputStream->filename = xmlMemStrdup(filename); inputStream->buf = buf; inputStream->base = inputStream->buf->buffer->content; inputStream->cur = inputStream->buf->buffer->content; @@ -6040,7 +6041,7 @@ xmlSAXParseFile(xmlSAXHandlerPtr sax, const char *filename, if (ctxt == NULL) return(NULL); if (sax != NULL) { if (ctxt->sax != NULL) - free(ctxt->sax); + xmlFree(ctxt->sax); ctxt->sax = sax; ctxt->userData = NULL; } @@ -6234,13 +6235,13 @@ xmlSetupParserForBuffer(xmlParserCtxtPtr ctxt, const CHAR* buffer, input = xmlNewInputStream(ctxt); if (input == NULL) { perror("malloc"); - free(ctxt); + xmlFree(ctxt); exit(1); } xmlClearParserCtxt(ctxt); if (filename != NULL) - input->filename = strdup(filename); + input->filename = xmlMemStrdup(filename); input->base = buffer; input->cur = buffer; inputPush(ctxt, input); @@ -6302,7 +6303,7 @@ void xmlClearNodeInfoSeq(xmlParserNodeInfoSeqPtr seq) { if ( seq->buffer != NULL ) - free(seq->buffer); + xmlFree(seq->buffer); xmlInitNodeInfoSeq(seq); } @@ -6376,9 +6377,9 @@ xmlParserAddNodeInfo(xmlParserCtxtPtr ctxt, *(ctxt->node_seq.maximum + block_size)); if ( ctxt->node_seq.buffer == NULL ) - tmp_buffer = (xmlParserNodeInfo*)malloc(byte_size); + tmp_buffer = (xmlParserNodeInfo*) xmlMalloc(byte_size); else - tmp_buffer = (xmlParserNodeInfo*)realloc(ctxt->node_seq.buffer, byte_size); + tmp_buffer = (xmlParserNodeInfo*) xmlRealloc(ctxt->node_seq.buffer, byte_size); if ( tmp_buffer == NULL ) { if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) diff --git a/parser.h b/parser.h index 34a65f1c..aab35530 100644 --- a/parser.h +++ b/parser.h @@ -238,7 +238,8 @@ typedef struct xmlSAXHandler { typedef xmlSAXHandler *xmlSAXHandlerPtr; /** - * Global variables: just the default SAX interface tables and XML version infos. + * Global variables: just the default SAX interface tables and XML + * version infos. */ extern const char *xmlParserVersion; @@ -246,6 +247,13 @@ extern xmlSAXLocator xmlDefaultSAXLocator; extern xmlSAXHandler xmlDefaultSAXHandler; extern xmlSAXHandler htmlDefaultSAXHandler; +/** + * entity substitution default behaviour. + */ + +extern int xmlSubstituteEntitiesDefaultValue; + + #include "entities.h" #include "xml-error.h" diff --git a/parserInternals.h b/parserInternals.h index 413c26c6..13ea1362 100644 --- a/parserInternals.h +++ b/parserInternals.h @@ -508,12 +508,6 @@ typedef unsigned char CHARVAL; #define MOVETO_STARTTAG(p) \ while (IS_CHAR(*p) && (*(p) != '<')) (p)++ -/** - * entity substitution default behaviour. - */ - -int xmlSubstituteEntitiesDefaultValue; - /** * Parser context */ diff --git a/tester.c b/tester.c index e4960111..a1e7c036 100644 --- a/tester.c +++ b/tester.c @@ -26,6 +26,7 @@ #include #include +#include "xmlmemory.h" #include "parser.h" #include "tree.h" #include "debugXML.h" @@ -231,6 +232,7 @@ int main(int argc, char **argv) { printf("\t--noout : don't output the result\n"); printf("\t--repeat : parse the file 100 times, for timing or profiling\n"); } + xmlMemoryDump(); return(0); } diff --git a/tree.c b/tree.c index 34c927a3..9e622ffe 100644 --- a/tree.c +++ b/tree.c @@ -16,6 +16,7 @@ #include #endif +#include "xmlmemory.h" #include "tree.h" #include "entities.h" #include "valid.h" @@ -89,7 +90,7 @@ xmlNewNs(xmlNodePtr node, const CHAR *href, const CHAR *prefix) { /* * Allocate a new DTD and fill the fields. */ - cur = (xmlNsPtr) malloc(sizeof(xmlNs)); + cur = (xmlNsPtr) xmlMalloc(sizeof(xmlNs)); if (cur == NULL) { fprintf(stderr, "xmlNewNs : malloc failed\n"); return(NULL); @@ -139,7 +140,7 @@ xmlNewGlobalNs(xmlDocPtr doc, const CHAR *href, const CHAR *prefix) { /* * Allocate a new DTD and fill the fields. */ - cur = (xmlNsPtr) malloc(sizeof(xmlNs)); + cur = (xmlNsPtr) xmlMalloc(sizeof(xmlNs)); if (cur == NULL) { fprintf(stderr, "xmlNewGlobalNs : malloc failed\n"); return(NULL); @@ -201,10 +202,10 @@ xmlFreeNs(xmlNsPtr cur) { fprintf(stderr, "xmlFreeNs : ns == NULL\n"); return; } - if (cur->href != NULL) free((char *) cur->href); - if (cur->prefix != NULL) free((char *) cur->prefix); + if (cur->href != NULL) xmlFree((char *) cur->href); + if (cur->prefix != NULL) xmlFree((char *) cur->prefix); memset(cur, -1, sizeof(xmlNs)); - free(cur); + xmlFree(cur); } /** @@ -251,7 +252,7 @@ xmlNewDtd(xmlDocPtr doc, const CHAR *name, /* * Allocate a new DTD and fill the fields. */ - cur = (xmlDtdPtr) malloc(sizeof(xmlDtd)); + cur = (xmlDtdPtr) xmlMalloc(sizeof(xmlDtd)); if (cur == NULL) { fprintf(stderr, "xmlNewDtd : malloc failed\n"); return(NULL); @@ -304,7 +305,7 @@ xmlCreateIntSubset(xmlDocPtr doc, const CHAR *name, /* * Allocate a new DTD and fill the fields. */ - cur = (xmlDtdPtr) malloc(sizeof(xmlDtd)); + cur = (xmlDtdPtr) xmlMalloc(sizeof(xmlDtd)); if (cur == NULL) { fprintf(stderr, "xmlNewDtd : malloc failed\n"); return(NULL); @@ -344,9 +345,9 @@ xmlFreeDtd(xmlDtdPtr cur) { fprintf(stderr, "xmlFreeDtd : DTD == NULL\n"); return; } - if (cur->name != NULL) free((char *) cur->name); - if (cur->SystemID != NULL) free((char *) cur->SystemID); - if (cur->ExternalID != NULL) free((char *) cur->ExternalID); + if (cur->name != NULL) xmlFree((char *) cur->name); + if (cur->SystemID != NULL) xmlFree((char *) cur->SystemID); + if (cur->ExternalID != NULL) xmlFree((char *) cur->ExternalID); if (cur->notations != NULL) xmlFreeNotationTable((xmlNotationTablePtr) cur->notations); if (cur->elements != NULL) @@ -356,7 +357,7 @@ xmlFreeDtd(xmlDtdPtr cur) { if (cur->entities != NULL) xmlFreeEntitiesTable((xmlEntitiesTablePtr) cur->entities); memset(cur, -1, sizeof(xmlDtd)); - free(cur); + xmlFree(cur); } /** @@ -377,7 +378,7 @@ xmlNewDoc(const CHAR *version) { /* * Allocate a new document and fill the fields. */ - cur = (xmlDocPtr) malloc(sizeof(xmlDoc)); + cur = (xmlDocPtr) xmlMalloc(sizeof(xmlDoc)); if (cur == NULL) { fprintf(stderr, "xmlNewDoc : malloc failed\n"); return(NULL); @@ -416,16 +417,16 @@ xmlFreeDoc(xmlDocPtr cur) { #endif return; } - if (cur->version != NULL) free((char *) cur->version); - if (cur->name != NULL) free((char *) cur->name); - if (cur->encoding != NULL) free((char *) cur->encoding); - if (cur->root != NULL) xmlFreeNode(cur->root); + if (cur->version != NULL) xmlFree((char *) cur->version); + if (cur->name != NULL) xmlFree((char *) cur->name); + if (cur->encoding != NULL) xmlFree((char *) cur->encoding); + if (cur->root != NULL) xmlFreeNodeList(cur->root); if (cur->intSubset != NULL) xmlFreeDtd(cur->intSubset); if (cur->extSubset != NULL) xmlFreeDtd(cur->extSubset); if (cur->oldNs != NULL) xmlFreeNsList(cur->oldNs); if (cur->ids != NULL) xmlFreeIDTable((xmlIDTablePtr) cur->ids); memset(cur, -1, sizeof(xmlDoc)); - free(cur); + xmlFree(cur); } /** @@ -501,7 +502,7 @@ xmlStringLenGetNodeList(xmlDocPtr doc, const CHAR *value, int len) { */ node = xmlNewReference(doc, val); if (node == NULL) { - if (val != NULL) free(val); + if (val != NULL) xmlFree(val); return(ret); } if (last == NULL) @@ -512,7 +513,7 @@ xmlStringLenGetNodeList(xmlDocPtr doc, const CHAR *value, int len) { last = node; } } - free(val); + xmlFree(val); } cur++; q = cur; @@ -612,7 +613,7 @@ xmlStringGetNodeList(xmlDocPtr doc, const CHAR *value) { */ node = xmlNewReference(doc, val); if (node == NULL) { - if (val != NULL) free(val); + if (val != NULL) xmlFree(val); return(ret); } if (last == NULL) @@ -623,7 +624,7 @@ xmlStringGetNodeList(xmlDocPtr doc, const CHAR *value) { last = node; } } - free(val); + xmlFree(val); } cur++; q = cur; @@ -679,7 +680,7 @@ xmlNodeListGetString(xmlDocPtr doc, xmlNodePtr list, int inLine) { buffer = xmlEncodeEntitiesReentrant(doc, node->content); if (buffer != NULL) { ret = xmlStrcat(ret, buffer); - free(buffer); + xmlFree(buffer); } } } else if (node->type == XML_ENTITY_REF_NODE) { @@ -730,7 +731,7 @@ xmlNewProp(xmlNodePtr node, const CHAR *name, const CHAR *value) { /* * Allocate a new property and fill the fields. */ - cur = (xmlAttrPtr) malloc(sizeof(xmlAttr)); + cur = (xmlAttrPtr) xmlMalloc(sizeof(xmlAttr)); if (cur == NULL) { fprintf(stderr, "xmlNewProp : malloc failed\n"); return(NULL); @@ -789,7 +790,7 @@ xmlNewNsProp(xmlNodePtr node, xmlNsPtr ns, const CHAR *name, /* * Allocate a new property and fill the fields. */ - cur = (xmlAttrPtr) malloc(sizeof(xmlAttr)); + cur = (xmlAttrPtr) xmlMalloc(sizeof(xmlAttr)); if (cur == NULL) { fprintf(stderr, "xmlNewProp : malloc failed\n"); return(NULL); @@ -846,7 +847,7 @@ xmlNewDocProp(xmlDocPtr doc, const CHAR *name, const CHAR *value) { /* * Allocate a new property and fill the fields. */ - cur = (xmlAttrPtr) malloc(sizeof(xmlAttr)); + cur = (xmlAttrPtr) xmlMalloc(sizeof(xmlAttr)); if (cur == NULL) { fprintf(stderr, "xmlNewProp : malloc failed\n"); return(NULL); @@ -900,10 +901,10 @@ xmlFreeProp(xmlAttrPtr cur) { fprintf(stderr, "xmlFreeProp : property == NULL\n"); return; } - if (cur->name != NULL) free((char *) cur->name); + if (cur->name != NULL) xmlFree((char *) cur->name); if (cur->val != NULL) xmlFreeNodeList(cur->val); memset(cur, -1, sizeof(xmlAttr)); - free(cur); + xmlFree(cur); } /** @@ -926,7 +927,7 @@ xmlNewPI(const CHAR *name, const CHAR *content) { /* * Allocate a new node and fill the fields. */ - cur = (xmlNodePtr) malloc(sizeof(xmlNode)); + cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode)); if (cur == NULL) { fprintf(stderr, "xmlNewPI : malloc failed\n"); return(NULL); @@ -976,7 +977,7 @@ xmlNewNode(xmlNsPtr ns, const CHAR *name) { /* * Allocate a new node and fill the fields. */ - cur = (xmlNodePtr) malloc(sizeof(xmlNode)); + cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode)); if (cur == NULL) { fprintf(stderr, "xmlNewNode : malloc failed\n"); return(NULL); @@ -1043,7 +1044,7 @@ xmlNewText(const CHAR *content) { /* * Allocate a new node and fill the fields. */ - cur = (xmlNodePtr) malloc(sizeof(xmlNode)); + cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode)); if (cur == NULL) { fprintf(stderr, "xmlNewText : malloc failed\n"); return(NULL); @@ -1084,7 +1085,7 @@ xmlNewReference(xmlDocPtr doc, const CHAR *name) { /* * Allocate a new node and fill the fields. */ - cur = (xmlNodePtr) malloc(sizeof(xmlNode)); + cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode)); if (cur == NULL) { fprintf(stderr, "xmlNewText : malloc failed\n"); return(NULL); @@ -1151,7 +1152,7 @@ xmlNewTextLen(const CHAR *content, int len) { /* * Allocate a new node and fill the fields. */ - cur = (xmlNodePtr) malloc(sizeof(xmlNode)); + cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode)); if (cur == NULL) { fprintf(stderr, "xmlNewText : malloc failed\n"); return(NULL); @@ -1209,7 +1210,7 @@ xmlNewComment(const CHAR *content) { /* * Allocate a new node and fill the fields. */ - cur = (xmlNodePtr) malloc(sizeof(xmlNode)); + cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode)); if (cur == NULL) { fprintf(stderr, "xmlNewComment : malloc failed\n"); return(NULL); @@ -1250,7 +1251,7 @@ xmlNewCDataBlock(xmlDocPtr doc, const CHAR *content, int len) { /* * Allocate a new node and fill the fields. */ - cur = (xmlNodePtr) malloc(sizeof(xmlNode)); + cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode)); if (cur == NULL) { fprintf(stderr, "xmlNewCDataBlock : malloc failed\n"); return(NULL); @@ -1438,7 +1439,7 @@ xmlAddChild(xmlNodePtr parent, xmlNodePtr cur) { text->next->prev = text; parent->childs = text; UPDATE_LAST_CHILD(parent) - free(parent->content); + xmlFree(parent->content); parent->content = NULL; } } @@ -1511,11 +1512,11 @@ xmlFreeNode(xmlNodePtr cur) { if (cur->childs != NULL) xmlFreeNodeList(cur->childs); if (cur->properties != NULL) xmlFreePropList(cur->properties); if (cur->type != XML_ENTITY_REF_NODE) - if (cur->content != NULL) free(cur->content); - if (cur->name != NULL) free((char *) cur->name); + if (cur->content != NULL) xmlFree(cur->content); + if (cur->name != NULL) xmlFree((char *) cur->name); if (cur->nsDef != NULL) xmlFreeNsList(cur->nsDef); memset(cur, -1, sizeof(xmlNode)); - free(cur); + xmlFree(cur); } /** @@ -1688,7 +1689,7 @@ xmlStaticCopyNode(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent, /* * Allocate a new node and fill the fields. */ - ret = (xmlNodePtr) malloc(sizeof(xmlNode)); + ret = (xmlNodePtr) xmlMalloc(sizeof(xmlNode)); if (ret == NULL) { fprintf(stderr, "xmlStaticCopyNode : malloc failed\n"); return(NULL); @@ -1883,7 +1884,7 @@ xmlCopyDoc(xmlDocPtr doc, int recursive) { ret = xmlNewDoc(doc->version); if (ret == NULL) return(NULL); if (doc->name != NULL) - ret->name = strdup(doc->name); + ret->name = xmlMemStrdup(doc->name); if (doc->encoding != NULL) ret->encoding = xmlStrdup(doc->encoding); ret->compression = doc->compression; @@ -2007,10 +2008,10 @@ xmlNodeSetContent(xmlNodePtr cur, const CHAR *content) { case XML_DOCUMENT_FRAG_NODE: case XML_ELEMENT_NODE: if (cur->content != NULL) { - free(cur->content); + xmlFree(cur->content); cur->content = NULL; } - if (cur->childs != NULL) xmlFreeNode(cur->childs); + if (cur->childs != NULL) xmlFreeNodeList(cur->childs); cur->childs = xmlStringGetNodeList(cur->doc, content); UPDATE_LAST_CHILD(cur) break; @@ -2022,8 +2023,8 @@ xmlNodeSetContent(xmlNodePtr cur, const CHAR *content) { case XML_ENTITY_NODE: case XML_PI_NODE: case XML_COMMENT_NODE: - if (cur->content != NULL) free(cur->content); - if (cur->childs != NULL) xmlFreeNode(cur->childs); + if (cur->content != NULL) xmlFree(cur->content); + if (cur->childs != NULL) xmlFreeNodeList(cur->childs); cur->last = cur->childs = NULL; if (content != NULL) cur->content = xmlStrdup(content); @@ -2056,10 +2057,10 @@ xmlNodeSetContentLen(xmlNodePtr cur, const CHAR *content, int len) { case XML_DOCUMENT_FRAG_NODE: case XML_ELEMENT_NODE: if (cur->content != NULL) { - free(cur->content); + xmlFree(cur->content); cur->content = NULL; } - if (cur->childs != NULL) xmlFreeNode(cur->childs); + if (cur->childs != NULL) xmlFreeNodeList(cur->childs); cur->childs = xmlStringLenGetNodeList(cur->doc, content, len); UPDATE_LAST_CHILD(cur) break; @@ -2071,8 +2072,8 @@ xmlNodeSetContentLen(xmlNodePtr cur, const CHAR *content, int len) { case XML_ENTITY_NODE: case XML_PI_NODE: case XML_COMMENT_NODE: - if (cur->content != NULL) free(cur->content); - if (cur->childs != NULL) xmlFreeNode(cur->childs); + if (cur->content != NULL) xmlFree(cur->content); + if (cur->childs != NULL) xmlFreeNodeList(cur->childs); cur->childs = cur->last = NULL; if (content != NULL) cur->content = xmlStrndup(content, len); @@ -2083,8 +2084,8 @@ xmlNodeSetContentLen(xmlNodePtr cur, const CHAR *content, int len) { case XML_DOCUMENT_TYPE_NODE: break; case XML_NOTATION_NODE: - if (cur->content != NULL) free(cur->content); - if (cur->childs != NULL) xmlFreeNode(cur->childs); + if (cur->content != NULL) xmlFree(cur->content); + if (cur->childs != NULL) xmlFreeNodeList(cur->childs); cur->childs = cur->last = NULL; if (content != NULL) cur->content = xmlStrndup(content, len); @@ -2120,7 +2121,7 @@ xmlNodeAddContentLen(xmlNodePtr cur, const CHAR *content, int len) { if (cur->content != NULL) { cur->childs = xmlStringGetNodeList(cur->doc, cur->content); UPDATE_LAST_CHILD(cur) - free(cur->content); + xmlFree(cur->content); cur->content = NULL; last = cur->last; } @@ -2216,7 +2217,7 @@ xmlGetNsList(xmlDocPtr doc, xmlNodePtr node) { cur = node->nsDef; while (cur != NULL) { if (ret == NULL) { - ret = (xmlNsPtr *) malloc((maxns + 1) * sizeof(xmlNsPtr)); + ret = (xmlNsPtr *) xmlMalloc((maxns + 1) * sizeof(xmlNsPtr)); if (ret == NULL) { fprintf(stderr, "xmlGetNsList : out of memory!\n"); return(NULL); @@ -2230,7 +2231,7 @@ xmlGetNsList(xmlDocPtr doc, xmlNodePtr node) { if (i >= nbns) { if (nbns >= maxns) { maxns *= 2; - ret = (xmlNsPtr *) realloc(ret, + ret = (xmlNsPtr *) xmlRealloc(ret, (maxns + 1) * sizeof(xmlNsPtr)); if (ret == NULL) { fprintf(stderr, "xmlGetNsList : realloc failed!\n"); @@ -2365,7 +2366,7 @@ xmlSetProp(xmlNodePtr node, const CHAR *name, const CHAR *value) { while (prop != NULL) { if (!xmlStrcmp(prop->name, name)) { if (prop->val != NULL) - xmlFreeNode(prop->val); + xmlFreeNodeList(prop->val); prop->val = NULL; if (value != NULL) prop->val = xmlStringGetNodeList(node->doc, value); @@ -2430,17 +2431,17 @@ xmlBufferPtr xmlBufferCreate(void) { xmlBufferPtr ret; - ret = (xmlBufferPtr) malloc(sizeof(xmlBuffer)); + ret = (xmlBufferPtr) xmlMalloc(sizeof(xmlBuffer)); if (ret == NULL) { fprintf(stderr, "xmlBufferCreate : out of memory!\n"); return(NULL); } ret->use = 0; ret->size = BASE_BUFFER_SIZE; - ret->content = (CHAR *) malloc(ret->size * sizeof(CHAR)); + ret->content = (CHAR *) xmlMalloc(ret->size * sizeof(CHAR)); if (ret->content == NULL) { fprintf(stderr, "xmlBufferCreate : out of memory!\n"); - free(ret); + xmlFree(ret); return(NULL); } ret->content[0] = 0; @@ -2463,10 +2464,10 @@ xmlBufferFree(xmlBufferPtr buf) { fprintf(stderr, "xmlBufferFree: buf->content == NULL\n"); } else { memset(buf->content, -1, BASE_BUFFER_SIZE); - free(buf->content); + xmlFree(buf->content); } memset(buf, -1, sizeof(xmlBuffer)); - free(buf); + xmlFree(buf); } /** @@ -2553,7 +2554,7 @@ xmlBufferAdd(xmlBufferPtr buf, const CHAR *str, int len) { buf->size *= 2; if (buf->use + len + 10 > buf->size) buf->size = buf->use + len + 10; - rebuf = (CHAR *) realloc(buf->content, buf->size * sizeof(CHAR)); + rebuf = (CHAR *) xmlRealloc(buf->content, buf->size * sizeof(CHAR)); if (rebuf == NULL) { fprintf(stderr, "xmlBufferAdd : out of memory!\n"); return; @@ -2585,7 +2586,7 @@ xmlBufferCat(xmlBufferPtr buf, const CHAR *str) { CHAR *rebuf; buf->size *= 2; - rebuf = (CHAR *) realloc(buf->content, buf->size * sizeof(CHAR)); + rebuf = (CHAR *) xmlRealloc(buf->content, buf->size * sizeof(CHAR)); if (rebuf == NULL) { fprintf(stderr, "xmlBufferAdd : out of memory!\n"); return; @@ -2616,7 +2617,7 @@ xmlBufferCCat(xmlBufferPtr buf, const char *str) { CHAR *rebuf; buf->size *= 2; - rebuf = (CHAR *) realloc(buf->content, buf->size * sizeof(CHAR)); + rebuf = (CHAR *) xmlRealloc(buf->content, buf->size * sizeof(CHAR)); if (rebuf == NULL) { fprintf(stderr, "xmlBufferAdd : out of memory!\n"); return; @@ -2836,7 +2837,7 @@ xmlAttrDump(xmlBufferPtr buf, xmlDocPtr doc, xmlAttrPtr cur) { if (value) { xmlBufferWriteChar(buf, "="); xmlBufferWriteQuotedString(buf, value); - free(value); + xmlFree(value); } else { xmlBufferWriteChar(buf, "=\"\""); } @@ -2922,7 +2923,7 @@ xmlNodeDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur, int level) { buffer = xmlEncodeEntitiesReentrant(doc, cur->content); if (buffer != NULL) { xmlBufferWriteCHAR(buf, buffer); - free(buffer); + xmlFree(buffer); } } return; @@ -2987,7 +2988,7 @@ xmlNodeDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur, int level) { buffer = xmlEncodeEntitiesReentrant(doc, cur->content); if (buffer != NULL) { xmlBufferWriteCHAR(buf, buffer); - free(buffer); + xmlFree(buffer); } } if (cur->childs != NULL) { diff --git a/valid.c b/valid.c index bb7a7476..3a107dbe 100644 --- a/valid.c +++ b/valid.c @@ -10,6 +10,7 @@ #include #include #include +#include "xmlmemory.h" #include "valid.h" #include "parser.h" #include "parserInternals.h" @@ -63,7 +64,7 @@ xmlNewElementContent(CHAR *name, xmlElementContentType type) { fprintf(stderr, "xmlNewElementContent: unknown type %d\n", type); exit(1); } - ret = (xmlElementContentPtr) malloc(sizeof(xmlElementContent)); + ret = (xmlElementContentPtr) xmlMalloc(sizeof(xmlElementContent)); if (ret == NULL) { fprintf(stderr, "xmlNewElementContent : out of memory!\n"); return(NULL); @@ -113,9 +114,9 @@ xmlFreeElementContent(xmlElementContentPtr cur) { if (cur == NULL) return; if (cur->c1 != NULL) xmlFreeElementContent(cur->c1); if (cur->c2 != NULL) xmlFreeElementContent(cur->c2); - if (cur->name != NULL) free((CHAR *) cur->name); + if (cur->name != NULL) xmlFree((CHAR *) cur->name); memset(cur, -1, sizeof(xmlElementContent)); - free(cur); + xmlFree(cur); } /** @@ -263,20 +264,20 @@ xmlCreateElementTable(void) { xmlElementTablePtr ret; ret = (xmlElementTablePtr) - malloc(sizeof(xmlElementTable)); + xmlMalloc(sizeof(xmlElementTable)); if (ret == NULL) { - fprintf(stderr, "xmlCreateElementTable : malloc(%ld) failed\n", + fprintf(stderr, "xmlCreateElementTable : xmlMalloc(%ld) failed\n", (long)sizeof(xmlElementTable)); return(NULL); } ret->max_elements = XML_MIN_ELEMENT_TABLE; ret->nb_elements = 0; ret->table = (xmlElementPtr *) - malloc(ret->max_elements * sizeof(xmlElementPtr)); + xmlMalloc(ret->max_elements * sizeof(xmlElementPtr)); if (ret == NULL) { - fprintf(stderr, "xmlCreateElementTable : malloc(%ld) failed\n", + fprintf(stderr, "xmlCreateElementTable : xmlMalloc(%ld) failed\n", ret->max_elements * (long)sizeof(xmlElement)); - free(ret); + xmlFree(ret); return(NULL); } return(ret); @@ -378,13 +379,13 @@ xmlAddElementDecl(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd, const CHAR *name, */ table->max_elements *= 2; table->table = (xmlElementPtr *) - realloc(table->table, table->max_elements * sizeof(xmlElementPtr)); + xmlRealloc(table->table, table->max_elements * sizeof(xmlElementPtr)); if (table->table == NULL) { fprintf(stderr, "xmlAddElementDecl: out of memory\n"); return(NULL); } } - ret = (xmlElementPtr) malloc(sizeof(xmlElement)); + ret = (xmlElementPtr) xmlMalloc(sizeof(xmlElement)); if (ret == NULL) { fprintf(stderr, "xmlAddElementDecl: out of memory\n"); return(NULL); @@ -414,9 +415,9 @@ xmlFreeElement(xmlElementPtr elem) { if (elem == NULL) return; xmlFreeElementContent(elem->content); if (elem->name != NULL) - free((CHAR *) elem->name); + xmlFree((CHAR *) elem->name); memset(elem, -1, sizeof(xmlElement)); - free(elem); + xmlFree(elem); } /** @@ -434,8 +435,8 @@ xmlFreeElementTable(xmlElementTablePtr table) { for (i = 0;i < table->nb_elements;i++) { xmlFreeElement(table->table[i]); } - free(table->table); - free(table); + xmlFree(table->table); + xmlFree(table); } /** @@ -452,26 +453,26 @@ xmlCopyElementTable(xmlElementTablePtr table) { xmlElementPtr cur, ent; int i; - ret = (xmlElementTablePtr) malloc(sizeof(xmlElementTable)); + ret = (xmlElementTablePtr) xmlMalloc(sizeof(xmlElementTable)); if (ret == NULL) { fprintf(stderr, "xmlCopyElementTable: out of memory !\n"); return(NULL); } - ret->table = (xmlElementPtr *) malloc(table->max_elements * + ret->table = (xmlElementPtr *) xmlMalloc(table->max_elements * sizeof(xmlElementPtr)); if (ret->table == NULL) { fprintf(stderr, "xmlCopyElementTable: out of memory !\n"); - free(ret); + xmlFree(ret); return(NULL); } ret->max_elements = table->max_elements; ret->nb_elements = table->nb_elements; for (i = 0;i < ret->nb_elements;i++) { - cur = (xmlElementPtr) malloc(sizeof(xmlElement)); + cur = (xmlElementPtr) xmlMalloc(sizeof(xmlElement)); if (cur == NULL) { fprintf(stderr, "xmlCopyElementTable: out of memory !\n"); - free(ret); - free(ret->table); + xmlFree(ret); + xmlFree(ret->table); return(NULL); } ret->table[i] = cur; @@ -549,9 +550,9 @@ xmlEnumerationPtr xmlCreateEnumeration(CHAR *name) { xmlEnumerationPtr ret; - ret = (xmlEnumerationPtr) malloc(sizeof(xmlEnumeration)); + ret = (xmlEnumerationPtr) xmlMalloc(sizeof(xmlEnumeration)); if (ret == NULL) { - fprintf(stderr, "xmlCreateEnumeration : malloc(%ld) failed\n", + fprintf(stderr, "xmlCreateEnumeration : xmlMalloc(%ld) failed\n", (long)sizeof(xmlEnumeration)); return(NULL); } @@ -576,9 +577,9 @@ xmlFreeEnumeration(xmlEnumerationPtr cur) { if (cur->next != NULL) xmlFreeEnumeration(cur->next); - if (cur->name != NULL) free((CHAR *) cur->name); + if (cur->name != NULL) xmlFree((CHAR *) cur->name); memset(cur, -1, sizeof(xmlEnumeration)); - free(cur); + xmlFree(cur); } /** @@ -636,20 +637,20 @@ xmlCreateAttributeTable(void) { xmlAttributeTablePtr ret; ret = (xmlAttributeTablePtr) - malloc(sizeof(xmlAttributeTable)); + xmlMalloc(sizeof(xmlAttributeTable)); if (ret == NULL) { - fprintf(stderr, "xmlCreateAttributeTable : malloc(%ld) failed\n", + fprintf(stderr, "xmlCreateAttributeTable : xmlMalloc(%ld) failed\n", (long)sizeof(xmlAttributeTable)); return(NULL); } ret->max_attributes = XML_MIN_ATTRIBUTE_TABLE; ret->nb_attributes = 0; ret->table = (xmlAttributePtr *) - malloc(ret->max_attributes * sizeof(xmlAttributePtr)); + xmlMalloc(ret->max_attributes * sizeof(xmlAttributePtr)); if (ret == NULL) { - fprintf(stderr, "xmlCreateAttributeTable : malloc(%ld) failed\n", + fprintf(stderr, "xmlCreateAttributeTable : xmlMalloc(%ld) failed\n", ret->max_attributes * (long)sizeof(xmlAttributePtr)); - free(ret); + xmlFree(ret); return(NULL); } return(ret); @@ -831,14 +832,14 @@ xmlAddAttributeDecl(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd, const CHAR *elem, */ table->max_attributes *= 2; table->table = (xmlAttributePtr *) - realloc(table->table, table->max_attributes * + xmlRealloc(table->table, table->max_attributes * sizeof(xmlAttributePtr)); if (table->table == NULL) { fprintf(stderr, "xmlAddAttributeDecl: out of memory\n"); return(NULL); } } - ret = (xmlAttributePtr) malloc(sizeof(xmlAttribute)); + ret = (xmlAttributePtr) xmlMalloc(sizeof(xmlAttribute)); if (ret == NULL) { fprintf(stderr, "xmlAddAttributeDecl: out of memory\n"); return(NULL); @@ -884,13 +885,13 @@ xmlFreeAttribute(xmlAttributePtr attr) { if (attr->tree != NULL) xmlFreeEnumeration(attr->tree); if (attr->elem != NULL) - free((CHAR *) attr->elem); + xmlFree((CHAR *) attr->elem); if (attr->name != NULL) - free((CHAR *) attr->name); + xmlFree((CHAR *) attr->name); if (attr->defaultValue != NULL) - free((CHAR *) attr->defaultValue); + xmlFree((CHAR *) attr->defaultValue); memset(attr, -1, sizeof(xmlAttribute)); - free(attr); + xmlFree(attr); } /** @@ -908,8 +909,8 @@ xmlFreeAttributeTable(xmlAttributeTablePtr table) { for (i = 0;i < table->nb_attributes;i++) { xmlFreeAttribute(table->table[i]); } - free(table->table); - free(table); + xmlFree(table->table); + xmlFree(table); } /** @@ -926,27 +927,27 @@ xmlCopyAttributeTable(xmlAttributeTablePtr table) { xmlAttributePtr cur, attr; int i; - ret = (xmlAttributeTablePtr) malloc(sizeof(xmlAttributeTable)); + ret = (xmlAttributeTablePtr) xmlMalloc(sizeof(xmlAttributeTable)); if (ret == NULL) { fprintf(stderr, "xmlCopyAttributeTable: out of memory !\n"); return(NULL); } - ret->table = (xmlAttributePtr *) malloc(table->max_attributes * + ret->table = (xmlAttributePtr *) xmlMalloc(table->max_attributes * sizeof(xmlAttributePtr)); if (ret->table == NULL) { fprintf(stderr, "xmlCopyAttributeTable: out of memory !\n"); - free(ret); + xmlFree(ret); return(NULL); } ret->max_attributes = table->max_attributes; ret->nb_attributes = table->nb_attributes; for (i = 0;i < ret->nb_attributes;i++) { attr = table->table[i]; - cur = (xmlAttributePtr) malloc(sizeof(xmlAttribute)); + cur = (xmlAttributePtr) xmlMalloc(sizeof(xmlAttribute)); if (cur == NULL) { fprintf(stderr, "xmlCopyAttributeTable: out of memory !\n"); - free(ret); - free(ret->table); + xmlFree(ret); + xmlFree(ret->table); return(NULL); } ret->table[i] = cur; @@ -1071,20 +1072,20 @@ xmlCreateNotationTable(void) { xmlNotationTablePtr ret; ret = (xmlNotationTablePtr) - malloc(sizeof(xmlNotationTable)); + xmlMalloc(sizeof(xmlNotationTable)); if (ret == NULL) { - fprintf(stderr, "xmlCreateNotationTable : malloc(%ld) failed\n", + fprintf(stderr, "xmlCreateNotationTable : xmlMalloc(%ld) failed\n", (long)sizeof(xmlNotationTable)); return(NULL); } ret->max_notations = XML_MIN_NOTATION_TABLE; ret->nb_notations = 0; ret->table = (xmlNotationPtr *) - malloc(ret->max_notations * sizeof(xmlNotationPtr)); + xmlMalloc(ret->max_notations * sizeof(xmlNotationPtr)); if (ret == NULL) { - fprintf(stderr, "xmlCreateNotationTable : malloc(%ld) failed\n", + fprintf(stderr, "xmlCreateNotationTable : xmlMalloc(%ld) failed\n", ret->max_notations * (long)sizeof(xmlNotation)); - free(ret); + xmlFree(ret); return(NULL); } return(ret); @@ -1157,14 +1158,14 @@ xmlAddNotationDecl(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd, const CHAR *name, */ table->max_notations *= 2; table->table = (xmlNotationPtr *) - realloc(table->table, table->max_notations * + xmlRealloc(table->table, table->max_notations * sizeof(xmlNotationPtr)); if (table->table == NULL) { fprintf(stderr, "xmlAddNotationDecl: out of memory\n"); return(NULL); } } - ret = (xmlNotationPtr) malloc(sizeof(xmlNotation)); + ret = (xmlNotationPtr) xmlMalloc(sizeof(xmlNotation)); if (ret == NULL) { fprintf(stderr, "xmlAddNotationDecl: out of memory\n"); return(NULL); @@ -1198,13 +1199,13 @@ void xmlFreeNotation(xmlNotationPtr nota) { if (nota == NULL) return; if (nota->name != NULL) - free((CHAR *) nota->name); + xmlFree((CHAR *) nota->name); if (nota->PublicID != NULL) - free((CHAR *) nota->PublicID); + xmlFree((CHAR *) nota->PublicID); if (nota->SystemID != NULL) - free((CHAR *) nota->SystemID); + xmlFree((CHAR *) nota->SystemID); memset(nota, -1, sizeof(xmlNotation)); - free(nota); + xmlFree(nota); } /** @@ -1222,8 +1223,8 @@ xmlFreeNotationTable(xmlNotationTablePtr table) { for (i = 0;i < table->nb_notations;i++) { xmlFreeNotation(table->table[i]); } - free(table->table); - free(table); + xmlFree(table->table); + xmlFree(table); } /** @@ -1240,26 +1241,26 @@ xmlCopyNotationTable(xmlNotationTablePtr table) { xmlNotationPtr cur, nota; int i; - ret = (xmlNotationTablePtr) malloc(sizeof(xmlNotationTable)); + ret = (xmlNotationTablePtr) xmlMalloc(sizeof(xmlNotationTable)); if (ret == NULL) { fprintf(stderr, "xmlCopyNotationTable: out of memory !\n"); return(NULL); } - ret->table = (xmlNotationPtr *) malloc(table->max_notations * + ret->table = (xmlNotationPtr *) xmlMalloc(table->max_notations * sizeof(xmlNotationPtr)); if (ret->table == NULL) { fprintf(stderr, "xmlCopyNotationTable: out of memory !\n"); - free(ret); + xmlFree(ret); return(NULL); } ret->max_notations = table->max_notations; ret->nb_notations = table->nb_notations; for (i = 0;i < ret->nb_notations;i++) { - cur = (xmlNotationPtr) malloc(sizeof(xmlNotation)); + cur = (xmlNotationPtr) xmlMalloc(sizeof(xmlNotation)); if (cur == NULL) { fprintf(stderr, "xmlCopyNotationTable: out of memory !\n"); - free(ret); - free(ret->table); + xmlFree(ret); + xmlFree(ret->table); return(NULL); } ret->table[i] = cur; @@ -1331,20 +1332,20 @@ xmlCreateIDTable(void) { xmlIDTablePtr ret; ret = (xmlIDTablePtr) - malloc(sizeof(xmlIDTable)); + xmlMalloc(sizeof(xmlIDTable)); if (ret == NULL) { - fprintf(stderr, "xmlCreateIDTable : malloc(%ld) failed\n", + fprintf(stderr, "xmlCreateIDTable : xmlMalloc(%ld) failed\n", (long)sizeof(xmlIDTable)); return(NULL); } ret->max_ids = XML_MIN_NOTATION_TABLE; ret->nb_ids = 0; ret->table = (xmlIDPtr *) - malloc(ret->max_ids * sizeof(xmlIDPtr)); + xmlMalloc(ret->max_ids * sizeof(xmlIDPtr)); if (ret == NULL) { - fprintf(stderr, "xmlCreateIDTable : malloc(%ld) failed\n", + fprintf(stderr, "xmlCreateIDTable : xmlMalloc(%ld) failed\n", ret->max_ids * (long)sizeof(xmlID)); - free(ret); + xmlFree(ret); return(NULL); } return(ret); @@ -1417,14 +1418,14 @@ xmlAddID(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const CHAR *value, */ table->max_ids *= 2; table->table = (xmlIDPtr *) - realloc(table->table, table->max_ids * + xmlRealloc(table->table, table->max_ids * sizeof(xmlIDPtr)); if (table->table == NULL) { fprintf(stderr, "xmlAddID: out of memory\n"); return(NULL); } } - ret = (xmlIDPtr) malloc(sizeof(xmlID)); + ret = (xmlIDPtr) xmlMalloc(sizeof(xmlID)); if (ret == NULL) { fprintf(stderr, "xmlAddID: out of memory\n"); return(NULL); @@ -1451,9 +1452,9 @@ void xmlFreeID(xmlIDPtr id) { if (id == NULL) return; if (id->value != NULL) - free((CHAR *) id->value); + xmlFree((CHAR *) id->value); memset(id, -1, sizeof(xmlID)); - free(id); + xmlFree(id); } /** @@ -1471,8 +1472,8 @@ xmlFreeIDTable(xmlIDTablePtr table) { for (i = 0;i < table->nb_ids;i++) { xmlFreeID(table->table[i]); } - free(table->table); - free(table); + xmlFree(table->table); + xmlFree(table); } /** diff --git a/xmlIO.c b/xmlIO.c index 8549089f..8e065389 100644 --- a/xmlIO.c +++ b/xmlIO.c @@ -11,7 +11,6 @@ #include #include #include -#include #ifdef HAVE_UNISTD_H #include #endif @@ -20,6 +19,7 @@ #endif #include +#include "xmlmemory.h" #include "parser.h" #include "xmlIO.h" @@ -45,7 +45,7 @@ xmlParserInputBufferPtr xmlAllocParserInputBuffer(xmlCharEncoding enc) { xmlParserInputBufferPtr ret; - ret = (xmlParserInputBufferPtr) malloc(sizeof(xmlParserInputBuffer)); + ret = (xmlParserInputBufferPtr) xmlMalloc(sizeof(xmlParserInputBuffer)); if (ret == NULL) { fprintf(stderr, "xmlAllocParserInputBuffer : out of memory!\n"); return(NULL); @@ -77,7 +77,7 @@ xmlFreeParserInputBuffer(xmlParserInputBufferPtr in) { if (in->fd >= 0) close(in->fd); memset(in, 0xbe, (size_t) sizeof(xmlParserInputBuffer)); - free(in); + xmlFree(in); } /** @@ -250,7 +250,7 @@ xmlParserInputBufferGrow(xmlParserInputBufferPtr in, int len) { if (len > buffree) len = buffree; - buffer = malloc((len + 1) * sizeof(char)); + buffer = xmlMalloc((len + 1) * sizeof(char)); if (buffer == NULL) { fprintf(stderr, "xmlParserInputBufferGrow : out of memory !\n"); return(-1); @@ -265,32 +265,32 @@ xmlParserInputBufferGrow(xmlParserInputBufferPtr in, int len) { res = read(in->fd, &buffer[0], len); } else { fprintf(stderr, "xmlParserInputBufferGrow : no input !\n"); - free(buffer); + xmlFree(buffer); return(-1); } if (res == 0) { - free(buffer); + xmlFree(buffer); return(0); } if (res < 0) { perror ("read error"); - free(buffer); + xmlFree(buffer); return(-1); } if (in->encoder != NULL) { CHAR *buf; - buf = (CHAR *) malloc((res + 1) * 2 * sizeof(CHAR)); + buf = (CHAR *) xmlMalloc((res + 1) * 2 * sizeof(CHAR)); if (buf == NULL) { fprintf(stderr, "xmlParserInputBufferGrow : out of memory !\n"); - free(buffer); + xmlFree(buffer); return(-1); } nbchars = in->encoder->input(buf, (res + 1) * 2 * sizeof(CHAR), BAD_CAST buffer, res); buf[nbchars] = 0; xmlBufferAdd(in->buffer, (CHAR *) buf, nbchars); - free(buf); + xmlFree(buf); } else { nbchars = res; buffer[nbchars] = 0; @@ -300,7 +300,7 @@ xmlParserInputBufferGrow(xmlParserInputBufferPtr in, int len) { fprintf(stderr, "I/O: read %d chars, buffer %d/%d\n", nbchars, in->buffer->use, in->buffer->size); #endif - free(buffer); + xmlFree(buffer); return(nbchars); } @@ -352,11 +352,11 @@ xmlParserGetDirectory(const char *filename) { if (*cur == sep) { if (cur == dir) dir[1] = 0; else *cur = 0; - ret = strdup(dir); + ret = xmlMemStrdup(dir); } else { if (getcwd(dir, 1024) != NULL) { dir[1023] = 0; - ret = strdup(dir); + ret = xmlMemStrdup(dir); } } return(ret); diff --git a/xmlmemory.c b/xmlmemory.c new file mode 100644 index 00000000..e3341da2 --- /dev/null +++ b/xmlmemory.c @@ -0,0 +1,459 @@ +/* + * memory.c: libxml memory allocator wrapper. + * + * Daniel.Veillard@w3.org + */ + +#include +#include +#include +#include +#include "xmlmemory.h" + +#ifndef NO_DEBUG_MEMORY + +#ifdef xmlMalloc +#undef xmlMalloc +#endif +#ifdef xmlRealloc +#undef xmlRealloc +#endif +#ifdef xmlMemStrdup +#undef xmlMemStrdup +#endif +extern void xmlMemoryDump(void); + +/* + * Each of the blocks allocated begin with a header containing informations + */ + +#define MEMTAG 0x5aa5 + +#define MALLOC_TYPE 1 +#define REALLOC_TYPE 2 +#define STRDUP_TYPE 3 + +typedef struct memnod { + unsigned int mh_tag; + unsigned int mh_type; + unsigned long mh_number; + size_t mh_size; +#ifdef MEM_LIST + struct memnod *mh_next; + struct memnod *mh_prev; +#endif + const char *mh_file; + unsigned int mh_line; +} MEMHDR; + + +#ifdef SUN4 +#define ALIGN_SIZE 16 +#else +#define ALIGN_SIZE sizeof(double) +#endif +#define HDR_SIZE sizeof(MEMHDR) +#define RESERVE_SIZE (((HDR_SIZE + (ALIGN_SIZE-1)) \ + / ALIGN_SIZE ) * ALIGN_SIZE) + + +#define CLIENT_2_HDR(a) ((MEMHDR *) (((char *) (a)) - RESERVE_SIZE)) +#define HDR_2_CLIENT(a) ((void *) (((char *) (a)) + RESERVE_SIZE)) + + +static unsigned long debugMemSize = 0; +static int block=0; +#ifdef MEM_LIST +static MEMHDR *memlist = NULL; +#endif + +void debugmem_tag_error(void *addr); +#ifdef MEM_LIST +void debugmem_list_add(MEMHDR *); +void debugmem_list_delete(MEMHDR *); +#endif +#define Mem_Tag_Err(a) debugmem_tag_error(a); + +#ifndef TEST_POINT +#define TEST_POINT +#endif + +/** + * xmlMallocLoc: + * @size: an int specifying the size in byte to allocate. + * @file: the file name or NULL + * @file: the line number + * + * a malloc() equivalent, with logging of the allocation info. + * + * Returns a pointer to the allocated area or NULL in case of lack of memory. + */ + +void * +xmlMallocLoc(int size, const char * file, int line) +{ + MEMHDR *p; + +#ifdef DEBUG_MEMORY + fprintf(stderr, "Malloc(%d)\n",size); +#endif + + TEST_POINT + + p = (MEMHDR *) malloc(RESERVE_SIZE+size); + + if (!p) { + fprintf(stderr, "xmlMalloc : Out of free space\n"); + xmlMemoryDump(); + } + p->mh_tag = MEMTAG; + p->mh_number = ++block; + p->mh_size = size; + p->mh_type = MALLOC_TYPE; + p->mh_file = file; + p->mh_line = line; + debugMemSize += size; +#ifdef MEM_LIST + debugmem_list_add(p); +#endif + +#ifdef DEBUG_MEMORY + fprintf(stderr, "Malloc(%d) Ok\n",size); +#endif + + + TEST_POINT + + return(HDR_2_CLIENT(p)); +} + +/** + * xmlMalloc: + * @size: an int specifying the size in byte to allocate. + * + * a malloc() equivalent, with logging of the allocation info. + * + * Returns a pointer to the allocated area or NULL in case of lack of memory. + */ + +void * +xmlMalloc(int size) +{ + return(xmlMallocLoc(size, "none", 0)); +} + +/** + * xmlReallocLoc: + * @ptr: the initial memory block pointer + * @size: an int specifying the size in byte to allocate. + * @file: the file name or NULL + * @file: the line number + * + * a realloc() equivalent, with logging of the allocation info. + * + * Returns a pointer to the allocated area or NULL in case of lack of memory. + */ + +void * +xmlReallocLoc(void *ptr,int size, const char * file, int line) +{ + MEMHDR *p; + unsigned long number; + + TEST_POINT + + p = CLIENT_2_HDR(ptr); + number = p->mh_number; + if (p->mh_tag != MEMTAG) { + Mem_Tag_Err(p); + goto error; + } + p->mh_tag = ~MEMTAG; + debugMemSize -= p->mh_size; +#ifdef MEM_LIST + debugmem_list_delete(p); +#endif + + p = (MEMHDR *) realloc(p,RESERVE_SIZE+size); + if (!p) { + goto error; + } + p->mh_tag = MEMTAG; + p->mh_number = number; + p->mh_type = REALLOC_TYPE; + p->mh_size = size; + p->mh_file = file; + p->mh_line = line; + debugMemSize += size; +#ifdef MEM_LIST + debugmem_list_add(p); +#endif + + TEST_POINT + + return(HDR_2_CLIENT(p)); + +error: + return(NULL); +} + +/** + * xmlRealloc: + * @ptr: the initial memory block pointer + * @size: an int specifying the size in byte to allocate. + * + * a realloc() equivalent, with logging of the allocation info. + * + * Returns a pointer to the allocated area or NULL in case of lack of memory. + */ + +void * +xmlRealloc(void *ptr,int size) { + return(xmlReallocLoc(ptr, size, "none", 0)); +} + +/** + * xmlFree: + * @ptr: the memory block pointer + * + * a free() equivalent, with error checking. + * + * Returns a pointer to the allocated area or NULL in case of lack of memory. + */ + + +void +xmlFree(void *ptr) +{ + MEMHDR *p; + + TEST_POINT + + p = CLIENT_2_HDR(ptr); + if (p->mh_tag != MEMTAG) { + Mem_Tag_Err(p); + goto error; + } + p->mh_tag = ~MEMTAG; + debugMemSize -= p->mh_size; + +#ifdef MEM_LIST + debugmem_list_delete(p); +#endif + free(p); + + TEST_POINT + + return; + +error: + fprintf(stderr, "xmlFree(%X) error\n", (unsigned int) ptr); + return; +} + +/** + * xmlMemStrdupLoc: + * @ptr: the initial string pointer + * @file: the file name or NULL + * @file: the line number + * + * a strdup() equivalent, with logging of the allocation info. + * + * Returns a pointer to the new string or NULL if allocation error occured. + */ + +char * +xmlMemStrdupLoc(const char *str, const char *file, int line) +{ + char *s; + size_t size = strlen(str) + 1; + MEMHDR *p; + + TEST_POINT + + p = (MEMHDR *) malloc(RESERVE_SIZE+size); + if (!p) { + goto error; + } + p->mh_tag = MEMTAG; + p->mh_number = ++block; + p->mh_size = size; + p->mh_type = STRDUP_TYPE; + p->mh_file = file; + p->mh_line = line; + debugMemSize += size; +#ifdef MEM_LIST + debugmem_list_add(p); +#endif + s = HDR_2_CLIENT(p); + + if (s != NULL) + strcpy(s,str); + else + goto error; + + TEST_POINT + + return(s); + +error: + return(NULL); +} + +/** + * xmlMemStrdup: + * @ptr: the initial string pointer + * + * a strdup() equivalent, with logging of the allocation info. + * + * Returns a pointer to the new string or NULL if allocation error occured. + */ + +char * +xmlMemStrdup(const char *str) { + return(xmlMemStrdupLoc(str, "none", 0)); +} + +/** + * xmlMemUsed: + * + * returns the amount of memory currenly allocated + * + * Returns an int representing the amount of memory allocated. + */ + +int +xmlMemUsed(void) { + return(debugMemSize); +} + +/** + * xmlMemDisplay: + * @fp: a FILE descriptor used as the output file, if NULL, the result is + 8 written to the file .memorylist + * + * show in-extenso the memory blocks allocated + */ + +void +xmlMemDisplay(FILE *fp) +{ +#ifdef MEM_LIST + MEMHDR *p; + int idx; + + fprintf(fp," MEMORY ALLOCATED : %lu\n",debugMemSize); + fprintf(fp,"BLOCK NUMBER SIZE TYPE\n"); + idx = 0; + p = memlist; + while (p) { + fprintf(fp,"%-5u %6lu %6u ",idx++,p->mh_number,p->mh_size); + switch (p->mh_type) { + case STRDUP_TYPE:fprintf(fp,"strdup() in ");break; + case MALLOC_TYPE:fprintf(fp,"malloc() in ");break; + case REALLOC_TYPE:fprintf(fp,"realloc() in ");break; + default:fprintf(fp," ??? in ");break; + } + if (p->mh_file != NULL) fprintf(fp,"%s(%d)", p->mh_file, p->mh_line); + if (p->mh_tag != MEMTAG) + fprintf(fp," INVALID"); + fprintf(fp,"\n"); + p = p->mh_next; + } +#else + fprintf(fp,"Memory list not compiled (MEM_LIST not defined !)\n"); +#endif +} + +#ifdef MEM_LIST + +void debugmem_list_add(MEMHDR *p) +{ + p->mh_next = memlist; + p->mh_prev = NULL; + if (memlist) memlist->mh_prev = p; + memlist = p; +#ifdef MEM_LIST_DEBUG + if (stderr) + Mem_Display(stderr); +#endif +} + +void debugmem_list_delete(MEMHDR *p) +{ + if (p->mh_next) + p->mh_next->mh_prev = p->mh_prev; + if (p->mh_prev) + p->mh_prev->mh_next = p->mh_next; + else memlist = p->mh_next; +#ifdef MEM_LIST_DEBUG + if (stderr) + Mem_Display(stderr); +#endif +} + +#endif + +/* + * debugmem_tag_error : internal error function. + */ + +void debugmem_tag_error(void *p) +{ + fprintf(stderr, "Memory tag error occurs :%p \n\t bye\n", p); +#ifdef MEM_LIST + if (stderr) + xmlMemDisplay(stderr); +#endif +} + +FILE *xmlMemoryDumpFile = NULL; + + +/** + * xmlMemoryDump: + * + * Dump in-extenso the memory blocks allocated to the file .memorylist + */ + +void +xmlMemoryDump(void) +{ + FILE *dump; + + dump = fopen(".memdump", "w"); + if (dump == NULL) xmlMemoryDumpFile = stdout; + else xmlMemoryDumpFile = dump; + + xmlMemDisplay(xmlMemoryDumpFile); + + if (dump != NULL) fclose(dump); +} + + +/**************************************************************** + * * + * Initialization Routines * + * * + ****************************************************************/ + +/** + * xmlInitMemory: + * + * Initialize the memory layer. + */ + + +int +xmlInitMemory(void) +{ + int ret; + +#ifdef DEBUG_MEMORY + fprintf(stderr, "xmlInitMemory() Ok\n"); +#endif + ret = 0; + return(ret); +} + +#endif /* ! NO_DEBUG_MEMORY */ diff --git a/xmlmemory.h b/xmlmemory.h new file mode 100644 index 00000000..d28b526c --- /dev/null +++ b/xmlmemory.h @@ -0,0 +1,66 @@ +/* + * memory.h: interface for the memory allocation debug. + * + * Daniel.Veillard@w3.org + */ + + +#ifndef _DEBUG_MEMORY_ALLOC_ +#define _DEBUG_MEMORY_ALLOC_ + +#define NO_DEBUG_MEMORY + +#ifdef NO_DEBUG_MEMORY +#ifdef HAVE_MALLOC_H +#include +#endif + +#define xmlFree(x) free((x)) +#define xmlMalloc(x) malloc(x) +#define xmlRealloc(p, x) realloc((p), (x)) +#define xmlMemStrdup(x) strdup((x)) +#define xmlInitMemory() +#define xmlMemUsed() +#define xmlInitMemory() +#define xmlMemoryDump() +#define xmlMemDisplay(x) + +#else /* ! NO_DEBUG_MEMORY */ +#include + +/* #define DEBUG_MEMORY */ /* */ + +#define DEBUG_MEMORY_LOCATION + +#ifdef DEBUG +#ifndef DEBUG_MEMORY +#define DEBUG_MEMORY +#endif +#endif + +#define MEM_LIST /* keep a list of all the allocated memory blocks */ + +int xmlInitMemory (void); +void * xmlMalloc (int size); +void * xmlRealloc (void *ptr, + int size); +void xmlFree (void *ptr); +char * xmlMemStrdup (const char *str); +int xmlMemUsed (void); +void xmlMemDisplay (FILE *fp); +void xmlMemoryDump (void); +int xmlInitMemory (void); + +#ifdef DEBUG_MEMORY_LOCATION +#define xmlMalloc(x) xmlMallocLoc((x), __FILE__, __LINE__) +#define xmlRealloc(p, x) xmlReallocLoc((p), (x), __FILE__, __LINE__) +#define xmlMemStrdup(x) xmlMemStrdupLoc((x), __FILE__, __LINE__) + +extern void * xmlMallocLoc(int size, const char *file, int line); +extern void * xmlReallocLoc(void *ptr,int size, const char *file, int line); +extern char * xmlMemStrdupLoc(const char *str, const char *file, int line); +#endif /* DEBUG_MEMORY_LOCATION */ +#endif /* ! NO_DEBUG_MEMORY */ + +#endif /* _DEBUG_MEMORY_ALLOC_ */ + diff --git a/xpath.c b/xpath.c index 694d4ef2..4ff7da52 100644 --- a/xpath.c +++ b/xpath.c @@ -14,7 +14,6 @@ */ #include -#include #ifdef HAVE_MATH_H #include #endif @@ -29,6 +28,7 @@ #endif #include #include +#include "xmlmemory.h" #include "tree.h" #include "valid.h" #include "xpath.h" @@ -169,7 +169,7 @@ void xmlXPathStringFunction(xmlXPathParserContextPtr ctxt, int nargs); extern int name##Push(xmlXPathParserContextPtr ctxt, type value) { \ if (ctxt->name##Nr >= ctxt->name##Max) { \ ctxt->name##Max *= 2; \ - ctxt->name##Tab = (void *) realloc(ctxt->name##Tab, \ + ctxt->name##Tab = (void *) xmlRealloc(ctxt->name##Tab, \ ctxt->name##Max * sizeof(ctxt->name##Tab[0])); \ if (ctxt->name##Tab == NULL) { \ fprintf(xmlXPathDebug, "realloc failed !\n"); \ @@ -351,14 +351,14 @@ xmlNodeSetPtr xmlXPathNodeSetCreate(xmlNodePtr val) { xmlNodeSetPtr ret; - ret = (xmlNodeSetPtr) malloc(sizeof(xmlNodeSet)); + ret = (xmlNodeSetPtr) xmlMalloc(sizeof(xmlNodeSet)); if (ret == NULL) { fprintf(xmlXPathDebug, "xmlXPathNewNodeSet: out of memory\n"); return(NULL); } memset(ret, 0 , (size_t) sizeof(xmlNodeSet)); if (val != NULL) { - ret->nodeTab = (xmlNodePtr *) malloc(XML_NODESET_DEFAULT * + ret->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT * sizeof(xmlNodePtr)); if (ret->nodeTab == NULL) { fprintf(xmlXPathDebug, "xmlXPathNewNodeSet: out of memory\n"); @@ -395,7 +395,7 @@ xmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val) { * grow the nodeTab if needed */ if (cur->nodeMax == 0) { - cur->nodeTab = (xmlNodePtr *) malloc(XML_NODESET_DEFAULT * + cur->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT * sizeof(xmlNodePtr)); if (cur->nodeTab == NULL) { fprintf(xmlXPathDebug, "xmlXPathNodeSetAdd: out of memory\n"); @@ -408,7 +408,7 @@ xmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val) { xmlNodePtr *temp; cur->nodeMax *= 2; - temp = (xmlNodePtr *) realloc(cur->nodeTab, cur->nodeMax * + temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax * sizeof(xmlNodePtr)); if (temp == NULL) { fprintf(xmlXPathDebug, "xmlXPathNodeSetAdd: out of memory\n"); @@ -510,12 +510,12 @@ xmlXPathFreeNodeSet(xmlNodeSetPtr obj) { #ifdef DEBUG memset(obj->nodeTab, 0xB , (size_t) sizeof(xmlNodePtr) * obj->nodeMax); #endif - free(obj->nodeTab); + xmlFree(obj->nodeTab); } #ifdef DEBUG memset(obj, 0xB , (size_t) sizeof(xmlNodeSet)); #endif - free(obj); + xmlFree(obj); } #if defined(DEBUG) || defined(DEBUG_STEP) @@ -605,7 +605,7 @@ xmlXPathObjectPtr xmlXPathNewFloat(double val) { xmlXPathObjectPtr ret; - ret = (xmlXPathObjectPtr) malloc(sizeof(xmlXPathObject)); + ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); if (ret == NULL) { fprintf(xmlXPathDebug, "xmlXPathNewFloat: out of memory\n"); return(NULL); @@ -628,7 +628,7 @@ xmlXPathObjectPtr xmlXPathNewBoolean(int val) { xmlXPathObjectPtr ret; - ret = (xmlXPathObjectPtr) malloc(sizeof(xmlXPathObject)); + ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); if (ret == NULL) { fprintf(xmlXPathDebug, "xmlXPathNewFloat: out of memory\n"); return(NULL); @@ -651,7 +651,7 @@ xmlXPathObjectPtr xmlXPathNewString(const CHAR *val) { xmlXPathObjectPtr ret; - ret = (xmlXPathObjectPtr) malloc(sizeof(xmlXPathObject)); + ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); if (ret == NULL) { fprintf(xmlXPathDebug, "xmlXPathNewFloat: out of memory\n"); return(NULL); @@ -674,7 +674,7 @@ xmlXPathObjectPtr xmlXPathNewCString(const char *val) { xmlXPathObjectPtr ret; - ret = (xmlXPathObjectPtr) malloc(sizeof(xmlXPathObject)); + ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); if (ret == NULL) { fprintf(xmlXPathDebug, "xmlXPathNewFloat: out of memory\n"); return(NULL); @@ -698,7 +698,7 @@ xmlXPathObjectPtr xmlXPathNewNodeSet(xmlNodePtr val) { xmlXPathObjectPtr ret; - ret = (xmlXPathObjectPtr) malloc(sizeof(xmlXPathObject)); + ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); if (ret == NULL) { fprintf(xmlXPathDebug, "xmlXPathNewFloat: out of memory\n"); return(NULL); @@ -722,7 +722,7 @@ xmlXPathObjectPtr xmlXPathNewNodeSetList(xmlNodeSetPtr val) { xmlXPathObjectPtr ret; - ret = (xmlXPathObjectPtr) malloc(sizeof(xmlXPathObject)); + ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); if (ret == NULL) { fprintf(xmlXPathDebug, "xmlXPathNewFloat: out of memory\n"); return(NULL); @@ -745,11 +745,11 @@ xmlXPathFreeObject(xmlXPathObjectPtr obj) { if (obj->nodesetval != NULL) xmlXPathFreeNodeSet(obj->nodesetval); if (obj->stringval != NULL) - free(obj->stringval); + xmlFree(obj->stringval); #ifdef DEBUG memset(obj, 0xB , (size_t) sizeof(xmlXPathObject)); #endif - free(obj); + xmlFree(obj); } /************************************************************************ @@ -772,7 +772,7 @@ xmlXPathContextPtr xmlXPathNewContext(xmlDocPtr doc, void *variables, void *functions) { xmlXPathContextPtr ret; - ret = (xmlXPathContextPtr) malloc(sizeof(xmlXPathContext)); + ret = (xmlXPathContextPtr) xmlMalloc(sizeof(xmlXPathContext)); if (ret == NULL) { fprintf(xmlXPathDebug, "xmlXPathNewContext: out of memory\n"); return(NULL); @@ -795,12 +795,12 @@ xmlXPathNewContext(xmlDocPtr doc, void *variables, void *functions) { void xmlXPathFreeContext(xmlXPathContextPtr ctxt) { if (ctxt->namespaces != NULL) - free(ctxt->namespaces); + xmlFree(ctxt->namespaces); #ifdef DEBUG memset(ctxt, 0xB , (size_t) sizeof(xmlXPathContext)); #endif - free(ctxt); + xmlFree(ctxt); } /************************************************************************ @@ -845,7 +845,7 @@ xmlXPathParserContextPtr xmlXPathNewParserContext(const CHAR *str, xmlXPathContextPtr ctxt) { xmlXPathParserContextPtr ret; - ret = (xmlXPathParserContextPtr) malloc(sizeof(xmlXPathParserContext)); + ret = (xmlXPathParserContextPtr) xmlMalloc(sizeof(xmlXPathParserContext)); if (ret == NULL) { fprintf(xmlXPathDebug, "xmlXPathNewParserContext: out of memory\n"); return(NULL); @@ -856,7 +856,7 @@ xmlXPathNewParserContext(const CHAR *str, xmlXPathContextPtr ctxt) { /* Allocate the value stack */ ret->valueTab = (xmlXPathObjectPtr *) - malloc(10 * sizeof(xmlXPathObjectPtr)); + xmlMalloc(10 * sizeof(xmlXPathObjectPtr)); ret->valueNr = 0; ret->valueMax = 10; ret->value = NULL; @@ -875,12 +875,12 @@ xmlXPathFreeParserContext(xmlXPathParserContextPtr ctxt) { #ifdef DEBUG memset(ctxt->valueTab, 0xB , 10 * (size_t) sizeof(xmlXPathObjectPtr)); #endif - free(ctxt->valueTab); + xmlFree(ctxt->valueTab); } #ifdef DEBUG memset(ctxt, 0xB , (size_t) sizeof(xmlXPathParserContext)); #endif - free(ctxt); + xmlFree(ctxt); } /************************************************************************ @@ -936,10 +936,10 @@ xmlXPathEqualNodeSetString(xmlXPathObjectPtr arg, const CHAR *str) { for (i = 0;i < ns->nodeNr;i++) { str2 = xmlNodeGetContent(ns->nodeTab[i]); if ((str2 != NULL) && (!xmlStrcmp(str, str2))) { - free(str2); + xmlFree(str2); return(1); } - free(str2); + xmlFree(str2); } return(0); } @@ -1008,10 +1008,10 @@ xmlXPathEqualNodeSets(xmlXPathObjectPtr arg1, xmlXPathObjectPtr arg2) { for (i = 0;i < ns->nodeNr;i++) { str = xmlNodeGetContent(ns->nodeTab[i]); if ((str != NULL) && (xmlXPathEqualNodeSetString(arg2, str))) { - free(str); + xmlFree(str); return(1); } - free(str); + xmlFree(str); } return(0); } @@ -1729,7 +1729,7 @@ xmlNsPtr xmlXPathNextNamespace(xmlXPathParserContextPtr ctxt, xmlAttrPtr cur) { if ((cur == NULL) || (ctxt->context->namespaces == NULL)) { if (ctxt->context->namespaces != NULL) - free(ctxt->context->namespaces); + xmlFree(ctxt->context->namespaces); ctxt->context->namespaces = xmlGetNsList(ctxt->context->doc, ctxt->context->node); if (ctxt->context->namespaces == NULL) return(NULL); @@ -2162,7 +2162,7 @@ xmlXPathIdFunction(xmlXPathParserContextPtr ctxt, int nargs) { xmlXPathNodeSetAdd(ret->nodesetval, elem); } if (ID != NULL) - free(ID); + xmlFree(ID); while (IS_BLANK(*cur)) cur++; tokens = cur; @@ -2331,7 +2331,7 @@ xmlXPathStringFunction(xmlXPathParserContextPtr ctxt, int nargs) { int i = 0; /* Should be first in document order !!!!! */ res = xmlNodeGetContent(cur->nodesetval->nodeTab[i]); valuePush(ctxt, xmlXPathNewString(res)); - free(res); + xmlFree(res); } xmlXPathFreeObject(cur); return; @@ -2384,7 +2384,7 @@ xmlXPathStringLengthFunction(xmlXPathParserContextPtr ctxt, int nargs) { content = xmlNodeGetContent(ctxt->context->node); valuePush(ctxt, xmlXPathNewFloat(xmlStrlen(content))); - free(content); + xmlFree(content); } return; } @@ -2581,7 +2581,7 @@ xmlXPathSubstringFunction(xmlXPathParserContextPtr ctxt, int nargs) { valuePush(ctxt, xmlXPathNewCString("")); else { valuePush(ctxt, xmlXPathNewString(ret)); - free(ret); + xmlFree(ret); } xmlXPathFreeObject(str); } @@ -3112,7 +3112,7 @@ xmlXPathEvalLiteral(xmlXPathParserContextPtr ctxt) { } if (ret == NULL) return; valuePush(ctxt, xmlXPathNewString(ret)); - free(ret); + xmlFree(ret); } /** @@ -3150,8 +3150,8 @@ xmlXPathEvalVariableReference(xmlXPathParserContextPtr ctxt) { ERROR(XPATH_UNDEF_VARIABLE_ERROR); } valuePush(ctxt, value); - if (prefix != NULL) free(prefix); - free(name); + if (prefix != NULL) xmlFree(prefix); + xmlFree(name); } @@ -3345,7 +3345,7 @@ xmlXPathEvalFunctionCall(xmlXPathParserContextPtr ctxt) { } func = xmlXPathIsFunction(ctxt, name); if (func == NULL) { - free(name); + xmlFree(name); ERROR(XPATH_UNKNOWN_FUNC_ERROR); } #ifdef DEBUG_EXPR @@ -3353,7 +3353,7 @@ xmlXPathEvalFunctionCall(xmlXPathParserContextPtr ctxt) { #endif if (CUR != '(') { - free(name); + xmlFree(name); ERROR(XPATH_EXPR_ERROR); } NEXT; @@ -3363,13 +3363,13 @@ xmlXPathEvalFunctionCall(xmlXPathParserContextPtr ctxt) { nbargs++; if (CUR == ')') break; if (CUR != ',') { - free(name); + xmlFree(name); ERROR(XPATH_EXPR_ERROR); } NEXT; } NEXT; - free(name); + xmlFree(name); func(ctxt, nbargs); } @@ -3540,7 +3540,7 @@ xmlXPathEvalPathExpr(xmlXPathParserContextPtr ctxt) { else xmlXPathEvalFilterExpr(ctxt); if (name != NULL) - free(name); + xmlFree(name); } } @@ -3953,7 +3953,7 @@ xmlXPathEvalBasis(xmlXPathParserContextPtr ctxt) { top = ctxt->value; func = xmlXPathIsFunction(ctxt, name); if (func == NULL) { - free(name); + xmlFree(name); ERROR(XPATH_UNKNOWN_FUNC_ERROR); } #ifdef DEBUG_EXPR @@ -3961,7 +3961,7 @@ xmlXPathEvalBasis(xmlXPathParserContextPtr ctxt) { #endif if (CUR != '(') { - free(name); + xmlFree(name); ERROR(XPATH_EXPR_ERROR); } NEXT; @@ -3971,13 +3971,13 @@ xmlXPathEvalBasis(xmlXPathParserContextPtr ctxt) { nbargs++; if (CUR == ')') break; if (CUR != ',') { - free(name); + xmlFree(name); ERROR(XPATH_EXPR_ERROR); } NEXT; } NEXT; - free(name); + xmlFree(name); func(ctxt, nbargs); if ((ctxt->value != top) && (ctxt->value != NULL) && @@ -4018,7 +4018,7 @@ xmlXPathEvalBasis(xmlXPathParserContextPtr ctxt) { goto search_nodes; case NODE_TYPE_PI: if (CUR != '(') break; - if (name != NULL) free(name); + if (name != NULL) xmlFree(name); name = NULL; if (NXT(1) != ')') { xmlXPathObjectPtr cur; @@ -4080,7 +4080,7 @@ parse_NodeTest: nodetest = NODE_TEST_ALL; } else { if (name != NULL) - free(name); + xmlFree(name); name = xmlXPathParseQName(ctxt, &prefix); if (name == NULL) { ERROR(XPATH_EXPR_ERROR); @@ -4113,7 +4113,7 @@ parse_NodeTest: goto search_nodes; case NODE_TYPE_PI: if (CUR != '(') break; - if (name != NULL) free(name); + if (name != NULL) xmlFree(name); name = NULL; if (NXT(1) != ')') { xmlXPathObjectPtr cur; @@ -4167,8 +4167,8 @@ search_nodes: fprintf(xmlXPathDebug, "Basis : "); xmlXPathDebugNodeSet(stdout, ctxt->context->nodelist); #endif - if (name != NULL) free(name); - if (prefix != NULL) free(prefix); + if (name != NULL) xmlFree(name); + if (prefix != NULL) xmlFree(prefix); } /**