]> andersk Git - splint.git/blob - src/general.c
Fixed line numbering when multi-line macro parameters are used.
[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: 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 # ifndef NOLCL
191 char *FormatInt (int i)
192 {
193   char temp[255]; /* assume the integer has at most 254 digits */
194   char *outs;
195
196   sprintf (temp, "%i", i);
197   outs = (char *) dmalloc (sizeof (*outs) * (1 + strlen (temp)));
198   strcpy (outs, temp);
199
200   return (outs);
201 }
202 # endif
203
204 # ifndef NOLCL
205 bool firstWord (char *s, char *w)
206 {
207   llassert (s != NULL);
208   llassert (w != NULL);
209   
210   for (; *w != '\0'; w++, s++)
211     {
212       if (*w != *s || *s == '\0')
213         return FALSE;
214     }
215   return TRUE;
216 }
217 # endif
218
219 void mstring_markFree (char *s)
220 {
221   sfreeEventually (s);
222 }
223
224 char *mstring_spaces (int n)
225 {
226   int i;
227   char *ret;
228   char *ptr;
229
230   llassert (n >= 0);
231
232   ret = (char *) dmalloc (size_fromInt (n + 1));
233   ptr = ret;
234
235   for (i = 0; i < n; i++)
236     {
237       *ptr++ = ' ';
238     }
239
240   *ptr = '\0';
241
242   return ret;
243 }
244
245 bool mstring_containsChar (const char *s, char c)
246 {
247   if (mstring_isDefined (s))
248     {
249       return (strchr (s, c) != NULL);
250     }
251   else
252     {
253       return FALSE;
254     }
255 }
256
257 bool mstring_containsString (const char *s, const char *c)
258 {
259   if (mstring_isDefined (s))
260     {
261       return (strstr (s, c) != NULL);
262     }
263   else
264     {
265       return FALSE;
266     }
267 }
268  
269 char *mstring_concat (const char *s1, const char *s2)
270 {
271   char *s = (char *) dmalloc (strlen (s1) + strlen (s2) + 1);
272   strcpy (s, s1);
273   strcat (s, s2);
274   return s;
275 }
276
277 extern /*@only@*/ char *
278 mstring_concatFree (/*@only@*/ char *s1, /*@only@*/ char *s2)
279 {
280   /* like mstring_concat but deallocates old strings */
281   char *s = (char *) dmalloc (strlen (s1) + strlen (s2) + 1);
282   strcpy (s, s1);
283   strcat (s, s2);
284
285   sfree (s1);
286   sfree (s2);
287   return s;
288 }
289
290 extern /*@only@*/ char *
291 mstring_concatFree1 (/*@only@*/ char *s1, const char *s2)
292 {
293   char *s = (char *) dmalloc (strlen (s1) + strlen (s2) + 1);
294   strcpy (s, s1);
295   strcat (s, s2);
296   sfree (s1);
297
298   return s;
299 }
300
301 extern /*@only@*/ char *
302 mstring_append (/*@only@*/ char *s1, char c)
303 {
304   size_t l = strlen (s1);
305   char *s;
306
307   s = (char *) dmalloc (sizeof (*s) * (l + 2));
308
309   strcpy (s, s1);
310   *(s + l) = c;
311   *(s + l + 1) = '\0';
312   sfree (s1); 
313   return s;
314 }
315
316 extern 
317 char *mstring_copy (char *s1) /*@ensures maxRead(result) == maxRead(s1) /\  maxSet(result) == maxSet(s1) @*/
318 {
319   if (s1 == NULL)
320     {
321       return NULL;
322     }
323   else
324     {
325       char *s = (char *) dmalloc ((strlen (s1) + 1) * sizeof (*s));
326       strcpy (s, s1);
327       return s;
328     }
329 }
330
331 extern
332 char *mstring_safePrint (char *s)
333 {
334   if (s == NULL)
335     {
336       return ("<undefined>");
337     }
338   else
339     {
340       return s;
341     }
342 }
343
344 extern
345 char *mstring_create (size_t n)
346 {
347   char *s;
348
349   s = dmalloc (sizeof (*s) * (n + 1));
350   *s = '\0';
351   return s;
352 }
353
354 void
355 fputline (FILE *out, char *s)
356 {
357   if (strlen (s) > 0) 
358     {
359       check (fputs (s, out) != EOF);
360     }
361
362   check (fputc ('\n', out) == (int) '\n');
363 }
364
365 unsigned int int_toNonNegative (int x) /*@*/
366 {
367   llassert (x >= 0);
368   return (unsigned) x;
369 }
370
371 int int_log (int x)
372 {
373   int ret = 1;
374
375   while (x > 10)
376     {
377       ret++;
378       x /= 10;
379     }
380
381   return ret;
382 }
383
384 /*@-czechfcns@*/
385 long unsigned int 
386 longUnsigned_fromInt (int x)
387 {
388   llassert (x >= 0);
389   
390   return (long unsigned) x;
391 }
392
393 size_t size_fromInt (int x) /*@ensures result==x@*/
394 {
395   size_t res = (size_t) x;
396
397   llassert ((int) res == x);
398   return res;
399 }
400
401 int size_toInt (size_t x)
402 {
403   int res = (int) x;
404
405   llassert ((size_t) res == x);
406   return res;
407 }
408
409 long size_toLong (size_t x)
410 {
411   long res = (long) x;
412
413   llassert ((size_t) res == x);
414   return res;
415 }
416
417 /*@=czechfcns@*/
418
419 char
420 char_fromInt (int x)
421 {
422   /*
423   ** evans 2001-09-28 - changed assertion in response to Anthony Giorgio's comment 
424   ** that the old assertions failed for EBCDIC character set.  Now we just check 
425   ** that the result is equal.
426   */
427
428   char res = (char) x;
429   llassert ((int) res == x);
430   return res;
431 }
432
433 /*@-czechfcns@*/
434 int
435 longUnsigned_toInt (long unsigned int x)
436 {
437   int res = (int) x;
438
439   llassert ((long unsigned) res == x);
440   return res;
441 }
442
443 int
444 long_toInt (long int x)
445 {
446   int res = (int) x;
447
448   /*@+ignorequals@*/ llassert (res == x); /*@=ignorequals@*/
449   return res;
450 }
451
452 /*@+czechfcns@*/
453
454 bool mstring_equalPrefix (const char *c1, const char *c2)
455 {
456   llassert (c1 != NULL);
457   llassert (c2 != NULL);
458
459   if (strncmp(c1, c2, strlen(c2)) == 0)
460     {
461       return TRUE;
462     }
463   else
464     {
465       return FALSE;
466     }
467 }
468
469 bool mstring_equal (/*@null@*/ const char *s1, /*@null@*/ const char *s2)
470 {
471   if (s1 == NULL)
472     {
473       return (s2 == NULL);
474     }
475   else
476     {
477       if (s2 == NULL)
478         {
479           return FALSE;
480         }
481       else
482         {
483           return (strcmp(s1, s2) == 0);
484         }
485     }
486 }
487
This page took 0.072492 seconds and 5 git commands to generate.