Annotation of XML/xmlmemory.c, revision 1.18

1.1       daniel      1: /*
                      2:  * memory.c:  libxml memory allocator wrapper.
                      3:  *
                      4:  * Daniel.Veillard@w3.org
                      5:  */
                      6: 
1.3       daniel      7: #ifdef WIN32
1.9       daniel      8: #include "win32config.h"
1.3       daniel      9: #else
1.4       daniel     10: #include "config.h"
1.3       daniel     11: #endif
                     12: 
                     13: #include <stdio.h>
                     14: #include <string.h>
                     15: 
                     16: #ifdef HAVE_SYS_TYPES_H
1.1       daniel     17: #include <sys/types.h>
1.3       daniel     18: #endif
1.4       daniel     19: #ifdef HAVE_TIME_H
                     20: #include <time.h>
                     21: #endif
1.3       daniel     22: #ifdef HAVE_MALLOC_H
1.1       daniel     23: #include <malloc.h>
1.3       daniel     24: #endif
1.7       daniel     25: #ifdef HAVE_STDLIB_H
                     26: #include <stdlib.h>
                     27: #endif
1.11      daniel     28: #ifdef HAVE_CTYPE_H
                     29: #include <ctype.h>
                     30: #endif
1.7       daniel     31: 
1.3       daniel     32: 
1.14      daniel     33: #include <libxml/xmlmemory.h>
1.1       daniel     34: 
                     35: #ifdef xmlMalloc
                     36: #undef xmlMalloc
                     37: #endif
                     38: #ifdef xmlRealloc
                     39: #undef xmlRealloc
                     40: #endif
                     41: #ifdef xmlMemStrdup
                     42: #undef xmlMemStrdup
                     43: #endif
1.6       daniel     44: 
1.1       daniel     45: 
                     46: /*
                     47:  * Each of the blocks allocated begin with a header containing informations
                     48:  */
                     49: 
                     50: #define MEMTAG 0x5aa5
                     51: 
                     52: #define MALLOC_TYPE 1
                     53: #define REALLOC_TYPE 2
                     54: #define STRDUP_TYPE 3
                     55: 
                     56: typedef struct memnod {
                     57:     unsigned int   mh_tag;
                     58:     unsigned int   mh_type;
                     59:     unsigned long  mh_number;
                     60:     size_t         mh_size;
                     61: #ifdef MEM_LIST
                     62:    struct memnod *mh_next;
                     63:    struct memnod *mh_prev;
                     64: #endif
                     65:    const char    *mh_file;
                     66:    unsigned int   mh_line;
                     67: }  MEMHDR;
                     68: 
                     69: 
                     70: #ifdef SUN4
                     71: #define ALIGN_SIZE  16
                     72: #else
                     73: #define ALIGN_SIZE  sizeof(double)
                     74: #endif
                     75: #define HDR_SIZE    sizeof(MEMHDR)
                     76: #define RESERVE_SIZE (((HDR_SIZE + (ALIGN_SIZE-1)) \
                     77:                      / ALIGN_SIZE ) * ALIGN_SIZE)
                     78: 
                     79: 
                     80: #define CLIENT_2_HDR(a) ((MEMHDR *) (((char *) (a)) - RESERVE_SIZE))
                     81: #define HDR_2_CLIENT(a)    ((void *) (((char *) (a)) + RESERVE_SIZE))
                     82: 
                     83: 
                     84: static unsigned long  debugMemSize = 0;
1.7       daniel     85: static unsigned long  debugMaxMemSize = 0;
1.1       daniel     86: static int block=0;
1.7       daniel     87: int xmlMemStopAtBlock = 0;
                     88: int xmlMemInitialized = 0;
