Convert t_filenm to C++
authorBerk Hess <hess@kth.se>
Fri, 23 Feb 2018 12:17:10 +0000 (13:17 +0100)
committerMark Abraham <mark.j.abraham@gmail.com>
Tue, 6 Mar 2018 15:40:31 +0000 (16:40 +0100)
This change is only refactoring.
Struct members opt and fn are now const char * const.
Replaced nfiles and fns by a vector of strings.
Removed, now unnecessary, copy and delete functions.

Change-Id: I7122f06e7264ad378022321b4c61acf1e3caabd6

28 files changed:
src/gromacs/commandline/filenm.cpp
src/gromacs/commandline/filenm.h
src/gromacs/commandline/pargs.cpp
src/gromacs/commandline/tests/pargs.cpp
src/gromacs/commandline/viewit.cpp
src/gromacs/gmxana/gmx_bar.cpp
src/gromacs/gmxana/gmx_clustsize.cpp
src/gromacs/gmxana/gmx_densorder.cpp
src/gromacs/gmxana/gmx_eneconv.cpp
src/gromacs/gmxana/gmx_energy.cpp
src/gromacs/gmxana/gmx_hydorder.cpp
src/gromacs/gmxana/gmx_make_ndx.cpp
src/gromacs/gmxana/gmx_nmr.cpp
src/gromacs/gmxana/gmx_sans.cpp
src/gromacs/gmxana/gmx_traj.cpp
src/gromacs/gmxana/gmx_trjcat.cpp
src/gromacs/gmxana/gmx_trjconv.cpp
src/gromacs/gmxana/powerspect.cpp
src/gromacs/gmxana/powerspect.h
src/gromacs/gmxpreprocess/genconf.cpp
src/gromacs/gmxpreprocess/solvate.cpp
src/gromacs/mdlib/forcerec.cpp
src/gromacs/mdlib/forcerec.h
src/gromacs/mdlib/main.cpp
src/gromacs/mdlib/main.h
src/gromacs/mdrunutility/handlerestart.cpp
src/programs/mdrun/mdrun.cpp
src/programs/mdrun/runner.cpp

index 3cefb0c3e73fec6b80c8a22e75c5ce3e0f277a42..e3461b35249025dc381fd8ee655ce80a81442c66 100644 (file)
@@ -46,6 +46,7 @@
 #include "gromacs/utility/cstringutil.h"
 #include "gromacs/utility/gmxassert.h"
 #include "gromacs/utility/smalloc.h"
+#include "gromacs/utility/stringutil.h"
 
 /* Use bitflag ... */
 static bool IS_SET(const t_filenm &fileOption)
@@ -58,7 +59,7 @@ static bool IS_OPT(const t_filenm &fileOption)
     return (fileOption.flag & ffOPT) != 0;
 }
 
-const t_filenm *getFilenm(const char *opt, int nfile, const t_filenm fnm[])
+static const t_filenm *getFileOption(const char *opt, int nfile, const t_filenm fnm[])
 {
     GMX_RELEASE_ASSERT(nfile == 0 || fnm, "need a valid list of filenames");
 
@@ -76,11 +77,11 @@ const t_filenm *getFilenm(const char *opt, int nfile, const t_filenm fnm[])
 
 const char *opt2fn(const char *opt, int nfile, const t_filenm fnm[])
 {
-    const t_filenm *fileOption = getFilenm(opt, nfile, fnm);
+    const t_filenm *fileOption = getFileOption(opt, nfile, fnm);
 
     if (fileOption)
     {
-        return fileOption->fns[0];
+        return fileOption->filenames[0].c_str();
     }
 
     GMX_RELEASE_ASSERT(false, "opt2fn should be called with a valid option");
@@ -88,19 +89,32 @@ const char *opt2fn(const char *opt, int nfile, const t_filenm fnm[])
     return nullptr;
 }
 
-int opt2fns(char **fns[], const char *opt, int nfile, const t_filenm fnm[])
+gmx::ArrayRef<const std::string>
+opt2fns(const char *opt, int nfile, const t_filenm fnm[])
 {
-    const t_filenm *fileOption = getFilenm(opt, nfile, fnm);
+    const t_filenm *fileOption = getFileOption(opt, nfile, fnm);
 
     if (fileOption)
     {
-        *fns = fileOption->fns;
-        return fileOption->nfiles;
+        return fileOption->filenames;
     }
 
     GMX_RELEASE_ASSERT(false, "opt2fns should be called with a valid option");
 
-    return 0;
+    return gmx::EmptyArrayRef();
+}
+
+gmx::ArrayRef<const std::string>
+opt2fnsIfOptionSet(const char *opt, int nfile, const t_filenm fnm[])
+{
+    if (opt2bSet(opt, nfile, fnm))
+    {
+        return opt2fns(opt, nfile, fnm);
+    }
+    else
+    {
+        return gmx::EmptyArrayRef();
+    }
 }
 
 const char *ftp2fn(int ftp, int nfile, const t_filenm fnm[])
@@ -111,7 +125,7 @@ const char *ftp2fn(int ftp, int nfile, const t_filenm fnm[])
     {
         if (ftp == fnm[i].ftp)
         {
-            return fnm[i].fns[0];
+            return fnm[i].filenames[0].c_str();
         }
     }
 
@@ -120,22 +134,20 @@ const char *ftp2fn(int ftp, int nfile, const t_filenm fnm[])
     return nullptr;
 }
 
-int ftp2fns(char **fns[], int ftp, int nfile, const t_filenm fnm[])
+gmx::ArrayRef<const std::string>
+ftp2fns(int ftp, int nfile, const t_filenm fnm[])
 {
-    int i;
-
-    for (i = 0; (i < nfile); i++)
+    for (int i = 0; (i < nfile); i++)
     {
         if (ftp == fnm[i].ftp)
         {
-            *fns = fnm[i].fns;
-            return fnm[i].nfiles;
+            return fnm[i].filenames;
         }
     }
 
     GMX_RELEASE_ASSERT(false, "ftp2fns should be called with a valid option");
 
-    return 0;
+    return gmx::EmptyArrayRef();
 }
 
 gmx_bool ftp2bSet(int ftp, int nfile, const t_filenm fnm[])
@@ -157,7 +169,7 @@ gmx_bool ftp2bSet(int ftp, int nfile, const t_filenm fnm[])
 
 gmx_bool opt2bSet(const char *opt, int nfile, const t_filenm fnm[])
 {
-    const t_filenm *fileOption = getFilenm(opt, nfile, fnm);
+    const t_filenm *fileOption = getFileOption(opt, nfile, fnm);
 
     if (fileOption)
     {
@@ -171,7 +183,7 @@ gmx_bool opt2bSet(const char *opt, int nfile, const t_filenm fnm[])
 
 const char *opt2fn_null(const char *opt, int nfile, const t_filenm fnm[])
 {
-    const t_filenm *fileOption = getFilenm(opt, nfile, fnm);
+    const t_filenm *fileOption = getFileOption(opt, nfile, fnm);
 
     if (fileOption)
     {
@@ -181,7 +193,7 @@ const char *opt2fn_null(const char *opt, int nfile, const t_filenm fnm[])
         }
         else
         {
-            return fileOption->fns[0];
+            return fileOption->filenames[0].c_str();
         }
     }
 
@@ -204,7 +216,7 @@ const char *ftp2fn_null(int ftp, int nfile, const t_filenm fnm[])
             }
             else
             {
-                return fnm[i].fns[0];
+                return fnm[i].filenames[0].c_str();
             }
         }
     }
@@ -231,80 +243,23 @@ gmx_bool is_set(const t_filenm *fnm)
 
 int add_suffix_to_output_names(t_filenm *fnm, int nfile, const char *suffix)
 {
-    int   i, j;
-    char  buf[STRLEN], newname[STRLEN];
+    char  buf[STRLEN];
     char *extpos;
 
-    for (i = 0; i < nfile; i++)
+    for (int i = 0; i < nfile; i++)
     {
         if (is_output(&fnm[i]) && fnm[i].ftp != efCPT)
         {
             /* We never use multiple _outputs_, but we might as well check
                for it, just in case... */
-            for (j = 0; j < fnm[i].nfiles; j++)
+            for (std::string &filename : fnm[i].filenames)
             {
-                std::strncpy(buf, fnm[i].fns[j], STRLEN - 1);
-                extpos  = strrchr(buf, '.');
-                *extpos = '\0';
-                sprintf(newname, "%s%s.%s", buf, suffix, extpos + 1);
-                sfree(fnm[i].fns[j]);
-                fnm[i].fns[j] = gmx_strdup(newname);
+                std::strncpy(buf, filename.c_str(), STRLEN - 1);
+                extpos   = strrchr(buf, '.');
+                *extpos  = '\0';
+                filename = gmx::formatString("%s%s.%s", buf, suffix, extpos + 1);
             }
         }
     }
     return 0;
 }
-
-t_filenm *dup_tfn(int nf, const t_filenm tfn[])
-{
-    int       i, j;
-    t_filenm *ret;
-
-    snew(ret, nf);
-    for (i = 0; i < nf; i++)
-    {
-        ret[i] = tfn[i]; /* just directly copy all non-string fields */
-        if (tfn[i].opt)
-        {
-            ret[i].opt = gmx_strdup(tfn[i].opt);
-        }
-        else
-        {
-            ret[i].opt = nullptr;
-        }
-
-        if (tfn[i].fn)
-        {
-            ret[i].fn = gmx_strdup(tfn[i].fn);
-        }
-        else
-        {
-            ret[i].fn = nullptr;
-        }
-
-        if (tfn[i].nfiles > 0)
-        {
-            snew(ret[i].fns, tfn[i].nfiles);
-            for (j = 0; j < tfn[i].nfiles; j++)
-            {
-                ret[i].fns[j] = gmx_strdup(tfn[i].fns[j]);
-            }
-        }
-    }
-    return ret;
-}
-
-void done_filenms(int nf, t_filenm fnm[])
-{
-    int i, j;
-
-    for (i = 0; i < nf; ++i)
-    {
-        for (j = 0; j < fnm[i].nfiles; ++j)
-        {
-            sfree(fnm[i].fns[j]);
-        }
-        sfree(fnm[i].fns);
-        fnm[i].fns = nullptr;
-    }
-}
index d39b54909a305dba665054352e598588a549f0d9..5c58f205cf71b08eec3d5086c4b8b58b3ac5709a 100644 (file)
 #ifndef GMX_COMMANDLINE_FILENM_H
 #define GMX_COMMANDLINE_FILENM_H
 
+#include <string>
+#include <vector>
+
 #include "gromacs/fileio/filetypes.h"
+#include "gromacs/utility/arrayref.h"
 #include "gromacs/utility/basedefinitions.h"
 
 
  */
 struct t_filenm
 {
-    int           ftp;    //!< File type (see enum in filetypes.h)
-    const char   *opt;    //!< Command line option, can be nullptr in which case the commandline module, including all opt2??? functions below, will use the default option for the file type
-    const char   *fn;     //!< File name (as set in source code), can be nullptr in which case the commandline module will use the default file name for the file type
-    unsigned long flag;   //!< Flag for all kinds of info (see defs)
-    int           nfiles; //!< number of files
-    char        **fns;    //!< File names
+    int                      ftp;       //!< File type, see enum in filetypes.h
+    const char * const       opt;       //!< Command line option, can be nullptr in which case the commandline module, including all opt2??? functions below, will use the default option for the file type
+    const char * const       fn;        //!< File name (as set in source code), can be nullptr in which case the commandline module will use the default file name for the file type
+    unsigned long            flag;      //!< Flag for all kinds of info (see defs)
+    std::vector<std::string> filenames; //!< File names
 };
 
 //! Whether a file name option is set.
@@ -107,18 +110,22 @@ struct t_filenm
  */
 const char *opt2fn(const char *opt, int nfile, const t_filenm fnm[]);
 
