Remove .tpa, .tpb, .tpx, .trj files. Part of #1500.
[alexxy/gromacs.git] / src / gromacs / fileio / gmxfio.c
index 700c84c2bea3181c55bc4bcfc45a018263268d39..24dbc9f54a26b3b2ef46c767432d48d5e749c27a 100644 (file)
@@ -2,8 +2,8 @@
  * This file is part of the GROMACS molecular simulation package.
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
- * Copyright (c) 2001-2004, The GROMACS development team,
- * Copyright (c) 2013, by the GROMACS development team, led by
+ * Copyright (c) 2001-2004, The GROMACS development team.
+ * Copyright (c) 2013,2014, by the GROMACS development team, led by
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
  * To help us fund GROMACS development, we humbly ask that you cite
  * the research papers on the package. Check out http://www.gromacs.org.
  */
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
+#include "gmxpre.h"
+
+#include "config.h"
 
-#include <ctype.h>
-#include <stdio.h>
 #include <errno.h>
+#include <stdio.h>
+#include <string.h>
 #ifdef HAVE_IO_H
 #include <io.h>
 #endif
 #include <unistd.h>
 #endif
 
-#include "gmx_fatal.h"
-#include "macros.h"
-#include "smalloc.h"
-#include "futil.h"
+#include "thread_mpi/threads.h"
+
+#include "gromacs/utility/fatalerror.h"
+#include "gromacs/legacyheaders/macros.h"
+#include "gromacs/utility/smalloc.h"
+#include "gromacs/utility/futil.h"
 #include "filenm.h"
-#include "string2.h"
+#include "gromacs/utility/cstringutil.h"
 #include "gmxfio.h"
 #include "md5.h"
 
-#ifdef GMX_THREAD_MPI
-#include "thread_mpi.h"
-#endif
-
 #include "gmxfio_int.h"
 
 /* This is the new improved and thread safe version of gmxfio. */
@@ -72,7 +70,6 @@
 static t_fileio *open_files = NULL;
 
 
-#ifdef GMX_THREAD_MPI
 /* this mutex locks the open_files structure so that no two threads can
    modify it.
 
@@ -83,58 +80,26 @@ static t_fileio *open_files = NULL;
    iterating along all open files. All these cases should be rare
    during the simulation. */
 static tMPI_Thread_mutex_t open_file_mutex = TMPI_THREAD_MUTEX_INITIALIZER;
-#endif
 
 
 /* These simple lists define the I/O type for these files */
 static const int ftpXDR[] =
-{ efTPR, efTRR, efEDR, efXTC, efMTX, efCPT };
+{ efTPR, efTRR, efEDR, efXTC, efTNG, efMTX, efCPT };
 static const int ftpASC[] =
-{ efTPA, efGRO, efPDB };
+{ efGRO, efPDB, efG96 };
 static const int ftpBIN[] =
-{ efTPB, efTRJ };
+{ efTNG };
 #ifdef HAVE_XML
 static const int ftpXML[] =
 {   efXML};
 #endif
 
-const char *itemstr[eitemNR] =
-{
-    "[header]", "[inputrec]", "[box]", "[topology]", "[coordinates]",
-    "[velocities]", "[forces]"
-};
-
 const char *eioNames[eioNR] =
 {
     "REAL", "INT", "GMX_STE_T", "UCHAR", "NUCHAR", "USHORT", "RVEC", "NRVEC",
     "IVEC", "STRING"
 };
 
-
-
-/* Comment strings for TPA only */
-const char *comment_str[eitemNR] = {
-    "; The header holds information on the number of atoms etc. and on whether\n"
-    "; certain items are present in the file or not.\n"
-    "; \n"
-    ";                             WARNING\n"
-    ";                   DO NOT EDIT THIS FILE BY HAND\n"
-    "; The GROMACS preprocessor performs a lot of checks on your input that\n"
-    "; you ignore when editing this. Your simulation may crash because of this\n",
-    "; The inputrec holds the parameters for MD such as the number of steps,\n"
-    "; the timestep and the cut-offs.\n",
-    "; The simulation box in nm.\n",
-    "; The topology section describes the topology of the molecules\n"
-    "; i.e. bonds, angles and dihedrals etc. and also holds the force field\n"
-    "; parameters.\n",
-    "; The atomic coordinates in nm\n",
-    "; The atomic velocities in nm/ps\n",
-    "; The forces on the atoms in nm/ps^2\n"
-};
-
-
-
-
 /******************************************************************
  *
  * Internal functions:
@@ -264,16 +229,12 @@ static void gmx_fio_set_iotype(t_fileio *fio)
    type of access to the fio's elements. */
 void gmx_fio_lock(t_fileio *fio)
 {
-#ifdef GMX_THREAD_MPI
     tMPI_Lock_lock(&(fio->mtx));
-#endif
 }
 /* unlock the mutex associated with this fio.  */
 void gmx_fio_unlock(t_fileio *fio)
 {
-#ifdef GMX_THREAD_MPI
     tMPI_Lock_unlock(&(fio->mtx));
-#endif
 }
 
 /* make a dummy head element, assuming we locked everything. */
