]> andersk Git - splint.git/blobdiff - src/llmain.c
Fixed problem with loop guards in loop test effects. New test case
[splint.git] / src / llmain.c
index 66d911521470a2c1ea8d523f086cdde19907f75c..2031c6d74516ef1f3d3cab8fc0ea990c69e36230 100644 (file)
@@ -17,8 +17,8 @@
 ** 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
 */
 /*
@@ -48,7 +48,7 @@
 # include <process.h>
 # endif
 
-# include "lclintMacros.nf"
+# include "splintMacros.nf"
 # include "llbasic.h"
 # include "osd.h"
 
@@ -69,7 +69,7 @@
 # include "imports.h"
 # endif
 
-# include "version.h"
+# include "Headers/version.h" /* Visual C++ finds the wrong version.h */
 # include "fileIdList.h"
 # include "lcllib.h"
 # include "cgrammar.h"
@@ -114,6 +114,8 @@ static /*@only@*/ /*@null@*/ inputStream initFile = inputStream_undefined;
 static fileIdList preprocessFiles (fileIdList, bool)
   /*@modifies fileSystem@*/ ;
 
+static void warnSysFiles(fileIdList p_files) /*@modifies fileSystem@*/;
+
 # ifndef NOLCL
 
 static
@@ -323,7 +325,7 @@ lslProcess (fileIdList lclfiles)
   fileIdList_elements (lclfiles, fid)
     {
       cstring actualName = cstring_undefined;
-      cstring fname = fileName (fid);
+      cstring fname = fileTable_fileName (fid);
       
       if (osd_getPath (cstring_fromChars (g_localSpecPath), 
                       fname, &actualName) == OSD_FILENOTFOUND)
@@ -364,12 +366,9 @@ lslProcess (fileIdList lclfiles)
 
          setSpecFileId (fid);
                  
-         if (context_getFlag (FLG_SHOWSCAN))
-           {
-             lldiagmsg (message ("< reading spec %s >", g_currentSpec));
-           }
+         displayScan (message ("reading spec %s", g_currentSpec));
          
-         /* Open source file */
+         /* Open the source file */
          
          if (!inputStream_open (specFile))
            {
@@ -523,11 +522,13 @@ static void handlePassThroughFlag (char *arg)
 
 void showHerald (void)
 {
-  if (hasShownHerald || context_getFlag (FLG_QUIET)) return;
-
+  if (hasShownHerald || context_getFlag (FLG_QUIET)) 
+    {
+      return;
+    }
   else
     {
-      fprintf (g_msgstream, "%s\n\n", SPLINT_VERSION);
+      fprintf (g_messagestream, "%s\n\n", SPLINT_VERSION);
       hasShownHerald = TRUE;
       llflush ();
     }
@@ -547,7 +548,7 @@ static cstring findLarchPathFile (/*@temp@*/ cstring s)
   else if (status == OSD_FILENOTFOUND)
     {
       showHerald ();
-      lldiagmsg        (message ("Cannot find file on LARCHPATH: %s", s));
+      lldiagmsg        (message ("Cannot find file on LARCH_PATH: %s", s));
     }
   else if (status == OSD_PATHTOOLONG)
     {
@@ -616,7 +617,7 @@ static void addXHFile (fileIdList files, /*@temp@*/ cstring s)
 }
 
 /*
-** Disable MSVC++ warning about return value.  Methinks humbly lclint control
+** Disable MSVC++ warning about return value.  Methinks humbly splint control
 ** comments are a mite more legible.
 */
 
@@ -628,7 +629,7 @@ int main (int argc, char *argv[])
 # ifdef NOLCL
   /*@globals killed undef g_currentloc,
             killed undef yyin,
-                    undef g_msgstream;
+                    undef g_warningstream, g_messagestream, g_errorstream;
    @*/
   /*@modifies g_currentloc, fileSystem,
              yyin; 
@@ -640,7 +641,7 @@ int main (int argc, char *argv[])
             killed undef g_currentSpec,
             killed undef g_currentSpecName,
             killed undef yyin,
-                    undef g_msgstream;
+                    undef g_warningstream, g_messagestream, g_errorstream;
    @*/
   /*@modifies g_currentloc, initFile, 
               g_localSpecPath, g_currentSpec, g_currentSpecName, fileSystem,
@@ -665,7 +666,9 @@ int main (int argc, char *argv[])
   _wildcard (&argc, &argv);
 # endif
 
-  g_msgstream = stdout;
+  g_warningstream = stdout;
+  g_messagestream = stderr;
+  g_errorstream = stderr;
 
   (void) signal (SIGINT, interrupt);
   (void) signal (SIGSEGV, interrupt); 
@@ -684,7 +687,7 @@ int main (int argc, char *argv[])
   setCodePoint ();
   
   g_currentloc = fileloc_createBuiltin ();
-  
+    
   before = clock ();
   context_initMod ();
 
@@ -798,13 +801,31 @@ int main (int argc, char *argv[])
              {
                nof = TRUE;
              }
-           else if (opt == FLG_SHOWSCAN || opt == FLG_WARNRC)
+           else if (flagcode_isMessageControlFlag (opt))
              {
                /*
                ** Need to set it immediately, so rc file scan is displayed
                */
 
                context_userSetFlag (opt, set);
+
+               if (flagcode_hasArgument (opt))
+                 {
+                   llassert (flagcode_hasString (opt));
+                   
+                   if (++i < argc)
+                     {
+                       fname = cstring_fromChars (argv[i]);
+                       setStringFlag (opt, fname);
+                     }
+                   else
+                     {
+                       llfatalerror 
+                         (message
+                          ("Flag %s must be followed by a string",
+                           flagcode_unparse (opt)));
+                     }
+                 }
              }
            else if (opt == FLG_OPTF)
              {
@@ -846,7 +867,7 @@ int main (int argc, char *argv[])
                readhomerc = readOptionsFile (homename, &passThroughArgs, FALSE);
                
                /*
-               ** Try ~/.lclintrc also for historical accuracy
+               ** Try ~/.splintrc also for historical accuracy
                */
                
                altname = message ("%s%h%s", home, CONNECTCHAR,
@@ -1008,10 +1029,16 @@ int main (int argc, char *argv[])
              opt = flags_identifyFlag (flagname);
              DPRINTF (("Flag: %s", flagcode_unparse (opt)));
 
-             if (flagcode_isSkip (opt) || opt == FLG_SHOWSCAN || opt == FLG_WARNRC)
+             if (flagcode_isMessageControlFlag (opt))
                {
-                 /* showscan already processed */
-                 DPRINTF (("Skipping!"));
+                 /*
+                 ** Processed on first pass
+                 */
+
+                 if (flagcode_hasArgument (opt))
+                   {
+                     ++i;
+                   }
                }
              else if (flagcode_isInvalid (opt))
                {
@@ -1045,7 +1072,7 @@ int main (int argc, char *argv[])
                          passThroughArgs = cstringSList_add 
                            (passThroughArgs, cstring_fromChars (thisarg));
                        }
-                     else if (flagcode_hasValue (opt))
+                     else if (flagcode_hasNumber (opt))
                        {
                          if (++i < argc)
                            {
@@ -1059,6 +1086,20 @@ int main (int argc, char *argv[])
                                  flagcode_unparse (opt)));
                            }
                        } 
+                     else if (flagcode_hasChar (opt))
+                       {
+                         if (++i < argc)
+                           {
+                             setValueFlag (opt, cstring_fromChars (argv[i]));
+                           }
+                         else
+                           {
+                             llfatalerror 
+                               (message
+                                ("Flag %s must be followed by a character",
+                                 flagcode_unparse (opt)));
+                           }
+                       } 
                      else if (opt == FLG_INCLUDEPATH || opt == FLG_SPECPATH)
                        {
                          cstring dir = cstring_suffix (cstring_fromChars (thisarg), 1); /* skip over I */
@@ -1119,7 +1160,7 @@ int main (int argc, char *argv[])
                                    }
                                  else
                                    {
-                                     setStringFlag (opt, arg);
+                                     setStringFlag (opt, cstring_copy (arg));
                                    }
                                }
                            }
