/*
** Splint - annotation-assisted static program checker
-** Copyright (C) 1994-2001 University of Virginia,
+** Copyright (C) 1994-2003 University of Virginia,
** Massachusetts Institute of Technology
**
** This program is free software; you can redistribute it and/or modify it
** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
** MA 02111-1307, USA.
**
-** For information on lclint: lclint-request@cs.virginia.edu
-** To report a bug: lclint-bug@cs.virginia.edu
+** For information on splint: info@splint.org
+** To report a bug: splint-bug@splint.org
** For more information: http://www.splint.org
*/
/*
* - Added conditional stuff (#define and #include) for IBM's compiler.
*/
-# include "lclintMacros.nf"
-# include "llbasic.h"
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <fcntl.h>
+# include "splintMacros.nf"
+# include "basic.h"
# include "osd.h"
# include "llmain.h"
# include "portab.h"
+
# if defined(__IBMC__) && defined(OS2)
# include <process.h>
+# include <io.h>
# define getpid _getpid
+# define S_IRUSR S_IREAD
+# define S_IWUSR S_IWRITE
+# define S_IXUSR S_IEXEC
# endif
/*@access fileId*/
+static void
+fileTable_addOpen (fileTable p_ft, /*@observer@*/ FILE *p_f, /*@only@*/ cstring p_fname)
+ /*@modifies p_ft@*/ ;
+
static bool fileTable_inRange (fileTable ft, fileId fid) /*@*/
{
return (fileTable_isDefined (ft) && (fid >= 0) && (fid < ft->nentries));
cstring abspath;
if (ft == NULL) return NOT_FOUND;
abspath = osd_absolutePath (cstring_undefined, s);
+
+ if (context_getFlag (FLG_CASEINSENSITIVEFILENAMES))
+ {
+ abspath = cstring_downcase (abspath);
+ }
+
DPRINTF (("Absolute path: %s: %s", s, abspath));
res = cstringTable_lookup (ft->htable, abspath);
cstring_free (abspath);
return res;
}
+static cstring ftentry_unparse (fileTable ft, ftentry fte)
+{
+ if (fileId_isValid (fte->fder))
+ {
+ llassert (fileTable_isDefined (ft));
+
+ return message ("%s %q %d (%s)",
+ fte->fname,
+ fileType_unparse (fte->ftype),
+ fte->fder,
+ ft->elements[fte->fder]->fname);
+ }
+ else
+ {
+ return message ("%s %q", fte->fname,
+ fileType_unparse (fte->ftype));
+ }
+}
+
/*@only@*/ cstring
fileTable_unparse (fileTable ft)
{
for (i = 0; i < ft->nentries; i++)
{
- if (fileId_isValid (ft->elements[i]->fder))
- {
- s = message ("%s\n[%d] %s %q %d (%s)",
- s, i,
- ft->elements[i]->fname,
- fileType_unparse (ft->elements[i]->ftype),
- ft->elements[i]->fder,
- ft->elements[ft->elements[i]->fder]->fname);
- }
- else
- {
- s = message ("%s\n[%d] %s %q", s, i, ft->elements[i]->fname,
- fileType_unparse (ft->elements[i]->ftype));
- }
- }
+ s = message ("%s\n[%d] %q", s, i, ftentry_unparse (ft, ft->elements[i]));
+ }
return s;
}
}
t->fname = tn;
-
t->basename = cstring_undefined;
t->ftemp = temp;
t->ftype = typ;
ft->nopen = 0;
ft->nopenspace = FTBASESIZE;
ft->openelements = (foentry *) dmalloc (FTBASESIZE * sizeof (*ft->openelements));
-
+
return (ft);
}
+/*@-bounds@*/
static void
fileTable_grow (fileTable ft)
{
sfree (ft->elements);
ft->elements = newent;
}
-
+/*@=bounds@*/
static void
fileTable_growOpen (fileTable ft)
{
ft->nspace--;
DPRINTF (("Adding: %s", e->fname));
- cstringTable_insert (ft->htable, e->fname, ft->nentries);
+
+ if (context_getFlag (FLG_CASEINSENSITIVEFILENAMES))
+ {
+ cstring sd = cstring_downcase (e->fname);
+ cstringTable_insert (ft->htable, sd, ft->nentries);
+ }
+ else
+ {
+ cstringTable_insert (ft->htable, cstring_copy (e->fname), ft->nentries);
+ }
+
+ /* evans 2002-07-12:
+ Before, there was no cstring_copy above, and e->fname was free'd in the if branch.
+ Splint should have caught this, and produced a warning for this assignment.
+ Why not?
+ */
ft->elements[ft->nentries] = e;
ft->nentries++;
{
fileId fid = fileTable_lookup (ft, name);
- if (fileId_isValid (fid)) {
- llassert (fileTable_isDefined (ft));
-
- ft->elements[fid]->ftype = FILE_NODELETE;
- }
+ if (fileId_isValid (fid))
+ {
+ llassert (fileTable_isDefined (ft));
+ ft->elements[fid]->ftype = FILE_NODELETE;
+ }
+ else
+ {
+ DPRINTF (("Invalid no delete: %s", name));
+ }
}
static fileId
{
cstring absname = osd_absolutePath (NULL, name);
int tindex = fileTable_getIndex (ft, absname);
-
+
llassert (ft != fileTable_undefined);
if (tindex != NOT_FOUND)
e->basename = fileLib_removePathFree (fileLib_removeAnyExtension (absname));
e->fsystem = context_isSystemDir (absname);
+
+ /*
+ ** evans 2002-03-15: change suggested by Jim Zelenka
+ ** support relative paths for system directories
+ */
+
+ if (!e->fsystem)
+ {
+ e->fsystem = context_isSystemDir (name);
+ }
+
e->fspecial = context_isSpecialFile (absname);
if (e->fspecial)
}
+void
+fileTable_addStreamFile (fileTable ft, FILE *fstream, cstring name)
+{
+ fileTable_addOpen (ft, fstream, cstring_copy (name));
+}
+
bool
fileTable_isHeader (fileTable ft, fileId fid)
{
return (fileTable_addFilePrim (ft, name, FALSE, FILE_XH, fileId_invalid));
}
-# ifndef NOLCL
fileId
fileTable_addImportFile (fileTable ft, cstring name)
{
{
return (fileTable_addFilePrim (ft, name, FALSE, FILE_HEADER, fileId_invalid));
}
-# endif
-# ifndef NOLCL
static int tmpcounter = 0;
-# endif
fileId
fileTable_addMacrosFile (fileTable ft)
C_EXTENSION);
fileId res;
+ DPRINTF (("tmp dir: %s", context_tmpdir ()));
+ DPRINTF (("new name: %s", newname));
+
llassert (fileTable_isDefined (ft));
if (!fileId_isValid (ft->elements[fid]->fder))
}
}
+ DPRINTF (("Added file: %s", fileTable_fileName (res)));
cstring_free (newname);
return res;
}
-# ifndef NOLCL
fileId
fileTable_addltemp (fileTable ft)
{
cstring_free (newname);
return (ret);
}
-# endif
bool
fileTable_exists (fileTable ft, cstring s)
fileId
fileTable_lookupBase (fileTable ft, cstring base)
{
- int tindex = fileTable_getIndex (ft, base);
+ int tindex;
+
+ if (context_getFlag (FLG_CASEINSENSITIVEFILENAMES))
+ {
+ cstring dbase = cstring_downcase (base);
+ tindex = fileTable_getIndex (ft, dbase);
+ cstring_free (dbase);
+ }
+ else
+ {
+ tindex = fileTable_getIndex (ft, base);
+ }
if (tindex == NOT_FOUND)
{
if (msg)
{
- (void) fflush (g_msgstream);
- fprintf (stderr, "< cleaning");
+ (void) fflush (g_warningstream);
+ displayScanOpen (cstring_makeLiteral ("cleaning"));
}
for (i = 0; i < ft->nentries; i++)
/*
** Make sure it is really a derived file
*/
+
if (fe->ftype == FILE_LSLTEMP || fe->ftype == FILE_NODELETE)
{
if (msg && ((i % skip) == 0))
{
- (void) fflush (g_msgstream);
-
- if (i == 0) {
- fprintf (stderr, " ");
- } else {
- fprintf (stderr, ".");
- }
-
- (void) fflush (stderr);
+ displayScanContinue (cstring_makeLiteral (i == 0 ? " " : "."));
}
}
-
+
if (msg)
{
- fprintf (stderr, " >\n");
+ displayScanClose ();
}
}
cstringTable_free (f->htable);
sfree (f->elements);
+ sfree (f->openelements); /*!! why didn't splint report this? */
sfree (f);
}
static int pid = 0;
static /*@owned@*/ char *msg = NULL;
static /*@only@*/ cstring pidname = NULL;
- int maxlen;
+ size_t maxlen;
cstring smsg;
llassert (cstring_length (pre) <= 3);
maxlen = (cstring_length (dir) + cstring_length (pre) + mstring_length (msg)
+ cstring_length (pidname) + cstring_length (suf) + 2);
+ DPRINTF (("Dir: %s / %s / %s / %s / %s",
+ dir, pre, pidname, msg, suf));
+
smsg = message ("%s%s%s%s%s", dir, pre, pidname, cstring_fromChars (msg), suf);
nextMsg (msg);
+ DPRINTF (("Trying: %s", smsg));
+
while (osd_fileExists (smsg))
{
cstring_free (smsg);
smsg = message ("%s%s%s%s%s", dir, pre, pidname, cstring_fromChars (msg), suf);
nextMsg (msg);
}
-
return smsg;
}
ft->nopen++;
}
-FILE *fileTable_openFile (fileTable ft, cstring fname, char *mode)
+FILE *fileTable_createFile (fileTable ft, cstring fname)
+{
+# ifdef WIN32
+ int fdesc = open (cstring_toCharsSafe (fname), O_WRONLY | O_CREAT | O_TRUNC | O_EXCL); /* not supported by VS.net: , S_IRUSR | S_IWUSR); */
+# else
+ int fdesc = open (cstring_toCharsSafe (fname), O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, S_IRUSR | S_IWUSR);
+# endif
+
+ if (fdesc == -1)
+ {
+ osd_setTempError ();
+ llfatalerror (message ("Temporary file for "
+ "pre-processor output already exists. Trying to "
+ "open: %s.",
+ fname));
+
+ /*@notreached@*/ return NULL;
+ }
+ else
+ {
+ FILE *res = fdopen (fdesc, "w");
+
+ if (res != NULL)
+ {
+ fileTable_addOpen (ft, res, cstring_copy (fname));
+ DPRINTF (("Opening file: %s / %p", fname, res));
+ }
+ else
+ {
+ DPRINTF (("Error opening: %s", fname));
+ }
+
+ return res;
+ }
+}
+
+FILE *fileTable_createMacrosFile (fileTable ft, cstring fname)
+{
+ int fdesc = open (cstring_toCharsSafe (fname), O_RDWR | O_CREAT | O_TRUNC | O_EXCL, S_IRUSR | S_IWUSR);
+
+ if (fdesc == -1)
+ {
+ osd_setTempError ();
+ llfatalerror (message ("Temporary file for "
+ "pre-processor output already exists. Trying to "
+ "open: %s.",
+ fname));
+
+ /*@notreached@*/ return NULL;
+ }
+ else
+ {
+ FILE *res = fdopen (fdesc, "w+");
+
+ if (res != NULL)
+ {
+ fileTable_addOpen (ft, res, cstring_copy (fname));
+ DPRINTF (("Opening file: %s / %p", fname, res));
+ }
+ else
+ {
+ DPRINTF (("Error opening: %s", fname));
+ }
+
+ return res;
+ }
+}
+
+FILE *fileTable_openReadFile (fileTable ft, cstring fname)
+{
+ FILE *res = fopen (cstring_toCharsSafe (fname), "r");
+
+ if (res != NULL)
+ {
+ fileTable_addOpen (ft, res, cstring_copy (fname));
+ DPRINTF (("Opening read file: %s / %p", fname, res));
+ }
+ else
+ {
+ DPRINTF (("Cannot open read file: %s", fname));
+ }
+
+ return res;
+}
+
+/*
+** Allows overwriting
+*/
+
+FILE *fileTable_openWriteFile (fileTable ft, cstring fname)
{
- FILE *res = fopen (cstring_toCharsSafe (fname), mode);
+ FILE *res = fopen (cstring_toCharsSafe (fname), "w");
+
+ if (res != NULL) {
+ fileTable_addOpen (ft, res, cstring_copy (fname));
+ DPRINTF (("Opening file: %s / %p", fname, res));
+ }
+
+ return res;
+}
+
+FILE *fileTable_openWriteUpdateFile (fileTable ft, cstring fname)
+{
+ FILE *res = fopen (cstring_toCharsSafe (fname), "w+");
if (res != NULL) {
fileTable_addOpen (ft, res, cstring_copy (fname));
if (ft->openelements[i]->f == f)
{
DPRINTF (("Closing file: %p = %s", f, ft->openelements[i]->fname));
-
+
if (i == ft->nopen - 1)
{
foentry_free (ft->openelements[i]);
{
int i = 0;
+ llassert (fileTable_isDefined (ft));
+
for (i = 0; i < ft->nopen; i++)
{
/*
lldiagmsg (message ("Unclosed file at exit: %s", ft->openelements[i]->fname));
*/
+
+ if (ft->openelements[i]->f != NULL)
+ {
+ (void) fclose (ft->openelements[i]->f); /* No check - cleaning up after errors */
+ }
- (void) fclose (ft->openelements[i]->f); /* No check - cleaning up after errors */
ft->openelements[i]->f = NULL;
foentry_free (ft->openelements[i]);
ft->openelements[i] = NULL;