Change use of t_inpfile to std::vector
authorPaul Bauer <paul.bauer.q@gmail.com>
Fri, 25 May 2018 16:44:43 +0000 (18:44 +0200)
committerErik Lindahl <erik.lindahl@gmail.com>
Thu, 7 Jun 2018 13:18:30 +0000 (15:18 +0200)
Refactored code to use std::vector for t_inpfile instead of pointers.
This is meant to be the basis for a change in mdp file writing from gmx
dump that requires the t_inpfile structure to use the already available
functions to write the file instead of having a custom one.

Rebased on change that changes the use of macros to functions for
reading the information into the structure.

Changed t_inpfile to a struct with constructor and destructor, as well as
replacing the custom sort function with std::sort.

Change-Id: I0c5c646b183d232c638db869f98457af82e0be18

src/gromacs/awh/read-params.cpp
src/gromacs/awh/read-params.h
src/gromacs/fileio/readinp.cpp
src/gromacs/fileio/readinp.h
src/gromacs/fileio/tests/readinp.cpp
src/gromacs/gmxana/gmx_xpm2ps.cpp
src/gromacs/gmxpreprocess/readir.cpp
src/gromacs/gmxpreprocess/readir.h
src/gromacs/gmxpreprocess/readpull.cpp
src/gromacs/gmxpreprocess/readrot.cpp
src/gromacs/mdlib/membed.cpp

