source: trunk/poppler/mypoppler/goo/gmem.c @ 2

Last change on this file since 2 was 2, checked in by Eugene Romanenko, 15 years ago

First import

File size: 4.7 KB
Line 
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
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(size_t size) {
59#ifdef DEBUG_MEM
60  size_t 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
100void *grealloc(void *p, size_t size) {
101#ifdef DEBUG_MEM
102  GMemHdr *hdr;
103  void *q;
104  size_t 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
141void *gmallocn(int nObjs, int objSize) {
142  int n;
143
144  n = nObjs * objSize;
145  if (objSize == 0 || n / objSize != nObjs) {
146    fprintf(stderr, "Bogus memory allocation size\n");
147    exit(1);
148  }
149  return gmalloc(n);
150}
151
152void *greallocn(void *p, int nObjs, int objSize) {
153  int n;
154
155  n = nObjs * objSize;
156  if (objSize == 0 || n / objSize != nObjs) {
157    fprintf(stderr, "Bogus memory allocation size\n");
158    exit(1);
159  }
160  return grealloc(p, n);
161}
162
163void gfree(void *p) {
164#ifdef DEBUG_MEM
165  size_t size;
166  GMemHdr *hdr;
167  GMemHdr *prevHdr, *q;
168  int lst;
169  unsigned long *trl, *clr;
170
171  if (p) {
172    hdr = (GMemHdr *)((char *)p - gMemHdrSize);
173    lst = ((int)hdr >> gMemListShift) & gMemListMask;
174    for (prevHdr = NULL, q = gMemList[lst]; q; prevHdr = q, q = q->next) {
175      if (q == hdr)
176        break;
177    }
178    if (q) {
179      if (prevHdr)
180        prevHdr->next = hdr->next;
181      else
182        gMemList[lst] = hdr->next;
183      --gMemAlloc;
184      gMemInUse -= hdr->size;
185      size = gMemDataSize(hdr->size);
186      trl = (unsigned long *)((char *)hdr + gMemHdrSize + size);
187      if (*trl != gMemDeadVal) {
188        fprintf(stderr, "Overwrite past end of block %d at address %p\n",
189                hdr->index, p);
190      }
191      for (clr = (unsigned long *)hdr; clr <= trl; ++clr)
192        *clr = gMemDeadVal;
193      free(hdr);
194    } else {
195      fprintf(stderr, "Attempted to free bad address %p\n", p);
196    }
197  }
198#else
199  if (p)
200    free(p);
201#endif
202}
203
204#ifdef DEBUG_MEM
205void gMemReport(FILE *f) {
206  GMemHdr *p;
207  int lst;
208
209  fprintf(f, "%d memory allocations in all\n", gMemIndex);
210  if (gMemAlloc > 0) {
211    fprintf(f, "%d memory blocks left allocated:\n", gMemAlloc);
212    fprintf(f, " index     size\n");
213    fprintf(f, "-------- --------\n");
214    for (lst = 0; lst < gMemNLists; ++lst) {
215      for (p = gMemList[lst]; p; p = p->next)
216        fprintf(f, "%8d %8d\n", p->index, p->size);
217    }
218  } else {
219    fprintf(f, "No memory blocks left allocated\n");
220  }
221}
222#endif
223
224char *copyString(char *s) {
225  char *s1;
226
227  s1 = (char *)gmalloc(strlen(s) + 1);
228  strcpy(s1, s);
229  return s1;
230}
Note: See TracBrowser for help on using the repository browser.