]> andersk Git - splint.git/blobdiff - src/osd.c
Surpressed spurious splintme error in osd.c
[splint.git] / src / osd.c
index 8bd823e141b816bdba242a08d2878dffe7fbd48e..71b5de41f10f4f0978283258913a93d7b2e164eb 100644 (file)
--- a/src/osd.c
+++ b/src/osd.c
@@ -1,6 +1,6 @@
 /*
-** LCLint - annotation-assisted static program checker
-** Copyright (C) 1994-2001 University of Virginia,
+** Splint - annotation-assisted static program checker
+** Copyright (C) 1994-2003 University of Virginia,
 **         Massachusetts Institute of Technology
 **
 ** This program is free software; you can redistribute it and/or modify it
@@ -17,9 +17,9 @@
 ** 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 more information: http://lclint.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
 */
 /*
 ** osd.c
@@ -37,6 +37,8 @@
  * Herbert 06/12/2000:
  * - added OS/2 specific includes before osd_getPid()
  * - handle files like in WIN32 for OS/2 in osd_fileExists()
+ * Herbert 02/17/2002:
+ * - added OS/2 support to absolute file names
  */
 
 /*@-allmacros*/
 /* POSIX platforms should defined getpid in unistd.h */
 # if defined (WIN32) || (defined(OS2) && defined(__IBMC__))
 # include <process.h>
+# include <direct.h>
+# define getcwd _getcwd
 # else
 # include <unistd.h>
 # endif
 
 /*@end@*/
 /*@=allmacros*/
-# include "lclintMacros.nf"
+# include "splintMacros.nf"
 # include "basic.h"
 # include "osd.h"
 # include "portab.h"
@@ -166,6 +170,12 @@ osd_getPath (cstring path, cstring file, cstring *returnPath)
   fullPath = path;
   llassert (cstring_isDefined (file));
   
+  /* 2002-01-01: make sure returnPath gets defined even when there are errors.
+  **             (fixed splint checking detected this)
+  */
+
+  *returnPath = cstring_undefined;
+
   if (fullPath == NULL 
       || 
 # if defined(OS2) || defined(MSDOS) || defined(WIN32)
@@ -218,7 +228,7 @@ osd_getPath (cstring path, cstring file, cstring *returnPath)
            }
        }       
     }
-  
+
   return rVal;
   /*@noaccess cstring@*/
 }
@@ -232,7 +242,8 @@ osd_getExePath (cstring path, cstring file, cstring *returnPath)
   char aPath[MAXPATHLEN];
   filestatus rVal = OSD_FILENOTFOUND;  /* assume file not found. */
   /*@access cstring@*/ 
-  
+
+  *returnPath = cstring_undefined;  
   fullPath = osd_getEnvironmentVariable (path);
   
   if (fullPath == NULL)
@@ -294,7 +305,7 @@ osd_fileExists (cstring filespec)
   return (stat (cstring_toCharsSafe (filespec), &buf) == 0);
 # else
 # if defined (WIN32) || defined (OS2)
-  FILE *test = fileTable_openFile (context_fileTable (), filespec, "r");
+  FILE *test = fileTable_openReadFile (context_fileTable (), filespec);
   
   if (test != NULL) 
     {
@@ -311,14 +322,25 @@ osd_fileExists (cstring filespec)
 # endif
 }
 
