Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 206 lines (176 sloc) 4.976 kb
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
1 /* safe.c */
2 /* Copyright 1995 by Steve Kirkendall */
3
4
5 #include "elvis.h"
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
6 #ifdef FEATURE_RCSID
7 char id_safe[] = "$Id: safe.c,v 2.17 2003/10/17 17:41:23 steve Exp $";
8 #endif
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
9
10 #ifndef DEBUG_ALLOC
11 void *safealloc(qty, size)
12 int qty; /* number of items to allocate */
13 size_t size; /* size of each item */
14 {
15 void *newp;
16
17 newp = (void *)calloc((size_t)qty, size);
18 if (!newp)
19 {
20 msg(MSG_FATAL, "no memory");
21 }
22 return newp;
23 }
24
25 void safefree(ptr)
26 void *ptr; /* pointer to item(s) to be freed */
27 {
28 free(ptr);
29 }
30
31 char *safedup(str)
32 char *str; /* nul-terminated string to be duplicated */
33 {
34 char *newp = (char *)safealloc((int)strlen(str) + 1, sizeof(char));
35 strcpy(newp, str);
36 return newp;
37 }
38 #else
39
40 #define MAGIC1 0x10d934a2
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
41 #define MAGIC2 0x42df3219
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
42 typedef struct sainfo_s
43 {
44 struct sainfo_s *next; /* another allocated memory chunk */
45 char *file; /* source file where allocated */
46 int line; /* source line where allocated */
47 int size; /* number of longs allocated */
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
48 ELVBOOL kept; /* if ElvTrue, don't complain if never freed */
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
49 long magic[2];/* magic number plus application info */
50 } sainfo_t;
51
52 sainfo_t *allocated;
53
54 /* inspect the list of allocated memory */
55 void safeinspect()
56 {
57 sainfo_t *scan;
58
59 /* inspect list of allocated blocks for overflow/underflow */
60 for (scan = allocated; scan; scan = scan->next)
61 {
62 if (scan->magic[0] != MAGIC1)
63 {
64 fprintf(stderr, "underflow in memory at 0x%lx, allocated from %s:%d, magic[0]=0x%lx\n",
65 (long)scan, scan->file, scan->line, scan->magic[0]);
66 abort();
67 }
68 else if (scan->magic[scan->size + 1] != MAGIC2)
69 {
70 fprintf(stderr, "overflow in memory at 0x%lx, allocated from %s:%d, magic[%d]=0x%lx\n",
71 (long)scan, scan->file, scan->line, scan->size+1, scan->magic[scan->size + 1]);
72 abort();
73 }
74 }
75 }
76
77
78 /* allocate memory, and remember where it was allocated */
79 void *_safealloc(file, line, kept, qty, size)
80 char *file; /* name of source file where this func was called */
81 int line; /* line of source file where this func was called */
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
82 ELVBOOL kept; /* if ElvTrue, don't complain if never allocated */
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
83 int qty; /* number of items to allocate */
84 size_t size; /* size of each item */
85 {
86 int nlongs;
87 sainfo_t *newp, *scan, *lag;
88
89 /* inspect previous allocations */
90 safeinspect();
91
92 /* round user request up to whole number of longs */
93 nlongs = (qty * size + sizeof(long) - 1) / sizeof(long);
94 assert(nlongs * sizeof(long) >= qty * size);
95
96 /* allocate storage space */
97 newp = (sainfo_t *)calloc(1, sizeof(sainfo_t) + nlongs * sizeof(long));
98 if (!newp)
99 {
100 msg(MSG_FATAL, "no memory");
101 }
102
103 /* save info about allocated memory */
104 newp->file = file;
105 newp->line = line;
106 newp->size = nlongs;
107 newp->kept = kept;
108 newp->magic[0] = MAGIC1;
109 newp->magic[1 + newp->size] = MAGIC2;
110 for (scan = allocated, lag = NULL;
111 scan && (strcmp(file, scan->file) < 0 || (!strcmp(file, scan->file) && line < scan->line));
112 lag = scan, scan = scan->next)
113 {
114 }
115 newp->next = scan;
116 if (lag)
117 lag->next = newp;
118 else
119 allocated = newp;
120
121 /* count allocations from that spot */
122 for (nlongs = 0, scan = newp;
123 scan && !strcmp(file, scan->file) && line == scan->line;
124 nlongs++, scan = scan->next)
125 {
126 }
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
127 if (nlongs > 100 && (!kept || strcmp(file, "options.c")))
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
128 {
129 fprintf(stderr, "%d allocations from %s(%d)\n", nlongs, file, line);
130 }
131
132 /* return the application portion of allocated memory */
133 return (void *)&newp->magic[1];
134 }
135
136
137 /* free allocated memory */
138 void _safefree(file, line, mem)
139 char *file; /* name of source file where this func was called */
140 int line; /* line of source file where this func was called */
141 void *mem; /* item(s) to be freed */
142 {
143 sainfo_t *scan, *lag;
144
145 /* inspect previous allocations */
146 safeinspect();
147
148 /* locate the memory in the allocated list */
149 for (lag = NULL, scan = allocated;
150 scan && (void *)&scan->magic[1] != mem;
151 lag = scan, scan = scan->next)
152 {
153 }
154
155 /* if not in allocation list, fail */
156 if (!scan)
157 {
158 fprintf(stderr, "attempt to free unallocated memory from %s:%ld\n",
159 file, (long)line);
160 return;
161 }
162
163 /* delete the memory from the allocated list */
164 if (lag)
165 {
166 lag->next = scan->next;
167 }
168 else
169 {
170 allocated = scan->next;
171 }
172
173 /* free the memory */
174 free(scan);
175 }
176
177 /* allocate a duplicate of a string, using _safealloc() */
178 char *_safedup(file, line, kept, str)
179 char *file; /* name of source file where this func was called */
180 int line; /* line of source file where this func was called */
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
181 ELVBOOL kept; /* if ElvTrue, don't complain if never freed */
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
182 char *str; /* nul-terminated string to duplicate */
183 {
184 char *newp;
185
186 newp = (char *)_safealloc(file, line, kept, (int)(strlen(str) + 1), sizeof(char));
187 strcpy(newp, str);
188 return newp;
189 }
190
191 /* list any unfreed memory */
192 void safeterm()
193 {
194 sainfo_t *scan;
195
196 for (scan = allocated; scan; scan = scan->next)
197 {
198 if (!scan->kept)
199 {
200 fprintf(stderr, "memory allocated from %s:%ld never freed\n",
201 scan->file, (long)scan->line);
202 }
203 }
204 }
205 #endif
Something went wrong with that request. Please try again.