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