1.1       daniel     89: #ifdef MEM_LIST
                     90: static MEMHDR *memlist = NULL;
                     91: #endif
                     92: 
                     93: void debugmem_tag_error(void *addr);
                     94: #ifdef MEM_LIST
                     95: void  debugmem_list_add(MEMHDR *);
                     96: void debugmem_list_delete(MEMHDR *);
                     97: #endif
                     98: #define Mem_Tag_Err(a) debugmem_tag_error(a);
                     99: 
                    100: #ifndef TEST_POINT
                    101: #define TEST_POINT
                    102: #endif
                    103: 
                    104: /**
1.7       daniel    105:  * xmlMallocBreakpoint:
                    106:  *
                    107:  * Breakpoint to use in conjunction with xmlMemStopAtBlock. When the block
                    108:  * number reaches the specified value this function is called. One need to add a breakpoint
                    109:  * to it to get the context in which the given block is allocated.
                    110:  */
                    111: 
                    112: void
                    113: xmlMallocBreakpoint(void) {
                    114:     fprintf(stderr, "xmlMallocBreakpoint reached on block %d\n", xmlMemStopAtBlock);
                    115: }
                    116: 
                    117: /**
1.1       daniel    118:  * xmlMallocLoc:
                    119:  * @size:  an int specifying the size in byte to allocate.
                    120:  * @file:  the file name or NULL
1.15      daniel    121:  * @line:  the line number
1.1       daniel    122:  *
                    123:  * a malloc() equivalent, with logging of the allocation info.
                    124:  *
                    125:  * Returns a pointer to the allocated area or NULL in case of lack of memory.
                    126:  */
                    127: 
                    128: void *
                    129: xmlMallocLoc(int size, const char * file, int line)
                    130: {
                    131:     MEMHDR *p;
                    132:     
1.7       daniel    133:     if (!xmlMemInitialized) xmlInitMemory();
1.1       daniel    134: #ifdef DEBUG_MEMORY
                    135:     fprintf(stderr, "Malloc(%d)\n",size);
                    136: #endif
                    137: 
                    138:     TEST_POINT
                    139:     
                    140:     p = (MEMHDR *) malloc(RESERVE_SIZE+size);
                    141: 
                    142:     if (!p) {
1.8       daniel    143:        fprintf(stderr, "xmlMalloc : Out of free space\n");
                    144:        xmlMemoryDump();
                    145:        return(NULL);
1.1       daniel    146:     }   
                    147:     p->mh_tag = MEMTAG;
                    148:     p->mh_number = ++block;
                    149:     p->mh_size = size;
                    150:     p->mh_type = MALLOC_TYPE;
                    151:     p->mh_file = file;
                    152:     p->mh_line = line;
                    153:     debugMemSize += size;
1.7       daniel    154:     if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize;
1.1       daniel    155: #ifdef MEM_LIST
                    156:     debugmem_list_add(p);
                    157: #endif
                    158: 
                    159: #ifdef DEBUG_MEMORY
                    160:     fprintf(stderr, "Malloc(%d) Ok\n",size);
                    161: #endif
                    162:     
1.7       daniel    163:     if (xmlMemStopAtBlock == block) xmlMallocBreakpoint();
1.1       daniel    164: 
                    165:     TEST_POINT
                    166: 
                    167:     return(HDR_2_CLIENT(p));
                    168: }
                    169: 
                    170: /**
1.12      daniel    171:  * xmlMemMalloc:
1.1       daniel    172:  * @size:  an int specifying the size in byte to allocate.
                    173:  *
                    174:  * a malloc() equivalent, with logging of the allocation info.
                    175:  *
                    176:  * Returns a pointer to the allocated area or NULL in case of lack of memory.
                    177:  */
                    178: 
                    179: void *