@@ -286,9 +247,7 @@ static void gmx_fio_make_dummy(void)
         open_files->fn   = NULL;
         open_files->next = open_files;
         open_files->prev = open_files;
-#ifdef GMX_THREAD_MPI
         tMPI_Lock_init(&(open_files->mtx));
-#endif
     }
 }
 
@@ -309,10 +268,8 @@ static void gmx_fio_make_dummy(void)
 static void gmx_fio_insert(t_fileio *fio)
 {
     t_fileio *prev;
-#ifdef GMX_THREAD_MPI
     /* first lock the big open_files mutex. */
     tMPI_Thread_mutex_lock(&open_file_mutex);
-#endif
     /* now check whether the dummy element has been allocated,
        and allocate it if it hasn't */
     gmx_fio_make_dummy();
@@ -341,10 +298,8 @@ static void gmx_fio_insert(t_fileio *fio)
     gmx_fio_unlock(open_files);
     gmx_fio_unlock(fio);
 
-#ifdef GMX_THREAD_MPI
     /* now unlock the big open_files mutex.  */
     tMPI_Thread_mutex_unlock(&open_file_mutex);
-#endif
 }
 
 /* remove a t_fileio into the list. We assume the fio is locked, and we leave
@@ -378,10 +333,8 @@ static t_fileio *gmx_fio_get_first(void)
     t_fileio *ret;
     /* first lock the big open_files mutex and the dummy's mutex */
 
-#ifdef GMX_THREAD_MPI
     /* first lock the big open_files mutex. */
     tMPI_Thread_mutex_lock(&open_file_mutex);
-#endif
     gmx_fio_make_dummy();
 
     gmx_fio_lock(open_files);
@@ -415,9 +368,7 @@ static t_fileio *gmx_fio_get_next(t_fileio *fio)
     if (fio->next == open_files)
     {
         ret = NULL;
-#ifdef GMX_THREAD_MPI
         tMPI_Thread_mutex_unlock(&open_file_mutex);
-#endif
     }
     else
     {
@@ -432,9 +383,7 @@ static t_fileio *gmx_fio_get_next(t_fileio *fio)
 static void gmx_fio_stop_getting_next(t_fileio *fio)
 {
     gmx_fio_unlock(fio);
-#ifdef GMX_THREAD_MPI
     tMPI_Thread_mutex_unlock(&open_file_mutex);
-#endif
 }
 
 
@@ -453,41 +402,34 @@ t_fileio *gmx_fio_open(const char *fn, const char *mode)
     gmx_bool  bRead, bReadWrite;
     int       xdrid;
 
-    if (fn2ftp(fn) == efTPA)
+    /* sanitize the mode string */
+    if (strncmp(mode, "r+", 2) == 0)
+    {
+        strcpy(newmode, "r+");
+    }
+    else if (mode[0] == 'r')
+    {
+        strcpy(newmode, "r");
+    }
+    else if (strncmp(mode, "w+", 2) == 0)
+    {
+        strcpy(newmode, "w+");
+    }
+    else if (mode[0] == 'w')
     {
-        strcpy(newmode, mode);
+        strcpy(newmode, "w");
+    }
+    else if (strncmp(mode, "a+", 2) == 0)
+    {
+        strcpy(newmode, "a+");
+    }
+    else if (mode[0] == 'a')
+    {
+        strcpy(newmode, "a");
     }
     else
     {
-        /* sanitize the mode string */
-        if (strncmp(mode, "r+", 2) == 0)
-        {
-            strcpy(newmode, "r+");
-        }
-        else if (mode[0] == 'r')
-        {
-            strcpy(newmode, "r");
-        }
-        else if (strncmp(mode, "w+", 2) == 0)
-        {
-            strcpy(newmode, "w+");
-        }
-        else if (mode[0] == 'w')
-        {
-            strcpy(newmode, "w");
-        }
-        else if (strncmp(mode, "a+", 2) == 0)
-        {
-            strcpy(newmode, "a+");
-        }
-        else if (mode[0] == 'a')
-        {
-            strcpy(newmode, "a");
-        }
-        else
-        {
-            gmx_fatal(FARGS, "DEATH HORROR in gmx_fio_open, mode is '%s'", mode);
-        }
+        gmx_fatal(FARGS, "DEATH HORROR in gmx_fio_open, mode is '%s'", mode);
     }
 
     /* Check if it should be opened as a binary file */
@@ -501,9 +443,7 @@ t_fileio *gmx_fio_open(const char *fn, const char *mode)
     }
 
     snew(fio, 1);
