]> andersk Git - splint.git/blobdiff - src/fileTable.c
Making fixes for Microsoft Visual C++ compiler.
[splint.git] / src / fileTable.c
index 0edbab562c80615b8b98b319c4895ec670dcfbb2..ffec6d2530f2585641b2cc238e40cfc264114a43 100644 (file)
@@ -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
 */
 /*
 ** fileTable.c
  * - Added conditional stuff (#define and #include) for IBM's compiler.
  */
 
-# include "lclintMacros.nf"
-# include "llbasic.h"
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <fcntl.h>
+# include "splintMacros.nf"
+# include "basic.h"
 # include "osd.h"
 # include "llmain.h"
 # include "portab.h"
+
+# ifdef WIN32
+# include <io.h>
+# else
 # if defined(__IBMC__) && defined(OS2)
 # include <process.h>
+# include <io.h>
 # define getpid _getpid
+# define S_IRUSR S_IREAD
+# define S_IWUSR S_IWRITE 
+# define S_IXUSR S_IEXEC
+# endif
 # endif
 
 /*@access fileId*/
 
+static void 
+fileTable_addOpen (fileTable p_ft, /*@observer@*/ FILE *p_f, /*@only@*/ cstring p_fname) 
+  /*@modifies p_ft@*/ ;
+
 static bool fileTable_inRange (fileTable ft, fileId fid) /*@*/ 
 {
   return (fileTable_isDefined (ft) && (fid >= 0) && (fid < ft->nentries));
@@ -85,8 +101,39 @@ fileType_unparse (fileType ft)
 static int
 fileTable_getIndex (fileTable ft, cstring s)
 {
+  int res;
+  cstring abspath;
   if (ft == NULL) return NOT_FOUND;
-  return (cstringTable_lookup (ft->htable, s));
+  abspath = osd_absolutePath (cstring_undefined, s);
+  
+  if (context_getFlag (FLG_CASEINSENSITIVEFILENAMES))
+    {
+      abspath = cstring_downcase (abspath);
+    }
+
+  DPRINTF (("Absolute path: %s: %s", s, abspath));
+  res = cstringTable_lookup (ft->htable, abspath);
+  cstring_free (abspath);
+  return res;
+}
+
+static cstring ftentry_unparse (fileTable ft, ftentry fte)
+{
+  if (fileId_isValid (fte->fder))
+    {
+      llassert (fileTable_isDefined (ft));
+
+      return message ("%s %q %d (%s)", 
+                     fte->fname, 
+                     fileType_unparse (fte->ftype),
+                     fte->fder,
+                     ft->elements[fte->fder]->fname);
+    }
+  else
+    {
+      return message ("%s %q", fte->fname,
+                     fileType_unparse (fte->ftype));
+    }
 }
 
 /*@only@*/ cstring
@@ -102,21 +149,8 @@ fileTable_unparse (fileTable ft)
 
   for (i = 0; i < ft->nentries; i++)
     {
-      if (fileId_isValid (ft->elements[i]->fder))
-       {
-         s = message ("%s\n[%d] %s %q %d (%s)", 
-                      s, i, 
-                      ft->elements[i]->fname, 
-                      fileType_unparse (ft->elements[i]->ftype),
-                      ft->elements[i]->fder,
-                      ft->elements[ft->elements[i]->fder]->fname);
-       }
-      else
-       {
-         s = message ("%s\n[%d] %s %q", s, i, ft->elements[i]->fname,
-                      fileType_unparse (ft->elements[i]->ftype));
-       }
-          }
+      s = message ("%s\n[%d] %q", s, i, ftentry_unparse (ft, ft->elements[i]));
+    }
 
   return s;
 }
@@ -162,7 +196,6 @@ ftentry_create (/*@keep@*/ cstring tn, bool temp, fileType typ, fileId der)
     }
   
   t->fname = tn;
-  
   t->basename = cstring_undefined;
   t->ftemp = temp;
   t->ftype = typ;
