]> git.ipfire.org Git - thirdparty/cups.git/blob - pdftops/gmem.c
Load cups into easysw/current.
[thirdparty/cups.git] / pdftops / gmem.c
1 /*
2 * gmem.c
3 *
4 * Memory routines with out-of-memory checking.
5 *
6 * Copyright 1996-2003 Glyph & Cog, LLC
7 */
8
9 #include <config.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
17 #ifdef DEBUG_MEM
18
19 typedef struct _GMemHdr {
20 int size;
21 int index;
22 struct _GMemHdr *next;
23 } GMemHdr;
24
25 #define gMemHdrSize ((sizeof(GMemHdr) + 7) & ~7)
26 #define gMemTrlSize (sizeof(long))
27
28 #if gmemTrlSize==8
29 #define gMemDeadVal 0xdeadbeefdeadbeefUL
30 #else
31 #define gMemDeadVal 0xdeadbeefUL
32 #endif
33
34 /* round data size so trailer will be aligned */
35 #define gMemDataSize(size) \
36 ((((size) + gMemTrlSize - 1) / gMemTrlSize) * gMemTrlSize)
37
38 #define gMemNLists 64
39 #define gMemListShift 4
40 #define gMemListMask (gMemNLists - 1)
41 static GMemHdr *gMemList[gMemNLists] = {
42 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
43 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
44 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
45 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
46 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
47 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
48 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
49 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
50 };
51
52 static int gMemIndex = 0;
53 static int gMemAlloc = 0;
54 static int gMemInUse = 0;
55
56 #endif /* DEBUG_MEM */
57
58 void *gmalloc(int size) {
59 #ifdef DEBUG_MEM
60 int size1;
61 char *mem;
62 GMemHdr *hdr;
63 void *data;
64 int lst;
65 unsigned long *trl, *p;
66
67 if (size <= 0)
68 return NULL;
69 size1 = gMemDataSize(size);
70 if (!(mem = (char *)malloc(size1 + gMemHdrSize + gMemTrlSize))) {
71 fprintf(stderr, "Out of memory\n");
72 exit(1);
73 }
74 hdr = (GMemHdr *)mem;
75 data = (void *)(mem + gMemHdrSize);
76 trl = (unsigned long *)(mem + gMemHdrSize + size1);
77 hdr->size = size;
78 hdr->index = gMemIndex++;
79 lst = ((int)hdr >> gMemListShift) & gMemListMask;
80 hdr->next = gMemList[lst];
81 gMemList[lst] = hdr;
82 ++gMemAlloc;
83 gMemInUse += size;
84 for (p = (unsigned long *)data; p <= trl; ++p)
85 *p = gMemDeadVal;
86 return data;
87 #else
88 void *p;
89
90 if (size <= 0)
91 return NULL;
92 if (!(p = malloc(size))) {
93 fprintf(stderr, "Out of memory\n");
94 exit(1);
95 }
96 return p;
97 #endif
98 }
99
100 void *grealloc(void *p, int size) {
101 #ifdef DEBUG_MEM
102 GMemHdr *hdr;
103 void *q;
104 int oldSize;
105
106 if (size <= 0) {
107 if (p)
108 gfree(p);
109 return NULL;
110 }
111 if (p) {
112 hdr = (GMemHdr *)((char *)p - gMemHdrSize);
113 oldSize = hdr->size;
114 q = gmalloc(size);
115 memcpy(q, p, size < oldSize ? size : oldSize);
116 gfree(p);
117 } else {
118 q = gmalloc(size);
119 }
120 return q;
121 #else
122 void *q;
123
124 if (size <= 0) {
125 if (p)
126 free(p);
127 return NULL;
128 }
129 if (p)
130 q = realloc(p, size);
131 else
132 q = malloc(size);
133 if (!q) {
134 fprintf(stderr, "Out of memory\n");
135 exit(1);
136 }
137 return q;
138 #endif
139 }
140
141 void *gmallocn(int nObjs, int objSize) {
142 int n;
143
144 if (nObjs == 0) {
145 return NULL;
146 }
147 n = nObjs * objSize;
148 if (objSize <= 0 || nObjs < 0 || nObjs >= INT_MAX / objSize) {
149 fprintf(stderr, "Bogus memory allocation size\n");
150 exit(1);
151 }
152 return gmalloc(n);
153 }
154
155 void *greallocn(void *p, int nObjs, int objSize) {
156 int n;
157
158 if (nObjs == 0) {
159 if (p) {
160 gfree(p);
161 }
162 return NULL;
163 }
164 n = nObjs * objSize;
165 if (objSize <= 0 || nObjs < 0 || nObjs >= INT_MAX / objSize) {
166 fprintf(stderr, "Bogus memory allocation size\n");
167 exit(1);
168 }
169 return grealloc(p, n);
170 }
171
172 void gfree(void *p) {
173 #ifdef DEBUG_MEM
174 int size;
175 GMemHdr *hdr;
176 GMemHdr *prevHdr, *q;
177 int lst;
178 unsigned long *trl, *clr;
179
180 if (p) {
181 hdr = (GMemHdr *)((char *)p - gMemHdrSize);
182 lst = ((int)hdr >> gMemListShift) & gMemListMask;
183 for (prevHdr = NULL, q = gMemList[lst]; q; prevHdr = q, q = q->next) {
184 if (q == hdr)
185 break;
186 }
187 if (q) {
188 if (prevHdr)
189 prevHdr->next = hdr->next;
190 else
191 gMemList[lst] = hdr->next;
192 --gMemAlloc;
193 gMemInUse -= hdr->size;
194 size = gMemDataSize(hdr->size);
195 trl = (unsigned long *)((char *)hdr + gMemHdrSize + size);
196 if (*trl != gMemDeadVal) {
197 fprintf(stderr, "Overwrite past end of block %d at address %p\n",
198 hdr->index, p);
199 }
200 for (clr = (unsigned long *)hdr; clr <= trl; ++clr)
201 *clr = gMemDeadVal;
202 free(hdr);
203 } else {
204 fprintf(stderr, "Attempted to free bad address %p\n", p);
205 }
206 }
207 #else
208 if (p)
209 free(p);
210 #endif
211 }
212
213 #ifdef DEBUG_MEM
214 void gMemReport(FILE *f) {
215 GMemHdr *p;
216 int lst;
217
218 fprintf(f, "%d memory allocations in all\n", gMemIndex);
219 if (gMemAlloc > 0) {
220 fprintf(f, "%d memory blocks left allocated:\n", gMemAlloc);
221 fprintf(f, " index size\n");
222 fprintf(f, "-------- --------\n");
223 for (lst = 0; lst < gMemNLists; ++lst) {
224 for (p = gMemList[lst]; p; p = p->next)
225 fprintf(f, "%8d %8d\n", p->index, p->size);
226 }
227 } else {
228 fprintf(f, "No memory blocks left allocated\n");
229 }
230 }
231 #endif
232
233 char *copyString(char *s) {
234 char *s1;
235
236 s1 = (char *)gmalloc(strlen(s) + 1);
237 strcpy(s1, s);
238 return s1;
239 }