]> andersk Git - splint.git/blob - src/general.c
972420079cde04b7be3ae3f554c2fbc149469108
[splint.git] / src / general.c
1 /*
2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2003 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: info@splint.org
21 ** To report a bug: splint-bug@splint.org
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           llcontbug (message ("Zero allocation at %q.",
117                               fileloc_unparseRaw (cstring_fromChars (name), line)));
118           
119           /* 
120           ** evans 2002-03-01
121           ** Return some allocated storage...hope we get lucky.
122           */
123
124           return dimalloc (16, name, line);
125         }
126       else
127         {
128           /* drl
129              fix this so message doesn't run out of
130              memory*/
131           
132           llbuglit("Out of memory");
133           
134           llfatalerrorLoc
135             (message ("Out of memory.  Allocating %w bytes at %s:%d.", 
136                       size_toLongUnsigned (size),
137                       cstring_fromChars (name), line));
138           
139         }
140     }
141       
142   /*@-null@*/ /* null okay for size = 0 */
143   /* fprintf (stderr, "%s:%d: Allocating: [%p / %d]\n", name, line, ret, size);  */
144   return ret; 
145   /*@=null@*/
146 }
147
148 void *dicalloc (size_t num, size_t size, const char *name, int line)
149 {
150   void *ret = (void *) calloc (num, size);
151
152   if (ret == NULL)
153     {
154       llfatalerrorLoc 
155         (message ("Out of memory.  Allocating %w bytes at %s:%d.", 
156                   size_toLongUnsigned (size),
157                   cstring_fromChars (name), line));
158     }
159   
160   return ret;
161 }
162
163 void *direalloc (/*@out@*/ /*@null@*/ void *x, size_t size, 
164                  char *name, int line)
165 {
166   void *ret;
167
168   if (x == NULL)
169     {                                  
170       ret = (void *) dmalloc (size);
171     }
172   else
173     {
174       ret = (void *) realloc (x, size);
175     }
176
177   if (ret == NULL)
178     {
179       llfatalerrorLoc
180         (message ("Out of memory.  Allocating %w bytes at %s:%d.", 
181                   size_toLongUnsigned (size),
182                   cstring_fromChars (name), line));
183     }
184   
185   return ret;
186 }
187
188 /*@=mustdefine@*/
189
190 char *FormatInt (int i)
191 {
192   char temp[255]; /* assume the integer has at most 254 digits */
193   char *outs;
194   int sres = snprintf (temp, 255, "%i", i);
195   check (sres >= 0 && sres <= 255);
196   outs = (char *) dmalloc (sizeof (*outs) * (1 + strlen (temp)));
197   strcpy (outs, temp);
198
199   return (outs);
200 }
201
202 bool firstWord (char *s, char *w)
203 {
204   llassert (s != NULL);
205   llassert (w != NULL);
206   
207   for (; *w != '\0'; w++, s++)
208     {
209       if (*w != *s || *s == '\0')
210         return FALSE;
211     }
212   return TRUE;
213 }
214
215 void mstring_markFree (char *s)
216 {
217   sfreeEventually (s);
218 }
219
220 char *mstring_spaces (int n)
221 {
222   int i;
223   char *ret;
224   char *ptr;
225
226   llassert (n >= 0);
227
228   ret = (char *) dmalloc (size_fromInt (n + 1));
229   ptr = ret;
230
231   for (i = 0; i < n; i++)
232     {
233       *ptr++ = ' ';
234     }
235
236   *ptr = '\0';
237
238   return ret;
239 }
240
241 bool mstring_containsChar (const char *s, char c)
242 {
243   if (mstring_isDefined (s))
244     {
245       return (strchr (s, c) != NULL);
246     }
247   else
248     {
249       return FALSE;
250     }
251 }
252
253 bool mstring_containsString (const char *s, const char *c)
254 {
255   if (mstring_isDefined (s))
256     {
257       return (strstr (s, c) != NULL);
258     }
259   else
260     {
261       return FALSE;
262     }
263 }
264  
265 char *mstring_concat (const char *s1, const char *s2)
266 {
267   char *s = (char *) dmalloc (strlen (s1) + strlen (s2) + 1);
268   strcpy (s, s1);
269   strcat (s, s2);
270   return s;
271 }
272
273 extern /*@only@*/ char *
274 mstring_concatFree (/*@only@*/ char *s1, /*@only@*/ char *s2)
275 {
276   /* like mstring_concat but deallocates old strings */
277   char *s = (char *) dmalloc (strlen (s1) + strlen (s2) + 1);
278   strcpy (s, s1);
279   strcat (s, s2);
280
281   sfree (s1);
282   sfree (s2);
283   return s;
284 }
285
286 extern /*@only@*/ char *
287 mstring_concatFree1 (/*@only@*/ char *s1, const char *s2)
288 {
289   char *s = (char *) dmalloc (strlen (s1) + strlen (s2) + 1);
290   strcpy (s, s1);
291   strcat (s, s2);
292   sfree (s1);
293
294   return s;
295 }
296
297 extern /*@only@*/ char *
298 mstring_append (/*@only@*/ char *s1, char c)
299 {
300   size_t l = strlen (s1);
301   char *s;
302
303   s = (char *) dmalloc (sizeof (*s) * (l + 2));
304
305   strcpy (s, s1);
306   *(s + l) = c;
307   *(s + l + 1) = '\0';
308   sfree (s1); 
309   return s;
310 }
311
312 extern 
313 char *mstring_copy (char *s1) /*@ensures maxRead(result) == maxRead(s1) /\  maxSet(result) == maxSet(s1) @*/
314 {
315   if (s1 == NULL)
316     {
317       return NULL;
318     }
319   else
320     {
321       char *s = (char *) dmalloc ((strlen (s1) + 1) * sizeof (*s));
322       strcpy (s, s1);
323       return s;
324     }
325 }
326
327 extern
328 char *mstring_safePrint (char *s)
329 {
330   if (s == NULL)
331     {
332       return ("<undefined>");
333     }
334   else
335     {
336       return s;
337     }
338 }
339
340 extern
341 char *mstring_create (size_t n)
342 {
343   char *s;
344
345   s = dmalloc (sizeof (*s) * (n + 1));
346   *s = '\0';
347   return s;
348 }
349
350 void
351 fputline (FILE *out, char *s)
352 {
353   if (strlen (s) > 0) 
354     {
355       check (fputs (s, out) != EOF);
356     }
357
358   check (fputc ('\n', out) == (int) '\n');
359 }
360
361 unsigned int int_toNonNegative (int x) /*@*/
362 {
363   llassert (x >= 0);
364   return (unsigned) x;
365 }
366
367 int int_log (int x)
368 {
369   int ret = 1;
370
371   while (x > 10)
372     {
373       ret++;
374       x /= 10;
375     }
376
377   return ret;
378 }
379
380 /*@-czechfcns@*/
381 long unsigned int 
382 longUnsigned_fromInt (int x)
383 {
384   llassert (x >= 0);
385   
386   return (long unsigned) x;
387 }
388
389 size_t size_fromInt (int x) /*@ensures result==x@*/
390 {
391   size_t res = (size_t) x;
392
393   llassert ((int) res == x);
394   return res;
395 }
396
397 size_t size_fromLong (long x) /*@ensures result==x@*/
398 {
399   size_t res = (size_t) x;
400
401   llassert ((long) res == x);
402   return res;
403 }
404
405 size_t size_fromLongUnsigned (unsigned long x) /*@ensures result==x@*/
406 {
407   size_t res = (size_t) x;
408
409   llassert ((unsigned long) res == x);
410   return res;
411 }
412
413 int size_toInt (size_t x)
414 {
415   int res = (int) x;
416
417   llassert ((size_t) res == x);
418   return res;
419 }
420
421 long size_toLong (size_t x)
422 {
423   long res = (long) x;
424
425   llassert ((size_t) res == x);
426   return res;
427 }
428
429 /*@=czechfcns@*/
430
431 char
432 char_fromInt (int x)
433 {
434   /*
435   ** evans 2001-09-28 - changed assertion in response to Anthony Giorgio's comment 
436   ** that the old assertions failed for EBCDIC character set.  Now we just check 
437   ** that the result is equal.
438   */
439
440   char res = (char) x;
441   llassert ((int) res == x);
442   return res;
443 }
444
445 /*@-czechfcns@*/
446 int
447 longUnsigned_toInt (long unsigned int x)
448 {
449   int res = (int) x;
450
451   llassert ((long unsigned) res == x);
452   return res;
453 }
454
455 int
456 long_toInt (long int x)
457 {
458   int res = (int) x;
459
460   /*@+ignorequals@*/ llassert (res == x); /*@=ignorequals@*/
461   return res;
462 }
463
464 /*@+czechfcns@*/
465
466 bool mstring_equalPrefix (const char *c1, const char *c2)
467 {
468   llassert (c1 != NULL);
469   llassert (c2 != NULL);
470
471   if (strncmp(c1, c2, strlen(c2)) == 0)
472     {
473       return TRUE;
474     }
475   else
476     {
477       return FALSE;
478     }
479 }
480
481 bool mstring_equal (/*@null@*/ const char *s1, /*@null@*/ const char *s2)
482 {
483   if (s1 == NULL)
484     {
485       return (s2 == NULL);
486     }
487   else
488     {
489       if (s2 == NULL)
490         {
491           return FALSE;
492         }
493       else
494         {
495           return (strcmp(s1, s2) == 0);
496         }
497     }
498 }
499
This page took 0.061484 seconds and 3 git commands to generate.