@@ -192,10 +225,15 @@ fileTable_create ()
   ft->nspace = FTBASESIZE;
   ft->elements = (ftentry *) dmalloc (FTBASESIZE * sizeof (*ft->elements));
   ft->htable = cstringTable_create (FTHASHSIZE);
-  
+
+  ft->nopen = 0;
+  ft->nopenspace = FTBASESIZE;
+  ft->openelements = (foentry *) dmalloc (FTBASESIZE * sizeof (*ft->openelements));
+
   return (ft);
 }
 
+/*@-bounds@*/
 static void
 fileTable_grow (fileTable ft)
 {
@@ -216,6 +254,27 @@ fileTable_grow (fileTable ft)
   sfree (ft->elements);
   ft->elements = newent;
 }
+/*@=bounds@*/
+static void
+fileTable_growOpen (fileTable ft)
+{
+  int i;
+  foentry *newent;
+
+  llassert (fileTable_isDefined (ft));
+
+  ft->nopenspace = FTBASESIZE;
+
+  newent = (foentry *) dmalloc ((ft->nopen + ft->nopenspace) * sizeof (*newent));
+  
+  for (i = 0; i < ft->nopen; i++)
+    {
+      newent[i] = ft->openelements[i];
+    }
+
+  sfree (ft->openelements);
+  ft->openelements = newent;
+}
 
 static fileId
 fileTable_internAddEntry (fileTable ft, /*@only@*/ ftentry e)
@@ -227,7 +286,23 @@ fileTable_internAddEntry (fileTable ft, /*@only@*/ ftentry e)
 
   ft->nspace--;
 
-  cstringTable_insert (ft->htable, e->fname, ft->nentries);
+  DPRINTF (("Adding: %s", e->fname));
+
+  if (context_getFlag (FLG_CASEINSENSITIVEFILENAMES))
+    {
+      cstring sd = cstring_downcase (e->fname);
+      cstringTable_insert (ft->htable, sd, ft->nentries);
+    }
+  else
+    {
+      cstringTable_insert (ft->htable, cstring_copy (e->fname), ft->nentries); 
+    }
+
+  /* evans 2002-07-12:
+     Before, there was no cstring_copy above, and e->fname was free'd in the if branch.
+     Splint should have caught this, and produced a warning for this assignment.
+     Why not?
+  */
   ft->elements[ft->nentries] = e;
 
   ft->nentries++;
@@ -238,46 +313,60 @@ void fileTable_noDelete (fileTable ft, cstring name)
 {
   fileId fid = fileTable_lookup (ft, name);
 
-  if (fileId_isValid (fid)) {
-    llassert (fileTable_isDefined (ft));
-
-    ft->elements[fid]->ftype = FILE_NODELETE;
-  }
+  if (fileId_isValid (fid)) 
+    {
+      llassert (fileTable_isDefined (ft));
+      ft->elements[fid]->ftype = FILE_NODELETE;
+    }
+  else
+    {
+      DPRINTF (("Invalid no delete: %s", name));
+    }
 }
 
 static fileId
