/*
-** LCLint - annotation-assisted static program checker
-** Copyright (C) 1994-2000 University of Virginia,
+** Splint - annotation-assisted static program checker
+** Copyright (C) 1994-2002 University of Virginia,
** Massachusetts Institute of Technology
**
** This program is free software; you can redistribute it and/or modify it
**
** For information on lclint: lclint-request@cs.virginia.edu
** To report a bug: lclint-bug@cs.virginia.edu
-** For more information: http://lclint.cs.virginia.edu
+** For more information: http://www.splint.org
*/
/*
** llmain.c
**
-** Main module for LCLint checker
+** Main module for Splint annotation-assisted program checker
*/
# include <signal.h>
-
+# include <time.h>
/*
** Ensure that WIN32 and _WIN32 are both defined or both undefined.
*/
# endif
# include "version.h"
-# include "herald.h"
# include "fileIdList.h"
# include "lcllib.h"
# include "cgrammar.h"
# include "llmain.h"
# include "portab.h"
-# include "cpp.h"
-# include <time.h>
+
extern /*@external@*/ int yydebug;
static void cleanupFiles (void);
static void showHelp (void);
static void interrupt (int p_i);
-static void loadrc (FILE *p_rcfile, cstringSList *p_passThroughArgs);
+
+static bool readOptionsFile (cstring p_fname,
+ cstringSList *p_passThroughArgs,
+ bool p_report)
+ /*@modifies fileSystem, internalState, *p_passThroughArgs@*/ ;
+
+static void loadrc (FILE *p_rcfile, cstringSList *p_passThroughArgs)
+ /*@modifies *p_passThroughArgs, p_rcfile@*/
+ /*@ensures closed p_rcfile@*/ ;
+
static void describeVars (void);
static bool specialFlagsHelp (char *p_next);
static bool hasShownHerald = FALSE;
+static char *specFullName (char *p_specfile, /*@out@*/ char **p_inpath)
+ /*@modifies *p_inpath@*/ ;
static bool anylcl = FALSE;
static clock_t inittime;
-static /*@only@*/ /*@null@*/ tsource *initFile = (tsource *) 0;
+static /*@only@*/ /*@null@*/ inputStream initFile = inputStream_undefined;
-static fileIdList preprocessFiles (fileIdList)
+static fileIdList preprocessFiles (fileIdList, bool)
/*@modifies fileSystem@*/ ;
# ifndef NOLCL
*/
cstring larchpath = context_getLarchPath ();
- tsource *LSLinitFile = (tsource *) 0;
+ inputStream LSLinitFile = inputStream_undefined;
setCodePoint ();
- if (initFile == (tsource *) 0)
+ if (inputStream_isUndefined (initFile))
{
- initFile = tsource_create (INITFILENAME, LCLINIT_SUFFIX, FALSE);
+ initFile = inputStream_create (cstring_makeLiteral (INITFILENAME),
+ cstring_makeLiteralTemp (LCLINIT_SUFFIX),
+ FALSE);
- if (!tsource_getPath (cstring_toCharsSafe (larchpath), initFile))
+ if (!inputStream_getPath (larchpath, initFile))
{
lldiagmsg (message ("Continuing without LCL init file: %s",
- cstring_fromChars (tsource_fileName (initFile))));
+ inputStream_fileName (initFile)));
}
else
{
- if (!tsource_open (initFile))
+ if (!inputStream_open (initFile))
{
lldiagmsg (message ("Continuing without LCL init file: %s",
- cstring_fromChars (tsource_fileName (initFile))));
+ inputStream_fileName (initFile)));
}
}
}
else
{
- if (!tsource_open (initFile))
+ if (!inputStream_open (initFile))
{
lldiagmsg (message ("Continuing without LCL init file: %s",
- cstring_fromChars (tsource_fileName (initFile))));
+ inputStream_fileName (initFile)));
}
}
setCodePoint ();
/* need this to initialize LCL checker */
- llassert (initFile != NULL);
-
- if (tsource_isOpen (initFile))
+
+ llassert (inputStream_isDefined (initFile));
+ if (inputStream_isOpen (initFile))
{
setCodePoint ();
LCLProcessInitFileCleanup ();
setCodePoint ();
- check (tsource_close (initFile));
+ check (inputStream_close (initFile));
}
/* Initialize LSL init files, for parsing LSL signatures from LSL */
- LSLinitFile = tsource_create ("lslinit.lsi", ".lsi", FALSE);
+ LSLinitFile = inputStream_create (cstring_makeLiteral ("lslinit.lsi"),
+ cstring_makeLiteralTemp (".lsi"),
+ FALSE);
- if (!tsource_getPath (cstring_toCharsSafe (larchpath), LSLinitFile))
+ if (!inputStream_getPath (larchpath, LSLinitFile))
{
lldiagmsg (message ("Continuing without LSL init file: %s",
- cstring_fromChars (tsource_fileName (LSLinitFile))));
+ inputStream_fileName (LSLinitFile)));
}
else
{
- if (!tsource_open (LSLinitFile))
+ if (!inputStream_open (LSLinitFile))
{
lldiagmsg (message ("Continuing without LSL init file: %s",
- cstring_fromChars (tsource_fileName (LSLinitFile))));
+ inputStream_fileName (LSLinitFile)));
}
}
lscanLineReset ();
LSLScanInit ();
- if (tsource_isOpen (LSLinitFile))
+ if (inputStream_isOpen (LSLinitFile))
{
setCodePoint ();
LSLScanReset (LSLinitFile);
setCodePoint ();
LSLProcessInitFile ();
setCodePoint ();
- check (tsource_close (LSLinitFile));
+ check (inputStream_close (LSLinitFile));
}
- tsource_free (LSLinitFile);
+ inputStream_free (LSLinitFile);
if (lclHadError ())
{
fileIdList_elements (lclfiles, fid)
{
- char *actualName = (char *) dmalloc (sizeof (*actualName));
- char *oactualName = actualName;
- char *fname = cstring_toCharsSafe (fileName (fid));
+ cstring actualName = cstring_undefined;
+ cstring fname = fileName (fid);
- if (osd_getPath (g_localSpecPath, fname, &actualName) == OSD_FILENOTFOUND)
+ if (osd_getPath (cstring_fromChars (g_localSpecPath),
+ fname, &actualName) == OSD_FILENOTFOUND)
{
if (mstring_equal (g_localSpecPath, "."))
{
- lldiagmsg (message ("Spec file not found: %s",
- cstring_fromChars (fname)));
+ lldiagmsg (message ("Spec file not found: %q", osd_outputPath (fname)));
}
else
{
- lldiagmsg (message ("Spec file not found: %s (on %s)",
- cstring_fromChars (fname),
+ lldiagmsg (message ("Spec file not found: %q (on %s)",
+ osd_outputPath (fname),
cstring_fromChars (g_localSpecPath)));
}
}
else
{
- tsource *specFile;
-
- while (*actualName == '.' && *(actualName + 1) == CONNECTCHAR)
+ inputStream specFile;
+ /*@access cstring@*/
+ char *namePtr = actualName;
+
+ while (*namePtr == '.' && *(namePtr + 1) == CONNECTCHAR)
{
- actualName += 2;
+ namePtr += 2;
}
+ /*@noaccess cstring@*/
+
+ g_currentSpec = cstring_fromCharsNew (namePtr);
+
+ specFile = inputStream_create (cstring_copy (g_currentSpec),
+ LCL_EXTENSION, TRUE);
- specFile = tsource_create (actualName, LCL_SUFFIX, TRUE);
- llassert (specFile != (tsource *) 0);
+ llassert (inputStream_isDefined (specFile));
- g_currentSpec = cstring_fromChars (mstring_copy (actualName));
-
g_currentSpecName = specFullName
(cstring_toCharsSafe (g_currentSpec),
&path);
/* Open source file */
- if (!tsource_open (specFile))
+ if (!inputStream_open (specFile))
{
- lldiagmsg (message ("Cannot open file: %s",
- cstring_fromChars (tsource_fileName (specFile))));
- tsource_free (specFile);
+ lldiagmsg (message ("Cannot open file: %q",
+ osd_outputPath (inputStream_fileName (specFile))));
+ inputStream_free (specFile);
}
else
{
{
if (overallStatus)
{
- outputLCSFile (path, "%%FAILED Output from ",
+ outputLCSFile (path, "%FAILED Output from ",
g_currentSpecName);
}
else
{
- outputLCSFile (path, "%%PASSED Output from ",
+ outputLCSFile (path, "%PASSED Output from ",
g_currentSpecName);
}
}
- (void) tsource_close (specFile);
- tsource_free (specFile);
+ (void) inputStream_close (specFile);
+ inputStream_free (specFile);
symtable_exitScope (g_symtab);
- }
+ }
}
-
- sfree (oactualName);
+ cstring_free (actualName);
} end_fileIdList_elements;
-
+
/* Can cleanup lsl stuff right away */
-
- lslCleanup ();
-
- g_currentSpec = cstring_undefined;
- g_currentSpecName = NULL;
+
+ lslCleanup ();
+
+ g_currentSpec = cstring_undefined;
+ g_currentSpecName = NULL;
}
# endif
char *quotechar = strchr (curarg, '\"');
int offset = 0;
bool open = FALSE;
+ char *freearg = NULL;
while (quotechar != NULL)
{
}
}
+ llassert (quotechar != NULL);
*quotechar = '\0';
offset = (quotechar - arg) + 2;
(message ("%s\"\'%s",
cstring_fromChars (arg),
cstring_fromChars (quotechar + 1)));
+ freearg = arg;
open = FALSE;
}
else
(message ("%s\'\"%s",
cstring_fromChars (arg),
cstring_fromChars (quotechar + 1)));
+ freearg = arg;
open = TRUE;
}
if (open)
{
showHerald ();
- llerror (FLG_BADFLAG,
- message ("Unclosed quote in flag: %s",
- cstring_fromChars (arg)));
+ voptgenerror (FLG_BADFLAG,
+ message ("Unclosed quote in flag: %s",
+ cstring_fromChars (arg)),
+ g_currentloc);
}
else
{
** them. This is an artifact of UNIX command line?
*/
- def = osd_fixDefine (arg + 1);
+ def = osd_fixDefine (cstring_fromChars (arg + 1));
DPRINTF (("Do define: %s", def));
cppDoDefine (def);
DPRINTF (("After define"));
BADBRANCH;
}
}
+
+ sfree (freearg);
}
void showHerald (void)
else
{
- fprintf (g_msgstream, "%s\n\n", LCL_VERSION);
+ fprintf (g_msgstream, "%s\n\n", SPLINT_VERSION);
hasShownHerald = TRUE;
llflush ();
}
}
+static cstring findLarchPathFile (/*@temp@*/ cstring s)
+{
+ cstring pathName;
+ filestatus status;
+
+ status = osd_getPath (context_getLarchPath (), s, &pathName);
+
+ if (status == OSD_FILEFOUND)
+ {
+ return pathName;
+ }
+ else if (status == OSD_FILENOTFOUND)
+ {
+ showHerald ();
+ lldiagmsg (message ("Cannot find file on LARCHPATH: %s", s));
+ }
+ else if (status == OSD_PATHTOOLONG)
+ {
+ /* Directory and filename are too long. Report error. */
+ llbuglit ("soure_getPath: Filename plus directory from search path too long");
+ }
+ else
+ {
+ BADBRANCH;
+ }
+
+ return cstring_undefined;
+}
+
+static void addLarchPathFile (fileIdList files, /*@temp@*/ cstring s)
+{
+ cstring pathName = findLarchPathFile (s);
+
+ if (cstring_isDefined (pathName))
+ {
+ if (fileTable_exists (context_fileTable (), pathName))
+ {
+ showHerald ();
+ lldiagmsg (message ("File listed multiple times: %s", pathName));
+ cstring_free (pathName);
+ }
+ else
+ {
+ fileIdList_add (files, fileTable_addFileOnly (context_fileTable (), pathName));
+ }
+ }
+}
+
static void addFile (fileIdList files, /*@only@*/ cstring s)
{
if (fileTable_exists (context_fileTable (), s))
}
}
+static void addXHFile (fileIdList files, /*@temp@*/ cstring s)
+{
+ cstring pathName = findLarchPathFile (s);
+
+ if (cstring_isDefined (pathName))
+ {
+ if (fileTable_exists (context_fileTable (), pathName))
+ {
+ showHerald ();
+ lldiagmsg (message ("File listed multiple times: %s", s));
+ }
+ else
+ {
+ fileIdList_add (files, fileTable_addXHFile (context_fileTable (), pathName));
+ }
+ }
+
+ cstring_free (pathName);
+}
+
/*
** Disable MSVC++ warning about return value. Methinks humbly lclint control
** comments are a mite more legible.
bool first_time = TRUE;
bool showhelp = FALSE;
bool allhelp = TRUE;
- tsource *sourceFile = (tsource *) 0;
+ bool expsuccess;
+ inputStream sourceFile = inputStream_undefined;
fileIdList dercfiles;
cstringSList fl = cstringSList_undefined;
cstringSList passThroughArgs = cstringSList_undefined;
- fileIdList cfiles;
- fileIdList lclfiles;
+ fileIdList cfiles, xfiles, lclfiles, mtfiles;
clock_t before, lcltime, libtime, pptime, cptime, rstime;
int i = 0;
+# ifdef __EMX__
+ _wildcard (&argc, &argv);
+# endif
+
g_msgstream = stdout;
(void) signal (SIGINT, interrupt);
(void) signal (SIGSEGV, interrupt);
cfiles = fileIdList_create ();
+ xfiles = fileIdList_create ();
lclfiles = fileIdList_create ();
+ mtfiles = fileIdList_create ();
flags_initMod ();
+ clabstract_initMod ();
typeIdSet_initMod ();
cppReader_initMod ();
+ osd_initMod ();
setCodePoint ();
-
+
g_currentloc = fileloc_createBuiltin ();
-
+
before = clock ();
context_initMod ();
+
context_setInCommandLine ();
if (argc <= 1)
*/
{
- char *incval = mstring_copy (osd_getEnvironmentVariable (INCLUDE_VAR));
+ cstring incval = cstring_copy (osd_getEnvironmentVariable (INCLUDEPATH_VAR));
+ cstring oincval = incval;
- if (incval != NULL)
+ if (cstring_isDefined (incval))
{
/*
** Each directory on the include path is a system include directory.
*/
DPRINTF (("include: %s", incval));
- context_setString (FLG_SYSTEMDIRS, cstring_fromCharsNew (incval));
+ context_setString (FLG_SYSTEMDIRS, cstring_copy (incval));
- while (incval != NULL)
+ while (cstring_isDefined (incval))
{
- char *nextsep = strchr (incval, SEPCHAR);
+ /*@access cstring@*/
+ char *nextsep = strchr (incval, PATH_SEPARATOR);
if (nextsep != NULL)
{
cstring dir;
*nextsep = '\0';
- dir = cstring_fromCharsNew (incval);
+ dir = cstring_copy (incval);
if (cstring_length (dir) == 0
|| !isalpha ((int) cstring_firstChar (dir)))
}
else
{
- DPRINTF (("Add include: %s", dir));
cppAddIncludeDir (dir);
}
- *nextsep = SEPCHAR;
- incval = nextsep + 1;
+ *nextsep = PATH_SEPARATOR;
+ incval = cstring_fromChars (nextsep + 1);
cstring_free (dir);
}
else
{
break;
}
+
+ /*@noaccess cstring@*/
+ }
+ }
+ else /* 2001-09-09: herbert */
+ {
+ /* Put C_INCLUDE_PATH directories in sysdirs */
+ cstring cincval = osd_getEnvironmentVariable (cstring_makeLiteralTemp ("C_INCLUDE_PATH"));
+ if (cstring_isDefined (cincval))
+ {
+ context_setString (FLG_SYSTEMDIRS, cstring_copy (cincval));
}
}
+ /* /herbert */
+
+ cstring_free (oincval);
}
/*
*/
{
- cstring home = cstring_fromChars (osd_getHomeDir ());
- char *fname = NULL;
- FILE *rcfile;
+ cstring home = osd_getHomeDir ();
+ cstring fname = cstring_undefined;
bool defaultf = TRUE;
bool nof = FALSE;
if (*thisarg == '-' || *thisarg == '+')
{
+ bool set = (*thisarg == '+');
+ flagcode opt;
+
thisarg++;
+ opt = identifyFlag (cstring_fromChars (thisarg));
- if (mstring_equal (thisarg, "nof"))
+ if (opt == FLG_NOF)
{
nof = TRUE;
}
- else if (mstring_equal (thisarg, "f"))
+ else if (opt == FLG_SHOWSCAN || opt == FLG_WARNRC)
+ {
+ /*
+ ** Need to set it immediately, so rc file scan is displayed
+ */
+
+ context_userSetFlag (opt, set);
+ }
+ else if (opt == FLG_OPTF)
{
if (++i < argc)
{
defaultf = FALSE;
- fname = argv[i];
- rcfile = fopen (fname, "r");
-
- if (rcfile != NULL)
- {
- fileloc oloc = g_currentloc;
-
- g_currentloc = fileloc_createRc (cstring_fromChars (fname));
- loadrc (rcfile, &passThroughArgs);
- fileloc_reallyFree (g_currentloc);
- g_currentloc = oloc;
- }
- else
- {
- showHerald ();
- lldiagmsg (message ("Options file not found: %s",
- cstring_fromChars (fname)));
- }
+ fname = cstring_fromChars (argv[i]);
+ (void) readOptionsFile (fname, &passThroughArgs, TRUE);
}
else
llfatalerror
}
}
}
-
- if (fname == NULL)
- {
- if (!cstring_isEmpty (home)) {
- fname = cstring_toCharsSafe (message ("%s%h%s", home, CONNECTCHAR,
- cstring_fromChars (RCFILE)));
- mstring_markFree (fname);
- }
- }
-
+
setCodePoint ();
if (!nof && defaultf)
{
- if (!mstring_isEmpty (fname)) {
- rcfile = fopen (fname, "r");
-
- if (rcfile != NULL)
- {
- fileloc oloc = g_currentloc;
-
- g_currentloc = fileloc_createRc (cstring_fromChars (fname));
- loadrc (rcfile, &passThroughArgs);
- fileloc_reallyFree (g_currentloc);
- g_currentloc = oloc;
- }
- }
-
-# if defined(MSDOS) || defined(OS2)
- fname = cstring_toCharsSafe (message ("%s",
- cstring_fromChars (RCFILE)));
-# else
- fname = cstring_toCharsSafe (message ("./%s",
- cstring_fromChars (RCFILE)));
-# endif
-
- rcfile = fopen (fname, "r");
+ /*
+ ** No explicit rc file, first try reading ~/.splintrc
+ */
- if (rcfile != NULL)
+ if (cstring_isUndefined (fname))
{
- fileloc oloc = g_currentloc;
+ if (!cstring_isEmpty (home))
+ {
+ bool readhomerc, readaltrc;
+ cstring homename, altname;
+
+ homename = message ("%s%h%s", home, CONNECTCHAR,
+ cstring_fromChars (RCFILE));
+ readhomerc = readOptionsFile (homename, &passThroughArgs, FALSE);
+
+ /*
+ ** Try ~/.lclintrc also for historical accuracy
+ */
+
+ altname = message ("%s%h%s", home, CONNECTCHAR,
+ cstring_fromChars (ALTRCFILE));
+ readaltrc = readOptionsFile (altname, &passThroughArgs, FALSE);
+
+ if (readhomerc && readaltrc)
+ {
- g_currentloc = fileloc_createRc (cstring_fromChars (fname));
- loadrc (rcfile, &passThroughArgs);
- fileloc_reallyFree (g_currentloc);
- g_currentloc = oloc;
+ voptgenerror
+ (FLG_WARNRC,
+ message ("Found both %s and %s files. Using both files, "
+ "but recommend using only %s to avoid confusion.",
+ homename, altname, homename),
+ g_currentloc);
+ }
+
+ cstring_free (homename);
+ cstring_free (altname);
+ }
}
+
+ /*
+ ** Next, read .splintrc in the current working directory
+ */
+
+ {
+ cstring rcname = message ("%s%s",osd_getCurrentDirectory (), cstring_fromChars (RCFILE));
+ cstring altname = message ("%s%s",osd_getCurrentDirectory (), cstring_fromChars (ALTRCFILE));
+ bool readrc, readaltrc;
+
+ readrc = readOptionsFile (rcname, &passThroughArgs, FALSE);
+ readaltrc = readOptionsFile (altname, &passThroughArgs, FALSE);
+
+ if (readrc && readaltrc)
+ {
+ voptgenerror (FLG_WARNRC,
+ message ("Found both %s and %s files. Using both files, "
+ "but recommend using only %s to avoid confusion.",
+ rcname, altname, rcname),
+ g_currentloc);
+
+ }
- sfree (fname);
+ cstring_free (rcname);
+ cstring_free (altname);
+ }
}
}
thisarg++; /* skip '-' */
flagname = cstring_fromChars (thisarg);
-
+
+ DPRINTF (("Flag: %s", flagname));
opt = identifyFlag (flagname);
-
- if (flagcode_isSkip (opt))
+ DPRINTF (("Flag: %s", flagcode_unparse (opt)));
+
+ if (flagcode_isSkip (opt) || opt == FLG_SHOWSCAN || opt == FLG_WARNRC)
{
- ;
+ /* showscan already processed */
+ DPRINTF (("Skipping!"));
}
else if (flagcode_isInvalid (opt))
{
+ DPRINTF (("Invalid: %s", flagname));
+
if (isMode (flagname))
{
context_setMode (flagname);
}
else
{
- llgloberror (message ("Unrecognized option: %s",
- cstring_fromChars (thisarg)));
+ DPRINTF (("Error!"));
+ voptgenerror (FLG_BADFLAG,
+ message ("Unrecognized option: %s",
+ cstring_fromChars (thisarg)),
+ g_currentloc);
}
}
else
g_localSpecPath = cstring_toCharsSafe
(message ("%s%h%s",
cstring_fromChars (g_localSpecPath),
- SEPCHAR,
+ PATH_SEPARATOR,
dir));
/*@=mustfree@*/
/*@switchbreak@*/ break;
else if (opt == FLG_INIT)
{
# ifndef NOLCL
- initFile = tsource_create
- (cstring_toCharsSafe (arg),
- LCLINIT_SUFFIX, FALSE);
+ initFile = inputStream_create
+ (arg,
+ cstring_makeLiteralTemp (LCLINIT_SUFFIX),
+ FALSE);
# endif
break;
}
else
{
- setStringFlag (opt, arg);
+ DPRINTF (("String flag: %s / %s",
+ flagcode_unparse (opt), arg));
+ if (opt == FLG_MTSFILE)
+ {
+ /*
+ ** arg identifies mts files
+ */
+ cstring tmp = message ("%s%s", arg, MTS_EXTENSION);
+ addLarchPathFile (mtfiles, tmp);
+ cstring_free (tmp);
+ tmp = message ("%s%s", arg, XH_EXTENSION);
+ addXHFile (xfiles, tmp);
+ cstring_free (tmp);
+ }
+ else
+ {
+ setStringFlag (opt, arg);
+ }
}
}
else
}
else /* its a filename */
{
+ DPRINTF (("Adding filename: %s", thisarg));
fl = cstringSList_add (fl, cstring_fromChars (thisarg));
}
}
}
setCodePoint ();
-
+ showHerald ();
+
/*
** create lists of C and LCL files
*/
cstringSList_elements (fl, current)
{
- char *fname = cstring_toCharsSafe (current);
- char *ext = strrchr (fname, '.');
-
- if (ext == NULL)
+ cstring ext = fileLib_getExtension (current);
+
+ if (cstring_isUndefined (ext))
{
/* no extension --- both C and LCL with default extensions */
- addFile (cfiles, message ("%s.c", cstring_fromChars (fname)));
- addFile (lclfiles, message ("%s.lcl", cstring_fromChars (fname)));
+ addFile (cfiles, message ("%s%s", current, C_EXTENSION));
+ addFile (lclfiles, message ("%s%s", current, LCL_EXTENSION));
}
- else if (isCext (ext))
+ else if (cstring_equal (ext, XH_EXTENSION))
{
- addFile (cfiles, cstring_fromCharsNew (fname));
+ addXHFile (xfiles, current);
}
- else
+ else if (cstring_equal (ext, PP_EXTENSION))
{
- if (!mstring_equal (ext, ".lcl"))
+ if (!context_getFlag (FLG_NOPP))
{
- lldiagmsg (message ("Unrecognized file extension: %s (assuming lcl)",
- cstring_fromChars (ext)));
+ voptgenerror
+ (FLG_FILEEXTENSIONS,
+ message ("File extension %s used without +nopp flag (will be processed as C source code): %s",
+ ext, current),
+ g_currentloc);
}
-
- addFile (lclfiles, cstring_fromCharsNew (fname));
+
+ addFile (cfiles, cstring_copy (current));
+ }
+ else if (cstring_equal (ext, LCL_EXTENSION))
+ {
+ addFile (lclfiles, cstring_copy (current));
+ }
+ else if (fileLib_isCExtension (ext))
+ {
+ addFile (cfiles, cstring_copy (current));
+ }
+ else if (cstring_equal (ext, MTS_EXTENSION))
+ {
+ addLarchPathFile (mtfiles, current);
+ }
+ else
+ {
+ voptgenerror
+ (FLG_FILEEXTENSIONS,
+ message ("Unrecognized file extension: %s (assuming %s is C source code)",
+ current, ext),
+ g_currentloc);
+
+ addFile (cfiles, cstring_copy (current));
}
} end_cstringSList_elements;
-
- showHerald ();
-
-
if (showhelp)
{
if (allhelp)
fprintf (g_msgstream, "\n");
fileIdList_free (cfiles);
+ fileIdList_free (xfiles);
fileIdList_free (lclfiles);
llexit (LLSUCCESS);
fileloc_free (g_currentloc);
g_currentloc = fileloc_createBuiltin ();
+ /*
+ ** Read metastate files (must happen before loading libraries)
+ */
+
+ fileIdList_elements (mtfiles, mtfile)
+ {
+ context_setFileId (mtfile);
+
+ if (context_getFlag (FLG_SHOWSCAN))
+ {
+ lldiagmsg (message ("< processing %s >", rootFileName (mtfile)));
+ }
+
+ mtreader_readFile (cstring_copy (fileName (mtfile)));
+ } end_fileIdList_elements;
+
libtime = clock ();
-
+
if (anylcl)
{
# ifdef NOLCL
- llfatalerror (cstring_makeLiteral ("This version of LCLint does not handle LCL files."));
+ llfatalerror (cstring_makeLiteral ("This version of Splint does not handle LCL files."));
# else
lslProcess (lclfiles);
# endif
}
+ usymtab_initGlobalMarker ();
+
/*
** pre-processing
**
context_setInCommandLine ();
- cppReader_initialize ();
-
DPRINTF (("Pass through: %s", cstringSList_unparse (passThroughArgs)));
cstringSList_elements (passThroughArgs, thisarg) {
cleanupMessages ();
+ DPRINTF (("Initializing cpp reader!"));
+ cppReader_initialize ();
cppReader_saveDefinitions ();
context_clearInCommandLine ();
if (!context_getFlag (FLG_NOPP))
{
+ fileIdList tfiles;
+
llflush ();
if (context_getFlag (FLG_SHOWSCAN))
lcltime = clock ();
context_setPreprocessing ();
- dercfiles = preprocessFiles (cfiles);
+ dercfiles = preprocessFiles (xfiles, TRUE);
+ tfiles = preprocessFiles (cfiles, FALSE);
+ dercfiles = fileIdList_append (dercfiles, tfiles);
+ fileIdList_free (tfiles);
+
context_clearPreprocessing ();
fileIdList_free (cfiles);
else
{
lcltime = clock ();
- dercfiles = cfiles;
+ dercfiles = fileIdList_append (cfiles, xfiles);
pptime = clock ();
}
-
+
/*
** now, check all the corresponding C files
**
# endif
}
+ DPRINTF (("Initializing..."));
+
exprNode_initMod ();
+ DPRINTF (("Okay..."));
+
fileIdList_elements (dercfiles, fid)
{
- sourceFile = tsource_create (cstring_toCharsSafe (fileName (fid)),
- C_SUFFIX, TRUE);
+ sourceFile = inputStream_create (cstring_copy (fileName (fid)), C_EXTENSION, TRUE);
context_setFileId (fid);
/* Open source file */
- if (sourceFile == (tsource *) 0 || (!tsource_open (sourceFile)))
+ if (inputStream_isUndefined (sourceFile) || (!inputStream_open (sourceFile)))
{
/* previously, this was ignored ?! */
llbug (message ("Could not open temp file: %s", fileName (fid)));
}
else
{
- yyin = sourceFile->file; /*< shared <- only */
+ yyin = inputStream_getFile (sourceFile); /*< shared <- only */
llassert (yyin != NULL);
if (context_getFlag (FLG_SHOWSCAN))
{
- lldiagmsg (message ("< checking %s >", rootFileName (fid)));
+ lldiagmsg (message ("< checking %q >", osd_outputPath (rootFileName (fid))));
}
/*
first_time = FALSE;
}
+ DPRINTF (("Entering..."));
context_enterFile ();
(void) yyparse ();
- context_exitFile ();
+ context_exitCFile ();
- (void) tsource_close (sourceFile);
- }
-
+ (void) inputStream_close (sourceFile);
+ }
} end_fileIdList_elements;
cptime = clock ();
summarizeErrors ();
}
- if (!context_getFlag (FLG_QUIET))
- {
- cstring specErrors = cstring_undefined;
+
+ {
+ bool isQuiet = context_getFlag (FLG_QUIET);
+ cstring specErrors = cstring_undefined;
# ifndef NOLCL
- int nspecErrors = lclNumberErrors ();
+ int nspecErrors = lclNumberErrors ();
# endif
+
+ expsuccess = TRUE;
- if (context_neednl ())
- fprintf (g_msgstream, "\n");
+ if (context_neednl ())
+ fprintf (g_msgstream, "\n");
# ifndef NOLCL
- if (nspecErrors > 0)
- {
- if (nspecErrors == context_getLCLExpect ())
- {
- specErrors =
- message ("%d spec error%p found, as expected\n ",
- nspecErrors);
- }
- else
- {
- if (context_getLCLExpect () > 0)
- {
- specErrors =
- message ("%d spec error%p found, expected %d\n ",
- nspecErrors,
- (int) context_getLCLExpect ());
- }
- else
- {
- specErrors = message ("%d spec error%p found\n ",
- nspecErrors);
- }
- }
- }
- else
+ if (nspecErrors > 0)
+ {
+ if (nspecErrors == context_getLCLExpect ())
+ {
+ specErrors =
+ message ("%d spec warning%&, as expected\n ",
+ nspecErrors);
+ }
+ else
+ {
+ if (context_getLCLExpect () > 0)
+ {
+ specErrors =
+ message ("%d spec warning%&, expected %d\n ",
+ nspecErrors,
+ (int) context_getLCLExpect ());
+ }
+ else
+ {
+ specErrors = message ("%d spec warning%& found\n ",
+ nspecErrors);
+ expsuccess = FALSE;
+ }
+ }
+ }
+ else
{
if (context_getLCLExpect () > 0)
{
- specErrors = message ("No spec errors found, expected %d\n ",
+ specErrors = message ("No spec warnings, expected %d\n ",
(int) context_getLCLExpect ());
+ expsuccess = FALSE;
}
}
# endif
{
if (context_numErrors () == context_getExpect ())
{
- llmsg (message ("Finished LCLint checking --- "
- "%s%d code error%p found, as expected",
- specErrors, context_numErrors ()));
+ if (!isQuiet) {
+ llmsg (message ("Finished checking --- "
+ "%s%d code warning%&, as expected",
+ specErrors, context_numErrors ()));
+ }
}
else
{
if (context_getExpect () > 0)
{
- llmsg (message
- ("Finished LCLint checking --- "
- "%s%d code error%p found, expected %d",
- specErrors, context_numErrors (),
- (int) context_getExpect ()));
+ if (!isQuiet) {
+ llmsg (message
+ ("Finished checking --- "
+ "%s%d code warning%&, expected %d",
+ specErrors, context_numErrors (),
+ (int) context_getExpect ()));
+ }
+
+ expsuccess = FALSE;
}
else
{
- llmsg (message ("Finished LCLint checking --- "
- "%s%d code error%p found",
- specErrors, context_numErrors ()));
+
+ if (!isQuiet)
+ {
+ llmsg (message ("Finished checking --- "
+ "%s%d code warning%& found",
+ specErrors, context_numErrors ()));
+ }
+
+ expsuccess = FALSE;
}
}
}
{
if (context_getExpect () > 0)
{
- llmsg (message
- ("Finished LCLint checking --- "
- "%sno code errors found, expected %d",
- specErrors,
- (int) context_getExpect ()));
+ if (!isQuiet) {
+ llmsg (message
+ ("Finished checking --- "
+ "%sno code warnings, expected %d",
+ specErrors,
+ (int) context_getExpect ()));
+ }
+
+ expsuccess = FALSE;
}
else
{
if (context_getLinesProcessed () > 0)
{
- llmsg (message ("Finished LCLint checking --- %sno code errors found",
- specErrors));
+ if (cstring_isEmpty (specErrors))
+ {
+ if (!isQuiet)
+ {
+ llmsg (message ("Finished checking --- no warnings"));
+ }
+ }
+ else
+ {
+ if (!isQuiet)
+ {
+ llmsg (message ("Finished checking --- %sno code warnings",
+ specErrors));
+ }
+ }
}
else
{
- llmsg (message ("Finished LCLint checking --- %sno code processed",
- specErrors));
+ if (!isQuiet) {
+ llmsg (message ("Finished checking --- %sno code processed",
+ specErrors));
+ }
}
}
}
cstring_free (specErrors);
- }
-
+ }
+
if (context_getFlag (FLG_STATS))
{
clock_t ttime = clock () - before;
int specLines = context_getSpecLinesProcessed ();
-
+
rstime = clock ();
-
+
if (specLines > 0)
{
fprintf (g_msgstream, "%d spec, ", specLines);
}
-
+
# ifndef CLOCKS_PER_SEC
fprintf (g_msgstream, "%d source lines in %ld time steps (steps/sec unknown)\n",
context_getLinesProcessed (),
if (context_getFlag (FLG_TIMEDIST))
{
clock_t ttime = clock () - before;
-
+
if (ttime > 0)
{
char *msg = (char *) dmalloc (256 * sizeof (*msg));
-
+
if (anylcl)
{
sprintf (msg,
(100.0 * (double) (cptime - pptime) / ttime),
(100.0 * (double) (rstime - cptime) / ttime));
}
-
+
llgenindentmsgnoloc (cstring_fromCharsO (msg));
}
}
- llexit (LLSUCCESS);
+ llexit (expsuccess ? LLSUCCESS : LLFAILURE);
+ BADBRANCHRET (LLFAILURE);
}
+# ifdef WIN32
/*
** Reenable return value warnings.
*/
-
-#pragma warning (default:4035)
+# pragma warning (default:4035)
+# endif
void
showHelp (void)
{
showHerald ();
- llmsglit ("Source files are .c, .h and .lcl files. If there is no suffix,");
- llmsglit (" LCLint will look for <file>.c and <file>.lcl.");
+ llmsg (message ("Source files are .c, .h and %s files. If there is no suffix,",
+ LCL_EXTENSION));
+ llmsg (message (" Splint will look for <file>.c and <file>%s.", LCL_EXTENSION));
llmsglit ("");
- llmsglit ("Use lclint -help <topic or flag name> for more information");
+ llmsglit ("Use splint -help <topic or flag name> for more information");
llmsglit ("");
llmsglit ("Topics:");
llmsglit ("");
"it is not advisible to use these, oftentimes one has no choice "
"when the system header files use compiler extensions. ");
llmsglit ("");
- llmsglit ("LCLint supports some of the GNU (gcc) compiler extensions, "
+ llmsglit ("Splint supports some of the GNU (gcc) compiler extensions, "
"if the +gnuextensions flag is set. You may be able to workaround "
"other compiler extensions by using a pre-processor define. "
"Alternately, you can surround the unparseable code with");
llmsglit ("");
- llmsglit (" # ifndef __LCLINT__");
+ llmsglit (" # ifndef S_SPLINT_S");
llmsglit (" ...");
llmsglit (" # endif");
llmsglit ("");
+ /* evans 2000-12-21 fixed typo reported by Jeroen Ruigrok/Asmodai */
llmsglit ("Missing type definitions --- an undefined type name will usually "
- "lead to a parse error. This ofter occurs when a standard header "
+ "lead to a parse error. This often occurs when a standard header "
"file defines some type that is not part of the standard library. ");
- llmsglit ("By default, LCLint does not process the local files corresponding "
+ llmsglit ("By default, Splint does not process the local files corresponding "
"to standard library headers, but uses a library specification "
"instead so dependencies on local system headers can be detected. "
"If another system header file that does not correspond to a "
"a parse error will result.");
llmsglit ("");
llmsglit ("If the parse error is inside a posix standard header file, the "
- "first thing to try is +posixlib. This make LCLint use "
+ "first thing to try is +posixlib. This makes Splint use "
"the posix library specification instead of reading the posix "
"header files.");
llmsglit ("");
llmsglit (" /*@=skipposixheaders@*/");
llmsglit (" # include <sys/local.h>");
llmsglit ("");
- llmsglit ("to force LCLint to process <sys/types.h>.");
+ llmsglit ("to force Splint to process <sys/types.h>.");
llmsglit ("");
- llmsglit ("At last resort, +trytorecover can be used to make LCLint attempt "
+ llmsglit ("At last resort, +trytorecover can be used to make Splint attempt "
"to continue after a parse error. This is usually not successful "
"and the author does not consider assertion failures when +trytorecover "
"is used to be bugs.");
llmsglit ("Annotations");
llmsglit ("-----------");
llmsglit ("");
- llmsglit ("Annotations are stylized comments that document certain "
+ llmsglit ("Annotations are semantic comments that document certain "
"assumptions about functions, variables, parameters, and types. ");
llmsglit ("");
llmsglit ("They may be used to indicate where the representation of a "
llmsglit ("/*@i<n>@*/");
llgenindentmsgnoloc
(cstring_makeLiteral
- ("No errors will be reported from an /*@i<n>@*/ (e.g., /*@i3@*/) comment to the end of the line. If there are not exactly n errors suppressed from the comment point to the end of the line, LCLint will report an error."));
+ ("No errors will be reported from an /*@i<n>@*/ (e.g., /*@i3@*/) comment to the end of the line. If there are not exactly n errors suppressed from the comment point to the end of the line, Splint will report an error."));
llmsglit ("/*@t@*/, /*@t<n>@*/");
llgenindentmsgnoloc
(cstring_makeLiteral
llmsglit ("Mailing Lists");
llmsglit ("-------------");
llmsglit ("");
- llmsglit ("There are two mailing lists associated with LCLint: ");
+ llmsglit ("There are two mailing lists associated with Splint: ");
llmsglit ("");
llmsglit (" lclint-announce@virginia.edu");
llmsglit ("");
llmsglit ("References");
llmsglit ("----------");
llmsglit ("");
- llmsglit ("The LCLint web site is http://lclint.cs.virginia.edu");
- llmsglit ("");
- llmsglit ("Technical papers relating to LCLint include:");
- llmsglit ("");
- llmsglit (" David Evans. \"Static Detection of Dynamic Memory Errors\".");
- llmsglit (" SIGPLAN Conference on Programming Language Design and ");
- llmsglit (" Implementation (PLDI '96), Philadelphia, PA, May 1996.");
- llmsglit ("");
- llmsglit (" David Evans, John Guttag, Jim Horning and Yang Meng Tan. ");
- llmsglit (" \"LCLint: A Tool for Using Specifications to Check Code\".");
- llmsglit (" SIGSOFT Symposium on the Foundations of Software Engineering,");
- llmsglit (" December 1994.");
- llmsglit ("");
- llmsglit ("A general book on Larch is:");
- llmsglit ("");
- llmsglit (" Guttag, John V., Horning, James J., (with Garland, S. J., Jones, ");
- llmsglit (" K. D., Modet, A., and Wing, J. M.), \"Larch: Languages and Tools ");
- llmsglit (" for Formal Specification\", Springer-Verlag, 1993.");
+ llmsglit ("For more information, see the Splint web site: http://www.splint.org");
}
void
describeVars (void)
{
cstring eval;
- char *def;
+ cstring def;
eval = context_getLarchPath ();
def = osd_getEnvironmentVariable (LARCH_PATH);
- if (def != NULL ||
+ if (cstring_isDefined (def) ||
!cstring_equal (eval, cstring_fromChars (DEFAULT_LARCHPATH)))
{
llmsg (message ("LARCH_PATH = %s", eval));
llmsglit (" --- path used to find larch initialization files and LSL traits");
eval = context_getLCLImportDir ();
- def = osd_getEnvironmentVariable (LCLIMPORTDIR);
+ def = osd_getEnvironmentVariable (cstring_makeLiteralTemp (LCLIMPORTDIR));
- if (def != NULL ||
+ if (cstring_isDefined (def) ||
!cstring_equal (eval, cstring_fromChars (DEFAULT_LCLIMPORTDIR)))
{
llmsg (message ("%q = %s", cstring_makeLiteral (LCLIMPORTDIR), eval));
llmsglit (" --- directory containing lcl standard library files "
"(import with < ... >)");;
- {
- cstring dirs = context_getString (FLG_SYSTEMDIRS);
- llmsg (message
- ("systemdirs = %s (set by include envirnoment variable or -systemdirs)",
- dirs));
+ llmsg (message
+ ("include path = %q (set by environment variable %s and -I flags)",
+ cppReader_getIncludePath (), INCLUDEPATH_VAR));
- }
+ llmsglit (" --- path used to find #include'd files");
+
+ llmsg (message
+ ("systemdirs = %s (set by -systemdirs or environment variable %s)", /*@i413223@*/
+ context_getString (FLG_SYSTEMDIRS),
+ INCLUDEPATH_VAR));
+
+ llmsglit (" --- if file is found on this path, it is treated as a system file for error reporting");
}
void
setCodePoint ();
+ /*
+ ** Close all open files
+ ** (There should only be open files, if we exited after a fatal error.)
+ */
+
+ fileTable_closeAll (context_fileTable ());
+
if (context_getFlag (FLG_KEEP))
{
check (fputs ("Temporary files kept:\n", stderr) != EOF);
}
/*
-** cleans up temp files (if necessary)
-** exits lclint
+** cleans up temp files (if necessary) and exits
*/
/*@exits@*/ void
llexit (int status)
{
+ DPRINTF (("llexit: %d", status));
+
# ifdef WIN32
if (status == LLFAILURE)
{
exit ((status == LLSUCCESS) ? EXIT_SUCCESS : EXIT_FAILURE);
}
+bool readOptionsFile (cstring fname, cstringSList *passThroughArgs, bool report)
+{
+ bool res = FALSE;
+
+ if (fileTable_exists (context_fileTable (), fname))
+ {
+ if (report)
+ {
+ voptgenerror
+ (FLG_WARNRC,
+ message ("Multiple attempts to read options file: %s", fname),
+ g_currentloc);
+ }
+ }
+ else
+ {
+ FILE *innerf = fileTable_openFile (context_fileTable (), fname, "r");
+
+ if (innerf != NULL)
+ {
+ fileloc fc = g_currentloc;
+ g_currentloc = fileloc_createRc (fname);
+
+ if (context_getFlag (FLG_SHOWSCAN))
+ {
+ lldiagmsg (message ("< reading options from %q >",
+ fileloc_outputFilename (g_currentloc)));
+ }
+
+ loadrc (innerf, passThroughArgs);
+ fileloc_reallyFree (g_currentloc);
+ g_currentloc = fc;
+ res = TRUE;
+ }
+ else
+ {
+ if (report)
+ {
+ voptgenerror
+ (FLG_WARNRC,
+ message ("Cannot open options file: %s", fname),
+ g_currentloc);
+ }
+ }
+ }
+
+ return res;
+}
+
+/*
+** This shouldn't be necessary, but Apple Darwin can't handle '"''s.
+*/
+
void
-loadrc (FILE *rcfile, cstringSList *passThroughArgs)
+loadrc (/*:open:*/ FILE *rcfile, cstringSList *passThroughArgs)
+ /*@modifies rcfile@*/
+ /*@ensures closed rcfile@*/
{
char *s = mstring_create (MAX_LINE_LENGTH);
char *os = s;
-
+
DPRINTF (("Pass through: %s", cstringSList_unparse (*passThroughArgs)));
s = os;
- while (fgets (s, MAX_LINE_LENGTH, rcfile) != NULL)
+ while (reader_readLine (rcfile, s, MAX_LINE_LENGTH) != NULL)
{
char c;
bool set = FALSE;
DPRINTF (("Line: %s", s));
DPRINTF (("Pass through: %s", cstringSList_unparse (*passThroughArgs)));
- incLine ();
- while (*s == ' ' || *s == '\t' || *s == '\n')
+ while (*s == ' ' || *s == '\t')
{
s++;
incColumn ();
else
{
showHerald ();
- llerror (FLG_SYNTAX,
- message ("Bad flag syntax (+ or - expected, "
- "+ is assumed): %s",
- cstring_fromChars (s)));
+ voptgenerror (FLG_BADFLAG,
+ message ("Bad flag syntax (+ or - expected, "
+ "+ is assumed): %s",
+ cstring_fromChars (s)),
+ g_currentloc);
s--;
set = TRUE;
}
}
else if (flagcode_isInvalid (opt))
{
+ DPRINTF (("Invalid: %s", thisflag));
+
if (isMode (cstring_fromChars (thisflag)))
{
context_setMode (cstring_fromChars (thisflag));
}
else
{
- llerror (FLG_BADFLAG,
- message ("Unrecognized option: %s",
- cstring_fromChars (thisflag)));
+ voptgenerror (FLG_BADFLAG,
+ message ("Unrecognized option: %s",
+ cstring_fromChars (thisflag)),
+ g_currentloc);
}
}
else
if (opt == FLG_HELP)
{
showHerald ();
- llerror (FLG_BADFLAG,
- message ("Cannot use help in rc files"));
+ voptgenerror (FLG_BADFLAG,
+ message ("Cannot use help in rc files"),
+ g_currentloc);
}
else if (flagcode_isPassThrough (opt)) /* -D or -U */
{
if (cstring_isUndefined (extra))
{
showHerald ();
- llerror
+ voptgenerror
(FLG_BADFLAG,
message
("Flag %s must be followed by an argument",
- flagcode_unparse (opt)));
+ flagcode_unparse (opt)),
+ g_currentloc);
}
else
{
{
DPRINTF (("Set value flag: %s", extra));
setValueFlag (opt, extra);
- cstring_free (extra);
}
else if (opt == FLG_OPTF)
{
- FILE *innerf = fopen (cstring_toCharsSafe (extra), "r");
- cstring_markOwned (extra);
-
- if (innerf != NULL)
- {
- fileloc fc = g_currentloc;
- g_currentloc = fileloc_createRc (extra);
- loadrc (innerf, passThroughArgs);
- fileloc_reallyFree (g_currentloc);
- g_currentloc = fc;
- }
- else
- {
- showHerald ();
- llerror
- (FLG_SYNTAX,
- message ("Options file not found: %s",
- extra));
- }
+ (void) readOptionsFile (extra, passThroughArgs, TRUE);
}
else if (opt == FLG_INIT)
{
# ifndef NOLCL
- llassert (initFile == NULL);
+ llassert (inputStream_isUndefined (initFile));
- initFile = tsource_create
- (cstring_toCharsSafe (extra),
- LCLINIT_SUFFIX, FALSE);
- cstring_markOwned (extra);
-# else
- cstring_free (extra);
+ initFile = inputStream_create
+ (cstring_copy (extra),
+ cstring_makeLiteralTemp (LCLINIT_SUFFIX),
+ FALSE);
# endif
}
else if (flagcode_hasString (opt))
{
- if (cstring_firstChar (extra) == '"')
+ DPRINTF (("Here: %s", extra));
+
+ /*
+ ** If it has "'s, we need to remove them.
+ */
+
+ if (cstring_firstChar (extra) == '\"')
{
- if (cstring_lastChar (extra) == '"')
+ if (cstring_lastChar (extra) == '\"')
{
- char *extras = cstring_toCharsSafe (extra);
-
- llassert (extras[strlen(extras) - 1] == '"');
- extras[strlen(extras) - 1] = '\0';
- extra = cstring_fromChars (extras + 1);
- DPRINTF (("Remove quites: %s", extra));
+ cstring unquoted = cstring_copyLength
+ (cstring_toCharsSafe (cstring_suffix (extra, 1)),
+ cstring_length (extra) - 2);
+
+ DPRINTF (("string flag: %s -> %s", extra, unquoted));
+ setStringFlag (opt, unquoted);
+ cstring_free (extra);
}
else
{
- llerror
- (FLG_SYNTAX,
+ voptgenerror
+ (FLG_BADFLAG,
message ("Unmatched \" in option string: %s",
- extra));
+ extra),
+ g_currentloc);
+ setStringFlag (opt, extra);
}
}
-
- setStringFlag (opt, extra);
+ else
+ {
+ DPRINTF (("No quotes: %s", extra));
+ setStringFlag (opt, extra);
+ }
+
+ extra = cstring_undefined;
}
else
{
- cstring_free (extra);
BADEXIT;
}
}
+
+ cstring_free (extra);
}
else
{
DPRINTF (("Pass through: %s", cstringSList_unparse (*passThroughArgs)));
sfree (os);
- check (fclose (rcfile) == 0);
+ check (fileTable_closeFile (context_fileTable (), rcfile));
}
-static fileIdList preprocessFiles (fileIdList fl)
+static fileIdList preprocessFiles (fileIdList fl, bool xhfiles)
/*@modifies fileSystem@*/
{
bool msg = (context_getFlag (FLG_SHOWSCAN) && fileIdList_size (fl) > 10);
fileIdList_elements (fl, fid)
{
- char *ppfname = cstring_toCharsSafe (fileName (fid));
+ cstring ppfname = fileName (fid);
if (!(osd_fileIsReadable (ppfname)))
{
- lldiagmsg (message ("Cannot open file: %s",
- cstring_fromChars (ppfname)));
+ lldiagmsg (message ("Cannot open file: %q", osd_outputPath (ppfname)));
+ ppfname = cstring_undefined;
}
- else
+
+ if (cstring_isDefined (ppfname))
{
- fileId dfile = fileTable_addCTempFile (context_fileTable (), fid);
-
- llassert (!mstring_isEmpty (ppfname));
+ fileId dfile = fileTable_addCTempFile (context_fileTable (), fid);
+
+ if (xhfiles)
+ {
+ llassert (fileTable_isXHFile (context_fileTable (), dfile));
+ }
+
+ llassert (cstring_isNonEmpty (ppfname));
if (msg)
{
filesprocessed++;
}
- if (cppProcess (cstring_fromChars (ppfname),
- fileName (dfile)) != 0)
+ if (cppProcess (ppfname, fileName (dfile)) != 0)
{
llfatalerror (message ("Preprocessing error for file: %s",
rootFileName (fid)));
return dfiles;
}
+
+/* This should be in an lclUtils.c file... */
+# ifndef NOLCL
+char *specFullName (char *specfile, /*@out@*/ char **inpath)
+{
+ /* extract the path and the specname associated with the given file */
+ char *specname = (char *) dmalloc (sizeof (*specname)
+ * (strlen (specfile) + 9));
+ char *ospecname = specname;
+ char *path = (char *) dmalloc (sizeof (*path) * (strlen (specfile)));
+ size_t size;
+ long int i, j;
+
+ /* initialized path to empty string or may have accidental garbage */
+ *path = '\0';
+
+ /*@-mayaliasunique@*/
+ strcpy (specname, specfile);
+ /*@=mayaliasunique@*/
+
+ /* trim off pathnames in specfile */
+ size = strlen (specname);
+
+ for (i = size_toInt (size) - 1; i >= 0; i--)
+ {
+ if (specname[i] == CONNECTCHAR)
+ {
+ /* strcpy (specname, (char *)specname+i+1); */
+ for (j = 0; j <= i; j++) /* include '/' */
+ {
+ path[j] = specname[j];
+ }
+
+ path[i + 1] = '\0';
+ specname += i + 1;
+ break;
+ }
+ }
+
+ /*
+ ** also remove .lcl file extension, assume it's the last extension
+ ** of the file name
+ */
+
+ size = strlen (specname);
+
+ for (i = size_toInt (size) - 1; i >= 0; i--)
+ {
+ if (specname[i] == '.')
+ {
+ specname[i] = '\0';
+ break;
+ }
+ }
+
+ *inpath = path;
+
+ /*
+ ** If specname no longer points to the original char,
+ ** we need to allocate a new pointer and copy the string.
+ */
+
+ if (specname != ospecname) {
+ char *rspecname = (char *) dmalloc (sizeof (*rspecname) * (strlen (specname) + 1));
+ strcpy (rspecname, specname); /* evs 2000-05-16: Bug: was ospecname! */
+ sfree (ospecname);
+ return rspecname;
+ }
+
+ return specname;
+}
+# endif