@@ -1211,7 +1252,7 @@ int main (int argc, char *argv[])
        {
          showHelp ();
        }
-      fprintf (g_msgstream, "\n");
+      fprintf (g_warningstream, "\n");
 
       fileIdList_free (cfiles);
       fileIdList_free (xfiles);
@@ -1235,17 +1276,9 @@ int main (int argc, char *argv[])
     {
       cstring m = context_getMerge ();
 
-      if (context_getFlag (FLG_SHOWSCAN))
-       {
-         fprintf (g_msgstream, "< loading %s ", cstring_toCharsSafe (m));
-       }
-
+      displayScanOpen (message ("< loading %s ", m));
       loadState (m);
-
-      if (context_getFlag (FLG_SHOWSCAN))
-       {
-         fprintf (g_msgstream, " >\n");
-       }
+      displayScanClose ();
 
       if (!usymtab_existsType (context_getBoolName ()))
        {
@@ -1277,13 +1310,8 @@ int main (int argc, char *argv[])
   fileIdList_elements (mtfiles, mtfile)
     {
       context_setFileId (mtfile);
-
-      if (context_getFlag (FLG_SHOWSCAN))
-       {
-         lldiagmsg (message ("< processing %s >", rootFileName (mtfile)));
-       }
-      
-      mtreader_readFile (cstring_copy (fileName (mtfile)));
+      displayScan (message ("processing %s", fileTable_rootFileName (mtfile)));
+      mtreader_readFile (cstring_copy (fileTable_fileName (mtfile)));
     } end_fileIdList_elements;
 
   libtime = clock ();
@@ -1331,16 +1359,14 @@ int main (int argc, char *argv[])
 
       llflush ();
 
-      if (context_getFlag (FLG_SHOWSCAN))
-       {
-         fprintf (stderr, "< preprocessing"); 
-       }
+      displayScanOpen (cstring_makeLiteral ("preprocessing"));
       
       lcltime = clock ();
 
       context_setPreprocessing ();
       dercfiles = preprocessFiles (xfiles, TRUE);
       tfiles = preprocessFiles (cfiles, FALSE);
+      warnSysFiles(cfiles);
       dercfiles = fileIdList_append (dercfiles, tfiles);
       fileIdList_free (tfiles);
 
@@ -1348,11 +1374,7 @@ int main (int argc, char *argv[])
 
       fileIdList_free (cfiles);
 
-      if (context_getFlag (FLG_SHOWSCAN))
-       {
-         fprintf (stderr, " >\n");
-       }
-      
+      displayScanClose ();
       pptime = clock ();
     }
   else
@@ -1388,7 +1410,7 @@ int main (int argc, char *argv[])
 
   fileIdList_elements (dercfiles, fid)
     {
-      sourceFile = inputStream_create (cstring_copy (fileName (fid)), C_EXTENSION, TRUE);
+      sourceFile = inputStream_create (cstring_copy (fileTable_fileName (fid)), C_EXTENSION, TRUE);
       context_setFileId (fid);
       
       /* Open source file  */
@@ -1396,7 +1418,7 @@ int main (int argc, char *argv[])
       if (inputStream_isUndefined (sourceFile) || (!inputStream_open (sourceFile)))
        {
          /* previously, this was ignored  ?! */
-         llbug (message ("Could not open temp file: %s", fileName (fid)));
+         llbug (message ("Could not open temp file: %s", fileTable_fileName (fid)));
        }
       else
        {
@@ -1404,10 +1426,7 @@ int main (int argc, char *argv[])
        
          llassert (yyin != NULL);
 
-         if (context_getFlag (FLG_SHOWSCAN))
-           {
-             lldiagmsg (message ("< checking %q >", osd_outputPath (rootFileName (fid))));
-           }
+         displayScan (message ("checking %q", osd_outputPath (fileTable_rootFileName (fid))));
          
          /*
          ** Every time, except the first time, through the loop,
@@ -1444,10 +1463,7 @@ int main (int argc, char *argv[])
   **   is this correct behaviour?
   */
   
-  if (context_getFlag (FLG_SHOWSCAN))
-    {
-      lldiagmsg (cstring_makeLiteral ("< global checks >"));
-    }
+  displayScan (cstring_makeLiteral ("global checks"));
 
   cleanupMessages ();
   
@@ -1515,7 +1531,7 @@ int main (int argc, char *argv[])
     expsuccess = TRUE;
 
     if (context_neednl ())
-      fprintf (g_msgstream, "\n");
+      fprintf (g_warningstream, "\n");
     
 # ifndef NOLCL
     if (nspecErrors > 0)
@@ -1648,15 +1664,15 @@ int main (int argc, char *argv[])
       
       if (specLines > 0)
        {
-         fprintf (g_msgstream, "%d spec, ", specLines);
+         fprintf (g_warningstream, "%d spec, ", specLines);
        }
       
 # ifndef CLOCKS_PER_SEC
-      fprintf (g_msgstream, "%d source lines in %ld time steps (steps/sec unknown)\n", 
+      fprintf (g_warningstream, "%d source lines in %ld time steps (steps/sec unknown)\n", 
               context_getLinesProcessed (), 
               (long) ttime);
 # else
-      fprintf (g_msgstream, "%d source lines in %.2f s.\n", 
+      fprintf (g_warningstream, "%d source lines in %.2f s.\n", 
               context_getLinesProcessed (), 
               (double) ttime / CLOCKS_PER_SEC);
 # endif
@@ -1767,6 +1783,16 @@ specialFlagsHelp (char *next)
          printAllFlags (FALSE, TRUE);
          return TRUE;
        }
+      else if (mstring_equal (next, "manual"))
+       {
+         printFlagManual (FALSE);
+         return TRUE;
+       }
+      else if (mstring_equal (next, "webmanual"))
+       {
+         printFlagManual (TRUE);
+         return TRUE;
+       }
       else
        {
          return FALSE;
@@ -1784,7 +1810,7 @@ printParseErrors (void)
   llmsglit ("Parse Errors");
   llmsglit ("------------");
   llmsglit ("");
-  llmsglit ("LCLint will sometimes encounter a parse error for code that "
+  llmsglit ("Splint will sometimes encounter a parse error for code that "
            "can be parsed with a local compiler. There are a few likely "
            "causes for this and a number of techniques that can be used "
            "to work around the problem.");
@@ -1820,12 +1846,12 @@ printParseErrors (void)
            "header files.");
   llmsglit ("");
   llmsglit ("Otherwise, you may need to either manually define the problematic "
-           "type (e.g., add -Dmlink_t=int to your .lclintrc file) or force "
-           "lclint to process the header file that defines it. This is done "
-           "by setting -skipansiheaders or -skipposixheaders before "
+           "type (e.g., add -Dmlink_t=int to your .splintrc file) or force "
+           "splint to process the header file that defines it. This is done "
+           "by setting -skipisoheaders or -skipposixheaders before "
            "the file that defines the type is #include'd.");
-  llmsglit ("(See lclint -help "
-           "skipansiheaders and lclint -help skipposixheaders for a list of "
+  llmsglit ("(See splint -help "
+           "skipisoheaders and splint -help skipposixheaders for a list of "
            "standard headers.)  For example, if <sys/local.h> uses a type "
            "defined by posix header <sys/types.h> but not defined by the "
            "posix library, we might do: ");
@@ -2025,15 +2051,15 @@ printFlags (void)
   llmsglit ("Flag Categories");
   llmsglit ("---------------");
   listAllCategories ();
-  llmsglit ("\nTo see the flags in a flag category, do\n   lclint -help flags <category>");
-  llmsglit ("To see a list of all flags in alphabetical order, do\n   lclint -help flags alpha");
-  llmsglit ("To see a full description of all flags, do\n   lclint -help flags full");
+  llmsglit ("\nTo see the flags in a flag category, do\n   splint -help flags <category>");
+  llmsglit ("To see a list of all flags in alphabetical order, do\n   splint -help flags alpha");
+  llmsglit ("To see a full description of all flags, do\n   splint -help flags full");
 }
 
 void
 printMaintainer (void)
 {
-  llmsg (message ("Maintainer: %s", cstring_makeLiteralTemp (LCLINT_MAINTAINER)));
+  llmsg (message ("Maintainer: %s", cstring_makeLiteralTemp (SPLINT_MAINTAINER)));
   llmsglit (LCL_COMPILE);
 }
 
@@ -2053,7 +2079,7 @@ printMail (void)
   llmsglit ("");
   llmsglit ("   lclint-interest@virginia.edu");
   llmsglit ("");
-  llmsglit ("      Informal discussions on the use and development of lclint.");
+  llmsglit ("      Informal discussions on the use and development of Splint.");
   llmsglit ("      To subscribe, send a message to majordomo@virginia.edu with body: ");
   llmsglit ("           subscribe lclint-interest");
 }
@@ -2145,7 +2171,7 @@ interrupt (int i)
   switch (i)
     {
     case SIGINT:
-      fprintf (stderr, "*** Interrupt\n");
+      fprintf (g_errorstream, "*** Interrupt\n");
       llexit (LLINTERRUPT);
     case SIGSEGV:
       {
@@ -2154,28 +2180,28 @@ interrupt (int i)
        /* Cheat when there are parse errors */
        checkParseError (); 
        
-       fprintf (stderr, "*** Segmentation Violation\n");
+       fprintf (g_errorstream, "*** Segmentation Violation\n");
        
        /* Don't catch it if fileloc_unparse causes a signal */
        (void) signal (SIGSEGV, NULL);
 
        loc = fileloc_unparse (g_currentloc);
        
-       fprintf (stderr, "*** Location (not trusted): %s\n", 
+       fprintf (g_errorstream, "*** Location (not trusted): %s\n", 
                 cstring_toCharsSafe (loc));
        cstring_free (loc);
        printCodePoint ();
-       fprintf (stderr, "*** Please report bug to %s\n", LCLINT_MAINTAINER);
+       fprintf (g_errorstream, "*** Please report bug to %s\n", SPLINT_MAINTAINER);
        exit (LLGIVEUP);
       }
     default:
-      fprintf (stderr, "*** Signal: %d\n", i);
+      fprintf (g_errorstream, "*** Signal: %d\n", i);
       /*@-mustfree@*/
-      fprintf (stderr, "*** Location (not trusted): %s\n", 
+      fprintf (g_errorstream, "*** Location (not trusted): %s\n", 
               cstring_toCharsSafe (fileloc_unparse (g_currentloc)));
       /*@=mustfree@*/
       printCodePoint ();
-      fprintf (stderr, "*** Please report bug to %s ***\n", LCLINT_MAINTAINER);
+      fprintf (g_errorstream, "*** Please report bug to %s ***\n", SPLINT_MAINTAINER);
       exit (LLGIVEUP);
     }
 }
@@ -2200,7 +2226,7 @@ cleanupFiles (void)
 
   if (context_getFlag (FLG_KEEP))
     {
-      check (fputs ("Temporary files kept:\n", stderr) != EOF);
+      check (fputs ("Temporary files kept:\n", g_messagestream) != EOF);
       fileTable_printTemps (context_fileTable ());
     }
   else
@@ -2277,11 +2303,8 @@ bool readOptionsFile (cstring fname, cstringSList *passThroughArgs, bool report)
          fileloc fc = g_currentloc;
          g_currentloc = fileloc_createRc (fname);
 
-         if (context_getFlag (FLG_SHOWSCAN))
-           {
-             lldiagmsg (message ("< reading options from %q >", 
-                                 fileloc_outputFilename (g_currentloc)));
-           }
+         displayScan (message ("< reading options from %q >", 
+                               fileloc_outputFilename (g_currentloc)));
          
          loadrc (innerf, passThroughArgs);
          fileloc_reallyFree (g_currentloc);
@@ -2482,7 +2505,8 @@ loadrc (/*:open:*/ FILE *rcfile, cstringSList *passThroughArgs)
                        }
                    }
                  else if (flagcode_hasString (opt)
-                          || flagcode_hasValue (opt)
+                          || flagcode_hasNumber (opt)
+                          || flagcode_hasChar (opt)
                           || opt == FLG_INIT || opt == FLG_OPTF)
                    {
                      cstring extra = cstring_undefined;
@@ -2531,7 +2555,7 @@ loadrc (/*:open:*/ FILE *rcfile, cstringSList *passThroughArgs)
                          
                          DPRINTF (("Here we are: %s", extra));
 
-                         if (flagcode_hasValue (opt))
+                         if (flagcode_hasNumber (opt) || flagcode_hasChar (opt))
                            {
                              DPRINTF (("Set value flag: %s", extra));
                              setValueFlag (opt, extra);
@@ -2634,7 +2658,7 @@ static fileIdList preprocessFiles (fileIdList fl, bool xhfiles)
 
   fileIdList_elements (fl, fid)
     {
-      cstring ppfname = fileName (fid);
+      cstring ppfname = fileTable_fileName (fid);
 
       if (!(osd_fileIsReadable (ppfname)))
        {
@@ -2658,21 +2682,23 @@ static fileIdList preprocessFiles (fileIdList fl, bool xhfiles)
              if ((filesprocessed % skip) == 0) 
                {
                  if (filesprocessed == 0) {
-                   fprintf (stderr, " ");
+                   fprintf (g_messagestream, " ");
                  }
                  else {
-                   fprintf (stderr, ".");
+                   fprintf (g_messagestream, ".");
                  }
                  
-                 (void) fflush (stderr);
+                 (void) fflush (g_messagestream);
                }
              filesprocessed++;
            }
 
-         if (cppProcess (ppfname, fileName (dfile)) != 0) 
+         DPRINTF (("outfile: %s", fileTable_fileName (dfile)));
+
+         if (cppProcess (ppfname, fileTable_fileName (dfile)) != 0) 
            {
              llfatalerror (message ("Preprocessing error for file: %s", 
-                                    rootFileName (fid)));
+                                    fileTable_rootFileName (fid)));
            }
          
          fileIdList_add (dfiles, dfile);
@@ -2753,3 +2779,19 @@ char *specFullName (char *specfile, /*@out@*/ char **inpath)
   return specname;
 }
 # endif
+
+void warnSysFiles(fileIdList files)
+{
+  fileIdList_elements (files, file)
+    {
+      
+      if (fileTable_isSystemFile (context_fileTable (), file) )
+       {
+         if (!context_getFlag( FLG_SYSTEMDIRERRORS ) )
+           {
+             voptgenerror (FLG_WARNSYSFILES, message ("Warning %s is a considered a system file. No errors in this file will be reported.", fileTable_rootFileName (file) ), g_currentloc);
+           }
+       }
+    } 
+  end_fileIdList_elements;
+}
This page took 0.328592 seconds and 4 git commands to generate.