fix build with recent changes/gcc 6.3.0
[AROS-Contrib.git] / arospdf / goo / gmem.cc
blob4c251b741b2f6108c623516a646bb14b43ae9937
1 /*
2 * gmem.c
4 * Memory routines with out-of-memory checking.
6 * Copyright 1996-2003 Glyph & Cog, LLC
7 */
9 #include <aconf.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <stddef.h>
13 #include <string.h>
14 #include <limits.h>
15 #include "gmem.h"
16 #include <aros/debug.h>
17 #ifdef DEBUG_MEM
19 typedef struct _GMemHdr {
20 unsigned int magic;
21 int size;
22 int index;
23 struct _GMemHdr *next, *prev;
24 } GMemHdr;
26 #define gMemHdrSize ((sizeof(GMemHdr) + 7) & ~7)
27 #define gMemTrlSize (sizeof(long))
29 #define gMemMagic 0xabcd9999
31 #if gmemTrlSize==8
32 #define gMemDeadVal 0xdeadbeefdeadbeefUL
33 #else
34 #define gMemDeadVal 0xdeadbeefUL
35 #endif
37 /* round data size so trailer will be aligned */
38 #define gMemDataSize(size) \
39 ((((size) + gMemTrlSize - 1) / gMemTrlSize) * gMemTrlSize)
41 static GMemHdr *gMemHead = NULL;
42 static GMemHdr *gMemTail = NULL;
44 static int gMemIndex = 0;
45 static int gMemAlloc = 0;
46 static int gMemInUse = 0;
48 #endif /* DEBUG_MEM */
50 void *gmalloc(int size) GMEM_EXCEP {
51 #ifdef DEBUG_MEM
52 int size1;
53 char *mem;
54 GMemHdr *hdr;
55 void *data;
56 unsigned long *trl, *p;
58 if (size <= 0) {
59 return NULL;
61 size1 = gMemDataSize(size);
62 if (!(mem = (char *)malloc(size1 + gMemHdrSize + gMemTrlSize))) {
63 #if USE_EXCEPTIONS
64 throw GMemException();
65 #else
66 exit(1);
67 #endif
69 hdr = (GMemHdr *)mem;
70 data = (void *)(mem + gMemHdrSize);
71 trl = (unsigned long *)(mem + gMemHdrSize + size1);
72 hdr->magic = gMemMagic;
73 hdr->size = size;
74 hdr->index = gMemIndex++;
75 if (gMemTail) {
76 gMemTail->next = hdr;
77 hdr->prev = gMemTail;
78 gMemTail = hdr;
79 } else {
80 hdr->prev = NULL;
81 gMemHead = gMemTail = hdr;
83 hdr->next = NULL;
84 ++gMemAlloc;
85 gMemInUse += size;
86 for (p = (unsigned long *)data; p <= trl; ++p) {
87 *p = gMemDeadVal;
89 return data;
90 #else
91 void *p;
93 if (size <= 0) {
94 return NULL;
96 if (!(p = malloc(size))) {
97 #if USE_EXCEPTIONS
98 throw GMemException();
99 #else
100 exit(1);
101 #endif
103 return p;
104 #endif
107 void *grealloc(void *p, int size) GMEM_EXCEP {
108 #ifdef DEBUG_MEM
109 GMemHdr *hdr;
110 void *q;
111 int oldSize;
113 if (size <= 0) {
114 if (p) {
115 gfree(p);
117 return NULL;
119 if (p) {
120 hdr = (GMemHdr *)((char *)p - gMemHdrSize);
121 oldSize = hdr->size;
122 q = gmalloc(size);
123 memcpy(q, p, size < oldSize ? size : oldSize);
124 gfree(p);
125 } else {
126 q = gmalloc(size);
128 return q;
129 #else
130 void *q;
132 if (size <= 0) {
133 if (p) {
134 free(p);
136 return NULL;
138 if (p) {
139 q = realloc(p, size);
140 } else {
141 q = malloc(size);
143 if (!q) {
144 #if USE_EXCEPTIONS
145 throw GMemException();
146 #else
147 exit(1);
148 #endif
150 return q;
151 #endif
154 void *gmallocn(int nObjs, int objSize) GMEM_EXCEP {
155 int n;
157 if (nObjs == 0) {
158 return NULL;
160 n = nObjs * objSize;
161 if (objSize <= 0 || nObjs < 0 || nObjs >= INT_MAX / objSize) {
162 #if USE_EXCEPTIONS
163 throw GMemException();
164 #else
165 exit(1);
166 #endif
168 return gmalloc(n);
171 void *greallocn(void *p, int nObjs, int objSize) GMEM_EXCEP {
172 int n;
174 if (nObjs == 0) {
175 if (p) {
176 gfree(p);
178 return NULL;
180 n = nObjs * objSize;
181 if (objSize <= 0 || nObjs < 0 || nObjs >= INT_MAX / objSize) {
182 #if USE_EXCEPTIONS
183 throw GMemException();
184 #else
185 bug( "Bogus memory allocation size\n");
186 exit(1);
187 #endif
189 return grealloc(p, n);
192 void gfree(void *p) {
193 #ifdef DEBUG_MEM
194 int size;
195 GMemHdr *hdr;
196 unsigned long *trl, *clr;
198 if (p) {
199 hdr = (GMemHdr *)((char *)p - gMemHdrSize);
200 if (hdr->magic == gMemMagic &&
201 ((hdr->prev == NULL) == (hdr == gMemHead)) &&
202 ((hdr->next == NULL) == (hdr == gMemTail))) {
203 if (hdr->prev) {
204 hdr->prev->next = hdr->next;
205 } else {
206 gMemHead = hdr->next;
208 if (hdr->next) {
209 hdr->next->prev = hdr->prev;
210 } else {
211 gMemTail = hdr->prev;
213 --gMemAlloc;
214 gMemInUse -= hdr->size;
215 size = gMemDataSize(hdr->size);
216 trl = (unsigned long *)((char *)hdr + gMemHdrSize + size);
217 if (*trl != gMemDeadVal) {
218 bug( "Overwrite past end of block %d at address %p\n",
219 hdr->index, p);
221 for (clr = (unsigned long *)hdr; clr <= trl; ++clr) {
222 *clr = gMemDeadVal;
224 free(hdr);
225 } else {
226 bug( "Attempted to free bad address %p\n", p);
229 #else
230 if (p) {
231 free(p);
233 #endif
236 #ifdef DEBUG_MEM
237 void gMemReport(FILE *f) {
238 GMemHdr *p;
240 fprintf(f, "%d memory allocations in all\n", gMemIndex);
241 if (gMemAlloc > 0) {
242 fprintf(f, "%d memory blocks left allocated:\n", gMemAlloc);
243 fprintf(f, " index size\n");
244 fprintf(f, "-------- --------\n");
245 for (p = gMemHead; p; p = p->next) {
246 fprintf(f, "%8d %8d\n", p->index, p->size);
248 } else {
249 fprintf(f, "No memory blocks left allocated\n");
252 #endif
254 char *copyString(char *s) {
255 char *s1;
257 s1 = (char *)gmalloc(strlen(s) + 1);
258 strcpy(s1, s);
259 return s1;