-fileTable_addFilePrim (fileTable ft, /*@only@*/ cstring name, 
+fileTable_addFilePrim (fileTable ft, /*@temp@*/ cstring name, 
                       bool temp, fileType typ, fileId der)
    /*@modifies ft@*/
 {
-  int tindex = fileTable_getIndex (ft, name);
-
+  cstring absname = osd_absolutePath (NULL, name);
+  int tindex = fileTable_getIndex (ft, absname);
+  
   llassert (ft != fileTable_undefined);
 
   if (tindex != NOT_FOUND)
     {
-      llcontbug (message ("fileTable_addFilePrim: duplicate entry: %q", name));
-
+      llcontbug (message ("fileTable_addFilePrim: duplicate entry: %q", absname));
       return tindex;
     }
   else
     {
-      ftentry e = ftentry_create (name, temp, typ, der);
+      ftentry e = ftentry_create (absname, temp, typ, der);
 
       if (der == fileId_invalid)
        {
          llassert (cstring_isUndefined (e->basename));
 
-         e->basename = fileLib_removePathFree (fileLib_removeAnyExtension (name));
-         e->fsystem = context_isSystemDir (name);
-         e->fspecial = context_isSpecialFile (name);
+         e->basename = fileLib_removePathFree (fileLib_removeAnyExtension (absname));
+         e->fsystem = context_isSystemDir (absname);
+
+         /*
+         ** evans 2002-03-15: change suggested by Jim Zelenka
+         **                   support relative paths for system directories
+         */
+
+         if (!e->fsystem)
+           {
+             e->fsystem = context_isSystemDir (name);
+           }
+
+         e->fspecial = context_isSpecialFile (absname);
 
          if (e->fspecial)
            {
-             cstring srcname = cstring_concatFree1 (fileLib_removeAnyExtension (name), 
+             cstring srcname = cstring_concatFree1 (fileLib_removeAnyExtension (absname), 
                                                     C_EXTENSION);
              fileId fid = fileTable_lookup (ft, srcname);
-
              cstring_free (srcname);
 
              if (fileId_isValid (fid))
@@ -310,29 +399,32 @@ fileTable_addFilePrim (fileTable ft, /*@only@*/ cstring name,
 fileId
 fileTable_addFile (fileTable ft, cstring name)
 {
-  /* while (*name == '.' && *(name + 1) == '/') name += 2; */
-
-  return (fileTable_addFilePrim (ft, cstring_copy (name), 
-                                FALSE, FILE_NORMAL, fileId_invalid));
+  return (fileTable_addFilePrim (ft, name, FALSE, FILE_NORMAL, fileId_invalid));
 }
 
 fileId
 fileTable_addFileOnly (fileTable ft, /*@only@*/ cstring name)
 {
-  return (fileTable_addFilePrim (ft, name, FALSE, FILE_NORMAL, fileId_invalid));
+  fileId res = fileTable_addFilePrim (ft, name, FALSE, FILE_NORMAL, fileId_invalid);
+  cstring_free (name);
+  return res;
 }
 
 fileId
 fileTable_addHeaderFile (fileTable ft, cstring name)
 {
   fileId res;
-
-  res = fileTable_addFilePrim (ft, cstring_copy (name), FALSE, 
-                              FILE_HEADER, fileId_invalid);
+  res = fileTable_addFilePrim (ft, name, FALSE, FILE_HEADER, fileId_invalid);
   return res;
 
 }
 
+void
+fileTable_addStreamFile (fileTable ft, FILE *fstream, cstring name)
+{
+  fileTable_addOpen (ft, fstream, cstring_copy (name));
+}
+
 bool
 fileTable_isHeader (fileTable ft, fileId fid)
 {
@@ -365,8 +457,15 @@ fileTable_isXHFile (fileTable ft, fileId fid)
       return FALSE;
     }
 
-  llassert (fileTable_isDefined (ft) && fileTable_inRange (ft, fid));
-  return (ft->elements[fid]->ftype == FILE_XH);
+  if (!(fileTable_isDefined (ft) && fileTable_inRange (ft, fid)))
+    {
+      llcontbug (message ("Bad file table or id: %s %d", bool_unparse (fileTable_isDefined (ft)), fid));
+      return FALSE;
+    }
+  else
+    {
+      return (ft->elements[fid]->ftype == FILE_XH);
+    }
 }
 
 bool
@@ -376,7 +475,7 @@ fileTable_isSpecialFile (fileTable ft, fileId fid)
     {
       return FALSE;
     }
-
+  
   llassert (fileTable_isDefined (ft) && fileTable_inRange (ft, fid));
   return (ft->elements[fid]->fspecial);
 }
@@ -384,36 +483,28 @@ fileTable_isSpecialFile (fileTable ft, fileId fid)
 fileId
 fileTable_addLibraryFile (fileTable ft, cstring name)
 {
-  return (fileTable_addFilePrim (ft, cstring_copy (name),
-                                FALSE, FILE_HEADER, fileId_invalid));
+  return (fileTable_addFilePrim (ft, name, FALSE, FILE_HEADER, fileId_invalid));
 }
 
 fileId
 fileTable_addXHFile (fileTable ft, cstring name)
 {
-  return (fileTable_addFilePrim (ft, cstring_copy (name),
-                                FALSE, FILE_XH, fileId_invalid));
+  return (fileTable_addFilePrim (ft, name, FALSE, FILE_XH, fileId_invalid));
 }
 
-# ifndef NOLCL
 fileId
 fileTable_addImportFile (fileTable ft, cstring name)
 {
-  return (fileTable_addFilePrim (ft, cstring_copy (name), 
-                                FALSE, FILE_HEADER, fileId_invalid));
+  return (fileTable_addFilePrim (ft, name, FALSE, FILE_HEADER, fileId_invalid));
 }
 
 fileId
 fileTable_addLCLFile (fileTable ft, cstring name)
 {
-  return (fileTable_addFilePrim (ft, cstring_copy (name), 
-                                FALSE, FILE_HEADER, fileId_invalid));
+  return (fileTable_addFilePrim (ft, name, FALSE, FILE_HEADER, fileId_invalid));
 }
-# endif
 
-# ifndef NOLCL
 static int tmpcounter = 0;
-# endif
 
 fileId
 fileTable_addMacrosFile (fileTable ft)
@@ -421,28 +512,27 @@ fileTable_addMacrosFile (fileTable ft)
   cstring newname =
     makeTempName (context_tmpdir (), cstring_makeLiteralTemp ("lmx"),
                  cstring_makeLiteralTemp (".llm"));
-
-  return (fileTable_addFilePrim (ft, newname, TRUE, FILE_MACROS, fileId_invalid));
+  fileId res = fileTable_addFilePrim (ft, newname, TRUE, FILE_MACROS, fileId_invalid);
+  cstring_free (newname);
+  return res;
 }
 
 fileId
 fileTable_addMetastateFile (fileTable ft, cstring name)
 {
-  return (fileTable_addFilePrim (ft, cstring_copy (name), 
-                                FALSE, FILE_METASTATE, fileId_invalid));
+  return (fileTable_addFilePrim (ft, name, FALSE, FILE_METASTATE, fileId_invalid));
 }
 
 fileId
 fileTable_addCTempFile (fileTable ft, fileId fid)
 {
-# if FALSE
-  /* Can't control output file name for cl preprocessor */
-  cstring newname = cstring_concatChars (fileLib_removeAnyExtension (fileName (fid)), ".i");
-# else
   cstring newname =
     makeTempName (context_tmpdir (), cstring_makeLiteralTemp ("cl"), 
                  C_EXTENSION);
-# endif
+  fileId res;
+
+  DPRINTF (("tmp dir: %s", context_tmpdir ()));
+  DPRINTF (("new name: %s", newname));
 
   llassert (fileTable_isDefined (ft));
 
@@ -450,29 +540,32 @@ fileTable_addCTempFile (fileTable ft, fileId fid)
     {
       if (fileTable_isXHFile (ft, fid))
        {
-         return (fileTable_addFilePrim (ft, newname, TRUE, FILE_XH, fid));
+         res = fileTable_addFilePrim (ft, newname, TRUE, FILE_XH, fid);
        }
       else
        {
-         return (fileTable_addFilePrim (ft, newname, TRUE, FILE_NORMAL, fid));
+         res = fileTable_addFilePrim (ft, newname, TRUE, FILE_NORMAL, fid);
        }
     }
   else 
     {
       if (fileTable_isXHFile (ft, fid))
        {
-         return (fileTable_addFilePrim (ft, newname, TRUE, FILE_XH,
-                                        ft->elements[fid]->fder));
+         res = fileTable_addFilePrim (ft, newname, TRUE, FILE_XH,
+                                      ft->elements[fid]->fder);
        }
       else
        {
-         return (fileTable_addFilePrim (ft, newname, TRUE, FILE_NORMAL,
-                                        ft->elements[fid]->fder));
+         res = fileTable_addFilePrim (ft, newname, TRUE, FILE_NORMAL,
+                                      ft->elements[fid]->fder);
        }
     }
+
+  DPRINTF (("Added file: %s", fileTable_fileName (res)));
+  cstring_free (newname);
+  return res;
 }
 
-# ifndef NOLCL
 fileId
 fileTable_addltemp (fileTable ft)
 {
@@ -515,12 +608,10 @@ fileTable_addltemp (fileTable ft)
   ** since cstring is abstract.  Should make it an only?
   */
 
-  ret = fileTable_addFilePrim (ft, cstring_copy (newname),
-                              TRUE, FILE_LSLTEMP, fileId_invalid);
+  ret = fileTable_addFilePrim (ft, newname, TRUE, FILE_LSLTEMP, fileId_invalid);
   cstring_free (newname);
   return (ret);
 }
-# endif
 
 bool
 fileTable_exists (fileTable ft, cstring s)
@@ -528,9 +619,14 @@ fileTable_exists (fileTable ft, cstring s)
   int tindex = fileTable_getIndex (ft, s);
 
   if (tindex == NOT_FOUND)
-    return FALSE;
+    {
+      DPRINTF (("Not found: %s", s));
+      return FALSE;
+    }
   else
-    return TRUE;
+    {
+      return TRUE;
+    }
 }
 
 fileId
@@ -566,11 +662,21 @@ fileTable_setFilePath (fileTable ft, fileId fid, cstring path)
 fileId
 fileTable_lookupBase (fileTable ft, cstring base)
 {
-  int tindex = fileTable_getIndex (ft, base);
+  int tindex;
+
+  if (context_getFlag (FLG_CASEINSENSITIVEFILENAMES))
+    {
+      cstring dbase = cstring_downcase (base);
+      tindex = fileTable_getIndex (ft, dbase);
+      cstring_free (dbase);
+    }
+  else
+    {
+      tindex = fileTable_getIndex (ft, base);
+    }
 
   if (tindex == NOT_FOUND)
     {
-      
       return fileId_invalid;
     }
   else
@@ -703,8 +809,8 @@ fileTable_cleanup (fileTable ft)
 
   if (msg)
     {
-      (void) fflush (g_msgstream);
-      fprintf (stderr, "< cleaning");
+      (void) fflush (g_warningstream);
+      displayScanOpen (cstring_makeLiteral ("cleaning"));
     }
 
   for (i = 0; i < ft->nentries; i++)
@@ -718,6 +824,7 @@ fileTable_cleanup (fileTable ft)
          /*
           ** Make sure it is really a derived file
          */
+
          
          if (fe->ftype == FILE_LSLTEMP || fe->ftype == FILE_NODELETE)
            {
@@ -725,7 +832,7 @@ fileTable_cleanup (fileTable ft)
            }
          else if (fileId_isValid (fe->fder)) 
            {
-             /*@i423 this should use close (fd) also... */
+             /* this should use close (fd) also... */
              (void) osd_unlink (fe->fname);
            }
          else if (fe->ftype == FILE_MACROS)
@@ -745,21 +852,13 @@ fileTable_cleanup (fileTable ft)
 
       if (msg && ((i % skip) == 0))
        {
-         (void) fflush (g_msgstream);
-
-         if (i == 0) {
-           fprintf (stderr, " ");
-         } else {
-           fprintf (stderr, ".");
-         }
-
-         (void) fflush (stderr);
+         displayScanContinue (cstring_makeLiteral (i == 0 ? " " : "."));
        }
     }
-  
+
   if (msg)
     {
-      fprintf (stderr, " >\n");
+      displayScanClose ();
     }
 }
 
@@ -781,6 +880,7 @@ fileTable_free (/*@only@*/ fileTable f)
   
   cstringTable_free (f->htable);
   sfree (f->elements);
+  sfree (f->openelements); /*!! why didn't splint report this? */
   sfree (f);
 }
 
@@ -832,7 +932,7 @@ static /*@only@*/ cstring makeTempName (cstring dir, cstring pre, cstring suf)
   static int pid = 0; 
   static /*@owned@*/ char *msg = NULL; 
   static /*@only@*/ cstring pidname = NULL;
-  int maxlen;
+  size_t maxlen;
   cstring smsg;
 
   llassert (cstring_length (pre) <= 3);
@@ -864,16 +964,241 @@ static /*@only@*/ cstring makeTempName (cstring dir, cstring pre, cstring suf)
   maxlen = (cstring_length (dir) + cstring_length (pre) + mstring_length (msg) 
            + cstring_length (pidname) + cstring_length (suf) + 2);
 
+  DPRINTF (("Dir: %s / %s / %s / %s / %s",
+           dir, pre, pidname, msg, suf));
+
   smsg = message ("%s%s%s%s%s", dir, pre, pidname, cstring_fromChars (msg), suf);
   nextMsg (msg);
 
+  DPRINTF (("Trying: %s", smsg));
+
   while (osd_fileExists (smsg))
     {
       cstring_free (smsg);
       smsg = message ("%s%s%s%s%s", dir, pre, pidname, cstring_fromChars (msg), suf);
       nextMsg (msg);
     }
-  
 
   return smsg;
 }
