]> andersk Git - splint.git/blobdiff - src/osd.c
Fixed preds.expect for name change.
[splint.git] / src / osd.c
index 8dc548238255023e4527440bde3af1212ffaade7..6f68ed2323f395f49083822abd226d6d581367fc 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-2002 University of Virginia,
 **         Massachusetts Institute of Technology
 **
 ** This program is free software; you can redistribute it and/or modify it
@@ -19,7 +19,7 @@
 **
 ** 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
 */
 /*
 ** osd.c
@@ -294,11 +294,11 @@ osd_fileExists (cstring filespec)
   return (stat (cstring_toCharsSafe (filespec), &buf) == 0);
 # else
 # if defined (WIN32) || defined (OS2)
-  FILE *test = fopen (cstring_toCharsSafe (filespec), "r");
+  FILE *test = fileTable_openFile (context_fileTable (), filespec, "r");
   
   if (test != NULL) 
     {
-      (void) fclose (test);
+      (void) fileTable_closeFile (context_fileTable (),test);
       return TRUE;
     } 
   else
@@ -535,11 +535,11 @@ cstring osd_fixDefine (cstring x)
 
 bool osd_fileIsReadable (cstring f)
 {
-  FILE *fl = fopen (cstring_toCharsSafe (f), "r");
+  FILE *fl = fileTable_openFile (context_fileTable (), f, "r");
 
-  if (fl != (FILE *) 0)
+  if (fl != NULL)
     {
-      check (fclose (fl) == 0);
+      check (fileTable_closeFile (context_fileTable (), fl));
       return (TRUE);
     }
   else
@@ -648,3 +648,454 @@ bool osd_equalCanonicalPrefix (cstring dirpath, cstring prefixpath)
 # endif
 }
 
+# if 0
+/*
+** This code provided by Herbert Martin Dietze, to canonicalize path names.
+*/
+
+char *osd_getcwd (/*@returned@*/ char *str, size_t size)
+{ 
+  return getcwd (str, size);
+}
+
+/*@null@*/ /*@observer@*/ char *
+osd_dirNext (char *str)
+{
+  char *p1 = strchr (str, '/');
+  char *p2 = strchr (str, '\\');
+
+  if (p1 == NULL)
+    {
+      if (p2 != NULL)
+       {
+         return p2 + 1;
+       }
+      else
+       {
+         return NULL;
+       }
+    }
+  else if (p2 == NULL)
+    {
+      return p1 + 1;
+    }
+  else /* both not null */
+    {
+      return (p1 < p2 ? p1 : p2) + 1;
+    }
+}
+
+static void 
+osd_dirShift (char *str, size_t num) /*@modifies str@*/
+{
+  int i;
+  
+  assert (num <= strlen (str));
+  
+  for (i = 0; str[i] != '\0'; i++)
+    {
+      str[i] = str[i + num];
+    }
+}
+
+bool
+osd_dirDotdot (char *str)
+{
+  return str[0] == '.' && str[1] == '.' && osd_isConnectChar (str[2]);
+}
+
+void
+osd_dirNormalize (char *str)
+{
+  char *pos1, *pos2;
+
+  for (; osd_isConnectChar (str[0]); str++)
+    {
+    }
+
+  for (; str != NULL && osd_dirDotdot (str); str = osd_dirNext (str))
+    {
+    }
+
+  for (pos1 = pos2 = str; 
+       pos1 != NULL; 
+       pos2 = pos1, pos1 = osd_dirNext (pos1))
+    {
+      /* remove redundant `./' entry */
+      while (pos1[0] == '.' && osd_isConnectChar (pos1[1]))
+        {
+          osd_dirShift (pos1, 2);
+        }
+
+      /* remove redundant `foo/../' entry */
+      if (osd_dirDotdot (pos1) && pos2 < pos1)
+        {
+          osd_dirShift (pos2, pos1 - pos2 + 1);
+          osd_dirNormalize (str);
+        }
+    }
+}
+
+/*@null@*/ char *
+osd_dirAbsolute (char *str)
+{
+  char *ret = NULL;
+  size_t size = PATH_MAX * sizeof (*ret);
+  
+  if (osd_isConnectChar (str[0]))
+    {
+      ret = dmalloc ((strlen (str) + 1) * sizeof (*ret));
+      strcpy (ret, str);
+    }
+  else
+    {
+      ret = dmalloc (size);
+      
+      ret = osd_getcwd (ret, size);
+      ret = realloc (ret, (strlen (str) + strlen (ret) + 2) * sizeof (*ret));
+
+      if (ret == NULL)
+        {
+          return NULL;
+        }
+
+      strcat (ret, CONNECTSTR);
+      strcat (ret, str);
+    }
+  
+  osd_dirNormalize (ret);
+  return ret;
+}
+
+# endif
+
+/*
+** absolute paths
+**
+** This code is adapted from:
+**
+** http://src.openresources.com/debian/src/devel/HTML/S/altgcc_2.7.2.2.orig%20altgcc-2.7.2.2.orig%20protoize.c.html#1297
+**
+**
+**  Protoize program - Original version by Ron Guilmette (rfg@segfault.us.com).
+**   Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+**
+** This file is part of GNU CC.
+**
+** GNU CC is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2, or (at your option)
+** any later version.
+**
+** GNU CC is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+** 
+** You should have received a copy of the GNU General Public License
+** along with GNU CC; see the file COPYING.  If not, write to
+** the Free Software Foundation, 59 Temple Place - Suite 330,
+** Boston, MA 02111-1307, USA.  
+*/
+
+/* 
+** Return the absolutized filename for the given relative
+** filename.  Note that if that filename is already absolute, it may
+** still be returned in a modified form because this routine also
+** eliminates redundant slashes and single dots and eliminates double
+** dots to get a shortest possible filename from the given input
+** filename.  The absolutization of relative filenames is made by
+** assuming that the given filename is to be taken as relative to
+** the first argument (cwd) or to the current directory if cwd is
+** NULL.  
+*/
+
+/* A pointer to the current directory filename (used by abspath).  */
+static /*@only@*/ cstring osd_cwd = cstring_undefined;
+
+static void osd_setWorkingDirectory (void)
+{
+# ifdef UNIX
+  char *buf = dmalloc (sizeof (*buf) * MAXPATHLEN);
+  char *cwd = getcwd (buf, MAXPATHLEN);
+
+  llassert (cstring_isUndefined (osd_cwd));
+
+  if (cwd == NULL)
+    {
+      lldiagmsg (message ("Cannot get working directory: %s\n",
+                         lldecodeerror (errno)));
+    }
+  else
+    {
+      osd_cwd = cstring_fromCharsNew (cwd);
+    }
+
+  sfree (buf);
+# else
+  ; /* Don't know how to do this for non-POSIX platforms */
+# endif
+}
+
+void osd_initMod (void)
+{
+  osd_setWorkingDirectory ();
+}
+
+cstring osd_absolutePath (cstring cwd, cstring filename)
+{
+# ifdef UNIX
+  /* Setup the current working directory as needed.  */
+  cstring cwd2 = cstring_isDefined (cwd) ? cwd : osd_cwd;
+  char *abs_buffer;
+  char *endp, *outp, *inp;
+
+  /*@access cstring@*/
+  llassert (cstring_isDefined (cwd2));
+  llassert (cstring_isDefined (filename));
+
+  abs_buffer = (char *) dmalloc (size_fromInt (cstring_length (cwd2) + cstring_length (filename) + 2));
+  endp = abs_buffer;
+  
+  /*
+  ** Copy the  filename (possibly preceded by the current working
+  ** directory name) into the absolutization buffer.  
+  */
+  
+  {
+    const char *src_p;
+
+    if (filename[0] != '/')
+      {
+        src_p = cwd2;
+
+        while ((*endp++ = *src_p++) != '\0') 
+         {
+           continue;
+         }
+
+        *(endp-1) = '/';                        /* overwrite null */
+      }
+
+    src_p = filename;
+
+    while ((*endp++ = *src_p++) != '\0')
+      {
+       continue;
+      }
+  }
+  
+  /* Now make a copy of abs_buffer into abs_buffer, shortening the
+     filename (by taking out slashes and dots) as we go.  */
+  
+  outp = inp = abs_buffer;
+  *outp++ = *inp++;             /* copy first slash */
+#ifdef apollo
+  if (inp[0] == '/')
+    *outp++ = *inp++;           /* copy second slash */
+#endif
+  for (;;)
+    {
+      if (inp[0] == '\0')
+       {
+         break;
+       }
+      else if (inp[0] == '/' && outp[-1] == '/')
+       {
+         inp++;
+         continue;
+       }
+      else if (inp[0] == '.' && outp[-1] == '/')
+       {
+         if (inp[1] == '\0')
+           {
+             break;
+           }
+         else if (inp[1] == '/')
+           {
+             inp += 2;
+             continue;
+           }
+         else if ((inp[1] == '.') 
+                  && (inp[2] == '\0' || inp[2] == '/'))
+           {
+             inp += (inp[2] == '/') ? 3 : 2;
+             outp -= 2;
+       
+             while (outp >= abs_buffer && *outp != '/')
+               {
+                 outp--;
+               }
+
+             if (outp < abs_buffer)
+               {
+                 /* Catch cases like /.. where we try to backup to a
+                     point above the absolute root of the logical file
+                     system.  */
+                 
+                 llfatalbug (message ("Invalid file name: %s", filename));
+               }
+
+             *++outp = '\0';
+             continue;
+           }
+         else
+           {
+             ;
+           }
+       }
+      else
+       {
+         ;
+       }
+
+      *outp++ = *inp++;
+    }
+  
+  /* On exit, make sure that there is a trailing null, and make sure that
+     the last character of the returned string is *not* a slash.  */
+  
+  *outp = '\0';
+  if (outp[-1] == '/')
+    *--outp  = '\0';
+  
+  /*@noaccess cstring@*/
+  return cstring_fromChars (abs_buffer);
+# else
+  return cstring_copy (filename);
+# endif
+}
+
+/* 
+** Given a filename (and possibly a directory name from which the filename
+** is relative) return a string which is the shortest possible
+** equivalent for the corresponding full (absolutized) filename.  The
+** shortest possible equivalent may be constructed by converting the
+** absolutized filename to be a relative filename (i.e. relative to
+** the actual current working directory).  However if a relative filename
+** is longer, then the full absolute filename is returned.
+**
+** KNOWN BUG:   subpart of the original filename is actually a symbolic link.  
+*/
+
+cstring osd_outputPath (cstring filename)
+{
+# ifdef UNIX
+  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));
+  
+  /*@access cstring@*/
+  path_p = filename;
+  rel_buf_p = rel_buffer = (char *) dmalloc (filename_len);
+
+  llassert (cwd_p != NULL);
+  llassert (path_p != NULL);
+
+  while ((*cwd_p != '\0') && (*cwd_p == *path_p))
+    {
+      cwd_p++;
+      path_p++;
+    }
+  
+  if ((*cwd_p == '\0') && (*path_p == '\0' || *path_p == '/'))  /* whole pwd matched */
+    {
+      if (*path_p == '\0')             /* input *is* the current path! */
+       return cstring_makeLiteral (".");
+      else
+       {
+         /*@i324 ! lclint didn't report an errors for: return ++path_p; */
+         return cstring_fromCharsNew (++path_p);
+       }
+    }
+  else
+    {
+      if (*path_p != '\0')
+        {
+          --cwd_p;
+          --path_p;
+          while (*cwd_p != '/')         /* backup to last slash */
+            {
+              --cwd_p;
+              --path_p;
+            }
+          cwd_p++;
+          path_p++;
+          unmatched_slash_count++;
+        }
+      
+      /* Find out how many directory levels in cwd were *not* matched.  */
+      while (*cwd_p != '\0')
+       {
+         if (*cwd_p++ == '/')
+           unmatched_slash_count++;
+       }
+      
+      /* Now we know how long the "short name" will be.
+         Reject it if longer than the input.  */
+      if (unmatched_slash_count * 3 + strlen (path_p) >= filename_len)
+       {
+         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);
+
+      /* 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)
+           {
+             sfree (rel_buffer);
+             return cstring_copy (filename);
+           }
+
+          *rel_buf_p++ = '.';
+          *rel_buf_p++ = '.';
+          *rel_buf_p++ = '/';
+        }
+      
+      /* Then tack on the unmatched part of the desired file's name.  */
+      do
+        {
+          if (rel_buffer + filename_len <= rel_buf_p)
+           {
+             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) == '/')
+        *--rel_buf_p = '\0';
+
+      return rel_buffer;
+    }
+  /*@noaccess cstring@*/
+# else
+  return cstring_copy (filename);
+# endif
+}
+
+cstring osd_getCurrentDirectory ()
+{
+# if defined(MSDOS) || defined(OS2)
+  return cstring_makeLiteralTemp ("");
+# else
+  return cstring_makeLiteralTemp ("./");
+# endif
+}
+
+
+
This page took 0.135892 seconds and 4 git commands to generate.