-/*! \brief Sets in \c fns the filenames belonging to cmd-line option
- * opt, or NULL when no such option. Returns the number of filenames
- * found.
+/*! \brief
+ * Returns the filenames belonging to cmd-line option opt.
+ *
+ * An assertion will fail when the option does not exist.
  */
-int opt2fns(char **fns[], const char *opt, int nfile,
-            const t_filenm fnm[]);
+gmx::ArrayRef<const std::string>
+opt2fns(const char *opt, int nfile, const t_filenm fnm[]);
 
 /*! \brief
- * Return a pointer to the t_filenm data structure of filenames belonging to
- * command-line option opt, or NULL when no such option was used.
+ * Returns the filenames belonging to cmd-line option opt when set,
+ * returns an empty vector when the option is not set.
+ *
+ * An assertion will fail when the option does not exist.
  */
-const t_filenm *getFilenm(const char *opt, int nfile, const t_filenm fnm[]);
+gmx::ArrayRef<const std::string>
+opt2fnsIfOptionSet(const char *opt, int nfile, const t_filenm fnm[]);
 
 //! Returns a file pointer from the filename.
 #define opt2FILE(opt, nfile, fnm, mode) gmx_ffopen(opt2fn(opt, nfile, fnm), mode)
@@ -127,10 +134,12 @@ const t_filenm *getFilenm(const char *opt, int nfile, const t_filenm fnm[]);
 const char *ftp2fn(int ftp, int nfile, const t_filenm fnm[]);
 
 /*! \brief
- * Returns the number of files for the first option with type ftp
- * and the files in **fns[] (will be allocated), or NULL when none found.
+ * Returns the filenames for the first option with type ftp.
+ *
+ * An assertion will fail when when none found.
  */
-int ftp2fns(char **fns[], int ftp, int nfile, const t_filenm fnm[]);
+gmx::ArrayRef<const std::string>
+ftp2fns(int ftp, int nfile, const t_filenm fnm[]);
 
 //! Returns a file pointer from the file type.
 #define ftp2FILE(ftp, nfile, fnm, mode) gmx_ffopen(ftp2fn(ftp, nfile, fnm), mode)
@@ -171,15 +180,6 @@ gmx_bool is_set(const t_filenm *fnm);
  */
 int add_suffix_to_output_names(t_filenm *fnm, int nfile, const char *suffix);
 
-/*! \brief
- * Duplicates the filename list (to make a private copy for each thread,
- * for example).
- */
-t_filenm *dup_tfn(int nf, const t_filenm tfn[]);
-
-//! Frees memory allocated for file names by parse_common_args().
-void done_filenms(int nf, t_filenm fnm[]);
-
 //! \}
 
 #endif
index c14efdabcfaa4b8d0ab8b6bf47e00782cedfda27..90574e6435f50fa7cfebc1283f68e08213d8d3ae 100644 (file)
 #include "gromacs/utility/arrayref.h"
 #include "gromacs/utility/basenetwork.h"
 #include "gromacs/utility/classhelpers.h"
-#include "gromacs/utility/cstringutil.h"
 #include "gromacs/utility/exceptions.h"
 #include "gromacs/utility/fatalerror.h"
 #include "gromacs/utility/gmxassert.h"
 #include "gromacs/utility/path.h"
 #include "gromacs/utility/programcontext.h"
-#include "gromacs/utility/smalloc.h"
 #include "gromacs/utility/stringutil.h"
 
 /* The source code in this file should be thread-safe.
@@ -419,12 +417,7 @@ void OptionsAdapter::copyValues()
         {
             file->fnm->flag |= ffSET;
         }
-        file->fnm->nfiles = file->values.size();
-        snew(file->fnm->fns, file->fnm->nfiles);
-        for (int i = 0; i < file->fnm->nfiles; ++i)
-        {
-            file->fnm->fns[i] = gmx_strdup(file->values[i].c_str());
-        }
+        file->fnm->filenames = file->values;
     }
     std::list<ProgramArgData>::const_iterator arg;
     for (arg = programArgs_.begin(); arg != programArgs_.end(); ++arg)
index 1d8a7b47e33d4aca1723050ef754862298b260ae..e7a1062d0ae86ede839e3827d66d8d8466b63976 100644 (file)
@@ -323,16 +323,14 @@ TEST_F(ParseCommonArgsTest, ParsesFileArgs)
     parseFromArray(cmdline, 0, fnm, gmx::EmptyArrayRef());
     EXPECT_STREQ("out1.xvg", opt2fn_null("-o1", nfile(), fnm));
     EXPECT_STREQ("test.xvg", opt2fn_null("-o2", nfile(), fnm));
-    char **files;
-    EXPECT_EQ(2, opt2fns(&files, "-om", nfile(), fnm));
-    EXPECT_TRUE(files != nullptr);
-    if (files != nullptr)
+    gmx::ArrayRef<const std::string> files = opt2fns("-om", nfile(), fnm);
+    EXPECT_EQ(2, files.size());
+    if (files.size() != 2)
     {
-        EXPECT_STREQ("test1.xvg", files[0]);
-        EXPECT_STREQ("test2.xvg", files[1]);
+        EXPECT_STREQ("test1.xvg", files[0].c_str());
+        EXPECT_STREQ("test2.xvg", files[1].c_str());
     }
     EXPECT_STREQ("outm2.xvg", opt2fn("-om2", nfile(), fnm));
-    done_filenms(nfile(), fnm);
 }
 
 TEST_F(ParseCommonArgsTest, ParsesFileArgsWithDefaults)
@@ -354,7 +352,6 @@ TEST_F(ParseCommonArgsTest, ParsesFileArgsWithDefaults)
     EXPECT_STREQ("trj3.xtc", opt2fn("-f3", nfile(), fnm));
     EXPECT_STREQ("out.xvg", opt2fn("-o", nfile(), fnm));
     EXPECT_STREQ("outm.xvg", opt2fn("-om", nfile(), fnm));
-    done_filenms(nfile(), fnm);
 }
 
 TEST_F(ParseCommonArgsTest, ParsesFileArgsWithDefaultFileName)
@@ -375,7 +372,6 @@ TEST_F(ParseCommonArgsTest, ParsesFileArgsWithDefaultFileName)
     EXPECT_STREQ("def.xtc", opt2fn("-f3", nfile(), fnm));
     EXPECT_STREQ("def.xvg", opt2fn("-o", nfile(), fnm));
     EXPECT_STREQ("def.xvg", opt2fn("-om", nfile(), fnm));
-    done_filenms(nfile(), fnm);
 }
 
 TEST_F(ParseCommonArgsTest, ParseFileArgsWithCustomDefaultExtension)
@@ -392,7 +388,6 @@ TEST_F(ParseCommonArgsTest, ParseFileArgsWithCustomDefaultExtension)
     EXPECT_STREQ("conf1.gro", opt2fn("-o1", nfile(), fnm));
     EXPECT_STREQ("conf2.pdb", opt2fn("-o2", nfile(), fnm));
     EXPECT_STREQ("test.gro", opt2fn("-o3", nfile(), fnm));
-    done_filenms(nfile(), fnm);
 }
 
 /********************************************************************
@@ -421,7 +416,6 @@ TEST_F(ParseCommonArgsTest, HandlesNonExistentInputFiles)
     EXPECT_STREQ("trj.gro", opt2fn("-f4", nfile(), fnm));
     EXPECT_STREQ("cnf.gro", opt2fn("-g", nfile(), fnm));
     EXPECT_STREQ("foo.gro", opt2fn("-g2", nfile(), fnm));
-    done_filenms(nfile(), fnm);
 }
 
 TEST_F(ParseCommonArgsTest, HandlesNonExistentOptionalInputFiles)
@@ -436,7 +430,6 @@ TEST_F(ParseCommonArgsTest, HandlesNonExistentOptionalInputFiles)
     parseFromArray(cmdline, 0, fnm, gmx::EmptyArrayRef());
     EXPECT_STREQ("topol.tpr", ftp2fn(efTPS, nfile(), fnm));
     EXPECT_STREQ("trj.xtc", opt2fn("-f", nfile(), fnm));
-    done_filenms(nfile(), fnm);
 }
 
 TEST_F(ParseCommonArgsTest, AcceptsNonExistentInputFilesIfSpecified)
@@ -457,7 +450,6 @@ TEST_F(ParseCommonArgsTest, AcceptsNonExistentInputFilesIfSpecified)
     EXPECT_STREQ("nonexistent.cpt", opt2fn("-c3", nfile(), fnm));
     EXPECT_STREQ("nonexistent.cpt", opt2fn("-c4", nfile(), fnm));
     EXPECT_STREQ("nonexistent.xtc", opt2fn("-f", nfile(), fnm));
-    done_filenms(nfile(), fnm);
 }
 
 TEST_F(ParseCommonArgsTest, HandlesCompressedFiles)
@@ -474,7 +466,6 @@ TEST_F(ParseCommonArgsTest, HandlesCompressedFiles)
     parseFromArgs(0, fnm, gmx::EmptyArrayRef());
     EXPECT_EQ(expectedF, opt2fn("-f", nfile(), fnm));
     EXPECT_EQ(expectedG, opt2fn("-g", nfile(), fnm));
-    done_filenms(nfile(), fnm);
 }
 
 TEST_F(ParseCommonArgsTest, AcceptsUnknownTrajectoryExtension)
@@ -486,30 +477,27 @@ TEST_F(ParseCommonArgsTest, AcceptsUnknownTrajectoryExtension)
     std::string       expected = addFileArg("-f", ".foo", efFull);
     parseFromArgs(0, fnm, gmx::EmptyArrayRef());
     EXPECT_EQ(expected, opt2fn("-f", nfile(), fnm));
-    done_filenms(nfile(), fnm);
 }
 
 TEST_F(ParseCommonArgsTest, CompletesExtensionFromExistingFile)
 {
-    t_filenm          fnm[] = {
+    args_.append("test");
+    std::string         expected1 = addFileArg("-f1", "1.xtc", efNoExtension);
+    std::string         expected2 = addFileArg("-f2", "2.gro", efNoExtension);
+    std::string         expected3 = addFileArg("-f3", "3.tng", efNoExtension);
+    std::string         expected4 = addFileArg("-f4", ".gro", efEmptyValue);
+    std::string         def4      = gmx::Path::stripExtension(expected4);
+    t_filenm            fnm[]     = {
         { efTRX, "-f1", nullptr, ffREAD },
         { efTRX, "-f2", nullptr, ffREAD },
         { efTRX, "-f3", nullptr, ffREAD },
-        { efTRX, "-f4", nullptr, ffREAD }
+        { efTRX, "-f4", def4.c_str(), ffREAD }
     };
-    args_.append("test");
-    std::string       expected1 = addFileArg("-f1", "1.xtc", efNoExtension);
-    std::string       expected2 = addFileArg("-f2", "2.gro", efNoExtension);
-    std::string       expected3 = addFileArg("-f3", "3.tng", efNoExtension);
-    std::string       expected4 = addFileArg("-f4", ".gro", efEmptyValue);
-    std::string       def4      = gmx::Path::stripExtension(expected4);
-    fnm[3].fn = def4.c_str();
     parseFromArgs(0, fnm, gmx::EmptyArrayRef());
     EXPECT_EQ(expected1, opt2fn("-f1", nfile(), fnm));
     EXPECT_EQ(expected2, opt2fn("-f2", nfile(), fnm));
     EXPECT_EQ(expected3, opt2fn("-f3", nfile(), fnm));
     EXPECT_EQ(expected4, opt2fn("-f4", nfile(), fnm));
-    done_filenms(nfile(), fnm);
 }
 
 TEST_F(ParseCommonArgsTest, CompletesExtensionFromExistingFileWithDefaultFileName)
@@ -533,7 +521,6 @@ TEST_F(ParseCommonArgsTest, CompletesExtensionFromExistingFileWithDefaultFileNam
     EXPECT_EQ(expected2, opt2fn("-f2", nfile(), fnm));
     EXPECT_EQ(expected3, opt2fn("-f3", nfile(), fnm));
     EXPECT_EQ(expected4, opt2fn("-f4", nfile(), fnm));
-    done_filenms(nfile(), fnm);
 }
 
 // This is needed e.g. for tune_pme, which passes unknown arguments on
@@ -566,7 +553,6 @@ TEST_F(ParseCommonArgsTest, CanKeepUnknownArgs)
     EXPECT_STREQ(cmdline[4],  args_.arg(3));
     EXPECT_STREQ(cmdline[9],  args_.arg(4));
     EXPECT_STREQ(cmdline[11], args_.arg(5));
-    done_filenms(nfile(), fnm);
 }
 
 } // namespace
index 87a8ebf76933c768866069f5b5fc1387a9588081..252ade56f28edcbb60e966a671d6dfed35c61f1c 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2017, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2017,2018, 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.
@@ -141,7 +141,7 @@ void view_all(const gmx_output_env_t *oenv, int nf, t_filenm fnm[])
         if (can_view(fnm[i].ftp) && is_output(&(fnm[i])) &&
             ( !is_optional(&(fnm[i])) || is_set(&(fnm[i])) ) )
         {
-            do_view(oenv, fnm[i].fns[0], nullptr);
+            do_view(oenv, fnm[i].filenames[0].c_str(), nullptr);
         }
     }
 }
index 865cf3c6a3153a74666d85c66463ce42f7cf041e..86f17f7c0199b071e880b1798dadcdebba4b44ab 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2010,2011,2012,2013,2014,2015,2017, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015,2017,2018, 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.
@@ -2845,7 +2845,7 @@ static void read_bar_xvg_lowlevel(const char *fn, real *temp, xvg_t *ba,
     }
 }
 
-static void read_bar_xvg(char *fn, real *temp, sim_data_t *sd)
+static void read_bar_xvg(const char *fn, real *temp, sim_data_t *sd)
 {
     xvg_t     *barsim;
     samples_t *s;
@@ -3145,7 +3145,7 @@ static samples_t *read_edr_hist_block(int *nsamples, t_enxblock *blk,
 }
 
 
-static void read_barsim_edr(char *fn, real *temp, sim_data_t *sd)
+static void read_barsim_edr(const char *fn, real *temp, sim_data_t *sd)
 {
     int            i, j;
     ener_file_t    fp;
@@ -3576,13 +3576,9 @@ int gmx_bar(int argc, char *argv[])
     int               f;
     int               nf = 0;    /* file counter */
     int               nfile_tot; /* total number of input files */