+
+static foentry
+foentry_create (/*@exposed@*/ FILE *f, /*@only@*/ cstring fname)
+{
+  foentry t = (foentry) dmalloc (sizeof (*t));
+  t->f = f;
+  t->fname = fname;
+  return t;
+}
+
+static void 
+foentry_free (/*@only@*/ foentry foe)
+{
+  cstring_free (foe->fname);
+  sfree (foe);
+}
+
+static void 
+fileTable_addOpen (fileTable ft, /*@observer@*/ FILE *f, /*@only@*/ cstring fname)
+{
+  llassert (fileTable_isDefined (ft));
+
+  if (ft->nopenspace <= 0) 
+    {
+      fileTable_growOpen (ft);
+    }
+
+  ft->nopenspace--;
+  ft->openelements[ft->nopen] = foentry_create (f, fname);
+  ft->nopen++;
+}
+
+FILE *fileTable_createFile (fileTable ft, cstring fname)
+{
+# ifdef WIN32
+  int fdesc = _open (cstring_toCharsSafe (fname), 
+                    O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 
+                    _S_IWRITE | S_IREAD);
+# else
+   int fdesc = open (cstring_toCharsSafe (fname), 
+                    O_WRONLY | O_CREAT | O_TRUNC | O_EXCL,
+                    S_IRUSR | S_IWUSR);
+# endif
+
+  if (fdesc == -1)
+    {
+      osd_setTempError ();
+      llfatalerror (message ("Temporary file for "
+                            "pre-processor output already exists.  Trying to "
+                            "open: %s.",
+                            fname));
+
+      /*@notreached@*/ return NULL;
+    }
+  else
+    {
+      FILE *res = fdopen (fdesc, "w");
+  
+      if (res != NULL) 
+       {
+         fileTable_addOpen (ft, res, cstring_copy (fname));
+         DPRINTF (("Opening file: %s / %p", fname, res));
+       }
+      else
+       {
+         DPRINTF (("Error opening: %s", fname));
+       }
+
+      return res;
+    }
+}
+
+FILE *fileTable_createMacrosFile (fileTable ft, cstring fname)
+{
+# ifdef WIN32
+  int fdesc = _open (cstring_toCharsSafe (fname), 
+                    O_RDWR | O_CREAT | O_TRUNC | O_EXCL,
+                    _S_IREAD | _S_IWRITE);
+# else
+  int fdesc = open (cstring_toCharsSafe (fname), 
+                   O_RDWR | O_CREAT | O_TRUNC | O_EXCL, 
+                   S_IRUSR | S_IWUSR);
+# endif
+
+  if (fdesc == -1)
+    {
+      osd_setTempError ();
+      llfatalerror (message ("Temporary file for "
+                            "pre-processor output already exists.  Trying to "
+                            "open: %s.",
+                            fname));
+
+      /*@notreached@*/ return NULL;
+    }
+  else
+    {
+      FILE *res = fdopen (fdesc, "w+");
+  
+      if (res != NULL) 
+       {
+         fileTable_addOpen (ft, res, cstring_copy (fname));
+         DPRINTF (("Opening file: %s / %p", fname, res));
+       }
+      else
+       {
+         DPRINTF (("Error opening: %s", fname));
+       }
+
+      return res;
+    }
+}
+
+FILE *fileTable_openReadFile (fileTable ft, cstring fname)
+{
+  FILE *res = fopen (cstring_toCharsSafe (fname), "r");
+
+  if (res != NULL) 
+    {
+      fileTable_addOpen (ft, res, cstring_copy (fname));
+      DPRINTF (("Opening read file: %s / %p", fname, res));
+    }
+  else
+    {
+      DPRINTF (("Cannot open read file: %s", fname));
+    }
+
+  return res;
+}
+
+/*
+** Allows overwriting
+*/
+
+FILE *fileTable_openWriteFile (fileTable ft, cstring fname)
+{
+  FILE *res = fopen (cstring_toCharsSafe (fname), "w");
+
+  if (res != NULL) {
+    fileTable_addOpen (ft, res, cstring_copy (fname));
+    DPRINTF (("Opening file: %s / %p", fname, res));
+  }
+
+  return res;
+}
+
+FILE *fileTable_openWriteUpdateFile (fileTable ft, cstring fname)
+{
+  FILE *res = fopen (cstring_toCharsSafe (fname), "w+");
+
+  if (res != NULL) {
+    fileTable_addOpen (ft, res, cstring_copy (fname));
+    DPRINTF (("Opening file: %s / %p", fname, res));
+  }
+
+  return res;
+}
+
+bool fileTable_closeFile (fileTable ft, FILE *f)
+{
+  bool foundit = FALSE;
+  int i = 0;
+
+  llassert (fileTable_isDefined (ft));
+
+  DPRINTF (("Closing file: %p", f));
+
+  for (i = 0; i < ft->nopen; i++) 
+    {
+      if (ft->openelements[i]->f == f)
+       {
+         DPRINTF (("Closing file: %p = %s", f, ft->openelements[i]->fname));
+         
+         if (i == ft->nopen - 1)
+           {
+             foentry_free (ft->openelements[i]);
+             ft->openelements[i] = NULL;
+           }
+         else
+           {
+             foentry_free (ft->openelements[i]);
+             ft->openelements[i] = ft->openelements[ft->nopen - 1];
+             ft->openelements[ft->nopen - 1] = NULL;
+           }
+
+         ft->nopen--;
+         ft->nopenspace++;
+         foundit = TRUE;
+         break;
+       }
+    }
+  
+  llassert (foundit);
+  return (fclose (f) == 0);
+}
+
+void fileTable_closeAll (fileTable ft)
+{
+  int i = 0;
+
+  llassert (fileTable_isDefined (ft));
+
+  for (i = 0; i < ft->nopen; i++) 
+    {
+      /* 
+        lldiagmsg (message ("Unclosed file at exit: %s", ft->openelements[i]->fname)); 
+      */
+      
+      if (ft->openelements[i]->f != NULL)
+       {
+         (void) fclose (ft->openelements[i]->f); /* No check - cleaning up after errors */
+       }
+
+      ft->openelements[i]->f = NULL;
+      foentry_free (ft->openelements[i]);
+      ft->openelements[i] = NULL;
+    }
+  
+  ft->nopenspace += ft->nopen;
+  ft->nopen = 0;
+}
+
This page took 0.391386 seconds and 4 git commands to generate.