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