1.12      daniel    180: xmlMemMalloc(int size)
1.1       daniel    181: {
                    182:     return(xmlMallocLoc(size, "none", 0));
                    183: }
                    184: 
                    185: /**
                    186:  * xmlReallocLoc:
                    187:  * @ptr:  the initial memory block pointer
                    188:  * @size:  an int specifying the size in byte to allocate.
                    189:  * @file:  the file name or NULL
1.15      daniel    190:  * @line:  the line number
1.1       daniel    191:  *
                    192:  * a realloc() equivalent, with logging of the allocation info.
                    193:  *
                    194:  * Returns a pointer to the allocated area or NULL in case of lack of memory.
                    195:  */
                    196: 
                    197: void *
                    198: xmlReallocLoc(void *ptr,int size, const char * file, int line)
                    199: {
                    200:     MEMHDR *p;
                    201:     unsigned long number;
                    202: 
1.7       daniel    203:     if (!xmlMemInitialized) xmlInitMemory();
1.1       daniel    204:     TEST_POINT
                    205: 
                    206:     p = CLIENT_2_HDR(ptr);
                    207:     number = p->mh_number;
                    208:     if (p->mh_tag != MEMTAG) {
1.4       daniel    209:        Mem_Tag_Err(p);
1.1       daniel    210:         goto error;
                    211:     }
                    212:     p->mh_tag = ~MEMTAG;
                    213:     debugMemSize -= p->mh_size;
                    214: #ifdef MEM_LIST
                    215:     debugmem_list_delete(p);
                    216: #endif
                    217: 
                    218:     p = (MEMHDR *) realloc(p,RESERVE_SIZE+size);
                    219:     if (!p) {
                    220:         goto error;
                    221:     }
                    222:     p->mh_tag = MEMTAG;
                    223:     p->mh_number = number;
                    224:     p->mh_type = REALLOC_TYPE;
                    225:     p->mh_size = size;
                    226:     p->mh_file = file;
                    227:     p->mh_line = line;
                    228:     debugMemSize += size;
1.7       daniel    229:     if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize;
1.1       daniel    230: #ifdef MEM_LIST
                    231:     debugmem_list_add(p);
                    232: #endif
                    233: 
                    234:     TEST_POINT
                    235: 
                    236:     return(HDR_2_CLIENT(p));
                    237:     
                    238: error:    
                    239:     return(NULL);
                    240: }
                    241: 
                    242: /**
1.12      daniel    243:  * xmlMemRealloc:
1.1       daniel    244:  * @ptr:  the initial memory block pointer
                    245:  * @size:  an int specifying the size in byte to allocate.
                    246:  *
                    247:  * a realloc() equivalent, with logging of the allocation info.
                    248:  *
                    249:  * Returns a pointer to the allocated area or NULL in case of lack of memory.
                    250:  */
                    251: 
                    252: void *
1.12      daniel    253: xmlMemRealloc(void *ptr,int size) {
1.1       daniel    254:     return(xmlReallocLoc(ptr, size, "none", 0));
                    255: }
                    256: 
                    257: /**
1.12      daniel    258:  * xmlMemFree:
1.1       daniel    259:  * @ptr:  the memory block pointer
                    260:  *
                    261:  * a free() equivalent, with error checking.
                    262:  */
                    263: void
1.12      daniel    264: xmlMemFree(void *ptr)
1.1       daniel    265: {
                    266:     MEMHDR *p;
                    267: 
                    268:     TEST_POINT
                    269: 
                    270:     p = CLIENT_2_HDR(ptr);
                    271:     if (p->mh_tag != MEMTAG) {
1.4       daniel    272:        Mem_Tag_Err(p);
                    273:        goto error;
1.1       daniel    274:     }
                    275:     p->mh_tag = ~MEMTAG;
                    276:     debugMemSize -= p->mh_size;
                    277: 
                    278: #ifdef MEM_LIST
                    279:     debugmem_list_delete(p);
                    280: #endif
                    281:     free(p);
                    282: 
                    283:     TEST_POINT
                    284: 
                    285:     return;
                    286:     
                    287: error:    
                    288:     fprintf(stderr, "xmlFree(%X) error\n", (unsigned int) ptr);
                    289:     return;
                    290: }
                    291: 
                    292: /**
                    293:  * xmlMemStrdupLoc:
                    294:  * @ptr:  the initial string pointer
                    295:  * @file:  the file name or NULL
1.15      daniel    296:  * @line:  the line number
1.1       daniel    297:  *
                    298:  * a strdup() equivalent, with logging of the allocation info.
                    299:  *
                    300:  * Returns a pointer to the new string or NULL if allocation error occured.
                    301:  */
                    302: 
                    303: char *
                    304: xmlMemStrdupLoc(const char *str, const char *file, int line)
                    305: {
                    306:     char *s;
                    307:     size_t size = strlen(str) + 1;
                    308:     MEMHDR *p;
                    309: 
1.7       daniel    310:     if (!xmlMemInitialized) xmlInitMemory();
1.1       daniel    311:     TEST_POINT
                    312: 
                    313:     p = (MEMHDR *) malloc(RESERVE_SIZE+size);
                    314:     if (!p) {
1.4       daniel    315:       goto error;
1.1       daniel    316:     }
                    317:     p->mh_tag = MEMTAG;
                    318:     p->mh_number = ++block;
                    319:     p->mh_size = size;
                    320:     p->mh_type = STRDUP_TYPE;
                    321:     p->mh_file = file;
                    322:     p->mh_line = line;
                    323:     debugMemSize += size;
1.7       daniel    324:     if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize;
1.1       daniel    325: #ifdef MEM_LIST
                    326:     debugmem_list_add(p);
                    327: #endif
1.16      veillard  328:     s = (char *) HDR_2_CLIENT(p);
1.1       daniel    329:     
1.7       daniel    330:     if (xmlMemStopAtBlock == block) xmlMallocBreakpoint();
                    331: 
1.1       daniel    332:     if (s != NULL)
1.4       daniel    333:       strcpy(s,str);
1.1       daniel    334:     else
1.4       daniel    335:       goto error;
1.1       daniel    336:     
                    337:     TEST_POINT
                    338: 
                    339:     return(s);
                    340: 
                    341: error:
                    342:     return(NULL);
                    343: }
                    344: 
                    345: /**
1.12      daniel    346:  * xmlMemoryStrdup:
1.1       daniel    347:  * @ptr:  the initial string pointer
                    348:  *
                    349:  * a strdup() equivalent, with logging of the allocation info.
                    350:  *
                    351:  * Returns a pointer to the new string or NULL if allocation error occured.
                    352:  */
                    353: 
                    354: char *
