]> andersk Git - splint.git/blame - src/general.c
Updating to use the LEnsures and LRequires instead of the ensures requires so
[splint.git] / src / general.c
CommitLineData
616915dd 1/*
2** LCLint - annotation-assisted static program checker
3** Copyright (C) 1994-2000 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
49void sfree (void *x)
50{
51 if (x != NULL)
52 {
53 /*
54 fprintf (stderr, "Freeing: %ld\n", x);
55 if ((unsigned long) x < 136000000 && (unsigned long) x > 135000000) {
56 fprintf (stderr, "Looks bad!\n");
57 }
58 */
59 free (x);
60 /* fprintf (stderr, "Done.\n"); */
61 }
62}
63# endif
64
65void sfreeEventually (void *x)
66{
67 if (x != NULL)
68 {
69 ; /* should keep in a table */
70 }
71/*@-mustfree@*/
72} /*@=mustfree@*/
73
74/*
75** all memory should be allocated from dimalloc
76*/
77
78static long unsigned size_toLongUnsigned (size_t x)
79{
80 long unsigned res = (long unsigned) x;
81
82 llassert ((size_t) res == x);
83 return res;
84}
85
86/*@out@*/ void *dimalloc (size_t size, char *name, int line)
87{
88 /*
89 static void *lastaddr = 0;
90 static int numallocs = 0;
91 static int numbad = 0;
92 */
93
94 /* was malloc, use calloc to initialize to zero */
95 void *ret = (void *) calloc (1, size);
96
97 /*
98 numallocs++;
99
100 if (ret < lastaddr)
101 {
102 numbad++;
103 fprintf (stderr, "Bad alloc: %d / %d\n", numbad, numallocs);
104 }
105
106 lastaddr = ret;
107 */
108
109 if (ret == NULL)
110 {
111 if (size == 0)
112 {
113 llbug (message ("Zero allocation at %q.",
114 fileloc_unparseRaw (cstring_fromChars (name), line)));
115 }
116 else
117 {
118 llfatalerrorLoc
119 (message ("Out of memory. Allocating %w bytes at %s:%d.",
120 size_toLongUnsigned (size),
121 cstring_fromChars (name), line));
122 }
123 }
124
125 /*@-null@*/ /* null okay for size = 0 */
126 return ret;
127 /*@=null@*/
128}
129
130void *dicalloc (size_t num, size_t size, char *name, int line)
131{
132 void *ret = (void *) calloc (num, size);
133
134 if (ret == NULL)
135 {
136 llfatalerrorLoc
137 (message ("Out of memory. Allocating %w bytes at %s:%d.",
138 size_toLongUnsigned (size),
139 cstring_fromChars (name), line));
140 }
141
142 return ret;
143}
144
145void *direalloc (/*@out@*/ /*@null@*/ void *x, size_t size,
146 char *name, int line)
147{
148 void *ret;
149
150 if (x == NULL)
151 {
152 ret = (void *) dmalloc (size);
153 }
154 else
155 {
156 ret = (void *) realloc (x, size);
157 }
158
159 if (ret == NULL)
160 {
161 llfatalerrorLoc
162 (message ("Out of memory. Allocating %w bytes at %s:%d.",
163 size_toLongUnsigned (size),
164 cstring_fromChars (name), line));
165 }
166
167 return ret;
168}
169
170/*@=mustdefine@*/
171
172# ifndef NOLCL
173char *FormatInt (int i)
174{
175 char temp[255]; /* assume the integer has at most 254 digits */
176 char *outs;
177
178 sprintf (temp, "%i", i);
179 outs = (char *) dmalloc (sizeof (*outs) * (1 + strlen (temp)));
180 strcpy (outs, temp);
181
182 return (outs);
183}
184# endif
185
186bool
187isCext (char *ext)
188{
189 return (!mstring_equal (ext, ".lcl") &&
190 !mstring_equal (ext, ".spc") &&
191 !mstring_equal (ext, ".ll"));
192}
193
194bool
195isLCLfile (cstring s)
196{
197 char *ext;
198
199 ext = filenameExtension (cstring_toCharsSafe (s));
200
201 if (ext != NULL)
202 {
203 return (!(isCext (ext)));
204 }
205
206 return (TRUE);
207}
208
209char *removeExtension (/*@temp@*/ char *s, const char *suffix)
210{
211 char *t = strrchr (s, '.');
212 char *s2;
213
214 if (t == (char *) 0 || !mstring_equal (t, suffix))
215 {
216 return mstring_copy (s);
217 }
218
219 /*@-mods@*/
220 *t = '\0';
221 s2 = mstring_copy (s);
222 *t = '.';
223 /*@=mods@*/ /* Modification is undone. */
224 return s2;
225}
226
227# ifndef NOLCL
228bool firstWord (char *s, char *w)
229{
230 llassert (s != NULL);
231 llassert (w != NULL);
232
233 for (; *w != '\0'; w++, s++)
234 {
235 if (*w != *s || *s == '\0')
236 return FALSE;
237 }
238 return TRUE;
239}
240# endif
241
242# ifndef NOLCL
243/*@only@*/ char *removePath (char *s)
244{
245 char *t = strrchr (s, CONNECTCHAR);
246
247 if (t == NULL) return (mstring_copy (s));
248 else return (mstring_copy (t + 1));
249}
250# endif
251
252/*@only@*/ char *
253removePathFree (/*@only@*/ char *s)
254{
255 char *t = strrchr (s, CONNECTCHAR);
256
257# ifdef ALTCONNECTCHAR
258 {
259 char *at = strrchr (s, ALTCONNECTCHAR);
260 if (t == NULL || (at > t)) {
261 t = at;
262 }
263 }
264# endif
265
266 if (t == NULL)
267 {
268 return (s);
269 }
270 else
271 {
272 char *res = mstring_copy (t + 1);
273 mstring_free (s);
274 return res;
275 }
276}
277
278void mstring_markFree (char *s)
279{
280 sfreeEventually (s);
281}
282
283/*@only@*/ char *
284removeAnyExtension (char *s)
285{
286 char *ret;
287 char *t = strrchr (s, '.');
288
289 if (t == (char *) 0)
290 {
291 return mstring_copy (s);
292 }
293
294 /*@-mods@*/
295 *t = '\0';
296 ret = mstring_copy (s);
297 *t = '.';
298 /*@=mods@*/ /* modification is undone */
299
300 return ret;
301}
302
303/*@only@*/ char *
304addExtension (char *s, const char *suffix)
305{
306 if (strrchr (s, '.') == (char *) 0)
307 {
308 /* <<< was mstring_concatFree1 --- bug detected by lclint >>> */
309 return (mstring_concat (s, suffix));
310 }
311 else
312 {
313 return mstring_copy (s);
314 }
315}
316
317int
318getInt (char **s)
319{
320 bool gotOne = FALSE;
321 int i = 0;
322
323 while (**s == ' ')
324 {
325 (*s)++;
326 }
327
328 if (**s == '-')
329 {
330 (*s)++;
331 if (**s < '0' || **s > '9')
332 {
333 llbug (message ("getInt: bad int: %s", cstring_fromChars (*s)));
334 }
335 else
336 {
337 i = -1 * (int) (**s - '0');
338 gotOne = TRUE;
339 }
340
341 (*s)++;
342 }
343
344 while (**s >= '0' && **s <= '9')
345 {
346 i *= 10;
347 i += (int) (**s - '0');
348 (*s)++;
349 gotOne = TRUE;
350 }
351
352 if (!gotOne)
353 {
354 llbug (message ("No int to read: %s", cstring_fromChars (*s)));
355 }
356
357 while (**s == '\n' || **s == ' ' || **s == '\t')
358 {
359 (*s)++;
360 }
361
362 return i;
363}
364
365char
366loadChar (char **s)
367{
368 char ret;
369
370 while (**s == ' ')
371 {
372 (*s)++;
373 }
374
375 ret = **s;
376 (*s)++;
377 return ret;
378}
379
380/*
381** not sure if this works...
382*/
383
384double
385getDouble (char **s)
386{
387 char *end = mstring_createEmpty ();
388 double ret;
389
390 ret = strtod (*s, &end);
391
392 *s = end;
393 return ret;
394}
395
396/*
397** read to ' ', '\t'. '\n', '#', ',' or '\0'
398*/
399
400char *
401getWord (char **s)
402{
403 char *res;
404 char *t = *s;
405 char c;
406
407 while ((c = **s) != '\0' && (c != ' ') && (c != ',')
408 && (c != '\n') && (c != '\t') && (c != '#'))
409 {
410 (*s)++;
411 }
412
413 if (*s == t)
414 {
415 return NULL;
416 }
417
418 **s = '\0';
419 res = mstring_copy (t);
420 **s = c;
421 return res;
422}
423
424bool
425optCheckChar (char **s, char c)
426{
427 if (**s == c)
428 {
429 (*s)++;
430 return TRUE;
431 }
432 else
433 {
434 return FALSE;
435 }
436}
437
438void
439docheckChar (char **s, char c, char *file, int line)
440{
441 /*@unchecked@*/ static int nbadchars = 0;
442
443 if (**s == c)
444 {
445 (*s)++;
446 }
447 else
448 {
449 nbadchars++;
450
451 if (nbadchars > 5)
452 {
453 llfatalbug (cstring_makeLiteral
454 ("checkChar: Too many errors. Check library is up to date."));
455 }
456 else
457 {
458 llbug (message ("checkChar: %q: Bad char, expecting %h: %s",
459 fileloc_unparseRaw (cstring_fromChars (file), line),
460 c,
461 cstring_fromChars (*s)));
462 }
463 }
464}
465
466char *mstring_spaces (int n)
467{
468 int i;
469 char *ret;
470 char *ptr;
471
472 llassert (n >= 0);
473
474 ret = (char *) dmalloc (size_fromInt (n + 1));
475 ptr = ret;
476
477 for (i = 0; i < n; i++)
478 {
479 *ptr++ = ' ';
480 }
481
482 *ptr = '\0';
483
484 return ret;
485}
486
487char *mstring_concat (const char *s1, const char *s2)
488{
489 char *s = (char *) dmalloc (strlen (s1) + strlen (s2) + 1);
490 strcpy (s, s1);
491 strcat (s, s2);
492 return s;
493}
494
495extern /*@only@*/ char *
496mstring_concatFree (/*@only@*/ char *s1, /*@only@*/ char *s2)
497{
498 /* like mstring_concat but deallocates old strings */
499 char *s = (char *) dmalloc (strlen (s1) + strlen (s2) + 1);
500 strcpy (s, s1);
501 strcat (s, s2);
502
503 sfree (s1);
504 sfree (s2);
505 return s;
506}
507
508extern /*@only@*/ char *
509mstring_concatFree1 (/*@only@*/ char *s1, const char *s2)
510{
511 char *s = (char *) dmalloc (strlen (s1) + strlen (s2) + 1);
512 strcpy (s, s1);
513 strcat (s, s2);
514 sfree (s1);
515
516 return s;
517}
518
519extern /*@only@*/ char *
520mstring_append (/*@only@*/ char *s1, char c)
521{
522 size_t l = strlen (s1);
523 char *s;
524
525 s = (char *) dmalloc (sizeof (*s) * (l + 2));
526
527 strcpy (s, s1);
528 *(s + l) = c;
529 *(s + l + 1) = '\0';
530 sfree (s1);
531 return s;
532}
533
534extern
535char *mstring_copy (char *s1)
536{
537 if (s1 == NULL)
538 {
539 return NULL;
540 }
541 else
542 {
543 char *s = (char *) dmalloc ((strlen (s1) + 1) * sizeof (*s));
544 strcpy (s, s1);
545 return s;
546 }
547}
548
549extern
550char *mstring_safePrint (char *s)
551{
552 if (s == NULL)
553 {
554 return ("<undefined>");
555 }
556 else
557 {
558 return s;
559 }
560}
561
562extern
563char *mstring_create (int n)
564{
565 char *s;
566
567 s = dmalloc (sizeof (*s) * (n + 1));
568 *s = '\0';
569 return s;
570}
571
572void
573fputline (FILE *out, char *s)
574{
575 if (strlen (s) > 0)
576 {
577 check (fputs (s, out) != EOF);
578 }
579
580 check (fputc ('\n', out) == (int) '\n');
581}
582
583int int_log (int x)
584{
585 int ret = 1;
586
587 while (x > 10)
588 {
589 ret++;
590 x /= 10;
591 }
592
593 return ret;
594}
595
596/*@-czechfcns@*/
597long unsigned int
598longUnsigned_fromInt (int x)
599{
600 llassert (x >= 0);
601
602 return (long unsigned) x;
603}
604
605size_t size_fromInt (int x)
606{
607 size_t res = (size_t) x;
608
609 llassert ((int) res == x);
610 return res;
611}
612
613int size_toInt (size_t x)
614{
615 int res = (int) x;
616
617 llassert ((size_t) res == x);
618 return res;
619}
620
621long size_toLong (size_t x)
622{
623 long res = (long) x;
624
625 llassert ((size_t) res == x);
626 return res;
627}
628
629/*@=czechfcns@*/
630
631char
632char_fromInt (int x)
633{
634 llassert ((x >= (int)'\0') && (x <= (int)'~'));
635
636 return ((char) x);
637}
638
639/*@-czechfcns@*/
640int
641longUnsigned_toInt (long unsigned int x)
642{
643 int res = (int) x;
644
645 llassert ((long unsigned) res == x);
646 return res;
647}
648
649int
650long_toInt (long int x)
651{
652 int res = (int) x;
653
654 /*@+ignorequals@*/ llassert (res == x); /*@=ignorequals@*/
655 return res;
656}
657
658/*@+czechfcns@*/
659
660bool mstring_equalPrefix (const char *c1, const char *c2)
661{
662 llassert (c1 != NULL);
663 llassert (c2 != NULL);
664
665 if (strncmp(c1, c2, strlen(c2)) == 0)
666 {
667 return TRUE;
668 }
669 else
670 {
671 return FALSE;
672 }
673}
674
675bool mstring_equal (/*@null@*/ const char *s1, /*@null@*/ const char *s2)
676{
677 if (s1 == NULL)
678 {
679 return (s2 == NULL);
680 }
681 else
682 {
683 if (s2 == NULL)
684 {
685 return FALSE;
686 }
687 else
688 {
689 return (strcmp(s1, s2) == 0);
690 }
691 }
692}
693
694/*@observer@*/ char *filenameExtension (/*@returned@*/ char *s)
695{
696 llassert (s != NULL);
697
698 return (strrchr(s, '.'));
699}
700
701char *removePreDirs (char *s)
702{
703 while (*s == '.' && *(s + 1) == CONNECTCHAR)
704 {
705 s += 2;
706 }
707
708# if defined(OS2) || defined(MSDOS)
709 /* remove remainders from double path delimiters... */
710 while (*s == CONNECTCHAR)
711 {
712 ++s;
713 }
714# endif /* !defined(OS2) && !defined(MSDOS) */
715
716 return s;
717}
718
719void checkUngetc (int c, FILE *f)
720{
721 int res;
722
723 llassert (c != EOF);
724 res = ungetc (c, f);
725 llassert (res == c);
726}
727
728bool isHeaderFile (cstring fname)
729{
730 char *ext = filenameExtension (cstring_toCharsSafe (fname));
731
732 return (mstring_equal (ext, ".h")
733 || mstring_equal (ext, ".H")
734 || mstring_equal (ext, ".lh"));
735}
736
This page took 0.197706 seconds and 5 git commands to generate.