]> andersk Git - splint.git/blob - src/general.c
Merged code tree with Dave Evans's version. Many changes to numberous to list....
[splint.git] / src / general.c
1 /*
2 ** LCLint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2001 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 lclint: lclint-request@cs.virginia.edu
21 ** To report a bug: lclint-bug@cs.virginia.edu
22 ** For more information: http://lclint.cs.virginia.edu
23 */
24 /*
25 ** general.c
26 */
27
28 # include "lclintMacros.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 # include <stdlib.h> 
46
47 /*@-mustdefine@*/
48
49 void sfree (void *x)
50 {
51   if (x != NULL)
52     {
53       /* fprintf (stderr, "Freeing: %p\n", x); */
54
55       /*
56       if ((unsigned long) x > 0xbf000000) {
57         fprintf (stderr, "Looks bad!\n");
58       }
59       */
60       
61       free (x);
62       
63       /* fprintf (stderr, "Done.\n"); */
64     }
65 }
66 # endif
67
68 void sfreeEventually (void *x)
69 {
70   if (x != NULL)
71     {
72       ; /* should keep in a table */
73     }
74 /*@-mustfree@*/
75 } /*@=mustfree@*/
76
77 /*
78 ** all memory should be allocated from dimalloc
79 */
80
81 static long unsigned size_toLongUnsigned (size_t x)
82 {
83   long unsigned res = (long unsigned) x;
84
85   llassert ((size_t) res == x);
86   return res;
87 }
88
89 /*@out@*/ void *dimalloc (size_t size, const char *name, int line)
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           llfatalerrorLoc
122             (message ("Out of memory.  Allocating %w bytes at %s:%d.", 
123                       size_toLongUnsigned (size),
124                       cstring_fromChars (name), line));
125         }
126     }
127       
128   /*@-null@*/ /* null okay for size = 0 */
129   /* fprintf (stderr, "%s:%d: Allocating: [%p / %d]\n", name, line, ret, size);  */
130   return ret; 
131   /*@=null@*/
132 }
133
134 void *dicalloc (size_t num, size_t size, const char *name, int line)
135 {
136   void *ret = (void *) calloc (num, size);
137
138   if (ret == NULL)
139     {
140       llfatalerrorLoc 
141         (message ("Out of memory.  Allocating %w bytes at %s:%d.", 
142                   size_toLongUnsigned (size),
143                   cstring_fromChars (name), line));
144     }
145   
146   return ret;
147 }
148
149 void *direalloc (/*@out@*/ /*@null@*/ void *x, size_t size, 
150                  char *name, int line)
151 {
152   void *ret;
153
154   if (x == NULL)
155     {                                  
156       ret = (void *) dmalloc (size);
157     }
158   else
159     {
160       ret = (void *) realloc (x, size);
161     }
162
163   if (ret == NULL)
164     {
165       llfatalerrorLoc
166         (message ("Out of memory.  Allocating %w bytes at %s:%d.", 
167                   size_toLongUnsigned (size),
168                   cstring_fromChars (name), line));
169     }
170   
171   return ret;
172 }
173
174 /*@=mustdefine@*/
175
176 # ifndef NOLCL
177 char *FormatInt (int i)
178 {
179   char temp[255]; /* assume the integer has at most 254 digits */
180   char *outs;
181
182   sprintf (temp, "%i", i);
183   outs = (char *) dmalloc (sizeof (*outs) * (1 + strlen (temp)));
184   strcpy (outs, temp);
185
186   return (outs);
187 }
188 # endif
189
190 # ifndef NOLCL
191 bool firstWord (char *s, char *w)
192 {
193   llassert (s != NULL);
194   llassert (w != NULL);
195   
196   for (; *w != '\0'; w++, s++)
197     {
198       if (*w != *s || *s == '\0')
199         return FALSE;
200     }
201   return TRUE;
202 }
203 # endif
204
205 void mstring_markFree (char *s)
206 {
207     sfreeEventually (s);
208 }
209
210 char *mstring_spaces (int n)
211 {
212   int i;
213   char *ret;
214   char *ptr;
215
216   llassert (n >= 0);
217
218   ret = (char *) dmalloc (size_fromInt (n + 1));
219   ptr = ret;
220
221   for (i = 0; i < n; i++)
222     {
223       *ptr++ = ' ';
224     }
225
226   *ptr = '\0';
227
228   return ret;
229 }
230
231 bool mstring_containsChar (const char *s, char c)
232 {
233   if (mstring_isDefined (s))
234     {
235       return (strchr (s, c) != NULL);
236     }
237   else
238     {
239       return FALSE;
240     }
241 }
242  
243 char *mstring_concat (const char *s1, const char *s2)
244 {
245   char *s = (char *) dmalloc (strlen (s1) + strlen (s2) + 1);
246   strcpy (s, s1);
247   strcat (s, s2);
248   return s;
249 }
250
251 extern /*@only@*/ char *
252 mstring_concatFree (/*@only@*/ char *s1, /*@only@*/ char *s2)
253 {
254   /* like mstring_concat but deallocates old strings */
255   char *s = (char *) dmalloc (strlen (s1) + strlen (s2) + 1);
256   strcpy (s, s1);
257   strcat (s, s2);
258
259   sfree (s1);
260   sfree (s2);
261   return s;
262 }
263
264 extern /*@only@*/ char *
265 mstring_concatFree1 (/*@only@*/ 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   sfree (s1);
271
272   return s;
273 }
274
275 extern /*@only@*/ char *
276 mstring_append (/*@only@*/ char *s1, char c)
277 {
278   size_t l = strlen (s1);
279   char *s;
280
281   s = (char *) dmalloc (sizeof (*s) * (l + 2));
282
283   strcpy (s, s1);
284   *(s + l) = c;
285   *(s + l + 1) = '\0';
286   sfree (s1); 
287   return s;
288 }
289
290 extern 
291 char *mstring_copy (char *s1)
292 {
293   if (s1 == NULL)
294     {
295       return NULL;
296     }
297   else
298     {
299       char *s = (char *) dmalloc ((strlen (s1) + 1) * sizeof (*s));
300       strcpy (s, s1);
301       return s;
302     }
303 }
304
305 extern
306 char *mstring_safePrint (char *s)
307 {
308   if (s == NULL)
309     {
310       return ("<undefined>");
311     }
312   else
313     {
314       return s;
315     }
316 }
317
318 extern
319 char *mstring_create (int n)
320 {
321   char *s;
322
323   s = dmalloc (sizeof (*s) * (n + 1));
324   *s = '\0';
325   return s;
326 }
327
328 void
329 fputline (FILE *out, char *s)
330 {
331   if (strlen (s) > 0) 
332     {
333       check (fputs (s, out) != EOF);
334     }
335
336   check (fputc ('\n', out) == (int) '\n');
337 }
338
339 int int_log (int x)
340 {
341   int ret = 1;
342
343   while (x > 10)
344     {
345       ret++;
346       x /= 10;
347     }
348
349   return ret;
350 }
351
352 /*@-czechfcns@*/
353 long unsigned int 
354 longUnsigned_fromInt (int x)
355 {
356   llassert (x >= 0);
357   
358   return (long unsigned) x;
359 }
360
361 size_t size_fromInt (int x)
362 {
363   size_t res = (size_t) x;
364
365   llassert ((int) res == x);
366   return res;
367 }
368
369 int size_toInt (size_t x)
370 {
371   int res = (int) x;
372
373   llassert ((size_t) res == x);
374   return res;
375 }
376
377 long size_toLong (size_t x)
378 {
379   long res = (long) x;
380
381   llassert ((size_t) res == x);
382   return res;
383 }
384
385 /*@=czechfcns@*/
386
387 char
388 char_fromInt (int x)
389 {
390   llassert ((x >= (int)'\0') && (x <= (int)'~'));
391
392   return ((char) x);
393 }
394
395 /*@-czechfcns@*/
396 int
397 longUnsigned_toInt (long unsigned int x)
398 {
399   int res = (int) x;
400
401   llassert ((long unsigned) res == x);
402   return res;
403 }
404
405 int
406 long_toInt (long int x)
407 {
408   int res = (int) x;
409
410   /*@+ignorequals@*/ llassert (res == x); /*@=ignorequals@*/
411   return res;
412 }
413
414 /*@+czechfcns@*/
415
416 bool mstring_equalPrefix (const char *c1, const char *c2)
417 {
418   llassert (c1 != NULL);
419   llassert (c2 != NULL);
420
421   if (strncmp(c1, c2, strlen(c2)) == 0)
422     {
423       return TRUE;
424     }
425   else
426     {
427       return FALSE;
428     }
429 }
430
431 bool mstring_equal (/*@null@*/ const char *s1, /*@null@*/ const char *s2)
432 {
433   if (s1 == NULL)
434     {
435       return (s2 == NULL);
436     }
437   else
438     {
439       if (s2 == NULL)
440         {
441           return FALSE;
442         }
443       else
444         {
445           return (strcmp(s1, s2) == 0);
446         }
447     }
448 }
449
This page took 0.073814 seconds and 5 git commands to generate.