1.12      daniel    355: xmlMemoryStrdup(const char *str) {
1.1       daniel    356:     return(xmlMemStrdupLoc(str, "none", 0));
                    357: }
                    358: 
                    359: /**
                    360:  * xmlMemUsed:
                    361:  *
                    362:  * returns the amount of memory currenly allocated
                    363:  *
                    364:  * Returns an int representing the amount of memory allocated.
                    365:  */
                    366: 
                    367: int
                    368: xmlMemUsed(void) {
                    369:      return(debugMemSize);
                    370: }
                    371: 
1.11      daniel    372: #ifdef MEM_LIST
                    373: /**
                    374:  * xmlMemContentShow:
                    375:  * @fp:  a FILE descriptor used as the output file
                    376:  * @p:  a memory block header
                    377:  *
                    378:  * tries to show some content from the memory block
                    379:  */
                    380: 
                    381: void
                    382: xmlMemContentShow(FILE *fp, MEMHDR *p)
                    383: {
                    384:     int i,j,len = p->mh_size;
1.16      veillard  385:     const char *buf = (const char *) HDR_2_CLIENT(p);
1.11      daniel    386: 
1.18    ! veillard  387:     if (p == NULL) {
        !           388:        fprintf(fp, " NULL");
        !           389:        return;
        !           390:     }
        !           391: 
1.11      daniel    392:     for (i = 0;i < len;i++) {
                    393:         if (buf[i] == 0) break;
                    394:        if (!isprint(buf[i])) break;
                    395:     }
                    396:     if ((i < 4) && ((buf[i] != 0) || (i == 0))) {
                    397:         if (len >= 4) {
                    398:            MEMHDR *q;
                    399:            void *cur;
                    400: 
                    401:             for (j = 0;j < len -3;j += 4) {
                    402:                cur = *((void **) &buf[j]);
                    403:                q = CLIENT_2_HDR(cur);
                    404:                p = memlist;
                    405:                while (p != NULL) {
                    406:                    if (p == q) break;
                    407:                    p = p->mh_next;
                    408:                }
1.18    ! veillard  409:                if ((p != NULL) && (p == q)) {
1.11      daniel    410:                    fprintf(fp, " pointer to #%lu at index %d",
                    411:                            p->mh_number, j);
                    412:                    return;
                    413:                }
                    414:            }
                    415:        }
                    416:     } else if ((i == 0) && (buf[i] == 0)) {
                    417:         fprintf(fp," null");
                    418:     } else {
                    419:         if (buf[i] == 0) fprintf(fp," \"%.25s\"", buf); 
                    420:        else {
                    421:             fprintf(fp," [");
                    422:            for (j = 0;j < i;j++)
                    423:                 fprintf(fp,"%c", buf[j]);
                    424:             fprintf(fp,"]");
                    425:        }
                    426:     }
                    427: }
                    428: #endif
                    429: 