-#ifdef GMX_THREAD_MPI
     tMPI_Lock_init(&(fio->mtx));
-#endif
     bRead      = (newmode[0] == 'r' && newmode[1] != '+');
     bReadWrite = (newmode[1] == '+');
     fio->fp    = NULL;
@@ -511,7 +451,7 @@ t_fileio *gmx_fio_open(const char *fn, const char *mode)
     if (fn)
     {
         fio->iFTP   = fn2ftp(fn);
-        fio->fn     = strdup(fn);
+        fio->fn     = gmx_strdup(fn);
         fio->bStdio = FALSE;
 
         /* If this file type is in the list of XDR files, open it like that */
@@ -535,8 +475,12 @@ t_fileio *gmx_fio_open(const char *fn, const char *mode)
                     gmx_open(fn);
                 }
             }
+            if (fn2ftp(fn) == efTNG)
+            {
+                gmx_incons("gmx_fio_open may not be used to open TNG files");
+            }
             /* Open the file */
-            fio->fp = ffopen(fn, newmode);
+            fio->fp = gmx_ffopen(fn, newmode);
 
             /* determine the XDR direction */
             if (newmode[0] == 'w' || newmode[0] == 'a')
@@ -554,7 +498,7 @@ t_fileio *gmx_fio_open(const char *fn, const char *mode)
         else
         {
             /* If it is not, open it as a regular file */
-            fio->fp = ffopen(fn, newmode);
+            fio->fp = gmx_ffopen(fn, newmode);
         }
 
         /* for appending seek to end of file to make sure ftell gives correct position
@@ -564,20 +508,11 @@ t_fileio *gmx_fio_open(const char *fn, const char *mode)
             gmx_fseek(fio->fp, 0, SEEK_END);
         }
     }
-    else
-    {
-        /* Use stdin/stdout for I/O */
-        fio->iFTP   = efTPA;
-        fio->fp     = bRead ? stdin : stdout;
-        fio->fn     = strdup("STDIO");
-        fio->bStdio = TRUE;
-    }
     fio->bRead             = bRead;
     fio->bReadWrite        = bReadWrite;
     fio->bDouble           = (sizeof(real) == sizeof(double));
     fio->bDebug            = FALSE;
     fio->bOpen             = TRUE;
-    fio->bLargerThan_off_t = FALSE;
 
     /* set the reader/writer functions */
     gmx_fio_set_iotype(fio);
@@ -605,7 +540,7 @@ static int gmx_fio_close_locked(t_fileio *fio)
     /* Don't close stdin and stdout! */
     if (!fio->bStdio && fio->fp != NULL)
     {
-        rc = ffclose(fio->fp); /* fclose returns 0 if happy */
+        rc = gmx_ffclose(fio->fp); /* fclose returns 0 if happy */
 
     }
     fio->bOpen = FALSE;
@@ -617,12 +552,14 @@ int gmx_fio_close(t_fileio *fio)
 {
     int rc = 0;
 
-#ifdef GMX_THREAD_MPI
     /* first lock the big open_files mutex. */
     /* We don't want two processes operating on the list at the same time */
     tMPI_Thread_mutex_lock(&open_file_mutex);
-#endif
 
+    if (fio->iFTP == efTNG)
+    {
+        gmx_incons("gmx_fio_close should not be called on a TNG file");
+    }
     gmx_fio_lock(fio);
     /* first remove it from the list */
     gmx_fio_remove(fio);
@@ -632,9 +569,7 @@ int gmx_fio_close(t_fileio *fio)
     sfree(fio->fn);
     sfree(fio);
 
-#ifdef GMX_THREAD_MPI
     tMPI_Thread_mutex_unlock(&open_file_mutex);
-#endif
 
     return rc;
 }
