/*
** Splint - annotation-assisted static program checker
-** Copyright (C) 1994-2001 University of Virginia,
+** Copyright (C) 1994-2002 University of Virginia,
** Massachusetts Institute of Technology
**
** This program is free software; you can redistribute it and/or modify it
static void showHelp (void);
static void interrupt (int p_i);
+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)
- /*@ensures closed p_rcfile@*/ ;
+ /*@modifies *p_passThroughArgs, p_rcfile@*/
+ /*@ensures closed p_rcfile@*/ ;
static void describeVars (void);
static bool specialFlagsHelp (char *p_next);
else
{
- fprintf (g_msgstream, "%s\n\n", LCL_VERSION);
+ fprintf (g_msgstream, "%s\n\n", SPLINT_VERSION);
hasShownHerald = TRUE;
llflush ();
}
{
cstring home = osd_getHomeDir ();
- char *fname = NULL;
- FILE *rcfile;
+ 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 = fileTable_openFile (context_fileTable (), cstring_fromChars (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 = fileTable_openFile (context_fileTable (), cstring_fromChars (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 = fileTable_openFile (context_fileTable (), cstring_fromChars (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);
+ }
}
}
opt = identifyFlag (flagname);
DPRINTF (("Flag: %s", flagcode_unparse (opt)));
- if (flagcode_isSkip (opt))
+ if (flagcode_isSkip (opt) || opt == FLG_SHOWSCAN || opt == FLG_WARNRC)
{
+ /* showscan already processed */
DPRINTF (("Skipping!"));
}
else if (flagcode_isInvalid (opt))
}
setCodePoint ();
-
+ showHerald ();
+
/*
** create lists of C and LCL files
*/
}
} end_cstringSList_elements;
- showHerald (); /*@i723 move earlier? */
-
if (showhelp)
{
if (allhelp)
}
}
else
+ {
if (!isQuiet)
{
llmsg (message ("Finished checking --- %sno code warnings",
specErrors));
}
+ }
}
else
{
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 (/*: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;
{
DPRINTF (("Set value flag: %s", extra));
setValueFlag (opt, extra);
- cstring_free (extra);
}
else if (opt == FLG_OPTF)
{
- FILE *innerf = fileTable_openFile (context_fileTable (), 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 ();
- voptgenerror
- (FLG_BADFLAG,
- message ("Options file not found: %s",
- extra),
- g_currentloc);
- }
+ (void) readOptionsFile (extra, passThroughArgs, TRUE);
}
else if (opt == FLG_INIT)
{
llassert (inputStream_isUndefined (initFile));
initFile = inputStream_create
- (extra,
+ (cstring_copy (extra),
cstring_makeLiteralTemp (LCLINIT_SUFFIX),
FALSE);
-# else
- cstring_free (extra);
# endif
}
else if (flagcode_hasString (opt))
{
+ DPRINTF (("Here: %s", extra));
+
+ /*
+ ** If it has "'s, we need to remove them.
+ */
+
if (cstring_firstChar (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 quotes: %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
{
message ("Unmatched \" in option string: %s",
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
{
if (!(osd_fileIsReadable (ppfname)))
{
- lldiagmsg (message ("Cannot open file: %s", osd_outputPath (ppfname)));
+ lldiagmsg (message ("Cannot open file: %q", osd_outputPath (ppfname)));
ppfname = cstring_undefined;
}