07bbf8108b0cf1be314e0b3a82c172df4674176b
[swftools.git] / pdf2swf / xpdf / 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 <aconf.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <stddef.h>
13 #include <string.h>
14 #include "gmem.h"
15
16 #ifdef DEBUG_MEM
17
18 typedef struct _GMemHdr {
19   int size;
20   int index;
21   struct _GMemHdr *next;
22 } GMemHdr;
23
24 #define gMemHdrSize ((sizeof(GMemHdr) + 7) & ~7)
25 #define gMemTrlSize (sizeof(long))
26
27 #if gmemTrlSize==8
28 #define gMemDeadVal 0xdeadbeefdeadbeefUL
29 #else
30 #define gMemDeadVal 0xdeadbeefUL
31 #endif
32
33 /* round data size so trailer will be aligned */
34 #define gMemDataSize(size) \
35   ((((size) + gMemTrlSize - 1) / gMemTrlSize) * gMemTrlSize)
36
37 #define gMemNLists    64
38 #define gMemListShift  4
39 #define gMemListMask  (gMemNLists - 1)
40 static GMemHdr *gMemList[gMemNLists] = {
41   NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
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 };
50
51 static int gMemIndex = 0;
52 static int gMemAlloc = 0;
53
54 #endif /* DEBUG_MEM */
55
56 void *gmalloc(int size) {
57 #ifdef DEBUG_MEM
58   int size1;
59   char *mem;
60   GMemHdr *hdr;
61   void *data;
62   int lst;
63   unsigned long *trl, *p;
64
65   if (size == 0)
66     return NULL;
67   size1 = gMemDataSize(size);
68   if (!(mem = (char *)malloc(size1 + gMemHdrSize + gMemTrlSize))) {
69     fprintf(stderr, "Out of memory\n");
70     exit(1);
71   }
72   hdr = (GMemHdr *)mem;
73   data = (void *)(mem + gMemHdrSize);
74   trl = (unsigned long *)(mem + gMemHdrSize + size1);
75   hdr->size = size;
76   hdr->index = gMemIndex++;
77   lst = ((int)hdr >> gMemListShift) & gMemListMask;
78   hdr->next = gMemList[lst];
79   gMemList[lst] = hdr;
80   ++gMemAlloc;
81   for (p = (unsigned long *)data; p <= trl; ++p)
82     *p = gMemDeadVal;
83   return data;
84 #else
85   void *p;
86
87   if (size == 0)
88     return NULL;
89   if (!(p = malloc(size))) {
90     fprintf(stderr, "Out of memory\n");
91     exit(1);
92   }
93   return p;
94 #endif
95 }
96
97 void *grealloc(void *p, int size) {
98 #ifdef DEBUG_MEM
99   GMemHdr *hdr;
100   void *q;
101   int oldSize;
102
103   if (size == 0) {
104     if (p)
105       gfree(p);
106     return NULL;
107   }
108   if (p) {
109     hdr = (GMemHdr *)((char *)p - gMemHdrSize);
110     oldSize = hdr->size;
111     q = gmalloc(size);
112     memcpy(q, p, size < oldSize ? size : oldSize);
113     gfree(p);
114   } else {
115     q = gmalloc(size);
116   }
117   return q;
118 #else
119   void *q;
120
121   if (size == 0) {
122     if (p)
123       free(p);
124     return NULL;
125   }
126   if (p)
127     q = realloc(p, size);
128   else
129     q = malloc(size);
130   if (!q) {
131     fprintf(stderr, "Out of memory\n");
132     exit(1);
133   }
134   return q;
135 #endif
136 }
137
138 void gfree(void *p) {
139 #ifdef DEBUG_MEM
140   int size;
141   GMemHdr *hdr;
142   GMemHdr *prevHdr, *q;
143   int lst;
144   unsigned long *trl, *clr;
145
146   if (p) {
147     hdr = (GMemHdr *)((char *)p - gMemHdrSize);
148     lst = ((int)hdr >> gMemListShift) & gMemListMask;
149     for (prevHdr = NULL, q = gMemList[lst]; q; prevHdr = q, q = q->next) {
150       if (q == hdr)
151         break;
152     }
153     if (q) {
154       if (prevHdr)
155         prevHdr->next = hdr->next;
156       else
157         gMemList[lst] = hdr->next;
158       --gMemAlloc;
159       size = gMemDataSize(hdr->size);
160       trl = (unsigned long *)((char *)hdr + gMemHdrSize + size);
161       if (*trl != gMemDeadVal) {
162         fprintf(stderr, "Overwrite past end of block %d at address %p\n",
163                 hdr->index, p);
164       }
165       for (clr = (unsigned long *)hdr; clr <= trl; ++clr)
166         *clr = gMemDeadVal;
167       free(hdr);
168     } else {
169       fprintf(stderr, "Attempted to free bad address %p\n", p);
170     }
171   }
172 #else
173   if (p)
174     free(p);
175 #endif
176 }
177
178 #ifdef DEBUG_MEM
179 void gMemReport(FILE *f) {
180   GMemHdr *p;
181   int lst;
182
183   fprintf(f, "%d memory allocations in all\n", gMemIndex);
184   if (gMemAlloc > 0) {
185     fprintf(f, "%d memory blocks left allocated:\n", gMemAlloc);
186     fprintf(f, " index     size\n");
187     fprintf(f, "-------- --------\n");
188     for (lst = 0; lst < gMemNLists; ++lst) {
189       for (p = gMemList[lst]; p; p = p->next)
190         fprintf(f, "%8d %8d\n", p->index, p->size);
191     }
192   } else {
193     fprintf(f, "No memory blocks left allocated\n");
194   }
195 }
196 #endif
197
198 char *copyString(char *s) {
199   char *s1;
200
201   s1 = (char *)gmalloc(strlen(s) + 1);
202   strcpy(s1, s);
203   return s1;
204 }