]> andersk Git - splint.git/blob - src/general.c
51f61c9f3a59c9408ebd40ce12c316a4aaad0b3c
[splint.git] / src / general.c
1 /*
2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2002 University of Virginia,
4 **         Massachusetts Institute of Technology
5 **
6 ** This program is free software; you can redistribute it and/or modify it
7 ** under the terms of the GNU General Public License as published by the
8 ** Free Software Foundation; either version 2 of the License, or (at your
9 ** option) any later version.
10 ** 
11 ** This program is distributed in the hope that it will be useful, but
12 ** WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 ** General Public License for more details.
15 ** 
16 ** The GNU General Public License is available from http://www.gnu.org/ or
17 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18 ** MA 02111-1307, USA.
19 **
20 ** For information on splint: splint@cs.virginia.edu
21 ** To report a bug: splint-bug@cs.virginia.edu
22 ** For more information: http://www.splint.org
23 */
24 /*
25 ** general.c
26 */
27
28 # include "splintMacros.nf"
29 # include "basic.h"
30 # undef malloc
31 # undef realloc
32 # undef calloc
33
34 # ifdef USEDMALLOC
35 # include "dmalloc.h"
36 # endif
37
38 # include "portab.h"
39
40 /*
41 ** redefine undef'd memory ops
42 */
43
44 # ifndef USEDMALLOC
45
46 /*@-mustdefine@*/
47
48 void sfree (void *x)
49 {
50   if (x != NULL)
51     {
52       /* fprintf (stderr, "Freeing: %p\n", x); */
53
54       /*
55       if ((unsigned long) x > 0xbf000000) {
56         fprintf (stderr, "Looks bad!\n");
57       }
58       */
59       
60       free (x);
61       
62       /* fprintf (stderr, "Done.\n"); */
63     }
64 }
65 # endif
66
67 void sfreeEventually (void *x)
68 {
69   if (x != NULL)
70     {
71       ; /* should keep in a table */
72     }
73 /*@-mustfree@*/
74 } /*@=mustfree@*/
75
76 /*
77 ** all memory should be allocated from dimalloc
78 */
79
80 static long unsigned size_toLongUnsigned (size_t x)
81 {
82   long unsigned res = (long unsigned) x;
83
84   llassert ((size_t) res == x);
85   return res;
86 }
87
88 /*@out@*/ void *dimalloc (size_t size, const char *name, int line)
89      /*@ensures maxSet(result) == (size - 1); @*/ 
90 {
91   /*
92   static void *lastaddr = 0;
93   static int numallocs = 0;
94   static int numbad = 0;
95   */
96
97   /* was malloc, use calloc to initialize to zero */
98   void *ret = (void *) calloc (1, size);
99
100   /*
101   numallocs++;
102
103   if (ret < lastaddr)
104     {
105       numbad++;
106       fprintf (stderr, "Bad alloc: %d / %d\n", numbad, numallocs);
107     }
108
109   lastaddr = ret;
110   */
111
112   if (ret == NULL)
113     {
114       if (size == 0)
115         {
116           llbug (message ("Zero allocation at %q.",
117                           fileloc_unparseRaw (cstring_fromChars (name), line)));
118         }
119       else
120         {
121           /* drl
122              fix this so message doesn't run out of
123              memory*/
124           
125           llbuglit("Out of memory");
126           
127           llfatalerrorLoc
128             (message ("Out of memory.  Allocating %w bytes at %s:%d.", 
129                       size_toLongUnsigned (size),
130                       cstring_fromChars (name), line));
131           
132         }
133     }
134       
135   /*@-null@*/ /* null okay for size = 0 */
136   /* fprintf (stderr, "%s:%d: Allocating: [%p / %d]\n", name, line, ret, size);  */
137   return ret; 
138   /*@=null@*/
139 }
140
141 void *dicalloc (size_t num, size_t size, const char *name, int line)
142 {
143   void *ret = (void *) calloc (num, size);
144
145   if (ret == NULL)
146     {
147       llfatalerrorLoc 
148         (message ("Out of memory.  Allocating %w bytes at %s:%d.", 
149                   size_toLongUnsigned (size),
150                   cstring_fromChars (name), line));
151     }
152   
153   return ret;
154 }
155
156 void *direalloc (/*@out@*/ /*@null@*/ void *x, size_t size, 
157                  char *name, int line)
158 {
159   void *ret;
160
161   if (x == NULL)
162     {                                  
163       ret = (void *) dmalloc (size);
164     }
165   else
166     {
167       ret = (void *) realloc (x, size);
168     }
169
170   if (ret == NULL)
171     {
172       llfatalerrorLoc
173         (message ("Out of memory.  Allocating %w bytes at %s:%d.", 
174                   size_toLongUnsigned (size),
175                   cstring_fromChars (name), line));
176     }
177   
178   return ret;
179 }
180
181 /*@=mustdefine@*/
182
183 # ifndef NOLCL
184 char *FormatInt (int i)
185 {
186   char temp[255]; /* assume the integer has at most 254 digits */
187   char *outs;
188
189   sprintf (temp, "%i", i);
190   outs = (char *) dmalloc (sizeof (*outs) * (1 + strlen (temp)));
191   strcpy (outs, temp);
192
193   return (outs);
194 }
195 # endif
196
197 # ifndef NOLCL
198 bool firstWord (char *s, char *w)
199 {
200   llassert (s != NULL);
201   llassert (w != NULL);
202   
203   for (; *w != '\0'; w++, s++)
204     {
205       if (*w != *s || *s == '\0')
206         return FALSE;
207     }
208   return TRUE;
209 }
210 # endif
211
212 void mstring_markFree (char *s)
213 {
214   sfreeEventually (s);
215 }
216
217 char *mstring_spaces (int n)
218 {
219   int i;
220   char *ret;
221   char *ptr;
222
223   llassert (n >= 0);
224
225   ret = (char *) dmalloc (size_fromInt (n + 1));
226   ptr = ret;
227
228   for (i = 0; i < n; i++)
229     {
230       *ptr++ = ' ';
231     }
232
233   *ptr = '\0';
234
235   return ret;
236 }
237
238 bool mstring_containsChar (const char *s, char c)
239 {
240   if (mstring_isDefined (s))
241     {
242       return (strchr (s, c) != NULL);
243     }
244   else
245     {
246       return FALSE;
247     }
248 }
249
250 bool mstring_containsString (const char *s, const char *c)
251 {
252   if (mstring_isDefined (s))
253     {
254       return (strstr (s, c) != NULL);
255     }
256   else
257     {
258       return FALSE;
259     }
260 }
261  
262 char *mstring_concat (const char *s1, const char *s2)
263 {
264   char *s = (char *) dmalloc (strlen (s1) + strlen (s2) + 1);
265   strcpy (s, s1);
266   strcat (s, s2);
267   return s;
268 }
269
270 extern /*@only@*/ char *
271 mstring_concatFree (/*@only@*/ char *s1, /*@only@*/ char *s2)
272 {
273   /* like mstring_concat but deallocates old strings */
274   char *s = (char *) dmalloc (strlen (s1) + strlen (s2) + 1);
275   strcpy (s, s1);
276   strcat (s, s2);
277
278   sfree (s1);
279   sfree (s2);
280   return s;
281 }
282
283 extern /*@only@*/ char *
284 mstring_concatFree1 (/*@only@*/ char *s1, const char *s2)
285 {
286   char *s = (char *) dmalloc (strlen (s1) + strlen (s2) + 1);
287   strcpy (s, s1);
288   strcat (s, s2);
289   sfree (s1);
290
291   return s;
292 }
293
294 extern /*@only@*/ char *
295 mstring_append (/*@only@*/ char *s1, char c)
296 {
297   size_t l = strlen (s1);
298   char *s;
299
300   s = (char *) dmalloc (sizeof (*s) * (l + 2));
301
302   strcpy (s, s1);
303   *(s + l) = c;
304   *(s + l + 1) = '\0';
305   sfree (s1); 
306   return s;
307 }
308
309 extern 
310 char *mstring_copy (char *s1) /*@ensures maxRead(result) == maxRead(s1) /\  maxSet(result) == maxSet(s1) @*/
311 {
312   if (s1 == NULL)
313     {
314       return NULL;
315     }
316   else
317     {
318       char *s = (char *) dmalloc ((strlen (s1) + 1) * sizeof (*s));
319       strcpy (s, s1);
320       return s;
321     }
322 }
323
324 extern
325 char *mstring_safePrint (char *s)
326 {
327   if (s == NULL)
328     {
329       return ("<undefined>");
330     }
331   else
332     {
333       return s;
334     }
335 }
336
337 extern
338 char *mstring_create (int n)
339 {
340   char *s;
341
342   s = dmalloc (sizeof (*s) * (n + 1));
343   *s = '\0';
344   return s;
345 }
346
347 void
348 fputline (FILE *out, char *s)
349 {
350   if (strlen (s) > 0) 
351     {
352       check (fputs (s, out) != EOF);
353     }
354
355   check (fputc ('\n', out) == (int) '\n');
356 }
357
358 unsigned int int_toNonNegative (int x) /*@*/
359 {
360   llassert (x >= 0);
361   return (unsigned) x;
362 }
363
364 int int_log (int x)
365 {
366   int ret = 1;
367
368   while (x > 10)
369     {
370       ret++;
371       x /= 10;
372     }
373
374   return ret;
375 }
376
377 /*@-czechfcns@*/
378 long unsigned int 
379 longUnsigned_fromInt (int x)
380 {
381   llassert (x >= 0);
382   
383   return (long unsigned) x;
384 }
385
386 size_t size_fromInt (int x) /*@ensures result==x@*/
387 {
388   size_t res = (size_t) x;
389
390   llassert ((int) res == x);
391   return res;
392 }
393
394 int size_toInt (size_t x)
395 {
396   int res = (int) x;
397
398   llassert ((size_t) res == x);
399   return res;
400 }
401
402 long size_toLong (size_t x)
403 {
404   long res = (long) x;
405
406   llassert ((size_t) res == x);
407   return res;
408 }
409
410 /*@=czechfcns@*/
411
412 char
413 char_fromInt (int x)
414 {
415   /*
416   ** evans 2001-09-28 - changed assertion in response to Anthony Giorgio's comment 
417   ** that the old assertions failed for EBCDIC character set.  Now we just check 
418   ** that the result is equal.
419   */
420
421   char res = (char) x;
422   llassert ((int) res == x);
423   return res;
424 }
425
426 /*@-czechfcns@*/
427 int
428 longUnsigned_toInt (long unsigned int x)
429 {
430   int res = (int) x;
431
432   llassert ((long unsigned) res == x);
433   return res;
434 }
435
436 int
437 long_toInt (long int x)
438 {
439   int res = (int) x;
440
441   /*@+ignorequals@*/ llassert (res == x); /*@=ignorequals@*/
442   return res;
443 }
444
445 /*@+czechfcns@*/
446
447 bool mstring_equalPrefix (const char *c1, const char *c2)
448 {
449   llassert (c1 != NULL);
450   llassert (c2 != NULL);
451
452   if (strncmp(c1, c2, strlen(c2)) == 0)
453     {
454       return TRUE;
455     }
456   else
457     {
458       return FALSE;
459     }
460 }
461
462 bool mstring_equal (/*@null@*/ const char *s1, /*@null@*/ const char *s2)
463 {
464   if (s1 == NULL)
465     {
466       return (s2 == NULL);
467     }
468   else
469     {
470       if (s2 == NULL)
471         {
472           return FALSE;
473         }
474       else
475         {
476           return (strcmp(s1, s2) == 0);
477         }
478     }
479 }
480
This page took 0.057893 seconds and 3 git commands to generate.