Fixed Autodoc formatting.
[AROS.git] / tools / cxref / memory.c
blobed63dccded1f1821c67271cd9fa931aaa498720e
1 /***************************************
2 $Header$
4 C Cross Referencing & Documentation tool. Version 1.5.
6 Memory management functions
7 ******************/ /******************
8 Written by Andrew M. Bishop
10 This file Copyright 1995,96,97 Andrew M. Bishop
11 It may be distributed under the GNU Public License, version 2, or
12 any higher version. See section COPYING of the GNU Public license
13 for conditions under which this file may be redistributed.
14 ***************************************/
16 /*+ The amount of debugging, non-zero for totals, 2 for logging, 4 for printing each call. +*/
17 #define DEBUG 0
19 /* The configure output */
21 #include "autoconfig.h"
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
27 #ifdef USE_STD_ARG
28 #include <stdarg.h>
29 #else
30 #include <varargs.h>
31 #endif
33 #include <memory.h>
34 #include "memory.h"
36 /*+ A private memory heap is used to reduce the number of malloc calls that are made, the Heap type is a pointer to this. +*/
37 typedef struct _Heap *Heap;
39 /*+ A structure containing all of the information about the private heap in a linked list. +*/
40 struct _Heap
42 char* mem; /*+ The memory that is private to the heap. +*/
43 Heap next; /*+ The next Heap structure. +*/
46 /*+ Local variable to control the usage of the private heap; +*/
47 static Heap first=NULL; /*+ the first segment of memory on the private heap. +*/
48 static int heap_left=0; /*+ the amount of space left in the current heap segment. +*/
50 static char* get_space(unsigned int l);
51 static Heap add_to_heap(unsigned int l);
53 #if DEBUG&2
54 /*+ Variable used for debugging, not a good thing to do. what if more than 16384 mallocs? +*/
55 static void* addresses[16384];
56 static char* files[16384];
57 static int lines[16384];
58 #endif
59 #if DEBUG
60 /*+ Variable used for debugging. +*/
61 static int malloc_count=0;
62 static int realloc_count=0;
63 static int free_count=0;
64 #endif
67 /*++++++++++++++++++++++++++++++++++++++
68 A replacement malloc() function.
70 void* SafeMalloc Returns the address.
72 unsigned int size The size of the memory to allocate.
74 char* file The file that the function is called from.
76 int line The line number that the function is called from.
77 ++++++++++++++++++++++++++++++++++++++*/
79 void* SafeMalloc(unsigned int size,char* file,int line)
81 void* rptr=malloc(size);
83 #if DEBUG&4
84 printf("$$Malloc #%5d of %4d bytes at %08lx (%s:%3d)\n",malloc_count+1,size,(long)rptr,file,line);
85 #endif
86 #if DEBUG&2
87 if(malloc_count==(sizeof(addresses)/sizeof(addresses[0])))
88 {fprintf(stderr,"$$Too many Mallocs to log, edit memory.c\n");exit(3);}
89 addresses[malloc_count]=(void*)rptr;
90 files[malloc_count]=file;
91 lines[malloc_count]=line;
92 #endif
93 #if DEBUG
94 malloc_count++;
95 if(!rptr) printf("$$Warning Malloc() returning NULL (%s:%3d)\n",file,line);
96 #endif
97 #if !DEBUG
98 if(!rptr) printf("Warning Malloc() returning NULL (%s:%3d)\n",file,line);
99 #endif
101 return(rptr);
105 /*++++++++++++++++++++++++++++++++++++++
106 A replacement calloc() function.
108 void* SafeCalloc Returns the address.
110 unsigned int n The number of items to allocate.
112 unsigned int size The size of the memory to allocate.
114 char* file The file that the function is called from.
116 int line The line number that the function is called from.
117 ++++++++++++++++++++++++++++++++++++++*/
119 void* SafeCalloc(unsigned int n,unsigned int size,char* file,int line)
121 void* rptr=calloc(n,size);
123 #if DEBUG&4
124 printf("$$Calloc #%5d of %4d bytes at %08lx (%s:%3d)\n",malloc_count+1,size,(long)rptr,file,line);
125 #endif
126 #if DEBUG&2
127 if(malloc_count==(sizeof(addresses)/sizeof(addresses[0])))
128 {fprintf(stderr,"$$Too many Mallocs to log, edit memory.c\n");exit(3);}
129 addresses[malloc_count]=(void*)rptr;
130 files[malloc_count]=file;
131 lines[malloc_count]=line;
132 #endif
133 #if DEBUG
134 malloc_count++;
135 if(!rptr) printf("$$Warning Calloc() returning NULL (%s:%3d)\n",file,line);
136 #endif
137 #if !DEBUG
138 if(!rptr) printf("Warning Calloc() returning NULL (%s:%3d)\n",file,line);
139 #endif
141 return(rptr);
145 /*++++++++++++++++++++++++++++++++++++++
146 A replacement realloc() function.
148 void* SafeRealloc Returns the address.
150 void* ptr The old pointer.
152 unsigned int size The size of the new memory to allocate.
154 char* file The file that the function is called from.
156 int line The line number that the function is called from.
157 ++++++++++++++++++++++++++++++++++++++*/
159 void* SafeRealloc(void* ptr,unsigned int size,char* file,int line)
161 void* rptr=realloc(ptr,size);
163 #if DEBUG&4
164 printf("$$Realloc #%4d of %4d bytes at %08lx (old %08lx) (%s:%3d)\n",realloc_count+1,size,(long)rptr,(long)ptr,file,line);
165 #endif
166 #if DEBUG&2
168 int i;
169 for(i=0;i<malloc_count;i++)
170 if(addresses[i]==(void*)ptr)
171 {addresses[i]=rptr;break;}
172 if(i==malloc_count)
173 printf("$$Realloc() called for a non Malloced pointer %08lx (%s:%3d)\n",(long)ptr,file,line);
175 #endif
176 #if DEBUG
177 realloc_count++;
178 if(!rptr) printf("$$Warning Realloc() returning NULL (%s:%3d)\n",file,line);
179 #endif
180 #if !DEBUG
181 if(!rptr) printf("Warning Realloc() returning NULL (%s:%3d)\n",file,line);
182 #endif
184 return(rptr);
188 /*++++++++++++++++++++++++++++++++++++++
189 A replacement free() function.
191 void* ptr The pointer that is to be freed up.
193 char* file The file that the function is called from.
195 int line The line number that the function is called from.
196 ++++++++++++++++++++++++++++++++++++++*/
198 void SafeFree(void* ptr,char* file,int line)
200 #if DEBUG&4
201 printf("$$Free #%5d at %08lx (%s:%3d)\n",free_count+1,(long)ptr,file,line);
202 #endif
203 #if DEBUG&2
205 int i;
206 for(i=0;i<malloc_count;i++)
207 if(addresses[i]==(void*)ptr)
208 {addresses[i]=(void*)1;break;}
209 if(i==malloc_count)
210 printf("$$Free() called for a non Malloced pointer %08lx (%s:%3d)\n",(long)ptr,file,line);
212 #endif
213 #if DEBUG
214 free_count++;
215 if(!ptr) printf("$$Calling Free() on NULL (%s:%3d)\n",file,line);
216 else
217 #endif
218 #if !DEBUG
219 if(!ptr) printf("Calling Free() on NULL (%s:%3d)\n",file,line);
220 else
221 #endif
223 free(ptr);
227 /*++++++++++++++++++++++++++++++++++++++
228 A function to copy a string on the public global heap.
230 char* SafeMallocString Returns the copy of the string.
232 char* x The string to be copied.
234 char* file The file that the function is called from.
236 int line The line number that the function is called from.
237 ++++++++++++++++++++++++++++++++++++++*/
239 char* SafeMallocString(char* x,char* file,int line)
241 char* t=NULL;
243 if(x)
245 t=(char*)SafeMalloc(strlen(x)+1,file,line);
246 strcpy(t,x);
249 return(t);
253 /*++++++++++++++++++++++++++++++++++++++
254 A function to copy a string on the local private memory heap.
256 char* CopyString Returns the copy of the string.
258 char* x The string to be copied.
259 ++++++++++++++++++++++++++++++++++++++*/
261 char* CopyString(char* x)
263 char* t=NULL;
265 if(x)
267 t=get_space(strlen(x)+1);
268 strcpy(t,x);
271 return(t);
275 /*++++++++++++++++++++++++++++++++++++++
276 A function to concatenate a number of strings.
278 char* ConcatStrings Returns the a pointer to the new string.
280 int n The number of strings
282 char* s The first string.
284 ... The other strings, 'n' including 's'.
286 Any of the strings that are inputs can be NULL, in this case they are quietly ignored.
287 ++++++++++++++++++++++++++++++++++++++*/
289 char* ConcatStrings(int n,char* s, ...)
291 char* t=NULL,*str;
292 unsigned int l=0;
293 int i;
294 va_list ap;
296 #ifdef USE_STD_ARG
297 va_start(ap,s);
298 #else
299 va_start(ap);
300 #endif
302 for(i=0;i<n;i++)
304 if(i)
305 str=va_arg(ap, char *);
306 else
307 str=s;
309 if(str)
310 l+=strlen(str);
313 va_end(ap);
315 if(l)
317 t=get_space(l+1); t[0]=0;
319 #ifdef USE_STD_ARG
320 va_start(ap,s);
321 #else
322 va_start(ap);
323 #endif
325 for(i=0;i<n;i++)
327 if(i)
328 str=va_arg(ap, char *);
329 else
330 str=s;
332 if(str)
333 strcat(t,str);
336 va_end(ap);
339 return(t);
343 /*++++++++++++++++++++++++++++++++++++++
344 Prints out the number of mallocs / reallocs and frees.
345 ++++++++++++++++++++++++++++++++++++++*/
347 void PrintMemoryStatistics(void)
349 #if DEBUG
350 printf("\n"
351 "$$Memory usage : %5d Malloc()/Calloc() calls\n"
352 "$$ %5d Realloc() calls\n"
353 "$$ %5d Free() calls\n"
354 "$$ %5d Net calls (Malloc-Free)\n",
355 malloc_count,realloc_count,free_count,malloc_count-free_count);
356 #endif
358 #if DEBUG&2
360 int i;
361 for(i=0;i<malloc_count;i++)
362 if(addresses[i]!=(void*)1)
363 printf("$$Malloc #%5d at address %08lx is not freed (%s:%3d) = '%s'\n",i+1,(long)addresses[i],files[i],lines[i],(char*)addresses[i]);
365 #endif
369 /*++++++++++++++++++++++++++++++++++++++
370 Tidies up the local heap of memory.
371 ++++++++++++++++++++++++++++++++++++++*/
373 void TidyMemory(void)
375 if(first)
377 Heap h=first,n;
380 n=h->next;
381 Free(h->mem);
382 Free(h);
383 h=n;
385 while(h);
388 first=NULL;
389 heap_left=0;
392 /*+ The size of each of the heap allocations +*/
393 #define HEAP_INC 8192
395 /*+ The size of a string that is large enough to have it's own mallocation. +*/
396 #define SMALL_STRING 256
398 /*++++++++++++++++++++++++++++++++++++++
399 A function to get some memory for a string, allocate a new heap structure if needed.
401 char* get_space Returns a pointer to enough space.
403 unsigned int l The amount of space that is needed.
404 ++++++++++++++++++++++++++++++++++++++*/
406 static char* get_space(unsigned int l)
408 static Heap current=NULL;
409 char* r=NULL;
411 if(l <= SMALL_STRING)
413 if(heap_left < l)
415 current=add_to_heap(HEAP_INC);
416 heap_left=HEAP_INC;
419 heap_left-=l;
421 r=&current->mem[heap_left]; /* Work downwards */
423 else
425 Heap h=add_to_heap(l);
426 r=h->mem;
429 return(r);
433 /*++++++++++++++++++++++++++++++++++++++
434 Add some bytes to the privately maintained memory heap.
436 Heap add_to_heap Returns a pointer to the required memory.
438 unsigned int l The size of the memory that is required.
439 ++++++++++++++++++++++++++++++++++++++*/
441 static Heap add_to_heap(unsigned int l)
443 Heap* h=&first;
445 while(*h)
446 h=&(*h)->next;
448 *h=(Heap)Malloc(sizeof(struct _Heap));
449 (*h)->next=NULL;
450 (*h)->mem=(char*)Malloc(l);
452 return(*h);