1.1       daniel    430: /**
1.10      daniel    431:  * xmlMemShow:
                    432:  * @fp:  a FILE descriptor used as the output file
                    433:  * @nr:  number of entries to dump
                    434:  *
                    435:  * show a show display of the memory allocated, and dump
                    436:  * the @nr last allocated areas which were not freed
                    437:  */
                    438: 
                    439: void
                    440: xmlMemShow(FILE *fp, int nr)
                    441: {
                    442: #ifdef MEM_LIST
                    443:     MEMHDR *p;
                    444: #endif
                    445: 
                    446:     if (fp != NULL)
                    447:        fprintf(fp,"      MEMORY ALLOCATED : %lu, MAX was %lu\n",
                    448:                debugMemSize, debugMaxMemSize);
                    449: #ifdef MEM_LIST
                    450:     if (nr > 0) {
                    451:        fprintf(fp,"NUMBER   SIZE  TYPE   WHERE\n");
                    452:        p = memlist;
                    453:        while ((p) && nr > 0) {
                    454:              fprintf(fp,"%6lu %6u ",p->mh_number,p->mh_size);
                    455:            switch (p->mh_type) {
                    456:               case STRDUP_TYPE:fprintf(fp,"strdup()  in ");break;
                    457:               case MALLOC_TYPE:fprintf(fp,"malloc()  in ");break;
                    458:              case REALLOC_TYPE:fprintf(fp,"realloc() in ");break;
                    459:                        default:fprintf(fp,"   ???    in ");break;
                    460:            }
                    461:            if (p->mh_file != NULL)
                    462:                fprintf(fp,"%s(%d)", p->mh_file, p->mh_line);
                    463:            if (p->mh_tag != MEMTAG)
                    464:                fprintf(fp,"  INVALID");
1.11      daniel    465:            xmlMemContentShow(fp, p);
1.10      daniel    466:            fprintf(fp,"\n");
                    467:            nr--;
                    468:            p = p->mh_next;
                    469:        }
                    470:     }
                    471: #endif /* MEM_LIST */    
                    472: }
                    473: 
                    474: /**
1.1       daniel    475:  * xmlMemDisplay:
                    476:  * @fp:  a FILE descriptor used as the output file, if NULL, the result is
1.10      daniel    477:  *       written to the file .memorylist
1.1       daniel    478:  *
                    479:  * show in-extenso the memory blocks allocated
                    480:  */
                    481: 
                    482: void
                    483: xmlMemDisplay(FILE *fp)
                    484: {
                    485: #ifdef MEM_LIST
1.4       daniel    486:     MEMHDR *p;
                    487:     int     idx;
                    488: #if defined(HAVE_LOCALTIME) && defined(HAVE_STRFTIME)
1.5       daniel    489:     time_t currentTime;
1.4       daniel    490:     char buf[500];
                    491:     struct tm * tstruct;
                    492: 
1.5       daniel    493:     currentTime = time(NULL);
                    494:     tstruct = localtime(&currentTime);
1.4       daniel    495:     strftime(buf, sizeof(buf) - 1, "%c", tstruct);
                    496:     fprintf(fp,"      %s\n\n", buf);
                    497: #endif
                    498: 
1.1       daniel    499:     
1.7       daniel    500:     fprintf(fp,"      MEMORY ALLOCATED : %lu, MAX was %lu\n",
                    501:             debugMemSize, debugMaxMemSize);
1.4       daniel    502:     fprintf(fp,"BLOCK  NUMBER   SIZE  TYPE\n");
                    503:     idx = 0;
                    504:     p = memlist;
                    505:     while (p) {
1.1       daniel    506:          fprintf(fp,"%-5u  %6lu %6u ",idx++,p->mh_number,p->mh_size);
1.4       daniel    507:         switch (p->mh_type) {
                    508:            case STRDUP_TYPE:fprintf(fp,"strdup()  in ");break;
                    509:            case MALLOC_TYPE:fprintf(fp,"malloc()  in ");break;
                    510:           case REALLOC_TYPE:fprintf(fp,"realloc() in ");break;
                    511:                     default:fprintf(fp,"   ???    in ");break;
                    512:         }
1.1       daniel    513:          if (p->mh_file != NULL) fprintf(fp,"%s(%d)", p->mh_file, p->mh_line);
1.4       daniel    514:         if (p->mh_tag != MEMTAG)
1.1       daniel    515:              fprintf(fp,"  INVALID");
1.11      daniel    516:        xmlMemContentShow(fp, p);
1.4       daniel    517:         fprintf(fp,"\n");
                    518:         p = p->mh_next;
                    519:     }
1.1       daniel    520: #else
1.4       daniel    521:     fprintf(fp,"Memory list not compiled (MEM_LIST not defined !)\n");
1.1       daniel    522: #endif
                    523: }
                    524: 
                    525: #ifdef MEM_LIST
                    526: 
                    527: void debugmem_list_add(MEMHDR *p)
                    528: {
1.4       daniel    529:      p->mh_next = memlist;
                    530:      p->mh_prev = NULL;
                    531:      if (memlist) memlist->mh_prev = p;
                    532:      memlist = p;
1.1       daniel    533: #ifdef MEM_LIST_DEBUG
1.4       daniel    534:      if (stderr)
                    535:      Mem_Display(stderr);
1.1       daniel    536: #endif
                    537: }
                    538: 
                    539: void debugmem_list_delete(MEMHDR *p)
                    540: {
1.4       daniel    541:      if (p->mh_next)
                    542:      p->mh_next->mh_prev = p->mh_prev;
                    543:      if (p->mh_prev)
                    544:      p->mh_prev->mh_next = p->mh_next;
                    545:      else memlist = p->mh_next;
1.1       daniel    546: #ifdef MEM_LIST_DEBUG
1.4       daniel    547:      if (stderr)
                    548:      Mem_Display(stderr);
1.1       daniel    549: #endif
                    550: }
                    551: 
                    552: #endif
                    553: 
                    554: /*
                    555:  * debugmem_tag_error : internal error function.
                    556:  */
                    557:  
                    558: void debugmem_tag_error(void *p)
                    559: {
1.4       daniel    560:      fprintf(stderr, "Memory tag error occurs :%p \n\t bye\n", p);
1.1       daniel    561: #ifdef MEM_LIST
1.4       daniel    562:      if (stderr)
                    563:      xmlMemDisplay(stderr);
1.1       daniel    564: #endif
                    565: }
                    566: 
                    567: FILE *xmlMemoryDumpFile = NULL;
                    568: 
                    569: 
                    570: /**
                    571:  * xmlMemoryDump:
                    572:  *
                    573:  * Dump in-extenso the memory blocks allocated to the file .memorylist
                    574:  */
                    575: 
                    576: void
                    577: xmlMemoryDump(void)
                    578: {
1.13      daniel    579: #if defined(DEBUG_MEMORY_LOCATION) | defined(DEBUG_MEMORY)
1.1       daniel    580:     FILE *dump;
                    581: 
                    582:     dump = fopen(".memdump", "w");
                    583:     if (dump == NULL) xmlMemoryDumpFile = stdout;
                    584:     else xmlMemoryDumpFile = dump;
                    585: 
                    586:     xmlMemDisplay(xmlMemoryDumpFile);
                    587: 
                    588:     if (dump != NULL) fclose(dump);
1.13      daniel    589: #endif
1.1       daniel    590: }
                    591: 
                    592: 
                    593: /****************************************************************
                    594:  *                                                             *
                    595:  *             Initialization Routines                         *
                    596:  *                                                             *
                    597:  ****************************************************************/
                    598: 