index e7c3eb9656139865b434a5de566e7b41a50c9b65..b9b33f933540d21b7f0737ff2e96f31e5fb5a377 100644 (file)
@@ -80,38 +80,34 @@ const char *eawhcoordprovider_names[eawhcoordproviderNR+1] = {
 /*! \brief
  * Read parameters of an AWH bias dimension.
  *
- * \param[in,out] ninp_p     Number of read input file entries.
- * \param[in,out] inp_p      Input file entries.
+ * \param[in,out] inp        Input file entries.
  * \param[in] prefix         Prefix for dimension parameters.
  * \param[in,out] dimParams  AWH dimensional parameters.
  * \param[in] pull_params    Pull parameters.
  * \param[in,out] wi         Struct for bookeeping warnings.
  * \param[in] bComment       True if comments should be printed.
  */
-static void readDimParams(int *ninp_p, t_inpfile **inp_p, const char *prefix,
+static void readDimParams(std::vector<t_inpfile> *inp, const char *prefix,
                           AwhDimParams *dimParams, const pull_params_t *pull_params,
                           warninp_t wi, bool bComment)
 {
-    char       warningmsg[STRLEN];
-
-    int        ninp = *ninp_p;
-    t_inpfile *inp  = *inp_p;
+    char                    warningmsg[STRLEN];
 
     if (bComment)
     {
-        printStringNoNewline(&ninp, &inp, "The provider of the reaction coordinate, currently only pull is supported");
+        printStringNoNewline(inp, "The provider of the reaction coordinate, currently only pull is supported");
     }
     char opt[STRLEN];
     sprintf(opt, "%s-coord-provider", prefix);
-    dimParams->eCoordProvider = get_eeenum(&ninp, &inp, opt, eawhcoordprovider_names, wi);
+    dimParams->eCoordProvider = get_eeenum(inp, opt, eawhcoordprovider_names, wi);
 
     if (bComment)
     {
-        printStringNoNewline(&ninp, &inp, "The coordinate index for this dimension");
+        printStringNoNewline(inp, "The coordinate index for this dimension");
     }
     sprintf(opt, "%s-coord-index", prefix);
     int coordIndexInput;
-    coordIndexInput = get_eint(&ninp, &inp, opt, 1, wi);
+    coordIndexInput = get_eint(inp, opt, 1, wi);
     if (coordIndexInput <  1)
     {
         gmx_fatal(FARGS, "Failed to read a valid coordinate index for %s. "
@@ -144,14 +140,14 @@ static void readDimParams(int *ninp_p, t_inpfile **inp_p, const char *prefix,
 
     if (bComment)
     {
-        printStringNoNewline(&ninp, &inp, "Start and end values for each coordinate dimension");
+        printStringNoNewline(inp, "Start and end values for each coordinate dimension");
     }
 
     sprintf(opt, "%s-start", prefix);
-    dimParams->origin = get_ereal(&ninp, &inp, opt, 0., wi);
+    dimParams->origin = get_ereal(inp, opt, 0., wi);
 
     sprintf(opt, "%s-end", prefix);
-    dimParams->end = get_ereal(&ninp, &inp, opt, 0., wi);
+    dimParams->end = get_ereal(inp, opt, 0., wi);
 
     if (gmx_within_tol(dimParams->end - dimParams->origin, 0, GMX_REAL_EPS))
     {
@@ -189,10 +185,10 @@ static void readDimParams(int *ninp_p, t_inpfile **inp_p, const char *prefix,
 
     if (bComment)
     {
-        printStringNoNewline(&ninp, &inp, "The force constant for this coordinate (kJ/mol/nm^2 or kJ/mol/rad^2)");
+        printStringNoNewline(inp, "The force constant for this coordinate (kJ/mol/nm^2 or kJ/mol/rad^2)");
     }
     sprintf(opt, "%s-force-constant", prefix);
-    dimParams->forceConstant = get_ereal(&ninp, &inp, opt, 0, wi);
+    dimParams->forceConstant = get_ereal(inp, opt, 0, wi);
     if (dimParams->forceConstant <= 0)
     {
         warning_error(wi, "The force AWH bias force constant should be > 0");
@@ -200,10 +196,10 @@ static void readDimParams(int *ninp_p, t_inpfile **inp_p, const char *prefix,
 
     if (bComment)
     {
-        printStringNoNewline(&ninp, &inp, "Estimated diffusion constant (nm^2/ps or rad^2/ps)");
+        printStringNoNewline(inp, "Estimated diffusion constant (nm^2/ps or rad^2/ps)");
     }
     sprintf(opt, "%s-diffusion", prefix);
-    dimParams->diffusion = get_ereal(&ninp, &inp, opt, 0, wi);
+    dimParams->diffusion = get_ereal(inp, opt, 0, wi);
 
     if (dimParams->diffusion <= 0)
     {
@@ -217,19 +213,16 @@ static void readDimParams(int *ninp_p, t_inpfile **inp_p, const char *prefix,
 
     if (bComment)
     {
-        printStringNoNewline(&ninp, &inp, "Diameter that needs to be sampled around a point before it is considered covered.");
+        printStringNoNewline(inp, "Diameter that needs to be sampled around a point before it is considered covered.");
     }
     sprintf(opt, "%s-cover-diameter", prefix);
-    dimParams->coverDiameter = get_ereal(&ninp, &inp, opt, 0, wi);
+    dimParams->coverDiameter = get_ereal(inp, opt, 0, wi);
 
     if (dimParams->coverDiameter < 0)
     {
         gmx_fatal(FARGS, "%s (%g) cannot be negative.",
                   opt, dimParams->coverDiameter);
     }
-
-    *ninp_p   = ninp;
-    *inp_p    = inp;
 }
 
 /*! \brief
@@ -255,30 +248,27 @@ static void checkInputConsistencyAwhBias(const AwhBiasParams &awhBiasParams,
 /*! \brief
  * Read parameters of an AWH bias.
  *
- * \param[in,out] ninp_p         Number of read input file entries.
- * \param[in,out] inp_p          Input file entries.
+ * \param[in,out] inp            Input file entries.
  * \param[in,out] awhBiasParams  AWH dimensional parameters.
  * \param[in]     prefix         Prefix for bias parameters.
  * \param[in]     ir             Input parameter struct.
  * \param[in,out] wi             Struct for bookeeping warnings.
  * \param[in]     bComment       True if comments should be printed.
  */
-static void read_bias_params(int *ninp_p, t_inpfile **inp_p, AwhBiasParams *awhBiasParams, const char *prefix,
+static void read_bias_params(std::vector<t_inpfile> *inp, AwhBiasParams *awhBiasParams, const char *prefix,
                              const t_inputrec *ir, warninp_t wi, bool bComment)
 {
-    int        ninp = *ninp_p;
-    t_inpfile *inp  = *inp_p;
     char       opt[STRLEN], prefixdim[STRLEN];
     char       warningmsg[STRLEN];
 
     if (bComment)
     {
-        printStringNoNewline(&ninp, &inp, "Estimated initial PMF error (kJ/mol)");
+        printStringNoNewline(inp, "Estimated initial PMF error (kJ/mol)");
     }
     sprintf(opt, "%s-error-init", prefix);
 
     /* We allow using a default value here without warning (but warn the user if the diffusion constant is not set). */
-    awhBiasParams->errorInitial = get_ereal(&ninp, &inp, opt, 10, wi);
+    awhBiasParams->errorInitial = get_ereal(inp, opt, 10, wi);
     if (awhBiasParams->errorInitial <= 0)
     {
         gmx_fatal(FARGS, "%s (%d) needs to be > 0.", opt);
@@ -286,17 +276,17 @@ static void read_bias_params(int *ninp_p, t_inpfile **inp_p, AwhBiasParams *awhB
 
     if (bComment)
     {
-        printStringNoNewline(&ninp, &inp, "Growth rate of the reference histogram determining the bias update size: exp-linear or linear");
+        printStringNoNewline(inp, "Growth rate of the reference histogram determining the bias update size: exp-linear or linear");
     }
     sprintf(opt, "%s-growth", prefix);
-    awhBiasParams->eGrowth = get_eeenum(&ninp, &inp, opt, eawhgrowth_names, wi);
+    awhBiasParams->eGrowth = get_eeenum(inp, opt, eawhgrowth_names, wi);
 
     if (bComment)
     {
-        printStringNoNewline(&ninp, &inp, "Start the simulation by equilibrating histogram towards the target distribution: no or yes");
+        printStringNoNewline(inp, "Start the simulation by equilibrating histogram towards the target distribution: no or yes");
     }
     sprintf(opt, "%s-equilibrate-histogram", prefix);
-    awhBiasParams->equilibrateHistogram = get_eeenum(&ninp, &inp, opt, yesno_names, wi);
+    awhBiasParams->equilibrateHistogram = get_eeenum(inp, opt, yesno_names, wi);
     if (awhBiasParams->equilibrateHistogram && awhBiasParams->eGrowth != eawhgrowthEXP_LINEAR)
     {
         sprintf(warningmsg, "Option %s will only have an effect for histogram growth type '%s'.",
@@ -306,10 +296,10 @@ static void read_bias_params(int *ninp_p, t_inpfile **inp_p, AwhBiasParams *awhB
 
     if (bComment)
     {
-        printStringNoNewline(&ninp, &inp, "Target distribution type: constant, cutoff, boltzmann or local-boltzmann");
+        printStringNoNewline(inp, "Target distribution type: constant, cutoff, boltzmann or local-boltzmann");
     }
     sprintf(opt, "%s-target", prefix);
-    awhBiasParams->eTarget = get_eeenum(&ninp, &inp, opt, eawhtarget_names, wi);
+    awhBiasParams->eTarget = get_eeenum(inp, opt, eawhtarget_names, wi);
 
     if ((awhBiasParams->eTarget == eawhtargetLOCALBOLTZMANN) &&
         (awhBiasParams->eGrowth == eawhgrowthEXP_LINEAR))
@@ -324,10 +314,10 @@ static void read_bias_params(int *ninp_p, t_inpfile **inp_p, AwhBiasParams *awhB
 
     if (bComment)
     {
-        printStringNoNewline(&ninp, &inp, "Boltzmann beta scaling factor for target distribution types 'boltzmann' and 'boltzmann-local'");
+        printStringNoNewline(inp, "Boltzmann beta scaling factor for target distribution types 'boltzmann' and 'boltzmann-local'");
     }
     sprintf(opt, "%s-target-beta-scaling", prefix);
-    awhBiasParams->targetBetaScaling = get_ereal(&ninp, &inp, opt, 0, wi);
+    awhBiasParams->targetBetaScaling = get_ereal(inp, opt, 0, wi);
 
     switch (awhBiasParams->eTarget)
     {
@@ -350,10 +340,10 @@ static void read_bias_params(int *ninp_p, t_inpfile **inp_p, AwhBiasParams *awhB
 
     if (bComment)
     {
-        printStringNoNewline(&ninp, &inp, "Free energy cutoff value for target distribution type 'cutoff'");
+        printStringNoNewline(inp, "Free energy cutoff value for target distribution type 'cutoff'");
     }
     sprintf(opt, "%s-target-cutoff", prefix);
-    awhBiasParams->targetCutoff = get_ereal(&ninp, &inp, opt, 0, wi);
+    awhBiasParams->targetCutoff = get_ereal(inp, opt, 0, wi);
 
     switch (awhBiasParams->eTarget)
     {
@@ -375,17 +365,17 @@ static void read_bias_params(int *ninp_p, t_inpfile **inp_p, AwhBiasParams *awhB
 
     if (bComment)
     {
-        printStringNoNewline(&ninp, &inp, "Initialize PMF and target with user data: no or yes");
+        printStringNoNewline(inp, "Initialize PMF and target with user data: no or yes");
     }
     sprintf(opt, "%s-user-data", prefix);
-    awhBiasParams->bUserData = get_eeenum(&ninp, &inp, opt, yesno_names, wi);
+    awhBiasParams->bUserData = get_eeenum(inp, opt, yesno_names, wi);
 
     if (bComment)
     {
-        printStringNoNewline(&ninp, &inp, "Group index to share the bias with, 0 means not shared");
+        printStringNoNewline(inp, "Group index to share the bias with, 0 means not shared");
     }
     sprintf(opt, "%s-share-group", prefix);
-    awhBiasParams->shareGroup = get_eint(&ninp, &inp, opt, 0, wi);
+    awhBiasParams->shareGroup = get_eint(inp, opt, 0, wi);
     if (awhBiasParams->shareGroup < 0)
     {
         warning_error(wi, "AWH bias share-group should be >= 0");
@@ -393,10 +383,10 @@ static void read_bias_params(int *ninp_p, t_inpfile **inp_p, AwhBiasParams *awhB
 
     if (bComment)
     {
-        printStringNoNewline(&ninp, &inp, "Dimensionality of the coordinate");
+        printStringNoNewline(inp, "Dimensionality of the coordinate");
     }
     sprintf(opt, "%s-ndim", prefix);
-    awhBiasParams->ndim = get_eint(&ninp, &inp, opt, 0, wi);
+    awhBiasParams->ndim = get_eint(inp, opt, 0, wi);
 
     if (awhBiasParams->ndim <= 0 ||
         awhBiasParams->ndim > c_biasMaxNumDim)
@@ -413,14 +403,11 @@ static void read_bias_params(int *ninp_p, t_inpfile **inp_p, AwhBiasParams *awhB
     {
         bComment = bComment && d == 0;
         sprintf(prefixdim, "%s-dim%d", prefix, d + 1);
-        readDimParams(&ninp, &inp, prefixdim, &awhBiasParams->dimParams[d], ir->pull, wi, bComment);
+        readDimParams(inp, prefixdim, &awhBiasParams->dimParams[d], ir->pull, wi, bComment);
     }
 
     /* Check consistencies here that cannot be checked at read time at a lower level. */
     checkInputConsistencyAwhBias(*awhBiasParams, wi);
-
-    *ninp_p   = ninp;
-    *inp_p    = inp;
 }
 
 /*! \brief
@@ -481,36 +468,33 @@ static void checkInputConsistencyAwh(const AwhParams &awhParams,
     }
 }
 
-AwhParams *readAndCheckAwhParams(int *ninp_p, t_inpfile **inp_p, const t_inputrec *ir, warninp_t wi)
+AwhParams *readAndCheckAwhParams(std::vector<t_inpfile> *inp, const t_inputrec *ir, warninp_t wi)
 {
     char       opt[STRLEN], prefix[STRLEN], prefixawh[STRLEN];
 
     AwhParams *awhParams;
     snew(awhParams, 1);
 
-    int        ninp = *ninp_p;
-    t_inpfile *inp  = *inp_p;
-
     sprintf(prefix, "%s", "awh");
 
     /* Parameters common for all biases */
 
-    printStringNoNewline(&ninp, &inp, "The way to apply the biasing potential: convolved or umbrella");
+    printStringNoNewline(inp, "The way to apply the biasing potential: convolved or umbrella");
     sprintf(opt, "%s-potential", prefix);
-    awhParams->ePotential = get_eeenum(&ninp, &inp, opt, eawhpotential_names, wi);
+    awhParams->ePotential = get_eeenum(inp, opt, eawhpotential_names, wi);
 
-    printStringNoNewline(&ninp, &inp, "The random seed used for sampling the umbrella center in the case of umbrella type potential");
+    printStringNoNewline(inp, "The random seed used for sampling the umbrella center in the case of umbrella type potential");
     sprintf(opt, "%s-seed", prefix);
-    awhParams->seed = get_eint(&ninp, &inp, opt, -1, wi);
+    awhParams->seed = get_eint(inp, opt, -1, wi);
     if (awhParams->seed == -1)
     {
         awhParams->seed = static_cast<int>(gmx::makeRandomSeed());
         fprintf(stderr, "Setting the AWH bias MC random seed to %" GMX_PRId64 "\n", awhParams->seed);
     }
 
-    printStringNoNewline(&ninp, &inp, "Data output interval in number of steps");
+    printStringNoNewline(inp, "Data output interval in number of steps");
     sprintf(opt, "%s-nstout", prefix);
-    awhParams->nstOut = get_eint(&ninp, &inp, opt, 100000, wi);
+    awhParams->nstOut = get_eint(inp, opt, 100000, wi);
     if (awhParams->nstOut <= 0)
     {
         char buf[STRLEN];
@@ -527,21 +511,21 @@ AwhParams *readAndCheckAwhParams(int *ninp_p, t_inpfile **inp_p, const t_inputre
         warning_error(wi, buf);
     }
 
-    printStringNoNewline(&ninp, &inp, "Coordinate sampling interval in number of steps");
+    printStringNoNewline(inp, "Coordinate sampling interval in number of steps");
     sprintf(opt, "%s-nstsample", prefix);
-    awhParams->nstSampleCoord = get_eint(&ninp, &inp, opt, 10, wi);
+    awhParams->nstSampleCoord = get_eint(inp, opt, 10, wi);
 
-    printStringNoNewline(&ninp, &inp, "Free energy and bias update interval in number of samples");
+    printStringNoNewline(inp, "Free energy and bias update interval in number of samples");
     sprintf(opt, "%s-nsamples-update", prefix);
-    awhParams->numSamplesUpdateFreeEnergy = get_eint(&ninp, &inp, opt, 10, wi);
+    awhParams->numSamplesUpdateFreeEnergy = get_eint(inp, opt, 10, wi);
 
-    printStringNoNewline(&ninp, &inp, "When true, biases with share-group>0 are shared between multiple simulations");
+    printStringNoNewline(inp, "When true, biases with share-group>0 are shared between multiple simulations");
     sprintf(opt, "%s-share-multisim", prefix);
-    awhParams->shareBiasMultisim = get_eeenum(&ninp, &inp, opt, yesno_names, wi);
+    awhParams->shareBiasMultisim = get_eeenum(inp, opt, yesno_names, wi);
 
-    printStringNoNewline(&ninp, &inp, "The number of independent AWH biases");
+    printStringNoNewline(inp, "The number of independent AWH biases");
     sprintf(opt, "%s-nbias", prefix);
-    awhParams->numBias = get_eint(&ninp, &inp, opt, 1, wi);
+    awhParams->numBias = get_eint(inp, opt, 1, wi);
     if (awhParams->numBias <= 0)
     {
         gmx_fatal(FARGS, "%s needs to be an integer > 0", opt);
@@ -554,7 +538,7 @@ AwhParams *readAndCheckAwhParams(int *ninp_p, t_inpfile **inp_p, const t_inputre
     {
         bool bComment = (k == 0);
         sprintf(prefixawh, "%s%d", prefix, k + 1);
-        read_bias_params(&ninp, &inp, &awhParams->awhBiasParams[k], prefixawh, ir, wi, bComment);
+        read_bias_params(inp, &awhParams->awhBiasParams[k], prefixawh, ir, wi, bComment);
     }
 
     /* Do a final consistency check before returning */
@@ -565,9 +549,6 @@ AwhParams *readAndCheckAwhParams(int *ninp_p, t_inpfile **inp_p, const t_inputre
         warning_error(wi, "With AWH init-step should be 0");
     }
 
-    *ninp_p   = ninp;
-    *inp_p    = inp;
-
     return awhParams;
 }
 
index f22fad92b8548a30a0245f555d1ac7e80b092baf..5c5be7a4f9010dfb6e7bbe9e42e604f0141548d0 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * 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.
@@ -60,16 +60,14 @@ struct AwhParams;
 
 /*! \brief Allocate, initialize and check the AWH parameters with values from the input file.
  *
- * \param[in,out] ninp_p       Number of read input file entries.
- * \param[in,out] inp_p        Input file entries.
+ * \param[in,out] inp          Input file entries.
  * \param[in]     inputrec     Input parameter struct.
  * \param[in,out] wi           Struct for bookeeping warnings.
  * \returns AWH parameters.
  */
-AwhParams *readAndCheckAwhParams(int               *ninp_p,
-                                 t_inpfile        **inp_p,
-                                 const t_inputrec  *inputrec,
-                                 warninp_t          wi);
+AwhParams *readAndCheckAwhParams(std::vector<t_inpfile> *inp,
+                                 const t_inputrec       *inputrec,
+                                 warninp_t               wi);
 
 
 /*! \brief
index 2dba58e4b8404f1c6ca6fcce8defbd10f03d5484..b3d26d43124ba0f42bfb0e443cd9a13fd7a3e4b9 100644 (file)
 #include "gromacs/utility/textreader.h"
 #include "gromacs/utility/textwriter.h"
 
-t_inpfile *read_inpfile(gmx::TextInputStream *stream, const char *fn, int *ninp,
-                        warninp_t wi)
+std::vector<t_inpfile>
+read_inpfile(gmx::TextInputStream *stream, const char *fn,
+             warninp_t wi)
 {
-    t_inpfile *inp = nullptr;
+    std::vector<t_inpfile> inp;
 
     if (debug)
     {
@@ -68,7 +69,6 @@ t_inpfile *read_inpfile(gmx::TextInputStream *stream, const char *fn, int *ninp,
     }
 
     int             indexOfLineReadFromFile = 0;
-    int             countOfUniqueKeysFound  = 0;
     std::string     line;
     gmx::TextReader reader(stream);
     reader.setTrimTrailingWhiteSpace(true);
@@ -125,19 +125,13 @@ t_inpfile *read_inpfile(gmx::TextInputStream *stream, const char *fn, int *ninp,
         }
 
         /* Now finally something sensible; check for duplicates */
-        int found_index = search_einp(countOfUniqueKeysFound, inp, tokens[0].c_str());
+        int found_index = search_einp(inp, tokens[0].c_str());
 
         if (found_index == -1)
         {
             /* add a new item */
-            srenew(inp, ++countOfUniqueKeysFound);
-            inp[countOfUniqueKeysFound-1].inp_count              = 1;
-            inp[countOfUniqueKeysFound-1].count                  = 0;
-            inp[countOfUniqueKeysFound-1].bObsolete              = FALSE;
-            inp[countOfUniqueKeysFound-1].bHandledAsKeyValueTree = FALSE;
-            inp[countOfUniqueKeysFound-1].bSet                   = FALSE;
-            inp[countOfUniqueKeysFound-1].name                   = gmx_strdup(tokens[0].c_str());
-            inp[countOfUniqueKeysFound-1].value                  = gmx_strdup(tokens[1].c_str());
+            inp.push_back(t_inpfile(0, 1, false, false, false,
+                                    tokens[0], tokens[1]));
         }
         else
         {
@@ -154,60 +148,61 @@ t_inpfile *read_inpfile(gmx::TextInputStream *stream, const char *fn, int *ninp,
 
     if (debug)
     {
-        fprintf(debug, "Done reading MDP file, there were %d entries in there\n",
-                countOfUniqueKeysFound);
+        fprintf(debug, "Done reading MDP file, there were %zu entries in there\n",
+                inp.size());
     }
 
-    *ninp = countOfUniqueKeysFound;
-
     return inp;
 }
 
-gmx::KeyValueTreeObject flatKeyValueTreeFromInpFile(int ninp, t_inpfile inp[])
+gmx::KeyValueTreeObject flatKeyValueTreeFromInpFile(gmx::ArrayRef<const t_inpfile> inp)
 {
     gmx::KeyValueTreeBuilder  builder;
     auto                      root = builder.rootObject();
-    for (int i = 0; i < ninp; ++i)
+    for (auto &local : inp)
     {
-        const char *value = inp[i].value;
-        root.addValue<std::string>(inp[i].name, value != nullptr ? value : "");
+        root.addValue<std::string>(local.name_, !local.value_.empty() ? local.value_ : "");
     }
     return builder.build();
 }
 
 
-static int inp_comp(const void *a, const void *b)
+struct inp_comp
 {
-    return (reinterpret_cast<const t_inpfile *>(a))->count - (reinterpret_cast<const t_inpfile *>(b))->count;
-}
+    bool operator()(t_inpfile const &a, t_inpfile const &b)
+    {
+        return a.count_ < b.count_;
+    }
+};
 
-static void sort_inp(int ninp, t_inpfile inp[])
+static void sort_inp(std::vector<t_inpfile> *inp)
 {
-    int i, mm;
+    std::vector<t_inpfile> &inpRef = *inp;
+    int                     mm;
 
     mm = -1;
-    for (i = 0; (i < ninp); i++)
+    for (const auto &local : inpRef)
     {
-        mm = std::max(mm, inp[i].count);
+        mm = std::max(mm, local.count_);
     }
-    for (i = 0; (i < ninp); i++)
+    for (auto &local : inpRef)
     {
-        if (inp[i].count == 0)
+        if (local.count_ == 0)
         {
-            inp[i].count = mm++;
+            local.count_ = mm++;
         }
     }
-    gmx_qsort(inp, ninp, static_cast<size_t>(sizeof(inp[0])), inp_comp);
+    std::sort(inpRef.begin(), inpRef.end(), inp_comp());
 }
 
-void write_inpfile(gmx::TextOutputStream *stream, const char *fn, int ninp, t_inpfile inp[],
+void write_inpfile(gmx::TextOutputStream *stream, const char *fn, std::vector<t_inpfile> *inp,
                    gmx_bool bHaltOnUnknown,
                    WriteMdpHeader writeHeader,
                    warninp_t wi)
 {
     using gmx::formatString;
 
-    sort_inp(ninp, inp);
+    sort_inp(inp);
 
     gmx::TextWriter writer(stream);
     if (writeHeader == WriteMdpHeader::yes)
@@ -219,27 +214,26 @@ void write_inpfile(gmx::TextOutputStream *stream, const char *fn, int ninp, t_in
         settings.linePrefix(";\t");
         gmx::printBinaryInformation(&writer, gmx::getProgramContext(), settings);
     }
-
-    for (int i = 0; (i < ninp); i++)
+    for (const auto &local : *inp)
     {
-        if (inp[i].bHandledAsKeyValueTree)
+        if (local.bHandledAsKeyValueTree_)
         {
         }
-        else if (inp[i].bSet)
+        else if (local.bSet_)
         {
-            if (inp[i].name[0] == ';' || (strlen(inp[i].name) > 2 && inp[i].name[1] == ';'))
+            if (local.name_[0] == ';' || (local.name_.length() > 2 && local.name_[1] == ';'))
             {
-                writer.writeLine(formatString("%-24s", inp[i].name));
+                writer.writeLine(formatString("%-24s", local.name_.c_str()));
             }
             else
             {
-                writer.writeLine(formatString("%-24s = %s", inp[i].name, inp[i].value ? inp[i].value : ""));
+                writer.writeLine(formatString("%-24s = %s", local.name_.c_str(), !local.value_.empty() ? local.value_.c_str() : ""));
             }
         }
-        else if (!inp[i].bObsolete)
+        else if (!local.bObsolete_)
         {
             auto message = formatString("Unknown left-hand '%s' in parameter file\n",
-                                        inp[i].name);
+                                        local.name_.c_str());
             if (bHaltOnUnknown)
             {
                 warning_error(wi, message.c_str());
@@ -254,49 +248,44 @@ void write_inpfile(gmx::TextOutputStream *stream, const char *fn, int ninp, t_in
     check_warning_error(wi, FARGS);
 }
 
-void replace_inp_entry(int ninp, t_inpfile *inp, const char *old_entry, const char *new_entry)
+void replace_inp_entry(gmx::ArrayRef<t_inpfile> inp, const char *old_entry, const char *new_entry)
 {
-    int  i;
-
-    for (i = 0; (i < ninp); i++)
+    for (auto &local : inp)
     {
-        if (gmx_strcasecmp_min(old_entry, inp[i].name) == 0)
+        if (gmx_strcasecmp_min(old_entry, local.name_.c_str()) == 0)
         {
             if (new_entry)
             {
                 fprintf(stderr, "Replacing old mdp entry '%s' by '%s'\n",
-                        inp[i].name, new_entry);
+                        local.name_.c_str(), new_entry);
 
-                int foundIndex = search_einp(ninp, inp, new_entry);
+                int foundIndex = search_einp(inp, new_entry);
                 if (foundIndex >= 0)
                 {
-                    gmx_fatal(FARGS, "A parameter is present with both the old name '%s' and the new name '%s'.", inp[i].name, inp[foundIndex].name);
+                    gmx_fatal(FARGS, "A parameter is present with both the old name '%s' and the new name '%s'.", local.name_.c_str(), inp[foundIndex].name_.c_str());
                 }
 
-                sfree(inp[i].name);
-                inp[i].name = gmx_strdup(new_entry);
+                local.name_.assign(new_entry);
             }
             else
             {
                 fprintf(stderr, "Ignoring obsolete mdp entry '%s'\n",
-                        inp[i].name);
-                inp[i].bObsolete = TRUE;
+                        local.name_.c_str());
+                local.bObsolete_ = TRUE;
             }
         }
     }
 }
 
-int search_einp(int ninp, const t_inpfile *inp, const char *name)
+int search_einp(gmx::ArrayRef<const t_inpfile> inp, const char *name)
 {
-    int i;
-
-    if (inp == nullptr)
+    if (inp.empty())
     {
         return -1;
     }
-    for (i = 0; i < ninp; i++)
+    for (size_t i = 0; i < inp.size(); i++)
     {
-        if (gmx_strcasecmp_min(name, inp[i].name) == 0)
+        if (gmx_strcasecmp_min(name, inp[i].name_.c_str()) == 0)
         {
             return i;
         }
@@ -304,47 +293,44 @@ int search_einp(int ninp, const t_inpfile *inp, const char *name)
     return -1;
 }
 
-void mark_einp_set(int ninp, t_inpfile *inp, const char *name)
+void mark_einp_set(gmx::ArrayRef<t_inpfile> inp, const char *name)
 {
-    int i = search_einp(ninp, inp, name);
+    int                     i      = search_einp(inp, name);
     if (i != -1)
     {
-        inp[i].count = inp[0].inp_count++;
-        inp[i].bSet  = TRUE;
+        inp[i].count_ = inp.front().inp_count_++;
+        inp[i].bSet_  = TRUE;
         /* Prevent mdp lines being written twice for
            options that are handled via key-value trees. */
-        inp[i].bHandledAsKeyValueTree = TRUE;
-
+        inp[i].bHandledAsKeyValueTree_ = TRUE;
     }
 }
 
-static int get_einp(int *ninp, t_inpfile **inp, const char *name)
+static int get_einp(std::vector<t_inpfile> *inp, const char *name)
 {
-    int    i;
-    int    notfound = FALSE;
+    std::vector<t_inpfile> &inpRef   = *inp;
+    bool                    notfound = false;
+
+    int                     i = search_einp(inpRef, name);
 
-    i = search_einp(*ninp, *inp, name);
     if (i == -1)
     {
-        notfound = TRUE;
-        i        = (*ninp)++;
-        srenew(*inp, (*ninp));
-        (*inp)[i].name                   = gmx_strdup(name);
-        (*inp)[i].bSet                   = TRUE;
-        (*inp)[i].bHandledAsKeyValueTree = FALSE;
-        if (i == 0)
+        notfound = true;
+        inpRef.push_back(t_inpfile(0, 0, false, true, false,
+                                   name, ""));
+        i = inpRef.size() - 1;
+        if (inpRef.size()  == 1)
         {
-            (*inp)[i].inp_count = 1;
+            inpRef.front().inp_count_ = 1;
         }
     }
-    (*inp)[i].count = (*inp)[0].inp_count++;
-    (*inp)[i].bSet  = TRUE;
+    inpRef[i].count_ = inpRef.front().inp_count_++;
+    inpRef[i].bSet_  = TRUE;
     if (debug)
     {
-        fprintf(debug, "Inp %d = %s\n", (*inp)[i].count, (*inp)[i].name);
+        fprintf(debug, "Inp %d = %s\n", inpRef[i].count_, inpRef[i].name_.c_str());
     }
 
-    /*if (i == (*ninp)-1)*/
     if (notfound)
     {
         return -1;
@@ -355,29 +341,28 @@ static int get_einp(int *ninp, t_inpfile **inp, const char *name)
     }
 }
 
-/* Note that sanitizing the trailing part of (*inp)[ii].value was the responsibility of read_inpfile() */
-int get_eint(int *ninp, t_inpfile **inp, const char *name, int def,
+/* Note that sanitizing the trailing part of inp[ii].value was the responsibility of read_inpfile() */
+int get_eint(std::vector<t_inpfile> *inp, const char *name, int def,
              warninp_t wi)
 {
-    char buf[32], *ptr, warn_buf[STRLEN];
-    int  ii;
-    int  ret;
+    std::vector<t_inpfile> &inpRef = *inp;
+    char                    buf[32], *ptr, warn_buf[STRLEN];
 
-    ii = get_einp(ninp, inp, name);
+    int                     ii = get_einp(inp, name);
 
     if (ii == -1)
     {
         sprintf(buf, "%d", def);
-        (*inp)[(*ninp)-1].value = gmx_strdup(buf);
+        inpRef.back().value_.assign(buf);
 
         return def;
     }
     else
     {
-        ret = std::strtol((*inp)[ii].value, &ptr, 10);
+        int ret = std::strtol(inpRef[ii].value_.c_str(), &ptr, 10);
         if (*ptr != '\0')
         {
-            sprintf(warn_buf, "Right hand side '%s' for parameter '%s' in parameter file is not an integer value\n", (*inp)[ii].value, (*inp)[ii].name);
+            sprintf(warn_buf, "Right hand side '%s' for parameter '%s' in parameter file is not an integer value\n", inpRef[ii].value_.c_str(), inpRef[ii].name_.c_str());
             warning_error(wi, warn_buf);
         }
 
@@ -385,30 +370,29 @@ int get_eint(int *ninp, t_inpfile **inp, const char *name, int def,
     }
 }
 
-/* Note that sanitizing the trailing part of (*inp)[ii].value was the responsibility of read_inpfile() */
-gmx_int64_t get_eint64(int *ninp, t_inpfile **inp,
+/* Note that sanitizing the trailing part of inp[ii].value was the responsibility of read_inpfile() */
+gmx_int64_t get_eint64(std::vector<t_inpfile> *inp,
                        const char *name, gmx_int64_t def,
                        warninp_t wi)
 {
-    char            buf[32], *ptr, warn_buf[STRLEN];
-    int             ii;
-    gmx_int64_t     ret;
+    std::vector<t_inpfile> &inpRef = *inp;
+    char                    buf[32], *ptr, warn_buf[STRLEN];
 
-    ii = get_einp(ninp, inp, name);
+    int                     ii = get_einp(inp, name);
 
     if (ii == -1)
     {
         sprintf(buf, "%" GMX_PRId64, def);
-        (*inp)[(*ninp)-1].value = gmx_strdup(buf);
+        inpRef.back().value_.assign(buf);
 
         return def;
     }
     else
     {
-        ret = str_to_int64_t((*inp)[ii].value, &ptr);
+        gmx_int64_t ret = str_to_int64_t(inpRef[ii].value_.c_str(), &ptr);
         if (*ptr != '\0')
         {
-            sprintf(warn_buf, "Right hand side '%s' for parameter '%s' in parameter file is not an integer value\n", (*inp)[ii].value, (*inp)[ii].name);
+            sprintf(warn_buf, "Right hand side '%s' for parameter '%s' in parameter file is not an integer value\n", inpRef[ii].value_.c_str(), inpRef[ii].name_.c_str());
             warning_error(wi, warn_buf);
         }
 
@@ -416,29 +400,28 @@ gmx_int64_t get_eint64(int *ninp, t_inpfile **inp,
     }
 }
 
-/* Note that sanitizing the trailing part of (*inp)[ii].value was the responsibility of read_inpfile() */
-double get_ereal(int *ninp, t_inpfile **inp, const char *name, double def,
+/* Note that sanitizing the trailing part of inp[ii].value was the responsibility of read_inpfile() */
+double get_ereal(std::vector<t_inpfile> *inp, const char *name, double def,
                  warninp_t wi)
 {
-    char   buf[32], *ptr, warn_buf[STRLEN];
-    int    ii;
-    double ret;
+    std::vector<t_inpfile> &inpRef = *inp;
+    char                    buf[32], *ptr, warn_buf[STRLEN];
 
-    ii = get_einp(ninp, inp, name);
+    int                     ii = get_einp(inp, name);
 
     if (ii == -1)
     {
         sprintf(buf, "%g", def);
-        (*inp)[(*ninp)-1].value = gmx_strdup(buf);
+        inpRef.back().value_.assign(buf);
 
         return def;
     }
     else
     {
-        ret = strtod((*inp)[ii].value, &ptr);
+        double ret = strtod(inpRef[ii].value_.c_str(), &ptr);
         if (*ptr != '\0')
         {
-            sprintf(warn_buf, "Right hand side '%s' for parameter '%s' in parameter file is not a real value\n", (*inp)[ii].value, (*inp)[ii].name);
+            sprintf(warn_buf, "Right hand side '%s' for parameter '%s' in parameter file is not a real value\n", inpRef[ii].value_.c_str(), inpRef[ii].name_.c_str());
             warning_error(wi, warn_buf);
         }
 
@@ -446,54 +429,54 @@ double get_ereal(int *ninp, t_inpfile **inp, const char *name, double def,
     }
 }
 
-/* Note that sanitizing the trailing part of (*inp)[ii].value was the responsibility of read_inpfile() */
-const char *get_estr(int *ninp, t_inpfile **inp, const char *name, const char *def)
+/* Note that sanitizing the trailing part of inp[ii].value was the responsibility of read_inpfile() */
+const char *get_estr(std::vector<t_inpfile> *inp, const char *name, const char *def)
 {
-    char buf[32];
-    int  ii;
+    std::vector<t_inpfile> &inpRef = *inp;
+    char                    buf[32];
 
-    ii = get_einp(ninp, inp, name);
+    int                     ii = get_einp(inp, name);
 
     if (ii == -1)
     {
         if (def)
         {
             sprintf(buf, "%s", def);
-            (*inp)[(*ninp)-1].value = gmx_strdup(buf);
+            inpRef.back().value_.assign(buf);
         }
         else
         {
-            (*inp)[(*ninp)-1].value = nullptr;
+            inpRef.back().value_.clear();
         }
 
         return def;
     }
     else
     {
-        return (*inp)[ii].value;
+        return inpRef[ii].value_.c_str();
     }
 }
 
-/* Note that sanitizing the trailing part of (*inp)[ii].value was the responsibility of read_inpfile() */
-int get_eeenum(int *ninp, t_inpfile **inp, const char *name, const char **defs,
+/* Note that sanitizing the trailing part of inp[ii].value was the responsibility of read_inpfile() */
+int get_eeenum(std::vector<t_inpfile> *inp, const char *name, const char **defs,
                warninp_t wi)
 {
-    int  ii, i, j;
-    int  n = 0;
-    char buf[STRLEN];
+    std::vector<t_inpfile> &inpRef = *inp;
+    int                     n      = 0;
+    char                    buf[STRLEN];
 
-    ii = get_einp(ninp, inp, name);
+    int                     ii = get_einp(inp, name);
 
     if (ii == -1)
     {
-        (*inp)[(*ninp)-1].value = gmx_strdup(defs[0]);
+        inpRef.back().value_.assign(defs[0]);
 
         return 0;
     }
-
+    int i = 0;
     for (i = 0; (defs[i] != nullptr); i++)
     {
-        if (gmx_strcasecmp_min(defs[i], (*inp)[ii].value) == 0)
+        if (gmx_strcasecmp_min(defs[i], inpRef[ii].value_.c_str()) == 0)
         {
             break;
         }
@@ -502,9 +485,9 @@ int get_eeenum(int *ninp, t_inpfile **inp, const char *name, const char **defs,
     if (defs[i] == nullptr)
     {
         n += sprintf(buf, "Invalid enum '%s' for variable %s, using '%s'\n",
-                     (*inp)[ii].value, name, defs[0]);
+                     inpRef[ii].value_.c_str(), name, defs[0]);
         n += sprintf(buf+n, "Next time use one of:");
-        j  = 0;
+        int j  = 0;
         while (defs[j])
         {
             n += sprintf(buf+n, " '%s'", defs[j]);
@@ -519,7 +502,7 @@ int get_eeenum(int *ninp, t_inpfile **inp, const char *name, const char **defs,
             fprintf(stderr, "%s\n", buf);
         }
 
-        (*inp)[ii].value = gmx_strdup(defs[0]);
+        inpRef[ii].value_ = gmx_strdup(defs[0]);
 
         return 0;
     }
@@ -527,31 +510,31 @@ int get_eeenum(int *ninp, t_inpfile **inp, const char *name, const char **defs,
     return i;
 }
 
-int get_eenum(int *ninp, t_inpfile **inp, const char *name, const char **defs)
+int get_eenum(std::vector<t_inpfile> *inp, const char *name, const char **defs)
 {
-    return get_eeenum(ninp, inp, name, defs, nullptr);
+    return get_eeenum(inp, name, defs, nullptr);
 }
 
 void
-printStringNewline(int *ninp, t_inpfile **inp, const char *line)
+printStringNewline(std::vector<t_inpfile> *inp, const char *line)
 {
     std::string tmp("\n; ");
     tmp.append(line);
-    get_estr(ninp, inp, tmp.c_str(), NULL);
+    get_estr(inp, tmp.c_str(), NULL);
 }
 
 void
-printStringNoNewline(int *ninp, t_inpfile **inp, const char *line)
+printStringNoNewline(std::vector<t_inpfile> *inp, const char *line)
 {
     std::string tmp("; ");
     tmp.append(line);
-    get_estr(ninp, inp, tmp.c_str(), NULL);
+    get_estr(inp, tmp.c_str(), NULL);
 }
 void
-setStringEntry(int *ninp, t_inpfile **inp, const char *name, char *newName, const char *def)
+setStringEntry(std::vector<t_inpfile> *inp, const char *name, char *newName, const char *def)
 {
     const char *found = nullptr;
-    found = get_estr(ninp, inp, name, def);
+    found = get_estr(inp, name, def);
     if (found != nullptr)
     {
         std::strcpy(newName, found);
index fa35b5f2caba78ebf66c2963a45f19e07d500926..2ed89b4c49ef88f9bd178ac5ca569f704151cb91 100644 (file)
 
 #include <cstring>
 
+#include <string>
+#include <vector>
+
+#include "gromacs/utility/arrayref.h"
 #include "gromacs/utility/basedefinitions.h"
 
 struct warninp;
@@ -51,33 +55,50 @@ class TextInputStream;
 class TextOutputStream;
 }
 
-typedef struct t_inpfile {
-    int      count;                  /* sort order for output  */
-    gmx_bool bObsolete;              /* whether it is an obsolete param value */
-    gmx_bool bSet;                   /* whether it it has been read out */
-    gmx_bool bHandledAsKeyValueTree; /* whether it it has been handled with key-value machinery */
-    char    *name;                   /* name of the parameter */
-    char    *value;                  /* parameter value string */
-    int      inp_count;              /* number of einps read. Only valid for the first item
-                                                              in the inpfile list. */
-} t_inpfile;
-/* entry in input files (like .mdp files).
-   Initally read in with read_inpfile, then filled in with missing values
-   through get_eint, get_ereal, etc. */
-
-/*! \brief Create and return an array of \c ninp t_inpfile structs
+/* !\brief Input file structure that is populated with entries read from a file.
+ *
+ * This structure contains the information read from the mdp file that is later used
+ * to build the ir from it. It is first constructed with a set of names and values,
+ * and later populated when checking against the available options in readir.
+ * Uses the functions below to both check entries and set the information.
+ */
+struct t_inpfile
+{
+    /*!\brief Minimum allowed constructor sets all elements */
+    t_inpfile (int count, int inp_count, bool bObsolete, bool bSet, bool bHandledAsKeyValueTree,
+               std::string name, std::string value) :
+        count_(count),
+        bObsolete_(bObsolete),
+        bSet_(bSet),
+        bHandledAsKeyValueTree_(bHandledAsKeyValueTree),
+        name_(name),
+        value_(value),
+        inp_count_(inp_count)
+    {
+    }
+    int         count_;                  /* sort order for output  */
+    bool        bObsolete_;              /* whether it is an obsolete param value */
+    bool        bSet_;                   /* whether it it has been read out */
+    bool        bHandledAsKeyValueTree_; /* whether it it has been handled with key-value machinery */
+    std::string name_;                   /* name of the parameter */
+    std::string value_;                  /* parameter value string */
+    int         inp_count_;              /* number of einps read. Only valid for the first item
+                                                                 in the inpfile list. */
+};
+
+/*! \brief Create and return a vector of t_inpfile structs
  * from "key = value" lines in \c stream corresponding to file \c fn.
  *
  * \param[in]  stream          Text stream to read.
  * \param[in]  fn              Filename corresponding to \c reader.
- * \param[out] ninp            Length of returned array.
  * \param[out] wi              Handler for context-sensitive warnings.
  * \throws     std::bad_alloc  If out of memory.
  * \throws     Anything the stream underlying \c reader can throw. */
-t_inpfile *read_inpfile(gmx::TextInputStream *stream, const char *fn, int *ninp,
-                        warninp_t wi);
+std::vector<t_inpfile>
+read_inpfile(gmx::TextInputStream *stream, const char *fn,
+             warninp_t wi);
 
-gmx::KeyValueTreeObject flatKeyValueTreeFromInpFile(int ninp, t_inpfile inp[]);
+gmx::KeyValueTreeObject flatKeyValueTreeFromInpFile(gmx::ArrayRef<const t_inpfile> inp);
 
 enum class WriteMdpHeader
 {
@@ -88,14 +109,13 @@ enum class WriteMdpHeader
  *
  * \param[in]  stream          Text stream to write.
  * \param[in]  fn              Filename corresponding to \c stream.
- * \param[in]  ninp            Length of \c inp.
- * \param[in]  inp             Array of key-value pairs.
+ * \param[in]  inp             vector of key-value pairs.
  * \param[in]  bHaltOnUnknown  Whether to issue a fatal error if an unknown key is found.
  * \param[in]  writeHeader     Whether to write a header recording some context a user might like.
  * \param[out] wi              Handler for context-sensitive warnings.
  * \throws     std::bad_alloc  If out of memory.
  * \throws     Anything the stream underlying \c writer can throw. */
-void write_inpfile(gmx::TextOutputStream *stream, const char *fn, int ninp, t_inpfile inp[],
+void write_inpfile(gmx::TextOutputStream *stream, const char *fn, std::vector<t_inpfile> *inp,
                    gmx_bool bHaltOnUnknown,
                    WriteMdpHeader writeHeader,
                    warninp_t wi);
@@ -103,39 +123,39 @@ void write_inpfile(gmx::TextOutputStream *stream, const char *fn, int ninp, t_in
  * unknown. The helpful header contains irreproducible content, so
  * its writing can be suppressed to make testing more useful. */
 
-void replace_inp_entry(int ninp, t_inpfile *inp,
+void replace_inp_entry(gmx::ArrayRef<t_inpfile> inp,
                        const char *old_entry, const char *new_entry);
 
-int search_einp(int ninp, const t_inpfile *inp, const char *name);
+int search_einp(gmx::ArrayRef<const t_inpfile> inp, const char *name);
 /* Return the index of an .mdp field with the given name within the
- * inp array, if it exists. Return -1 if it does not exist. */
+ * inp vector, if it exists. Return -1 if it does not exist. */
 
-void mark_einp_set(int ninp, t_inpfile *inp, const char *name);
+void mark_einp_set(gmx::ArrayRef<t_inpfile> inp, const char *name);
 
-int get_eint(int *ninp, t_inpfile **inp, const char *name, int def,
+int get_eint(std::vector<t_inpfile> *inp, const char *name, int def,
              warninp_t wi);
 
-gmx_int64_t get_eint64(int *ninp, t_inpfile **inp,
+gmx_int64_t get_eint64(std::vector<t_inpfile> *inp,
                        const char *name, gmx_int64_t def,
                        warninp_t);
 
-double get_ereal(int *ninp, t_inpfile **inp, const char *name, double def,
+double get_ereal(std::vector<t_inpfile> *inp, const char *name, double def,
                  warninp_t wi);
 
-const char *get_estr(int *ninp, t_inpfile **inp, const char *name, const char *def);
+const char *get_estr(std::vector<t_inpfile> *inp, const char *name, const char *def);
 
-int get_eeenum(int *ninp, t_inpfile **inp, const char *name, const char **defs,
+int get_eeenum(std::vector<t_inpfile> *inp, const char *name, const char **defs,
                warninp_t wi);
 /* defs must be NULL terminated */
 
-int get_eenum(int *ninp, t_inpfile **inp, const char *name, const char **defs);
+int get_eenum(std::vector<t_inpfile> *inp, const char *name, const char **defs);
 /* defs must be NULL terminated */
 
 //! Replace for macro CCTYPE, prints comment string after newline
-void printStringNewline(int *ninp, t_inpfile **inp, const char *line);
+void printStringNewline(std::vector<t_inpfile> *inp, const char *line);
 //! Replace for macro CTYPE, prints comment string
-void printStringNoNewline(int *ninp, t_inpfile **inp, const char *line);
+void printStringNoNewline(std::vector<t_inpfile> *inp, const char *line);
 //! Replace for macro STYPE, checks for existing string entry and if possible replaces it
-void setStringEntry(int *ninp, t_inpfile **inp, const char *name, char *newName, const char *def);
+void setStringEntry(std::vector<t_inpfile> *inp, const char *name, char *newName, const char *def);
 
 #endif
index 61f8d27998d780bafb82788de492498f6dd9f97f..e3d764ce8cc1fa087826b9eeb8ee524ddece86d3 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2016,2017, by the GROMACS development team, led by
+ * Copyright (c) 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.
@@ -56,92 +56,79 @@ namespace testing
 class ReadTest : public ::testing::Test
 {
     public:
-        ReadTest() : numInputs_(1),
-                     inputField_(nullptr),
-                     inpGuard_(),
-                     wi_(),
-                     wiGuard_()
+        ReadTest() : inputField_ {{(t_inpfile(0, 0, false, false, false, "test", ""))}},
+        wi_(),
+        wiGuard_()
         {
-            snew(inputField_, numInputs_);
-            inpGuard_.reset(inputField_);
-
-            inputField_[0].count     = 0;
-            inputField_[0].bObsolete = FALSE;
-            inputField_[0].bSet      = FALSE;
-            inputField_[0].name      = (char *) "test";
-            inputField_[0].inp_count = 0;
-
             wi_ = init_warning(FALSE, 0);
             wiGuard_.reset(wi_);
         }
 
-        int                                            numInputs_;
-        t_inpfile                                     *inputField_;
-        gmx::unique_cptr<t_inpfile>                    inpGuard_;
+        std::vector<t_inpfile>                         inputField_;
         warninp_t                                      wi_;
         gmx::unique_cptr<struct warninp, free_warning> wiGuard_;
 };
 
 TEST_F(ReadTest, get_eint_ReadsInteger)
 {
-    inputField_[0].value = (char *) "1";
-    ASSERT_EQ(1, get_eint(&numInputs_, &inputField_, "test", 2, wi_));
+    inputField_.front().value_.assign("1");
+    ASSERT_EQ(1, get_eint(&inputField_, "test", 2, wi_));
     ASSERT_FALSE(warning_errors_exist(wi_));
 }
 
 TEST_F(ReadTest, get_eint_WarnsAboutFloat)
 {
-    inputField_[0].value = (char *) "0.8";
-    get_eint(&numInputs_, &inputField_, "test", 2, wi_);
+    inputField_.front().value_.assign("0.8");
+    get_eint(&inputField_, "test", 2, wi_);
     ASSERT_TRUE(warning_errors_exist(wi_));
 }
 
 TEST_F(ReadTest, get_eint_WarnsAboutString)
 {
-    inputField_[0].value = (char *) "hello";
-    get_eint(&numInputs_, &inputField_, "test", 2, wi_);
+    inputField_.front().value_.assign("hello");
+    get_eint(&inputField_, "test", 2, wi_);
     ASSERT_TRUE(warning_errors_exist(wi_));
 }
 
 TEST_F(ReadTest, get_eint64_ReadsInteger)
 {
-    inputField_[0].value = (char *) "1";
-    ASSERT_EQ(1, get_eint64(&numInputs_, &inputField_, "test", 2, wi_));
+    inputField_.front().value_.assign("1");
+    ASSERT_EQ(1, get_eint64(&inputField_, "test", 2, wi_));
     ASSERT_FALSE(warning_errors_exist(wi_));
 }
 
 TEST_F(ReadTest, get_eint64_WarnsAboutFloat)
 {
-    inputField_[0].value = (char *) "0.8";
-    get_eint64(&numInputs_, &inputField_, "test", 2, wi_);
+    inputField_.front().value_.assign("0.8");
+    get_eint64(&inputField_, "test", 2, wi_);
     ASSERT_TRUE(warning_errors_exist(wi_));
 }
 
 TEST_F(ReadTest, get_eint64_WarnsAboutString)
 {
-    inputField_[0].value = (char *) "hello";
-    get_eint64(&numInputs_, &inputField_, "test", 2, wi_);
+    inputField_.front().value_.assign("hello");
+    get_eint64(&inputField_, "test", 2, wi_);
     ASSERT_TRUE(warning_errors_exist(wi_));
 }
 
 TEST_F(ReadTest, get_ereal_ReadsInteger)
 {
-    inputField_[0].value = (char *) "1";
-    ASSERT_EQ(1, get_ereal(&numInputs_, &inputField_, "test", 2, wi_));
+    inputField_.front().value_.assign("1");
+    ASSERT_EQ(1, get_ereal(&inputField_, "test", 2, wi_));
     ASSERT_FALSE(warning_errors_exist(wi_));
 }
 
 TEST_F(ReadTest, get_ereal_ReadsFloat)
 {
-    inputField_[0].value = (char *) "0.8";
-    ASSERT_EQ(0.8, get_ereal(&numInputs_, &inputField_, "test", 2, wi_));
+    inputField_.front().value_.assign("0.8");
+    ASSERT_EQ(0.8, get_ereal(&inputField_, "test", 2, wi_));
     ASSERT_FALSE(warning_errors_exist(wi_));
 }
 
 TEST_F(ReadTest, get_ereal_WarnsAboutString)
 {
-    inputField_[0].value = (char *) "hello";
-    get_ereal(&numInputs_, &inputField_, "test", 2, wi_);
+    inputField_.front().value_.assign("hello");
+    get_ereal(&inputField_, "test", 2, wi_);
     ASSERT_TRUE(warning_errors_exist(wi_));
 }
 
index c993a3eda89f7b9fb19aaa7ad225e3e5083f3fa4..f15f0955e38ade0963fde7fc73c4641b147089b4 100644 (file)
@@ -116,72 +116,71 @@ enum {
 
 static void get_params(const char *mpin, const char *mpout, t_psrec *psr)
 {
-    static const char *gmx_bools[BOOL_NR+1]  = { "no", "yes", nullptr };
+    static const char     *gmx_bools[BOOL_NR+1]  = { "no", "yes", nullptr };
     /* this must correspond to t_rgb *linecolors[] below */
-    static const char *colors[] = { "none", "black", "white", nullptr };
-    warninp_t          wi;
-    t_inpfile         *inp;
-    int                ninp = 0;
+    static const char     *colors[] = { "none", "black", "white", nullptr };
+    warninp_t              wi;
+    std::vector<t_inpfile> inp;
 
     wi = init_warning(FALSE, 0);
 
     if (mpin != nullptr)
     {
         gmx::TextInputFile stream(mpin);
-        inp = read_inpfile(&stream, mpin, &ninp, wi);
+        inp = read_inpfile(&stream, mpin, wi);
     }
     else
     {
-        inp = nullptr;
-    }
-    psr->bw        = get_eenum(&ninp, &inp, "black&white",             gmx_bools);
-    psr->linewidth = get_ereal(&ninp, &inp, "linewidth",      1.0, wi);
-    setStringEntry(&ninp, &inp, "titlefont",      psr->titfont,        "Helvetica");
-    psr->titfontsize = get_ereal(&ninp, &inp, "titlefontsize",    20.0, wi);
-    psr->legend      = get_eenum(&ninp, &inp, "legend",         gmx_bools);
-    setStringEntry(&ninp, &inp, "legendfont",     psr->legfont,        psr->titfont);
-    setStringEntry(&ninp, &inp, "legendlabel",    psr->leglabel,       "");
-    setStringEntry(&ninp, &inp, "legend2label",   psr->leg2label,      psr->leglabel);
-    psr->legfontsize    = get_ereal(&ninp, &inp, "legendfontsize",    14.0, wi);
-    psr->xboxsize       = get_ereal(&ninp, &inp, "xbox",       0.0, wi);
-    psr->yboxsize       = get_ereal(&ninp, &inp, "ybox",       0.0, wi);
-    psr->boxspacing     = get_ereal(&ninp, &inp, "matrixspacing",     20.0, wi);
-    psr->xoffs          = get_ereal(&ninp, &inp, "xoffset",          0.0, wi);
-    psr->yoffs          = get_ereal(&ninp, &inp, "yoffset",          psr->xoffs, wi);
-    psr->boxlinewidth   = get_ereal(&ninp, &inp, "boxlinewidth",   psr->linewidth, wi);
-    psr->ticklinewidth  = get_ereal(&ninp, &inp, "ticklinewidth",  psr->linewidth, wi);
-    psr->zerolinewidth  = get_ereal(&ninp, &inp, "zerolinewidth",  psr->ticklinewidth, wi);
-    psr->X.lineatzero   = get_eenum(&ninp, &inp, "x-lineat0value",   colors);
-    psr->X.major        = get_ereal(&ninp, &inp, "x-major",        1, wi);
-    psr->X.minor        = get_ereal(&ninp, &inp, "x-minor",        1, wi);
-    psr->X.offset       = get_ereal(&ninp, &inp, "x-firstmajor",       0.0, wi);
-    psr->X.first        = get_eenum(&ninp, &inp, "x-majorat0",        gmx_bools);
-    psr->X.majorticklen = get_ereal(&ninp, &inp, "x-majorticklen", 8.0, wi);
-    psr->X.minorticklen = get_ereal(&ninp, &inp, "x-minorticklen", 4.0, wi);
-    setStringEntry(&ninp, &inp, "x-label",        psr->X.label,        "");
-    psr->X.fontsize = get_ereal(&ninp, &inp, "x-fontsize",     16.0, wi);
-    setStringEntry(&ninp, &inp, "x-font",         psr->X.font,         psr->titfont);
-    psr->X.tickfontsize = get_ereal(&ninp, &inp, "x-tickfontsize", 10.0, wi);
-    setStringEntry(&ninp, &inp, "x-tickfont",     psr->X.tickfont,     psr->X.font);
-    psr->Y.lineatzero   = get_eenum(&ninp, &inp, "y-lineat0value",   colors);
-    psr->Y.major        = get_ereal(&ninp, &inp, "y-major",        psr->X.major, wi);
-    psr->Y.minor        = get_ereal(&ninp, &inp, "y-minor",        psr->X.minor, wi);
-    psr->Y.offset       = get_ereal(&ninp, &inp, "y-firstmajor",       psr->X.offset, wi);
-    psr->Y.first        = get_eenum(&ninp, &inp, "y-majorat0",        gmx_bools);
-    psr->Y.majorticklen = get_ereal(&ninp, &inp, "y-majorticklen", psr->X.majorticklen, wi);
-    psr->Y.minorticklen = get_ereal(&ninp, &inp, "y-minorticklen", psr->X.minorticklen, wi);
-    setStringEntry(&ninp, &inp, "y-label",        psr->Y.label,        psr->X.label);
-    psr->Y.fontsize = get_ereal(&ninp, &inp, "y-fontsize",     psr->X.fontsize, wi);
-    setStringEntry(&ninp, &inp, "y-font",         psr->Y.font,         psr->X.font);
-    psr->Y.tickfontsize = get_ereal(&ninp, &inp, "y-tickfontsize", psr->X.tickfontsize, wi);
-    setStringEntry(&ninp, &inp, "y-tickfont",     psr->Y.tickfont,     psr->Y.font);
+        inp.clear();
+    }
+    psr->bw        = get_eenum(&inp, "black&white",             gmx_bools);
+    psr->linewidth = get_ereal(&inp, "linewidth",      1.0, wi);
+    setStringEntry(&inp, "titlefont",      psr->titfont,        "Helvetica");
+    psr->titfontsize = get_ereal(&inp, "titlefontsize",    20.0, wi);
+    psr->legend      = get_eenum(&inp, "legend",         gmx_bools);
+    setStringEntry(&inp, "legendfont",     psr->legfont,        psr->titfont);
+    setStringEntry(&inp, "legendlabel",    psr->leglabel,       "");
+    setStringEntry(&inp, "legend2label",   psr->leg2label,      psr->leglabel);
+    psr->legfontsize    = get_ereal(&inp, "legendfontsize",    14.0, wi);
+    psr->xboxsize       = get_ereal(&inp, "xbox",       0.0, wi);
+    psr->yboxsize       = get_ereal(&inp, "ybox",       0.0, wi);
+    psr->boxspacing     = get_ereal(&inp, "matrixspacing",     20.0, wi);
+    psr->xoffs          = get_ereal(&inp, "xoffset",          0.0, wi);
+    psr->yoffs          = get_ereal(&inp, "yoffset",          psr->xoffs, wi);
+    psr->boxlinewidth   = get_ereal(&inp, "boxlinewidth",   psr->linewidth, wi);
+    psr->ticklinewidth  = get_ereal(&inp, "ticklinewidth",  psr->linewidth, wi);
+    psr->zerolinewidth  = get_ereal(&inp, "zerolinewidth",  psr->ticklinewidth, wi);
+    psr->X.lineatzero   = get_eenum(&inp, "x-lineat0value",   colors);
+    psr->X.major        = get_ereal(&inp, "x-major",        1, wi);
+    psr->X.minor        = get_ereal(&inp, "x-minor",        1, wi);
+    psr->X.offset       = get_ereal(&inp, "x-firstmajor",       0.0, wi);
+    psr->X.first        = get_eenum(&inp, "x-majorat0",        gmx_bools);
+    psr->X.majorticklen = get_ereal(&inp, "x-majorticklen", 8.0, wi);
+    psr->X.minorticklen = get_ereal(&inp, "x-minorticklen", 4.0, wi);
+    setStringEntry(&inp, "x-label",        psr->X.label,        "");
+    psr->X.fontsize = get_ereal(&inp, "x-fontsize",     16.0, wi);
+    setStringEntry(&inp, "x-font",         psr->X.font,         psr->titfont);
+    psr->X.tickfontsize = get_ereal(&inp, "x-tickfontsize", 10.0, wi);
+    setStringEntry(&inp, "x-tickfont",     psr->X.tickfont,     psr->X.font);
+    psr->Y.lineatzero   = get_eenum(&inp, "y-lineat0value",   colors);
+    psr->Y.major        = get_ereal(&inp, "y-major",        psr->X.major, wi);
+    psr->Y.minor        = get_ereal(&inp, "y-minor",        psr->X.minor, wi);
+    psr->Y.offset       = get_ereal(&inp, "y-firstmajor",       psr->X.offset, wi);
+    psr->Y.first        = get_eenum(&inp, "y-majorat0",        gmx_bools);
+    psr->Y.majorticklen = get_ereal(&inp, "y-majorticklen", psr->X.majorticklen, wi);
+    psr->Y.minorticklen = get_ereal(&inp, "y-minorticklen", psr->X.minorticklen, wi);
+    setStringEntry(&inp, "y-label",        psr->Y.label,        psr->X.label);
+    psr->Y.fontsize = get_ereal(&inp, "y-fontsize",     psr->X.fontsize, wi);
+    setStringEntry(&inp, "y-font",         psr->Y.font,         psr->X.font);
+    psr->Y.tickfontsize = get_ereal(&inp, "y-tickfontsize", psr->X.tickfontsize, wi);
+    setStringEntry(&inp, "y-tickfont",     psr->Y.tickfont,     psr->Y.font);
 
     check_warning_error(wi, FARGS);
 
     if (mpout != nullptr)
     {
         gmx::TextOutputFile stream(mpout);
-        write_inpfile(&stream, mpout, ninp, inp, TRUE, WriteMdpHeader::yes, wi);
+        write_inpfile(&stream, mpout, &inp, TRUE, WriteMdpHeader::yes, wi);
         stream.close();
     }
 
index 19c0588dc04b9a900be92766ec69a19ac0d80a3c..e018f18273e77a508ede094f7412b8df0764dd6e 100644 (file)
@@ -1663,43 +1663,34 @@ static void add_wall_energrps(gmx_groups_t *groups, int nwall, t_symtab *symtab)
     }
 }
 
-static void read_expandedparams(int *ninp_p, t_inpfile **inp_p,
+static void read_expandedparams(std::vector<t_inpfile> *inp,
                                 t_expanded *expand, warninp_t wi)
 {
-    int        ninp;
-    t_inpfile *inp;
-
-    ninp   = *ninp_p;
-    inp    = *inp_p;
-
     /* read expanded ensemble parameters */
-    printStringNewline(&ninp, &inp, "expanded ensemble variables");
-    expand->nstexpanded    = get_eint(&ninp, &inp, "nstexpanded", -1, wi);
-    expand->elamstats      = get_eeenum(&ninp, &inp, "lmc-stats", elamstats_names, wi);
-    expand->elmcmove       = get_eeenum(&ninp, &inp, "lmc-move", elmcmove_names, wi);
-    expand->elmceq         = get_eeenum(&ninp, &inp, "lmc-weights-equil", elmceq_names, wi);
-    expand->equil_n_at_lam = get_eint(&ninp, &inp, "weight-equil-number-all-lambda", -1, wi);
-    expand->equil_samples  = get_eint(&ninp, &inp, "weight-equil-number-samples", -1, wi);
-    expand->equil_steps    = get_eint(&ninp, &inp, "weight-equil-number-steps", -1, wi);
-    expand->equil_wl_delta = get_ereal(&ninp, &inp, "weight-equil-wl-delta", -1, wi);
-    expand->equil_ratio    = get_ereal(&ninp, &inp, "weight-equil-count-ratio", -1, wi);
-    printStringNewline(&ninp, &inp, "Seed for Monte Carlo in lambda space");
-    expand->lmc_seed            = get_eint(&ninp, &inp, "lmc-seed", -1, wi);
-    expand->mc_temp             = get_ereal(&ninp, &inp, "mc-temperature", -1, wi);
-    expand->lmc_repeats         = get_eint(&ninp, &inp, "lmc-repeats", 1, wi);
-    expand->gibbsdeltalam       = get_eint(&ninp, &inp, "lmc-gibbsdelta", -1, wi);
-    expand->lmc_forced_nstart   = get_eint(&ninp, &inp, "lmc-forced-nstart", 0, wi);
-    expand->bSymmetrizedTMatrix = get_eeenum(&ninp, &inp, "symmetrized-transition-matrix", yesno_names, wi);
-    expand->nstTij              = get_eint(&ninp, &inp, "nst-transition-matrix", -1, wi);
-    expand->minvarmin           = get_eint(&ninp, &inp, "mininum-var-min", 100, wi); /*default is reasonable */
-    expand->c_range             = get_eint(&ninp, &inp, "weight-c-range", 0, wi);    /* default is just C=0 */
-    expand->wl_scale            = get_ereal(&ninp, &inp, "wl-scale", 0.8, wi);
-    expand->wl_ratio            = get_ereal(&ninp, &inp, "wl-ratio", 0.8, wi);
-    expand->init_wl_delta       = get_ereal(&ninp, &inp, "init-wl-delta", 1.0, wi);
-    expand->bWLoneovert         = get_eeenum(&ninp, &inp, "wl-oneovert", yesno_names, wi);
-
-    *ninp_p   = ninp;
-    *inp_p    = inp;
+    printStringNewline(inp, "expanded ensemble variables");
+    expand->nstexpanded    = get_eint(inp, "nstexpanded", -1, wi);
+    expand->elamstats      = get_eeenum(inp, "lmc-stats", elamstats_names, wi);
+    expand->elmcmove       = get_eeenum(inp, "lmc-move", elmcmove_names, wi);
+    expand->elmceq         = get_eeenum(inp, "lmc-weights-equil", elmceq_names, wi);
+    expand->equil_n_at_lam = get_eint(inp, "weight-equil-number-all-lambda", -1, wi);
+    expand->equil_samples  = get_eint(inp, "weight-equil-number-samples", -1, wi);
+    expand->equil_steps    = get_eint(inp, "weight-equil-number-steps", -1, wi);
+    expand->equil_wl_delta = get_ereal(inp, "weight-equil-wl-delta", -1, wi);
+    expand->equil_ratio    = get_ereal(inp, "weight-equil-count-ratio", -1, wi);
+    printStringNewline(inp, "Seed for Monte Carlo in lambda space");
+    expand->lmc_seed            = get_eint(inp, "lmc-seed", -1, wi);
+    expand->mc_temp             = get_ereal(inp, "mc-temperature", -1, wi);
+    expand->lmc_repeats         = get_eint(inp, "lmc-repeats", 1, wi);
+    expand->gibbsdeltalam       = get_eint(inp, "lmc-gibbsdelta", -1, wi);
+    expand->lmc_forced_nstart   = get_eint(inp, "lmc-forced-nstart", 0, wi);
+    expand->bSymmetrizedTMatrix = get_eeenum(inp, "symmetrized-transition-matrix", yesno_names, wi);
+    expand->nstTij              = get_eint(inp, "nst-transition-matrix", -1, wi);
+    expand->minvarmin           = get_eint(inp, "mininum-var-min", 100, wi); /*default is reasonable */
+    expand->c_range             = get_eint(inp, "weight-c-range", 0, wi);    /* default is just C=0 */
+    expand->wl_scale            = get_ereal(inp, "wl-scale", 0.8, wi);
+    expand->wl_ratio            = get_ereal(inp, "wl-ratio", 0.8, wi);
+    expand->init_wl_delta       = get_ereal(inp, "init-wl-delta", 1.0, wi);
+    expand->bWLoneovert         = get_eeenum(inp, "wl-oneovert", yesno_names, wi);
 
     return;
 }
@@ -1764,24 +1755,23 @@ void get_ir(const char *mdparin, const char *mdparout,
             gmx::MDModules *mdModules, t_inputrec *ir, t_gromppopts *opts,
             WriteMdpHeader writeMdpHeader, warninp_t wi)
 {
-    char       *dumstr[2];
-    double      dumdub[2][6];
-    t_inpfile  *inp;
-    int         i, j, m, ninp;
-    char        warn_buf[STRLEN];
-    t_lambda   *fep    = ir->fepvals;
-    t_expanded *expand = ir->expandedvals;
+    char                  *dumstr[2];
+    double                 dumdub[2][6];
+    int                    i, j, m;
+    char                   warn_buf[STRLEN];
+    t_lambda              *fep    = ir->fepvals;
+    t_expanded            *expand = ir->expandedvals;
 
-    const char *no_names[] = { "no", nullptr };
+    const char            *no_names[] = { "no", nullptr };
 
     init_inputrec_strings();
-    gmx::TextInputFile stream(mdparin);
-    inp = read_inpfile(&stream, mdparin, &ninp, wi);
+    gmx::TextInputFile     stream(mdparin);
+    std::vector<t_inpfile> inp = read_inpfile(&stream, mdparin, wi);
 
     snew(dumstr[0], STRLEN);
     snew(dumstr[1], STRLEN);
 
-    if (-1 == search_einp(ninp, inp, "cutoff-scheme"))
+    if (-1 == search_einp(inp, "cutoff-scheme"))
     {
         sprintf(warn_buf,
                 "%s did not specify a value for the .mdp option "
@@ -1794,298 +1784,298 @@ void get_ir(const char *mdparin, const char *mdparout,
     }
 
     /* ignore the following deprecated commands */
-    replace_inp_entry(ninp, inp, "title", NULL);
-    replace_inp_entry(ninp, inp, "cpp", NULL);
-    replace_inp_entry(ninp, inp, "domain-decomposition", NULL);
-    replace_inp_entry(ninp, inp, "andersen-seed", NULL);
-    replace_inp_entry(ninp, inp, "dihre", NULL);
-    replace_inp_entry(ninp, inp, "dihre-fc", NULL);
-    replace_inp_entry(ninp, inp, "dihre-tau", NULL);
-    replace_inp_entry(ninp, inp, "nstdihreout", NULL);
-    replace_inp_entry(ninp, inp, "nstcheckpoint", NULL);
-    replace_inp_entry(ninp, inp, "optimize-fft", NULL);
-    replace_inp_entry(ninp, inp, "adress_type", NULL);
-    replace_inp_entry(ninp, inp, "adress_const_wf", NULL);
-    replace_inp_entry(ninp, inp, "adress_ex_width", NULL);
-    replace_inp_entry(ninp, inp, "adress_hy_width", NULL);
-    replace_inp_entry(ninp, inp, "adress_ex_forcecap", NULL);
-    replace_inp_entry(ninp, inp, "adress_interface_correction", NULL);
-    replace_inp_entry(ninp, inp, "adress_site", NULL);
-    replace_inp_entry(ninp, inp, "adress_reference_coords", NULL);
-    replace_inp_entry(ninp, inp, "adress_tf_grp_names", NULL);
-    replace_inp_entry(ninp, inp, "adress_cg_grp_names", NULL);
-    replace_inp_entry(ninp, inp, "adress_do_hybridpairs", NULL);
-    replace_inp_entry(ninp, inp, "rlistlong", NULL);
-    replace_inp_entry(ninp, inp, "nstcalclr", NULL);
-    replace_inp_entry(ninp, inp, "pull-print-com2", NULL);
-    replace_inp_entry(ninp, inp, "gb-algorithm", NULL);
-    replace_inp_entry(ninp, inp, "nstgbradii", NULL);
-    replace_inp_entry(ninp, inp, "rgbradii", NULL);
-    replace_inp_entry(ninp, inp, "gb-epsilon-solvent", NULL);
-    replace_inp_entry(ninp, inp, "gb-saltconc", NULL);
-    replace_inp_entry(ninp, inp, "gb-obc-alpha", NULL);
-    replace_inp_entry(ninp, inp, "gb-obc-beta", NULL);
-    replace_inp_entry(ninp, inp, "gb-obc-gamma", NULL);
-    replace_inp_entry(ninp, inp, "gb-dielectric-offset", NULL);
-    replace_inp_entry(ninp, inp, "sa-algorithm", NULL);
-    replace_inp_entry(ninp, inp, "sa-surface-tension", NULL);
+    replace_inp_entry(inp, "title", NULL);
+    replace_inp_entry(inp, "cpp", NULL);
+    replace_inp_entry(inp, "domain-decomposition", NULL);
+    replace_inp_entry(inp, "andersen-seed", NULL);
+    replace_inp_entry(inp, "dihre", NULL);
+    replace_inp_entry(inp, "dihre-fc", NULL);
+    replace_inp_entry(inp, "dihre-tau", NULL);
+    replace_inp_entry(inp, "nstdihreout", NULL);
+    replace_inp_entry(inp, "nstcheckpoint", NULL);
+    replace_inp_entry(inp, "optimize-fft", NULL);
+    replace_inp_entry(inp, "adress_type", NULL);
+    replace_inp_entry(inp, "adress_const_wf", NULL);
+    replace_inp_entry(inp, "adress_ex_width", NULL);
+    replace_inp_entry(inp, "adress_hy_width", NULL);
+    replace_inp_entry(inp, "adress_ex_forcecap", NULL);
+    replace_inp_entry(inp, "adress_interface_correction", NULL);
+    replace_inp_entry(inp, "adress_site", NULL);
+    replace_inp_entry(inp, "adress_reference_coords", NULL);
+    replace_inp_entry(inp, "adress_tf_grp_names", NULL);
+    replace_inp_entry(inp, "adress_cg_grp_names", NULL);
+    replace_inp_entry(inp, "adress_do_hybridpairs", NULL);
+    replace_inp_entry(inp, "rlistlong", NULL);
+    replace_inp_entry(inp, "nstcalclr", NULL);
+    replace_inp_entry(inp, "pull-print-com2", NULL);
+    replace_inp_entry(inp, "gb-algorithm", NULL);
+    replace_inp_entry(inp, "nstgbradii", NULL);
+    replace_inp_entry(inp, "rgbradii", NULL);
+    replace_inp_entry(inp, "gb-epsilon-solvent", NULL);
+    replace_inp_entry(inp, "gb-saltconc", NULL);
+    replace_inp_entry(inp, "gb-obc-alpha", NULL);
+    replace_inp_entry(inp, "gb-obc-beta", NULL);
+    replace_inp_entry(inp, "gb-obc-gamma", NULL);
+    replace_inp_entry(inp, "gb-dielectric-offset", NULL);
+    replace_inp_entry(inp, "sa-algorithm", NULL);
+    replace_inp_entry(inp, "sa-surface-tension", NULL);
 
     /* replace the following commands with the clearer new versions*/
-    replace_inp_entry(ninp, inp, "unconstrained-start", "continuation");
-    replace_inp_entry(ninp, inp, "foreign-lambda", "fep-lambdas");
-    replace_inp_entry(ninp, inp, "verlet-buffer-drift", "verlet-buffer-tolerance");
-    replace_inp_entry(ninp, inp, "nstxtcout", "nstxout-compressed");
-    replace_inp_entry(ninp, inp, "xtc-grps", "compressed-x-grps");
-    replace_inp_entry(ninp, inp, "xtc-precision", "compressed-x-precision");
-    replace_inp_entry(ninp, inp, "pull-print-com1", "pull-print-com");
-
-    printStringNewline(&ninp, &inp, "VARIOUS PREPROCESSING OPTIONS");
-    printStringNoNewline(&ninp, &inp, "Preprocessor information: use cpp syntax.");
-    printStringNoNewline(&ninp, &inp, "e.g.: -I/home/joe/doe -I/home/mary/roe");
-    setStringEntry(&ninp, &inp, "include", opts->include,  nullptr);
-    printStringNoNewline(&ninp, &inp, "e.g.: -DPOSRES -DFLEXIBLE (note these variable names are case sensitive)");
-    setStringEntry(&ninp, &inp, "define",  opts->define,   nullptr);
-
-    printStringNewline(&ninp, &inp, "RUN CONTROL PARAMETERS");
-    ir->eI = get_eeenum(&ninp, &inp, "integrator",         ei_names, wi);
-    printStringNoNewline(&ninp, &inp, "Start time and timestep in ps");
-    ir->init_t  = get_ereal(&ninp, &inp, "tinit", 0.0, wi);
-    ir->delta_t = get_ereal(&ninp, &inp, "dt",    0.001, wi);
-    ir->nsteps  = get_eint64(&ninp, &inp, "nsteps",     0, wi);
-    printStringNoNewline(&ninp, &inp, "For exact run continuation or redoing part of a run");
-    ir->init_step = get_eint64(&ninp, &inp, "init-step",  0, wi);
-    printStringNoNewline(&ninp, &inp, "Part index is updated automatically on checkpointing (keeps files separate)");
-    ir->simulation_part = get_eint(&ninp, &inp, "simulation-part", 1, wi);
-    printStringNoNewline(&ninp, &inp, "mode for center of mass motion removal");
-    ir->comm_mode = get_eeenum(&ninp, &inp, "comm-mode",  ecm_names, wi);
-    printStringNoNewline(&ninp, &inp, "number of steps for center of mass motion removal");
-    ir->nstcomm = get_eint(&ninp, &inp, "nstcomm",    100, wi);
-    printStringNoNewline(&ninp, &inp, "group(s) for center of mass motion removal");
-    setStringEntry(&ninp, &inp, "comm-grps",   is->vcm,            nullptr);
-
-    printStringNewline(&ninp, &inp, "LANGEVIN DYNAMICS OPTIONS");
-    printStringNoNewline(&ninp, &inp, "Friction coefficient (amu/ps) and random seed");
-    ir->bd_fric = get_ereal(&ninp, &inp, "bd-fric",    0.0, wi);
-    ir->ld_seed = get_eint64(&ninp, &inp, "ld-seed",    -1, wi);
+    replace_inp_entry(inp, "unconstrained-start", "continuation");
+    replace_inp_entry(inp, "foreign-lambda", "fep-lambdas");
+    replace_inp_entry(inp, "verlet-buffer-drift", "verlet-buffer-tolerance");
+    replace_inp_entry(inp, "nstxtcout", "nstxout-compressed");
+    replace_inp_entry(inp, "xtc-grps", "compressed-x-grps");
+    replace_inp_entry(inp, "xtc-precision", "compressed-x-precision");
+    replace_inp_entry(inp, "pull-print-com1", "pull-print-com");
+
+    printStringNewline(&inp, "VARIOUS PREPROCESSING OPTIONS");
+    printStringNoNewline(&inp, "Preprocessor information: use cpp syntax.");
+    printStringNoNewline(&inp, "e.g.: -I/home/joe/doe -I/home/mary/roe");
+    setStringEntry(&inp, "include", opts->include,  nullptr);
+    printStringNoNewline(&inp, "e.g.: -DPOSRES -DFLEXIBLE (note these variable names are case sensitive)");
+    setStringEntry(&inp, "define",  opts->define,   nullptr);
+
+    printStringNewline(&inp, "RUN CONTROL PARAMETERS");
+    ir->eI = get_eeenum(&inp, "integrator",         ei_names, wi);
+    printStringNoNewline(&inp, "Start time and timestep in ps");
+    ir->init_t  = get_ereal(&inp, "tinit", 0.0, wi);
+    ir->delta_t = get_ereal(&inp, "dt",    0.001, wi);
+    ir->nsteps  = get_eint64(&inp, "nsteps",     0, wi);
+    printStringNoNewline(&inp, "For exact run continuation or redoing part of a run");
+    ir->init_step = get_eint64(&inp, "init-step",  0, wi);
+    printStringNoNewline(&inp, "Part index is updated automatically on checkpointing (keeps files separate)");
+    ir->simulation_part = get_eint(&inp, "simulation-part", 1, wi);
+    printStringNoNewline(&inp, "mode for center of mass motion removal");
+    ir->comm_mode = get_eeenum(&inp, "comm-mode",  ecm_names, wi);
+    printStringNoNewline(&inp, "number of steps for center of mass motion removal");
+    ir->nstcomm = get_eint(&inp, "nstcomm",    100, wi);
+    printStringNoNewline(&inp, "group(s) for center of mass motion removal");
+    setStringEntry(&inp, "comm-grps",   is->vcm,            nullptr);
+
+    printStringNewline(&inp, "LANGEVIN DYNAMICS OPTIONS");
+    printStringNoNewline(&inp, "Friction coefficient (amu/ps) and random seed");
+    ir->bd_fric = get_ereal(&inp, "bd-fric",    0.0, wi);
+    ir->ld_seed = get_eint64(&inp, "ld-seed",    -1, wi);
 
     /* Em stuff */
-    printStringNewline(&ninp, &inp, "ENERGY MINIMIZATION OPTIONS");
-    printStringNoNewline(&ninp, &inp, "Force tolerance and initial step-size");
-    ir->em_tol      = get_ereal(&ninp, &inp, "emtol",     10.0, wi);
-    ir->em_stepsize = get_ereal(&ninp, &inp, "emstep", 0.01, wi);
-    printStringNoNewline(&ninp, &inp, "Max number of iterations in relax-shells");
-    ir->niter = get_eint(&ninp, &inp, "niter",      20, wi);
-    printStringNoNewline(&ninp, &inp, "Step size (ps^2) for minimization of flexible constraints");
-    ir->fc_stepsize = get_ereal(&ninp, &inp, "fcstep", 0, wi);
-    printStringNoNewline(&ninp, &inp, "Frequency of steepest descents steps when doing CG");
-    ir->nstcgsteep = get_eint(&ninp, &inp, "nstcgsteep", 1000, wi);
-    ir->nbfgscorr  = get_eint(&ninp, &inp, "nbfgscorr",  10, wi);
-
-    printStringNewline(&ninp, &inp, "TEST PARTICLE INSERTION OPTIONS");
-    ir->rtpi = get_ereal(&ninp, &inp, "rtpi",   0.05, wi);
+    printStringNewline(&inp, "ENERGY MINIMIZATION OPTIONS");
+    printStringNoNewline(&inp, "Force tolerance and initial step-size");
+    ir->em_tol      = get_ereal(&inp, "emtol",     10.0, wi);
+    ir->em_stepsize = get_ereal(&inp, "emstep", 0.01, wi);
+    printStringNoNewline(&inp, "Max number of iterations in relax-shells");
+    ir->niter = get_eint(&inp, "niter",      20, wi);
+    printStringNoNewline(&inp, "Step size (ps^2) for minimization of flexible constraints");
+    ir->fc_stepsize = get_ereal(&inp, "fcstep", 0, wi);
+    printStringNoNewline(&inp, "Frequency of steepest descents steps when doing CG");
+    ir->nstcgsteep = get_eint(&inp, "nstcgsteep", 1000, wi);
+    ir->nbfgscorr  = get_eint(&inp, "nbfgscorr",  10, wi);
+
+    printStringNewline(&inp, "TEST PARTICLE INSERTION OPTIONS");
+    ir->rtpi = get_ereal(&inp, "rtpi",   0.05, wi);
 
     /* Output options */
-    printStringNewline(&ninp, &inp, "OUTPUT CONTROL OPTIONS");
-    printStringNoNewline(&ninp, &inp, "Output frequency for coords (x), velocities (v) and forces (f)");
-    ir->nstxout = get_eint(&ninp, &inp, "nstxout",    0, wi);
-    ir->nstvout = get_eint(&ninp, &inp, "nstvout",    0, wi);
-    ir->nstfout = get_eint(&ninp, &inp, "nstfout",    0, wi);
-    printStringNoNewline(&ninp, &inp, "Output frequency for energies to log file and energy file");
-    ir->nstlog        = get_eint(&ninp, &inp, "nstlog", 1000, wi);
-    ir->nstcalcenergy = get_eint(&ninp, &inp, "nstcalcenergy", 100, wi);
-    ir->nstenergy     = get_eint(&ninp, &inp, "nstenergy",  1000, wi);
-    printStringNoNewline(&ninp, &inp, "Output frequency and precision for .xtc file");
-    ir->nstxout_compressed      = get_eint(&ninp, &inp, "nstxout-compressed",  0, wi);
-    ir->x_compression_precision = get_ereal(&ninp, &inp, "compressed-x-precision", 1000.0, wi);
-    printStringNoNewline(&ninp, &inp, "This selects the subset of atoms for the compressed");
-    printStringNoNewline(&ninp, &inp, "trajectory file. You can select multiple groups. By");
-    printStringNoNewline(&ninp, &inp, "default, all atoms will be written.");
-    setStringEntry(&ninp, &inp, "compressed-x-grps", is->x_compressed_groups, nullptr);
-    printStringNoNewline(&ninp, &inp, "Selection of energy groups");
-    setStringEntry(&ninp, &inp, "energygrps",  is->energy,         nullptr);
+    printStringNewline(&inp, "OUTPUT CONTROL OPTIONS");
+    printStringNoNewline(&inp, "Output frequency for coords (x), velocities (v) and forces (f)");
+    ir->nstxout = get_eint(&inp, "nstxout",    0, wi);
+    ir->nstvout = get_eint(&inp, "nstvout",    0, wi);
+    ir->nstfout = get_eint(&inp, "nstfout",    0, wi);
+    printStringNoNewline(&inp, "Output frequency for energies to log file and energy file");
+    ir->nstlog        = get_eint(&inp, "nstlog", 1000, wi);
+    ir->nstcalcenergy = get_eint(&inp, "nstcalcenergy", 100, wi);
+    ir->nstenergy     = get_eint(&inp, "nstenergy",  1000, wi);
+    printStringNoNewline(&inp, "Output frequency and precision for .xtc file");
+    ir->nstxout_compressed      = get_eint(&inp, "nstxout-compressed",  0, wi);
+    ir->x_compression_precision = get_ereal(&inp, "compressed-x-precision", 1000.0, wi);
+    printStringNoNewline(&inp, "This selects the subset of atoms for the compressed");
+    printStringNoNewline(&inp, "trajectory file. You can select multiple groups. By");
+    printStringNoNewline(&inp, "default, all atoms will be written.");
+    setStringEntry(&inp, "compressed-x-grps", is->x_compressed_groups, nullptr);
+    printStringNoNewline(&inp, "Selection of energy groups");
+    setStringEntry(&inp, "energygrps",  is->energy,         nullptr);
 
     /* Neighbor searching */
-    printStringNewline(&ninp, &inp, "NEIGHBORSEARCHING PARAMETERS");
-    printStringNoNewline(&ninp, &inp, "cut-off scheme (Verlet: particle based cut-offs, group: using charge groups)");
-    ir->cutoff_scheme = get_eeenum(&ninp, &inp, "cutoff-scheme",    ecutscheme_names, wi);
-    printStringNoNewline(&ninp, &inp, "nblist update frequency");
-    ir->nstlist = get_eint(&ninp, &inp, "nstlist",    10, wi);
-    printStringNoNewline(&ninp, &inp, "ns algorithm (simple or grid)");
-    ir->ns_type = get_eeenum(&ninp, &inp, "ns-type",    ens_names, wi);
-    printStringNoNewline(&ninp, &inp, "Periodic boundary conditions: xyz, no, xy");
-    ir->ePBC          = get_eeenum(&ninp, &inp, "pbc",       epbc_names, wi);
-    ir->bPeriodicMols = get_eeenum(&ninp, &inp, "periodic-molecules", yesno_names, wi);
-    printStringNoNewline(&ninp, &inp, "Allowed energy error due to the Verlet buffer in kJ/mol/ps per atom,");
-    printStringNoNewline(&ninp, &inp, "a value of -1 means: use rlist");
-    ir->verletbuf_tol = get_ereal(&ninp, &inp, "verlet-buffer-tolerance",    0.005, wi);
-    printStringNoNewline(&ninp, &inp, "nblist cut-off");
-    ir->rlist = get_ereal(&ninp, &inp, "rlist",  1.0, wi);
-    printStringNoNewline(&ninp, &inp, "long-range cut-off for switched potentials");
+    printStringNewline(&inp, "NEIGHBORSEARCHING PARAMETERS");
+    printStringNoNewline(&inp, "cut-off scheme (Verlet: particle based cut-offs, group: using charge groups)");
+    ir->cutoff_scheme = get_eeenum(&inp, "cutoff-scheme",    ecutscheme_names, wi);
+    printStringNoNewline(&inp, "nblist update frequency");
+    ir->nstlist = get_eint(&inp, "nstlist",    10, wi);
+    printStringNoNewline(&inp, "ns algorithm (simple or grid)");
+    ir->ns_type = get_eeenum(&inp, "ns-type",    ens_names, wi);
+    printStringNoNewline(&inp, "Periodic boundary conditions: xyz, no, xy");
+    ir->ePBC          = get_eeenum(&inp, "pbc",       epbc_names, wi);
+    ir->bPeriodicMols = get_eeenum(&inp, "periodic-molecules", yesno_names, wi);
+    printStringNoNewline(&inp, "Allowed energy error due to the Verlet buffer in kJ/mol/ps per atom,");
+    printStringNoNewline(&inp, "a value of -1 means: use rlist");
+    ir->verletbuf_tol = get_ereal(&inp, "verlet-buffer-tolerance",    0.005, wi);
+    printStringNoNewline(&inp, "nblist cut-off");
+    ir->rlist = get_ereal(&inp, "rlist",  1.0, wi);
+    printStringNoNewline(&inp, "long-range cut-off for switched potentials");
 
     /* Electrostatics */
-    printStringNewline(&ninp, &inp, "OPTIONS FOR ELECTROSTATICS AND VDW");
-    printStringNoNewline(&ninp, &inp, "Method for doing electrostatics");
-    ir->coulombtype      = get_eeenum(&ninp, &inp, "coulombtype",    eel_names, wi);
-    ir->coulomb_modifier = get_eeenum(&ninp, &inp, "coulomb-modifier",    eintmod_names, wi);
-    printStringNoNewline(&ninp, &inp, "cut-off lengths");
-    ir->rcoulomb_switch = get_ereal(&ninp, &inp, "rcoulomb-switch",    0.0, wi);
-    ir->rcoulomb        = get_ereal(&ninp, &inp, "rcoulomb",   1.0, wi);
-    printStringNoNewline(&ninp, &inp, "Relative dielectric constant for the medium and the reaction field");
-    ir->epsilon_r  = get_ereal(&ninp, &inp, "epsilon-r",  1.0, wi);
-    ir->epsilon_rf = get_ereal(&ninp, &inp, "epsilon-rf", 0.0, wi);
-    printStringNoNewline(&ninp, &inp, "Method for doing Van der Waals");
-    ir->vdwtype      = get_eeenum(&ninp, &inp, "vdw-type",    evdw_names, wi);
-    ir->vdw_modifier = get_eeenum(&ninp, &inp, "vdw-modifier",    eintmod_names, wi);
-    printStringNoNewline(&ninp, &inp, "cut-off lengths");
-    ir->rvdw_switch = get_ereal(&ninp, &inp, "rvdw-switch",    0.0, wi);
-    ir->rvdw        = get_ereal(&ninp, &inp, "rvdw",   1.0, wi);
-    printStringNoNewline(&ninp, &inp, "Apply long range dispersion corrections for Energy and Pressure");
-    ir->eDispCorr = get_eeenum(&ninp, &inp, "DispCorr",  edispc_names, wi);
-    printStringNoNewline(&ninp, &inp, "Extension of the potential lookup tables beyond the cut-off");
-    ir->tabext = get_ereal(&ninp, &inp, "table-extension", 1.0, wi);
-    printStringNoNewline(&ninp, &inp, "Separate tables between energy group pairs");
-    setStringEntry(&ninp, &inp, "energygrp-table", is->egptable,   nullptr);
-    printStringNoNewline(&ninp, &inp, "Spacing for the PME/PPPM FFT grid");
-    ir->fourier_spacing = get_ereal(&ninp, &inp, "fourierspacing", 0.12, wi);
-    printStringNoNewline(&ninp, &inp, "FFT grid size, when a value is 0 fourierspacing will be used");
-    ir->nkx = get_eint(&ninp, &inp, "fourier-nx",         0, wi);
-    ir->nky = get_eint(&ninp, &inp, "fourier-ny",         0, wi);
-    ir->nkz = get_eint(&ninp, &inp, "fourier-nz",         0, wi);
-    printStringNoNewline(&ninp, &inp, "EWALD/PME/PPPM parameters");
-    ir->pme_order              = get_eint(&ninp, &inp, "pme-order",   4, wi);
-    ir->ewald_rtol             = get_ereal(&ninp, &inp, "ewald-rtol", 0.00001, wi);
-    ir->ewald_rtol_lj          = get_ereal(&ninp, &inp, "ewald-rtol-lj", 0.001, wi);
-    ir->ljpme_combination_rule = get_eeenum(&ninp, &inp, "lj-pme-comb-rule", eljpme_names, wi);
-    ir->ewald_geometry         = get_eeenum(&ninp, &inp, "ewald-geometry", eewg_names, wi);
-    ir->epsilon_surface        = get_ereal(&ninp, &inp, "epsilon-surface", 0.0, wi);
+    printStringNewline(&inp, "OPTIONS FOR ELECTROSTATICS AND VDW");
+    printStringNoNewline(&inp, "Method for doing electrostatics");
+    ir->coulombtype      = get_eeenum(&inp, "coulombtype",    eel_names, wi);
+    ir->coulomb_modifier = get_eeenum(&inp, "coulomb-modifier",    eintmod_names, wi);
+    printStringNoNewline(&inp, "cut-off lengths");
+    ir->rcoulomb_switch = get_ereal(&inp, "rcoulomb-switch",    0.0, wi);
+    ir->rcoulomb        = get_ereal(&inp, "rcoulomb",   1.0, wi);
+    printStringNoNewline(&inp, "Relative dielectric constant for the medium and the reaction field");
+    ir->epsilon_r  = get_ereal(&inp, "epsilon-r",  1.0, wi);
+    ir->epsilon_rf = get_ereal(&inp, "epsilon-rf", 0.0, wi);
+    printStringNoNewline(&inp, "Method for doing Van der Waals");
+    ir->vdwtype      = get_eeenum(&inp, "vdw-type",    evdw_names, wi);
+    ir->vdw_modifier = get_eeenum(&inp, "vdw-modifier",    eintmod_names, wi);
+    printStringNoNewline(&inp, "cut-off lengths");
+    ir->rvdw_switch = get_ereal(&inp, "rvdw-switch",    0.0, wi);
+    ir->rvdw        = get_ereal(&inp, "rvdw",   1.0, wi);
+    printStringNoNewline(&inp, "Apply long range dispersion corrections for Energy and Pressure");
+    ir->eDispCorr = get_eeenum(&inp, "DispCorr",  edispc_names, wi);
+    printStringNoNewline(&inp, "Extension of the potential lookup tables beyond the cut-off");
+    ir->tabext = get_ereal(&inp, "table-extension", 1.0, wi);
+    printStringNoNewline(&inp, "Separate tables between energy group pairs");
+    setStringEntry(&inp, "energygrp-table", is->egptable,   nullptr);
+    printStringNoNewline(&inp, "Spacing for the PME/PPPM FFT grid");
+    ir->fourier_spacing = get_ereal(&inp, "fourierspacing", 0.12, wi);
+    printStringNoNewline(&inp, "FFT grid size, when a value is 0 fourierspacing will be used");
+    ir->nkx = get_eint(&inp, "fourier-nx",         0, wi);
+    ir->nky = get_eint(&inp, "fourier-ny",         0, wi);
+    ir->nkz = get_eint(&inp, "fourier-nz",         0, wi);
+    printStringNoNewline(&inp, "EWALD/PME/PPPM parameters");
+    ir->pme_order              = get_eint(&inp, "pme-order",   4, wi);
+    ir->ewald_rtol             = get_ereal(&inp, "ewald-rtol", 0.00001, wi);
+    ir->ewald_rtol_lj          = get_ereal(&inp, "ewald-rtol-lj", 0.001, wi);
+    ir->ljpme_combination_rule = get_eeenum(&inp, "lj-pme-comb-rule", eljpme_names, wi);
+    ir->ewald_geometry         = get_eeenum(&inp, "ewald-geometry", eewg_names, wi);
+    ir->epsilon_surface        = get_ereal(&inp, "epsilon-surface", 0.0, wi);
 
     /* Implicit solvation is no longer supported, but we need grompp
        to be able to refuse old .mdp files that would have built a tpr
        to run it. Thus, only "no" is accepted. */
-    ir->implicit_solvent = get_eeenum(&ninp, &inp, "implicit-solvent", no_names, wi);
+    ir->implicit_solvent = get_eeenum(&inp, "implicit-solvent", no_names, wi);
 
     /* Coupling stuff */
-    printStringNewline(&ninp, &inp, "OPTIONS FOR WEAK COUPLING ALGORITHMS");
-    printStringNoNewline(&ninp, &inp, "Temperature coupling");
-    ir->etc                = get_eeenum(&ninp, &inp, "tcoupl",        etcoupl_names, wi);
-    ir->nsttcouple         = get_eint(&ninp, &inp, "nsttcouple",  -1, wi);
-    ir->opts.nhchainlength = get_eint(&ninp, &inp, "nh-chain-length", 10, wi);
-    ir->bPrintNHChains     = get_eeenum(&ninp, &inp, "print-nose-hoover-chain-variables", yesno_names, wi);
-    printStringNoNewline(&ninp, &inp, "Groups to couple separately");
-    setStringEntry(&ninp, &inp, "tc-grps",     is->tcgrps,         nullptr);
-    printStringNoNewline(&ninp, &inp, "Time constant (ps) and reference temperature (K)");
-    setStringEntry(&ninp, &inp, "tau-t",   is->tau_t,      nullptr);
-    setStringEntry(&ninp, &inp, "ref-t",   is->ref_t,      nullptr);
-    printStringNoNewline(&ninp, &inp, "pressure coupling");
-    ir->epc        = get_eeenum(&ninp, &inp, "pcoupl",        epcoupl_names, wi);
-    ir->epct       = get_eeenum(&ninp, &inp, "pcoupltype",       epcoupltype_names, wi);
-    ir->nstpcouple = get_eint(&ninp, &inp, "nstpcouple",  -1, wi);
-    printStringNoNewline(&ninp, &inp, "Time constant (ps), compressibility (1/bar) and reference P (bar)");
-    ir->tau_p = get_ereal(&ninp, &inp, "tau-p",  1.0, wi);
-    setStringEntry(&ninp, &inp, "compressibility", dumstr[0],  nullptr);
-    setStringEntry(&ninp, &inp, "ref-p",       dumstr[1],      nullptr);
-    printStringNoNewline(&ninp, &inp, "Scaling of reference coordinates, No, All or COM");
-    ir->refcoord_scaling = get_eeenum(&ninp, &inp, "refcoord-scaling", erefscaling_names, wi);
+    printStringNewline(&inp, "OPTIONS FOR WEAK COUPLING ALGORITHMS");
+    printStringNoNewline(&inp, "Temperature coupling");
+    ir->etc                = get_eeenum(&inp, "tcoupl",        etcoupl_names, wi);
+    ir->nsttcouple         = get_eint(&inp, "nsttcouple",  -1, wi);
+    ir->opts.nhchainlength = get_eint(&inp, "nh-chain-length", 10, wi);
+    ir->bPrintNHChains     = get_eeenum(&inp, "print-nose-hoover-chain-variables", yesno_names, wi);
+    printStringNoNewline(&inp, "Groups to couple separately");
+    setStringEntry(&inp, "tc-grps",     is->tcgrps,         nullptr);
+    printStringNoNewline(&inp, "Time constant (ps) and reference temperature (K)");
+    setStringEntry(&inp, "tau-t",   is->tau_t,      nullptr);
+    setStringEntry(&inp, "ref-t",   is->ref_t,      nullptr);
+    printStringNoNewline(&inp, "pressure coupling");
+    ir->epc        = get_eeenum(&inp, "pcoupl",        epcoupl_names, wi);
+    ir->epct       = get_eeenum(&inp, "pcoupltype",       epcoupltype_names, wi);
+    ir->nstpcouple = get_eint(&inp, "nstpcouple",  -1, wi);
+    printStringNoNewline(&inp, "Time constant (ps), compressibility (1/bar) and reference P (bar)");
+    ir->tau_p = get_ereal(&inp, "tau-p",  1.0, wi);
+    setStringEntry(&inp, "compressibility", dumstr[0],  nullptr);
+    setStringEntry(&inp, "ref-p",       dumstr[1],      nullptr);
+    printStringNoNewline(&inp, "Scaling of reference coordinates, No, All or COM");
+    ir->refcoord_scaling = get_eeenum(&inp, "refcoord-scaling", erefscaling_names, wi);
 
     /* QMMM */
-    printStringNewline(&ninp, &inp, "OPTIONS FOR QMMM calculations");
-    ir->bQMMM = get_eeenum(&ninp, &inp, "QMMM", yesno_names, wi);
-    printStringNoNewline(&ninp, &inp, "Groups treated Quantum Mechanically");
-    setStringEntry(&ninp, &inp, "QMMM-grps",  is->QMMM,          nullptr);
-    printStringNoNewline(&ninp, &inp, "QM method");
-    setStringEntry(&ninp, &inp, "QMmethod",     is->QMmethod, nullptr);
-    printStringNoNewline(&ninp, &inp, "QMMM scheme");
-    ir->QMMMscheme = get_eeenum(&ninp, &inp, "QMMMscheme",    eQMMMscheme_names, wi);
-    printStringNoNewline(&ninp, &inp, "QM basisset");
-    setStringEntry(&ninp, &inp, "QMbasis",      is->QMbasis, nullptr);
-    printStringNoNewline(&ninp, &inp, "QM charge");
-    setStringEntry(&ninp, &inp, "QMcharge",    is->QMcharge, nullptr);
-    printStringNoNewline(&ninp, &inp, "QM multiplicity");
-    setStringEntry(&ninp, &inp, "QMmult",      is->QMmult, nullptr);
-    printStringNoNewline(&ninp, &inp, "Surface Hopping");
-    setStringEntry(&ninp, &inp, "SH",          is->bSH, nullptr);
-    printStringNoNewline(&ninp, &inp, "CAS space options");
-    setStringEntry(&ninp, &inp, "CASorbitals",      is->CASorbitals,   nullptr);
-    setStringEntry(&ninp, &inp, "CASelectrons",     is->CASelectrons,  nullptr);
-    setStringEntry(&ninp, &inp, "SAon", is->SAon, nullptr);
-    setStringEntry(&ninp, &inp, "SAoff", is->SAoff, nullptr);
-    setStringEntry(&ninp, &inp, "SAsteps", is->SAsteps, nullptr);
-    printStringNoNewline(&ninp, &inp, "Scale factor for MM charges");
-    ir->scalefactor = get_ereal(&ninp, &inp, "MMChargeScaleFactor", 1.0, wi);
+    printStringNewline(&inp, "OPTIONS FOR QMMM calculations");
+    ir->bQMMM = get_eeenum(&inp, "QMMM", yesno_names, wi);
+    printStringNoNewline(&inp, "Groups treated Quantum Mechanically");
+    setStringEntry(&inp, "QMMM-grps",  is->QMMM,          nullptr);
+    printStringNoNewline(&inp, "QM method");
+    setStringEntry(&inp, "QMmethod",     is->QMmethod, nullptr);
+    printStringNoNewline(&inp, "QMMM scheme");
+    ir->QMMMscheme = get_eeenum(&inp, "QMMMscheme",    eQMMMscheme_names, wi);
+    printStringNoNewline(&inp, "QM basisset");
+    setStringEntry(&inp, "QMbasis",      is->QMbasis, nullptr);
+    printStringNoNewline(&inp, "QM charge");
+    setStringEntry(&inp, "QMcharge",    is->QMcharge, nullptr);
+    printStringNoNewline(&inp, "QM multiplicity");
+    setStringEntry(&inp, "QMmult",      is->QMmult, nullptr);
+    printStringNoNewline(&inp, "Surface Hopping");
+    setStringEntry(&inp, "SH",          is->bSH, nullptr);
+    printStringNoNewline(&inp, "CAS space options");
+    setStringEntry(&inp, "CASorbitals",      is->CASorbitals,   nullptr);
+    setStringEntry(&inp, "CASelectrons",     is->CASelectrons,  nullptr);
+    setStringEntry(&inp, "SAon", is->SAon, nullptr);
+    setStringEntry(&inp, "SAoff", is->SAoff, nullptr);
+    setStringEntry(&inp, "SAsteps", is->SAsteps, nullptr);
+    printStringNoNewline(&inp, "Scale factor for MM charges");
+    ir->scalefactor = get_ereal(&inp, "MMChargeScaleFactor", 1.0, wi);
 
     /* Simulated annealing */
-    printStringNewline(&ninp, &inp, "SIMULATED ANNEALING");
-    printStringNoNewline(&ninp, &inp, "Type of annealing for each temperature group (no/single/periodic)");
-    setStringEntry(&ninp, &inp, "annealing",   is->anneal,      nullptr);
-    printStringNoNewline(&ninp, &inp, "Number of time points to use for specifying annealing in each group");
-    setStringEntry(&ninp, &inp, "annealing-npoints", is->anneal_npoints, nullptr);
-    printStringNoNewline(&ninp, &inp, "List of times at the annealing points for each group");
-    setStringEntry(&ninp, &inp, "annealing-time",       is->anneal_time,       nullptr);
-    printStringNoNewline(&ninp, &inp, "Temp. at each annealing point, for each group.");
-    setStringEntry(&ninp, &inp, "annealing-temp",  is->anneal_temp,  nullptr);
+    printStringNewline(&inp, "SIMULATED ANNEALING");
+    printStringNoNewline(&inp, "Type of annealing for each temperature group (no/single/periodic)");
+    setStringEntry(&inp, "annealing",   is->anneal,      nullptr);
+    printStringNoNewline(&inp, "Number of time points to use for specifying annealing in each group");
+    setStringEntry(&inp, "annealing-npoints", is->anneal_npoints, nullptr);
+    printStringNoNewline(&inp, "List of times at the annealing points for each group");
+    setStringEntry(&inp, "annealing-time",       is->anneal_time,       nullptr);
+    printStringNoNewline(&inp, "Temp. at each annealing point, for each group.");
+    setStringEntry(&inp, "annealing-temp",  is->anneal_temp,  nullptr);
 
     /* Startup run */
-    printStringNewline(&ninp, &inp, "GENERATE VELOCITIES FOR STARTUP RUN");
-    opts->bGenVel = get_eeenum(&ninp, &inp, "gen-vel",  yesno_names, wi);
-    opts->tempi   = get_ereal(&ninp, &inp, "gen-temp",    300.0, wi);
-    opts->seed    = get_eint(&ninp, &inp, "gen-seed",     -1, wi);
+    printStringNewline(&inp, "GENERATE VELOCITIES FOR STARTUP RUN");
+    opts->bGenVel = get_eeenum(&inp, "gen-vel",  yesno_names, wi);
+    opts->tempi   = get_ereal(&inp, "gen-temp",    300.0, wi);
+    opts->seed    = get_eint(&inp, "gen-seed",     -1, wi);
 
     /* Shake stuff */
-    printStringNewline(&ninp, &inp, "OPTIONS FOR BONDS");
-    opts->nshake = get_eeenum(&ninp, &inp, "constraints",   constraints, wi);
-    printStringNoNewline(&ninp, &inp, "Type of constraint algorithm");
-    ir->eConstrAlg = get_eeenum(&ninp, &inp, "constraint-algorithm", econstr_names, wi);
-    printStringNoNewline(&ninp, &inp, "Do not constrain the start configuration");
-    ir->bContinuation = get_eeenum(&ninp, &inp, "continuation", yesno_names, wi);
-    printStringNoNewline(&ninp, &inp, "Use successive overrelaxation to reduce the number of shake iterations");
-    ir->bShakeSOR = get_eeenum(&ninp, &inp, "Shake-SOR", yesno_names, wi);
-    printStringNoNewline(&ninp, &inp, "Relative tolerance of shake");
-    ir->shake_tol = get_ereal(&ninp, &inp, "shake-tol", 0.0001, wi);
-    printStringNoNewline(&ninp, &inp, "Highest order in the expansion of the constraint coupling matrix");
-    ir->nProjOrder = get_eint(&ninp, &inp, "lincs-order", 4, wi);
-    printStringNoNewline(&ninp, &inp, "Number of iterations in the final step of LINCS. 1 is fine for");
-    printStringNoNewline(&ninp, &inp, "normal simulations, but use 2 to conserve energy in NVE runs.");
-    printStringNoNewline(&ninp, &inp, "For energy minimization with constraints it should be 4 to 8.");
-    ir->nLincsIter = get_eint(&ninp, &inp, "lincs-iter", 1, wi);
-    printStringNoNewline(&ninp, &inp, "Lincs will write a warning to the stderr if in one step a bond");
-    printStringNoNewline(&ninp, &inp, "rotates over more degrees than");
-    ir->LincsWarnAngle = get_ereal(&ninp, &inp, "lincs-warnangle", 30.0, wi);
-    printStringNoNewline(&ninp, &inp, "Convert harmonic bonds to morse potentials");
-    opts->bMorse = get_eeenum(&ninp, &inp, "morse", yesno_names, wi);
+    printStringNewline(&inp, "OPTIONS FOR BONDS");
+    opts->nshake = get_eeenum(&inp, "constraints",   constraints, wi);
+    printStringNoNewline(&inp, "Type of constraint algorithm");
+    ir->eConstrAlg = get_eeenum(&inp, "constraint-algorithm", econstr_names, wi);
+    printStringNoNewline(&inp, "Do not constrain the start configuration");
+    ir->bContinuation = get_eeenum(&inp, "continuation", yesno_names, wi);
+    printStringNoNewline(&inp, "Use successive overrelaxation to reduce the number of shake iterations");
+    ir->bShakeSOR = get_eeenum(&inp, "Shake-SOR", yesno_names, wi);
+    printStringNoNewline(&inp, "Relative tolerance of shake");
+    ir->shake_tol = get_ereal(&inp, "shake-tol", 0.0001, wi);
+    printStringNoNewline(&inp, "Highest order in the expansion of the constraint coupling matrix");
+    ir->nProjOrder = get_eint(&inp, "lincs-order", 4, wi);
+    printStringNoNewline(&inp, "Number of iterations in the final step of LINCS. 1 is fine for");
+    printStringNoNewline(&inp, "normal simulations, but use 2 to conserve energy in NVE runs.");
+    printStringNoNewline(&inp, "For energy minimization with constraints it should be 4 to 8.");
+    ir->nLincsIter = get_eint(&inp, "lincs-iter", 1, wi);
+    printStringNoNewline(&inp, "Lincs will write a warning to the stderr if in one step a bond");
+    printStringNoNewline(&inp, "rotates over more degrees than");
+    ir->LincsWarnAngle = get_ereal(&inp, "lincs-warnangle", 30.0, wi);
+    printStringNoNewline(&inp, "Convert harmonic bonds to morse potentials");
+    opts->bMorse = get_eeenum(&inp, "morse", yesno_names, wi);
 
     /* Energy group exclusions */
-    printStringNewline(&ninp, &inp, "ENERGY GROUP EXCLUSIONS");
-    printStringNoNewline(&ninp, &inp, "Pairs of energy groups for which all non-bonded interactions are excluded");
-    setStringEntry(&ninp, &inp, "energygrp-excl", is->egpexcl,     nullptr);
+    printStringNewline(&inp, "ENERGY GROUP EXCLUSIONS");
+    printStringNoNewline(&inp, "Pairs of energy groups for which all non-bonded interactions are excluded");
+    setStringEntry(&inp, "energygrp-excl", is->egpexcl,     nullptr);
 
     /* Walls */
-    printStringNewline(&ninp, &inp, "WALLS");
-    printStringNoNewline(&ninp, &inp, "Number of walls, type, atom types, densities and box-z scale factor for Ewald");
-    ir->nwall         = get_eint(&ninp, &inp, "nwall", 0, wi);
-    ir->wall_type     = get_eeenum(&ninp, &inp, "wall-type",   ewt_names, wi);
-    ir->wall_r_linpot = get_ereal(&ninp, &inp, "wall-r-linpot", -1, wi);
-    setStringEntry(&ninp, &inp, "wall-atomtype", is->wall_atomtype, nullptr);
-    setStringEntry(&ninp, &inp, "wall-density",  is->wall_density,  nullptr);
-    ir->wall_ewald_zfac = get_ereal(&ninp, &inp, "wall-ewald-zfac", 3, wi);
+    printStringNewline(&inp, "WALLS");
+    printStringNoNewline(&inp, "Number of walls, type, atom types, densities and box-z scale factor for Ewald");
+    ir->nwall         = get_eint(&inp, "nwall", 0, wi);
+    ir->wall_type     = get_eeenum(&inp, "wall-type",   ewt_names, wi);
+    ir->wall_r_linpot = get_ereal(&inp, "wall-r-linpot", -1, wi);
+    setStringEntry(&inp, "wall-atomtype", is->wall_atomtype, nullptr);
+    setStringEntry(&inp, "wall-density",  is->wall_density,  nullptr);
+    ir->wall_ewald_zfac = get_ereal(&inp, "wall-ewald-zfac", 3, wi);
 
     /* COM pulling */
-    printStringNewline(&ninp, &inp, "COM PULLING");
-    ir->bPull = get_eeenum(&ninp, &inp, "pull", yesno_names, wi);
+    printStringNewline(&inp, "COM PULLING");
+    ir->bPull = get_eeenum(&inp, "pull", yesno_names, wi);
     if (ir->bPull)
     {
         snew(ir->pull, 1);
-        is->pull_grp = read_pullparams(&ninp, &inp, ir->pull, wi);
+        is->pull_grp = read_pullparams(&inp, ir->pull, wi);
     }
 
     /* AWH biasing
        NOTE: needs COM pulling input */
-    printStringNewline(&ninp, &inp, "AWH biasing");
-    ir->bDoAwh = get_eeenum(&ninp, &inp, "awh", yesno_names, wi);
+    printStringNewline(&inp, "AWH biasing");
+    ir->bDoAwh = get_eeenum(&inp, "awh", yesno_names, wi);
     if (ir->bDoAwh)
     {
         if (ir->bPull)
         {
-            ir->awhParams = gmx::readAndCheckAwhParams(&ninp, &inp, ir, wi);
+            ir->awhParams = gmx::readAndCheckAwhParams(&inp, ir, wi);
         }
         else
         {
@@ -2094,19 +2084,19 @@ void get_ir(const char *mdparin, const char *mdparout,
     }
 
     /* Enforced rotation */
-    printStringNewline(&ninp, &inp, "ENFORCED ROTATION");
-    printStringNoNewline(&ninp, &inp, "Enforced rotation: No or Yes");
-    ir->bRot = get_eeenum(&ninp, &inp, "rotation", yesno_names, wi);
+    printStringNewline(&inp, "ENFORCED ROTATION");
+    printStringNoNewline(&inp, "Enforced rotation: No or Yes");
+    ir->bRot = get_eeenum(&inp, "rotation", yesno_names, wi);
     if (ir->bRot)
     {
         snew(ir->rot, 1);
-        is->rot_grp = read_rotparams(&ninp, &inp, ir->rot, wi);
+        is->rot_grp = read_rotparams(&inp, ir->rot, wi);
     }
 
     /* Interactive MD */
     ir->bIMD = FALSE;
-    printStringNewline(&ninp, &inp, "Group to display and/or manipulate in interactive MD session");
-    setStringEntry(&ninp, &inp, "IMD-group", is->imd_grp, nullptr);
+    printStringNewline(&inp, "Group to display and/or manipulate in interactive MD session");
+    setStringEntry(&inp, "IMD-group", is->imd_grp, nullptr);
     if (is->imd_grp[0] != '\0')
     {
         snew(ir->imd, 1);
@@ -2114,87 +2104,87 @@ void get_ir(const char *mdparin, const char *mdparout,
     }
 
     /* Refinement */
-    printStringNewline(&ninp, &inp, "NMR refinement stuff");
-    printStringNoNewline(&ninp, &inp, "Distance restraints type: No, Simple or Ensemble");
-    ir->eDisre = get_eeenum(&ninp, &inp, "disre",     edisre_names, wi);
-    printStringNoNewline(&ninp, &inp, "Force weighting of pairs in one distance restraint: Conservative or Equal");
-    ir->eDisreWeighting = get_eeenum(&ninp, &inp, "disre-weighting", edisreweighting_names, wi);
-    printStringNoNewline(&ninp, &inp, "Use sqrt of the time averaged times the instantaneous violation");
-    ir->bDisreMixed = get_eeenum(&ninp, &inp, "disre-mixed", yesno_names, wi);
-    ir->dr_fc       = get_ereal(&ninp, &inp, "disre-fc",  1000.0, wi);
-    ir->dr_tau      = get_ereal(&ninp, &inp, "disre-tau", 0.0, wi);
-    printStringNoNewline(&ninp, &inp, "Output frequency for pair distances to energy file");
-    ir->nstdisreout = get_eint(&ninp, &inp, "nstdisreout", 100, wi);
-    printStringNoNewline(&ninp, &inp, "Orientation restraints: No or Yes");
-    opts->bOrire = get_eeenum(&ninp, &inp, "orire",   yesno_names, wi);
-    printStringNoNewline(&ninp, &inp, "Orientation restraints force constant and tau for time averaging");
-    ir->orires_fc  = get_ereal(&ninp, &inp, "orire-fc",  0.0, wi);
-    ir->orires_tau = get_ereal(&ninp, &inp, "orire-tau", 0.0, wi);
-    setStringEntry(&ninp, &inp, "orire-fitgrp", is->orirefitgrp,    nullptr);
-    printStringNoNewline(&ninp, &inp, "Output frequency for trace(SD) and S to energy file");
-    ir->nstorireout = get_eint(&ninp, &inp, "nstorireout", 100, wi);
+    printStringNewline(&inp, "NMR refinement stuff");
+    printStringNoNewline(&inp, "Distance restraints type: No, Simple or Ensemble");
+    ir->eDisre = get_eeenum(&inp, "disre",     edisre_names, wi);
+    printStringNoNewline(&inp, "Force weighting of pairs in one distance restraint: Conservative or Equal");
+    ir->eDisreWeighting = get_eeenum(&inp, "disre-weighting", edisreweighting_names, wi);
+    printStringNoNewline(&inp, "Use sqrt of the time averaged times the instantaneous violation");
+    ir->bDisreMixed = get_eeenum(&inp, "disre-mixed", yesno_names, wi);
+    ir->dr_fc       = get_ereal(&inp, "disre-fc",  1000.0, wi);
+    ir->dr_tau      = get_ereal(&inp, "disre-tau", 0.0, wi);
+    printStringNoNewline(&inp, "Output frequency for pair distances to energy file");
+    ir->nstdisreout = get_eint(&inp, "nstdisreout", 100, wi);
+    printStringNoNewline(&inp, "Orientation restraints: No or Yes");
+    opts->bOrire = get_eeenum(&inp, "orire",   yesno_names, wi);
+    printStringNoNewline(&inp, "Orientation restraints force constant and tau for time averaging");
+    ir->orires_fc  = get_ereal(&inp, "orire-fc",  0.0, wi);
+    ir->orires_tau = get_ereal(&inp, "orire-tau", 0.0, wi);
+    setStringEntry(&inp, "orire-fitgrp", is->orirefitgrp,    nullptr);
+    printStringNoNewline(&inp, "Output frequency for trace(SD) and S to energy file");
+    ir->nstorireout = get_eint(&inp, "nstorireout", 100, wi);
 
     /* free energy variables */
-    printStringNewline(&ninp, &inp, "Free energy variables");
-    ir->efep = get_eeenum(&ninp, &inp, "free-energy", efep_names, wi);
-    setStringEntry(&ninp, &inp, "couple-moltype",  is->couple_moltype,  nullptr);
-    opts->couple_lam0  = get_eeenum(&ninp, &inp, "couple-lambda0", couple_lam, wi);
-    opts->couple_lam1  = get_eeenum(&ninp, &inp, "couple-lambda1", couple_lam, wi);
-    opts->bCoupleIntra = get_eeenum(&ninp, &inp, "couple-intramol", yesno_names, wi);
-
-    fep->init_lambda    = get_ereal(&ninp, &inp, "init-lambda", -1, wi); /* start with -1 so
+    printStringNewline(&inp, "Free energy variables");
+    ir->efep = get_eeenum(&inp, "free-energy", efep_names, wi);
+    setStringEntry(&inp, "couple-moltype",  is->couple_moltype,  nullptr);
+    opts->couple_lam0  = get_eeenum(&inp, "couple-lambda0", couple_lam, wi);
+    opts->couple_lam1  = get_eeenum(&inp, "couple-lambda1", couple_lam, wi);
+    opts->bCoupleIntra = get_eeenum(&inp, "couple-intramol", yesno_names, wi);
+
+    fep->init_lambda    = get_ereal(&inp, "init-lambda", -1, wi); /* start with -1 so
                                                                             we can recognize if
                                                                             it was not entered */
-    fep->init_fep_state = get_eint(&ninp, &inp, "init-lambda-state", -1, wi);
-    fep->delta_lambda   = get_ereal(&ninp, &inp, "delta-lambda", 0.0, wi);
-    fep->nstdhdl        = get_eint(&ninp, &inp, "nstdhdl", 50, wi);
-    setStringEntry(&ninp, &inp, "fep-lambdas", is->fep_lambda[efptFEP], nullptr);
-    setStringEntry(&ninp, &inp, "mass-lambdas", is->fep_lambda[efptMASS], nullptr);
-    setStringEntry(&ninp, &inp, "coul-lambdas", is->fep_lambda[efptCOUL], nullptr);
-    setStringEntry(&ninp, &inp, "vdw-lambdas", is->fep_lambda[efptVDW], nullptr);
-    setStringEntry(&ninp, &inp, "bonded-lambdas", is->fep_lambda[efptBONDED], nullptr);
-    setStringEntry(&ninp, &inp, "restraint-lambdas", is->fep_lambda[efptRESTRAINT], nullptr);
-    setStringEntry(&ninp, &inp, "temperature-lambdas", is->fep_lambda[efptTEMPERATURE], nullptr);
-    fep->lambda_neighbors = get_eint(&ninp, &inp, "calc-lambda-neighbors", 1, wi);
-    setStringEntry(&ninp, &inp, "init-lambda-weights", is->lambda_weights, nullptr);
-    fep->edHdLPrintEnergy   = get_eeenum(&ninp, &inp, "dhdl-print-energy", edHdLPrintEnergy_names, wi);
-    fep->sc_alpha           = get_ereal(&ninp, &inp, "sc-alpha", 0.0, wi);
-    fep->sc_power           = get_eint(&ninp, &inp, "sc-power", 1, wi);
-    fep->sc_r_power         = get_ereal(&ninp, &inp, "sc-r-power", 6.0, wi);
-    fep->sc_sigma           = get_ereal(&ninp, &inp, "sc-sigma", 0.3, wi);
-    fep->bScCoul            = get_eeenum(&ninp, &inp, "sc-coul", yesno_names, wi);
-    fep->dh_hist_size       = get_eint(&ninp, &inp, "dh_hist_size", 0, wi);
-    fep->dh_hist_spacing    = get_ereal(&ninp, &inp, "dh_hist_spacing", 0.1, wi);
-    fep->separate_dhdl_file = get_eeenum(&ninp, &inp, "separate-dhdl-file", separate_dhdl_file_names, wi);
-    fep->dhdl_derivatives   = get_eeenum(&ninp, &inp, "dhdl-derivatives", dhdl_derivatives_names, wi);
-    fep->dh_hist_size       = get_eint(&ninp, &inp, "dh_hist_size", 0, wi);
-    fep->dh_hist_spacing    = get_ereal(&ninp, &inp, "dh_hist_spacing", 0.1, wi);
+    fep->init_fep_state = get_eint(&inp, "init-lambda-state", -1, wi);
+    fep->delta_lambda   = get_ereal(&inp, "delta-lambda", 0.0, wi);
+    fep->nstdhdl        = get_eint(&inp, "nstdhdl", 50, wi);
+    setStringEntry(&inp, "fep-lambdas", is->fep_lambda[efptFEP], nullptr);
+    setStringEntry(&inp, "mass-lambdas", is->fep_lambda[efptMASS], nullptr);
+    setStringEntry(&inp, "coul-lambdas", is->fep_lambda[efptCOUL], nullptr);
+    setStringEntry(&inp, "vdw-lambdas", is->fep_lambda[efptVDW], nullptr);
+    setStringEntry(&inp, "bonded-lambdas", is->fep_lambda[efptBONDED], nullptr);
+    setStringEntry(&inp, "restraint-lambdas", is->fep_lambda[efptRESTRAINT], nullptr);
+    setStringEntry(&inp, "temperature-lambdas", is->fep_lambda[efptTEMPERATURE], nullptr);
+    fep->lambda_neighbors = get_eint(&inp, "calc-lambda-neighbors", 1, wi);
+    setStringEntry(&inp, "init-lambda-weights", is->lambda_weights, nullptr);
+    fep->edHdLPrintEnergy   = get_eeenum(&inp, "dhdl-print-energy", edHdLPrintEnergy_names, wi);
+    fep->sc_alpha           = get_ereal(&inp, "sc-alpha", 0.0, wi);
+    fep->sc_power           = get_eint(&inp, "sc-power", 1, wi);
+    fep->sc_r_power         = get_ereal(&inp, "sc-r-power", 6.0, wi);
+    fep->sc_sigma           = get_ereal(&inp, "sc-sigma", 0.3, wi);
+    fep->bScCoul            = get_eeenum(&inp, "sc-coul", yesno_names, wi);
+    fep->dh_hist_size       = get_eint(&inp, "dh_hist_size", 0, wi);
+    fep->dh_hist_spacing    = get_ereal(&inp, "dh_hist_spacing", 0.1, wi);
+    fep->separate_dhdl_file = get_eeenum(&inp, "separate-dhdl-file", separate_dhdl_file_names, wi);
+    fep->dhdl_derivatives   = get_eeenum(&inp, "dhdl-derivatives", dhdl_derivatives_names, wi);
+    fep->dh_hist_size       = get_eint(&inp, "dh_hist_size", 0, wi);
+    fep->dh_hist_spacing    = get_ereal(&inp, "dh_hist_spacing", 0.1, wi);
 
     /* Non-equilibrium MD stuff */
-    printStringNewline(&ninp, &inp, "Non-equilibrium MD stuff");
-    setStringEntry(&ninp, &inp, "acc-grps",    is->accgrps,        nullptr);
-    setStringEntry(&ninp, &inp, "accelerate",  is->acc,            nullptr);
-    setStringEntry(&ninp, &inp, "freezegrps",  is->freeze,         nullptr);
-    setStringEntry(&ninp, &inp, "freezedim",   is->frdim,          nullptr);
-    ir->cos_accel = get_ereal(&ninp, &inp, "cos-acceleration", 0, wi);
-    setStringEntry(&ninp, &inp, "deform",      is->deform,         nullptr);
+    printStringNewline(&inp, "Non-equilibrium MD stuff");
+    setStringEntry(&inp, "acc-grps",    is->accgrps,        nullptr);
+    setStringEntry(&inp, "accelerate",  is->acc,            nullptr);
+    setStringEntry(&inp, "freezegrps",  is->freeze,         nullptr);
+    setStringEntry(&inp, "freezedim",   is->frdim,          nullptr);
+    ir->cos_accel = get_ereal(&inp, "cos-acceleration", 0, wi);
+    setStringEntry(&inp, "deform",      is->deform,         nullptr);
 
     /* simulated tempering variables */
-    printStringNewline(&ninp, &inp, "simulated tempering variables");
-    ir->bSimTemp                   = get_eeenum(&ninp, &inp, "simulated-tempering", yesno_names, wi);
-    ir->simtempvals->eSimTempScale = get_eeenum(&ninp, &inp, "simulated-tempering-scaling", esimtemp_names, wi);
-    ir->simtempvals->simtemp_low   = get_ereal(&ninp, &inp, "sim-temp-low", 300.0, wi);
-    ir->simtempvals->simtemp_high  = get_ereal(&ninp, &inp, "sim-temp-high", 300.0, wi);
+    printStringNewline(&inp, "simulated tempering variables");
+    ir->bSimTemp                   = get_eeenum(&inp, "simulated-tempering", yesno_names, wi);
+    ir->simtempvals->eSimTempScale = get_eeenum(&inp, "simulated-tempering-scaling", esimtemp_names, wi);
+    ir->simtempvals->simtemp_low   = get_ereal(&inp, "sim-temp-low", 300.0, wi);
+    ir->simtempvals->simtemp_high  = get_ereal(&inp, "sim-temp-high", 300.0, wi);
 
     /* expanded ensemble variables */
     if (ir->efep == efepEXPANDED || ir->bSimTemp)
     {
-        read_expandedparams(&ninp, &inp, expand, wi);
+        read_expandedparams(&inp, expand, wi);
     }
 
     /* Electric fields */
     {
-        gmx::KeyValueTreeObject      convertedValues = flatKeyValueTreeFromInpFile(ninp, inp);
+        gmx::KeyValueTreeObject      convertedValues = flatKeyValueTreeFromInpFile(inp);
         gmx::KeyValueTreeTransformer transform;
         transform.rules()->addRule()
             .keyMatchType("/", gmx::StringCompareType::CaseAndDashInsensitive);
@@ -2202,7 +2192,7 @@ void get_ir(const char *mdparin, const char *mdparout,
         for (const auto &path : transform.mappedPaths())
         {
             GMX_ASSERT(path.size() == 1, "Inconsistent mapping back to mdp options");
-            mark_einp_set(ninp, inp, path[0].c_str());
+            mark_einp_set(inp, path[0].c_str());
         }
         MdpErrorHandler              errorHandler(wi);
         auto                         result
@@ -2214,9 +2204,9 @@ void get_ir(const char *mdparin, const char *mdparout,
     }
 
     /* Ion/water position swapping ("computational electrophysiology") */
-    printStringNewline(&ninp, &inp, "Ion/water position swapping for computational electrophysiology setups");
-    printStringNoNewline(&ninp, &inp, "Swap positions along direction: no, X, Y, Z");
-    ir->eSwapCoords = get_eeenum(&ninp, &inp, "swapcoords", eSwapTypes_names, wi);
+    printStringNewline(&inp, "Ion/water position swapping for computational electrophysiology setups");
+    printStringNoNewline(&inp, "Swap positions along direction: no, X, Y, Z");
+    ir->eSwapCoords = get_eeenum(&inp, "swapcoords", eSwapTypes_names, wi);
     if (ir->eSwapCoords != eswapNO)
     {
         char buf[STRLEN];
@@ -2224,10 +2214,10 @@ void get_ir(const char *mdparin, const char *mdparout,
 
 
         snew(ir->swap, 1);
-        printStringNoNewline(&ninp, &inp, "Swap attempt frequency");
-        ir->swap->nstswap = get_eint(&ninp, &inp, "swap-frequency", 1, wi);
-        printStringNoNewline(&ninp, &inp, "Number of ion types to be controlled");
-        nIonTypes = get_eint(&ninp, &inp, "iontypes", 1, wi);
+        printStringNoNewline(&inp, "Swap attempt frequency");
+        ir->swap->nstswap = get_eint(&inp, "swap-frequency", 1, wi);
+        printStringNoNewline(&inp, "Number of ion types to be controlled");
+        nIonTypes = get_eint(&inp, "iontypes", 1, wi);
         if (nIonTypes < 1)
         {
             warning_error(wi, "You need to provide at least one ion type for position exchanges.");
@@ -2238,81 +2228,81 @@ void get_ir(const char *mdparin, const char *mdparout,
         {
             snew(ir->swap->grp[i].molname, STRLEN);
         }
-        printStringNoNewline(&ninp, &inp, "Two index groups that contain the compartment-partitioning atoms");
-        setStringEntry(&ninp, &inp, "split-group0", ir->swap->grp[eGrpSplit0].molname, nullptr);
-        setStringEntry(&ninp, &inp, "split-group1", ir->swap->grp[eGrpSplit1].molname, nullptr);
-        printStringNoNewline(&ninp, &inp, "Use center of mass of split groups (yes/no), otherwise center of geometry is used");
-        ir->swap->massw_split[0] = get_eeenum(&ninp, &inp, "massw-split0", yesno_names, wi);
-        ir->swap->massw_split[1] = get_eeenum(&ninp, &inp, "massw-split1", yesno_names, wi);
-
-        printStringNoNewline(&ninp, &inp, "Name of solvent molecules");
-        setStringEntry(&ninp, &inp, "solvent-group", ir->swap->grp[eGrpSolvent].molname, nullptr);
-
-        printStringNoNewline(&ninp, &inp, "Split cylinder: radius, upper and lower extension (nm) (this will define the channels)");
-        printStringNoNewline(&ninp, &inp, "Note that the split cylinder settings do not have an influence on the swapping protocol,");
-        printStringNoNewline(&ninp, &inp, "however, if correctly defined, the permeation events are recorded per channel");
-        ir->swap->cyl0r = get_ereal(&ninp, &inp, "cyl0-r", 2.0, wi);
-        ir->swap->cyl0u = get_ereal(&ninp, &inp, "cyl0-up", 1.0, wi);
-        ir->swap->cyl0l = get_ereal(&ninp, &inp, "cyl0-down", 1.0, wi);
-        ir->swap->cyl1r = get_ereal(&ninp, &inp, "cyl1-r", 2.0, wi);
-        ir->swap->cyl1u = get_ereal(&ninp, &inp, "cyl1-up", 1.0, wi);
-        ir->swap->cyl1l = get_ereal(&ninp, &inp, "cyl1-down", 1.0, wi);
-
-        printStringNoNewline(&ninp, &inp, "Average the number of ions per compartment over these many swap attempt steps");
-        ir->swap->nAverage = get_eint(&ninp, &inp, "coupl-steps", 10, wi);
-
-        printStringNoNewline(&ninp, &inp, "Names of the ion types that can be exchanged with solvent molecules,");
-        printStringNoNewline(&ninp, &inp, "and the requested number of ions of this type in compartments A and B");
-        printStringNoNewline(&ninp, &inp, "-1 means fix the numbers as found in step 0");
+        printStringNoNewline(&inp, "Two index groups that contain the compartment-partitioning atoms");
+        setStringEntry(&inp, "split-group0", ir->swap->grp[eGrpSplit0].molname, nullptr);
+        setStringEntry(&inp, "split-group1", ir->swap->grp[eGrpSplit1].molname, nullptr);
+        printStringNoNewline(&inp, "Use center of mass of split groups (yes/no), otherwise center of geometry is used");
+        ir->swap->massw_split[0] = get_eeenum(&inp, "massw-split0", yesno_names, wi);
+        ir->swap->massw_split[1] = get_eeenum(&inp, "massw-split1", yesno_names, wi);
+
+        printStringNoNewline(&inp, "Name of solvent molecules");
+        setStringEntry(&inp, "solvent-group", ir->swap->grp[eGrpSolvent].molname, nullptr);
+
+        printStringNoNewline(&inp, "Split cylinder: radius, upper and lower extension (nm) (this will define the channels)");
+        printStringNoNewline(&inp, "Note that the split cylinder settings do not have an influence on the swapping protocol,");
+        printStringNoNewline(&inp, "however, if correctly defined, the permeation events are recorded per channel");
+        ir->swap->cyl0r = get_ereal(&inp, "cyl0-r", 2.0, wi);
+        ir->swap->cyl0u = get_ereal(&inp, "cyl0-up", 1.0, wi);
+        ir->swap->cyl0l = get_ereal(&inp, "cyl0-down", 1.0, wi);
+        ir->swap->cyl1r = get_ereal(&inp, "cyl1-r", 2.0, wi);
+        ir->swap->cyl1u = get_ereal(&inp, "cyl1-up", 1.0, wi);
+        ir->swap->cyl1l = get_ereal(&inp, "cyl1-down", 1.0, wi);
+
+        printStringNoNewline(&inp, "Average the number of ions per compartment over these many swap attempt steps");
+        ir->swap->nAverage = get_eint(&inp, "coupl-steps", 10, wi);
+
+        printStringNoNewline(&inp, "Names of the ion types that can be exchanged with solvent molecules,");
+        printStringNoNewline(&inp, "and the requested number of ions of this type in compartments A and B");
+        printStringNoNewline(&inp, "-1 means fix the numbers as found in step 0");
         for (i = 0; i < nIonTypes; i++)
         {
             int ig = eSwapFixedGrpNR + i;
 
             sprintf(buf, "iontype%d-name", i);
-            setStringEntry(&ninp, &inp, buf, ir->swap->grp[ig].molname, nullptr);
+            setStringEntry(&inp, buf, ir->swap->grp[ig].molname, nullptr);
             sprintf(buf, "iontype%d-in-A", i);
-            ir->swap->grp[ig].nmolReq[0] = get_eint(&ninp, &inp, buf, -1, wi);
+            ir->swap->grp[ig].nmolReq[0] = get_eint(&inp, buf, -1, wi);
             sprintf(buf, "iontype%d-in-B", i);
-            ir->swap->grp[ig].nmolReq[1] = get_eint(&ninp, &inp, buf, -1, wi);
+            ir->swap->grp[ig].nmolReq[1] = get_eint(&inp, buf, -1, wi);
         }
 
-        printStringNoNewline(&ninp, &inp, "By default (i.e. bulk offset = 0.0), ion/water exchanges happen between layers");
-        printStringNoNewline(&ninp, &inp, "at maximum distance (= bulk concentration) to the split group layers. However,");
-        printStringNoNewline(&ninp, &inp, "an offset b (-1.0 < b < +1.0) can be specified to offset the bulk layer from the middle at 0.0");
-        printStringNoNewline(&ninp, &inp, "towards one of the compartment-partitioning layers (at +/- 1.0).");
-        ir->swap->bulkOffset[0] = get_ereal(&ninp, &inp, "bulk-offsetA", 0.0, wi);
-        ir->swap->bulkOffset[1] = get_ereal(&ninp, &inp, "bulk-offsetB", 0.0, wi);
+        printStringNoNewline(&inp, "By default (i.e. bulk offset = 0.0), ion/water exchanges happen between layers");
+        printStringNoNewline(&inp, "at maximum distance (= bulk concentration) to the split group layers. However,");
+        printStringNoNewline(&inp, "an offset b (-1.0 < b < +1.0) can be specified to offset the bulk layer from the middle at 0.0");
+        printStringNoNewline(&inp, "towards one of the compartment-partitioning layers (at +/- 1.0).");
+        ir->swap->bulkOffset[0] = get_ereal(&inp, "bulk-offsetA", 0.0, wi);
+        ir->swap->bulkOffset[1] = get_ereal(&inp, "bulk-offsetB", 0.0, wi);
         if (!(ir->swap->bulkOffset[0] > -1.0 && ir->swap->bulkOffset[0] < 1.0)
             || !(ir->swap->bulkOffset[1] > -1.0 && ir->swap->bulkOffset[1] < 1.0) )
         {
             warning_error(wi, "Bulk layer offsets must be > -1.0 and < 1.0 !");
         }
 
-        printStringNoNewline(&ninp, &inp, "Start to swap ions if threshold difference to requested count is reached");
-        ir->swap->threshold = get_ereal(&ninp, &inp, "threshold", 1.0, wi);
+        printStringNoNewline(&inp, "Start to swap ions if threshold difference to requested count is reached");
+        ir->swap->threshold = get_ereal(&inp, "threshold", 1.0, wi);
     }
 
     /* AdResS is no longer supported, but we need grompp to be able to
        refuse to process old .mdp files that used it. */
-    ir->bAdress = get_eeenum(&ninp, &inp, "adress", no_names, wi);
+    ir->bAdress = get_eeenum(&inp, "adress", no_names, wi);
 
     /* User defined thingies */
-    printStringNewline(&ninp, &inp, "User defined thingies");
-    setStringEntry(&ninp, &inp, "user1-grps",  is->user1,          nullptr);
-    setStringEntry(&ninp, &inp, "user2-grps",  is->user2,          nullptr);
-    ir->userint1  = get_eint(&ninp, &inp, "userint1",   0, wi);
-    ir->userint2  = get_eint(&ninp, &inp, "userint2",   0, wi);
-    ir->userint3  = get_eint(&ninp, &inp, "userint3",   0, wi);
-    ir->userint4  = get_eint(&ninp, &inp, "userint4",   0, wi);
-    ir->userreal1 = get_ereal(&ninp, &inp, "userreal1",  0, wi);
-    ir->userreal2 = get_ereal(&ninp, &inp, "userreal2",  0, wi);
-    ir->userreal3 = get_ereal(&ninp, &inp, "userreal3",  0, wi);
-    ir->userreal4 = get_ereal(&ninp, &inp, "userreal4",  0, wi);
+    printStringNewline(&inp, "User defined thingies");
+    setStringEntry(&inp, "user1-grps",  is->user1,          nullptr);
+    setStringEntry(&inp, "user2-grps",  is->user2,          nullptr);
+    ir->userint1  = get_eint(&inp, "userint1",   0, wi);
+    ir->userint2  = get_eint(&inp, "userint2",   0, wi);
+    ir->userint3  = get_eint(&inp, "userint3",   0, wi);
+    ir->userint4  = get_eint(&inp, "userint4",   0, wi);
+    ir->userreal1 = get_ereal(&inp, "userreal1",  0, wi);
+    ir->userreal2 = get_ereal(&inp, "userreal2",  0, wi);
+    ir->userreal3 = get_ereal(&inp, "userreal3",  0, wi);
+    ir->userreal4 = get_ereal(&inp, "userreal4",  0, wi);
 #undef CTYPE
 
     {
         gmx::TextOutputFile stream(mdparout);
-        write_inpfile(&stream, mdparout, ninp, inp, FALSE, writeMdpHeader, wi);
+        write_inpfile(&stream, mdparout, &inp, FALSE, writeMdpHeader, wi);
 
         // Transform module data into a flat key-value tree for output.
         gmx::KeyValueTreeBuilder       builder;
@@ -2325,13 +2315,6 @@ void get_ir(const char *mdparin, const char *mdparout,
         stream.close();
     }
 
-    for (i = 0; (i < ninp); i++)
-    {
-        sfree(inp[i].name);
-        sfree(inp[i].value);
-    }
-    sfree(inp);
-
     /* Process options if necessary */
     for (m = 0; m < 2; m++)
     {
index 50999e15e972c359dc90120b4f9676eae94e99a9..73bd5db542042cb9d86907e011267a44a027ed22 100644 (file)
@@ -133,9 +133,9 @@ void do_index(const char* mdparin,
 
 /* Routines In readpull.c */
 
-char **read_pullparams(int *ninp_p, t_inpfile **inp,
-                       pull_params_t *pull,
-                       warninp_t wi);
+char **read_pullparams(std::vector<t_inpfile> *inp,
+                       pull_params_t          *pull,
+                       warninp_t               wi);
 /* Reads the pull parameters, returns a list of the pull group names */
 
 void make_pull_groups(pull_params_t *pull,
@@ -157,7 +157,7 @@ pull_t *set_pull_init(t_inputrec *ir, const gmx_mtop_t *mtop,
 int str_nelem(const char *str, int maxptr, char *ptr[]);
 /* helper function from readir.c to convert strings */
 
-char **read_rotparams(int *ninp_p, t_inpfile **inp, t_rot *rot, warninp_t wi);
+char **read_rotparams(std::vector<t_inpfile> *inp, t_rot *rot, warninp_t wi);
 /* Reads enforced rotation parameters, returns a list of the rot group names */
 
 void make_rotation_groups(t_rot *rot, char **rotgnames,
index 2b6f5414aaa48758a065ab755bfb86bd718da81f..42071b14e50d5cfbfa0518bb4974bf9a016aec25 100644 (file)
@@ -263,32 +263,32 @@ static void init_pull_coord(t_pull_coord *pcrd, int coord_index_for_output,
     }
 }
 
-char **read_pullparams(int *ninp_p, t_inpfile **inp_p,
-                       pull_params_t *pull,
-                       warninp_t wi)
+char **read_pullparams(std::vector<t_inpfile> *inp,
+                       pull_params_t          *pull,
+                       warninp_t               wi)
 {
-    int           nscan, idum;
-    char        **grpbuf;
-    char          buf[STRLEN];
-    char          provider[STRLEN], groups[STRLEN], dim_buf[STRLEN];
-    char          wbuf[STRLEN], origin_buf[STRLEN], vec_buf[STRLEN];
+    int                    nscan, idum;
+    char                 **grpbuf;
+    char                   buf[STRLEN];
+    char                   provider[STRLEN], groups[STRLEN], dim_buf[STRLEN];
+    char                   wbuf[STRLEN], origin_buf[STRLEN], vec_buf[STRLEN];
 
-    t_pull_group *pgrp;
-    t_pull_coord *pcrd;
+    t_pull_group          *pgrp;
+    t_pull_coord          *pcrd;
 
     /* read pull parameters */
-    printStringNoNewline(ninp_p, inp_p, "Cylinder radius for dynamic reaction force groups (nm)");
-    pull->cylinder_r     = get_ereal(ninp_p, inp_p, "pull-cylinder-r", 1.5, wi);
-    pull->constr_tol     = get_ereal(ninp_p, inp_p, "pull-constr-tol", 1E-6, wi);
-    pull->bPrintCOM      = get_eeenum(ninp_p, inp_p, "pull-print-com", yesno_names, wi);
-    pull->bPrintRefValue = get_eeenum(ninp_p, inp_p, "pull-print-ref-value", yesno_names, wi);
-    pull->bPrintComp     = get_eeenum(ninp_p, inp_p, "pull-print-components", yesno_names, wi);
-    pull->nstxout        = get_eint(ninp_p, inp_p, "pull-nstxout", 50, wi);
-    pull->nstfout        = get_eint(ninp_p, inp_p, "pull-nstfout", 50, wi);
-    printStringNoNewline(ninp_p, inp_p, "Number of pull groups");
-    pull->ngroup = get_eint(ninp_p, inp_p, "pull-ngroups", 1, wi);
-    printStringNoNewline(ninp_p, inp_p, "Number of pull coordinates");
-    pull->ncoord = get_eint(ninp_p, inp_p, "pull-ncoords", 1, wi);
+    printStringNoNewline(inp, "Cylinder radius for dynamic reaction force groups (nm)");
+    pull->cylinder_r     = get_ereal(inp, "pull-cylinder-r", 1.5, wi);
+    pull->constr_tol     = get_ereal(inp, "pull-constr-tol", 1E-6, wi);
+    pull->bPrintCOM      = get_eeenum(inp, "pull-print-com", yesno_names, wi);
+    pull->bPrintRefValue = get_eeenum(inp, "pull-print-ref-value", yesno_names, wi);
+    pull->bPrintComp     = get_eeenum(inp, "pull-print-components", yesno_names, wi);
+    pull->nstxout        = get_eint(inp, "pull-nstxout", 50, wi);
+    pull->nstfout        = get_eint(inp, "pull-nstfout", 50, wi);
+    printStringNoNewline(inp, "Number of pull groups");
+    pull->ngroup = get_eint(inp, "pull-ngroups", 1, wi);
+    printStringNoNewline(inp, "Number of pull coordinates");
+    pull->ncoord = get_eint(inp, "pull-ncoords", 1, wi);
 
     if (pull->ngroup < 1)
     {
@@ -307,7 +307,7 @@ char **read_pullparams(int *ninp_p, t_inpfile **inp_p,
     snew(pull->coord, pull->ncoord);
 
     /* pull group options */
-    printStringNoNewline(ninp_p, inp_p, "Group and coordinate parameters");
+    printStringNoNewline(inp, "Group and coordinate parameters");
 
     /* Read the pull groups */
     snew(grpbuf, pull->ngroup);
@@ -317,11 +317,11 @@ char **read_pullparams(int *ninp_p, t_inpfile **inp_p,
         pgrp = &pull->group[groupNum];
         snew(grpbuf[groupNum], STRLEN);
         sprintf(buf, "pull-group%d-name", groupNum);
-        setStringEntry(ninp_p, inp_p, buf, grpbuf[groupNum], "");
+        setStringEntry(inp, buf, grpbuf[groupNum], "");
         sprintf(buf, "pull-group%d-weights", groupNum);
-        setStringEntry(ninp_p, inp_p, buf, wbuf, "");
+        setStringEntry(inp, buf, wbuf, "");
         sprintf(buf, "pull-group%d-pbcatom", groupNum);
-        pgrp->pbcatom = get_eint(ninp_p, inp_p, buf, 0, wi);
+        pgrp->pbcatom = get_eint(inp, buf, 0, wi);
 
         /* Initialize the pull group */
         init_pull_group(pgrp, wbuf);
@@ -332,14 +332,14 @@ char **read_pullparams(int *ninp_p, t_inpfile **inp_p,
     {
         pcrd = &pull->coord[coordNum - 1];
         sprintf(buf, "pull-coord%d-type", coordNum);
-        pcrd->eType = get_eeenum(ninp_p, inp_p, buf, epull_names, wi);
+        pcrd->eType = get_eeenum(inp, buf, epull_names, wi);
         sprintf(buf, "pull-coord%d-potential-provider", coordNum);
-        setStringEntry(ninp_p, inp_p, buf, provider, "");
+        setStringEntry(inp, buf, provider, "");
         pcrd->externalPotentialProvider = gmx_strdup(provider);
         sprintf(buf, "pull-coord%d-geometry", coordNum);
-        pcrd->eGeom = get_eeenum(ninp_p, inp_p, buf, epullg_names, wi);
+        pcrd->eGeom = get_eeenum(inp, buf, epullg_names, wi);
         sprintf(buf, "pull-coord%d-groups", coordNum);
-        setStringEntry(ninp_p, inp_p, buf, groups, "");
+        setStringEntry(inp, buf, groups, "");
 
         switch (pcrd->eGeom)
         {
@@ -373,21 +373,21 @@ char **read_pullparams(int *ninp_p, t_inpfile **inp_p,
         }
 
         sprintf(buf, "pull-coord%d-dim", coordNum);
-        setStringEntry(ninp_p, inp_p, buf, dim_buf, "Y Y Y");
+        setStringEntry(inp, buf, dim_buf, "Y Y Y");
         sprintf(buf, "pull-coord%d-origin", coordNum);
-        setStringEntry(ninp_p, inp_p, buf, origin_buf, "0.0 0.0 0.0");
+        setStringEntry(inp, buf, origin_buf, "0.0 0.0 0.0");
         sprintf(buf, "pull-coord%d-vec", coordNum);
-        setStringEntry(ninp_p, inp_p, buf, vec_buf, "0.0 0.0 0.0");
+        setStringEntry(inp, buf, vec_buf, "0.0 0.0 0.0");
         sprintf(buf, "pull-coord%d-start", coordNum);
-        pcrd->bStart = get_eeenum(ninp_p, inp_p, buf, yesno_names, wi);
+        pcrd->bStart = get_eeenum(inp, buf, yesno_names, wi);
         sprintf(buf, "pull-coord%d-init", coordNum);
-        pcrd->init = get_ereal(ninp_p, inp_p, buf, 0.0, wi);
+        pcrd->init = get_ereal(inp, buf, 0.0, wi);
         sprintf(buf, "pull-coord%d-rate", coordNum);
-        pcrd->rate = get_ereal(ninp_p, inp_p, buf, 0.0, wi);
+        pcrd->rate = get_ereal(inp, buf, 0.0, wi);
         sprintf(buf, "pull-coord%d-k", coordNum);
-        pcrd->k = get_ereal(ninp_p, inp_p, buf, 0.0, wi);
+        pcrd->k = get_ereal(inp, buf, 0.0, wi);
         sprintf(buf, "pull-coord%d-kB", coordNum);
-        pcrd->kB = get_ereal(ninp_p, inp_p, buf, pcrd->k, wi);
+        pcrd->kB = get_ereal(inp, buf, pcrd->k, wi);
 
         /* Initialize the pull coordinate */
         init_pull_coord(pcrd, coordNum, dim_buf, origin_buf, vec_buf, wi);
index e6d9351e0bc40d4b406bc9b6b2ebec10e9622e9a..70cfc5e4c9c1e8749b2cfb427dbdd5e7de5dbc5b 100644 (file)
@@ -65,23 +65,23 @@ static void string2dvec(char buf[], dvec nums)
 }
 
 
-extern char **read_rotparams(int *ninp_p, t_inpfile **inp_p, t_rot *rot,
+extern char **read_rotparams(std::vector<t_inpfile> *inp, t_rot *rot,
                              warninp_t wi)
 {
-    int         g, m;
-    char      **grpbuf;
-    char        buf[STRLEN];
-    char        warn_buf[STRLEN];
-    dvec        vec;
-    t_rotgrp   *rotg;
+    int                    g, m;
+    char                 **grpbuf;
+    char                   buf[STRLEN];
+    char                   warn_buf[STRLEN];
+    dvec                   vec;
+    t_rotgrp              *rotg;
 
     /* read rotation parameters */
-    printStringNoNewline(ninp_p, inp_p, "Output frequency for angle, torque and rotation potential energy for the whole group");
-    rot->nstrout = get_eint(ninp_p, inp_p, "rot-nstrout", 100, wi);
-    printStringNoNewline(ninp_p, inp_p, "Output frequency for per-slab data (angles, torques and slab centers)");
-    rot->nstsout = get_eint(ninp_p, inp_p, "rot-nstsout", 1000, wi);
-    printStringNoNewline(ninp_p, inp_p, "Number of rotation groups");
-    rot->ngrp = get_eint(ninp_p, inp_p, "rot-ngroups", 1, wi);
+    printStringNoNewline(inp, "Output frequency for angle, torque and rotation potential energy for the whole group");
+    rot->nstrout = get_eint(inp, "rot-nstrout", 100, wi);
+    printStringNoNewline(inp, "Output frequency for per-slab data (angles, torques and slab centers)");
+    rot->nstsout = get_eint(inp, "rot-nstsout", 1000, wi);
+    printStringNoNewline(inp, "Number of rotation groups");
+    rot->ngrp = get_eint(inp, "rot-ngroups", 1, wi);
 
     if (rot->ngrp < 1)
     {
@@ -96,21 +96,21 @@ extern char **read_rotparams(int *ninp_p, t_inpfile **inp_p, t_rot *rot,
     {
         rotg = &rot->grp[g];
         snew(grpbuf[g], STRLEN);
-        printStringNoNewline(ninp_p, inp_p, "Rotation group name");
+        printStringNoNewline(inp, "Rotation group name");
         sprintf(buf, "rot-group%d", g);
-        setStringEntry(ninp_p, inp_p, buf, grpbuf[g], "");
+        setStringEntry(inp, buf, grpbuf[g], "");
 
-        printStringNoNewline(ninp_p, inp_p, "Rotation potential. Can be iso, iso-pf, pm, pm-pf, rm, rm-pf, rm2, rm2-pf, flex, flex-t, flex2, flex2-t");
+        printStringNoNewline(inp, "Rotation potential. Can be iso, iso-pf, pm, pm-pf, rm, rm-pf, rm2, rm2-pf, flex, flex-t, flex2, flex2-t");
         sprintf(buf, "rot-type%d", g);
-        rotg->eType = get_eenum(ninp_p, inp_p, buf, erotg_names);
+        rotg->eType = get_eenum(inp, buf, erotg_names);
 
-        printStringNoNewline(ninp_p, inp_p, "Use mass-weighting of the rotation group positions");
+        printStringNoNewline(inp, "Use mass-weighting of the rotation group positions");
         sprintf(buf, "rot-massw%d", g);
-        rotg->bMassW = get_eenum(ninp_p, inp_p, buf, yesno_names);
+        rotg->bMassW = get_eenum(inp, buf, yesno_names);
 
-        printStringNoNewline(ninp_p, inp_p, "Rotation vector, will get normalized");
+        printStringNoNewline(inp, "Rotation vector, will get normalized");
         sprintf(buf, "rot-vec%d", g);
-        setStringEntry(ninp_p, inp_p, buf, s_vec, "1.0 0.0 0.0");
+        setStringEntry(inp, buf, s_vec, "1.0 0.0 0.0");
         string2dvec(s_vec, vec);
         /* Normalize the rotation vector */
         if (dnorm(vec) != 0)
@@ -129,9 +129,9 @@ extern char **read_rotparams(int *ninp_p, t_inpfile **inp_p, t_rot *rot,
             rotg->vec[m] = vec[m];
         }
 
-        printStringNoNewline(ninp_p, inp_p, "Pivot point for the potentials iso, pm, rm, and rm2 (nm)");
+        printStringNoNewline(inp, "Pivot point for the potentials iso, pm, rm, and rm2 (nm)");
         sprintf(buf, "rot-pivot%d", g);
-        setStringEntry(ninp_p, inp_p, buf, s_vec, "0.0 0.0 0.0");
+        setStringEntry(inp, buf, s_vec, "0.0 0.0 0.0");
         clear_dvec(vec);
         if ( (rotg->eType == erotgISO) || (rotg->eType == erotgPM) || (rotg->eType == erotgRM) || (rotg->eType == erotgRM2) )
         {
@@ -142,59 +142,59 @@ extern char **read_rotparams(int *ninp_p, t_inpfile **inp_p, t_rot *rot,
             rotg->pivot[m] = vec[m];
         }
 
-        printStringNoNewline(ninp_p, inp_p, "Rotation rate (degree/ps) and force constant (kJ/(mol*nm^2))");
+        printStringNoNewline(inp, "Rotation rate (degree/ps) and force constant (kJ/(mol*nm^2))");
         sprintf(buf, "rot-rate%d", g);
-        rotg->rate = get_ereal(ninp_p, inp_p, buf, 0.0, wi);
+        rotg->rate = get_ereal(inp, buf, 0.0, wi);
 
         sprintf(buf, "rot-k%d", g);
-        rotg->k = get_ereal(ninp_p, inp_p, buf, 0.0, wi);
+        rotg->k = get_ereal(inp, buf, 0.0, wi);
         if (rotg->k <= 0.0)
         {
             sprintf(warn_buf, "rot-k%d <= 0", g);
             warning_note(wi, warn_buf);
         }
 
-        printStringNoNewline(ninp_p, inp_p, "Slab distance for flexible axis rotation (nm)");
+        printStringNoNewline(inp, "Slab distance for flexible axis rotation (nm)");
         sprintf(buf, "rot-slab-dist%d", g);
-        rotg->slab_dist = get_ereal(ninp_p, inp_p, buf, 1.5, wi);
+        rotg->slab_dist = get_ereal(inp, buf, 1.5, wi);
         if (rotg->slab_dist <= 0.0)
         {
             sprintf(warn_buf, "rot-slab-dist%d <= 0", g);
             warning_error(wi, warn_buf);
         }
 
-        printStringNoNewline(ninp_p, inp_p, "Minimum value of Gaussian function for the force to be evaluated (for flex* potentials)");
+        printStringNoNewline(inp, "Minimum value of Gaussian function for the force to be evaluated (for flex* potentials)");
         sprintf(buf, "rot-min-gauss%d", g);
-        rotg->min_gaussian = get_ereal(ninp_p, inp_p, buf, 1e-3, wi);
+        rotg->min_gaussian = get_ereal(inp, buf, 1e-3, wi);
         if (rotg->min_gaussian <= 0.0)
         {
             sprintf(warn_buf, "rot-min-gauss%d <= 0", g);
             warning_error(wi, warn_buf);
         }
 
-        printStringNoNewline(ninp_p, inp_p, "Value of additive constant epsilon' (nm^2) for rm2* and flex2* potentials");
+        printStringNoNewline(inp, "Value of additive constant epsilon' (nm^2) for rm2* and flex2* potentials");
         sprintf(buf, "rot-eps%d", g);
-        rotg->eps = get_ereal(ninp_p, inp_p, buf, 1e-4, wi);
+        rotg->eps = get_ereal(inp, buf, 1e-4, wi);
         if ( (rotg->eps <= 0.0) && (rotg->eType == erotgRM2 || rotg->eType == erotgFLEX2) )
         {
             sprintf(warn_buf, "rot-eps%d <= 0", g);
             warning_error(wi, warn_buf);
         }
 
-        printStringNoNewline(ninp_p, inp_p, "Fitting method to determine angle of rotation group (rmsd, norm, or potential)");
+        printStringNoNewline(inp, "Fitting method to determine angle of rotation group (rmsd, norm, or potential)");
         sprintf(buf, "rot-fit-method%d", g);
-        rotg->eFittype = get_eenum(ninp_p, inp_p, buf, erotg_fitnames);
-        printStringNoNewline(ninp_p, inp_p, "For fit type 'potential', nr. of angles around the reference for which the pot. is evaluated");
+        rotg->eFittype = get_eenum(inp, buf, erotg_fitnames);
+        printStringNoNewline(inp, "For fit type 'potential', nr. of angles around the reference for which the pot. is evaluated");
         sprintf(buf, "rot-potfit-nsteps%d", g);
-        rotg->PotAngle_nstep = get_eint(ninp_p, inp_p, buf, 21, wi);
+        rotg->PotAngle_nstep = get_eint(inp, buf, 21, wi);
         if ( (rotg->eFittype == erotgFitPOT) && (rotg->PotAngle_nstep < 1) )
         {
             sprintf(warn_buf, "rot-potfit-nsteps%d < 1", g);
             warning_error(wi, warn_buf);
         }
-        printStringNoNewline(ninp_p, inp_p, "For fit type 'potential', distance in degrees between two consecutive angles");
+        printStringNoNewline(inp, "For fit type 'potential', distance in degrees between two consecutive angles");
         sprintf(buf, "rot-potfit-step%d", g);
-        rotg->PotAngle_step = get_ereal(ninp_p, inp_p, buf, 0.25, wi);
+        rotg->PotAngle_step = get_ereal(inp, buf, 0.25, wi);
     }
 
     return grpbuf;
index 1918e06c3f121c3b13f38d6930e3fe578d4eaad4..5bf972c1ae1e30b6d7131402d15fa1c0c856d0ed 100644 (file)
@@ -215,33 +215,32 @@ static void get_input(const char *membed_input, real *xy_fac, real *xy_max, real
                       int *it_xy, int *it_z, real *probe_rad, int *low_up_rm, int *maxwarn,
                       int *pieces, gmx_bool *bALLOW_ASYMMETRY)
 {
-    warninp_t  wi;
-    t_inpfile *inp;
-    int        ninp;
+    warninp_t               wi;
+    std::vector <t_inpfile> inp;
 
     wi = init_warning(TRUE, 0);
 
     {
         gmx::TextInputFile stream(membed_input);
-        inp = read_inpfile(&stream, membed_input, &ninp, wi);
+        inp = read_inpfile(&stream, membed_input, wi);
         stream.close();
     }
-    *it_xy            = get_eint(&ninp, &inp, "nxy", 1000, wi);
-    *it_z             = get_eint(&ninp, &inp, "nz", 0, wi);
-    *xy_fac           = get_ereal(&ninp, &inp, "xyinit", 0.5, wi);
-    *xy_max           = get_ereal(&ninp, &inp, "xyend", 1.0, wi);
-    *z_fac            = get_ereal(&ninp, &inp, "zinit", 1.0, wi);
-    *z_max            = get_ereal(&ninp, &inp, "zend", 1.0, wi);
-    *probe_rad        = get_ereal(&ninp, &inp, "rad", 0.22, wi);
-    *low_up_rm        = get_eint(&ninp, &inp, "ndiff", 0, wi);
-    *maxwarn          = get_eint(&ninp, &inp, "maxwarn", 0, wi);
-    *pieces           = get_eint(&ninp, &inp, "pieces", 1, wi);
-    *bALLOW_ASYMMETRY = get_eeenum(&ninp, &inp, "asymmetry", yesno_names, wi);
+    *it_xy            = get_eint(&inp, "nxy", 1000, wi);
+    *it_z             = get_eint(&inp, "nz", 0, wi);
+    *xy_fac           = get_ereal(&inp, "xyinit", 0.5, wi);
+    *xy_max           = get_ereal(&inp, "xyend", 1.0, wi);
+    *z_fac            = get_ereal(&inp, "zinit", 1.0, wi);
+    *z_max            = get_ereal(&inp, "zend", 1.0, wi);
+    *probe_rad        = get_ereal(&inp, "rad", 0.22, wi);
+    *low_up_rm        = get_eint(&inp, "ndiff", 0, wi);
+    *maxwarn          = get_eint(&inp, "maxwarn", 0, wi);
+    *pieces           = get_eint(&inp, "pieces", 1, wi);
+    *bALLOW_ASYMMETRY = get_eeenum(&inp, "asymmetry", yesno_names, wi);
 
     check_warning_error(wi, FARGS);
     {
         gmx::TextOutputFile stream(membed_input);
-        write_inpfile(&stream, membed_input, ninp, inp, FALSE, WriteMdpHeader::yes, wi);
+        write_inpfile(&stream, membed_input, &inp, FALSE, WriteMdpHeader::yes, wi);
         stream.close();
     }
     done_warning(wi, FARGS);