-    int               nxvgfile = 0;
-    int               nedrfile = 0;
-    char            **fxvgnms;
-    char            **fedrnms;
-    sim_data_t        sim_data; /* the simulation data */
-    barres_t         *results;  /* the results */
-    int               nresults; /* number of results in results array */
+    sim_data_t        sim_data;  /* the simulation data */
+    barres_t         *results;   /* the results */
+    int               nresults;  /* number of results in results array */
 
     double           *partsum;
     double            prec, dg_tot;
@@ -3608,14 +3604,8 @@ int gmx_bar(int argc, char *argv[])
         return 0;
     }
 
-    if (opt2bSet("-f", NFILE, fnm))
-    {
-        nxvgfile = opt2fns(&fxvgnms, "-f", NFILE, fnm);
-    }
-    if (opt2bSet("-g", NFILE, fnm))
-    {
-        nedrfile = opt2fns(&fedrnms, "-g", NFILE, fnm);
-    }
+    gmx::ArrayRef<const std::string> xvgFiles = opt2fnsIfOptionSet("-f", NFILE, fnm);
+    gmx::ArrayRef<const std::string> edrFiles = opt2fnsIfOptionSet("-g", NFILE, fnm);
 
     sim_data_init(&sim_data);
 #if 0
@@ -3627,7 +3617,7 @@ int gmx_bar(int argc, char *argv[])
 #endif
 
 
-    nfile_tot = nxvgfile + nedrfile;
+    nfile_tot = xvgFiles.size() + edrFiles.size();
 
     if (nfile_tot == 0)
     {
@@ -3644,15 +3634,15 @@ int gmx_bar(int argc, char *argv[])
     nf = 0;
 
     /* read in all files. First xvg files */
-    for (f = 0; f < nxvgfile; f++)
+    for (const std::string &filenm : xvgFiles)
     {
-        read_bar_xvg(fxvgnms[f], &temp, &sim_data);
+        read_bar_xvg(filenm.c_str(), &temp, &sim_data);
         nf++;
     }
     /* then .edr files */
-    for (f = 0; f < nedrfile; f++)
+    for (const std::string &filenm : edrFiles)
     {
-        read_barsim_edr(fedrnms[f], &temp, &sim_data);;
+        read_barsim_edr(filenm.c_str(), &temp, &sim_data);;
         nf++;
     }
 
index f1eb7d508c065b06b4c748cdb0426fea8cdb4a32..738843ac9936d2f33dde02a2eca175cf554c7e20 100644 (file)
@@ -552,7 +552,6 @@ int gmx_clustsize(int argc, char *argv[])
                bMol, bPBC, fnTPR,
                cutoff, nskip, nlevels, rgblo, rgbhi, ndf, oenv);
 
-    done_filenms(NFILE, fnm);
     output_env_done(oenv);
 
     return 0;
index e329e11f0762c75d3454a0421efc1c21b2e4f76c..74c4fd7a449754862b281ca775e5fc0070c11be7 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2017, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015,2016,2017,2018, 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.
@@ -530,7 +530,7 @@ static void interfaces_txy (real ****Densmap, int xslices, int yslices, int zsli
 
 }
 
