/* viDOOM - level editor for DOOM Copyright (C) 2000 Ian Cowburn (ianc@noddybox.demon.co.uk) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ------------------------------------------------------------------------- Memory allocation code */ static const char rcs_id[]="$Id$"; #include "config.h" #include #include #include "mem.h" #include "gfx.h" #include "file.h" #include "debug.h" /* Set MEMSTAT to the following levels : 0 - Nodebug information 1 - Fatal debug information (still allocated block on failure, general release errors) 2 - All debug information Regardless of the above no debug is generated if DEBUG is not set */ #ifndef DEBUG #define MEMSTAT 0 #else #define MEMSTAT 1 #endif typedef struct memmap { char file[64]; int line; void *addr; struct memmap *next; struct memmap *prev; } MemMap; static MemMap *mmap=NULL; static void DumpMemList(char *p) { MemMap *m; # if MEMSTAT == 0 return; # endif Debug(("**** %s ****\n",p)); Debug(("Still waiting to be freed:\n")); if ((m=mmap)) while(m) { Debug(("\t%p allocated to %s:%d\n",m->addr,m->file,m->line)); m=m->next; } else Debug(("\tNONE\n")); } static void AddMM(char *mode,char *file, int line, void *addr) { MemMap *n; # if MEMSTAT == 0 return; # endif n=malloc(sizeof(MemMap)); strcpy(n->file,Basename(file)); n->line=line; n->addr=addr; if (!mmap) { mmap=n; n->next=NULL; n->prev=NULL; } else { mmap->prev=n; n->next=mmap; n->prev=NULL; mmap=n; } # if MEMSTAT == 2 Debug(("%s: Memory %p allocated to %s:%d\n",mode,addr,file,line)); # endif } static void RmMM(char *mode, char *file, int line, void *addr) { MemMap *n; int del; # if MEMSTAT == 0 return; # endif del=0; n=mmap; while(n) if (n->addr==addr) { # if MEMSTAT == 2 Debug(("%s: Address %p freed by %s:%d\n",mode,addr,file,line)); # endif if (n->prev) n->prev->next=n->next; else mmap=n->next; if (n->next) n->next->prev=n->prev; free(n); n=NULL; del=1; } else n=n->next; if (!del) Debug(("%s: ***** Address %p not found - freed by %s:%d\n", mode,addr,file,line)); } void *FGrab(char *fn, int line, int len) { char *ptr; if (len==0) len=1; if (!(ptr=malloc(len))) { DumpMemList("GRAB FAILED"); GFX_exit(EXIT_FAILURE,"Memory allocation failed!\n" "%s:%d Grab(%d)\n",fn,line,len); } memset(ptr,0,len); AddMM("Grab",fn,line,ptr); return(ptr); } void *FReGrab(char *fn, int line, void *ptr, int len) { if (len==0) len=1; if (ptr) RmMM("ReGrab(RELEASE)",fn,line,ptr); if (!(ptr=realloc(ptr,len))) { DumpMemList("REGRAB FAILED"); GFX_exit(EXIT_FAILURE,"Memory allocation failed!\n" "%s:%d ReGrab(%d)\n",fn,line,len); } AddMM("ReGrab(ACQUIRE)",fn,line,ptr); return(ptr); } void FRelease(char *fn, int line, void *p) { RmMM("Release",fn,line,p); free(p); } void *FCopy(char *fn, int line, void *p,int len) { void *ptr; if (len==0) ptr=malloc(1); else ptr=malloc(len); if (!ptr) { DumpMemList("COPY FAILED"); GFX_exit(EXIT_FAILURE,"Memory allocation failed!\n" "%s:%d Copy(%p,%d)\n",fn,line,p,len); } if (len) memcpy(ptr,p,len); AddMM("Copy",fn,line,ptr); return(ptr); } char *FStrdup(char *fn, int line, char *p) { char n_fn[PATH_MAX]; char *ptr; strcpy(n_fn,fn); strcat(n_fn," [STRDUP]"); if (p) { if (!(ptr=malloc(strlen(p)+1))) { DumpMemList("STRDUP FAILED"); GFX_exit(EXIT_FAILURE,"Memory allocation failed!\n" "%s:%d Stdup(%s)\n",fn,line,p); } strcpy(ptr,p); AddMM("Strdup",fn,line,ptr); return(ptr); } else return(NULL); } /* END OF FILE */