+# if defined(__IBMC__) && defined(OS2)
+# define S_IFMT (unsigned short)0xFFFF
+# endif
+
+/*
+** Works form Win32 at least...
+*/
+
+# ifndef S_IXUSR
+/*@-macrounrecog@*/
+# define S_IXUSR _S_IEXEC
+/*@=macrounrecog@*/
+# endif
+
 bool
 osd_executableFileExists (/*@unused@*/ char *filespec)
 {
 # ifdef UNIX
-       struct stat buf;
-# if defined(__IBMC__) && defined(OS2)
-# define S_IFMT (unsigned short)0xFFFF
-# endif
+  struct stat buf;
   if (stat (filespec, &buf) == 0)
     { 
       /* mask by file type */
@@ -327,14 +349,14 @@ osd_executableFileExists (/*@unused@*/ char *filespec)
        {
          /* as long as it is an executable file */
 # if defined(__IBMC__) && defined(OS2)
-      int com_or_exe_pos = strlen( filespec) - 4;
-      return stricmp( &filespec[com_or_exe_pos], ".exe") == 0
-        || stricmp( &filespec[com_or_exe_pos], ".com") == 0
-        || stricmp( &filespec[com_or_exe_pos], ".bat") == 0
-        || stricmp( &filespec[com_or_exe_pos], ".cmd") == 0;
+         int com_or_exe_pos = strlen( filespec) - 4;
+         return stricmp( &filespec[com_or_exe_pos], ".exe") == 0
+           || stricmp( &filespec[com_or_exe_pos], ".com") == 0
+           || stricmp( &filespec[com_or_exe_pos], ".bat") == 0
+           || stricmp( &filespec[com_or_exe_pos], ".cmd") == 0;
 # else
          return (((buf.st_mode & S_IXUSR)
-# if !defined(MSDOS) && !defined(OS2) 
+# if defined (S_IXGRP) && defined (S_IXOTH)
                   | (buf.st_mode & S_IXGRP) |
                   (buf.st_mode & S_IXOTH)
 # endif
@@ -342,7 +364,6 @@ osd_executableFileExists (/*@unused@*/ char *filespec)
 # endif
        }
     }
-
 # endif
   return (FALSE);
 
@@ -396,6 +417,7 @@ nextdir (d_char *current_dir, d_char *dir, size_t *len)
   if (**current_dir == '\0')
     {
       *len = 0;
+      *dir = NULL;
       return FALSE;
     }
 
@@ -431,8 +453,6 @@ nextdir (d_char *current_dir, d_char *dir, size_t *len)
 # endif
 }
 
-# ifndef NOLCL
-
 # ifdef WIN32
 extern /*@external@*/ int _flushall (void) /*@modifies fileSystem@*/ ;
 # endif
@@ -451,7 +471,6 @@ int osd_system (cstring cmd)
   res = system (cstring_toCharsSafe (cmd));
   return res;
 }
-# endif
 
 # ifndef unlink
 /* This should be defined by unistd.h */
@@ -460,6 +479,13 @@ extern /*@external@*/ int unlink (const char *) /*@modifies fileSystem@*/ ;
 /*@=redecl@*/
 # endif
 
+static s_tempError = FALSE;
+
+void osd_setTempError (void)
+{
+  s_tempError = TRUE;
+}
+
 int osd_unlink (cstring fname)
 {
   int res;
@@ -468,9 +494,12 @@ int osd_unlink (cstring fname)
 
   if (res != 0)
     {
-      llcontbug (message ("Cannot remove temporary file: %s (%s)",
-                         fname,
-                         cstring_fromChars (strerror (errno))));
+      if (!s_tempError)
+       {
+         llcontbug (message ("Cannot remove temporary file: %s (%s)",
+                             fname,
+                             cstring_fromChars (strerror (errno))));
+       }
     }
   
   return res;
@@ -535,7 +564,7 @@ cstring osd_fixDefine (cstring x)
 
 bool osd_fileIsReadable (cstring f)
 {
-  FILE *fl = fileTable_openFile (context_fileTable (), f, "r");
+  FILE *fl = fileTable_openReadFile (context_fileTable (), f);
 
   if (fl != NULL)
     {
@@ -742,6 +771,20 @@ osd_dirAbsolute (char *str)
   char *ret = NULL;
   size_t size = PATH_MAX * sizeof (*ret);
   
+  DPRINTF (("Absolute for: %s", str));
+
+# if defined (WIN32) || defined (OS2) || defined (MSDOS)
+  if (strlen (str) > 1 && str[1] == ':')
+    {
+      /*
+      ** Its a drive letter
+      */
+      
+      ret = dmalloc ((strlen (str) + 1) * sizeof (*ret));
+      strcpy (ret, str);
+    }
+  else
+# endif
   if (osd_isConnectChar (str[0]))
     {
       ret = dmalloc ((strlen (str) + 1) * sizeof (*ret));
@@ -815,7 +858,7 @@ static /*@only@*/ cstring osd_cwd = cstring_undefined;
 
 static void osd_setWorkingDirectory (void)
 {
-# ifdef UNIX
+# if defined (UNIX) || defined (OS2)
   char *buf = dmalloc (sizeof (*buf) * MAXPATHLEN);
   char *cwd = getcwd (buf, MAXPATHLEN);
 
@@ -825,6 +868,7 @@ static void osd_setWorkingDirectory (void)
     {
       lldiagmsg (message ("Cannot get working directory: %s\n",
                          lldecodeerror (errno)));
+      osd_cwd = cstring_makeLiteral ("<missing directory>");
     }
   else
     {
@@ -842,9 +886,15 @@ void osd_initMod (void)
   osd_setWorkingDirectory ();
 }
 
+void osd_destroyMod (void)
+{
+  cstring_free (osd_cwd);
+  osd_cwd = cstring_undefined;
+}
+
 cstring osd_absolutePath (cstring cwd, cstring filename)
 {
-# ifdef UNIX
+# if defined (UNIX) || defined (OS2)
   /* Setup the current working directory as needed.  */
   cstring cwd2 = cstring_isDefined (cwd) ? cwd : osd_cwd;
   char *abs_buffer;
@@ -854,7 +904,7 @@ cstring osd_absolutePath (cstring cwd, cstring filename)
   llassert (cstring_isDefined (cwd2));
   llassert (cstring_isDefined (filename));
 
-  abs_buffer = (char *) dmalloc (size_fromInt (cstring_length (cwd2) + cstring_length (filename) + 2));
+  abs_buffer = (char *) dmalloc (cstring_length (cwd2) + cstring_length (filename) + 2);
   endp = abs_buffer;
   
   /*
@@ -865,7 +915,11 @@ cstring osd_absolutePath (cstring cwd, cstring filename)
   {
     const char *src_p;
 
-    if (filename[0] != '/')
+    if (!osd_isConnectChar (filename[0])
+# ifdef OS2
+       && !(isalpha (filename[0]) && filename[1] == ':')
+# endif
+       )
       {
         src_p = cwd2;
 
@@ -874,7 +928,7 @@ cstring osd_absolutePath (cstring cwd, cstring filename)
            continue;
          }
 
-        *(endp-1) = '/';                        /* overwrite null */
+        *(endp-1) = CONNECTCHAR;                        /* overwrite null */
       }
 
     src_p = filename;
@@ -900,29 +954,29 @@ cstring osd_absolutePath (cstring cwd, cstring filename)
        {
          break;
        }
-      else if (inp[0] == '/' && outp[-1] == '/')
+      else if (osd_isConnectChar (inp[0]) && osd_isConnectChar (outp[-1]))
        {
          inp++;
          continue;
        }
-      else if (inp[0] == '.' && outp[-1] == '/')
+      else if (inp[0] == '.' && osd_isConnectChar (outp[-1]))
        {
          if (inp[1] == '\0')
            {
              break;
            }
-         else if (inp[1] == '/')
+         else if (osd_isConnectChar (inp[1]))
            {
              inp += 2;
              continue;
            }
          else if ((inp[1] == '.') 
-                  && (inp[2] == '\0' || inp[2] == '/'))
+                  && (inp[2] == '\0' || osd_isConnectChar (inp[2])))
            {
-             inp += (inp[2] == '/') ? 3 : 2;
+             inp += (osd_isConnectChar (inp[2])) ? 3 : 2;
              outp -= 2;
        
-             while (outp >= abs_buffer && *outp != '/')
+             while (outp >= abs_buffer && !osd_isConnectChar (*outp))
                {
                  outp--;
                }
@@ -956,12 +1010,13 @@ cstring osd_absolutePath (cstring cwd, cstring filename)
      the last character of the returned string is *not* a slash.  */
   
   *outp = '\0';
-  if (outp[-1] == '/')
+  if (osd_isConnectChar (outp[-1]))
     *--outp  = '\0';
   
   /*@noaccess cstring@*/
   return cstring_fromChars (abs_buffer);
 # else
+  DPRINTF (("Here: %s", filename));
   return cstring_copy (filename);
 # endif
 }
@@ -976,21 +1031,34 @@ cstring osd_absolutePath (cstring cwd, cstring filename)
 ** is longer, then the full absolute filename is returned.
 **
 ** KNOWN BUG:   subpart of the original filename is actually a symbolic link.  
+**
+** this is really horrible code...surely someone has written a less buggy version of this!
 */
 
 cstring osd_outputPath (cstring filename)
 {
-# ifdef UNIX
+  /*@i2534 fix this junky code once and for all! */
+# if defined (UNIX) || defined (OS2)
   char *rel_buffer;
   char *rel_buf_p;
   cstring cwd_p = osd_cwd;
   char *path_p;
   int unmatched_slash_count = 0;
-  size_t filename_len = size_fromInt (cstring_length (filename));
+  size_t filename_len = cstring_length (filename);
   
+  llassertretval (filename_len > 0, filename);
+
   /*@access cstring@*/
   path_p = filename;
-  rel_buf_p = rel_buffer = (char *) dmalloc (filename_len);
+  rel_buffer = (char *) dmalloc (filename_len);
+  rel_buf_p = rel_buffer;
+  *rel_buf_p = '\0';
+
+  if (cwd_p == NULL) 
+    {
+      /* Need to prevent recursive assertion failures */
+      return cstring_copy (filename);
+    }
 
   llassert (cwd_p != NULL);
   llassert (path_p != NULL);
@@ -1001,23 +1069,38 @@ cstring osd_outputPath (cstring filename)
       path_p++;
     }
   
-  if ((*cwd_p == '\0') && (*path_p == '\0' || *path_p == '/'))  /* whole pwd matched */
+  if ((*cwd_p == '\0') && (*path_p == '\0' || osd_isConnectChar (*path_p)))  /* whole pwd matched */
     {
       if (*path_p == '\0')             /* input *is* the current path! */
-       return cstring_makeLiteral (".");
+       {
+         cstring_free (rel_buffer);
+         return cstring_makeLiteral (".");
+       }
       else
        {
-         /*@i324 ! lclint didn't report an errors for: return ++path_p; */
-         return cstring_fromCharsNew (++path_p);
+         /*@i324 ! splint didn't report an errors for: return ++path_p; */
+         cstring_free (rel_buffer);
+         return cstring_fromCharsNew (path_p + 1);
        }
     }
   else
     {
+
+      /* drl   2002-10/14 I had to put this code back*/
+      /* the case that needs it is when splint is given an absolute path name of a file outside of the current directory and the subdirectories below the current directory. e.g. cd /home/; splint /tmp/prog.c
+       */
+      
+      /* evans 2002-02-05 This is horrible code, which I've removed.  I couldn't find any
+      ** test cases that need it, so I hope I'm not breaking anything.
+      */
+      /*#if 0*/
+
       if (*path_p != '\0')
         {
           --cwd_p;
           --path_p;
-          while (*cwd_p != '/')         /* backup to last slash */
+
+          while (cwd_p >= osd_cwd && !osd_isConnectChar (*cwd_p)) /* backup to last slash */
             {
               --cwd_p;
               --path_p;
@@ -1026,11 +1109,11 @@ cstring osd_outputPath (cstring filename)
           path_p++;
           unmatched_slash_count++;
         }
-      
+
       /* Find out how many directory levels in cwd were *not* matched.  */
       while (*cwd_p != '\0')
        {
-         if (*cwd_p++ == '/')
+         if (osd_isConnectChar (*cwd_p++))
            unmatched_slash_count++;
        }
       
@@ -1038,22 +1121,28 @@ cstring osd_outputPath (cstring filename)
          Reject it if longer than the input.  */
       if (unmatched_slash_count * 3 + strlen (path_p) >= filename_len)
        {
+         cstring_free (rel_buffer);
+         /* fprintf (stderr, "Returning filename: %s [%p]\n", filename); */
          return cstring_copy (filename);
        }
-      
-      /*
-      ** evans 2001-10-15
-      ** I'm trusting the code on this one...don't see how this is guaranteed though.
-      */
-
-      assertSet (rel_buffer);
 
+      /*drl 10-14-2002 end previously removed code */
+      /*#endif*/
       /* For each of them, put a `../' at the beginning of the short name.  */
       while (unmatched_slash_count-- > 0)
         {
           /* Give up if the result gets to be longer
              than the absolute path name.  */
-          if (rel_buffer + filename_len <= rel_buf_p + 3)
+         char * temp_rel_buf_p;
+
+         /*drl This comment is necessary because for some reason Splint
+           does not realize that the pasts where rel_buf_p is released
+           do not reach here*/
+         /*@-usereleased@*/
+         temp_rel_buf_p = rel_buf_p;
+         /*@-usereleased@*/
+         
+          if (rel_buffer + filename_len <= temp_rel_buf_p + 3)
            {
              sfree (rel_buffer);
              return cstring_copy (filename);
@@ -1061,10 +1150,11 @@ cstring osd_outputPath (cstring filename)
 
           *rel_buf_p++ = '.';
           *rel_buf_p++ = '.';
-          *rel_buf_p++ = '/';
+          *rel_buf_p++ = CONNECTCHAR;
         }
       
       /* Then tack on the unmatched part of the desired file's name.  */
+
       do
         {
           if (rel_buffer + filename_len <= rel_buf_p)
@@ -1072,13 +1162,17 @@ cstring osd_outputPath (cstring filename)
              cstring_free (rel_buffer);
              return cstring_copy (filename);
            }
-        }
+        } /*@-usereleased@*/
       while ((*rel_buf_p++ = *path_p++) != '\0') ;
+
       
+      /*@=usereleased@*/ /*@i523! shouldn't need these */
       --rel_buf_p;
-      if (*(rel_buf_p-1) == '/')
+
+      if (osd_isConnectChar (*(rel_buf_p-1)))
         *--rel_buf_p = '\0';
 
+      /* fprintf (stderr, "Returning buffer: %s [%p]\n", rel_buffer, rel_buffer); */
       return rel_buffer;
     }
   /*@noaccess cstring@*/
@@ -1087,5 +1181,14 @@ cstring osd_outputPath (cstring filename)
 # endif
 }
 
+cstring osd_getCurrentDirectory ()
+{
+# if defined(MSDOS) || defined(OS2)
+  return cstring_makeLiteralTemp ("");
+# else
+  return cstring_makeLiteralTemp ("./");
+# endif
+}
+
 
 
This page took 0.065033 seconds and 4 git commands to generate.