-static void writesurftoxpms(t_interf ***surf1, t_interf ***surf2, int tblocks, int xbins, int ybins, int zbins, real bw, real bwz, char **outfiles, int maplevels )
+static void writesurftoxpms(t_interf ***surf1, t_interf ***surf2, int tblocks, int xbins, int ybins, int zbins, real bw, real bwz, gmx::ArrayRef<const std::string> outfiles, int maplevels )
 {
     char   numbuf[STRLEN];
     int    n, i, j;
@@ -558,8 +558,8 @@ static void writesurftoxpms(t_interf ***surf1, t_interf ***surf2, int tblocks, i
         yticks[j] += bw;
     }
 
-    xpmfile1 = gmx_ffopen(outfiles[0], "w");
-    xpmfile2 = gmx_ffopen(outfiles[1], "w");
+    xpmfile1 = gmx_ffopen(outfiles[0].c_str(), "w");
+    xpmfile2 = gmx_ffopen(outfiles[1].c_str(), "w");
 
     max1 = max2 = 0.0;
     min1 = min2 = zbins*bwz;
@@ -609,14 +609,14 @@ static void writesurftoxpms(t_interf ***surf1, t_interf ***surf2, int tblocks, i
 }
 
 static void writeraw(t_interf ***int1, t_interf ***int2, int tblocks,
-                     int xbins, int ybins, char **fnms,
+                     int xbins, int ybins, gmx::ArrayRef<const std::string> fnms,
                      const gmx_output_env_t *oenv)
 {
     FILE *raw1, *raw2;
     int   i, j, n;
 
-    raw1 = gmx_ffopen(fnms[0], "w");
-    raw2 = gmx_ffopen(fnms[1], "w");
+    raw1 = gmx_ffopen(fnms[0].c_str(), "w");
+    raw2 = gmx_ffopen(fnms[1].c_str(), "w");
     try
     {
         gmx::BinaryInformationSettings settings;
@@ -694,9 +694,6 @@ int gmx_densorder(int argc, char *argv[])
     static const char *meth[] = {nullptr, "bisect", "functional", nullptr};
     int                eMeth;
 
-    char             **graphfiles, **rawfiles, **spectra; /* Filenames for xpm-surface maps, rawdata and powerspectra */
-    int                nfxpm = -1, nfraw, nfspect;        /* # files for interface maps and spectra = # interfaces */
-
     t_pargs            pa[] = {
         { "-1d", FALSE, etBOOL, {&b1d},
           "Pseudo-1d interface geometry"},
@@ -775,12 +772,12 @@ int gmx_densorder(int argc, char *argv[])
     {
 
         /*Output surface-xpms*/
-        nfxpm = opt2fns(&graphfiles, "-og", NFILE, fnm);
-        if (nfxpm != 2)
+        gmx::ArrayRef<const std::string> graphFiles = opt2fns("-og", NFILE, fnm);
+        if (graphFiles.size() != 2)
         {
-            gmx_fatal(FARGS, "No or not correct number (2) of output-files: %d", nfxpm);
+            gmx_fatal(FARGS, "No or not correct number (2) of output-files: %zu", graphFiles.size());
         }
-        writesurftoxpms(surf1, surf2, tblock, xslices, yslices, zslices, binw, binwz, graphfiles, zslices);
+        writesurftoxpms(surf1, surf2, tblock, xslices, yslices, zslices, binw, binwz, graphFiles, zslices);
     }
 
 
@@ -790,23 +787,23 @@ int gmx_densorder(int argc, char *argv[])
 /*Output raw-data*/
     if (bRawOut)
     {
-        nfraw = opt2fns(&rawfiles, "-or", NFILE, fnm);
-        if (nfraw != 2)
+        gmx::ArrayRef<const std::string> rawFiles = opt2fns("-or", NFILE, fnm);
+        if (rawFiles.size() != 2)
         {
-            gmx_fatal(FARGS, "No or not correct number (2) of output-files: %d", nfxpm);
+            gmx_fatal(FARGS, "No or not correct number (2) of output-files: %zu", rawFiles.size());
         }
-        writeraw(surf1, surf2, tblock, xslices, yslices, rawfiles, oenv);
+        writeraw(surf1, surf2, tblock, xslices, yslices, rawFiles, oenv);
     }
 
 
 
     if (bFourier)
     {
-        nfspect = opt2fns(&spectra, "-Spect", NFILE, fnm);
-        if (nfspect != 2)
+        gmx::ArrayRef<const std::string> spectra = opt2fns("-Spect", NFILE, fnm);
+        if (spectra.size() != 2)
         {
-            gmx_fatal(FARGS, "No or not correct number (2) of output-file-series: %d",
-                      nfspect);
+            gmx_fatal(FARGS, "No or not correct number (2) of output-file-series: %zu",
+                      spectra.size());
         }
         powerspectavg_intf(surf1, surf2, tblock, xslices, yslices, spectra);
     }
index 6d47833172f5b9218bb56cec16555011baf77894..a84f667b672131cc10b11e6497f876096f390796 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2016,2017, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2016,2017,2018, 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.
@@ -50,6 +50,7 @@
 #include "gromacs/math/functions.h"
 #include "gromacs/math/vec.h"
 #include "gromacs/mdtypes/md_enums.h"
+#include "gromacs/utility/arrayref.h"
 #include "gromacs/utility/arraysize.h"
 #include "gromacs/utility/cstringutil.h"
 #include "gromacs/utility/fatalerror.h"
@@ -118,16 +119,12 @@ static int *select_it(int nre, gmx_enxnm_t *nm, int *nset)
     return set;
 }
 
-static void sort_files(char **fnms, real *settime, int nfile)
+static void sort_files(gmx::ArrayRef<std::string> files, real *settime)
 {
-    int   i, j, minidx;
-    real  timeswap;
-    char *chptr;
-
-    for (i = 0; i < nfile; i++)
+    for (size_t i = 0; i < files.size(); i++)
     {
-        minidx = i;
-        for (j = i+1; j < nfile; j++)
+        size_t minidx = i;
+        for (size_t j = i + 1; j < files.size(); j++)
         {
             if (settime[j] < settime[minidx])
             {
@@ -136,22 +133,22 @@ static void sort_files(char **fnms, real *settime, int nfile)
         }
         if (minidx != i)
         {
-            timeswap        = settime[i];
+            real timeswap   = settime[i];
             settime[i]      = settime[minidx];
             settime[minidx] = timeswap;
-            chptr           = fnms[i];
-            fnms[i]         = fnms[minidx];
-            fnms[minidx]    = chptr;
+            std::string tmp = files[i];
+            files[i]        = files[minidx];
+            files[minidx]   = tmp;
         }
     }
 }
 
 
-static int scan_ene_files(char **fnms, int nfiles,
+static int scan_ene_files(const std::vector<std::string> &files,
                           real *readtime, real *timestep, int *nremax)
 {
     /* Check number of energy terms and start time of all files */
-    int          f, nre, nremin = 0, nresav = 0;
+    int          nre, nremin = 0, nresav = 0;
     ener_file_t  in;
     real         t1, t2;
     char         inputstring[STRLEN];
@@ -160,9 +157,9 @@ static int scan_ene_files(char **fnms, int nfiles,
 
     snew(fr, 1);
 
-    for (f = 0; f < nfiles; f++)
+    for (size_t f = 0; f < files.size(); f++)
     {
-        in  = open_enx(fnms[f], "r");
+        in  = open_enx(files[f].c_str(), "r");
         enm = nullptr;
         do_enxnms(in, &nre, &enm);
 
@@ -187,7 +184,7 @@ static int scan_ene_files(char **fnms, int nfiles,
             {
                 fprintf(stderr,
                         "Energy files don't match, different number of energies:\n"
-                        " %s: %d\n %s: %d\n", fnms[f-1], nresav, fnms[f], fr->nre);
+                        " %s: %d\n %s: %d\n", files[f - 1].c_str(), nresav, files[f].c_str(), fr->nre);
                 fprintf(stderr,
                         "\nContinue conversion using only the first %d terms (n/y)?\n"
                         "(you should be sure that the energy terms match)\n", nremin);
@@ -217,16 +214,15 @@ static int scan_ene_files(char **fnms, int nfiles,
 }
 
 
-static void edit_files(char **fnms, int nfiles, real *readtime,
+static void edit_files(gmx::ArrayRef<std::string> files, real *readtime,
                        real *settime, int *cont_type, gmx_bool bSetTime, gmx_bool bSort)
 {
-    int      i;
     gmx_bool ok;
     char     inputstring[STRLEN], *chptr;
 
     if (bSetTime)
     {
-        if (nfiles == 1)
+        if (files.size() == 1)
         {
             fprintf(stderr, "\n\nEnter the new start time:\n\n");
         }
@@ -246,9 +242,9 @@ static void edit_files(char **fnms, int nfiles, real *readtime,
         fprintf(stderr, "          File             Current start       New start\n"
                 "---------------------------------------------------------\n");
 
-        for (i = 0; i < nfiles; i++)
+        for (size_t i = 0; i < files.size(); i++)
         {
-            fprintf(stderr, "%25s   %10.3f             ", fnms[i], readtime[i]);
+            fprintf(stderr, "%25s   %10.3f             ", files[i].c_str(), readtime[i]);
             ok = FALSE;
             do
             {
@@ -297,15 +293,15 @@ static void edit_files(char **fnms, int nfiles, real *readtime,
     }
     else
     {
-        for (i = 0; i < nfiles; i++)
+        for (size_t i = 0; i < files.size(); i++)
         {
             settime[i] = readtime[i];
         }
     }
 
-    if (bSort && (nfiles > 1))
+    if (bSort && files.size() > 1)
     {
-        sort_files(fnms, settime, nfiles);
+        sort_files(files, settime);
     }
     else
     {
@@ -317,26 +313,26 @@ static void edit_files(char **fnms, int nfiles, real *readtime,
     fprintf(stderr, "\nSummary of files and start times used:\n\n"
             "          File                Start time\n"
             "-----------------------------------------\n");
-    for (i = 0; i < nfiles; i++)
+    for (size_t i = 0; i < files.size(); i++)
     {
         switch (cont_type[i])
         {
             case TIME_EXPLICIT:
-                fprintf(stderr, "%25s   %10.3f\n", fnms[i], settime[i]);
+                fprintf(stderr, "%25s   %10.3f\n", files[i].c_str(), settime[i]);
                 break;
             case TIME_CONTINUE:
-                fprintf(stderr, "%25s        Continue from end of last file\n", fnms[i]);
+                fprintf(stderr, "%25s        Continue from end of last file\n", files[i].c_str());
                 break;
             case TIME_LAST:
-                fprintf(stderr, "%25s        Change by same amount as last file\n", fnms[i]);
+                fprintf(stderr, "%25s        Change by same amount as last file\n", files[i].c_str());
                 break;
         }
     }
     fprintf(stderr, "\n");
 
-    settime[nfiles]   = FLT_MAX;
-    cont_type[nfiles] = TIME_EXPLICIT;
-    readtime[nfiles]  = FLT_MAX;
+    settime[files.size()]   = FLT_MAX;
+    cont_type[files.size()] = TIME_EXPLICIT;
+    readtime[files.size()]  = FLT_MAX;
 }
 
 
@@ -455,9 +451,8 @@ int gmx_eneconv(int argc, char *argv[])
     t_energy         *ee_sum;
     gmx_int64_t       lastfilestep, laststep, startstep_file = 0;
     int               noutfr;
-    int               nre, nremax, this_nre, nfile, f, i, kkk, nset, *set = nullptr;
+    int               nre, nremax, this_nre, i, kkk, nset, *set = nullptr;
     double            last_t;
-    char            **fnms;
     real             *readtime, *settime, timestep, tadjust;
     char              buf[22], buf2[22];
     int              *cont_type;
@@ -508,27 +503,27 @@ int gmx_eneconv(int argc, char *argv[])
     {
         return 0;
     }
-    tadjust  = 0;
-    nremax   = 0;
-    nset     = 0;
-    timestep = 0.0;
-    snew(fnms, argc);
+    tadjust      = 0;
+    nremax       = 0;
+    nset         = 0;
+    timestep     = 0.0;
     lastfilestep = 0;
     laststep     = 0;
 
-    nfile = opt2fns(&fnms, "-f", NFILE, fnm);
+    gmx::ArrayRef<const std::string> filesOrig = opt2fns("-f", NFILE, fnm);
+    std::vector<std::string>         files(filesOrig.begin(), filesOrig.end());
 
-    if (!nfile)
+    if (files.empty())
     {
         gmx_fatal(FARGS, "No input files!");
     }
 
-    snew(settime, nfile+1);
-    snew(readtime, nfile+1);
-    snew(cont_type, nfile+1);
+    snew(settime, files.size() + 1);
+    snew(readtime, files.size() + 1);
+    snew(cont_type, files.size() + 1);
 
-    nre = scan_ene_files(fnms, nfile, readtime, &timestep, &nremax);
-    edit_files(fnms, nfile, readtime, settime, cont_type, bSetTime, bSort);
+    nre = scan_ene_files(files, readtime, &timestep, &nremax);
+    edit_files(files, readtime, settime, cont_type, bSetTime, bSort);
 
     ee_sum_nsteps = 0;
     ee_sum_nsum   = 0;
@@ -544,11 +539,11 @@ int gmx_eneconv(int argc, char *argv[])
     bFirst = TRUE;
 
     last_t = fro->t;
-    for (f = 0; f < nfile; f++)
+    for (size_t f = 0; f < files.size(); f++)
     {
         bNewFile   = TRUE;
         bNewOutput = TRUE;
-        in         = open_enx(fnms[f], "r");
+        in         = open_enx(files[f].c_str(), "r");
         enm        = nullptr;
         do_enxnms(in, &this_nre, &enm);
         if (f == 0)
@@ -611,7 +606,7 @@ int gmx_eneconv(int argc, char *argv[])
             {
                 if ((end > 0) && (fro->t > end+GMX_REAL_EPS))
                 {
-                    f = nfile;
+                    f = files.size();
                     break;
                 }
             }
@@ -745,7 +740,7 @@ int gmx_eneconv(int argc, char *argv[])
                                                "         This is almost certainly not what you want.\n"
                                                "         Use the -rmdh option to throw all delta H samples away.\n"
                                                "         Use g_energy -odh option to extract these samples.\n",
-                                               fnms[f], size);
+                                               files[f].c_str(), size);
                                         warned_about_dh = TRUE;
                                         break;
                                     }
@@ -763,12 +758,12 @@ int gmx_eneconv(int argc, char *argv[])
                 noutfr++;
             }
         }
-        if (f == nfile)
+        if (f == files.size())
         {
             f--;
         }
         printf("\nLast step written from %s: t %g, step %s\n",
-               fnms[f], last_t, gmx_step_str(laststep, buf));
+               files[f].c_str(), last_t, gmx_step_str(laststep, buf));
         lastfilestep = laststep;
 
         /* set the next time from the last in previous file */
@@ -783,7 +778,7 @@ int gmx_eneconv(int argc, char *argv[])
             /* cont_type[f+1]==TIME_EXPLICIT; */
         }
 
-        if ((fro->t < end) && (f < nfile-1) &&
+        if ((fro->t < end) && (f < files.size() - 1) &&
             (fro->t < settime[f+1]-1.5*timestep))
         {
             fprintf(stderr,
index c756e4e777b7ad14112f995c83bc86cf5d94214f..3132b67322ff0f013df58dcf66ed30849d39e581 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2016,2017, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2016,2017,2018, 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.
@@ -2130,7 +2130,6 @@ int gmx_energy(int argc, char *argv[])
         do_view(oenv, opt2fn_null("-odh", NFILE, fnm), nxy);
     }
     output_env_done(oenv);
-    done_filenms(NFILE, fnm);
 
     return 0;
 }
index e3b7d45061f1b5f9030284d6228bfbf15791f9f4..bb461db399dc4f429cc1387a8ea4133f00ea4d31 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2010,2011,2012,2013,2014,2015,2017, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2012,2013,2014,2015,2017,2018, 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.
@@ -446,7 +446,7 @@ static void calc_tetra_order_interface(const char *fnNDX, const char *fnTPS, con
     sfree(sg_4d);
 }
 
-static void writesurftoxpms(real ***surf, int tblocks, int xbins, int ybins, real bw, char **outfiles, int maplevels )
+static void writesurftoxpms(real ***surf, int tblocks, int xbins, int ybins, real bw, gmx::ArrayRef<const std::string> outfiles, int maplevels )
 {
 
     char   numbuf[STRLEN];
@@ -475,8 +475,8 @@ static void writesurftoxpms(real ***surf, int tblocks, int xbins, int ybins, rea
         yticks[j] += bw;
     }
 
-    xpmfile1 = gmx_ffopen(outfiles[0], "w");
-    xpmfile2 = gmx_ffopen(outfiles[1], "w");
+    xpmfile1 = gmx_ffopen(outfiles[0].c_str(), "w");
+    xpmfile2 = gmx_ffopen(outfiles[1].c_str(), "w");
 
     max1 = max2 = 0.0;
     min1 = min2 = 1000.00;
@@ -527,13 +527,14 @@ static void writesurftoxpms(real ***surf, int tblocks, int xbins, int ybins, rea
 }
 
 
-static void writeraw(real ***surf, int tblocks, int xbins, int ybins, char **fnms)
+static void writeraw(real ***surf, int tblocks, int xbins, int ybins,
+                     gmx::ArrayRef<const std::string> fnms)
 {
     FILE *raw1, *raw2;
     int   i, j, n;
 
-    raw1 = gmx_ffopen(fnms[0], "w");
-    raw2 = gmx_ffopen(fnms[1], "w");
+    raw1 = gmx_ffopen(fnms[0].c_str(), "w");
+    raw2 = gmx_ffopen(fnms[1].c_str(), "w");
     fprintf(raw1, "#Legend\n#TBlock\n#Xbin Ybin Z t\n");
     fprintf(raw2, "#Legend\n#TBlock\n#Xbin Ybin Z t\n");
     for (n = 0; n < tblocks; n++)
@@ -608,8 +609,6 @@ int gmx_hydorder(int argc, char *argv[])
 
     /*Filenames*/
     const char       *ndxfnm, *tpsfnm, *trxfnm;
-    char            **spectra, **intfn, **raw;
-    int               nfspect, nfxpm, nfraw;
     gmx_output_env_t *oenv;
 
     if (!parse_common_args(&argc, argv, PCA_CAN_VIEW | PCA_CAN_TIME,
@@ -663,30 +662,30 @@ int gmx_hydorder(int argc, char *argv[])
 
     /* tetraheder order parameter */
     /* If either of the options is set we compute both */
-    nfxpm = opt2fns(&intfn, "-o", NFILE, fnm);
-    if (nfxpm != 2)
+    gmx::ArrayRef<const std::string> intfn = opt2fns("-o", NFILE, fnm);
+    if (intfn.size() != 2)
     {
-        gmx_fatal(FARGS, "No or not correct number (2) of output-files: %d", nfxpm);
+        gmx_fatal(FARGS, "No or not correct number (2) of output-files: %d", intfn.size());
     }
     calc_tetra_order_interface(ndxfnm, tpsfnm, trxfnm, binwidth, nsttblock, &frames, &xslices, &yslices, sg1, sg2, &intfpos, oenv);
     writesurftoxpms(intfpos, frames, xslices, yslices, binwidth, intfn, nlevels);
 
     if (bFourier)
     {
-        nfspect = opt2fns(&spectra, "-Spect", NFILE, fnm);
-        if (nfspect != 2)
+        gmx::ArrayRef<const std::string> spectra = opt2fns("-Spect", NFILE, fnm);
+        if (spectra.size() != 2)
         {
-            gmx_fatal(FARGS, "No or not correct number (2) of output-files: %d", nfspect);
+            gmx_fatal(FARGS, "No or not correct number (2) of output-files: %d", spectra.size());
         }
         powerspectavg(intfpos, frames, xslices, yslices, spectra);
     }
 
     if (bRawOut)
     {
-        nfraw = opt2fns(&raw, "-or", NFILE, fnm);
-        if (nfraw != 2)
+        gmx::ArrayRef<const std::string> raw = opt2fns("-or", NFILE, fnm);
+        if (raw.size() != 2)
         {
-            gmx_fatal(FARGS, "No or not correct number (2) of output-files: %d", nfraw);
+            gmx_fatal(FARGS, "No or not correct number (2) of output-files: %d", raw.size());
         }
         writeraw(intfpos, frames, xslices, yslices, raw);
     }
index 85468fbebedf1d368506117eacaacf88128675f5..ed9a7412f40f97348a95b9d1f2b85c98ff51a6f0 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2012,2013,2014,2015,2016,2017, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014,2015,2016,2017,2018, 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.
@@ -1553,12 +1553,10 @@ int gmx_make_ndx(int argc, char *argv[])
 #define NPA asize(pa)
 
     gmx_output_env_t *oenv;
-    int               nndxin;
     const char       *stxfile;
-    char            **ndxinfiles;
     const char       *ndxoutfile;
     gmx_bool          bNatoms;
-    int               i, j;
+    int               j;
     t_atoms          *atoms;
     rvec             *x, *v;
     int               ePBC;
@@ -1579,18 +1577,11 @@ int gmx_make_ndx(int argc, char *argv[])
     }
 
     stxfile = ftp2fn_null(efSTX, NFILE, fnm);
-    if (opt2bSet("-n", NFILE, fnm))
-    {
-        nndxin = opt2fns(&ndxinfiles, "-n", NFILE, fnm);
-    }
-    else
-    {
-        nndxin = 0;
-    }
+    gmx::ArrayRef<const std::string> ndxInFiles = opt2fnsIfOptionSet("-n", NFILE, fnm);
     ndxoutfile = opt2fn("-o", NFILE, fnm);
     bNatoms    = opt2parg_bSet("-natoms", NPA, pa);
 
-    if (!stxfile && !nndxin)
+    if (!stxfile && ndxInFiles.empty())
     {
         gmx_fatal(FARGS, "No input files (structure or index)");
     }
@@ -1618,12 +1609,12 @@ int gmx_make_ndx(int argc, char *argv[])
     /* read input file(s) */
     block  = new_blocka();
     gnames = nullptr;
-    printf("Going to read %d old index file(s)\n", nndxin);
-    if (nndxin)
+    printf("Going to read %zu old index file(s)\n", ndxInFiles.size());
+    if (!ndxInFiles.empty())
     {
-        for (i = 0; i < nndxin; i++)
+        for (const std::string &ndxInFile : ndxInFiles)
         {
-            block2 = init_index(ndxinfiles[i], &gnames2);
+            block2 = init_index(ndxInFile.c_str(), &gnames2);
             srenew(gnames, block->nr+block2->nr);
             for (j = 0; j < block2->nr; j++)
             {
index a33c01a85d99b44bdd3a3d77411ca0f300439192..f09415228ab6a30e2071f8e1eb4d1fc1193a4de6 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2016,2017, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2016,2017,2018, 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.
@@ -947,7 +947,6 @@ int gmx_nmr(int argc, char *argv[])
         do_view(oenv, opt2fn_null("-oten", NFILE, fnm), nxy);
     }
     output_env_done(oenv);
-    done_filenms(NFILE, fnm);
 
     return 0;
 }
index b9b608dbb92d3112991a68d978bd4eff71b4746c..3cee45fec78c9bbcc4384c176d9c7d670c8a49a4 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2012,2013,2014,2015,2016,2017, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014,2015,2016,2017,2018, 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.
@@ -37,6 +37,8 @@
 
 #include "config.h"
 
+#include <array>
+
 #include "gromacs/commandline/pargs.h"
 #include "gromacs/fileio/confio.h"
 #include "gromacs/fileio/trxio.h"
@@ -136,23 +138,22 @@ int gmx_sans(int argc, char *argv[])
     int                                   i;
     char                                 *hdr            = nullptr;
     char                                 *suffix         = nullptr;
-    t_filenm                             *fnmdup         = nullptr;
     gmx_radial_distribution_histogram_t  *prframecurrent = nullptr, *pr = nullptr;
     gmx_static_structurefactor_t         *sqframecurrent = nullptr, *sq = nullptr;
     gmx_output_env_t                     *oenv;
 
 #define NFILE asize(fnm)
 
-    t_filenm   fnm[] = {
-        { efTPR,  "-s",       nullptr,       ffREAD },
-        { efTRX,  "-f",       nullptr,       ffREAD },
-        { efNDX,  nullptr,       nullptr,       ffOPTRD },
+    std::array<t_filenm, 8> filenames =
+    { { { efTPR,  "-s",       nullptr,    ffREAD  },
+        { efTRX,  "-f",       nullptr,    ffREAD  },
+        { efNDX,  nullptr,    nullptr,    ffOPTRD },
         { efDAT,  "-d",       "nsfactor", ffOPTRD },
         { efXVG,  "-pr",      "pr",       ffWRITE },
-        { efXVG,  "-sq",       "sq",      ffWRITE },
+        { efXVG,  "-sq",      "sq",       ffWRITE },
         { efXVG,  "-prframe", "prframe",  ffOPTWR },
-        { efXVG,  "-sqframe", "sqframe",  ffOPTWR }
-    };
+        { efXVG,  "-sqframe", "sqframe",  ffOPTWR } } };
+    t_filenm               *fnm = filenames.data();
 
     nthreads = gmx_omp_get_max_threads();
 
@@ -297,19 +298,17 @@ int gmx_sans(int argc, char *argv[])
             /* prepare header */
             sprintf(hdr, "g(r), t = %f", t);
             /* prepare output filename */
-            fnmdup = dup_tfn(NFILE, fnm);
+            auto fnmdup = filenames;
             sprintf(suffix, "-t%.2f", t);
-            add_suffix_to_output_names(fnmdup, NFILE, suffix);
-            fp = xvgropen(opt2fn_null("-prframe", NFILE, fnmdup), hdr, "Distance (nm)", "Probability", oenv);
+            add_suffix_to_output_names(fnmdup.data(), NFILE, suffix);
+            fp = xvgropen(opt2fn_null("-prframe", NFILE, fnmdup.data()), hdr, "Distance (nm)", "Probability", oenv);
             for (i = 0; i < prframecurrent->grn; i++)
             {
                 fprintf(fp, "%10.6f%10.6f\n", prframecurrent->r[i], prframecurrent->gr[i]);
             }
-            done_filenms(NFILE, fnmdup);
             xvgrclose(fp);
             sfree(hdr);
             sfree(suffix);
-            sfree(fnmdup);
         }
         if (opt2fn_null("-sqframe", NFILE, fnm))
         {
@@ -318,19 +317,17 @@ int gmx_sans(int argc, char *argv[])
             /* prepare header */
             sprintf(hdr, "I(q), t = %f", t);
             /* prepare output filename */
-            fnmdup = dup_tfn(NFILE, fnm);
+            auto fnmdup = filenames;
             sprintf(suffix, "-t%.2f", t);
-            add_suffix_to_output_names(fnmdup, NFILE, suffix);
-            fp = xvgropen(opt2fn_null("-sqframe", NFILE, fnmdup), hdr, "q (nm^-1)", "s(q)/s(0)", oenv);
+            add_suffix_to_output_names(fnmdup.data(), NFILE, suffix);
+            fp = xvgropen(opt2fn_null("-sqframe", NFILE, fnmdup.data()), hdr, "q (nm^-1)", "s(q)/s(0)", oenv);
             for (i = 0; i < sqframecurrent->qn; i++)
             {
                 fprintf(fp, "%10.6f%10.6f\n", sqframecurrent->q[i], sqframecurrent->s[i]);
             }
-            done_filenms(NFILE, fnmdup);
             xvgrclose(fp);
             sfree(hdr);
             sfree(suffix);
-            sfree(fnmdup);
         }
         /* free pr structure */
         sfree(prframecurrent->gr);
index 9c806d4a4ee7a03cf4b0f9fdcc74d85e92975ab1..0289165fe22155c8c2d64bf903f97e370aa312c6 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2016,2017, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2016,2017,2018, 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.
@@ -1143,7 +1143,6 @@ int gmx_traj(int argc, char *argv[])
     sfree(index0);
     sfree(isize0);
     sfree(grpname);
-    done_filenms(NFILE, fnm);
     done_frame(&fr);
     output_env_done(oenv);
 
index 144764792eaa4f3120b8e80a1d1727aa411d29cb..a2b694ed1b67b3a7c42a71e05b7877e2e0316b40 100644 (file)
 #include "gromacs/mdtypes/md_enums.h"
 #include "gromacs/topology/index.h"
 #include "gromacs/trajectory/trajectoryframe.h"
+#include "gromacs/utility/arrayref.h"
 #include "gromacs/utility/arraysize.h"
 #include "gromacs/utility/fatalerror.h"
 #include "gromacs/utility/futil.h"
 #include "gromacs/utility/smalloc.h"
+#include "gromacs/utility/stringutil.h"
 
 #define TIME_EXPLICIT 0
 #define TIME_CONTINUE 1
 #endif
 #define FLAGS (TRX_READ_X | TRX_READ_V | TRX_READ_F)
 
-static void scan_trj_files(char **fnms, int nfiles, real *readtime,
+static void scan_trj_files(gmx::ArrayRef<const std::string> files,
+                           real *readtime,
                            real *timestep, int imax,
                            const gmx_output_env_t *oenv)
 {
     /* Check start time of all files */
-    int          i, natoms = 0;
+    int          natoms = 0;
     t_trxstatus *status;
     t_trxframe   fr;
     bool         ok;
 
-    for (i = 0; i < nfiles; i++)
+    for (size_t i = 0; i < files.size(); i++)
     {
-        ok = read_first_frame(oenv, &status, fnms[i], &fr, FLAGS);
+        ok = read_first_frame(oenv, &status, files[i].c_str(), &fr, FLAGS);
 
         if (!ok)
         {
@@ -148,16 +151,12 @@ static void scan_trj_files(char **fnms, int nfiles, real *readtime,
 
 }
 
-static void sort_files(char **fnms, real *settime, int nfile)
+static void sort_files(gmx::ArrayRef<std::string> files, real *settime)
 {
-    int   i, j, minidx;
-    real  timeswap;
-    char *chptr;
-
-    for (i = 0; i < nfile; i++)
+    for (size_t i = 0; i < files.size(); i++)
     {
-        minidx = i;
-        for (j = i + 1; j < nfile; j++)
+        size_t minidx = i;
+        for (size_t j = i + 1; j < files.size(); j++)
         {
             if (settime[j] < settime[minidx])
             {
@@ -166,21 +165,19 @@ static void sort_files(char **fnms, real *settime, int nfile)
         }
         if (minidx != i)
         {
-            timeswap        = settime[i];
+            real timeswap   = settime[i];
             settime[i]      = settime[minidx];
             settime[minidx] = timeswap;
-            chptr           = fnms[i];
-            fnms[i]         = fnms[minidx];
-            fnms[minidx]    = chptr;
+            std::swap(files[i], files[minidx]);
         }
     }
 }
 
-static void edit_files(char **fnms, int nfiles, real *readtime, real *timestep,
+static void edit_files(gmx::ArrayRef<std::string> files,
+                       real *readtime, real *timestep,
                        real *settime, int *cont_type, gmx_bool bSetTime,
                        gmx_bool bSort, const gmx_output_env_t *oenv)
 {
-    int      i;
     gmx_bool ok;
     char     inputstring[STRLEN], *chptr;
 
@@ -204,9 +201,9 @@ static void edit_files(char **fnms, int nfiles, real *readtime, real *timestep,
                 "---------------------------------------------------------\n",
                 timeUnit.c_str(), timeUnit.c_str());
 
-        for (i = 0; i < nfiles; i++)
+        for (size_t i = 0; i < files.size(); i++)
         {
-            fprintf(stderr, "%25s   %10.3f %s          ", fnms[i],
+            fprintf(stderr, "%25s   %10.3f %s          ", files[i].c_str(),
                     output_env_conv_time(oenv, readtime[i]), timeUnit.c_str());
             ok = FALSE;
             do
@@ -259,7 +256,7 @@ static void edit_files(char **fnms, int nfiles, real *readtime, real *timestep,
     }
     else
     {
-        for (i = 0; i < nfiles; i++)
+        for (size_t i = 0; i < files.size(); i++)
         {
             settime[i] = readtime[i];
         }
@@ -270,19 +267,19 @@ static void edit_files(char **fnms, int nfiles, real *readtime, real *timestep,
     }
     else
     {
-        sort_files(fnms, settime, nfiles);
+        sort_files(files, settime);
     }
     /* Write out the new order and start times */
     fprintf(stderr, "\nSummary of files and start times used:\n\n"
             "          File                Start time       Time step\n"
             "---------------------------------------------------------\n");
-    for (i = 0; i < nfiles; i++)
+    for (size_t i = 0; i < files.size(); i++)
     {
         switch (cont_type[i])
         {
             case TIME_EXPLICIT:
                 fprintf(stderr, "%25s   %10.3f %s   %10.3f %s",
-                        fnms[i],
+                        files[i].c_str(),
                         output_env_conv_time(oenv, settime[i]), timeUnit.c_str(),
                         output_env_conv_time(oenv, timestep[i]), timeUnit.c_str());
                 if (i > 0 &&
@@ -293,39 +290,40 @@ static void edit_files(char **fnms, int nfiles, real *readtime, real *timestep,
                 fprintf(stderr, "\n");
                 break;
             case TIME_CONTINUE:
-                fprintf(stderr, "%25s        Continue from last file\n", fnms[i]);
+                fprintf(stderr, "%25s        Continue from last file\n", files[i].c_str());
                 break;
             case TIME_LAST:
                 fprintf(stderr, "%25s        Change by same amount as last file\n",
-                        fnms[i]);
+                        files[i].c_str());
                 break;
         }
     }
     fprintf(stderr, "\n");
 
-    settime[nfiles]   = FLT_MAX;
-    cont_type[nfiles] = TIME_EXPLICIT;
-    readtime[nfiles]  = FLT_MAX;
+    settime[files.size()]   = FLT_MAX;
+    cont_type[files.size()] = TIME_EXPLICIT;
+    readtime[files.size()]  = FLT_MAX;
 }
 
-static void do_demux(int nset, char *fnms[], char *fnms_out[], int nval,
+static void do_demux(gmx::ArrayRef<const std::string> inFiles,
+                     gmx::ArrayRef<const std::string> outFiles, int nval,
                      real **value, real *time, real dt_remd, int isize,
                      int index[], real dt, const gmx_output_env_t *oenv)
 {
-    int           i, j, k, natoms;
+    int           k, natoms;
     t_trxstatus **fp_in, **fp_out;
     gmx_bool      bCont, *bSet;
     real          t, first_time = 0;
     t_trxframe   *trx;
 
-    snew(fp_in, nset);
-    snew(trx, nset);
-    snew(bSet, nset);
+    snew(fp_in, inFiles.size());
+    snew(trx, inFiles.size());
+    snew(bSet, inFiles.size());
     natoms = -1;
     t      = -1;
-    for (i = 0; (i < nset); i++)
+    for (size_t i = 0; i < inFiles.size(); i++)
     {
-        read_first_frame(oenv, &(fp_in[i]), fnms[i], &(trx[i]),
+        read_first_frame(oenv, &(fp_in[i]), inFiles[i].c_str(), &(trx[i]),
                          TRX_NEED_X);
         if (natoms == -1)
         {
@@ -334,7 +332,7 @@ static void do_demux(int nset, char *fnms[], char *fnms_out[], int nval,
         }
         else if (natoms != trx[i].natoms)
         {
-            gmx_fatal(FARGS, "Trajectory file %s has %d atoms while previous trajs had %d atoms", fnms[i], trx[i].natoms, natoms);
+            gmx_fatal(FARGS, "Trajectory file %s has %d atoms while previous trajs had %d atoms", inFiles[i].c_str(), trx[i].natoms, natoms);
         }
         if (t == -1)
         {
@@ -342,14 +340,14 @@ static void do_demux(int nset, char *fnms[], char *fnms_out[], int nval,
         }
         else if (t != trx[i].time)
         {
-            gmx_fatal(FARGS, "Trajectory file %s has time %f while previous trajs had time %f", fnms[i], trx[i].time, t);
+            gmx_fatal(FARGS, "Trajectory file %s has time %f while previous trajs had time %f", inFiles[i].c_str(), trx[i].time, t);
         }
     }
 
-    snew(fp_out, nset);
-    for (i = 0; (i < nset); i++)
+    snew(fp_out, inFiles.size());
+    for (size_t i = 0; i < inFiles.size(); i++)
     {
-        fp_out[i] = open_trx(fnms_out[i], "w");
+        fp_out[i] = open_trx(outFiles[i].c_str(), "w");
     }
     k = 0;
     if (std::round(time[k] - t) != 0)
@@ -366,14 +364,14 @@ static void do_demux(int nset, char *fnms[], char *fnms_out[], int nval,
         {
             fprintf(debug, "trx[0].time = %g, time[k] = %g\n", trx[0].time, time[k]);
         }
-        for (i = 0; (i < nset); i++)
+        for (size_t i = 0; i < inFiles.size(); i++)
         {
             bSet[i] = FALSE;
         }
-        for (i = 0; (i < nset); i++)
+        for (size_t i = 0; i < inFiles.size(); i++)
         {
-            j = std::round(value[i][k]);
-            range_check(j, 0, nset);
+            int j = std::round(value[i][k]);
+            range_check(j, 0, inFiles.size());
             if (bSet[j])
             {
                 gmx_fatal(FARGS, "Demuxing the same replica %d twice at time %f",
@@ -395,14 +393,14 @@ static void do_demux(int nset, char *fnms[], char *fnms_out[], int nval,
         }
 
         bCont = (k < nval);
-        for (i = 0; (i < nset); i++)
+        for (size_t i = 0; i < inFiles.size(); i++)
         {
             bCont = bCont && read_next_frame(oenv, fp_in[i], &trx[i]);
         }
     }
     while (bCont);
 
-    for (i = 0; (i < nset); i++)
+    for (size_t i = 0; i < inFiles.size(); i++)
     {
         close_trx(fp_in[i]);
         close_trx(fp_out[i]);
@@ -475,10 +473,9 @@ int gmx_trjcat(int argc, char *argv[])
     t_trxstatus      *status, *trxout = nullptr;
     real              t_corr;
     t_trxframe        fr, frout;
-    char            **fnms, **fnms_out, *out_file;
     int               n_append;
     gmx_bool          bNewFile, bIndex, bWrite;
-    int               nfile_in, nfile_out, *cont_type;
+    int              *cont_type;
     real             *readtime, *timest, *settime;
     real              first_time  = 0, lasttime, last_ok_t = -1, timestep;
     gmx_bool          lastTimeSet = FALSE;
@@ -547,80 +544,80 @@ int gmx_trjcat(int argc, char *argv[])
         }
     }
 
-    nfile_in = opt2fns(&fnms, "-f", NFILE, fnm);
-    if (!nfile_in)
+    gmx::ArrayRef<const std::string> inFiles = opt2fns("-f", NFILE, fnm);
+    if (inFiles.empty())
     {
         gmx_fatal(FARGS, "No input files!" );
     }
 
-    if (bDeMux && (nfile_in != nset))
+    if (bDeMux && static_cast<int>(inFiles.size()) != nset)
     {
-        gmx_fatal(FARGS, "You have specified %d files and %d entries in the demux table", nfile_in, nset);
+        gmx_fatal(FARGS, "You have specified %zu files and %d entries in the demux table", inFiles.size(), nset);
     }
 
-    ftpin = fn2ftp(fnms[0]);
+    ftpin = fn2ftp(inFiles[0].c_str());
 
     if (ftpin != efTRR && ftpin != efXTC && ftpin != efTNG)
     {
         gmx_fatal(FARGS, "gmx trjcat can only handle binary trajectory formats (trr, xtc, tng)");
     }
 
-    for (i = 1; i < nfile_in; i++)
+    for (const std::string &inFile : inFiles)
     {
-        if (ftpin != fn2ftp(fnms[i]))
+        if (ftpin != fn2ftp(inFile.c_str()))
         {
             gmx_fatal(FARGS, "All input files must be of the same (trr, xtc or tng) format");
         }
     }
 
-    nfile_out = opt2fns(&fnms_out, "-o", NFILE, fnm);
-    if (!nfile_out)
+    gmx::ArrayRef<const std::string> outFiles = opt2fns("-o", NFILE, fnm);
+    if (outFiles.empty())
     {
         gmx_fatal(FARGS, "No output files!");
     }
-    if ((nfile_out > 1) && !bDeMux)
+    if ((outFiles.size() > 1) && !bDeMux)
     {
         gmx_fatal(FARGS, "Don't know what to do with more than 1 output file if  not demultiplexing");
     }
-    else if (bDeMux && (nfile_out != nset) && (nfile_out != 1))
+    else if (bDeMux && static_cast<int>(outFiles.size()) != nset && outFiles.size() != 1)
     {
-        gmx_fatal(FARGS, "Number of output files should be 1 or %d (#input files), not %d", nset, nfile_out);
+        gmx_fatal(FARGS, "Number of output files should be 1 or %d (#input files), not %zu", nset, outFiles.size());
     }
     if (bDeMux)
     {
-        if (nfile_out != nset)
+        std::vector<std::string> outFilesDemux(outFiles.begin(), outFiles.end());
+        if (static_cast<int>(outFilesDemux.size()) != nset)
         {
-            char *buf = gmx_strdup(fnms_out[0]);
-            snew(fnms_out, nset);
+            std::string name = outFilesDemux[0];
+            outFilesDemux.resize(nset);
             for (i = 0; (i < nset); i++)
             {
-                snew(fnms_out[i], std::strlen(buf)+32);
-                sprintf(fnms_out[i], "%d_%s", i, buf);
+                outFilesDemux[0] = gmx::formatString("%d_%s", i, name.c_str());
             }
-            sfree(buf);
         }
-        do_demux(nfile_in, fnms, fnms_out, n, val, t, dt_remd, isize, index, dt, oenv);
+        do_demux(inFiles, outFilesDemux, n, val, t, dt_remd, isize, index, dt, oenv);
     }
     else
     {
-        snew(readtime, nfile_in+1);
-        snew(timest, nfile_in+1);
-        scan_trj_files(fnms, nfile_in, readtime, timest, imax, oenv);
-
-        snew(settime, nfile_in+1);
-        snew(cont_type, nfile_in+1);
-        edit_files(fnms, nfile_in, readtime, timest, settime, cont_type, bSetTime, bSort,
+        snew(readtime, inFiles.size() + 1);
+        snew(timest, inFiles.size() + 1);
+        scan_trj_files(inFiles, readtime, timest, imax, oenv);
+
+        snew(settime, inFiles.size() + 1);
+        snew(cont_type, inFiles.size() + 1);
+        std::vector<std::string> inFilesEdited(inFiles.begin(), inFiles.end());
+        edit_files(inFilesEdited, readtime, timest, settime, cont_type, bSetTime, bSort,
                    oenv);
 
         /* Check whether the output file is amongst the input files
          * This has to be done after sorting etc.
          */
-        out_file = fnms_out[0];
+        const char *out_file = outFiles[0].c_str();
         ftpout   = fn2ftp(out_file);
         n_append = -1;
-        for (i = 0; ((i < nfile_in) && (n_append == -1)); i++)
+        for (size_t i = 0; i < inFilesEdited.size() && n_append == -1; i++)
         {
-            if (std::strcmp(fnms[i], out_file) == 0)
+            if (std::strcmp(inFilesEdited[i].c_str(), out_file) == 0)
             {
                 n_append = i;
             }
@@ -633,7 +630,7 @@ int gmx_trjcat(int argc, char *argv[])
         else if (n_append != -1)
         {
             gmx_fatal(FARGS, "Can only append to the first file which is %s (not %s)",
-                      fnms[0], out_file);
+                      inFilesEdited[0].c_str(), out_file);
         }
 
         /* Not checking input format, could be dangerous :-) */
@@ -657,12 +654,12 @@ int gmx_trjcat(int argc, char *argv[])
                 if (bIndex)
                 {
                     trxout = trjtools_gmx_prepare_tng_writing(out_file, 'w', nullptr,
-                                                              fnms[0], isize, nullptr, index, grpname);
+                                                              inFilesEdited[0].c_str(), isize, nullptr, index, grpname);
                 }
                 else
                 {
                     trxout = trjtools_gmx_prepare_tng_writing(out_file, 'w', nullptr,
-                                                              fnms[0], -1, nullptr, nullptr, nullptr);
+                                                              inFilesEdited[0].c_str(), -1, nullptr, nullptr, nullptr);
                 }
             }
             else
@@ -720,7 +717,7 @@ int gmx_trjcat(int argc, char *argv[])
 
                 /* xtc_seek_time broken for trajectories containing only 1 or 2 frames
                  *     or when seek time = 0 */
-                if (nfile_in > 1 && settime[1] < last_frame_time+timest[0]*0.5)
+                if (inFilesEdited.size() > 1 && settime[1] < last_frame_time+timest[0]*0.5)
                 {
                     /* Jump to one time-frame before the start of next
                      *  trajectory file */
@@ -758,7 +755,7 @@ int gmx_trjcat(int argc, char *argv[])
         }
         /* Lets stitch up some files */
         timestep = timest[0];
-        for (i = n_append+1; (i < nfile_in); i++)
+        for (size_t i = n_append + 1; i < inFilesEdited.size(); i++)
         {
             /* Open next file */
 
@@ -797,8 +794,8 @@ int gmx_trjcat(int argc, char *argv[])
                 /* Or, if time is set explicitly, we check for overlap/gap */
                 if (cont_type[i] == TIME_EXPLICIT)
                 {
-                    if ( ( i < nfile_in ) &&
-                         ( frout.time < settime[i]-1.5*timestep ) )
+                    if (i < inFilesEdited.size() &&
+                        frout.time < settime[i] - 1.5*timestep)
                     {
                         fprintf(stderr, "WARNING: Frames around t=%f %s have a different "
                                 "spacing than the rest,\n"
@@ -814,7 +811,7 @@ int gmx_trjcat(int argc, char *argv[])
             {
                 timestep = timest[i];
             }
-            read_first_frame(oenv, &status, fnms[i], &fr, FLAGS);
+            read_first_frame(oenv, &status, inFilesEdited[i].c_str(), &fr, FLAGS);
             if (!fr.bTime)
             {
                 fr.time = 0;
@@ -857,7 +854,7 @@ int gmx_trjcat(int argc, char *argv[])
                 /* quit if we have reached the end of what should be written */
                 if ((end > 0) && (frout.time > end+GMX_REAL_EPS))
                 {
-                    i = nfile_in;
+                    i = inFilesEdited.size();
                     break;
                 }
 
@@ -894,7 +891,8 @@ int gmx_trjcat(int argc, char *argv[])
                         {
                             fprintf(stderr, "\nContinue writing frames from %s t=%g %s, "
                                     "frame=%d      \n",
-                                    fnms[i], output_env_conv_time(oenv, frout.time), timeUnit.c_str(),
+                                    inFilesEdited[i].c_str(),
+                                    output_env_conv_time(oenv, frout.time), timeUnit.c_str(),
                                     frame);
                             bNewFile = FALSE;
                         }
index e2ec4eedb864889fd5515b0d3602ef93f9553b3e..64fad1696b73bc833c287fa5d492504a73061169 100644 (file)
@@ -1985,7 +1985,6 @@ int gmx_trjconv(int argc, char *argv[])
     sfree(grpnm);
     sfree(index);
     sfree(cindex);
-    done_filenms(NFILE, fnm);
     done_frame(&fr);
 
     do_view(oenv, out_file, nullptr);
index 442003ecdfd87bc54626881f2e27ef7362a52366..7a46d73334e11c8357bfab1914115dc34d1eeb61 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2010,2011,2013,2014,2015,2017, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2013,2014,2015,2017,2018, 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.
@@ -55,7 +55,8 @@ static void addtoavgenergy(t_complex *list, real *result, int size, int tsteps)
 }
 
 
-void powerspectavg(real ***intftab, int tsteps, int xbins, int ybins, char **outfiles)
+void powerspectavg(real ***intftab, int tsteps, int xbins, int ybins,
+                   gmx::ArrayRef<const std::string> outfiles)
 {
     /*Fourier plans and output;*/
     gmx_fft_t  fftp;
@@ -97,8 +98,8 @@ void powerspectavg(real ***intftab, int tsteps, int xbins, int ybins, char **out
     }
     /*Print out average energy-spectrum to outfiles[0] and outfiles[1];*/
 
-    datfile1 = gmx_ffopen(outfiles[0], "w");
-    datfile2 = gmx_ffopen(outfiles[1], "w");
+    datfile1 = gmx_ffopen(outfiles[0].c_str(), "w");
+    datfile2 = gmx_ffopen(outfiles[1].c_str(), "w");
 
 /*Filling dat files with spectral data*/
     fprintf(datfile1, "%s\n", "kx\t ky\t\tPower(kx,ky)");
@@ -116,7 +117,8 @@ void powerspectavg(real ***intftab, int tsteps, int xbins, int ybins, char **out
 
 }
 
-void powerspectavg_intf(t_interf ***if1, t_interf ***if2, int t, int xb, int yb, char **fnms)
+void powerspectavg_intf(t_interf ***if1, t_interf ***if2, int t, int xb, int yb,
+                        gmx::ArrayRef<const std::string> outfiles)
 {
     real ***surf;
 
@@ -136,5 +138,5 @@ void powerspectavg_intf(t_interf ***if1, t_interf ***if2, int t, int xb, int yb,
             surf[1][n][i] = if2[n][i]->Z;
         }
     }
-    powerspectavg(surf, t, xb, yb, fnms);
+    powerspectavg(surf, t, xb, yb, outfiles);
 }
index a8b49b8b7f33e7b094a5355fac51bfa1a9233c6a..0fbc85df0999fb4e8317198ad80dd5aeb383340e 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2010,2011,2013,2014,2015, by the GROMACS development team, led by
+ * Copyright (c) 2010,2011,2013,2014,2015,2018, 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.
 #ifndef _powerspect_h
 #define _powerspect_h
 
+#include <string>
+#include <vector>
+
 #include "gromacs/gmxana/interf.h"
+#include "gromacs/utility/arrayref.h"
 #include "gromacs/utility/real.h"
 
 #ifdef __cplusplus
@@ -45,10 +49,11 @@ extern "C"
 #endif
 
 extern void powerspectavg(real ***interface, int t, int xbins, int ybins,
-                          char **outfiles);
+                          gmx::ArrayRef<const std::string> outfiles);
 
 extern void powerspectavg_intf(t_interf ***if1, t_interf ***if2, int t,
-                               int xbins, int ybins, char **outfiles);
+                               int xbins, int ybins,
+                               gmx::ArrayRef<const std::string> outfiles);
 
 #ifdef __cplusplus
 }
index 00b8d11fa7fb00315895717cf587f4f5279b29bd..1c0275bc8cbaa4e7a38bd12b4311ac1e28f807a8 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2016,2017, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2016,2017,2018, 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.
@@ -319,7 +319,6 @@ int gmx_genconf(int argc, char *argv[])
     sfree(xx);
     done_top(top);
     sfree(top);
-    done_filenms(NFILE, fnm);
     output_env_done(oenv);
 
     return 0;
index 1a73fe22afcc3cfbd27a6702540129c7ab439d5e..046a849294d09e822c4090b2325d96408cbb05aa 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
  * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2016,2017, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015,2016,2017,2018, 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.
@@ -1024,7 +1024,6 @@ int gmx_solvate(int argc, char *argv[])
     done_top(top);
     sfree(top);
     output_env_done(oenv);
-    done_filenms(NFILE, fnm);
 
     return 0;
 }
index d96b3c24be2119b5c91f358373aa1dc45612fdd1..ef5b66f7eb543dc26a2ad622e0eece8c02548f03 100644 (file)
@@ -1435,7 +1435,7 @@ static void count_tables(int ftype1, int ftype2, const gmx_mtop_t *mtop,
 static bondedtable_t *make_bonded_tables(FILE *fplog,
                                          int ftype1, int ftype2,
                                          const gmx_mtop_t *mtop,
-                                         const t_filenm *tabbfnm,
+                                         gmx::ArrayRef<const std::string> tabbfnm,
                                          const char *tabext)
 {
     int            ncount, *count;
@@ -1462,13 +1462,12 @@ static bondedtable_t *make_bonded_tables(FILE *fplog,
                 // being recognized and used for table 1.
                 std::string patternToFind = gmx::formatString("_%s%d.%s", tabext, i, ftp2ext(efXVG));
                 bool        madeTable     = false;
-                for (int j = 0; j < tabbfnm->nfiles && !madeTable; ++j)
+                for (size_t j = 0; j < tabbfnm.size() && !madeTable; ++j)
                 {
-                    std::string filename(tabbfnm->fns[j]);
-                    if (gmx::endsWith(filename, patternToFind))
+                    if (gmx::endsWith(tabbfnm[j].c_str(), patternToFind))
                     {
                         // Finally read the table from the file found
-                        tab[i]    = make_bonded_table(fplog, tabbfnm->fns[j], NRAL(ftype1)-2);
+                        tab[i]    = make_bonded_table(fplog, tabbfnm[j].c_str(), NRAL(ftype1)-2);
                         madeTable = true;
                     }
                 }
@@ -2307,21 +2306,21 @@ gmx_bool usingGpu(nonbonded_verlet_t *nbv)
     return nbv != nullptr && nbv->bUseGPU;
 }
 
-void init_forcerec(FILE                    *fp,
-                   const gmx::MDLogger     &mdlog,
-                   t_forcerec              *fr,
-                   t_fcdata                *fcd,
-                   const t_inputrec        *ir,
-                   const gmx_mtop_t        *mtop,
-                   const t_commrec         *cr,
-                   matrix                   box,
-                   const char              *tabfn,
-                   const char              *tabpfn,
-                   const t_filenm          *tabbfnm,
-                   const gmx_hw_info_t     &hardwareInfo,
-                   const gmx_device_info_t *deviceInfo,
-                   gmx_bool                 bNoSolvOpt,
-                   real                     print_force)
+void init_forcerec(FILE                             *fp,
+                   const gmx::MDLogger              &mdlog,
+                   t_forcerec                       *fr,
+                   t_fcdata                         *fcd,
+                   const t_inputrec                 *ir,
+                   const gmx_mtop_t                 *mtop,
+                   const t_commrec                  *cr,
+                   matrix                            box,
+                   const char                       *tabfn,
+                   const char                       *tabpfn,
+                   gmx::ArrayRef<const std::string>  tabbfnm,
+                   const gmx_hw_info_t              &hardwareInfo,
+                   const gmx_device_info_t          *deviceInfo,
+                   gmx_bool                          bNoSolvOpt,
+                   real                              print_force)
 {
     int            m, negp_pp, negptable, egi, egj;
     real           rtab;
@@ -2983,7 +2982,7 @@ void init_forcerec(FILE                    *fp,
         make_wall_tables(fp, ir, tabfn, &mtop->groups, fr);
     }
 
-    if (fcd && tabbfnm)
+    if (fcd && !tabbfnm.empty())
     {
         // Need to catch std::bad_alloc
         // TODO Don't need to catch this here, when merging with master branch
index af7e5d77e8fbfeeeb188bdfd25e6907c682d6215..5e1774a9f2127ef8f75122b1a72424a2cc45b0a9 100644 (file)
@@ -42,6 +42,7 @@
 #include "gromacs/mdlib/vsite.h"
 #include "gromacs/mdtypes/forcerec.h"
 #include "gromacs/timing/wallcycle.h"
+#include "gromacs/utility/arrayref.h"
 
 struct gmx_device_info_t;
 struct gmx_hw_info_t;
@@ -113,21 +114,21 @@ void init_interaction_const_tables(FILE                   *fp,
  * \param[in]  bNoSolvOpt  Do not use solvent optimization
  * \param[in]  print_force Print forces for atoms with force >= print_force
  */
-void init_forcerec(FILE                    *fplog,
-                   const gmx::MDLogger     &mdlog,
-                   t_forcerec              *fr,
-                   t_fcdata                *fcd,
-                   const t_inputrec        *ir,
-                   const gmx_mtop_t        *mtop,
-                   const t_commrec         *cr,
-                   matrix                   box,
-                   const char              *tabfn,
-                   const char              *tabpfn,
-                   const t_filenm          *tabbfnm,
-                   const gmx_hw_info_t     &hardwareInfo,
-                   const gmx_device_info_t *deviceInfo,
-                   gmx_bool                 bNoSolvOpt,
-                   real                     print_force);
+void init_forcerec(FILE                             *fplog,
+                   const gmx::MDLogger              &mdlog,
+                   t_forcerec                       *fr,
+                   t_fcdata                         *fcd,
+                   const t_inputrec                 *ir,
+                   const gmx_mtop_t                 *mtop,
+                   const t_commrec                  *cr,
+                   matrix                            box,
+                   const char                       *tabfn,
+                   const char                       *tabpfn,
+                   gmx::ArrayRef<const std::string>  tabbfnm,
+                   const gmx_hw_info_t              &hardwareInfo,
+                   const gmx_device_info_t          *deviceInfo,
+                   gmx_bool                          bNoSolvOpt,
+                   real                              print_force);
 
 /*! \brief Divide exclusions over threads
  *
index 642542c0d89e325f5b9321cc3f21d11542a1e8e5..44c5c6e1fc8286598654ca6b421bc8f3821b9a75 100644 (file)
@@ -239,7 +239,8 @@ void gmx_log_close(FILE *fp)
 }
 
 // TODO move this to multi-sim module
-gmx_multisim_t *init_multisystem(MPI_Comm comm, int nsim, char **multidirs)
+gmx_multisim_t *init_multisystem(MPI_Comm                         comm,
+                                 gmx::ArrayRef<const std::string> multidirs)
 {
     gmx_multisim_t *ms;
 #if GMX_MPI
@@ -247,36 +248,35 @@ gmx_multisim_t *init_multisystem(MPI_Comm comm, int nsim, char **multidirs)
     int            *rank;
 #endif
 
-    if (nsim <= 1)
+    if (multidirs.size() <= 1)
     {
         return nullptr;
     }
-    if (!GMX_LIB_MPI && nsim > 1)
+    if (!GMX_LIB_MPI && multidirs.size() > 1)
     {
         gmx_fatal(FARGS, "mdrun -multidir is only supported when GROMACS has been "
                   "configured with a proper external MPI library.");
     }
-    GMX_RELEASE_ASSERT(multidirs, "Must have multiple directories for -multisim");
 
 #if GMX_MPI
     int numRanks;
     MPI_Comm_size(comm, &numRanks);
-    if (numRanks % nsim != 0)
+    if (numRanks % multidirs.size() != 0)
     {
-        gmx_fatal(FARGS, "The number of ranks (%d) is not a multiple of the number of simulations (%d)", numRanks, nsim);
+        gmx_fatal(FARGS, "The number of ranks (%d) is not a multiple of the number of simulations (%zu)", numRanks, multidirs.size());
     }
 
-    int numRanksPerSim = numRanks/nsim;
+    int numRanksPerSim = numRanks/multidirs.size();
     int rankWithinComm;
     MPI_Comm_rank(comm, &rankWithinComm);
 
     if (debug)
     {
-        fprintf(debug, "We have %d simulations, %d ranks per simulation, local simulation is %d\n", nsim, numRanksPerSim, rankWithinComm/numRanksPerSim);
+        fprintf(debug, "We have %zu simulations, %d ranks per simulation, local simulation is %d\n", multidirs.size(), numRanksPerSim, rankWithinComm/numRanksPerSim);
     }
 
     ms       = new gmx_multisim_t;
-    ms->nsim = nsim;
+    ms->nsim = multidirs.size();
     ms->sim  = rankWithinComm/numRanksPerSim;
     /* Create a communicator for the master nodes */
     snew(rank, ms->nsim);
@@ -304,7 +304,7 @@ gmx_multisim_t *init_multisystem(MPI_Comm comm, int nsim, char **multidirs)
 #endif
 
     // TODO This should throw upon error
-    gmx_chdir(multidirs[ms->sim]);
+    gmx_chdir(multidirs[ms->sim].c_str());
 #else
     GMX_UNUSED_VALUE(comm);
     ms = nullptr;
index f7c77b87d835d945cd7b2a7abada6c5bb0761ffd..8dd8bdb555d2662ce9f395fc5516de20289dfa12 100644 (file)
 #ifndef GMX_MDLIB_MAIN_H
 #define GMX_MDLIB_MAIN_H
 
-#include <stdio.h>
+#include <cstdio>
 
+#include <string>
+#include <vector>
+
+#include "gromacs/utility/arrayref.h"
 #include "gromacs/utility/basedefinitions.h"
 #include "gromacs/utility/gmxmpi.h"
 
@@ -67,8 +71,9 @@ void check_multi_int64(FILE *log, const gmx_multisim_t *ms,
  * no output is written.
  */
 
-gmx_multisim_t *init_multisystem(MPI_Comm comm, int nsim, char **multidirs);
-/* Splits the communication into nsim separate simulations
+gmx_multisim_t *init_multisystem(MPI_Comm                         comm,
+                                 gmx::ArrayRef<const std::string> multidirs);
+/* Splits the communication into multidirs.size() separate simulations, if >1,
  * and creates a communication structure between the master
  * these simulations.
  */
index e21ef66c803b3d65ae6660c36e9269ca3ccad2b5..45f92de7dfa2d0d9fc494fef299332cd35af4cd5 100644 (file)
@@ -75,7 +75,7 @@ static gmx_bool exist_output_file(const char *fnm_cp, int nfile, const t_filenm
      */
     i = 0;
     while (i < nfile &&
-           !(is_output(&fnm[i]) && strcmp(fnm_cp, fnm[i].fns[0]) == 0))
+           !(is_output(&fnm[i]) && strcmp(fnm_cp, fnm[i].filenames[0].c_str()) == 0))
     {
         i++;
     }
index 7f86acafbbdeebcd77088ebf15a86cbfdb0d46fe..efae59180c6f4b18dedbfbc181b553ba8b770d70 100644 (file)
@@ -369,7 +369,6 @@ int Mdrunner::mainFunction(int argc, char *argv[])
           "HIDDENReset the cycle counters after half the number of steps or halfway [TT]-maxh[tt]" }
     };
     int               rc;
-    char            **multidir = nullptr;
 
     cr = init_commrec();
 
@@ -432,14 +431,9 @@ int Mdrunner::mainFunction(int argc, char *argv[])
     hw_opt.thread_affinity = nenum(thread_aff_opt_choices);
 
     // now check for a multi-simulation
-    int nmultisim = 1;
-    if (opt2bSet("-multidir", nfile, fnm))
-    {
-        nmultisim = opt2fns(&multidir, "-multidir", nfile, fnm);
-    }
-
+    gmx::ArrayRef<const std::string> multidir = opt2fnsIfOptionSet("-multidir", nfile, fnm);
 
-    if (replExParams.exchangeInterval != 0 && nmultisim < 2)
+    if (replExParams.exchangeInterval != 0 && multidir.size() < 2)
     {
         gmx_fatal(FARGS, "Need at least two replicas for replica exchange (use option -multidir)");
     }
@@ -449,7 +443,7 @@ int Mdrunner::mainFunction(int argc, char *argv[])
         gmx_fatal(FARGS, "Replica exchange number of exchanges needs to be positive");
     }
 
-    ms = init_multisystem(MPI_COMM_WORLD, nmultisim, multidir);
+    ms = init_multisystem(MPI_COMM_WORLD, multidir);
 
     /* Prepare the intra-simulation communication */
     // TODO consolidate this with init_commrec, after changing the
@@ -457,7 +451,7 @@ int Mdrunner::mainFunction(int argc, char *argv[])
 #if GMX_MPI
     if (ms != nullptr)
     {
-        cr->nnodes = cr->nnodes / nmultisim;
+        cr->nnodes = cr->nnodes / ms->nsim;
         MPI_Comm_split(MPI_COMM_WORLD, ms->sim, cr->sim_nodeid, &cr->mpi_comm_mysim);
         cr->mpi_comm_mygroup = cr->mpi_comm_mysim;
         MPI_Comm_rank(cr->mpi_comm_mysim, &cr->sim_nodeid);
index 67824e3258e4705a9d4c2312dab72175a0124469..573af97a8e248698412e86b2a80176ec58073192 100644 (file)
@@ -153,14 +153,6 @@ static void threadMpiMdrunnerAccessBarrier()
 
 void Mdrunner::reinitializeOnSpawnedThread()
 {
-    // TODO This duplication is formally necessary if any thread might
-    // modify any memory in fnm or the pointers it contains. If the
-    // contents are ever provably const, then we can remove this
-    // allocation (and memory leak).
-    // TODO This should probably become part of a copy constructor for
-    // Mdrunner.
-    fnm = dup_tfn(nfile, fnm);
-
     threadMpiMdrunnerAccessBarrier();
 
     cr  = reinitialize_commrec_for_this_thread(cr, ms);
@@ -1168,7 +1160,7 @@ int Mdrunner::mdrunner()
                       inputrec, mtop, cr, box,
                       opt2fn("-table", nfile, fnm),
                       opt2fn("-tablep", nfile, fnm),
-                      getFilenm("-tableb", nfile, fnm),
+                      opt2fns("-tableb", nfile, fnm),
                       *hwinfo, nonbondedDeviceInfo,
                       FALSE,
                       pforce);