1 /*
2 * wmslib/src/wms.c, part of wmslib (Library functions)
3 * Copyright (C) 1995 William Shubert.
4 * See "configure.h.in" for more copyright information.
5 */
6
7 #include <wms.h>
8 #if !HAVE_GETDTABLESIZE
9 #include <sys/resource.h>
10 #endif
11
12 #if DEBUG
13
14 typedef struct alloc_struct {
15 int magic;
16 int size;
17 const char *file;
18 int line;
19 struct alloc_struct *next, *prev;
20 } alloc_t;
21
22 static int alloc_count=0, total_bytes=0, check=FALSE;
23 static alloc_t *ring_head = NULL;
24
25
wms_malloc_debug(uint bufsize,const char * file,int line)26 void *wms_malloc_debug(uint bufsize, const char *file, int line) {
27 void *ret;
28 alloc_t *alloc;
29
30 if (bufsize == 0)
31 return(NULL);
32 ++alloc_count;
33 total_bytes += bufsize;
34 bufsize += sizeof(alloc_t);
35 alloc = malloc(bufsize);
36 assert(alloc != NULL);
37 if (alloc == NULL) {
38 fprintf(stderr, "%s: FATAL ERROR: Failed to allocate %d bytes.\n",
39 wms_progname, bufsize);
40 exit(1);
41 }
42 ret = (void *)((int)alloc + sizeof(alloc_t));
43 alloc->magic = 0x91325832;
44 alloc->size = bufsize - sizeof(alloc_t);
45 alloc->file = file;
46 alloc->line = line;
47 if (ring_head == NULL) {
48 ring_head = alloc;
49 alloc->next = alloc->prev = alloc;
50 } else {
51 alloc->next = ring_head;
52 alloc->prev = ring_head->prev;
53 alloc->next->prev = alloc;
54 alloc->prev->next = alloc;
55 }
56 return(ret);
57 }
58
59
wms_free(void * deadbuf)60 void wms_free(void *deadbuf) {
61 alloc_t *alloc;
62
63 assert(deadbuf != NULL);
64 alloc = (alloc_t *)((int)deadbuf - sizeof(alloc_t));
65 --alloc_count;
66 assert(alloc->magic == 0x91325832);
67 total_bytes -= alloc->size;
68 alloc->magic = 0;
69 if (ring_head == alloc) {
70 if (alloc->next == alloc)
71 ring_head = NULL;
72 else {
73 ring_head = alloc->next;
74 alloc->next->prev = alloc->prev;
75 alloc->prev->next = alloc->next;
76 }
77 } else if (alloc->next != alloc) {
78 alloc->next->prev = alloc->prev;
79 alloc->prev->next = alloc->next;
80 }
81 free(alloc);
82 }
83
84
wms_alloc_ring_reset(void)85 void wms_alloc_ring_reset(void) {
86 ring_head = NULL;
87 }
88
89
wms_alloc_ring_show(void)90 void wms_alloc_ring_show(void) {
91 alloc_t *alloc;
92
93 if (ring_head == NULL) {
94 printf("*** wms_alloc: Empty ring\n");
95 } else {
96 alloc = ring_head;
97 do {
98 printf("*** wms_alloc: %4d bytes; file \"%s\", line %d.\n",
99 alloc->size, alloc->file, alloc->line);
100 alloc = alloc->next;
101 } while (alloc != ring_head);
102 printf("\n");
103 }
104 }
105
106
wms_alloc_stat(void)107 void wms_alloc_stat(void) {
108 fprintf(stderr, "Count of allocated buffers: %d\n", alloc_count);
109 fprintf(stderr, " Total bytes allocated: %d\n", total_bytes);
110 check = TRUE;
111 }
112
113
114
115 #else /* !DEBUG */
116
117
wms_malloc(uint bufsize)118 void *wms_malloc(uint bufsize) {
119 void *ret;
120
121 if (bufsize == 0)
122 return(NULL);
123 ret = malloc(bufsize);
124 assert(ret != NULL);
125 if (ret == NULL) {
126 fprintf(stderr, "%s: FATAL ERROR: Failed to allocate %d bytes.\n",
127 wms_progname, bufsize);
128 exit(1);
129 }
130 return(ret);
131 }
132
133 #endif /* DEBUG */
134
135
136 #if !HAVE_STRERROR
137
138 /*
139 * Do a fake, really bad strerror() function.
140 */
strerror(int error)141 const char *strerror(int error) {
142 static char out[20];
143
144 sprintf(out, "System error %d", error);
145 return(out);
146 }
147
148 #endif /* !HAVE_STRERROR */
149
150
151 #if !HAVE_GETDTABLESIZE
152
getdtablesize(void)153 int getdtablesize(void) {
154 struct rlimit tmp_rlim;
155
156 getrlimit(RLIMIT_NOFILE, &tmp_rlim);
157 return(tmp_rlim.rlim_cur);
158 }
159
160 #endif /* !HAVE_GETDTABLESIZE */
161
162
wms_atoi(const char * str,bool * err)163 int wms_atoi(const char *str, bool *err) {
164 bool dummy;
165 bool negative = FALSE, inNum = FALSE, gotNum = FALSE, doneNum = FALSE;
166 int i, v = 0, newV;
167
168 if (err == NULL)
169 err = &dummy;
170 *err = FALSE;
171 for (i = 0; str[i]; ++i) {
172 if (isspace(str[i])) {
173 if (inNum)
174 doneNum = TRUE;
175 } else if (str[i] == '-') {
176 if (inNum) {
177 *err = TRUE;
178 return(0);
179 } else {
180 inNum = TRUE;
181 negative = TRUE;
182 }
183 } else if (isdigit(str[i])) {
184 if (doneNum) {
185 *err = TRUE;
186 return(0);
187 } else {
188 inNum = TRUE;
189 gotNum = TRUE;
190 newV = v*10 + (int)(str[i] - '0');
191 if (newV / 10 != v) {
192 *err = TRUE;
193 return(0);
194 }
195 v = newV;
196 }
197 } else {
198 *err = TRUE;
199 return(0);
200 }
201 }
202 if (!gotNum) {
203 *err = TRUE;
204 return(0);
205 }
206 if (negative)
207 return(-v);
208 else
209 return(v);
210 }
211
212
wms_atof(const char * str,bool * err)213 double wms_atof(const char *str, bool *err) {
214 int i;
215 bool decimal = FALSE;
216
217 i = 0;
218 if (str[0] == '-')
219 ++i;
220 while (str[i]) {
221 if (str[i] == '.') {
222 if (decimal) {
223 if (err)
224 *err = TRUE;
225 return(0.0);
226 }
227 decimal = TRUE;
228 } else if (!isdigit(str[i])) {
229 if (err)
230 *err = TRUE;
231 return(0.0);
232 }
233 ++i;
234 }
235 if (err)
236 *err = FALSE;
237 return(atof(str));
238 }
239
240
241 #if WORDS_BIGENDIAN
242
stdInt32_int(StdInt32 i)243 int stdInt32_int(StdInt32 i) {
244 return(((i >> 24) & 0x000000ff) |
245 ((i >> 8) & 0x0000ff00) |
246 ((i << 8) & 0x00ff0000) |
247 ((i << 24) & 0xff000000));
248 }
249
250
int_stdInt32(int i)251 StdInt32 int_stdInt32(int i) {
252 return(((i >> 24) & 0x000000ff) |
253 ((i >> 8) & 0x0000ff00) |
254 ((i << 8) & 0x00ff0000) |
255 ((i << 24) & 0xff000000));
256 }
257
258 #endif /* WORDS_BIGENDIAN */
259
260
261 #if !HAVE_MEMMOVE
262
memmove(void * dest,const void * src,size_t n)263 void *memmove(void *dest, const void *src, size_t n) {
264 char *dc;
265 const char *sc;
266 int i;
267
268 dc = dest;
269 sc = src;
270 if ((dc + n < sc) || (sc + n < dc))
271 return(memcpy(dest, src, n));
272 else {
273 if (dc < sc) {
274 for (i = 0; i < n; ++i) {
275 dc[i] = sc[i];
276 }
277 } else if (sc < dc) {
278 for (i = n - 1; i >= 0; --i) {
279 dc[i] = sc[i];
280 }
281 }
282 }
283 return(dest);
284 }
285
286 #endif /* !HAVE_MEMMOVE */
287
288 #if !HAVE_STRCASECMP
289
strcasecmp(const char * s1,const char * s2)290 int strcasecmp(const char *s1, const char *s2) {
291 int i;
292 char c1, c2;
293
294 for (i = 0; s1[i]; ++i) {
295 c1 = s1[i];
296 c2 = s2[i];
297 if ((c1 >= 'a') && (c1 <= 'z'))
298 c1 += 'A' - 'a';
299 if ((c2 >= 'a') && (c2 <= 'z'))
300 c2 += 'A' - 'a';
301 if (c1 != c2)
302 return((int)c1 - (int)c2);
303 }
304 if (s2[i])
305 return(-1);
306 return(0);
307 }
308
309 #endif /* !HAVE_STRCASECMP */
310