]> git.ipfire.org Git - thirdparty/cups.git/blame - pdftops/gmem.c
Merge changes from CUPS 1.4svn-r7199.
[thirdparty/cups.git] / pdftops / gmem.c
CommitLineData
ef416fc2 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>
bd7854cb 14#include <limits.h>
ef416fc2 15#include "gmem.h"
16
17#ifdef DEBUG_MEM
18
19typedef 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)
41static 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
52static int gMemIndex = 0;
53static int gMemAlloc = 0;
54static int gMemInUse = 0;
55
56#endif /* DEBUG_MEM */
57
58void *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
bd7854cb 67 if (size <= 0)
ef416fc2 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
bd7854cb 90 if (size <= 0)
ef416fc2 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
100void *grealloc(void *p, int size) {
101#ifdef DEBUG_MEM
102 GMemHdr *hdr;
103 void *q;
104 int oldSize;
105
bd7854cb 106 if (size <= 0) {
ef416fc2 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
bd7854cb 124 if (size <= 0) {
ef416fc2 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
141void *gmallocn(int nObjs, int objSize) {
142 int n;
143
bd7854cb 144 if (nObjs == 0) {
145 return NULL;
146 }
ef416fc2 147 n = nObjs * objSize;
bd7854cb 148 if (objSize <= 0 || nObjs < 0 || nObjs >= INT_MAX / objSize) {
ef416fc2 149 fprintf(stderr, "Bogus memory allocation size\n");
150 exit(1);
151 }
152 return gmalloc(n);
153}
154
155void *greallocn(void *p, int nObjs, int objSize) {
156 int n;
157
bd7854cb 158 if (nObjs == 0) {
159 if (p) {
160 gfree(p);
161 }
162 return NULL;
163 }
ef416fc2 164 n = nObjs * objSize;
bd7854cb 165 if (objSize <= 0 || nObjs < 0 || nObjs >= INT_MAX / objSize) {
ef416fc2 166 fprintf(stderr, "Bogus memory allocation size\n");
167 exit(1);
168 }
169 return grealloc(p, n);
170}
171
172void 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
214void 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
233char *copyString(char *s) {
234 char *s1;
235
236 s1 = (char *)gmalloc(strlen(s) + 1);
237 strcpy(s1, s);
238 return s1;
239}