@@ -646,7 +581,7 @@ int gmx_fio_fp_close(t_fileio *fio)
     gmx_fio_lock(fio);
     if (!in_ftpset(fio->iFTP, asize(ftpXDR), ftpXDR) && !fio->bStdio)
     {
-        rc      = ffclose(fio->fp); /* fclose returns 0 if happy */
+        rc      = gmx_ffclose(fio->fp); /* fclose returns 0 if happy */
         fio->fp = NULL;
     }
     gmx_fio_unlock(fio);
@@ -697,11 +632,11 @@ static int gmx_fio_int_get_file_md5(t_fileio *fio, gmx_off_t offset,
 {
     /*1MB: large size important to catch almost identical files */
 #define CPT_CHK_LEN  1048576
-    md5_state_t   state;
-    unsigned char buf[CPT_CHK_LEN];
-    gmx_off_t     read_len;
-    gmx_off_t     seek_offset;
-    int           ret = -1;
+    md5_state_t    state;
+    unsigned char *buf;
+    gmx_off_t      read_len;
+    gmx_off_t      seek_offset;
+    int            ret = -1;
 
     seek_offset = offset - CPT_CHK_LEN;
     if (seek_offset < 0)
@@ -724,6 +659,7 @@ static int gmx_fio_int_get_file_md5(t_fileio *fio, gmx_off_t offset,
         return -1;
     }
 
+    snew(buf, CPT_CHK_LEN);
     /* the read puts the file position back to offset */
     if ((gmx_off_t)fread(buf, 1, read_len, fio->fp) != read_len)
     {
@@ -769,15 +705,13 @@ static int gmx_fio_int_get_file_md5(t_fileio *fio, gmx_off_t offset,
 
     if (!ret)
     {
-        md5_init(&state);
-        md5_append(&state, buf, read_len);
-        md5_finish(&state, digest);
-        return read_len;
-    }
-    else
-    {
-        return ret;
+        gmx_md5_init(&state);
+        gmx_md5_append(&state, buf, read_len);
+        gmx_md5_finish(&state, digest);
+        ret = read_len;
     }
+    sfree(buf);
+    return ret;
 }
 
 
@@ -825,29 +759,6 @@ static int gmx_fio_int_get_file_position(t_fileio *fio, gmx_off_t *offset)
     return 0;
 }
 
-int gmx_fio_check_file_position(t_fileio gmx_unused *fio)
-{
-    /* If gmx_off_t is 4 bytes we can not store file offset > 2 GB.
-     * If we do not have ftello, we will play it safe.
-     */
-#if (SIZEOF_GMX_OFF_T == 4 || !defined HAVE_FSEEKO)
-    gmx_off_t offset;
-
-    gmx_fio_lock(fio);
-    gmx_fio_int_get_file_position(fio, &offset);
-    /* We have a 4 byte offset,
-     * make sure that we will detect out of range for all possible cases.
-     */
-    if (offset < 0 || offset > 2147483647)
-    {
-        fio->bLargerThan_off_t = TRUE;
-    }
-    gmx_fio_unlock(fio);
-#endif
-
-    return 0;
-}
-
 int gmx_fio_get_output_file_positions(gmx_file_position_t **p_outputfiles,
                                       int                  *p_nfiles)
 {
@@ -887,23 +798,13 @@ int gmx_fio_get_output_file_positions(gmx_file_position_t **p_outputfiles,
             strncpy(outputfiles[nfiles].filename, cur->fn, STRLEN - 1);
 
             /* Get the file position */
-            if (cur->bLargerThan_off_t)
-            {
-                /* -1 signals out of range */
-                outputfiles[nfiles].offset      = -1;
-                outputfiles[nfiles].chksum_size = -1;
-            }
-            else
-            {
-                gmx_fio_int_get_file_position(cur, &outputfiles[nfiles].offset);
+            gmx_fio_int_get_file_position(cur, &outputfiles[nfiles].offset);
 #ifndef GMX_FAHCORE
-                outputfiles[nfiles].chksum_size
-                    = gmx_fio_int_get_file_md5(cur,
-                                               outputfiles[nfiles].offset,
-                                               outputfiles[nfiles].chksum);
+            outputfiles[nfiles].chksum_size
+                = gmx_fio_int_get_file_md5(cur,
+                                           outputfiles[nfiles].offset,
+                                           outputfiles[nfiles].chksum);
 #endif
-            }
-
             nfiles++;
         }