1.12      daniel    599: #if defined(DEBUG_MEMORY_LOCATION) | defined(DEBUG_MEMORY)
1.13      daniel    600: xmlFreeFunc xmlFree = (xmlFreeFunc) xmlMemFree;
                    601: xmlMallocFunc xmlMalloc = (xmlMallocFunc) xmlMemMalloc;
                    602: xmlReallocFunc xmlRealloc = (xmlReallocFunc) xmlMemRealloc;
                    603: xmlStrdupFunc xmlMemStrdup = (xmlStrdupFunc) xmlMemoryStrdup;
1.12      daniel    604: #else
1.13      daniel    605: xmlFreeFunc xmlFree = (xmlFreeFunc) free;
                    606: xmlMallocFunc xmlMalloc = (xmlMallocFunc) malloc;
                    607: xmlReallocFunc xmlRealloc = (xmlReallocFunc) realloc;
                    608: xmlStrdupFunc xmlMemStrdup = (xmlStrdupFunc) strdup;
1.12      daniel    609: #endif
                    610: 
1.1       daniel    611: /**
                    612:  * xmlInitMemory:
                    613:  *
                    614:  * Initialize the memory layer.
1.6       daniel    615:  *
                    616:  * Returns 0 on success
1.1       daniel    617:  */
                    618: 
