2 ** LCLint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2000 University of Virginia,
4 ** Massachusetts Institute of Technology
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.
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.
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.
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
28 # include "lclintMacros.nf"
41 ** redefine undef'd memory ops
54 fprintf (stderr, "Freeing: %ld\n", x);
55 if ((unsigned long) x < 136000000 && (unsigned long) x > 135000000) {
56 fprintf (stderr, "Looks bad!\n");
60 /* fprintf (stderr, "Done.\n"); */
65 void sfreeEventually (void *x)
69 ; /* should keep in a table */
75 ** all memory should be allocated from dimalloc
78 static long unsigned size_toLongUnsigned (size_t x)
80 long unsigned res = (long unsigned) x;
82 llassert ((size_t) res == x);
86 /*@out@*/ void *dimalloc (size_t size, char *name, int line)
89 static void *lastaddr = 0;
90 static int numallocs = 0;
91 static int numbad = 0;
94 /* was malloc, use calloc to initialize to zero */
95 void *ret = (void *) calloc (1, size);
103 fprintf (stderr, "Bad alloc: %d / %d\n", numbad, numallocs);
113 llbug (message ("Zero allocation at %q.",
114 fileloc_unparseRaw (cstring_fromChars (name), line)));
119 (message ("Out of memory. Allocating %w bytes at %s:%d.",
120 size_toLongUnsigned (size),
121 cstring_fromChars (name), line));
125 /*@-null@*/ /* null okay for size = 0 */
130 void *dicalloc (size_t num, size_t size, char *name, int line)
132 void *ret = (void *) calloc (num, size);
137 (message ("Out of memory. Allocating %w bytes at %s:%d.",
138 size_toLongUnsigned (size),
139 cstring_fromChars (name), line));
145 void *direalloc (/*@out@*/ /*@null@*/ void *x, size_t size,
146 char *name, int line)
152 ret = (void *) dmalloc (size);
156 ret = (void *) realloc (x, size);
162 (message ("Out of memory. Allocating %w bytes at %s:%d.",
163 size_toLongUnsigned (size),
164 cstring_fromChars (name), line));
173 char *FormatInt (int i)
175 char temp[255]; /* assume the integer has at most 254 digits */
178 sprintf (temp, "%i", i);
179 outs = (char *) dmalloc (sizeof (*outs) * (1 + strlen (temp)));
189 return (!mstring_equal (ext, ".lcl") &&
190 !mstring_equal (ext, ".spc") &&
191 !mstring_equal (ext, ".ll"));
195 isLCLfile (cstring s)
199 ext = filenameExtension (cstring_toCharsSafe (s));
203 return (!(isCext (ext)));
209 char *removeExtension (/*@temp@*/ char *s, const char *suffix)
211 char *t = strrchr (s, '.');
214 if (t == (char *) 0 || !mstring_equal (t, suffix))
216 return mstring_copy (s);
221 s2 = mstring_copy (s);
223 /*@=mods@*/ /* Modification is undone. */
228 bool firstWord (char *s, char *w)
230 llassert (s != NULL);
231 llassert (w != NULL);
233 for (; *w != '\0'; w++, s++)
235 if (*w != *s || *s == '\0')
243 /*@only@*/ char *removePath (char *s)
245 char *t = strrchr (s, CONNECTCHAR);
247 if (t == NULL) return (mstring_copy (s));
248 else return (mstring_copy (t + 1));
253 removePathFree (/*@only@*/ char *s)
255 char *t = strrchr (s, CONNECTCHAR);
257 # ifdef ALTCONNECTCHAR
259 char *at = strrchr (s, ALTCONNECTCHAR);
260 if (t == NULL || (at > t)) {
272 char *res = mstring_copy (t + 1);
278 void mstring_markFree (char *s)
284 removeAnyExtension (char *s)
287 char *t = strrchr (s, '.');
291 return mstring_copy (s);
296 ret = mstring_copy (s);
298 /*@=mods@*/ /* modification is undone */
304 addExtension (char *s, const char *suffix)
306 if (strrchr (s, '.') == (char *) 0)
308 /* <<< was mstring_concatFree1 --- bug detected by lclint >>> */
309 return (mstring_concat (s, suffix));
313 return mstring_copy (s);
331 if (**s < '0' || **s > '9')
333 llbug (message ("getInt: bad int: %s", cstring_fromChars (*s)));
337 i = -1 * (int) (**s - '0');
344 while (**s >= '0' && **s <= '9')
347 i += (int) (**s - '0');
354 llbug (message ("No int to read: %s", cstring_fromChars (*s)));
357 while (**s == '\n' || **s == ' ' || **s == '\t')
381 ** not sure if this works...
387 char *end = mstring_createEmpty ();
390 ret = strtod (*s, &end);
397 ** read to ' ', '\t'. '\n', '#', ',' or '\0'
407 while ((c = **s) != '\0' && (c != ' ') && (c != ',')
408 && (c != '\n') && (c != '\t') && (c != '#'))
419 res = mstring_copy (t);
425 optCheckChar (char **s, char c)
439 docheckChar (char **s, char c, char *file, int line)
441 /*@unchecked@*/ static int nbadchars = 0;
453 llfatalbug (cstring_makeLiteral
454 ("checkChar: Too many errors. Check library is up to date."));
458 llbug (message ("checkChar: %q: Bad char, expecting %h: %s",
459 fileloc_unparseRaw (cstring_fromChars (file), line),
461 cstring_fromChars (*s)));
466 char *mstring_spaces (int n)
474 ret = (char *) dmalloc (size_fromInt (n + 1));
477 for (i = 0; i < n; i++)
487 char *mstring_concat (const char *s1, const char *s2)
489 char *s = (char *) dmalloc (strlen (s1) + strlen (s2) + 1);
495 extern /*@only@*/ char *
496 mstring_concatFree (/*@only@*/ char *s1, /*@only@*/ char *s2)
498 /* like mstring_concat but deallocates old strings */
499 char *s = (char *) dmalloc (strlen (s1) + strlen (s2) + 1);
508 extern /*@only@*/ char *
509 mstring_concatFree1 (/*@only@*/ char *s1, const char *s2)
511 char *s = (char *) dmalloc (strlen (s1) + strlen (s2) + 1);
519 extern /*@only@*/ char *
520 mstring_append (/*@only@*/ char *s1, char c)
522 size_t l = strlen (s1);
525 s = (char *) dmalloc (sizeof (*s) * (l + 2));
535 char *mstring_copy (char *s1)
543 char *s = (char *) dmalloc ((strlen (s1) + 1) * sizeof (*s));
550 char *mstring_safePrint (char *s)
554 return ("<undefined>");
563 char *mstring_create (int n)
567 s = dmalloc (sizeof (*s) * (n + 1));
573 fputline (FILE *out, char *s)
577 check (fputs (s, out) != EOF);
580 check (fputc ('\n', out) == (int) '\n');
598 longUnsigned_fromInt (int x)
602 return (long unsigned) x;
605 size_t size_fromInt (int x)
607 size_t res = (size_t) x;
609 llassert ((int) res == x);
613 int size_toInt (size_t x)
617 llassert ((size_t) res == x);
621 long size_toLong (size_t x)
625 llassert ((size_t) res == x);
634 llassert ((x >= (int)'\0') && (x <= (int)'~'));
641 longUnsigned_toInt (long unsigned int x)
645 llassert ((long unsigned) res == x);
650 long_toInt (long int x)
654 /*@+ignorequals@*/ llassert (res == x); /*@=ignorequals@*/
660 bool mstring_equalPrefix (const char *c1, const char *c2)
662 llassert (c1 != NULL);
663 llassert (c2 != NULL);
665 if (strncmp(c1, c2, strlen(c2)) == 0)
675 bool mstring_equal (/*@null@*/ const char *s1, /*@null@*/ const char *s2)
689 return (strcmp(s1, s2) == 0);
694 /*@observer@*/ char *filenameExtension (/*@returned@*/ char *s)
696 llassert (s != NULL);
698 return (strrchr(s, '.'));
701 char *removePreDirs (char *s)
703 while (*s == '.' && *(s + 1) == CONNECTCHAR)
708 # if defined(OS2) || defined(MSDOS)
709 /* remove remainders from double path delimiters... */
710 while (*s == CONNECTCHAR)
714 # endif /* !defined(OS2) && !defined(MSDOS) */
719 void checkUngetc (int c, FILE *f)
728 bool isHeaderFile (cstring fname)
730 char *ext = filenameExtension (cstring_toCharsSafe (fname));
732 return (mstring_equal (ext, ".h")
733 || mstring_equal (ext, ".H")
734 || mstring_equal (ext, ".lh"));