A bunch of slightly risky string handling is now safer or simpler.
Refs #2645
Change-Id: I0e02a34ecf7be16135e406ba2aaefab8a6e6ba39
if(CYGWIN)
GMX_TEST_CFLAG(CFLAGS_WARN_SUBSCRIPT "-Wno-char-subscripts" GMXC_CFLAGS)
endif()
+ GMX_TEST_CFLAG(CFLAGS_STRINGOP_TRUNCATION "-Werror=stringop-truncation" GMXC_CFLAGS)
+ GMX_TEST_CFLAG(CFLAGS_FORMAT_OVERFLOW "-Werror=format-overflow" GMXC_CFLAGS)
endif()
# new in gcc 4.5
GMX_TEST_CFLAG(CFLAGS_EXCESS_PREC "-fexcess-precision=fast" GMXC_CFLAGS_RELEASE)
GMX_TEST_CXXFLAG(CXXFLAGS_WARN_UNDEF "-Wundef" GMXC_CXXFLAGS)
endif()
GMX_TEST_CFLAG(CXXFLAGS_WARN_REL "-Wno-array-bounds" GMXC_CXXFLAGS_RELEASE_ONLY)
+ GMX_TEST_CXXFLAG(CXXFLAGS_STRINGOP_TRUNCATION "-Wstringop-truncation" GMXC_CXXFLAGS)
+ if (CXXFLAGS_STRINGOP_TRUNCATION)
+ set(CXXFLAGS_NO_STRINGOP_TRUNCATION "-Wno-stringop-truncation")
+ endif()
+ GMX_TEST_CXXFLAG(CXXFLAGS_FORMAT_OVERFLOW "-Wformat-overflow" GMXC_CXXFLAGS)
endif()
# new in gcc 4.5
GMX_TEST_CXXFLAG(CXXFLAGS_EXCESS_PREC "-fexcess-precision=fast" GMXC_CXXFLAGS_RELEASE)
set_property(GLOBAL PROPERTY GMX_AVX_512_SOURCE)
add_library(libgromacs_external OBJECT "")
+if(CMAKE_COMPILER_IS_GNUCXX)
+ # Keep quiet about e.g. linearalgebra module
+ target_compile_options(libgromacs_external PRIVATE ${CXXFLAGS_NO_STRINGOP_TRUNCATION})
+endif()
+
add_library(libgromacs_generated OBJECT "")
if (BUILD_SHARED_LIBS)
set_target_properties(libgromacs_external PROPERTIES POSITION_INDEPENDENT_CODE true)
#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/smalloc.h"
+#include "gromacs/utility/stringutil.h"
#include "biasparams.h"
#include "biassharing.h"
* \param[in,out] wi Struct for bookeeping warnings.
* \param[in] bComment True if comments should be printed.
*/
-static void readDimParams(std::vector<t_inpfile> *inp, const char *prefix,
+static void readDimParams(std::vector<t_inpfile> *inp, const std::string &prefix,
AwhDimParams *dimParams, const pull_params_t *pull_params,
warninp_t wi, bool bComment)
{
- char warningmsg[STRLEN];
-
+ std::string opt;
if (bComment)
{
printStringNoNewline(inp, "The provider of the reaction coordinate, currently only pull is supported");
}
- char opt[STRLEN];
- sprintf(opt, "%s-coord-provider", prefix);
+
+ opt = prefix + "-coord-provider";
dimParams->eCoordProvider = get_eeenum(inp, opt, eawhcoordprovider_names, wi);
if (bComment)
{
printStringNoNewline(inp, "The coordinate index for this dimension");
}
- sprintf(opt, "%s-coord-index", prefix);
+ opt = prefix + "-coord-index";
int coordIndexInput;
coordIndexInput = get_eint(inp, opt, 1, wi);
if (coordIndexInput < 1)
{
gmx_fatal(FARGS, "Failed to read a valid coordinate index for %s. "
- "Note that the pull coordinate indexing starts at 1.", opt);
+ "Note that the pull coordinate indexing starts at 1.", opt.c_str());
}
/* The pull coordinate indices start at 1 in the input file, at 0 internally */
}
if (pull_params->coord[dimParams->coordIndex].rate != 0)
{
- sprintf(warningmsg, "Setting pull-coord%d-rate (%g) is incompatible with AWH biasing this coordinate", coordIndexInput, pull_params->coord[dimParams->coordIndex].rate);
- warning_error(wi, warningmsg);
+ auto message = formatString("Setting pull-coord%d-rate (%g) is incompatible with AWH biasing this coordinate",
+ coordIndexInput, pull_params->coord[dimParams->coordIndex].rate);
+ warning_error(wi, message);
}
/* Grid params for each axis */
printStringNoNewline(inp, "Start and end values for each coordinate dimension");
}
- sprintf(opt, "%s-start", prefix);
+ opt = prefix + "-start";
dimParams->origin = get_ereal(inp, opt, 0., wi);
- sprintf(opt, "%s-end", prefix);
+ opt = prefix + "-end";
dimParams->end = get_ereal(inp, opt, 0., wi);
if (gmx_within_tol(dimParams->end - dimParams->origin, 0, GMX_REAL_EPS))
{
- sprintf(warningmsg, "The given interval length given by %s-start (%g) and %s-end (%g) is zero. "
- "This will result in only one point along this axis in the coordinate value grid.",
- prefix, dimParams->origin, prefix, dimParams->end);
- warning(wi, warningmsg);
+ auto message = formatString("The given interval length given by %s-start (%g) and %s-end (%g) is zero. "
+ "This will result in only one point along this axis in the coordinate value grid.",
+ prefix.c_str(), dimParams->origin, prefix.c_str(), dimParams->end);
+ warning(wi, message);
}
/* Check that the requested interval is in allowed range */
if (eGeom == epullgDIST)
{
gmx_fatal(FARGS, "%s-start (%g) or %s-end (%g) set to a negative value. With pull geometry distance coordinate values are non-negative. "
"Perhaps you want to use geometry %s instead?",
- prefix, dimParams->origin, prefix, dimParams->end, EPULLGEOM(epullgDIR));
+ prefix.c_str(), dimParams->origin, prefix.c_str(), dimParams->end, EPULLGEOM(epullgDIR));
}
}
else if (eGeom == epullgANGLE || eGeom == epullgANGLEAXIS)
if (dimParams->origin < 0 || dimParams->end > 180)
{
gmx_fatal(FARGS, "%s-start (%g) and %s-end (%g) are outside of the allowed range 0 to 180 deg for pull geometries %s and %s ",
- prefix, dimParams->origin, prefix, dimParams->end, EPULLGEOM(epullgANGLE), EPULLGEOM(epullgANGLEAXIS));
+ prefix.c_str(), dimParams->origin, prefix.c_str(), dimParams->end, EPULLGEOM(epullgANGLE), EPULLGEOM(epullgANGLEAXIS));
}
}
else if (eGeom == epullgDIHEDRAL)
if (dimParams->origin < -180 || dimParams->end > 180)
{
gmx_fatal(FARGS, "%s-start (%g) and %s-end (%g) are outside of the allowed range -180 to 180 deg for pull geometry %s. ",
- prefix, dimParams->origin, prefix, dimParams->end, EPULLGEOM(epullgDIHEDRAL));
+ prefix.c_str(), dimParams->origin, prefix.c_str(), dimParams->end, EPULLGEOM(epullgDIHEDRAL));
}
}
{
printStringNoNewline(inp, "The force constant for this coordinate (kJ/mol/nm^2 or kJ/mol/rad^2)");
}
- sprintf(opt, "%s-force-constant", prefix);
+ opt = prefix + "-force-constant";
dimParams->forceConstant = get_ereal(inp, opt, 0, wi);
if (dimParams->forceConstant <= 0)
{
{
printStringNoNewline(inp, "Estimated diffusion constant (nm^2/ps or rad^2/ps)");
}
- sprintf(opt, "%s-diffusion", prefix);
+ opt = prefix + "-diffusion";
dimParams->diffusion = get_ereal(inp, opt, 0, wi);
if (dimParams->diffusion <= 0)
{
const double diffusion_default = 1e-5;
- sprintf(warningmsg, "%s not explicitly set by user."
- " You can choose to use a default value (%g nm^2/ps or rad^2/ps) but this may very well be non-optimal for your system!",
- opt, diffusion_default);
- warning(wi, warningmsg);
+ auto message = formatString
+ ("%s not explicitly set by user. You can choose to use a default "
+ "value (%g nm^2/ps or rad^2/ps) but this may very well be "
+ "non-optimal for your system!", opt.c_str(), diffusion_default);
+ warning(wi, message);
dimParams->diffusion = diffusion_default;
}
{
printStringNoNewline(inp, "Diameter that needs to be sampled around a point before it is considered covered.");
}
- sprintf(opt, "%s-cover-diameter", prefix);
+ opt = prefix + "-cover-diameter";
dimParams->coverDiameter = get_ereal(inp, opt, 0, wi);
if (dimParams->coverDiameter < 0)
{
gmx_fatal(FARGS, "%s (%g) cannot be negative.",
- opt, dimParams->coverDiameter);
+ opt.c_str(), dimParams->coverDiameter);
}
}
* \param[in,out] wi Struct for bookeeping warnings.
* \param[in] bComment True if comments should be printed.
*/
-static void read_bias_params(std::vector<t_inpfile> *inp, AwhBiasParams *awhBiasParams, const char *prefix,
+static void read_bias_params(std::vector<t_inpfile> *inp, AwhBiasParams *awhBiasParams, const std::string &prefix,
const t_inputrec *ir, warninp_t wi, bool bComment)
{
- char opt[STRLEN], prefixdim[STRLEN];
- char warningmsg[STRLEN];
-
if (bComment)
{
printStringNoNewline(inp, "Estimated initial PMF error (kJ/mol)");
}
- sprintf(opt, "%s-error-init", prefix);
+ std::string opt = prefix + "-error-init";
/* We allow using a default value here without warning (but warn the user if the diffusion constant is not set). */
awhBiasParams->errorInitial = get_ereal(inp, opt, 10, wi);
if (awhBiasParams->errorInitial <= 0)
{
- gmx_fatal(FARGS, "%s needs to be > 0.", opt);
+ gmx_fatal(FARGS, "%s needs to be > 0.", opt.c_str());
}
if (bComment)
{
printStringNoNewline(inp, "Growth rate of the reference histogram determining the bias update size: exp-linear or linear");
}
- sprintf(opt, "%s-growth", prefix);
+ opt = prefix + "-growth";
awhBiasParams->eGrowth = get_eeenum(inp, opt, eawhgrowth_names, wi);
if (bComment)
{
printStringNoNewline(inp, "Start the simulation by equilibrating histogram towards the target distribution: no or yes");
}
- sprintf(opt, "%s-equilibrate-histogram", prefix);
+ opt = prefix + "-equilibrate-histogram";
awhBiasParams->equilibrateHistogram = (get_eeenum(inp, opt, yesno_names, wi) != 0);
if (awhBiasParams->equilibrateHistogram && awhBiasParams->eGrowth != eawhgrowthEXP_LINEAR)
{
- sprintf(warningmsg, "Option %s will only have an effect for histogram growth type '%s'.",
- opt, EAWHGROWTH(eawhgrowthEXP_LINEAR));
- warning(wi, warningmsg);
+ auto message = formatString("Option %s will only have an effect for histogram growth type '%s'.",
+ opt.c_str(), EAWHGROWTH(eawhgrowthEXP_LINEAR));
+ warning(wi, message);
}
if (bComment)
{
printStringNoNewline(inp, "Target distribution type: constant, cutoff, boltzmann or local-boltzmann");
}
- sprintf(opt, "%s-target", prefix);
+ opt = prefix + "-target";
awhBiasParams->eTarget = get_eeenum(inp, opt, eawhtarget_names, wi);
if ((awhBiasParams->eTarget == eawhtargetLOCALBOLTZMANN) &&
(awhBiasParams->eGrowth == eawhgrowthEXP_LINEAR))
{
- sprintf(warningmsg, "Target type '%s' combined with histogram growth type '%s' is not "
- "expected to give stable bias updates. You probably want to use growth type "
- "'%s' instead.",
- EAWHTARGET(eawhtargetLOCALBOLTZMANN), EAWHGROWTH(eawhgrowthEXP_LINEAR),
- EAWHGROWTH(eawhgrowthLINEAR));
- warning(wi, warningmsg);
+ auto message = formatString("Target type '%s' combined with histogram growth type '%s' is not "
+ "expected to give stable bias updates. You probably want to use growth type "
+ "'%s' instead.",
+ EAWHTARGET(eawhtargetLOCALBOLTZMANN), EAWHGROWTH(eawhgrowthEXP_LINEAR),
+ EAWHGROWTH(eawhgrowthLINEAR));
+ warning(wi, message);
}
if (bComment)
{
printStringNoNewline(inp, "Boltzmann beta scaling factor for target distribution types 'boltzmann' and 'boltzmann-local'");
}
- sprintf(opt, "%s-target-beta-scaling", prefix);
+ opt = prefix + "-target-beta-scaling";
awhBiasParams->targetBetaScaling = get_ereal(inp, opt, 0, wi);
switch (awhBiasParams->eTarget)
if (awhBiasParams->targetBetaScaling < 0 || awhBiasParams->targetBetaScaling > 1)
{
gmx_fatal(FARGS, "%s = %g is not useful for target type %s.",
- opt, awhBiasParams->targetBetaScaling, EAWHTARGET(awhBiasParams->eTarget));
+ opt.c_str(), awhBiasParams->targetBetaScaling, EAWHTARGET(awhBiasParams->eTarget));
}
break;
default:
if (awhBiasParams->targetBetaScaling != 0)
{
gmx_fatal(FARGS, "Value for %s (%g) set explicitly but will not be used for target type %s.",
- opt, awhBiasParams->targetBetaScaling, EAWHTARGET(awhBiasParams->eTarget));
+ opt.c_str(), awhBiasParams->targetBetaScaling, EAWHTARGET(awhBiasParams->eTarget));
}
break;
}
{
printStringNoNewline(inp, "Free energy cutoff value for target distribution type 'cutoff'");
}
- sprintf(opt, "%s-target-cutoff", prefix);
+ opt = prefix + "-target-cutoff";
awhBiasParams->targetCutoff = get_ereal(inp, opt, 0, wi);
switch (awhBiasParams->eTarget)
if (awhBiasParams->targetCutoff <= 0)
{
gmx_fatal(FARGS, "%s = %g is not useful for target type %s.",
- opt, awhBiasParams->targetCutoff, EAWHTARGET(awhBiasParams->eTarget));
+ opt.c_str(), awhBiasParams->targetCutoff, EAWHTARGET(awhBiasParams->eTarget));
}
break;
default:
if (awhBiasParams->targetCutoff != 0)
{
gmx_fatal(FARGS, "Value for %s (%g) set explicitly but will not be used for target type %s.",
- opt, awhBiasParams->targetCutoff, EAWHTARGET(awhBiasParams->eTarget));
+ opt.c_str(), awhBiasParams->targetCutoff, EAWHTARGET(awhBiasParams->eTarget));
}
break;
}
{
printStringNoNewline(inp, "Initialize PMF and target with user data: no or yes");
}
- sprintf(opt, "%s-user-data", prefix);
+ opt = prefix + "-user-data";
awhBiasParams->bUserData = get_eeenum(inp, opt, yesno_names, wi);
if (bComment)
{
printStringNoNewline(inp, "Group index to share the bias with, 0 means not shared");
}
- sprintf(opt, "%s-share-group", prefix);
+ opt = prefix + "-share-group";
awhBiasParams->shareGroup = get_eint(inp, opt, 0, wi);
if (awhBiasParams->shareGroup < 0)
{
{
printStringNoNewline(inp, "Dimensionality of the coordinate");
}
- sprintf(opt, "%s-ndim", prefix);
+ opt = prefix + "-ndim";
awhBiasParams->ndim = get_eint(inp, opt, 0, wi);
if (awhBiasParams->ndim <= 0 ||
awhBiasParams->ndim > c_biasMaxNumDim)
{
- gmx_fatal(FARGS, "%s-ndim (%d) needs to be > 0 and at most %d\n", prefix, awhBiasParams->ndim, c_biasMaxNumDim);
+ gmx_fatal(FARGS, "%s (%d) needs to be > 0 and at most %d\n", opt.c_str(), awhBiasParams->ndim, c_biasMaxNumDim);
}
if (awhBiasParams->ndim > 2)
{
for (int d = 0; d < awhBiasParams->ndim; d++)
{
bComment = bComment && d == 0;
- sprintf(prefixdim, "%s-dim%d", prefix, d + 1);
+ std::string prefixdim = prefix + formatString("-dim%d", d + 1);
readDimParams(inp, prefixdim, &awhBiasParams->dimParams[d], ir->pull, wi, bComment);
}
AwhParams *readAndCheckAwhParams(std::vector<t_inpfile> *inp, const t_inputrec *ir, warninp_t wi)
{
- char opt[STRLEN], prefix[STRLEN], prefixawh[STRLEN];
-
- AwhParams *awhParams;
+ AwhParams *awhParams;
snew(awhParams, 1);
-
- sprintf(prefix, "%s", "awh");
+ std::string opt;
/* Parameters common for all biases */
printStringNoNewline(inp, "The way to apply the biasing potential: convolved or umbrella");
- sprintf(opt, "%s-potential", prefix);
+ opt = "awh-potential";
awhParams->ePotential = get_eeenum(inp, opt, eawhpotential_names, wi);
printStringNoNewline(inp, "The random seed used for sampling the umbrella center in the case of umbrella type potential");
- sprintf(opt, "%s-seed", prefix);
+ opt = "awh-seed";
awhParams->seed = get_eint(inp, opt, -1, wi);
if (awhParams->seed == -1)
{
}
printStringNoNewline(inp, "Data output interval in number of steps");
- sprintf(opt, "%s-nstout", prefix);
+ opt = "awh-nstout";
awhParams->nstOut = get_eint(inp, opt, 100000, wi);
if (awhParams->nstOut <= 0)
{
- char buf[STRLEN];
- sprintf(buf, "Not writing AWH output with AWH (%s = %d) does not make sense",
- opt, awhParams->nstOut);
- warning_error(wi, buf);
+ auto message = formatString("Not writing AWH output with AWH (%s = %d) does not make sense",
+ opt.c_str(), awhParams->nstOut);
+ warning_error(wi, message);
}
/* This restriction can be removed by changing a flag of print_ebin() */
if (ir->nstenergy == 0 || awhParams->nstOut % ir->nstenergy != 0)
{
- char buf[STRLEN];
- sprintf(buf, "%s (%d) should be a multiple of nstenergy (%d)",
- opt, awhParams->nstOut, ir->nstenergy);
- warning_error(wi, buf);
+ auto message = formatString("%s (%d) should be a multiple of nstenergy (%d)",
+ opt.c_str(), awhParams->nstOut, ir->nstenergy);
+ warning_error(wi, message);
}
printStringNoNewline(inp, "Coordinate sampling interval in number of steps");
- sprintf(opt, "%s-nstsample", prefix);
+ opt = "awh-nstsample";
awhParams->nstSampleCoord = get_eint(inp, opt, 10, wi);
printStringNoNewline(inp, "Free energy and bias update interval in number of samples");
- sprintf(opt, "%s-nsamples-update", prefix);
+ opt = "awh-nsamples-update";
awhParams->numSamplesUpdateFreeEnergy = get_eint(inp, opt, 10, wi);
if (awhParams->numSamplesUpdateFreeEnergy <= 0)
{
- char buf[STRLEN];
- sprintf(buf, "%s needs to be an integer > 0", opt);
- warning_error(wi, buf);
+ warning_error(wi, opt + " needs to be an integer > 0");
}
printStringNoNewline(inp, "When true, biases with share-group>0 are shared between multiple simulations");
- sprintf(opt, "%s-share-multisim", prefix);
+ opt = "awh-share-multisim";
awhParams->shareBiasMultisim = (get_eeenum(inp, opt, yesno_names, wi) != 0);
printStringNoNewline(inp, "The number of independent AWH biases");
- sprintf(opt, "%s-nbias", prefix);
+ opt = "awh-nbias";
awhParams->numBias = get_eint(inp, opt, 1, wi);
if (awhParams->numBias <= 0)
{
- gmx_fatal(FARGS, "%s needs to be an integer > 0", opt);
+ gmx_fatal(FARGS, "%s needs to be an integer > 0", opt.c_str());
}
/* Read the parameters specific to each AWH bias */
for (int k = 0; k < awhParams->numBias; k++)
{
- bool bComment = (k == 0);
- sprintf(prefixawh, "%s%d", prefix, k + 1);
+ bool bComment = (k == 0);
+ std::string prefixawh = formatString("awh%d", k + 1);
read_bias_params(inp, &awhParams->awhBiasParams[k], prefixawh, ir, wi, bComment);
}
/* Warn if the pull initial coordinate value is not in the grid */
if (!valueIsInInterval(origin, end, period, coordValueInit))
{
- char warningmsg[STRLEN];
- sprintf(warningmsg, "The initial coordinate value (%.8g) for pull coordinate index %d falls outside "
+ auto message = formatString
+ ("The initial coordinate value (%.8g) for pull coordinate index %d falls outside "
"of the sampling nterval awh%d-dim%d-start (%.8g) to awh%d-dim%d-end (%.8g). "
"This can lead to large initial forces pulling the coordinate towards the sampling interval.",
- coordValueInit, coordIndex + 1,
- k + 1, d + 1, origin, k + 1, d + 1, end);
- warning(wi, warningmsg);
+ coordValueInit, coordIndex + 1, k + 1, d + 1, origin, k + 1, d + 1, end);
+ warning(wi, message);
}
}
}
/* Adds 'buf' to 'str' */
-static void add_to_string(char **str, char *buf)
+static void add_to_string(char **str, const char *buf)
{
int len;
}
-static void add_to_string_aligned(char **str, char *buf)
+static void add_to_string_aligned(char **str, const char *buf)
{
char buf_aligned[STRLEN];
static void nice_legend(const char ***setname, int *nsets, char **LegendStr, const char *value, const char *unit, char EDgroupchar)
{
- char tmp[STRLEN], tmp2[STRLEN];
-
-
- sprintf(tmp, "%c %s", EDgroupchar, value);
- add_to_string_aligned(LegendStr, tmp);
- sprintf(tmp2, "%s (%s)", tmp, unit);
- (*setname)[*nsets] = gmx_strdup(tmp2);
+ auto tmp = gmx::formatString("%c %s", EDgroupchar, value);
+ add_to_string_aligned(LegendStr, tmp.c_str());
+ tmp += gmx::formatString(" (%s)", unit);
+ (*setname)[*nsets] = gmx_strdup(tmp.c_str());
(*nsets)++;
}
#include "gromacs/utility/gmxassert.h"
#include "gromacs/utility/logger.h"
#include "gromacs/utility/smalloc.h"
+#include "gromacs/utility/strconvert.h"
#include "pme-internal.h"
const pme_setup_t *set,
double cycles)
{
- char buf[STRLEN], buft[STRLEN];
-
+ auto buf = gmx::formatString("%-11s%10s pme grid %d %d %d, coulomb cutoff %.3f",
+ pre, desc,
+ set->grid[XX], set->grid[YY], set->grid[ZZ], set->rcut_coulomb);
if (cycles >= 0)
{
- sprintf(buft, ": %.1f M-cycles", cycles*1e-6);
+ buf += gmx::formatString(": %.1f M-cycles", cycles*1e-6);
}
- else
- {
- buft[0] = '\0';
- }
- sprintf(buf, "%-11s%10s pme grid %d %d %d, coulomb cutoff %.3f%s",
- pre,
- desc, set->grid[XX], set->grid[YY], set->grid[ZZ], set->rcut_coulomb,
- buft);
if (fp_err != nullptr)
{
- fprintf(fp_err, "\r%s\n", buf);
+ fprintf(fp_err, "\r%s\n", buf.c_str());
fflush(fp_err);
}
if (fp_log != nullptr)
{
- fprintf(fp_log, "%s\n", buf);
+ fprintf(fp_log, "%s\n", buf.c_str());
}
}
int64_t step,
pme_load_balancing_t *pme_lb)
{
- char buf[STRLEN], sbuf[22];
-
- sprintf(buf, "step %4s: the %s limits the PME load balancing to a coulomb cut-off of %.3f",
- gmx_step_str(step, sbuf),
- pmelblim_str[pme_lb->elimited],
- pme_lb->setup[pme_loadbal_end(pme_lb)-1].rcut_coulomb);
+ auto buf = gmx::formatString("step %4s: the %s limits the PME load balancing to a coulomb cut-off of %.3f",
+ gmx::int64ToString(step).c_str(),
+ pmelblim_str[pme_lb->elimited],
+ pme_lb->setup[pme_loadbal_end(pme_lb)-1].rcut_coulomb);
if (fp_err != nullptr)
{
- fprintf(fp_err, "\r%s\n", buf);
+ fprintf(fp_err, "\r%s\n", buf.c_str());
fflush(fp_err);
}
if (fp_log != nullptr)
{
- fprintf(fp_log, "%s\n", buf);
+ fprintf(fp_log, "%s\n", buf.c_str());
}
}
snew(fntemp, std::strlen(fn));
std::strcpy(fntemp, fn);
#endif
- char timebuf[STRLEN];
- gmx_format_current_time(timebuf, STRLEN);
+ std::string timebuf = gmx_format_current_time();
if (fplog)
{
fprintf(fplog, "Writing checkpoint, step %s at %s\n\n",
- gmx_step_str(step, buf), timebuf);
+ gmx_step_str(step, buf), timebuf.c_str());
}
/* Get offsets for open files */
};
std::strcpy(headerContents.version, gmx_version());
std::strcpy(headerContents.fprog, gmx::getProgramContext().fullBinaryPath());
- std::strcpy(headerContents.ftime, timebuf);
+ std::strcpy(headerContents.ftime, timebuf.c_str());
if (DOMAINDECOMP(cr))
{
copy_ivec(domdecCells, headerContents.dd_nc);
if (filename == nullptr ||
!gmx_fexist(filename) ||
- (!(fp = gmx_fio_open(filename, "r"))))
+ ((fp = gmx_fio_open(filename, "r")) == nullptr))
{
*simulation_part = 0;
*step = 0;
int nx, const int index[],
const rvec *x, const rvec *v, const matrix box)
{
- char resnm[6], nm[6];
int ai, i, resind, resnr;
fprintf(out, "%s\n", (title && title[0]) ? title : gmx::bromacs().c_str());
ai = index[i];
resind = atoms->atom[ai].resind;
- std::strncpy(resnm, " ??? ", sizeof(resnm)-1);
+ std::string resnm;
if (resind < atoms->nres)
{
- std::strncpy(resnm, *atoms->resinfo[resind].name, sizeof(resnm)-1);
+ resnm = *atoms->resinfo[resind].name;
resnr = atoms->resinfo[resind].nr;
}
else
{
- std::strncpy(resnm, " ??? ", sizeof(resnm)-1);
+ resnm = " ??? ";
resnr = resind + 1;
}
+ std::string nm;
if (atoms->atom)
{
- std::strncpy(nm, *atoms->atomname[ai], sizeof(nm)-1);
+ nm = *atoms->atomname[i];
}
else
{
- std::strncpy(nm, " ??? ", sizeof(nm)-1);
+ nm = " ??? ";
}
- fprintf(out, "%5d%-5.5s%5.5s%5d", resnr%100000, resnm, nm, (ai+1)%100000);
+ fprintf(out, "%5d%-5.5s%5.5s%5d", resnr%100000, resnm.c_str(), nm.c_str(), (ai+1)%100000);
/* next fprintf uses built format string */
if (v)
{
}
}
-static void xlate_atomname_gmx2pdb(char *name)
+// Deliberately taking a copy of name to return it later
+static std::string xlate_atomname_gmx2pdb(std::string name)
{
- int i, length;
- char temp;
-
- length = std::strlen(name);
+ size_t length = name.size();
if (length > 3 && std::isdigit(name[length-1]))
{
- temp = name[length-1];
- for (i = length-1; i > 0; --i)
+ char temp = name[length-1];
+ for (size_t i = length-1; i > 0; --i)
{
name[i] = name[i-1];
}
name[0] = temp;
}
+ return name;
}
bool usePqrFormat)
{
gmx_conect_t *gc = static_cast<gmx_conect_t *>(conect);
- char resnm[6], nm[6];
int i, ii;
int resind, resnr;
enum PDB_record type;
lastchainnum = chainnum;
}
- strncpy(resnm, *atoms->resinfo[resind].name, sizeof(resnm)-1);
- resnm[sizeof(resnm)-1] = 0;
- strncpy(nm, *atoms->atomname[i], sizeof(nm)-1);
- nm[sizeof(nm)-1] = 0;
+ std::string resnm = *atoms->resinfo[resind].name;
+ std::string nm = *atoms->atomname[i];
/* rename HG12 to 2HG1, etc. */
- xlate_atomname_gmx2pdb(nm);
+ nm = xlate_atomname_gmx2pdb(nm);
resnr = atoms->resinfo[resind].nr;
resic = atoms->resinfo[resind].ic;
if (chainid != ' ')
gmx_fprintf_pdb_atomline(out,
type,
i+1,
- nm,
+ nm.c_str(),
altloc,
- resnm,
+ resnm.c_str(),
ch,
resnr,
resic,
if (atoms->pdbinfo && atoms->pdbinfo[i].bAnisotropic)
{
fprintf(out, "ANISOU%5d %-4.4s%4.4s%c%4d%c %7d%7d%7d%7d%7d%7d\n",
- (i+1)%100000, nm, resnm, ch, resnr,
+ (i+1)%100000, nm.c_str(), resnm.c_str(), ch, resnr,
(resic == '\0') ? ' ' : resic,
atoms->pdbinfo[i].uij[0], atoms->pdbinfo[i].uij[1],
atoms->pdbinfo[i].uij[2], atoms->pdbinfo[i].uij[3],
gmx_fprintf_pqr_atomline(out,
type,
i+1,
- nm,
- resnm,
+ nm.c_str(),
+ resnm.c_str(),
ch,
resnr,
10*x[i][XX], 10*x[i][YY], 10*x[i][ZZ],
static void gmx_conect_addline(gmx_conect_t *con, char *line)
{
- int n, ai, aj;
- char format[32], form2[32];
+ int n, ai, aj;
- sprintf(form2, "%%*s");
- sprintf(format, "%s%%d", form2);
- if (sscanf(line, format, &ai) == 1)
+ std::string form2 = "%%*s";
+ std::string format = form2 + "%%d";
+ if (sscanf(line, format.c_str(), &ai) == 1)
{
do
{
- std::strcat(form2, "%*s");
- sprintf(format, "%s%%d", form2);
- n = sscanf(line, format, &aj);
+ form2 += "%*s";
+ format = form2 + "%%d";
+ n = sscanf(line, format.c_str(), &aj);
if (n == 1)
{
srenew(con->conect, ++con->nconect);
}
}
+int get_eint(std::vector<t_inpfile> *inp, const std::string &name, int def,
+ warninp_t wi)
+{
+ return get_eint(inp, name.c_str(), def, wi);
+}
+
/* Note that sanitizing the trailing part of inp[ii].value was the responsibility of read_inpfile() */
int64_t get_eint64(std::vector<t_inpfile> *inp,
const char *name, int64_t def,
}
}
+int64_t get_eint64(std::vector<t_inpfile> *inp,
+ const std::string &name, int64_t def,
+ warninp_t wi)
+{
+ return get_eint64(inp, name.c_str(), def, wi);
+}
+
/* 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)
}
}
+double get_ereal(std::vector<t_inpfile> *inp, const std::string &name, double def,
+ warninp_t wi)
+{
+ return get_ereal(inp, name.c_str(), def, wi);
+}
+
/* 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)
{
}
}
+const char *get_estr(std::vector<t_inpfile> *inp, const std::string &name, const char *def)
+{
+ return get_estr(inp, name.c_str(), def);
+}
+
/* 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)
return i;
}
+int get_eeenum(std::vector<t_inpfile> *inp, const std::string &name, const char **defs,
+ warninp_t wi)
+{
+ return get_eeenum(inp, name.c_str(), defs, wi);
+}
+
int get_eenum(std::vector<t_inpfile> *inp, const char *name, const char **defs)
{
return get_eeenum(inp, name, defs, nullptr);
int get_eint(std::vector<t_inpfile> *inp, const char *name, int def,
warninp_t wi);
+int get_eint(std::vector<t_inpfile> *inp, const std::string &name, int def,
+ warninp_t wi);
int64_t get_eint64(std::vector<t_inpfile> *inp,
const char *name, int64_t def,
- warninp_t /*wi*/);
+ warninp_t wi);
+int64_t get_eint64(std::vector<t_inpfile> *inp,
+ const std::string &name, int64_t def,
+ warninp_t wi);
double get_ereal(std::vector<t_inpfile> *inp, const char *name, double def,
warninp_t wi);
+double get_ereal(std::vector<t_inpfile> *inp, const std::string &name, double def,
+ warninp_t wi);
const char *get_estr(std::vector<t_inpfile> *inp, const char *name, const char *def);
+const char *get_estr(std::vector<t_inpfile> *inp, const std::string &name, const char *def);
int get_eeenum(std::vector<t_inpfile> *inp, const char *name, const char **defs,
warninp_t wi);
/* defs must be NULL terminated */
+int get_eeenum(std::vector<t_inpfile> *inp, const std::string &name, const char **defs,
+ warninp_t wi);
+/* defs must be NULL terminated */
int get_eenum(std::vector<t_inpfile> *inp, const char *name, const char **defs);
/* defs must be NULL terminated */
check_warning_error_impl(wi, f_errno, file, line);
}
+void warning_error_and_exit(warninp_t wi, const std::string &s, int f_errno, const char *file, int line)
+{
+ warning_error_and_exit(wi, s.c_str(), f_errno, file, line);
+}
+
gmx_bool warning_errors_exist(warninp_t wi)
{
return (wi->nwarn_error > 0);
* This is intended for use where there is no way to produce a data
* structure that would prevent execution from segfaulting. */
[[noreturn]] void warning_error_and_exit(warninp_t wi, const char *s, int f_errno, const char *file, int line);
+//! \copydoc warning_error_and_exit(warninp_t, const char *, int, const char *, int);
+[[noreturn]] void warning_error_and_exit(warninp_t wi, const std::string &s, int f_errno, const char *file, int line);
gmx_bool warning_errors_exist(warninp_t wi);
/* Return whether any error-level warnings were issued to wi. */
if (output_env_get_print_xvgr_codes(oenv))
{
- gmx_format_current_time(buf, STRLEN);
- fprintf(fp, "# This file was created %s", buf);
+ fprintf(fp, "# This file was created %s", gmx_format_current_time().c_str());
try
{
gmx::BinaryInformationSettings settings;
#include <cstdlib>
#include <cstring>
+#include <string>
+
#include "gromacs/commandline/pargs.h"
#include "gromacs/fileio/confio.h"
#include "gromacs/fileio/xvgr.h"
#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/futil.h"
+#include "gromacs/utility/path.h"
#include "gromacs/utility/pleasecite.h"
#include "gromacs/utility/smalloc.h"
return pdbf;
}
-static t_pdbfile **read_em_all(const char *fn, int *npdbf)
+static t_pdbfile **read_em_all(const std::string &fn, int *npdbf)
{
t_pdbfile **pdbf = nullptr;
int i, maxpdbf;
- char buf[256], name[256];
gmx_bool bExist;
- std::strcpy(buf, fn);
- buf[std::strlen(buf)-4] = '\0';
maxpdbf = 100;
snew(pdbf, maxpdbf);
i = 0;
do
{
- sprintf(name, "%s_%d.pdb", buf, i+1);
- if ((bExist = gmx_fexist(name)))
+ auto newFilename = gmx::Path::concatenateBeforeExtension(fn, gmx::formatString("_%d", i+1));
+ if ((bExist = gmx_fexist(newFilename)))
{
- pdbf[i] = read_pdbf(name);
+ pdbf[i] = read_pdbf(newFilename.c_str());
pdbf[i]->index = i+1;
i++;
if (i >= maxpdbf)
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/futil.h"
#include "gromacs/utility/smalloc.h"
+#include "gromacs/utility/stringutil.h"
static gmx_bool bAllowed(real phi, real psi)
{
int ***his_aa, *histmp;
int i, j, k, m, n, nn, Dih, nres, hindex, angle;
gmx_bool bBfac, bOccup;
- char hisfile[256], hhisfile[256], sshisfile[256], title[256], *ss_str = nullptr;
+ char hisfile[256], hhisfile[256], title[256], *ss_str = nullptr;
char **leg;
const char *residue_name;
int rt_size;
{
for (k = 0; (k < 3); k++)
{
- sprintf(sshisfile, "%s-%s.xvg", hisfile, sss[k]);
+ std::string sshisfile = gmx::formatString("%s-%s.xvg", hisfile, sss[k]);
ssfp[k] = gmx_ffopen(sshisfile, "w");
}
}
int d, dj, nfit;
int *index, *ifit;
gmx_bool bDiffMass1, bDiffMass2;
- char timebuf[STRLEN];
t_rgb rlo, rmi, rhi;
real *eigenvectors;
gmx_output_env_t *oenv;
out = gmx_ffopen(logfile, "w");
- gmx_format_current_time(timebuf, STRLEN);
- fprintf(out, "Covariance analysis log, written %s\n", timebuf);
+ fprintf(out, "Covariance analysis log, written %s\n", gmx_format_current_time().c_str());
fprintf(out, "Program: %s\n", argv[0]);
gmx_getcwd(str, STRLEN);
int nr; /* number of atomstypes to read */
int i;
- if (!(in = gmx_ffopen(fn, "r")))
+ if ((in = gmx_ffopen(fn, "r")) == nullptr)
{
gmx_fatal(FARGS, "Couldn't open %s. Exiting.\n", fn);
}
yticks[j] += bw;
}
- xpmfile1 = gmx_ffopen(outfiles[0].c_str(), "w");
- xpmfile2 = gmx_ffopen(outfiles[1].c_str(), "w");
+ xpmfile1 = gmx_ffopen(outfiles[0], "w");
+ xpmfile2 = gmx_ffopen(outfiles[1], "w");
max1 = max2 = 0.0;
min1 = min2 = zbins*bwz;
FILE *raw1, *raw2;
int i, j, n;
- raw1 = gmx_ffopen(fnms[0].c_str(), "w");
- raw2 = gmx_ffopen(fnms[1].c_str(), "w");
+ raw1 = gmx_ffopen(fnms[0], "w");
+ raw2 = gmx_ffopen(fnms[1], "w");
try
{
gmx::BinaryInformationSettings settings;
yticks[j] += bw;
}
- xpmfile1 = gmx_ffopen(outfiles[0].c_str(), "w");
- xpmfile2 = gmx_ffopen(outfiles[1].c_str(), "w");
+ xpmfile1 = gmx_ffopen(outfiles[0], "w");
+ xpmfile2 = gmx_ffopen(outfiles[1], "w");
max1 = max2 = 0.0;
min1 = min2 = 1000.00;
FILE *raw1, *raw2;
int i, j, n;
- raw1 = gmx_ffopen(fnms[0].c_str(), "w");
- raw2 = gmx_ffopen(fnms[1].c_str(), "w");
+ raw1 = gmx_ffopen(fnms[0], "w");
+ raw2 = gmx_ffopen(fnms[1], "w");
fprintf(raw1, "#Legend\n#TBlock\n#Xbin Ybin Z t\n");
fprintf(raw2, "#Legend\n#TBlock\n#Xbin Ybin Z t\n");
for (n = 0; n < tblocks; n++)
static char **atnames, *ostring;
static gmx_bool bFirst = TRUE;
char inp_string[STRLEN], *string;
- char gname[STRLEN], gname1[STRLEN], gname2[STRLEN];
+ char gname[STRLEN*3], gname1[STRLEN], gname2[STRLEN];
int i, i0, i1, sel_nr, sel_nr2, newgroup;
int nr, nr1, nr2, *index, *index1, *index2;
gmx_bool bAnd, bOr, bPrintOnce;
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/futil.h"
#include "gromacs/utility/smalloc.h"
+#include "gromacs/utility/stringutil.h"
static void low_print_data(FILE *fp, real time, rvec x[], int n, const int *index,
const gmx_bool bDim[], const char *sffmt)
t_block *mols;
gmx_bool bTop, bOX, bOXT, bOV, bOF, bOB, bOT, bEKT, bEKR, bCV, bCF;
gmx_bool bDim[4], bDum[4], bVD;
- char sffmt[STRLEN], sffmt6[STRLEN];
+ char sffmt[STRLEN];
const char *box_leg[6] = { "XX", "YY", "ZZ", "YX", "ZX", "ZY" };
gmx_output_env_t *oenv;
{
sprintf(sffmt, "\t%%g");
}
- sprintf(sffmt6, "%s%s%s%s%s%s", sffmt, sffmt, sffmt, sffmt, sffmt, sffmt);
+ std::string sffmt6 = gmx::formatString("%s%s%s%s%s%s", sffmt, sffmt, sffmt, sffmt, sffmt, sffmt);
bTop = read_tps_conf(ftp2fn(efTPS, NFILE, fnm), &top, &ePBC,
&xtop, nullptr, topbox,
if (bOB && fr.bBox)
{
fprintf(outb, "\t%g", fr.time);
- fprintf(outb, sffmt6,
+ fprintf(outb, sffmt6.c_str(),
fr.box[XX][XX], fr.box[YY][YY], fr.box[ZZ][ZZ],
fr.box[YY][XX], fr.box[ZZ][XX], fr.box[ZZ][YY]);
fprintf(outb, "\n");
char out_file2[256], *charpt;
char *outf_base = nullptr;
const char *outf_ext = nullptr;
- char top_title[256], title[256], timestr[32], stepstr[32], filemode[5];
+ char top_title[256], timestr[32], stepstr[32], filemode[5];
gmx_output_env_t *oenv;
t_filenm fnm[] = {
mk_filenm(outf_base, ftp2ext(ftp), nzero, file_nr, out_file2);
}
+ std::string title;
switch (ftp)
{
case efTNG:
{
std::strcpy(stepstr, "");
}
- snprintf(title, 256, "%s%s%s", top_title, timestr, stepstr);
+ title = gmx::formatString("%s%s%s", top_title, timestr, stepstr);
if (bSeparate || bSplitHere)
{
out = gmx_ffopen(out_file2, "w");
switch (ftp)
{
case efGRO:
- write_hconf_p(out, title, &useatoms,
+ write_hconf_p(out, title.c_str(), &useatoms,
frout.x, frout.bV ? frout.v : nullptr, frout.box);
break;
case efPDB:
{
model_nr++;
}
- write_pdbfile(out, title, &useatoms, frout.x,
+ write_pdbfile(out, title.c_str(), &useatoms, frout.x,
frout.ePBC, frout.box, ' ', model_nr, gc, TRUE);
break;
case efG96:
const char *outputTitle = "";
if (bSeparate || bTDump)
{
- outputTitle = title;
+ outputTitle = title.c_str();
if (bTPS)
{
frout.bAtoms = TRUE;
{
if (outframe == 0)
{
- outputTitle = title;
+ outputTitle = title.c_str();
}
frout.bAtoms = FALSE;
frout.bStep = TRUE;
int nPMEnodes, int nr, gmx_bool bKeepStderr)
{
char numstring[STRLEN];
- char newfilename[STRLEN];
const char *fn = nullptr;
int i;
const char *opt;
{
sprintf(numstring, "_%d", nr);
}
- sprintf(newfilename, "%s_no%d_np%d_npme%d%s", opt2fn("-bg", nfile, fnm), k, nnodes, nPMEnodes, numstring);
+ std::string newfilename = gmx::formatString("%s_no%d_np%d_npme%d%s", opt2fn("-bg", nfile, fnm), k, nnodes, nPMEnodes, numstring);
if (gmx_fexist(opt2fn("-bg", nfile, fnm)))
{
- fprintf(stdout, "renaming log file to %s\n", newfilename);
+ fprintf(stdout, "renaming log file to %s\n", newfilename.c_str());
make_backup(newfilename);
- rename(opt2fn("-bg", nfile, fnm), newfilename);
+ rename(opt2fn("-bg", nfile, fnm), newfilename.c_str());
}
}
else if (std::strcmp(opt, "-err") == 0)
{
sprintf(numstring, "_%d", nr);
}
- sprintf(newfilename, "%s_no%d_np%d_npme%d%s", fn, k, nnodes, nPMEnodes, numstring);
+ std::string newfilename = gmx::formatString("%s_no%d_np%d_npme%d%s", fn, k, nnodes, nPMEnodes, numstring);
if (gmx_fexist(fn))
{
if (bKeepStderr)
{
- fprintf(stdout, "Saving stderr output in %s\n", newfilename);
+ fprintf(stdout, "Saving stderr output in %s\n", newfilename.c_str());
make_backup(newfilename);
- rename(fn, newfilename);
+ rename(fn, newfilename.c_str());
}
else
{
//! Open a file or a pipe to a gzipped file
static FILE *open_pdo_pipe(const char *fn, t_UmbrellaOptions *opt, gmx_bool *bPipeOpen)
{
- char Buffer[1024], gunzip[1024], *Path = nullptr;
+ char Buffer[2048], gunzip[1024], *Path = nullptr;
FILE *pipe = nullptr;
static gmx_bool bFirst = true;
}
/*Print out average energy-spectrum to outfiles[0] and outfiles[1];*/
- datfile1 = gmx_ffopen(outfiles[0].c_str(), "w");
- datfile2 = gmx_ffopen(outfiles[1].c_str(), "w");
+ datfile1 = gmx_ffopen(outfiles[0], "w");
+ datfile2 = gmx_ffopen(outfiles[1], "w");
/*Filling dat files with spectral data*/
fprintf(datfile1, "%s\n", "kx\t ky\t\tPower(kx,ky)");
{
std::string fileFullPath = gmx::findLibraryFile(file);
fprintf(stderr, "Opening force field file %s\n", fileFullPath.c_str());
- return gmx_ffopen(fileFullPath.c_str(), "r");
+ return gmx_ffopen(fileFullPath, "r");
}
if (haveDecoupledMode)
{
- char modeMessage[STRLEN];
- sprintf(modeMessage, "There are atoms at both ends of an angle, connected by constraints and with masses that differ by more than a factor of %g. This means that there are likely dynamic modes that are only very weakly coupled.",
- massFactorThreshold);
- char buf[STRLEN];
+ std::string message = gmx::formatString(
+ "There are atoms at both ends of an angle, connected by constraints "
+ "and with masses that differ by more than a factor of %g. This means "
+ "that there are likely dynamic modes that are only very weakly coupled.",
+ massFactorThreshold);
if (ir->cutoff_scheme == ecutsVERLET)
{
- sprintf(buf, "%s To ensure good equipartitioning, you need to either not use constraints on all bonds (but, if possible, only on bonds involving hydrogens) or use integrator = %s or decrease one or more tolerances: verlet-buffer-tolerance <= %g, LINCS iterations >= %d, LINCS order >= %d or SHAKE tolerance <= %g",
- modeMessage,
- ei_names[eiSD1],
- bufferToleranceThreshold,
- lincsIterationThreshold, lincsOrderThreshold,
- shakeToleranceThreshold);
+ message += gmx::formatString(
+ " To ensure good equipartitioning, you need to either not use "
+ "constraints on all bonds (but, if possible, only on bonds involving "
+ "hydrogens) or use integrator = %s or decrease one or more tolerances: "
+ "verlet-buffer-tolerance <= %g, LINCS iterations >= %d, LINCS order "
+ ">= %d or SHAKE tolerance <= %g",
+ ei_names[eiSD1],
+ bufferToleranceThreshold,
+ lincsIterationThreshold, lincsOrderThreshold,
+ shakeToleranceThreshold);
}
else
{
- sprintf(buf, "%s To ensure good equipartitioning, we suggest to switch to the %s cutoff-scheme, since that allows for better control over the Verlet buffer size and thus over the energy drift.",
- modeMessage,
- ecutscheme_names[ecutsVERLET]);
+ message += gmx::formatString(
+ " To ensure good equipartitioning, we suggest to switch to the %s "
+ "cutoff-scheme, since that allows for better control over the Verlet "
+ "buffer size and thus over the energy drift.",
+ ecutscheme_names[ecutsVERLET]);
}
- warning(wi, buf);
+ warning(wi, message);
}
}
// TODO: Use a C++ API without such an intermediate/fixed-length buffer.
char buf[STRLEN];
/* We don't use fflib_open, because we don't want printf's */
- FILE *fp = gmx_ffopen(docFileName.c_str(), "r");
+ FILE *fp = gmx_ffopen(docFileName, "r");
get_a_line(fp, buf, STRLEN);
gmx_ffclose(fp);
desc.emplace_back(buf);
&pcrd->group[4], &pcrd->group[5], &idum);
if (nscan != pcrd->ngroup)
{
- sprintf(wbuf, "%s should contain %d pull group indices with geometry %s",
- buf, pcrd->ngroup, epullg_names[pcrd->eGeom]);
+ auto message = gmx::formatString("%s should contain %d pull group indices with geometry %s",
+ buf, pcrd->ngroup, epullg_names[pcrd->eGeom]);
set_warning_line(wi, nullptr, -1);
- warning_error(wi, wbuf);
+ warning_error(wi, message);
}
for (int g = 0; g < pcrd->ngroup; g++)
{
*/
#include "gmxpre.h"
+#include <string>
+
#include "gromacs/fileio/readinp.h"
#include "gromacs/fileio/trrio.h"
#include "gromacs/fileio/warninp.h"
#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/futil.h"
+#include "gromacs/utility/path.h"
#include "gromacs/utility/smalloc.h"
+#include "gromacs/utility/stringutil.h"
static const char *RotStr = "Enforced rotation:";
/* Check whether the box is unchanged */
-static void check_box_unchanged(matrix f_box, matrix box, char fn[], warninp_t wi)
+static void check_box_unchanged(matrix f_box, matrix box, const char fn[], warninp_t wi)
{
int i, ii;
bool bSame = TRUE;
{
int g, i, ii;
t_rotgrp *rotg;
- gmx_trr_header_t header; /* Header information of reference file */
- char base[STRLEN], extension[STRLEN], reffile[STRLEN];
- char *extpos;
+ gmx_trr_header_t header; /* Header information of reference file */
rvec f_box[3]; /* Box from reference file */
-
- /* Base name and extension of the reference file: */
- strncpy(base, fn, STRLEN - 1);
- base[STRLEN-1] = '\0';
- extpos = strrchr(base, '.');
- strcpy(extension, extpos+1);
- *extpos = '\0';
-
-
for (g = 0; g < rot->ngrp; g++)
{
rotg = &rot->grp[g];
snew(rotg->x_ref, rotg->nat);
/* Construct the name for the file containing the reference positions for this group: */
- sprintf(reffile, "%s.%d.%s", base, g, extension);
+ std::string reffileString = gmx::Path::concatenateBeforeExtension(fn, gmx::formatString(".%d", g));
+ const char *reffile = reffileString.c_str();
/* If the base filename for the reference position files was explicitly set by
* the user, we issue a fatal error if the group file can not be found */
gmx_atomprop_t aps)
{
FILE *fpin, *fpout;
- char buf[STRLEN], buf2[STRLEN], *temp;
+ char buf[STRLEN*2], buf2[STRLEN], *temp;
const char *topinout;
int line;
bool bSystem;
e = std::min(b+MAXCOL, nspec-1);
for (i = b; (i < e); i++)
{
- sprintf(buf, "%s%d", *pdba->atomname[sgp[i]], sgp[i]+1);
- fprintf(stderr, "%8s", buf);
+ std::string buf = gmx::formatString("%s%d", *pdba->atomname[sgp[i]], sgp[i]+1);
+ fprintf(stderr, "%8s", buf.c_str());
}
fprintf(stderr, "\n");
/* print matrix */
e = std::min(b+MAXCOL, nspec);
for (i = b+1; (i < nspec); i++)
{
- sprintf(buf, "%s%d", *pdba->resinfo[pdba->atom[sgp[i]].resind].name,
- pdba->resinfo[specp[i]].nr);
- fprintf(stderr, "%8s", buf);
- sprintf(buf, "%s%d", *pdba->atomname[sgp[i]], sgp[i]+1);
- fprintf(stderr, "%8s", buf);
+ std::string buf = gmx::formatString("%s%d", *pdba->resinfo[pdba->atom[sgp[i]].resind].name,
+ pdba->resinfo[specp[i]].nr);
+ fprintf(stderr, "%8s", buf.c_str());
+ buf = gmx::formatString("%s%d", *pdba->atomname[sgp[i]], sgp[i]+1);
+ fprintf(stderr, "%8s", buf.c_str());
e2 = std::min(i, e);
for (j = b; (j < e2); j++)
{
#include <cstring>
#include <algorithm>
+#include <string>
#include "gromacs/fileio/warninp.h"
#include "gromacs/gmxpreprocess/gpp_atomtype.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/gmxassert.h"
#include "gromacs/utility/smalloc.h"
+#include "gromacs/utility/stringutil.h"
void generate_nbparams(int comb, int ftype, t_params *plist, gpp_atomtype_t atype,
warninp_t wi)
int i, j, k = -1, nf;
int nr, nrfp;
real c, bi, bj, ci, cj, ci0, ci1, ci2, cj0, cj1, cj2;
- char errbuf[STRLEN];
/* Lean mean shortcuts */
nr = get_atomtype_ntypes(atype);
break;
default:
- sprintf(errbuf, "No such combination rule %d", comb);
- warning_error_and_exit(wi, errbuf, FARGS);
+ auto message = gmx::formatString("No such combination rule %d", comb);
+ warning_error_and_exit(wi, message, FARGS);
}
if (plist->nr != k)
{
break;
default:
- sprintf(errbuf, "Invalid nonbonded type %s",
- interaction_function[ftype].longname);
- warning_error(wi, errbuf);
+ auto message = gmx::formatString("Invalid nonbonded type %s",
+ interaction_function[ftype].longname);
+ warning_error(wi, message);
}
}
double m, q;
double c[MAXFORCEPARAM];
char tmpfield[12][100]; /* Max 12 fields of width 100 */
- char errbuf[STRLEN];
t_atom *atom;
t_param *param;
int atomnr;
break;
default:
- sprintf(errbuf, "Invalid function type %d in push_at", nb_funct);
- warning_error_and_exit(wi, errbuf, FARGS);
+ auto message = gmx::formatString("Invalid function type %d in push_at", nb_funct);
+ warning_error_and_exit(wi, message, FARGS);
}
for (j = nfp0; (j < MAXFORCEPARAM); j++)
{
}
if (j == eptNR)
{
- sprintf(errbuf, "Invalid particle type %s", ptype);
- warning_error_and_exit(wi, errbuf, FARGS);
+ auto message = gmx::formatString("Invalid particle type %s", ptype);
+ warning_error_and_exit(wi, message, FARGS);
}
pt = xl[j].ptype;
if ((nr = get_atomtype_type(type, at)) != NOTSET)
{
- sprintf(errbuf, "Overriding atomtype %s", type);
- warning(wi, errbuf);
+ auto message = gmx::formatString("Overriding atomtype %s", type);
+ warning(wi, message);
if ((nr = set_atomtype(nr, at, symtab, atom, type, param, batype_nr,
atomnr)) == NOTSET)
{
- sprintf(errbuf, "Replacing atomtype %s failed", type);
- warning_error_and_exit(wi, errbuf, FARGS);
+ auto message = gmx::formatString("Replacing atomtype %s failed", type);
+ warning_error_and_exit(wi, message, FARGS);
}
}
else if ((add_atomtype(at, symtab, atom, type, param,
batype_nr, atomnr)) == NOTSET)
{
- sprintf(errbuf, "Adding atomtype %s failed", type);
- warning_error_and_exit(wi, errbuf, FARGS);
+ auto message = gmx::formatString("Adding atomtype %s failed", type);
+ warning_error_and_exit(wi, message, FARGS);
}
else
{
{
int nr = bt->nr;
int nrfp = NRFP(ftype);
- char errbuf[STRLEN];
/* If bAllowRepeat is TRUE, we allow multiple entries as long as they
are on directly _adjacent_ lines.
*/
if (!isContinuationOfBlock && !haveErrored)
{
- warning_error(wi, "Encountered a second block of parameters for dihedral type 9 for the same atoms, with either different parameters and/or the first block has multiple lines. This is not supported.");
+ warning_error(wi, "Encountered a second block of parameters for dihedral "
+ "type 9 for the same atoms, with either different parameters "
+ "and/or the first block has multiple lines. This is not supported.");
haveErrored = true;
}
}
else if (!haveWarned)
{
- sprintf(errbuf, "Overriding %s parameters.%s",
+ auto message = gmx::formatString
+ ("Overriding %s parameters.%s",
interaction_function[ftype].longname,
(ftype == F_PDIHS) ?
- "\nUse dihedraltype 9 to allow several multiplicity terms. Only consecutive lines are combined. Non-consective lines overwrite each other."
+ "\nUse dihedraltype 9 to allow several multiplicity terms. Only consecutive "
+ "lines are combined. Non-consective lines overwrite each other."
: "");
- warning(wi, errbuf);
+ warning(wi, message);
fprintf(stderr, " old: ");
for (int j = 0; (j < nrfp); j++)
/* One force parameter more, so we can check if we read too many */
double c[MAXFORCEPARAM+1];
t_param p;
- char errbuf[STRLEN];
if ((bat && at) || (!bat && !at))
{
if ((nn = sscanf(line, formal[nral],
alc[0], alc[1], alc[2], alc[3], alc[4], alc[5])) != nral+1)
{
- sprintf(errbuf, "Not enough atomtypes (%d instead of %d)", nn-1, nral);
- warning_error(wi, errbuf);
+ auto message = gmx::formatString("Not enough atomtypes (%d instead of %d)", nn-1, nral);
+ warning_error(wi, message);
return;
}
{
if (at && ((p.a[i] = get_atomtype_type(alc[i], at)) == NOTSET))
{
- sprintf(errbuf, "Unknown atomtype %s\n", alc[i]);
- warning_error_and_exit(wi, errbuf, FARGS);
+ auto message = gmx::formatString("Unknown atomtype %s\n", alc[i]);
+ warning_error_and_exit(wi, message, FARGS);
}
else if (bat && ((p.a[i] = get_bond_atomtype_type(alc[i], bat)) == NOTSET))
{
- sprintf(errbuf, "Unknown bond_atomtype %s\n", alc[i]);
- warning_error_and_exit(wi, errbuf, FARGS);
+ auto message = gmx::formatString("Unknown bond_atomtype %s\n", alc[i]);
+ warning_error_and_exit(wi, message, FARGS);
}
}
for (i = 0; (i < nrfp); i++)
double c[MAXFORCEPARAM];
t_param p;
bool bAllowRepeat;
- char errbuf[STRLEN];
/* This routine accepts dihedraltypes defined from either 2 or 4 atoms.
*
}
else
{
- sprintf(errbuf, "Incorrect number of atomtypes for dihedral (%d instead of 2 or 4)", nn-1);
- warning_error(wi, errbuf);
+ auto message = gmx::formatString("Incorrect number of atomtypes for dihedral (%d instead of 2 or 4)", nn-1);
+ warning_error(wi, message);
return;
}
{
if ((p.a[i] = get_bond_atomtype_type(alc[i], bat)) == NOTSET)
{
- sprintf(errbuf, "Unknown bond_atomtype %s", alc[i]);
- warning_error_and_exit(wi, errbuf, FARGS);
+ auto message = gmx::formatString("Unknown bond_atomtype %s", alc[i]);
+ warning_error_and_exit(wi, message, FARGS);
}
}
}
int ai, aj;
t_nbparam *nbp;
bool bId;
- char errbuf[STRLEN];
if (sscanf (pline, "%s%s%d", a0, a1, &f) != 3)
{
if (ftype != nb_funct)
{
- sprintf(errbuf, "Trying to add %s while the default nonbond type is %s",
- interaction_function[ftype].longname,
- interaction_function[nb_funct].longname);
- warning_error(wi, errbuf);
+ auto message = gmx::formatString("Trying to add %s while the default nonbond type is %s",
+ interaction_function[ftype].longname,
+ interaction_function[nb_funct].longname);
+ warning_error(wi, message);
return;
}
}
else
{
- sprintf(errbuf, "Number of force parameters for nonbonded interactions is %d", nrfp);
- warning_error_and_exit(wi, errbuf, FARGS);
+ auto message = gmx::formatString("Number of force parameters for nonbonded interactions is %d", nrfp);
+ warning_error_and_exit(wi, message, FARGS);
}
for (i = 0; (i < nrfp); i++)
{
/* Put the parameters in the matrix */
if ((ai = get_atomtype_type (a0, atype)) == NOTSET)
{
- sprintf(errbuf, "Atomtype %s not found", a0);
- warning_error_and_exit(wi, errbuf, FARGS);
+ auto message = gmx::formatString("Atomtype %s not found", a0);
+ warning_error_and_exit(wi, message, FARGS);
}
if ((aj = get_atomtype_type (a1, atype)) == NOTSET)
{
- sprintf(errbuf, "Atomtype %s not found", a1);
- warning_error_and_exit(wi, errbuf, FARGS);
+ auto message = gmx::formatString("Atomtype %s not found", a1);
+ warning_error_and_exit(wi, message, FARGS);
}
nbp = &(nbt[std::max(ai, aj)][std::min(ai, aj)]);
}
if (!bId)
{
- sprintf(errbuf, "Overriding non-bonded parameters,");
- warning(wi, errbuf);
+ auto message = gmx::formatString("Overriding non-bonded parameters,");
+ warning(wi, message);
fprintf(stderr, " old:");
for (i = 0; i < nrfp; i++)
{
int nxcmap, nycmap, ncmap, read_cmap, sl, nct;
char s[20], alc[MAXATOMLIST+2][20];
t_param p;
- char errbuf[STRLEN];
/* Keep the compiler happy */
read_cmap = 0;
/* Here we can only check for < 8 */
if ((nn = sscanf(line, formal, alc[0], alc[1], alc[2], alc[3], alc[4], alc[5], alc[6], alc[7], &nchar_consumed)) < nral+3)
{
- sprintf(errbuf, "Incorrect number of atomtypes for cmap (%d instead of 5)", nn-1);
- warning_error(wi, errbuf);
+ auto message = gmx::formatString("Incorrect number of atomtypes for cmap (%d instead of 5)", nn-1);
+ warning_error(wi, message);
return;
}
start += nchar_consumed;
/* Check for equal grid spacing in x and y dims */
if (nxcmap != nycmap)
{
- sprintf(errbuf, "Not the same grid spacing in x and y for cmap grid: x=%d, y=%d", nxcmap, nycmap);
- warning_error(wi, errbuf);
+ auto message = gmx::formatString("Not the same grid spacing in x and y for cmap grid: x=%d, y=%d", nxcmap, nycmap);
+ warning_error(wi, message);
}
ncmap = nxcmap*nycmap;
}
else
{
- sprintf(errbuf, "Error in reading cmap parameter for angle %s %s %s %s %s", alc[0], alc[1], alc[2], alc[3], alc[4]);
- warning_error(wi, errbuf);
+ auto message = gmx::formatString("Error in reading cmap parameter for angle %s %s %s %s %s", alc[0], alc[1], alc[2], alc[3], alc[4]);
+ warning_error(wi, message);
}
}
{
if (at && ((p.a[i] = get_bond_atomtype_type(alc[i], bat)) == NOTSET))
{
- sprintf(errbuf, "Unknown atomtype %s\n", alc[i]);
- warning_error(wi, errbuf);
+ auto message = gmx::formatString("Unknown atomtype %s\n", alc[i]);
+ warning_error(wi, message);
}
else if (bat && ((p.a[i] = get_bond_atomtype_type(alc[i], bat)) == NOTSET))
{
- sprintf(errbuf, "Unknown bond_atomtype %s\n", alc[i]);
- warning_error(wi, errbuf);
+ auto message = gmx::formatString("Unknown bond_atomtype %s\n", alc[i]);
+ warning_error(wi, message);
}
/* Assign a grid number to each cmap_type */
/* Check for the correct number of atoms (again) */
if (bt[F_CMAP].nct != nct)
{
- sprintf(errbuf, "Incorrect number of atom types (%d) in cmap type %d\n", nct, bt[F_CMAP].nc);
- warning_error(wi, errbuf);
+ auto message = gmx::formatString("Incorrect number of atom types (%d) in cmap type %d\n", nct, bt[F_CMAP].nc);
+ warning_error(wi, message);
}
/* Is this correct?? */
int j, resind = 0, resnr;
unsigned char ric;
int nr = at->nr;
- char errbuf[STRLEN];
if (((nr == 0) && (atomnr != 1)) || (nr && (atomnr != at->nr+1)))
{
- sprintf(errbuf, "Atoms in the .top are not numbered consecutively from 1 (rather, atomnr = %d, while at->nr = %d)", atomnr, at->nr);
- warning_error_and_exit(wi, errbuf, FARGS);
+ auto message = gmx::formatString
+ ("Atoms in the .top are not numbered consecutively from 1 (rather, "
+ "atomnr = %d, while at->nr = %d)", atomnr, at->nr);
+ warning_error_and_exit(wi, message, FARGS);
}
j = strlen(resnumberic) - 1;
ric = resnumberic[j];
if (j == 0 || !isdigit(resnumberic[j-1]))
{
- sprintf(errbuf, "Invalid residue number '%s' for atom %d",
- resnumberic, atomnr);
- warning_error_and_exit(wi, errbuf, FARGS);
+ auto message = gmx::formatString("Invalid residue number '%s' for atom %d",
+ resnumberic, atomnr);
+ warning_error_and_exit(wi, message, FARGS);
}
}
resnr = strtol(resnumberic, nullptr, 10);
resnumberic[STRLEN], resname[STRLEN], name[STRLEN], check[STRLEN];
double m, q, mb, qb;
real m0, q0, mB, qB;
- char errbuf[STRLEN];
/* Make a shortcut for writing in this molecule */
nr = at->nr;
sscanf(id, "%d", &atomnr);
if ((type = get_atomtype_type(ctype, atype)) == NOTSET)
{
- sprintf(errbuf, "Atomtype %s not found", ctype);
- warning_error_and_exit(wi, errbuf, FARGS);
+ auto message = gmx::formatString("Atomtype %s not found", ctype);
+ warning_error_and_exit(wi, message, FARGS);
}
ptype = get_atomtype_ptype(type, atype);
{
if ((typeB = get_atomtype_type(ctypeB, atype)) == NOTSET)
{
- sprintf(errbuf, "Atomtype %s not found", ctypeB);
- warning_error_and_exit(wi, errbuf, FARGS);
+ auto message = gmx::formatString("Atomtype %s not found", ctypeB);
+ warning_error_and_exit(wi, message, FARGS);
}
qB = get_atomtype_qA(typeB, atype);
mB = get_atomtype_massA(typeB, atype);
char type[STRLEN];
int nrexcl, i;
t_molinfo *newmol;
- char errbuf[STRLEN];
if ((sscanf(line, "%s%d", type, &nrexcl)) != 2)
{
{
if (strcmp(*((*mol)[i].name), type) == 0)
{
- sprintf(errbuf, "moleculetype %s is redefined", type);
- warning_error_and_exit(wi, errbuf, FARGS);
+ auto message = gmx::formatString("moleculetype %s is redefined", type);
+ warning_error_and_exit(wi, message, FARGS);
}
i++;
}
int i, nparam_found;
int ct;
bool bFound = FALSE;
- char errbuf[STRLEN];
nparam_found = 0;
ct = 0;
/* If we did not find a matching type for this cmap torsion */
if (!bFound)
{
- sprintf(errbuf, "Unknown cmap torsion between atoms %d %d %d %d %d",
- p->a[0]+1, p->a[1]+1, p->a[2]+1, p->a[3]+1, p->a[4]+1);
- warning_error_and_exit(wi, errbuf, FARGS);
+ auto message = gmx::formatString("Unknown cmap torsion between atoms %d %d %d %d %d",
+ p->a[0]+1, p->a[1]+1, p->a[2]+1, p->a[3]+1, p->a[4]+1);
+ warning_error_and_exit(wi, message, FARGS);
}
*nparam_def = nparam_found;
t_param param, *param_defA, *param_defB;
bool bFoundA = FALSE, bFoundB = FALSE, bDef, bPert, bSwapParity = FALSE;
int nparam_defA, nparam_defB;
- char errbuf[STRLEN];
nparam_defA = nparam_defB = 0;
case F_VSITE3OUT:
break;
default:
- sprintf(errbuf, "Negative function types only allowed for %s and %s",
- interaction_function[F_VSITE3FAD].longname,
- interaction_function[F_VSITE3OUT].longname);
- warning_error_and_exit(wi, errbuf, FARGS);
+ auto message = gmx::formatString("Negative function types only allowed for %s and %s",
+ interaction_function[F_VSITE3FAD].longname,
+ interaction_function[F_VSITE3OUT].longname);
+ warning_error_and_exit(wi, message, FARGS);
}
}
}
{
if (aa[i] < 1 || aa[i] > at->nr)
{
- sprintf(errbuf, "Atom index (%d) in %s out of bounds (1-%d).\n"
+ auto message = gmx::formatString
+ ("Atom index (%d) in %s out of bounds (1-%d).\n"
"This probably means that you have inserted topology section \"%s\"\n"
"in a part belonging to a different molecule than you intended to.\n"
"In that case move the \"%s\" section to the right molecule.",
aa[i], dir2str(d), at->nr, dir2str(d), dir2str(d));
- warning_error_and_exit(wi, errbuf, FARGS);
+ warning_error_and_exit(wi, message, FARGS);
}
for (j = i+1; (j < nral); j++)
{
GMX_ASSERT(j < MAXATOMLIST + 1, "Values from nral=NRAL() will satisfy this, we assert to keep gcc 4 happy");
if (aa[i] == aa[j])
{
- sprintf(errbuf, "Duplicate atom index (%d) in %s", aa[i], dir2str(d));
+ auto message = gmx::formatString("Duplicate atom index (%d) in %s", aa[i], dir2str(d));
if (ftype == F_ANGRES)
{
/* Since the angle restraints uses 2 pairs of atoms to
* defines an angle between vectors, it can be useful
* to use one atom twice, so we only issue a note here.
*/
- warning_note(wi, errbuf);
+ warning_note(wi, message);
}
else
{
- warning_error(wi, errbuf);
+ warning_error(wi, message);
}
}
}
if (bPert && *bWarn_copy_A_B)
{
- sprintf(errbuf,
- "Some parameters for bonded interaction involving perturbed atoms are specified explicitly in state A, but not B - copying A to B");
- warning(wi, errbuf);
+ auto message = gmx::formatString("Some parameters for bonded interaction involving "
+ "perturbed atoms are specified explicitly in "
+ "state A, but not B - copying A to B");
+ warning(wi, message);
*bWarn_copy_A_B = FALSE;
}
if ((nread != 0) && (nread != EOF) && (nread != NRFP(ftype)) &&
!(ftype == F_LJC14_Q && nread == 1))
{
- sprintf(errbuf, "Incorrect number of parameters - found %d, expected %d or %d for %s (after the function type).",
+ auto message = gmx::formatString
+ ("Incorrect number of parameters - found %d, expected %d "
+ "or %d for %s (after the function type).",
nread, NRFPA(ftype), NRFP(ftype), interaction_function[ftype].longname);
- warning_error_and_exit(wi, errbuf, FARGS);
+ warning_error_and_exit(wi, message, FARGS);
}
for (j = 0; (j < nread); j++)
{
if ((nparam_defA != nparam_defB) || ((nparam_defA > 1 || nparam_defB > 1) && (param_defA != param_defB)))
{
- sprintf(errbuf,
- "Cannot automatically perturb a torsion with multiple terms to different form.\n"
- "Please specify perturbed parameters manually for this torsion in your topology!");
- warning_error(wi, errbuf);
+ auto message =
+ gmx::formatString("Cannot automatically perturb a torsion with multiple terms to different form.\n"
+ "Please specify perturbed parameters manually for this torsion in your topology!");
+ warning_error(wi, message);
}
}
if (nread > 0 && nread < NRFPA(ftype))
{
/* Issue an error, do not use defaults */
- sprintf(errbuf, "Not enough parameters, there should be at least %d (or 0 for defaults)", NRFPA(ftype));
- warning_error(wi, errbuf);
+ auto message = gmx::formatString("Not enough parameters, there should be at least %d (or 0 for defaults)", NRFPA(ftype));
+ warning_error(wi, message);
}
if (nread == 0 || nread == EOF)
}
else
{
- sprintf(errbuf, "No default %s types", interaction_function[ftype].longname);
- warning_error(wi, errbuf);
+ auto message = gmx::formatString("No default %s types", interaction_function[ftype].longname);
+ warning_error(wi, message);
}
}
}
if (bPert)
{
- sprintf(errbuf, "No default %s types for perturbed atoms, "
- "using normal values", interaction_function[ftype].longname);
- warning(wi, errbuf);
+ auto message = gmx::formatString("No default %s types for perturbed atoms, "
+ "using normal values", interaction_function[ftype].longname);
+ warning(wi, message);
}
}
}
if ((ftype == F_PDIHS || ftype == F_ANGRES || ftype == F_ANGRESZ)
&& param.c[5] != param.c[2])
{
- sprintf(errbuf, "%s multiplicity can not be perturbed %f!=%f",
- interaction_function[ftype].longname,
- param.c[2], param.c[5]);
- warning_error_and_exit(wi, errbuf, FARGS);
+ auto message = gmx::formatString("%s multiplicity can not be perturbed %f!=%f",
+ interaction_function[ftype].longname,
+ param.c[2], param.c[5]);
+ warning_error_and_exit(wi, message, FARGS);
}
if (IS_TABULATED(ftype) && param.c[2] != param.c[0])
{
- sprintf(errbuf, "%s table number can not be perturbed %d!=%d",
- interaction_function[ftype].longname,
- gmx::roundToInt(param.c[0]), gmx::roundToInt(param.c[2]));
- warning_error_and_exit(wi, errbuf, FARGS);
+ auto message = gmx::formatString("%s table number can not be perturbed %d!=%d",
+ interaction_function[ftype].longname,
+ gmx::roundToInt(param.c[0]), gmx::roundToInt(param.c[2]));
+ warning_error_and_exit(wi, message, FARGS);
}
/* Dont add R-B dihedrals where all parameters are zero (no interaction) */
int i, j, ftype, nral, nread, ncmap_params;
int cmap_type;
int aa[MAXATOMLIST+1];
- char errbuf[STRLEN];
bool bFound;
t_param param;
{
if (aa[i] < 1 || aa[i] > at->nr)
{
- sprintf(errbuf, "Atom index (%d) in %s out of bounds (1-%d).\n"
+ auto message = gmx::formatString
+ ("Atom index (%d) in %s out of bounds (1-%d).\n"
"This probably means that you have inserted topology section \"%s\"\n"
"in a part belonging to a different molecule than you intended to.\n"
"In that case move the \"%s\" section to the right molecule.",
aa[i], dir2str(d), at->nr, dir2str(d), dir2str(d));
- warning_error_and_exit(wi, errbuf, FARGS);
+ warning_error_and_exit(wi, message, FARGS);
}
for (j = i+1; (j < nral); j++)
{
if (aa[i] == aa[j])
{
- sprintf(errbuf, "Duplicate atom index (%d) in %s", aa[i], dir2str(d));
- warning_error(wi, errbuf);
+ auto message = gmx::formatString("Duplicate atom index (%d) in %s", aa[i], dir2str(d));
+ warning_error(wi, message);
}
}
}
else
{
/* This is essentially the same check as in default_cmap_params() done one more time */
- sprintf(errbuf, "Unable to assign a cmap type to torsion %d %d %d %d and %d\n",
- param.a[0]+1, param.a[1]+1, param.a[2]+1, param.a[3]+1, param.a[4]+1);
- warning_error_and_exit(wi, errbuf, FARGS);
+ auto message = gmx::formatString("Unable to assign a cmap type to torsion %d %d %d %d and %d\n",
+ param.a[0]+1, param.a[1]+1, param.a[2]+1, param.a[3]+1, param.a[4]+1);
+ warning_error_and_exit(wi, message, FARGS);
}
}
int *atc = nullptr;
double *weight = nullptr, weight_tot;
t_param param;
- char errbuf[STRLEN];
/* default force parameters */
for (j = 0; (j < MAXATOMLIST); j++)
ptr += n;
if (ret == 0)
{
- sprintf(errbuf, "Expected an atom index in section \"%s\"",
- dir2str(d));
- warning_error_and_exit(wi, errbuf, FARGS);
+ auto message = gmx::formatString("Expected an atom index in section \"%s\"",
+ dir2str(d));
+ warning_error_and_exit(wi, message, FARGS);
}
param.a[0] = a - 1;
ptr += n;
if (weight[nj] < 0)
{
- sprintf(errbuf, "No weight or negative weight found for vsiten constructing atom %d (atom index %d)",
+ auto message = gmx::formatString
+ ("No weight or negative weight found for vsiten "
+ "constructing atom %d (atom index %d)",
nj+1, atc[nj]+1);
- warning_error_and_exit(wi, errbuf, FARGS);
+ warning_error_and_exit(wi, message, FARGS);
}
break;
default:
- sprintf(errbuf, "Unknown vsiten type %d", type);
- warning_error_and_exit(wi, errbuf, FARGS);
+ auto message = gmx::formatString("Unknown vsiten type %d", type);
+ warning_error_and_exit(wi, message, FARGS);
}
weight_tot += weight[nj];
nj++;
if (nj == 0)
{
- sprintf(errbuf, "Expected more than one atom index in section \"%s\"",
- dir2str(d));
- warning_error_and_exit(wi, errbuf, FARGS);
+ auto message = gmx::formatString("Expected more than one atom index in section \"%s\"",
+ dir2str(d));
+ warning_error_and_exit(wi, message, FARGS);
}
if (weight_tot == 0)
warninp_t wi)
{
char type[STRLEN];
- char errbuf[STRLEN];
if (sscanf(pline, "%s%d", type, nrcopies) != 2)
{
// avoid matching case-insensitive when we have multiple matches
if (nrci > 1)
{
- sprintf(errbuf, "For moleculetype '%s' in [ system ] %d case insensitive matches, but %d case sensitive matches were found. Check the case of the characters in the moleculetypes.", type, nrci, nrcs);
- warning_error_and_exit(wi, errbuf, FARGS);
+ auto message = gmx::formatString
+ ("For moleculetype '%s' in [ system ] %d case insensitive "
+ "matches, but %d case sensitive matches were found. Check "
+ "the case of the characters in the moleculetypes.",
+ type, nrci, nrcs);
+ warning_error_and_exit(wi, message, FARGS);
}
if (nrci == 1)
{
}
else
{
- sprintf(errbuf, "No such moleculetype %s", type);
- warning_error_and_exit(wi, errbuf, FARGS);
+ auto message = gmx::formatString("No such moleculetype %s", type);
+ warning_error_and_exit(wi, message, FARGS);
}
}
}
int i, j;
int n;
char base[STRLEN], format[STRLEN];
- char errbuf[STRLEN];
if (sscanf(line, "%d", &i) == 0)
{
}
else
{
- sprintf(errbuf, "Invalid Atomnr j: %d, b2->nr: %d\n", j, b2->nr);
- warning_error_and_exit(wi, errbuf, FARGS);
+ auto message = gmx::formatString("Invalid Atomnr j: %d, b2->nr: %d\n", j, b2->nr);
+ warning_error_and_exit(wi, message, FARGS);
}
}
}
int i, k;
int j;
int nra;
- char errbuf[STRLEN];
if (!b2->nr)
{
}
else if (b2->nr != excl->nr)
{
- sprintf(errbuf, "DEATH HORROR: b2->nr = %d, while excl->nr = %d",
- b2->nr, excl->nr);
- warning_error_and_exit(wi, errbuf, FARGS);
+ auto message = gmx::formatString("DEATH HORROR: b2->nr = %d, while excl->nr = %d",
+ b2->nr, excl->nr);
+ warning_error_and_exit(wi, message, FARGS);
}
/* First copy all entries from excl to b2 */
t_blocka *excl;
bool bExcl;
t_param param;
- char errbuf[STRLEN];
n = mol->atoms.nr;
atom = mol->atoms.atom;
{
if (nb_funct != F_LJ)
{
- sprintf(errbuf, "Can only generate non-bonded pair interactions for Van der Waals type Lennard-Jones");
- warning_error_and_exit(wi, errbuf, FARGS);
+ auto message = gmx::formatString
+ ("Can only generate non-bonded pair interactions "
+ "for Van der Waals type Lennard-Jones");
+ warning_error_and_exit(wi, message, FARGS);
}
param.a[0] = i;
param.a[1] = j;
const char *mol_name, warninp_t wi)
{
int i;
- char errbuf[STRLEN];
for (i = 0; i < atoms->nr; i++)
{
if (atom->qB != atom->q || atom->typeB != atom->type)
{
- sprintf(errbuf, "Atom %d in molecule type '%s' has different A and B state charges and/or atom types set in the topology file as well as through the mdp option '%s'. You can not use both these methods simultaneously.",
+ auto message = gmx::formatString
+ ("Atom %d in molecule type '%s' has different A and B state "
+ "charges and/or atom types set in the topology file as well "
+ "as through the mdp option '%s'. You can not use both "
+ "these methods simultaneously.",
i + 1, mol_name, "couple-moltype");
- warning_error_and_exit(wi, errbuf, FARGS);
+ warning_error_and_exit(wi, message, FARGS);
}
if (couple_lam0 == ecouplamNONE || couple_lam0 == ecouplamVDW)
#include <cstdlib>
#include <cstring>
+#include <string>
+
#include "gromacs/awh/awh.h"
#include "gromacs/fileio/enxio.h"
#include "gromacs/fileio/gmxfio.h"
#include "gromacs/utility/arraysize.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/smalloc.h"
+#include "gromacs/utility/stringutil.h"
static const char *conrmsd_nm[] = { "Constr. rmsd", "Constr.2 rmsd" };
FILE *fp;
const char *dhdl = "dH/d\\lambda", *deltag = "\\DeltaH", *lambda = "\\lambda",
*lambdastate = "\\lambda state";
- char title[STRLEN], label_x[STRLEN], label_y[STRLEN];
- int i, nps, nsets, nsets_de, nsetsbegin;
+ int i, nsets, nsets_de, nsetsbegin;
int n_lambda_terms = 0;
t_lambda *fep = ir->fepvals; /* for simplicity */
t_expanded *expand = ir->expandedvals;
- char **setname;
- char buf[STRLEN], lambda_vec_str[STRLEN], lambda_name_str[STRLEN];
- int bufplace = 0;
+ char lambda_vec_str[STRLEN], lambda_name_str[STRLEN];
int nsets_dhdl = 0;
int s = 0;
}
}
+ std::string title, label_x, label_y;
if (fep->n_lambda == 0)
{
- sprintf(title, "%s", dhdl);
- sprintf(label_x, "Time (ps)");
- sprintf(label_y, "%s (%s %s)",
- dhdl, unit_energy, "[\\lambda]\\S-1\\N");
+ title = gmx::formatString("%s", dhdl);
+ label_x = gmx::formatString("Time (ps)");
+ label_y = gmx::formatString("%s (%s %s)",
+ dhdl, unit_energy, "[\\lambda]\\S-1\\N");
}
else
{
- sprintf(title, "%s and %s", dhdl, deltag);
- sprintf(label_x, "Time (ps)");
- sprintf(label_y, "%s and %s (%s %s)",
- dhdl, deltag, unit_energy, "[\\8l\\4]\\S-1\\N");
+ title = gmx::formatString("%s and %s", dhdl, deltag);
+ label_x = gmx::formatString("Time (ps)");
+ label_y = gmx::formatString("%s and %s (%s %s)",
+ dhdl, deltag, unit_energy, "[\\8l\\4]\\S-1\\N");
}
fp = gmx_fio_fopen(filename, "w+");
- xvgr_header(fp, title, label_x, label_y, exvggtXNY, oenv);
+ xvgr_header(fp, title.c_str(), label_x, label_y, exvggtXNY, oenv);
+ std::string buf;
if (!(ir->bSimTemp))
{
- bufplace = sprintf(buf, "T = %g (K) ",
- ir->opts.ref_t[0]);
+ buf = gmx::formatString("T = %g (K) ", ir->opts.ref_t[0]);
}
if ((ir->efep != efepSLOWGROWTH) && (ir->efep != efepEXPANDED))
{
if ( (fep->init_lambda >= 0) && (n_lambda_terms == 1 ))
{
/* compatibility output */
- sprintf(&(buf[bufplace]), "%s = %.4f", lambda, fep->init_lambda);
+ buf += gmx::formatString("%s = %.4f", lambda, fep->init_lambda);
}
else
{
lambda_vec_str);
print_lambda_vector(fep, fep->init_fep_state, TRUE, TRUE,
lambda_name_str);
- sprintf(&(buf[bufplace]), "%s %d: %s = %s",
- lambdastate, fep->init_fep_state,
- lambda_name_str, lambda_vec_str);
+ buf += gmx::formatString("%s %d: %s = %s",
+ lambdastate, fep->init_fep_state,
+ lambda_name_str, lambda_vec_str);
}
}
- xvgr_subtitle(fp, buf, oenv);
+ xvgr_subtitle(fp, buf.c_str(), oenv);
nsets_dhdl = 0;
dhdl.xvg file) */
write_pV = TRUE;
}
- snew(setname, nsetsextend);
+ std::vector<std::string> setname(nsetsextend);
if (expand->elmcmove > elmcmoveNO)
{
/* state for the fep_vals, if we have alchemical sampling */
- sprintf(buf, "%s", "Thermodynamic state");
- setname[s] = gmx_strdup(buf);
- s += 1;
+ setname[s++] = "Thermodynamic state";
}
if (fep->edHdLPrintEnergy != edHdLPrintEnergyNO)
{
+ std::string energy;
switch (fep->edHdLPrintEnergy)
{
case edHdLPrintEnergyPOTENTIAL:
- sprintf(buf, "%s (%s)", "Potential Energy", unit_energy);
+ energy = gmx::formatString("%s (%s)", "Potential Energy", unit_energy);
break;
case edHdLPrintEnergyTOTAL:
case edHdLPrintEnergyYES:
default:
- sprintf(buf, "%s (%s)", "Total Energy", unit_energy);
+ energy = gmx::formatString("%s (%s)", "Total Energy", unit_energy);
}
- setname[s] = gmx_strdup(buf);
- s += 1;
+ setname[s++] = energy;
}
if (fep->dhdl_derivatives == edhdlderivativesYES)
{
if (fep->separate_dvdl[i])
{
-
+ std::string derivative;
if ( (fep->init_lambda >= 0) && (n_lambda_terms == 1 ))
{
/* compatibility output */
- sprintf(buf, "%s %s %.4f", dhdl, lambda, fep->init_lambda);
+ derivative = gmx::formatString("%s %s %.4f", dhdl, lambda, fep->init_lambda);
}
else
{
{
lam = fep->all_lambda[i][fep->init_fep_state];
}
- sprintf(buf, "%s %s = %.4f", dhdl, efpt_singular_names[i],
- lam);
+ derivative = gmx::formatString("%s %s = %.4f", dhdl, efpt_singular_names[i],
+ lam);
}
- setname[s] = gmx_strdup(buf);
- s += 1;
+ setname[s++] = derivative;
}
}
}
for (i = fep->lambda_start_n; i < fep->lambda_stop_n; i++)
{
print_lambda_vector(fep, i, FALSE, FALSE, lambda_vec_str);
+ std::string buf;
if ( (fep->init_lambda >= 0) && (n_lambda_terms == 1 ))
{
/* for compatible dhdl.xvg files */
- nps = sprintf(buf, "%s %s %s", deltag, lambda, lambda_vec_str);
+ buf = gmx::formatString("%s %s %s", deltag, lambda, lambda_vec_str);
}
else
{
- nps = sprintf(buf, "%s %s to %s", deltag, lambda, lambda_vec_str);
+ buf = gmx::formatString("%s %s to %s", deltag, lambda, lambda_vec_str);
}
if (ir->bSimTemp)
{
/* print the temperature for this state if doing simulated annealing */
- sprintf(&buf[nps], "T = %g (%s)",
- ir->simtempvals->temperatures[s-(nsetsbegin)],
- unit_temp_K);
+ buf += gmx::formatString("T = %g (%s)",
+ ir->simtempvals->temperatures[s-(nsetsbegin)],
+ unit_temp_K);
}
- setname[s] = gmx_strdup(buf);
- s++;
+ setname[s++] = buf;
}
if (write_pV)
{
- sprintf(buf, "pV (%s)", unit_energy);
- setname[nsetsextend-1] = gmx_strdup(buf); /* the first entry after
- nsets */
+ setname[s++] = gmx::formatString("pV (%s)", unit_energy);
}
- xvgr_legend(fp, nsetsextend, setname, oenv);
-
- for (s = 0; s < nsetsextend; s++)
- {
- sfree(setname[s]);
- }
- sfree(setname);
+ xvgrLegend(fp, setname, oenv);
}
return fp;
#include "gromacs/utility/logger.h"
#include "gromacs/utility/pleasecite.h"
#include "gromacs/utility/smalloc.h"
+#include "gromacs/utility/strconvert.h"
#include "gromacs/utility/sysinfo.h"
#include "nbnxn_gpu.h"
const t_commrec *cr)
{
time_t finish;
- char timebuf[STRLEN];
double dt, elapsed_seconds, time_per_step;
- char buf[48];
#if !GMX_THREAD_MPI
if (!PAR(cr))
{
fprintf(out, "\r");
}
- fprintf(out, "step %s", gmx_step_str(step, buf));
+ fputs("step ", out);
+ fputs(gmx::int64ToString(step).c_str(), out);
fflush(out);
if ((step >= ir->nstlist))
if (dt >= 300)
{
finish = static_cast<time_t>(seconds_since_epoch + dt);
- gmx_ctime_r(&finish, timebuf, STRLEN);
- sprintf(buf, "%s", timebuf);
- buf[strlen(buf)-1] = '\0';
- fprintf(out, ", will finish %s", buf);
+ auto timebuf = gmx_ctime_r(&finish);
+ fputs(", will finish ", out);
+ fputs(timebuf.c_str(), out);
}
else
{
void print_date_and_time(FILE *fplog, int nodeid, const char *title,
double the_time)
{
- char time_string[STRLEN];
-
if (!fplog)
{
return;
}
- {
- int i;
- char timebuf[STRLEN];
- time_t temp_time = static_cast<time_t>(the_time);
+ time_t temp_time = static_cast<time_t>(the_time);
- gmx_ctime_r(&temp_time, timebuf, STRLEN);
- for (i = 0; timebuf[i] >= ' '; i++)
- {
- time_string[i] = timebuf[i];
- }
- time_string[i] = '\0';
- }
+ auto timebuf = gmx_ctime_r(&temp_time);
+ // Retain only the characters before the first space
+ timebuf.erase(std::find(timebuf.begin(), timebuf.end(), ' '), timebuf.end());
- fprintf(fplog, "%s on rank %d %s\n", title, nodeid, time_string);
+ fprintf(fplog, "%s on rank %d %s\n", title, nodeid, timebuf.c_str());
}
void print_start(FILE *fplog, const t_commrec *cr,
{
int pid;
char host[256];
- char timebuf[STRLEN];
GMX_RELEASE_ASSERT(fplog != nullptr, "Log file must be already open");
gmx_fatal_set_log_file(fplog);
/* Get some machine parameters */
gmx_gethostname(host, 256);
pid = gmx_getpid();
- gmx_format_current_time(timebuf, STRLEN);
fprintf(fplog,
"Log file opened on %s"
"Host: %s pid: %d rank ID: %d number of ranks: %d\n",
- timebuf, host, pid, rankIndex, numRanks);
+ gmx_format_current_time().c_str(), host, pid, rankIndex, numRanks);
try
{
settings.extendedInfo(true);
if (SIMMASTER(cr))
{
- if (!gmx_fexist(filename) || (!(fp = gmx_fio_open(filename, "r")) ))
+ if (!gmx_fexist(filename) || ((fp = gmx_fio_open(filename, "r")) == nullptr ))
{
*simulation_part = 0;
/* We have already warned the user that no checkpoint file existed before, don't
#include "gromacs/utility/smalloc.h"
#include "gromacs/utility/snprintf.h"
#include "gromacs/utility/strconvert.h"
+#include "gromacs/utility/stringutil.h"
#include "gromacs/utility/textwriter.h"
#include "gromacs/utility/txtdump.h"
}
}
-static void pr_awh_bias_dim(FILE *fp, int indent, gmx::AwhDimParams *awhDimParams, char *prefix)
+static void pr_awh_bias_dim(FILE *fp, int indent, gmx::AwhDimParams *awhDimParams, const char *prefix)
{
pr_indent(fp, indent);
indent++;
PR("cover-diameter", awhDimParams->coverDiameter);
}
-static void pr_awh_bias(FILE *fp, int indent, gmx::AwhBiasParams *awhBiasParams, char *prefix)
+static void pr_awh_bias(FILE *fp, int indent, gmx::AwhBiasParams *awhBiasParams, const char *prefix)
{
char opt[STRLEN];
static void pr_awh(FILE *fp, int indent, gmx::AwhParams *awhParams)
{
- int k;
- char opt[STRLEN], prefix[STRLEN];
-
- sprintf(prefix, "%s", "awh");
-
- sprintf(opt, "%s-potential", prefix);
- PS(opt, EAWHPOTENTIAL(awhParams->ePotential));
- sprintf(opt, "%s-seed", prefix);
- PI(opt, awhParams->seed);
- sprintf(opt, "%s-nstout", prefix);
- PI(opt, awhParams->nstOut);
- sprintf(opt, "%s-nstsample", prefix);
- PI(opt, awhParams->nstSampleCoord);
- sprintf(opt, "%s-nsamples-update", prefix);
- PI(opt, awhParams->numSamplesUpdateFreeEnergy);
- sprintf(opt, "%s-share-bias-multisim", prefix);
- PS(opt, EBOOL(awhParams->shareBiasMultisim));
- sprintf(opt, "%s-nbias", prefix);
- PI(opt, awhParams->numBias);
-
- for (k = 0; k < awhParams->numBias; k++)
- {
- sprintf(prefix, "awh%d", k + 1);
- pr_awh_bias(fp, indent, &awhParams->awhBiasParams[k], prefix);
+ PS("awh-potential", EAWHPOTENTIAL(awhParams->ePotential));
+ PI("awh-seed", awhParams->seed);
+ PI("awh-nstout", awhParams->nstOut);
+ PI("awh-nstsample", awhParams->nstSampleCoord);
+ PI("awh-nsamples-update", awhParams->numSamplesUpdateFreeEnergy);
+ PS("awh-share-bias-multisim", EBOOL(awhParams->shareBiasMultisim));
+ PI("awh-nbias", awhParams->numBias);
+
+ for (int k = 0; k < awhParams->numBias; k++)
+ {
+ auto prefix = gmx::formatString("awh%d", k + 1);
+ pr_awh_bias(fp, indent, &awhParams->awhBiasParams[k], prefix.c_str());
}
}
#include "gromacs/utility/futil.h"
#include "gromacs/utility/mutex.h"
#include "gromacs/utility/programcontext.h"
+#include "gromacs/utility/stringutil.h"
#if GMX_MPI
#include "gromacs/utility/basenetwork.h"
log_file = fp;
}
-static void default_error_handler(const char *title, const char *msg,
+static void default_error_handler(const char *title, const std::string &msg,
const char *file, int line)
{
if (log_file)
{
gmx::internal::printFatalErrorHeader(log_file, title, nullptr, file, line);
- gmx::internal::printFatalErrorMessageLine(log_file, msg, 0);
+ gmx::internal::printFatalErrorMessageLine(log_file, msg.c_str(), 0);
gmx::internal::printFatalErrorFooter(log_file);
}
gmx::internal::printFatalErrorHeader(stderr, title, nullptr, file, line);
- gmx::internal::printFatalErrorMessageLine(stderr, msg, 0);
+ gmx::internal::printFatalErrorMessageLine(stderr, msg.c_str(), 0);
gmx::internal::printFatalErrorFooter(stderr);
}
return gmx::getErrorCodeString(gmx::eeUnknownError);
}
-static void call_error_handler(const char *key, const char *file, int line, const char *msg)
+static void call_error_handler(const char *key, const char *file, int line, const std::string &msg)
{
- if (msg == nullptr)
- {
- msg = "Empty gmx_fatal message (bug).";
- }
Lock lock(error_mutex);
- gmx_error_handler(gmx_strerror(key), msg, file, line);
+ gmx_error_handler(gmx_strerror(key),
+ msg.empty() ? "Empty gmx_fatal message (bug)." : msg,
+ file, line);
}
void gmx_exit_on_fatal_error(ExitType exitType, int returnValue)
{
if (bMaster)
{
- char msg[STRLEN];
- vsprintf(msg, fmt, ap);
+ std::string msg = gmx::formatStringV(fmt, ap);
call_error_handler("fatal", file, line, msg);
}
va_end(ap);
}
-void _gmx_error(const char *key, const char *msg, const char *file, int line)
+void _gmx_error(const char *key, const std::string &msg, const char *file, int line)
{
call_error_handler(key, file, line, msg);
gmx_exit_on_fatal_error(ExitType_Abort, 1);
gmx_fatal_set_log_file(FILE *fp);
/** Function pointer type for fatal error handler callback. */
-typedef void (*gmx_error_handler_t)(const char *title, const char *msg, const char *file, int line);
+typedef void (*gmx_error_handler_t)(const char *title, const std::string &msg, const char *file, int line);
/*! \brief
* Sets an error handler for gmx_fatal() and other fatal error routines.
#define FARGS 0, __FILE__, __LINE__
/** Implementation for gmx_error(). */
-[[noreturn]] void _gmx_error(const char *key, const char *msg, const char *file, int line);
+[[noreturn]] void _gmx_error(const char *key, const std::string &msg, const char *file, int line);
/*! \brief
* Alternative fatal error routine with canned messages.
*
#include <cstdlib>
#include <cstring>
+#include <tuple>
+
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#endif
}
-int gmx_truncate(const char *filename, gmx_off_t length)
+int gmx_truncate(const std::string &filename, gmx_off_t length)
{
#if GMX_NATIVE_WINDOWS
- FILE *fp = fopen(filename, "rb+");
+ FILE *fp = fopen(filename.c_str(), "rb+");
if (fp == NULL)
{
return -1;
fclose(fp);
return rc;
#else
- return truncate(filename, length);
+ return truncate(filename.c_str(), length);
#endif
}
-static FILE *uncompress(const char *fn, const char *mode)
+static FILE *uncompress(const std::string &fn, const char *mode)
{
- FILE *fp;
- char buf[256];
-
- sprintf(buf, "uncompress -c < %s", fn);
- fprintf(stderr, "Going to execute '%s'\n", buf);
- if ((fp = popen(buf, mode)) == nullptr)
+ FILE *fp;
+ std::string buf = "uncompress -c < " + fn;
+ fprintf(stderr, "Going to execute '%s'\n", buf.c_str());
+ if ((fp = popen(buf.c_str(), mode)) == nullptr)
{
gmx_open(fn);
}
return fp;
}
-static FILE *gunzip(const char *fn, const char *mode)
+static FILE *gunzip(const std::string &fn, const char *mode)
{
- FILE *fp;
- char buf[256];
-
- sprintf(buf, "gunzip -c < %s", fn);
- fprintf(stderr, "Going to execute '%s'\n", buf);
- if ((fp = popen(buf, mode)) == nullptr)
+ FILE *fp;
+ std::string buf = "gunzip -c < ";
+ buf += fn;
+ fprintf(stderr, "Going to execute '%s'\n", buf.c_str());
+ if ((fp = popen(buf.c_str(), mode)) == nullptr)
{
gmx_open(fn);
}
return fp;
}
-gmx_bool gmx_fexist(const char *fname)
+gmx_bool gmx_fexist(const std::string &fname)
{
FILE *test;
- if (fname == nullptr)
+ if (fname.empty())
{
return FALSE;
}
- test = fopen(fname, "r");
+ test = fopen(fname.c_str(), "r");
if (test == nullptr)
{
/*Windows doesn't allow fopen of directory - so we need to check this seperately */
#if GMX_NATIVE_WINDOWS
- DWORD attr = GetFileAttributes(fname);
+ DWORD attr = GetFileAttributes(fname.c_str());
return (attr != INVALID_FILE_ATTRIBUTES) && (attr & FILE_ATTRIBUTE_DIRECTORY);
#else
return FALSE;
}
}
-static char *backup_fn(const char *file)
+static std::string backup_fn(const std::string &file)
{
- int i, count = 1;
- char *directory, *fn;
- char *buf;
+ int count = 1;
- smalloc(buf, GMX_PATH_MAX);
-
- for (i = strlen(file)-1; ((i > 0) && (file[i] != DIR_SEPARATOR)); i--)
+ std::string directory, fn, buf;
+ std::tie(directory, fn) = gmx::Path::getParentPathAndBasename(file);
+ if (directory.empty())
{
- ;
- }
- /* Must check whether i > 0, i.e. whether there is a directory
- * in the file name. In that case we overwrite the / sign with
- * a '\0' to end the directory string .
- */
- if (i > 0)
- {
- directory = gmx_strdup(file);
- directory[i] = '\0';
- fn = gmx_strdup(file+i+1);
- }
- else
- {
- directory = gmx_strdup(".");
- fn = gmx_strdup(file);
+ directory = ".";
}
do
{
- sprintf(buf, "%s/#%s.%d#", directory, fn, count);
+ buf = gmx::formatString("%s/#%s.%d#", directory.c_str(), fn.c_str(), count);
count++;
}
while ((count <= s_maxBackupCount) && gmx_fexist(buf));
* Gromacs command-line interface. */
gmx_fatal(FARGS, "Won't make more than %d backups of %s for you.\n"
"The env.var. GMX_MAXBACKUP controls this maximum, -1 disables backups.",
- s_maxBackupCount, fn);
+ s_maxBackupCount, fn.c_str());
}
- sfree(directory);
- sfree(fn);
-
return buf;
}
-void make_backup(const char *name)
+void make_backup(const std::string &name)
{
if (s_maxBackupCount <= 0)
{
}
if (gmx_fexist(name))
{
- char *backup = backup_fn(name);
- if (rename(name, backup) == 0)
+ auto backup = backup_fn(name);
+ if (rename(name.c_str(), backup.c_str()) == 0)
{
fprintf(stderr, "\nBack Off! I just backed up %s to %s\n",
- name, backup);
+ name.c_str(), backup.c_str());
}
else
{
- fprintf(stderr, "\nSorry couldn't backup %s to %s\n", name, backup);
+ fprintf(stderr, "\nSorry couldn't backup %s to %s\n", name.c_str(), backup.c_str());
}
- sfree(backup);
}
}
-FILE *gmx_ffopen(const char *file, const char *mode)
+FILE *gmx_ffopen(const std::string &file, const char *mode)
{
#ifdef SKIP_FFOPS
return fopen(file, mode);
#else
- FILE *ff = nullptr;
- char *bufsize = nullptr, *ptr;
+ FILE *ff = nullptr;
gmx_bool bRead;
int bs;
- if (file == nullptr)
+ if (file.empty())
{
return nullptr;
}
bRead = (mode[0] == 'r' && mode[1] != '+');
if (!bRead || gmx_fexist(file))
{
- if ((ff = fopen(file, mode)) == nullptr)
+ if ((ff = fopen(file.c_str(), mode)) == nullptr)
{
gmx_file(file);
}
/* Check whether we should be using buffering (default) or not
* (for debugging)
*/
+ const char *bufsize = nullptr;
if (bUnbuffered || ((bufsize = getenv("GMX_LOG_BUFFER")) != nullptr))
{
/* Check whether to use completely unbuffered */
}
else
{
+ char *ptr;
snew(ptr, bs+8);
if (setvbuf(ff, ptr, _IOFBF, bs) != 0)
{
{
std::string compressedFileName = file;
compressedFileName += ".Z";
- if (gmx_fexist(compressedFileName.c_str()))
+ if (gmx_fexist(compressedFileName))
{
- ff = uncompress(compressedFileName.c_str(), mode);
+ ff = uncompress(compressedFileName, mode);
}
else
{
compressedFileName = file;
compressedFileName += ".gz";
- if (gmx_fexist(compressedFileName.c_str()))
+ if (gmx_fexist(compressedFileName))
{
- ff = gunzip(compressedFileName.c_str(), mode);
+ ff = gunzip(compressedFileName, mode);
}
else
{
* Note that this returns `TRUE` even if \p fname is a directory instead of a
* file.
*/
-gmx_bool gmx_fexist(const char *fname);
+gmx_bool gmx_fexist(const std::string &fname);
/*! \brief
* Makes a backup of file if the file exists.
*/
-void make_backup(const char *file);
+void make_backup(const std::string &file);
/*! \brief
* Opens a file, with \Gromacs-specific additions.
* overwriting it.
* A fatal error results if the file cannot be opened, for whatever reason.
*/
-FILE *gmx_ffopen(const char *file, const char *mode);
+FILE *gmx_ffopen(const std::string &file, const char *mode);
/** Closes a file opened with gmx_ffopen(). */
int gmx_ffclose(FILE *fp);
gmx_off_t gmx_ftell(FILE *stream);
/** OS-independent truncate(). */
-int gmx_truncate(const char *filename, gmx_off_t length);
+int gmx_truncate(const std::string &filename, gmx_off_t length);
namespace gmx
{
int uid;
char userbuf[256];
char hostbuf[256];
- char timebuf[256];
/* Write a nice header for an output file */
writer->writeLine(formatString("%c", commentChar));
uid = gmx_getuid();
gmx_getusername(userbuf, 256);
gmx_gethostname(hostbuf, 256);
- gmx_format_current_time(timebuf, 256);
writer->writeLine(formatString("%c\tBy user: %s (%d)", commentChar, userbuf, uid));
writer->writeLine(formatString("%c\tOn host: %s", commentChar, hostbuf));
- writer->writeLine(formatString("%c\tAt date: %s", commentChar, timebuf));
+ writer->writeLine(formatString("%c\tAt date: %s", commentChar, gmx_format_current_time().c_str()));
writer->writeLine(formatString("%c", commentChar));
}
#include <algorithm>
#include <string>
+#include <utility>
#include <sys/stat.h>
return path.substr(0, pos);
}
+std::pair<std::string, std::string> Path::getParentPathAndBasename(const std::string &path)
+{
+ /* Expects that the path doesn't contain "." or "..". If used on a path for
+ * which this isn't guaranteed realpath needs to be called first. */
+ size_t pos = path.find_last_of(cDirSeparators);
+ if (pos == std::string::npos)
+ {
+ return std::make_pair(std::string(), path);
+ }
+ return std::make_pair(path.substr(0, pos), path.substr(pos+1));
+}
+
std::string Path::getFilename(const std::string &path)
{
size_t pos = path.find_last_of(cDirSeparators);
static std::string join(const std::string &path1,
const std::string &path2,
const std::string &path3);
+ //! Return a path using directory separators that suit the execution OS.
static std::string normalize(const std::string &path);
+ /*! \brief Returns the part of the path before the last
+ * directory separator, if any.
+ *
+ * Path must not contain '.' or '..' elements. */
static std::string getParentPath(const std::string &path);
+ /*! \brief Returns the parts of the path before and after the
+ * last directory separator, if any.
+ *
+ * Path must not contain '.' or '..' elements. */
+ static std::pair<std::string, std::string> getParentPathAndBasename(const std::string &path);
static std::string getFilename(const std::string &path);
static bool hasExtension(const std::string &path);
static std::string stripExtension(const std::string &path);
#include <cstring>
#include <ctime>
+#include <array>
+
#include <sys/types.h>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
return -1;
}
-char *
-gmx_ctime_r(const time_t *clock, char *buf, size_t len)
+std::string
+gmx_ctime_r(const time_t *clock)
{
#ifdef _MSC_VER
- /* Windows */
- ctime_s(buf, len, clock);
+ std::array<char, 1024> buf;
+ ctime_s(buf.data(), buf.size(), clock);
+ return std::string(buf.begin(), buf.end());
#elif GMX_NATIVE_WINDOWS
char *tmpbuf = ctime(clock);
- strncpy(buf, tmpbuf, len-1);
- buf[len-1] = '\0';
+ return tmpbuf;
#elif (defined(__sun))
/*Solaris*/
- ctime_r(clock, buf);
+ std::array<char, 1024> buf;
+ ctime_r(clock, buf.data());
+ return std::string(buf.begin(), buf.end());
#else
- char tmpbuf[30];
- ctime_r(clock, tmpbuf);
- strncpy(buf, tmpbuf, len-1);
- buf[len-1] = '\0';
+ std::array<char, 1024> buf;
+ ctime_r(clock, buf.data());
+ return std::string(buf.begin(), buf.end());
#endif
- return buf;
}
-void gmx_format_current_time(char *buf, size_t len)
+std::string gmx_format_current_time()
{
time_t clock = time(nullptr);
- gmx_ctime_r(&clock, buf, len);
+ return gmx_ctime_r(&clock);
}
int gmx_set_nice(int level)
#include <stddef.h>
#include <time.h>
+#include <string>
+
/*! \addtogroup module_utility
* \{
*/
/*! \brief
* Portable version of ctime_r.
*
- * Does not throw.
+ * \throws std::bad_alloc when out of memory.
*/
-char *gmx_ctime_r(const time_t *clock, char *buf, size_t len);
+std::string
+gmx_ctime_r(const time_t *clock);
/*! \brief
* Gets the current time as a string.
*
- * \param[out] buf Buffer to receive the string.
- * \param[in] len Length of buffer \p buf (26 characters should be sufficient).
- *
- * Does not throw.
+ * \throws std::bad_alloc when out of memory.
*/
-void gmx_format_current_time(char *buf, size_t len);
+std::string gmx_format_current_time();
/*! \brief
* Wrapper for nice().
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2016, by the GROMACS development team, led by
+ * Copyright (c) 2016,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.
#include "gromacs/utility/path.h"
+#include <utility>
+
#include <gtest/gtest.h>
namespace
EXPECT_STREQ("complex.dir/traj34", gmx::Path::concatenateBeforeExtension("complex.dir/traj", "34").c_str());
}
+TEST(PathTest, GetParentPathWorks)
+{
+ {
+ auto result = gmx::Path::getParentPath("");
+ EXPECT_EQ("", result);
+ }
+ {
+ auto result = gmx::Path::getParentPath("file.txt");
+ EXPECT_EQ("", result);
+ }
+ {
+ auto result = gmx::Path::getParentPath("dir/file.txt");
+ EXPECT_EQ("dir", result);
+ }
+ {
+ auto result = gmx::Path::getParentPath("windowsdir\\file.txt");
+ EXPECT_EQ("windowsdir", result);
+ }
+ {
+ auto result = gmx::Path::getParentPath("dir/anotherdir/file.txt");
+ EXPECT_EQ("dir/anotherdir", result);
+ }
+ {
+ auto result = gmx::Path::getParentPath("dir");
+ EXPECT_EQ("", result);
+ }
+ {
+ auto result = gmx::Path::getParentPath("dir/anotherdir");
+ EXPECT_EQ("dir", result);
+ }
+}
+
+TEST(PathTest, GetParentPathAndBasenameWorks)
+{
+ {
+ auto result = gmx::Path::getParentPathAndBasename("");
+ EXPECT_EQ("", std::get<0>(result));
+ EXPECT_EQ("", std::get<1>(result));
+ }
+ {
+ auto result = gmx::Path::getParentPathAndBasename("file.txt");
+ EXPECT_EQ("", std::get<0>(result));
+ EXPECT_EQ("file.txt", std::get<1>(result));
+ }
+ {
+ auto result = gmx::Path::getParentPathAndBasename("dir/file.txt");
+ EXPECT_EQ("dir", std::get<0>(result));
+ EXPECT_EQ("file.txt", std::get<1>(result));
+ }
+ {
+ auto result = gmx::Path::getParentPathAndBasename("windowsdir\\file.txt");
+ EXPECT_EQ("windowsdir", std::get<0>(result));
+ EXPECT_EQ("file.txt", std::get<1>(result));
+ }
+ {
+ auto result = gmx::Path::getParentPathAndBasename("dir/anotherdir/file.txt");
+ EXPECT_EQ("dir/anotherdir", std::get<0>(result));
+ EXPECT_EQ("file.txt", std::get<1>(result));
+ }
+ {
+ auto result = gmx::Path::getParentPathAndBasename("dir");
+ EXPECT_EQ("", std::get<0>(result));
+ EXPECT_EQ("dir", std::get<1>(result));
+ }
+ {
+ auto result = gmx::Path::getParentPathAndBasename("dir/anotherdir");
+ EXPECT_EQ("dir", std::get<0>(result));
+ EXPECT_EQ("anotherdir", std::get<1>(result));
+ }
+}
+
} // namespace