1.12      daniel    619: static int xmlInitMemoryDone = 0;
1.1       daniel    620: 
                    621: int
                    622: xmlInitMemory(void)
                    623: {
                    624:      int ret;
1.7       daniel    625:      
                    626: #ifdef HAVE_STDLIB_H
                    627:      char *breakpoint;
1.12      daniel    628: #endif     
                    629: 
                    630:      if (xmlInitMemoryDone) return(-1);
1.7       daniel    631: 
1.12      daniel    632: #ifdef HAVE_STDLIB_H
1.7       daniel    633:      breakpoint = getenv("XML_MEM_BREAKPOINT");
                    634:      if (breakpoint != NULL) {
                    635:          sscanf(breakpoint, "%d", &xmlMemStopAtBlock);
                    636:      }
                    637: #endif     
1.1       daniel    638:     
                    639: #ifdef DEBUG_MEMORY
                    640:      fprintf(stderr, "xmlInitMemory() Ok\n");
                    641: #endif     
                    642:      ret = 0;
                    643:      return(ret);
1.12      daniel    644: }
                    645: 
                    646: /**
                    647:  * xmlMemSetup:
                    648:  * @freeFunc: the free() function to use
                    649:  * @mallocFunc: the malloc() function to use
                    650:  * @reallocFunc: the realloc() function to use
                    651:  * @strdupFunc: the strdup() function to use
                    652:  *
                    653:  * Override the default memory access functions with a new set
1.13      daniel    654:  * This has to be called before any other libxml routines !
                    655:  *
                    656:  * Should this be blocked if there was already some allocations
                    657:  * done ?
1.12      daniel    658:  *
                    659:  * Returns 0 on success
                    660:  */
                    661: int
                    662: xmlMemSetup(xmlFreeFunc freeFunc, xmlMallocFunc mallocFunc,
                    663:             xmlReallocFunc reallocFunc, xmlStrdupFunc strdupFunc) {
1.17      veillard  664:     if (freeFunc == NULL)
1.12      daniel    665:        return(-1);
1.17      veillard  666:     if (mallocFunc == NULL)
1.12      daniel    667:        return(-1);
1.17      veillard  668:     if (reallocFunc == NULL)
1.12      daniel    669:        return(-1);
1.17      veillard  670:     if (strdupFunc == NULL)
1.12      daniel    671:        return(-1);
                    672:     xmlFree = freeFunc;
                    673:     xmlMalloc = mallocFunc;
                    674:     xmlRealloc = reallocFunc;
                    675:     xmlMemStrdup = strdupFunc;
                    676:     return(0);
                    677: }
                    678: 
                    679: /**
                    680:  * xmlMemGet:
                    681:  * @freeFunc: the free() function in use
                    682:  * @mallocFunc: the malloc() function in use
                    683:  * @reallocFunc: the realloc() function in use
                    684:  * @strdupFunc: the strdup() function in use
                    685:  *
                    686:  * Return the memory access functions set currently in use
                    687:  *
                    688:  * Returns 0 on success
                    689:  */
                    690: int
                    691: xmlMemGet(xmlFreeFunc *freeFunc, xmlMallocFunc *mallocFunc,
                    692:          xmlReallocFunc *reallocFunc, xmlStrdupFunc *strdupFunc) {
1.13      daniel    693:     if (freeFunc != NULL) *freeFunc = xmlFree;
                    694:     if (mallocFunc != NULL) *mallocFunc = xmlMalloc;
                    695:     if (reallocFunc != NULL) *reallocFunc = xmlRealloc;
                    696:     if (strdupFunc != NULL) *strdupFunc = xmlMemStrdup;
1.12      daniel    697:     return(0);
1.1       daniel    698: }
                    699: 

Webmaster