AnalysisTemplate();
virtual Options *initOptions(TrajectoryAnalysisSettings *settings);
- virtual int initAnalysis(const TopologyInformation &top);
+ virtual void initAnalysis(const TopologyInformation &top);
- virtual int startFrames(AnalysisDataParallelOptions opt,
- const SelectionCollection &selections,
- TrajectoryAnalysisModuleData **pdatap);
- virtual int analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc,
- TrajectoryAnalysisModuleData *pdata);
+ virtual TrajectoryAnalysisModuleData *startFrames(
+ AnalysisDataParallelOptions opt,
+ const SelectionCollection &selections);
+ virtual void analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc,
+ TrajectoryAnalysisModuleData *pdata);
- virtual int finishAnalysis(int nframes);
- virtual int writeOutput();
+ virtual void finishAnalysis(int nframes);
+ virtual void writeOutput();
private:
class ModuleData;
class AnalysisTemplate::ModuleData : public TrajectoryAnalysisModuleData
{
public:
- ModuleData() : _nb(NULL)
+ ModuleData(TrajectoryAnalysisModule *module,
+ AnalysisDataParallelOptions opt,
+ const SelectionCollection &selections)
+ : TrajectoryAnalysisModuleData(module, opt, selections),
+ _nb(NULL)
{
}
delete _nb;
}
- virtual int finish()
+ virtual void finish()
{
- return finishDataHandles();
+ finishDataHandles();
}
NeighborhoodSearch *_nb;
}
-int
+void
AnalysisTemplate::initAnalysis(const TopologyInformation & /*top*/)
{
_data.setColumns(_sel.size());
plotm->setYLabel("Distance (nm)");
_data.addModule(plotm);
}
- return 0;
}
-int
+TrajectoryAnalysisModuleData *
AnalysisTemplate::startFrames(AnalysisDataParallelOptions opt,
- const SelectionCollection &selections,
- TrajectoryAnalysisModuleData **pdatap)
+ const SelectionCollection &selections)
{
- *pdatap = NULL;
- ModuleData *pdata = new ModuleData();
- int rc = pdata->init(this, opt, selections);
+ ModuleData *pdata = new ModuleData(this, opt, selections);
+ int rc = NeighborhoodSearch::create(&pdata->_nb, _cutoff, _refsel->posCount());
if (rc != 0)
{
delete pdata;
- return rc;
+ // FIXME: Use exceptions in the neighborhood search API
+ GMX_THROW(InternalError("Neighborhood search initialization failed"));
}
- rc = NeighborhoodSearch::create(&pdata->_nb, _cutoff, _refsel->posCount());
- if (rc != 0)
- {
- delete pdata;
- return rc;
- }
- *pdatap = pdata;
- return rc;
+ return pdata;
}
-int
+void
AnalysisTemplate::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc,
TrajectoryAnalysisModuleData *pdata)
{
int rc = nb->init(pbc, _refsel->positions());
if (rc != 0)
{
- return rc;
+ // FIXME: Use exceptions in the neighborhood search API
+ GMX_THROW(InternalError("Neighborhood search frame initialization failed"));
}
dh->startFrame(frnr, fr.time);
for (size_t g = 0; g < _sel.size(); ++g)
dh->addPoint(g, frave);
}
dh->finishFrame();
- return 0;
}
-int
+void
AnalysisTemplate::finishAnalysis(int /*nframes*/)
{
- return 0;
}
-int
+void
AnalysisTemplate::writeOutput()
{
// We print out the average of the mean distances for each group.
fprintf(stderr, "Average mean distance for '%s': %.3f nm\n",
_sel[g]->name(), _avem->average(g));
}
- return 0;
}
/*! \brief
int
main(int argc, char *argv[])
{
- AnalysisTemplate module;
- TrajectoryAnalysisCommandLineRunner runner(&module);
- return runner.run(argc, argv);
+ try
+ {
+ AnalysisTemplate module;
+ TrajectoryAnalysisCommandLineRunner runner(&module);
+ return runner.run(argc, argv);
+ }
+ catch (std::exception &ex)
+ {
+ fprintf(stderr, "%s", gmx::formatErrorMessage(ex).c_str());
+ return 1;
+ }
}
* calls the notification functions in \p module as if the module had
* been registered to the data object when the data was added.
*/
- int presentData(AbstractAnalysisData *data,
- AnalysisDataModuleInterface *module);
+ void presentData(AbstractAnalysisData *data,
+ AnalysisDataModuleInterface *module);
//! List of modules added to the data.
ModuleList _modules;
*/
#include "gromacs/analysisdata/abstractdata.h"
-#include <cassert>
+#include <memory>
// Legacy header.
#include "smalloc.h"
-#include "gromacs/fatalerror/fatalerror.h"
+#include "gromacs/fatalerror/exceptions.h"
+#include "gromacs/fatalerror/gmxassert.h"
#include "abstractdata-impl.h"
#include "dataproxy.h"
}
-int
+void
AbstractAnalysisData::Impl::presentData(AbstractAnalysisData *data,
AnalysisDataModuleInterface *module)
{
- int rc = module->dataStarted(data);
- if (rc != 0)
- {
- return rc;
- }
+ module->dataStarted(data);
bool bCheckMissing = _bAllowMissing
&& !(module->flags() & AnalysisDataModuleInterface::efAllowMissing);
int ncol = data->columnCount();
const real *y, *dy;
const bool *present;
- rc = data->getDataWErr(i, &x, &dx, &y, &dy, &present);
- if (rc == 0)
+ if (!data->getDataWErr(i, &x, &dx, &y, &dy, &present))
{
- if (bCheckMissing && present)
+ GMX_THROW(APIError("Data not available when module added"));
+ }
+ if (bCheckMissing && present)
+ {
+ for (int j = 0; j < ncol; ++j)
{
- for (int j = 0; j < ncol; ++j)
+ if (!present[j])
{
- if (!present[j])
- {
- GMX_ERROR(eeInvalidValue,
- "Missing data not supported by a module");
- }
+ GMX_THROW(APIError("Missing data not supported by a module"));
}
}
- rc = module->frameStarted(x, dx);
- }
- if (rc == 0)
- {
- rc = module->pointsAdded(x, dx, 0, ncol, y, dy, present);
- }
- if (rc == 0)
- {
- rc = module->frameFinished();
- }
- if (rc != 0)
- {
- return rc;
}
+ module->frameStarted(x, dx);
+ module->pointsAdded(x, dx, 0, ncol, y, dy, present);
+ module->frameFinished();
}
if (!_bInData)
{
- rc = module->dataFinished();
+ module->dataFinished();
}
- return rc;
}
}
-int
+bool
AbstractAnalysisData::getData(int index, real *x, const real **y,
const bool **missing) const
{
}
-int
+bool
AbstractAnalysisData::getErrors(int index, real *dx, const real **dy) const
{
return getDataWErr(index, 0, dx, 0, dy, 0);
}
-int
+void
AbstractAnalysisData::addModule(AnalysisDataModuleInterface *module)
{
+ std::auto_ptr<AnalysisDataModuleInterface> module_ptr(module);
if ((columnCount() > 1 && !(module->flags() & AnalysisDataModuleInterface::efAllowMulticolumn))
|| (isMultipoint() && !(module->flags() & AnalysisDataModuleInterface::efAllowMultipoint))
|| (!isMultipoint() && (module->flags() & AnalysisDataModuleInterface::efOnlyMultipoint)))
{
- GMX_ERROR(eeInvalidValue,
- "Data module not compatible with data object properties");
+ GMX_THROW(APIError("Data module not compatible with data object properties"));
}
if (_impl->_bDataStart)
{
- if (_impl->_bInFrame)
- {
- GMX_ERROR(eeInvalidCall,
- "Cannot add data modules in mid-frame");
- }
- int rc = _impl->presentData(this, module);
- if (rc != 0)
- {
- return rc;
- }
+ GMX_RELEASE_ASSERT(!_impl->_bInFrame,
+ "Cannot add data modules in mid-frame");
+ _impl->presentData(this, module);
}
if (!(module->flags() & AnalysisDataModuleInterface::efAllowMissing))
{
_impl->_bAllowMissing = false;
}
_impl->_modules.push_back(module);
- return 0;
+ module_ptr.release();
}
-int
+void
AbstractAnalysisData::addColumnModule(int col, int span,
AnalysisDataModuleInterface *module)
{
- assert(col >= 0 && span >= 1 && col + span <= _ncol);
+ std::auto_ptr<AnalysisDataModuleInterface> module_ptr(module);
+ GMX_RELEASE_ASSERT(col >= 0 && span >= 1 && col + span <= _ncol,
+ "Invalid columns specified for a column module");
if (_impl->_bDataStart)
{
- GMX_ERROR(eeNotImplemented,
- "Cannot add column modules after data");
+ GMX_THROW(NotImplementedError("Cannot add column modules after data"));
}
- AnalysisDataProxy *proxy = new AnalysisDataProxy(col, span, this);
- int rc = proxy->addModule(module);
- if (rc == 0)
- {
- rc = addModule(proxy);
- }
- if (rc != 0)
- {
- delete proxy;
- }
- return rc;
+ std::auto_ptr<AnalysisDataProxy> proxy(new AnalysisDataProxy(col, span, this));
+ proxy->addModule(module_ptr.release());
+ addModule(proxy.release());
}
-int
+void
AbstractAnalysisData::applyModule(AnalysisDataModuleInterface *module)
{
if ((columnCount() > 1 && !(module->flags() & AnalysisDataModuleInterface::efAllowMulticolumn))
|| (isMultipoint() && !(module->flags() & AnalysisDataModuleInterface::efAllowMultipoint))
|| (!isMultipoint() && (module->flags() & AnalysisDataModuleInterface::efOnlyMultipoint)))
{
- GMX_ERROR(eeInvalidValue,
- "Data module not compatible with data object properties");
- }
- if (!_impl->_bDataStart || _impl->_bInData)
- {
- GMX_ERROR(eeInvalidCall,
- "Data module can only be applied to ready data");
+ GMX_THROW(APIError("Data module not compatible with data object properties"));
}
+ GMX_RELEASE_ASSERT(_impl->_bDataStart && !_impl->_bInData,
+ "Data module can only be applied to ready data");
- return _impl->presentData(this, module);
+ _impl->presentData(this, module);
}
void
AbstractAnalysisData::setColumnCount(int ncol)
{
- assert(ncol > 0);
- assert(_ncol == 0 || _impl->_modules.empty());
- assert(!_impl->_bDataStart);
+ GMX_RELEASE_ASSERT(ncol > 0, "Invalid data column count");
+ GMX_RELEASE_ASSERT(_ncol == 0 || _impl->_modules.empty(),
+ "Data column count cannot be changed after modules are added");
+ GMX_RELEASE_ASSERT(!_impl->_bDataStart,
+ "Data column count cannot be changed after data has been added");
_ncol = ncol;
}
void
AbstractAnalysisData::setMultipoint(bool multipoint)
{
- assert(_impl->_modules.empty());
- assert(!_impl->_bDataStart);
+ GMX_RELEASE_ASSERT(_impl->_modules.empty(),
+ "Data type cannot be changed after modules are added");
+ GMX_RELEASE_ASSERT(!_impl->_bDataStart,
+ "Data type cannot be changed after data has been added");
_bMultiPoint = multipoint;
}
* This method is not const because the dataStarted() methods of the attached
* modules can request storage of the data.
*/
-int
+void
AbstractAnalysisData::notifyDataStart()
{
- assert(!_impl->_bDataStart);
- assert(_ncol > 0);
+ GMX_RELEASE_ASSERT(!_impl->_bDataStart,
+ "notifyDataStart() called more than once");
+ GMX_RELEASE_ASSERT(_ncol > 0, "Data column count is not set");
_impl->_bDataStart = _impl->_bInData = true;
Impl::ModuleList::const_iterator i;
{
if (_ncol > 1 && !((*i)->flags() & AnalysisDataModuleInterface::efAllowMulticolumn))
{
- GMX_ERROR(eeInvalidValue,
- "Data module not compatible with data object properties");
- }
- int rc = (*i)->dataStarted(this);
- if (rc != 0)
- {
- return rc;
+ GMX_THROW(APIError("Data module not compatible with data object properties"));
}
+ (*i)->dataStarted(this);
}
- return 0;
}
-int
+void
AbstractAnalysisData::notifyFrameStart(real x, real dx) const
{
- assert(_impl->_bInData && !_impl->_bInFrame);
+ GMX_ASSERT(_impl->_bInData, "notifyDataStart() not called");
+ GMX_ASSERT(!_impl->_bInFrame,
+ "notifyFrameStart() called while inside a frame");
_impl->_bInFrame = true;
_impl->_currx = x;
_impl->_currdx = dx;
Impl::ModuleList::const_iterator i;
for (i = _impl->_modules.begin(); i != _impl->_modules.end(); ++i)
{
- int rc = (*i)->frameStarted(x, dx);
- if (rc != 0)
- {
- return rc;
- }
+ (*i)->frameStarted(x, dx);
}
- return 0;
}
-int
+void
AbstractAnalysisData::notifyPointsAdd(int firstcol, int n,
const real *y, const real *dy,
const bool *present) const
{
- assert(_impl->_bInData && _impl->_bInFrame);
- assert(firstcol >= 0 && n > 0 && firstcol + n <= _ncol);
+ GMX_ASSERT(_impl->_bInData, "notifyDataStart() not called");
+ GMX_ASSERT(_impl->_bInFrame, "notifyFrameStart() not called");
+ GMX_ASSERT(firstcol >= 0 && n > 0 && firstcol + n <= _ncol, "Invalid column");
if (present && !_impl->_bAllowMissing)
{
for (int i = 0; i < n; ++i)
{
if (!present[i])
{
- GMX_ERROR(eeInvalidValue,
- "Missing data not supported by a module");
+ GMX_THROW(APIError("Missing data not supported by a module"));
}
}
}
Impl::ModuleList::const_iterator i;
for (i = _impl->_modules.begin(); i != _impl->_modules.end(); ++i)
{
- int rc = (*i)->pointsAdded(_impl->_currx, _impl->_currdx, firstcol, n,
- y, dy, present);
- if (rc != 0)
- {
- return rc;
- }
+ (*i)->pointsAdded(_impl->_currx, _impl->_currdx, firstcol, n,
+ y, dy, present);
}
- return 0;
}
-int
+void
AbstractAnalysisData::notifyFrameFinish() const
{
- assert(_impl->_bInData && _impl->_bInFrame);
+ GMX_ASSERT(_impl->_bInData, "notifyDataStart() not called");
+ GMX_ASSERT(_impl->_bInFrame, "notifyFrameStart() not called");
_impl->_bInFrame = false;
Impl::ModuleList::const_iterator i;
for (i = _impl->_modules.begin(); i != _impl->_modules.end(); ++i)
{
- int rc = (*i)->frameFinished();
- if (rc != 0)
- {
- return rc;
- }
+ (*i)->frameFinished();
}
- return 0;
}
-int
+void
AbstractAnalysisData::notifyDataFinish() const
{
- assert(_impl->_bInData && !_impl->_bInFrame);
+ GMX_RELEASE_ASSERT(_impl->_bInData, "notifyDataStart() not called");
+ GMX_RELEASE_ASSERT(!_impl->_bInFrame,
+ "notifyDataFinish() called while inside a frame");
_impl->_bInData = false;
Impl::ModuleList::const_iterator i;
for (i = _impl->_modules.begin(); i != _impl->_modules.end(); ++i)
{
- int rc = (*i)->dataFinished();
- if (rc != 0)
- {
- return rc;
- }
+ (*i)->dataFinished();
}
- return 0;
}
}
-int
+bool
AbstractAnalysisDataStored::getDataWErr(int index, real *x, real *dx,
const real **y, const real **dy,
const bool **present) const
index = _impl->getStoreIndex(index);
if (index < 0)
{
- return eedataDataNotAvailable;
+ return false;
}
// Retrieve the data.
{
*present = fr->_present;
}
- return 0;
+ return true;
}
-int
+bool
AbstractAnalysisDataStored::requestStorage(int nframes)
{
- assert(nframes >= -1);
+ GMX_RELEASE_ASSERT(nframes >= -1, "Invalid number of frames requested");
if (nframes == 0)
{
- return 0;
- }
- if (isMultipoint())
- {
- GMX_ERROR(eeNotImplemented,
- "Storage of multipoint data not supported");
+ return true;
}
+ GMX_RELEASE_ASSERT(!isMultipoint(), "Storage of multipoint data not supported");
// Handle the case when everything needs to be stored.
if (nframes == -1)
{
_impl->_bStoreAll = true;
_impl->_nalloc = 1;
- return 0;
+ return true;
}
// Check whether an earier call has requested more storage.
if (_impl->_bStoreAll || nframes < _impl->_nalloc)
{
- return 0;
+ return true;
}
_impl->_nalloc = nframes;
- return 0;
+ return true;
}
void
AbstractAnalysisDataStored::setMultipoint(bool multipoint)
{
- assert(_impl->_nalloc == 0 || !multipoint);
+ GMX_RELEASE_ASSERT(_impl->_nalloc == 0 || !multipoint,
+ "Storage of multipoint data not supported");
AbstractAnalysisData::setMultipoint(multipoint);
}
-int
+void
AbstractAnalysisDataStored::startDataStore()
{
// We first notify any attached modules, because they also might request
// some storage.
- int rc = notifyDataStart();
- if (rc != 0)
- {
- return rc;
- }
+ notifyDataStart();
int ncol = columnCount();
}
_impl->_nextind = 0;
}
- return 0;
}
-int
+void
AbstractAnalysisDataStored::startNextFrame(real x, real dx)
{
// Start storing the frame if needed.
}
// Notify any modules.
- return notifyFrameStart(x, dx);
+ notifyFrameStart(x, dx);
}
-int
+void
AbstractAnalysisDataStored::storeThisFrame(const real *y, const real *dy,
const bool *present)
{
++_impl->_nframes;
// Notify modules of new data.
- int rc = notifyPointsAdd(0, ncol, y, dy, present);
+ notifyPointsAdd(0, ncol, y, dy, present);
// The index needs to be incremented after the notifications to allow
// the modules to use getData() properly.
if (_impl->_nextind >= 0)
{
++_impl->_nextind;
}
- if (rc != 0)
- {
- return rc;
- }
- return notifyFrameFinish();
+ notifyFrameFinish();
}
-int
+void
AbstractAnalysisDataStored::storeNextFrame(real x, real dx, const real *y,
const real *dy, const bool *present)
{
- int rc = startNextFrame(x, dx);
- if (rc != 0)
- {
- return rc;
- }
- return storeThisFrame(y, dy, present);
+ startNextFrame(x, dx);
+ storeThisFrame(y, dy, present);
}
} // namespace gmx
namespace gmx
{
-//! Additional error codes for functions in the analysis data module.
-enum AnalysisDataErrorCode
-{
- eedataDataNotAvailable = -1,
-};
-
class AnalysisDataModuleInterface;
/*! \libinternal \brief
* cases), and that the data provided through the public interface matches
* that passed to the modules with the notify methods.
*
+ * Currently, it is not possible to continue using the data object if an
+ * attached module throws an exception during data processing; it is only safe
+ * to destroy such data object.
+ *
+ * \todo
+ * Improve the exception-handling semantics. In most cases, it doesn't make
+ * much sense to continue data processing after one module fails, but having
+ * the alternative would not hurt.
+ *
* \inlibraryapi
* \ingroup module_analysisdata
*/
* \param[out] present Returns a pointer to an array that tells
* whether the corresponding column is present in that frame.
* If NULL, no missing information is returned.
- * \retval 0 on success.
- * \retval ::eedataDataNotAvailable if data for the requested frame is
- * no longer available (this is regarded as a normal outcome,
- * i.e., no error handlers are invoked).
- *
- * Derived classes can choose to return ::eedataDataNotAvailable if
- * requestStorage() has not been called at all, or if the frame is
- * too old (compared to the value given to requestStorage()).
+ * \retval \c false if data for the requested frame is no longer
+ * available.
+ *
+ * Derived classes can choose to return false if requestStorage() has
+ * not been called at all, or if the frame is too old (compared to the
+ * value given to requestStorage()).
+ *
+ * \todo
+ * For more flexibility, it would be better to return a data row/frame
+ * object from this method, which could then be used to access all the
+ * data for that frame.
*/
- virtual int getDataWErr(int index, real *x, real *dx,
- const real **y, const real **dy,
- const bool **present = 0) const = 0;
+ virtual bool getDataWErr(int index, real *x, real *dx,
+ const real **y, const real **dy,
+ const bool **present = 0) const = 0;
/*! \brief
* Convenience function for accessing stored data.
*
* \see getDataWErr()
*/
- int getData(int index, real *x, const real **y,
- const bool **present = 0) const;
+ bool getData(int index, real *x, const real **y,
+ const bool **present = 0) const;
/*! \brief
* Convenience function for accessing errors for stored data.
*
* \see getDataWErr()
*/
- int getErrors(int index, real *dx, const real **dy) const;
+ bool getErrors(int index, real *dx, const real **dy) const;
/*! \brief
* Request storage of frames.
*
* \param[in] nframes Request storing at least \c nframes previous
* frames (-1 = request storing all).
- * \retval 0 on success.
- * \retval eedataInvalidCall if data has already been added and
- * cannot be stored.
- * \retval eedataNotSupported if the object does not support storage.
+ * \retval true if the request could be satisfied.
*
* If called multiple times, the largest request should be honored.
*
* \see getData()
*/
- virtual int requestStorage(int nframes = -1) = 0;
+ virtual bool requestStorage(int nframes = -1) = 0;
/*! \brief
* Adds a module to process the data.
*
* \param module Module to add.
- * \retval 0 on success.
- * \retval ::eeInvalidValue if \p module is not compatible with the
- * data object.
- * \retval ::eedataDataNotAvailable if data has already been added to
- * the data object and everything is not available through
- * getData().
+ * \exception APIError if
+ * - \p module is not compatible with the data object
+ * - data has already been added to the data object and everything
+ * is not available through getData().
*
* If data has already been added to the module, the new module
- * immediately processes all existing data. ::eedataDataNotAvailable
- * is returned if all data is not available through getData().
+ * immediately processes all existing data. APIError is thrown
+ * if all data is not available through getData().
*
- * If the call successful, the data object takes ownership of the
+ * When this function is entered, the data object takes ownership of the
* module, and automatically destructs it when the data object itself
* is destroyed.
+ *
+ * \todo
+ * Provide additional semantics that does not acquire ownership of the
+ * data object.
*/
- int addModule(AnalysisDataModuleInterface *module);
+ void addModule(AnalysisDataModuleInterface *module);
/*! \brief
* Adds a module that processes only a subset of the columns.
*
* \param[in] col First column.
* \param[in] span Number of columns.
* \param module Module to add.
- * \retval 0 on success.
*
- * Can return any of the return codes for addModule().
+ * \see addModule()
*/
- int addColumnModule(int col, int span, AnalysisDataModuleInterface *module);
+ void addColumnModule(int col, int span, AnalysisDataModuleInterface *module);
/*! \brief
* Applies a module to process data that is ready.
*
* It is provided for additional flexibility in postprocessing
* in-memory data.
*/
- int applyModule(AnalysisDataModuleInterface *module);
+ void applyModule(AnalysisDataModuleInterface *module);
protected:
AbstractAnalysisData();
* notification functions. The derived class should prepare for
* requestStorage() calls from the attached modules.
*/
- int notifyDataStart();
+ void notifyDataStart();
/*! \brief
* Notifies attached modules of the start of a frame.
*
* Should be called once for each frame, before notifyPointsAdd() calls
* for thet frame.
*/
- int notifyFrameStart(real x, real dx) const;
+ void notifyFrameStart(real x, real dx) const;
/*! \brief
* Notifies attached modules of the addition of points to the
* current frame.
* even the whole frame in a single call rather than calling the method
* for each column separately.
*/
- int notifyPointsAdd(int firstcol, int n,
- const real *y, const real *dy,
- const bool *present) const;
+ void notifyPointsAdd(int firstcol, int n,
+ const real *y, const real *dy,
+ const bool *present) const;
/*! \brief
* Notifies attached modules of the end of a frame.
*
* Should be called once for each call of notifyFrameStart(), after any
* notifyPointsAdd() calls for the frame.
*/
- int notifyFrameFinish() const;
+ void notifyFrameFinish() const;
/*! \brief
* Notifies attached modules of the end of data.
*
* Should be called once, after all the other notification calls.
*/
- int notifyDataFinish() const;
+ void notifyDataFinish() const;
private:
class Impl;
virtual ~AbstractAnalysisDataStored();
virtual int frameCount() const;
- virtual int getDataWErr(int index, real *x, real *dx,
- const real **y, const real **dy,
- const bool **present = 0) const;
- virtual int requestStorage(int nframes = -1);
+ virtual bool getDataWErr(int index, real *x, real *dx,
+ const real **y, const real **dy,
+ const bool **present = 0) const;
+ virtual bool requestStorage(int nframes = -1);
protected:
AbstractAnalysisDataStored();
void setMultipoint(bool multipoint);
//! Start storing data.
- int startDataStore();
+ void startDataStore();
//! Starts storing a next frame.
- int startNextFrame(real x, real dx);
+ void startNextFrame(real x, real dx);
//! Stores the whole frame in a single call after start_next_frame().
- int storeThisFrame(const real *y, const real *dy, const bool *present);
+ void storeThisFrame(const real *y, const real *dy, const bool *present);
//! Convenience function for storing a whole frame in a single call.
- int storeNextFrame(real x, real dx, const real *y, const real *dy,
- const bool *present);
+ void storeNextFrame(real x, real dx, const real *y, const real *dy,
+ const bool *present);
private:
class Impl;
* AbstractStoredData. Otherwise, it is put into the correct location
* in \a _pending. Calls processPendingFrame() after processing \p fr.
*/
- int addPendingFrame(AnalysisDataFrame *fr);
+ void addPendingFrame(AnalysisDataFrame *fr);
/*! \brief
* Passes pending frames to base class if all earlier frames are ready.
*/
- int processPendingFrames();
+ void processPendingFrames();
//! Increments \a _pstart.
void incrementPStart();
#include "gromacs/analysisdata/analysisdata.h"
#include <algorithm>
+#include <memory>
-#include <cassert>
-
-#include "gromacs/fatalerror/fatalerror.h"
+#include "gromacs/fatalerror/exceptions.h"
+#include "gromacs/fatalerror/gmxassert.h"
#include "abstractdata-impl.h"
#include "analysisdata-impl.h"
}
-int
+void
AnalysisData::Impl::addPendingFrame(AnalysisDataFrame *fr)
{
- assert(fr->_index >= _data.frameCount());
+ GMX_ASSERT(fr->_index >= _data.frameCount(),
+ "addPendingFrame() called for too old frame");
size_t pindex = fr->_index - _data.frameCount();
if (pindex == 0)
{
- int rc;
-
// Just store our frame if it is the next one.
- rc = _data.storeNextFrame(fr->_x, fr->_dx,
- fr->_y, fr->_dy, fr->_present);
- if (rc != 0)
- {
- return rc;
- }
+ _data.storeNextFrame(fr->_x, fr->_dx, fr->_y, fr->_dy, fr->_present);
incrementPStart();
}
else
}
_pending[pindex]->_index = fr->_index;
}
- return processPendingFrames();
+ processPendingFrames();
}
-int
+void
AnalysisData::Impl::processPendingFrames()
{
while (_pending[_pstart]->_index != -1)
{
AnalysisDataFrame *fr = _pending[_pstart];
- int rc = _data.storeNextFrame(fr->_x, fr->_dx,
- fr->_y, fr->_dy, fr->_present);
- if (rc != 0)
- {
- return rc;
- }
+ _data.storeNextFrame(fr->_x, fr->_dx, fr->_y, fr->_dy, fr->_present);
fr->_index = -1;
incrementPStart();
}
- return 0;
}
void
AnalysisData::setColumns(int ncol, bool multipoint)
{
- assert(ncol > 0);
- assert(_impl->_handles.empty());
+ GMX_RELEASE_ASSERT(ncol > 0, "Number of columns must be positive");
+ GMX_RELEASE_ASSERT(_impl->_handles.empty(),
+ "Cannot change data dimensionality after creating handles");
setColumnCount(ncol);
setMultipoint(multipoint);
}
-int
-AnalysisData::startData(AnalysisDataHandle **handlep,
- AnalysisDataParallelOptions opt)
+AnalysisDataHandle *
+AnalysisData::startData(AnalysisDataParallelOptions opt)
{
if (_impl->_handles.empty())
{
- int rc = startDataStore();
- if (rc != 0)
- {
- return rc;
- }
+ startDataStore();
}
else if (isMultipoint())
{
- GMX_ERROR(eeNotImplemented,
- "Parallelism not supported for multipoint data");
+ GMX_THROW(NotImplementedError("Parallelism not supported for multipoint data"));
}
- AnalysisDataHandle *handle = new AnalysisDataHandle(this);
- _impl->_handles.push_back(handle);
- *handlep = handle;
+ std::auto_ptr<AnalysisDataHandle> handle(new AnalysisDataHandle(this));
+ _impl->_handles.push_back(handle.get());
_impl->_pending.resize(2 * _impl->_handles.size() - 1);
Impl::FrameList::iterator i;
(*i)->_index = -1;
}
- return 0;
+ return handle.release();
}
-int
+void
AnalysisData::finishData(AnalysisDataHandle *handle)
{
Impl::HandleList::iterator i;
i = std::find(_impl->_handles.begin(), _impl->_handles.end(), handle);
- assert(i != _impl->_handles.end());
+ GMX_RELEASE_ASSERT(i != _impl->_handles.end(),
+ "finishData() called for an unknown handle");
_impl->_handles.erase(i);
delete handle;
if (_impl->_handles.empty())
{
- return notifyDataFinish();
+ notifyDataFinish();
}
- return 0;
}
}
-int
+void
AnalysisDataHandle::startFrame(int index, real x, real dx)
{
if (_impl->_data.isMultipoint())
{
- return _impl->_data.notifyFrameStart(x, dx);
+ _impl->_data.notifyFrameStart(x, dx);
}
else
{
_impl->_frame->_dy[i] = 0.0;
_impl->_frame->_present[i] = false;
}
- return 0;
}
}
-int
+void
AnalysisDataHandle::addPoint(int col, real y, real dy, bool present)
{
if (_impl->_data.isMultipoint())
{
- return _impl->_data.notifyPointsAdd(col, 1, &y, &dy, &present);
+ _impl->_data.notifyPointsAdd(col, 1, &y, &dy, &present);
}
else
{
- assert(!_impl->_frame->_present[col]);
+ GMX_ASSERT(!_impl->_frame->_present[col],
+ "Data for a column set multiple times");
_impl->_frame->_y[col] = y;
_impl->_frame->_dy[col] = dy;
_impl->_frame->_present[col] = present;
- return 0;
}
}
-int
+void
AnalysisDataHandle::addPoints(int firstcol, int n,
const real *y, const real *dy,
const bool *present)
{
if (_impl->_data.isMultipoint())
{
- return _impl->_data.notifyPointsAdd(firstcol, n, y, dy, present);
+ _impl->_data.notifyPointsAdd(firstcol, n, y, dy, present);
}
else
{
addPoint(firstcol + i, y[i], dy ? dy[i] : 0.0,
present ? present[i] : true);
}
- return 0;
}
}
-int
+void
AnalysisDataHandle::finishFrame()
{
if (_impl->_data.isMultipoint())
{
- return _impl->_data.notifyFrameFinish();
+ _impl->_data.notifyFrameFinish();
}
else
{
- return _impl->_data._impl->addPendingFrame(_impl->_frame);
+ _impl->_data._impl->addPendingFrame(_impl->_frame);
}
}
-int
+void
AnalysisDataHandle::addFrame(int index, real x, const real *y, const real *dy,
const bool *present)
{
- return addFrame(index, x, 0.0, y, dy, present);
+ addFrame(index, x, 0.0, y, dy, present);
}
-int
+void
AnalysisDataHandle::addFrame(int index, real x, real dx,
const real *y, const real *dy,
const bool *present)
{
- int rc = startFrame(index, x, dx);
- if (rc == 0)
- {
- rc = addPoints(0, _impl->_data.columnCount(), y, dy, present);
- }
- if (rc == 0)
- {
- rc = finishFrame();
- }
- return rc;
+ startFrame(index, x, dx);
+ addPoints(0, _impl->_data.columnCount(), y, dy, present);
+ finishFrame();
}
-int
+void
AnalysisDataHandle::finishData()
{
// Calls delete this
- return _impl->_data.finishData(this);
+ _impl->_data.finishData(this);
}
} // namespace gmx
/*! \brief
* Create a handle for adding data.
*
- * \param[out] handlep The created handle is stored in \p *handlep.
* \param[in] opt Options for setting how this handle will be
* used.
+ * \returns The created handle.
*/
- int startData(AnalysisDataHandle **handlep,
- AnalysisDataParallelOptions opt);
+ AnalysisDataHandle *startData(AnalysisDataParallelOptions opt);
/*! \brief
* Destroy a handle after all data has been added.
*
*
* The pointer \p handle is invalid after the call.
*/
- int finishData(AnalysisDataHandle *handle);
+ void finishData(AnalysisDataHandle *handle);
private:
class Impl;
class AnalysisDataHandle
{
public:
+ /*! \brief
+ * Frees memory allocated for the internal implementation.
+ *
+ * Should not be called directly, but through finishData() or
+ * AnalysisData::finishData().
+ */
+ ~AnalysisDataHandle();
+
//! Start data for a new frame.
- int startFrame(int index, real x, real dx = 0.0);
+ void startFrame(int index, real x, real dx = 0.0);
//! Add a data point for in single column for the current frame.
- int addPoint(int col, real y, real dy = 0.0, bool present = true);
+ void addPoint(int col, real y, real dy = 0.0, bool present = true);
//! Add multiple data points in neighboring columns for the current frame.
- int addPoints(int firstcol, int n,
- const real *y, const real *dy = 0,
- const bool *present = 0);
+ void addPoints(int firstcol, int n,
+ const real *y, const real *dy = 0,
+ const bool *present = 0);
//! Finish data for the current frame.
- int finishFrame();
+ void finishFrame();
//! Convenience function for adding a complete frame.
- int addFrame(int index, real x, const real *y, const real *dy = 0,
- const bool *present = 0);
+ void addFrame(int index, real x, const real *y, const real *dy = 0,
+ const bool *present = 0);
//! Convenience function for adding a complete frame.
- int addFrame(int index, real x, real dx,
- const real *y, const real *dy = 0,
- const bool *present = 0);
+ void addFrame(int index, real x, real dx,
+ const real *y, const real *dy = 0,
+ const bool *present = 0);
//! Calls AnalysisData::finishData() for this handle.
- int finishData();
+ void finishData();
private:
/*! \brief
* constructed through AnalysisData::startData().
*/
explicit AnalysisDataHandle(AnalysisData *data);
- /*! \brief
- * Frees memory allocated for the internal implementation.
- *
- * The destructor is private because data handles should only be
- * deleted by calling AnalysisData::finishData() (or finishData()).
- */
- ~AnalysisDataHandle();
class Impl;
*/
#include "gromacs/analysisdata/arraydata.h"
-#include <cassert>
-
// Legacy header.
#include "smalloc.h"
-#include "gromacs/fatalerror/fatalerror.h"
+#include "gromacs/fatalerror/exceptions.h"
+#include "gromacs/fatalerror/gmxassert.h"
namespace gmx
{
}
-int
+bool
AbstractAnalysisArrayData::getDataWErr(int index, real *x, real *dx,
const real **y, const real **dy,
const bool **present) const
index += _nrows;
if (index < 0)
{
- GMX_ERROR(eeInvalidValue, "Frame index out of range");
+ return false;
}
}
if (index >= frameCount())
{
- GMX_ERROR(eeInvalidValue, "Frame index out of range");
+ return false;
}
- if (x)
+ if (x != NULL)
{
*x = _xstart + index * _xstep;
}
- if (dx)
+ if (dx != NULL)
{
*dx = 0.0;
}
- if (y)
+ if (y != NULL)
{
*y = _value + (index * columnCount());
}
- if (dy)
+ if (dy != NULL)
{
// TODO: Implement
*dy = NULL;
}
- if (present)
+ if (present != NULL)
{
// TODO: Implement
*present = NULL;
}
- return 0;
+ return true;
}
-int
-AbstractAnalysisArrayData::requestStorage(int nframes)
+bool
+AbstractAnalysisArrayData::requestStorage(int /*nframes*/)
{
- return 0;
+ return true;
}
void
AbstractAnalysisArrayData::setColumnCount(int ncols)
{
- assert(!_value);
+ GMX_RELEASE_ASSERT(!_value,
+ "Cannot change column count after data has been allocated");
AbstractAnalysisData::setColumnCount(ncols);
}
void
AbstractAnalysisArrayData::setRowCount(int nrows)
{
- assert(nrows > 0);
- assert(!_value && columnCount() > 0);
+ GMX_RELEASE_ASSERT(nrows > 0, "Invalid number of rows");
+ GMX_RELEASE_ASSERT(!_value,
+ "Cannot change row count after data has been allocated");
+ GMX_RELEASE_ASSERT(columnCount() > 0, "Column count must be set before row count");
_nrows = nrows;
snew(_value, _nrows * columnCount());
}
void
AbstractAnalysisArrayData::setXAxis(real start, real step)
{
- assert(!_bReady);
+ GMX_RELEASE_ASSERT(!_bReady, "X axis cannot be set after data is finished");
_xstart = start;
_xstep = step;
}
-int
+void
AbstractAnalysisArrayData::valuesReady()
{
- assert(columnCount() > 0 && _nrows > 0);
+ GMX_RELEASE_ASSERT(columnCount() > 0 && _nrows > 0 && _value,
+ "There must be some data");
if (_bReady)
{
- return 0;
+ return;
}
_bReady = true;
- int rc = notifyDataStart();
- if (rc != 0)
- {
- return rc;
- }
+ notifyDataStart();
for (int i = 0; i < _nrows; ++i)
{
- rc = notifyFrameStart(_xstart + i * _xstep, 0);
- if (rc != 0)
- {
- return rc;
- }
- rc = notifyPointsAdd(0, columnCount(), _value + (i * columnCount()),
- NULL, NULL);
- if (rc != 0)
- {
- return rc;
- }
- rc = notifyFrameFinish();
- if (rc != 0)
- {
- return rc;
- }
+ notifyFrameStart(_xstart + i * _xstep, 0);
+ notifyPointsAdd(0, columnCount(), _value + (i * columnCount()),
+ NULL, NULL);
+ notifyFrameFinish();
}
- return notifyDataFinish();
+ notifyDataFinish();
}
AbstractAnalysisArrayData::copyContents(const AbstractAnalysisArrayData *src,
AbstractAnalysisArrayData *dest)
{
- assert(src->columnCount() > 0 && src->_nrows > 0 && src->_value);
- assert(!dest->_value);
+ GMX_RELEASE_ASSERT(src->columnCount() > 0 && src->_nrows > 0 && src->_value,
+ "Source data must not be empty");
+ GMX_RELEASE_ASSERT(!dest->_value, "Destination data must not be allocated");
dest->setColumnCount(src->columnCount());
dest->setRowCount(src->_nrows);
dest->setXAxis(src->_xstart, src->_xstep);
#ifndef GMX_ANALYSISDATA_ARRAYDATA_H
#define GMX_ANALYSISDATA_ARRAYDATA_H
-#include <cassert>
+#include <cstddef>
+
+#include "../fatalerror/gmxassert.h"
#include "abstractdata.h"
virtual ~AbstractAnalysisArrayData();
virtual int frameCount() const;
- virtual int getDataWErr(int index, real *x, real *dx,
- const real **y, const real **dy,
- const bool **present = 0) const;
- virtual int requestStorage(int nframes = -1);
+ virtual bool getDataWErr(int index, real *x, real *dx,
+ const real **y, const real **dy,
+ const bool **present = 0) const;
+ virtual bool requestStorage(int nframes = -1);
protected:
AbstractAnalysisArrayData();
//! Returns a reference to a given array element.
real &value(int row, int col)
{
- assert(row >= 0 && row < _nrows);
- assert(col >= 0 && col < columnCount());
- assert(_value);
+ GMX_ASSERT(row >= 0 && row < _nrows, "Row index out of range");
+ GMX_ASSERT(col >= 0 && col < columnCount(), "Column index out of range");
+ GMX_ASSERT(_value != NULL, "Data array not allocated");
return _value[row * columnCount() + col];
}
//! Returns a given array element.
const real &value(int row, int col) const
{
- assert(row >= 0 && row < _nrows);
- assert(col >= 0 && col < columnCount());
- assert(_value);
+ GMX_ASSERT(row >= 0 && row < _nrows, "Row index out of range");
+ GMX_ASSERT(col >= 0 && col < columnCount(), "Column index out of range");
+ GMX_ASSERT(_value != NULL, "Data array not allocated");
return _value[row * columnCount() + col];
}
/*! \brief
* have been initialized. The values should not be changed after this
* function has been called.
*/
- int valuesReady();
+ void valuesReady();
/*! \brief
* Copies the contents into a new object.
* (column count, whether it's multipoint) do not change once this
* method has been called.
*/
- virtual int dataStarted(AbstractAnalysisData *data) = 0;
+ virtual void dataStarted(AbstractAnalysisData *data) = 0;
/*! \brief
* Called at the start of each data frame.
*/
- virtual int frameStarted(real x, real dx) = 0;
+ virtual void frameStarted(real x, real dx) = 0;
/*! \brief
* Called one or more times during each data frame.
*
* For convenience, the \p x and \p dx values for the frame are
* passed to each call of this function.
+ *
+ * \todo
+ * For more flexibility, this function should take a data row/frame
+ * object, which could be used to access all relevant data.
*/
- virtual int pointsAdded(real x, real dx, int firstcol, int n,
- const real *y, const real *dy,
- const bool *present) = 0;
+ virtual void pointsAdded(real x, real dx, int firstcol, int n,
+ const real *y, const real *dy,
+ const bool *present) = 0;
/*! \brief
* Called when a data frame is finished.
*/
- virtual int frameFinished() = 0;
+ virtual void frameFinished() = 0;
/*! \brief
* Called (once) when no more data is available.
*/
- virtual int dataFinished() = 0;
+ virtual void dataFinished() = 0;
protected:
AnalysisDataModuleInterface() {}
*/
#include "dataproxy.h"
-#include <cassert>
+#include "gromacs/fatalerror/gmxassert.h"
namespace gmx
{
AbstractAnalysisData *data)
: _source(*data), _col(col), _span(span)
{
- assert(data);
- assert(col >= 0 && span > 0);
+ GMX_RELEASE_ASSERT(data, "Source data must not be NULL");
+ GMX_RELEASE_ASSERT(col >= 0 && span > 0, "Invalid proxy column");
setColumnCount(span);
setMultipoint(_source.isMultipoint());
}
}
-int
+bool
AnalysisDataProxy::getDataWErr(int index, real *x, real *dx,
const real **y, const real **dy,
const bool **missing) const
{
- int rc = _source.getDataWErr(index, x, dx, y, dy, missing);
- if (rc == 0)
+ bool bExists = _source.getDataWErr(index, x, dx, y, dy, missing);
+ if (bExists)
{
if (y && *y)
{
*missing += _col;
}
}
- return rc;
+ return bExists;
}
-int
+bool
AnalysisDataProxy::requestStorage(int nframes)
{
return _source.requestStorage(nframes);
}
-int
+void
AnalysisDataProxy::dataStarted(AbstractAnalysisData *data)
{
- assert(data == &_source);
- assert(_col + _span <= _source.columnCount());
- return notifyDataStart();
+ GMX_RELEASE_ASSERT(data == &_source, "Source data mismatch");
+ GMX_RELEASE_ASSERT(_col + _span <= _source.columnCount(),
+ "Invalid column(s) specified");
+ notifyDataStart();
}
-int
+void
AnalysisDataProxy::frameStarted(real x, real dx)
{
- return notifyFrameStart(x, dx);
+ notifyFrameStart(x, dx);
}
-int
+void
AnalysisDataProxy::pointsAdded(real x, real dx, int firstcol, int n,
const real *y, const real *dy,
const bool *missing)
{
if (firstcol + n <= _col || firstcol >= _col + _span)
{
- return 0;
+ return;
}
firstcol -= _col;
if (firstcol < 0)
{
n = _span - firstcol;
}
- return notifyPointsAdd(firstcol, n, y, dy, missing);
+ notifyPointsAdd(firstcol, n, y, dy, missing);
}
-int
+void
AnalysisDataProxy::frameFinished()
{
- return notifyFrameFinish();
+ notifyFrameFinish();
}
-int
+void
AnalysisDataProxy::dataFinished()
{
- return notifyDataFinish();
+ notifyDataFinish();
}
} // namespace gmx
AnalysisDataProxy(int col, int span, AbstractAnalysisData *data);
virtual int frameCount() const;
- virtual int getDataWErr(int index, real *x, real *dx,
- const real **y, const real **dy,
- const bool **missing = 0) const;
- virtual int requestStorage(int nframes = -1);
+ virtual bool getDataWErr(int index, real *x, real *dx,
+ const real **y, const real **dy,
+ const bool **missing = 0) const;
+ virtual bool requestStorage(int nframes = -1);
virtual int flags() const;
- virtual int dataStarted(AbstractAnalysisData *data);
- virtual int frameStarted(real x, real dx);
- virtual int pointsAdded(real x, real dx, int firstcol, int n,
- const real *y, const real *dy,
- const bool *missing);
- virtual int frameFinished();
- virtual int dataFinished();
+ virtual void dataStarted(AbstractAnalysisData *data);
+ virtual void frameStarted(real x, real dx);
+ virtual void pointsAdded(real x, real dx, int firstcol, int n,
+ const real *y, const real *dy,
+ const bool *missing);
+ virtual void frameFinished();
+ virtual void dataFinished();
private:
AbstractAnalysisData &_source;
}
-int
+void
AnalysisDataAverageModule::dataStarted(AbstractAnalysisData *data)
{
int nrows = data->columnCount();
setRowCount(nrows);
snew(_nsamples, nrows);
- return 0;
}
-int
+void
AnalysisDataAverageModule::frameStarted(real x, real dx)
{
- return 0;
}
-int
+void
AnalysisDataAverageModule::pointsAdded(real x, real dx, int firstcol, int n,
const real *y, const real *dy,
const bool *present)
_nsamples[firstcol + i] += 1;
}
}
- return 0;
}
-int
+void
AnalysisDataAverageModule::frameFinished()
{
- return 0;
}
-int
+void
AnalysisDataAverageModule::dataFinished()
{
for (int i = 0; i < rowCount(); ++i)
setValue(i, 0, ave);
setValue(i, 1, std);
}
- return valuesReady();
+ valuesReady();
}
virtual int flags() const;
- virtual int dataStarted(AbstractAnalysisData *data);
- virtual int frameStarted(real x, real dx);
- virtual int pointsAdded(real x, real dx, int firstcol, int n,
- const real *y, const real *dy,
- const bool *present);
- virtual int frameFinished();
- virtual int dataFinished();
+ virtual void dataStarted(AbstractAnalysisData *data);
+ virtual void frameStarted(real x, real dx);
+ virtual void pointsAdded(real x, real dx, int firstcol, int n,
+ const real *y, const real *dy,
+ const bool *present);
+ virtual void frameFinished();
+ virtual void dataFinished();
//! Convenience access to the average of a data column.
real average(int index) const;
#include "gromacs/analysisdata/modules/histogram.h"
#include "gromacs/basicmath.h"
-#include "gromacs/fatalerror/fatalerror.h"
+#include "gromacs/fatalerror/exceptions.h"
+#include "gromacs/fatalerror/gmxassert.h"
#include "displacement-impl.h"
}
-int
+void
AnalysisDataDisplacementModule::setMSDHistogram(AnalysisDataBinAverageModule *histm)
{
- assert(!_impl->histm);
+ GMX_RELEASE_ASSERT(!_impl->histm, "Can only set MSD histogram once");
_impl->histm = histm;
histm->setIgnoreMissing(true);
- return addModule(histm);
+ addModule(histm);
}
}
-int
+bool
AnalysisDataDisplacementModule::getDataWErr(int index, real *x, real *dx,
const real **y, const real **dy,
const bool **present) const
{
- return eedataDataNotAvailable;
+ return false;
}
-int
+bool
AnalysisDataDisplacementModule::requestStorage(int nframes)
{
- GMX_ERROR(eeNotImplemented, "Displacement storage not supported");
+ return false;
}
}
-int
+void
AnalysisDataDisplacementModule::dataStarted(AbstractAnalysisData *data)
{
if (data->columnCount() % _impl->ndim != 0)
{
- GMX_ERROR(eeInvalidValue, "Data has incorrect number of columns");
+ GMX_THROW(APIError("Data has incorrect number of columns"));
}
_impl->nmax = data->columnCount();
snew(_impl->oldval, _impl->nmax);
int ncol = _impl->nmax / _impl->ndim + 1;
snew(_impl->currd, ncol);
setColumnCount(ncol);
-
- return 0;
}
-int
+void
AnalysisDataDisplacementModule::frameStarted(real x, real dx)
{
// Initialize times.
_impl->dt = x - _impl->t0;
if (_impl->dt < 0 || gmx_within_tol(_impl->dt, 0.0, GMX_REAL_EPS))
{
- GMX_ERROR(eeInvalidInput, "Identical or decreasing frame times");
+ GMX_THROW(APIError("Identical or decreasing frame times"));
}
}
else
{
if (!gmx_within_tol(x - _impl->t, _impl->dt, GMX_REAL_EPS))
{
- GMX_ERROR(eeInvalidInput, "Frames not evenly spaced");
+ GMX_THROW(APIError("Frames not evenly spaced"));
}
}
_impl->t = x;
*/
_impl->nstored++;
_impl->bFirst = false;
- return 0;
}
-int
+void
AnalysisDataDisplacementModule::pointsAdded(real x, real dx, int firstcol, int n,
const real *y, const real *dy,
const bool *present)
{
if (firstcol % _impl->ndim != 0 || n % _impl->ndim != 0)
{
- GMX_ERROR(eeInvalidValue, "Partial data points");
+ GMX_THROW(APIError("Partial data points"));
}
for (int i = firstcol; i < firstcol + n; ++i)
{
_impl->oldval[_impl->ci + i] = y[i];
}
- return 0;
}
-int
+void
AnalysisDataDisplacementModule::frameFinished()
{
if (_impl->nstored <= 1)
{
- return 0;
+ return;
}
int step, i;
_impl->histm->initNBins(0, _impl->dt,
_impl->max_store / _impl->nmax, true);
}
- rc = notifyDataStart();
- if (rc != 0)
- {
- _impl->nstored = 1;
- return rc;
- }
- }
- rc = notifyFrameStart(_impl->t, 0);
- if (rc != 0)
- {
- return rc;
+ notifyDataStart();
}
+ notifyFrameStart(_impl->t, 0);
for (i = _impl->ci - _impl->nmax, step = 1;
step < _impl->nstored && i != _impl->ci;
}
_impl->currd[k] = dist2;
}
- rc = notifyPointsAdd(0, k, _impl->currd, NULL, NULL);
- if (rc != 0)
- {
- return rc;
- }
+ notifyPointsAdd(0, k, _impl->currd, NULL, NULL);
}
- return notifyFrameFinish();
+ notifyFrameFinish();
}
-int
+void
AnalysisDataDisplacementModule::dataFinished()
{
if (_impl->nstored >= 2)
{
- return notifyDataFinish();
+ notifyDataFinish();
}
- return 0;
}
} // namespace gmx
*
* If this function is not called, no histogram is calculated.
*/
- int setMSDHistogram(AnalysisDataBinAverageModule *histm);
+ void setMSDHistogram(AnalysisDataBinAverageModule *histm);
virtual int frameCount() const;
- virtual int getDataWErr(int index, real *x, real *dx,
- const real **y, const real **dy,
- const bool **present = 0) const;
- virtual int requestStorage(int nframes = -1);
+ virtual bool getDataWErr(int index, real *x, real *dx,
+ const real **y, const real **dy,
+ const bool **present = 0) const;
+ virtual bool requestStorage(int nframes = -1);
virtual int flags() const;
- virtual int dataStarted(AbstractAnalysisData *data);
- virtual int frameStarted(real x, real dx);
- virtual int pointsAdded(real x, real dx, int firstcol, int n,
- const real *y, const real *dy,
- const bool *present);
- virtual int frameFinished();
- virtual int dataFinished();
+ virtual void dataStarted(AbstractAnalysisData *data);
+ virtual void frameStarted(real x, real dx);
+ virtual void pointsAdded(real x, real dx, int firstcol, int n,
+ const real *y, const real *dy,
+ const bool *present);
+ virtual void frameFinished();
+ virtual void dataFinished();
private:
class Impl;
#include <config.h>
#endif
-#include <cassert>
#include <cmath>
+#include <memory>
+
// Legacy include.
#include "smalloc.h"
#include "gromacs/basicmath.h"
-#include "gromacs/fatalerror/fatalerror.h"
+#include "gromacs/fatalerror/exceptions.h"
+#include "gromacs/fatalerror/gmxassert.h"
namespace gmx
{
}
-int
+void
AbstractHistogramModule::initNBins(real miny, real binw, int nbins,
bool bIntegerBins)
{
- assert(nbins > 0 && binw > 0);
+ GMX_RELEASE_ASSERT(nbins > 0 && binw > 0, "Invalid histogram parameters");
if (bIntegerBins)
{
miny -= 0.5*binw;
_maxy = miny + nbins * binw;
_invbw = 1.0/binw;
setColumnCount(_nbins);
- return 0;
}
-int
+void
AbstractHistogramModule::initRange(real miny, real maxy, real binw,
bool bIntegerBins)
{
- assert(miny < maxy && binw > 0);
+ GMX_RELEASE_ASSERT(miny < maxy && binw > 0, "Invalid histogram parameters");
if (bIntegerBins)
{
_nbins = (int)ceil((maxy - miny) / binw) + 1;
_binwidth = binw;
_invbw = 1.0/binw;
setColumnCount(_nbins);
- return 0;
}
}
-int
+void
AbstractHistogramModule::dataStarted(AbstractAnalysisData *data)
{
if (!_averager)
}
_averager->setXAxis(_miny + 0.5 * _binwidth, _binwidth);
snew(_hist, nbins());
- return startDataStore();
+ startDataStore();
}
-int
+void
AbstractHistogramModule::frameStarted(real x, real dx)
{
for (int i = 0; i < nbins(); ++i)
{
_hist[i] = 0.0;
}
- return startNextFrame(x, dx);
+ startNextFrame(x, dx);
}
-int
+void
AbstractHistogramModule::frameFinished()
{
- return storeThisFrame(_hist, NULL, NULL);
+ storeThisFrame(_hist, NULL, NULL);
}
-int
+void
AbstractHistogramModule::dataFinished()
{
- return notifyDataFinish();
+ notifyDataFinish();
}
}
-int
+void
HistogramAverageModule::dataStarted(AbstractAnalysisData *data)
{
setRowCount(data->columnCount());
- return 0;
}
-int
-HistogramAverageModule::frameStarted(real x, real dx)
+void
+HistogramAverageModule::frameStarted(real /*x*/, real /*dx*/)
{
- return 0;
}
-int
+void
HistogramAverageModule::pointsAdded(real x, real dx, int firstcol, int n,
const real *y, const real *dy,
const bool *present)
}
if (_bIgnoreMissing)
{
- assert(present != NULL);
+ GMX_ASSERT(present != NULL, "Required data not available");
for (int i = 0; i < n; ++i)
{
if (present[i])
}
}
}
- return 0;
}
-int
+void
HistogramAverageModule::frameFinished()
{
++_nframes;
- return 0;
}
-int
+void
HistogramAverageModule::dataFinished()
{
for (int i = 0; i < rowCount(); ++i)
setValue(i, 0, ave);
setValue(i, 1, std);
}
- return 0;
}
HistogramAverageModule *
HistogramAverageModule::resampleDoubleBinWidth(bool bIntegerBins) const
{
- HistogramAverageModule *dest = new HistogramAverageModule();
+ std::auto_ptr<HistogramAverageModule> dest(new HistogramAverageModule());
int nbins = rowCount() / 2;
dest->setRowCount(nbins);
real minx = xstart() + xstep() / 2;
dest->setValue(i, 0, v);
dest->setValue(i, 1, ve);
}
- return dest;
+ return dest.release();
}
HistogramAverageModule *
HistogramAverageModule::clone() const
{
- HistogramAverageModule *dest = new HistogramAverageModule();
- copyContents(this, dest);
- return dest;
+ std::auto_ptr<HistogramAverageModule> dest(new HistogramAverageModule());
+ copyContents(this, dest.get());
+ return dest.release();
}
* AnalysisDataSimpleHistogramModule
*/
-int
+void
AnalysisDataSimpleHistogramModule::pointsAdded(real /*x*/, real /*dx*/,
int /*firstcol*/, int n,
const real *y, const real * /*dy*/,
int bin = findBin(y[i]);
_hist[bin] += 1;
}
- return 0;
}
}
-int
+void
AnalysisDataWeightedHistogramModule::pointsAdded(real x, real dx, int firstcol, int n,
const real *y, const real *dy,
const bool *present)
{
if (firstcol != 0 || n < 2)
{
- GMX_ERROR(eeInvalidValue, "Invalid data layout");
+ GMX_THROW(APIError("Invalid data layout"));
}
int bin = findBin(y[0]);
for (int i = 1; i < n; ++i)
{
_hist[bin] += y[i];
}
- return 0;
}
AnalysisDataBinAverageModule::setIgnoreMissing(bool bIgnoreMissing)
{
// Changes can only be made before there is data.
- assert(!_n);
+ GMX_RELEASE_ASSERT(_n == NULL, "Cannot make changes after data is allocated");
_bIgnoreMissing = bIgnoreMissing;
averager()->setIgnoreMissing(bIgnoreMissing);
}
}
-int
+void
AnalysisDataBinAverageModule::dataStarted(AbstractAnalysisData *data)
{
snew(_n, nbins());
snew(_present, nbins());
- return AbstractHistogramModule::dataStarted(data);
+ AbstractHistogramModule::dataStarted(data);
}
-int
+void
AnalysisDataBinAverageModule::frameStarted(real x, real dx)
{
for (int i = 0; i < nbins(); ++i)
{
_n[i] = 0;
}
- return AbstractHistogramModule::frameStarted(x, dx);
+ AbstractHistogramModule::frameStarted(x, dx);
}
-int
+void
AnalysisDataBinAverageModule::pointsAdded(real x, real dx, int firstcol, int n,
const real *y, const real *dy,
const bool *present)
{
if (firstcol != 0 || n < 2)
{
- GMX_ERROR(eeInvalidValue, "Invalid data layout");
+ GMX_THROW(APIError("Invalid data layout"));
}
int bin = findBin(y[0]);
for (int i = 1; i < n; ++i)
_hist[bin] += y[i];
}
_n[bin] += n - 1;
- return 0;
}
-int
+void
AnalysisDataBinAverageModule::frameFinished()
{
for (int i = 0; i < nbins(); ++i)
}
if (!_bIgnoreMissing)
{
- return AbstractHistogramModule::frameFinished();
+ AbstractHistogramModule::frameFinished();
}
- return storeThisFrame(_hist, NULL, _present);
+ storeThisFrame(_hist, NULL, _present);
}
} // namespace gmx
/*! \brief
* Initializes the histogram using bin width and the number of bins.
*/
- int initNBins(real miny, real binw, int nbins,
- bool bIntegerBins = false);
+ void initNBins(real miny, real binw, int nbins,
+ bool bIntegerBins = false);
/*! \brief
* Initializes the histogram using a range and a bin width.
*/
- int initRange(real miny, real maxy, real binw,
- bool bIntegerBins = false);
+ void initRange(real miny, real maxy, real binw,
+ bool bIntegerBins = false);
/*! \brief
* Sets the histogram to match all values.
*
virtual int flags() const;
- virtual int dataStarted(AbstractAnalysisData *data);
- virtual int frameStarted(real x, real dx);
- virtual int pointsAdded(real x, real dx, int firstcol, int n,
- const real *y, const real *dy,
- const bool *present) = 0;
- virtual int frameFinished();
- virtual int dataFinished();
+ virtual void dataStarted(AbstractAnalysisData *data);
+ virtual void frameStarted(real x, real dx);
+ virtual void pointsAdded(real x, real dx, int firstcol, int n,
+ const real *y, const real *dy,
+ const bool *present) = 0;
+ virtual void frameFinished();
+ virtual void dataFinished();
protected:
AbstractHistogramModule();
public:
virtual int flags() const;
- virtual int dataStarted(AbstractAnalysisData *data);
- virtual int frameStarted(real x, real dx);
- virtual int pointsAdded(real x, real dx, int firstcol, int n,
- const real *y, const real *dy,
- const bool *present);
- virtual int frameFinished();
- virtual int dataFinished();
+ virtual void dataStarted(AbstractAnalysisData *data);
+ virtual void frameStarted(real x, real dx);
+ virtual void pointsAdded(real x, real dx, int firstcol, int n,
+ const real *y, const real *dy,
+ const bool *present);
+ virtual void frameFinished();
+ virtual void dataFinished();
/*! \brief
* Sets the averager to ignore missing values.
* After this function has been called, it is no longer possible to
* alter the histogram.
*/
- int done() { return AbstractAnalysisArrayData::valuesReady(); }
+ void done() { AbstractAnalysisArrayData::valuesReady(); }
private:
HistogramAverageModule();
class AnalysisDataSimpleHistogramModule : public AbstractHistogramModule
{
public:
- virtual int pointsAdded(real x, real dx, int firstcol, int n,
- const real *y, const real *dy,
- const bool *present);
+ virtual void pointsAdded(real x, real dx, int firstcol, int n,
+ const real *y, const real *dy,
+ const bool *present);
// Copy and assign disallowed by base.
};
public:
virtual int flags() const;
- virtual int pointsAdded(real x, real dx, int firstcol, int n,
- const real *y, const real *dy,
- const bool *present);
+ virtual void pointsAdded(real x, real dx, int firstcol, int n,
+ const real *y, const real *dy,
+ const bool *present);
// Copy and assign disallowed by base.
};
virtual int flags() const;
- virtual int dataStarted(AbstractAnalysisData *data);
- virtual int frameStarted(real x, real dx);
- virtual int pointsAdded(real x, real dx, int firstcol, int n,
- const real *y, const real *dy,
- const bool *present);
- virtual int frameFinished();
+ virtual void dataStarted(AbstractAnalysisData *data);
+ virtual void frameStarted(real x, real dx);
+ virtual void pointsAdded(real x, real dx, int firstcol, int n,
+ const real *y, const real *dy,
+ const bool *present);
+ virtual void frameFinished();
private:
int *_n;
#include <string>
#include <vector>
-#include <cassert>
#include <cstdio>
#include <cstring>
#include <vec.h>
#include <xvgr.h>
+// FIXME: This kind of trickery should not be necessary...
+#undef min
+#undef max
#include "gromacs/options/globalproperties.h"
#include "gromacs/options/options.h"
-#include "gromacs/fatalerror/fatalerror.h"
+#include "gromacs/fatalerror/exceptions.h"
+#include "gromacs/fatalerror/gmxassert.h"
#include "gromacs/selection/selectioncollection.h"
#include "plot-impl.h"
void
AbstractPlotModule::Impl::closeFile()
{
- if (fp)
+ if (fp != NULL)
{
if (bPlain)
{
void
AbstractPlotModule::setXFormat(int width, int prec, char fmt)
{
- assert(width >= 0 && prec >= 0 && width <= 99 && prec <= 99);
- assert(strchr("eEfFgG", fmt) != NULL);
+ GMX_RELEASE_ASSERT(width >= 0 && prec >= 0 && width <= 99 && prec <= 99,
+ "Invalid width or precision");
+ GMX_RELEASE_ASSERT(strchr("eEfFgG", fmt) != NULL,
+ "Invalid format specifier");
sprintf(_impl->xfmt, "%%%d.%d%c", width, prec, fmt);
}
void
AbstractPlotModule::setYFormat(int width, int prec, char fmt)
{
- assert(width >= 0 && prec >= 0 && width <= 99 && prec <= 99);
- assert(strchr("eEfFgG", fmt) != NULL);
+ GMX_RELEASE_ASSERT(width >= 0 && prec >= 0 && width <= 99 && prec <= 99,
+ "Invalid width or precision");
+ GMX_RELEASE_ASSERT(strchr("eEfFgG", fmt) != NULL,
+ "Invalid format specifier");
sprintf(_impl->yfmt, " %%%d.%d%c", width, prec, fmt);
}
}
-int
+void
AbstractPlotModule::dataStarted(AbstractAnalysisData *data)
{
if (!_impl->fnm.empty())
}
}
}
-
- return 0;
}
-int
+void
AbstractPlotModule::frameStarted(real x, real dx)
{
if (!isFileOpen())
{
- return 0;
+ return;
}
if (!_impl->bOmitX)
{
std::fprintf(_impl->fp, _impl->xfmt, x);
}
- return 0;
}
-int
+void
AbstractPlotModule::frameFinished()
{
if (!isFileOpen())
{
- return 0;
+ return;
}
std::fprintf(_impl->fp, "\n");
- return 0;
}
-int
+void
AbstractPlotModule::dataFinished()
{
_impl->closeFile();
- return 0;
}
void
AbstractPlotModule::writeValue(real value) const
{
- assert(isFileOpen());
+ GMX_ASSERT(isFileOpen(), "File not opened, but write attempted");
std::fprintf(_impl->fp, _impl->yfmt, value);
}
}
-int
+void
AnalysisDataPlotModule::pointsAdded(real x, real dx, int firstcol, int n,
const real *y, const real *dy,
const bool *present)
{
if (!isFileOpen())
{
- return 0;
+ return;
}
for (int i = 0; i < n; ++i)
{
writeValue(y[i]);
}
- return 0;
}
void
-AnalysisDataVectorPlotModule::setWriteMask(bool bWrite[4])
+AnalysisDataVectorPlotModule::setWriteMask(bool bWrite[DIM + 1])
{
for (int i = 0; i < DIM + 1; ++i)
{
}
-int
+void
AnalysisDataVectorPlotModule::pointsAdded(real x, real dx, int firstcol, int n,
const real *y, const real *dy,
const bool *present)
{
if (firstcol % DIM != 0)
{
- GMX_ERROR(eeInvalidValue, "Partial data points");
+ GMX_THROW(APIError("Partial data points"));
}
if (!isFileOpen())
{
- return 0;
+ return;
}
for (int i = 0; i < n; i += 3)
{
writeValue(norm(&y[i]));
}
}
- return 0;
}
} // namespace gmx
virtual int flags() const;
- virtual int dataStarted(AbstractAnalysisData *data);
- virtual int frameStarted(real x, real dx);
- virtual int pointsAdded(real x, real dx, int firstcol, int n,
- const real *y, const real *dy,
- const bool *present) = 0;
- virtual int frameFinished();
- virtual int dataFinished();
+ virtual void dataStarted(AbstractAnalysisData *data);
+ virtual void frameStarted(real x, real dx);
+ virtual void pointsAdded(real x, real dx, int firstcol, int n,
+ const real *y, const real *dy,
+ const bool *present) = 0;
+ virtual void frameFinished();
+ virtual void dataFinished();
protected:
explicit AbstractPlotModule(const Options &options);
public:
explicit AnalysisDataPlotModule(const Options &options);
- virtual int pointsAdded(real x, real dx, int firstcol, int n,
- const real *y, const real *dy,
- const bool *present);
+ virtual void pointsAdded(real x, real dx, int firstcol, int n,
+ const real *y, const real *dy,
+ const bool *present);
// Copy and assign disallowed by base.
};
void setWriteNorm(bool bWrite);
void setWriteMask(bool bWrite[4]);
- virtual int pointsAdded(real x, real dx, int firstcol, int n,
- const real *y, const real *dy,
- const bool *present);
+ virtual void pointsAdded(real x, real dx, int firstcol, int n,
+ const real *y, const real *dy,
+ const bool *present);
private:
bool _bWrite[4];
*/
#include "gromacs/options/abstractoption.h"
-#include <cassert>
-
-#include "gromacs/errorreporting/abstracterrorreporter.h"
-#include "gromacs/fatalerror/fatalerror.h"
+#include "gromacs/fatalerror/exceptions.h"
+#include "gromacs/fatalerror/gmxassert.h"
#include "gromacs/options/abstractoptionstorage.h"
#include "gromacs/options/optionflags.h"
* AbstractOptionStorage
*/
-AbstractOptionStorage::AbstractOptionStorage()
- : _minValueCount(0), _maxValueCount(0), _currentValueCount(-1),
- _options(NULL)
-{
-}
-
-AbstractOptionStorage::~AbstractOptionStorage()
-{
-}
-
-int AbstractOptionStorage::init(const AbstractOption &settings,
- Options *options)
+AbstractOptionStorage::AbstractOptionStorage(const AbstractOption &settings,
+ Options *options,
+ OptionFlags staticFlags)
+ : _flags(settings._flags | staticFlags),
+ _minValueCount(settings._minValueCount),
+ _maxValueCount(settings._maxValueCount),
+ _currentValueCount(-1),
+ _options(options)
{
- // We add user-provided flags to the ones possibly set by the subclass.
- _flags |= settings._flags;
- _minValueCount = settings._minValueCount;
- _maxValueCount = settings._maxValueCount;
- _options = options;
-
// If the maximum number of values is not known, storage to
// caller-allocated memory is unsafe.
if ((_maxValueCount < 0 || hasFlag(efMulti)) && hasFlag(efExternalStore))
{
- GMX_ERROR(eeInvalidValue,
- "Cannot set user-allocated storage for arbitrary number of values");
+ GMX_THROW(APIError("Cannot set user-allocated storage for arbitrary number of values"));
}
// Check that user has not provided incorrect values for vectors.
if (hasFlag(efVector) && (_minValueCount > 1 || _maxValueCount < 1))
{
- GMX_ERROR(eeInvalidValue,
- "Inconsistent value counts for vector values");
+ GMX_THROW(APIError("Inconsistent value counts for vector values"));
}
if (settings._name != NULL)
_name = settings._name;
}
_descr = settings.createDescription();
+}
- return 0;
+AbstractOptionStorage::~AbstractOptionStorage()
+{
}
-int AbstractOptionStorage::startSource()
+void AbstractOptionStorage::startSource()
{
setFlag(efHasDefaultValue);
- return 0;
}
-int AbstractOptionStorage::startSet(AbstractErrorReporter *errors)
+void AbstractOptionStorage::startSet()
{
if (hasFlag(efHasDefaultValue))
{
}
else if (isSet() && !hasFlag(efMulti))
{
- errors->error("Option specified multiple times");
- return eeInvalidInput;
+ GMX_THROW(InvalidInputError("Option specified multiple times"));
}
_currentValueCount = 0;
- return 0;
}
-int AbstractOptionStorage::appendValue(const std::string &value,
- AbstractErrorReporter *errors)
+void AbstractOptionStorage::appendValue(const std::string &value)
{
- assert(_currentValueCount >= 0);
+ GMX_RELEASE_ASSERT(_currentValueCount >= 0, "startSet() not called");
if (!hasFlag(efConversionMayNotAddValues) && _maxValueCount >= 0
&& _currentValueCount >= _maxValueCount)
{
- errors->warning("Ignoring extra value: " + value);
- return eeInvalidInput;
+ GMX_THROW(InvalidInputError("Ignoring extra value: " + value));
}
- return convertValue(value, errors);
+ convertValue(value);
}
-int AbstractOptionStorage::finishSet(AbstractErrorReporter *errors)
+class CurrentCountClearer
{
- assert(_currentValueCount >= 0);
+ public:
+ explicit CurrentCountClearer(int *currentValueCount)
+ : value_(currentValueCount)
+ {
+ }
+ ~CurrentCountClearer()
+ {
+ *value_ = -1;
+ }
+
+ private:
+ int *value_;
+};
+
+void AbstractOptionStorage::finishSet()
+{
+ GMX_RELEASE_ASSERT(_currentValueCount >= 0, "startSet() not called");
setFlag(efSet);
- // TODO: Remove invalid values if there are too few
- int rc = processSet(_currentValueCount, errors);
+
+ CurrentCountClearer clearOnExit(&_currentValueCount);
+ // TODO: Remove invalid values
+ processSet(_currentValueCount);
+ // TODO: Should this also be checked if processSet throws?
if (!hasFlag(efDontCheckMinimumCount)
&& _currentValueCount < _minValueCount)
{
- errors->error("Too few (valid) values");
- rc = eeInvalidInput;
+ GMX_THROW(InvalidInputError("Too few (valid) values"));
}
- _currentValueCount = -1;
- return rc;
}
-int AbstractOptionStorage::finish(AbstractErrorReporter *errors)
+void AbstractOptionStorage::finish()
{
- assert(_currentValueCount == -1);
- int rc = processAll(errors);
+ GMX_RELEASE_ASSERT(_currentValueCount == -1, "finishSet() not called");
+ processAll();
+ // TODO: Should this also be checked if processAll throws?
if (hasFlag(efRequired) && !isSet())
{
- errors->error("Required option '" + _name + "' not set");
- rc = eeInconsistentInput;
+ GMX_THROW(InvalidInputError("Option is required, but not set"));
}
- return rc;
}
-int AbstractOptionStorage::setMinValueCount(int count,
- AbstractErrorReporter *errors)
+void AbstractOptionStorage::setMinValueCount(int count)
{
- assert(!hasFlag(efMulti));
- assert(count >= 0);
+ GMX_RELEASE_ASSERT(!hasFlag(efMulti),
+ "setMinValueCount() not supported with efMulti");
+ GMX_RELEASE_ASSERT(count >= 0, "Invalid value count");
_minValueCount = count;
if (isSet()
&& !hasFlag(efDontCheckMinimumCount) && valueCount() < _minValueCount)
{
- if (_maxValueCount == -1 || valueCount() <= _maxValueCount)
- {
- errors->error("Too few values");
- }
- return eeInconsistentInput;
+ GMX_THROW(InvalidInputError("Too few values"));
}
- return 0;
}
-int AbstractOptionStorage::setMaxValueCount(int count,
- AbstractErrorReporter *errors)
+void AbstractOptionStorage::setMaxValueCount(int count)
{
- assert(!hasFlag(efMulti));
- assert(count >= -1);
+ GMX_RELEASE_ASSERT(!hasFlag(efMulti),
+ "setMaxValueCount() not supported with efMulti");
+ GMX_RELEASE_ASSERT(count >= -1, "Invalid value count");
_maxValueCount = count;
if (isSet() && _maxValueCount >= 0 && valueCount() > _maxValueCount)
{
- if (hasFlag(efDontCheckMinimumCount) || valueCount() >= _minValueCount)
- {
- errors->error("Too many values");
- }
- return eeInconsistentInput;
+ GMX_THROW(InvalidInputError("Too many values"));
}
- return 0;
}
-int AbstractOptionStorage::incrementValueCount()
+void AbstractOptionStorage::incrementValueCount()
{
if (_currentValueCount == -1)
{
- return 0;
+ return;
}
if (_maxValueCount >= 0 && _currentValueCount >= _maxValueCount)
{
- return eeInvalidInput;
+ GMX_THROW(InvalidInputError("Too many values"));
}
++_currentValueCount;
- return 0;
}
} // namespace gmx
* Creates a default storage object for the option.
*
* \param[in] options Option collection object.
- * \param[out] storage The created storage object.
- * \retval 0 if there are no errors.
+ * \returns The created storage object.
*
* This method is called by when creating an option object
* The \p options object is used to implement global properties.
*
* \see AbstractOptionStorage::init()
*/
- virtual int createDefaultStorage(Options *options,
- AbstractOptionStorage **storage) const = 0;
+ virtual AbstractOptionStorage *createDefaultStorage(Options *options) const = 0;
/*! \brief
* Creates the description string for the option.
namespace gmx
{
-class AbstractErrorReporter;
class AbstractOption;
class Options;
public:
virtual ~AbstractOptionStorage();
- /*! \brief
- * Initializes the storage object from the settings object.
- *
- * \param[in] settings Option settings.
- * \param[in] options Option collection that will contain the
- * option.
- * \retval 0 on success.
- */
- int init(const AbstractOption &settings, Options *options);
-
//! Returns true if the option has been set.
bool isSet() const { return hasFlag(efSet); }
//! Returns true if the option is a boolean option.
/*! \brief
* Starts adding values from a new source for the option.
*
- * \retval 0 on success.
- *
* This marks the vurrent value of the option as a default value,
* causing next call to startSet() to clear it. This allows values
* from the new source to overwrite old values.
*/
- int startSource();
+ void startSource();
/*! \brief
* Starts adding a new set of values for the option.
*
- * \param[in] errors Error reporter for errors.
- * \retval 0 on success.
- *
* If the parameter is specified multiple times, startSet() should be
* called before the values for each instance.
*/
- int startSet(AbstractErrorReporter *errors);
+ void startSet();
/*! \brief
* Adds a new value for the option, converting it from a string.
*
* \param[in] value String value to convert.
- * \param[in] errors Error reporter for errors.
- * \retval 0 if the value was successfully converted and added.
*/
- int appendValue(const std::string &value,
- AbstractErrorReporter *errors);
+ void appendValue(const std::string &value);
/*! \brief
* Performs validation and/or actions once a set of values has been
* added.
*
- * \param[in] errors Error reporter for errors.
- * \retval 0 on success.
- *
* If the parameter is specified multiple times, finishSet() should be
* called after the values for each instance.
*/
- int finishSet(AbstractErrorReporter *errors);
+ void finishSet();
/*! \brief
* Performs validation and/or actions once all values have been added.
*
- * \param[in] errors Error reporter for errors.
- * \retval 0 on success.
- *
* This function should be called after all values have been provided
- * with appendValue(). Calls finishSet() if needed.
+ * with appendValue().
*/
- int finish(AbstractErrorReporter *errors);
+ void finish();
protected:
- //! Creates an uninitialized storage object.
- AbstractOptionStorage();
+ /*! \brief
+ * Initializes the storage object from the settings object.
+ *
+ * \param[in] settings Option settings.
+ * \param[in] options Option collection that will contain the
+ * option.
+ */
+ AbstractOptionStorage(const AbstractOption &settings, Options *options,
+ OptionFlags staticFlags = OptionFlags());
//! Returns true if the given flag is set.
bool hasFlag(OptionFlag flag) const { return _flags.test(flag); }
* Sets a new minimum number of values required in one set.
*
* \param[in] count New minimum number of values (must be > 0).
- * \param[in] errors Error reporter for errors.
- * \retval 0 on success.
*
* If values have already been provided, it is checked that there are
* enough. If called together with setMaxValueCount(), only
* Cannot be called for options with ::efMulti set, because it is
* impossible to check the requirement after the values have been set.
*/
- int setMinValueCount(int count, AbstractErrorReporter *errors);
+ void setMinValueCount(int count);
/*! \brief
* Sets a new maximum number of values required in one set.
*
* \param[in] count New maximum number of values
* (must be > 0, or -1 for no limit).
- * \param[in] errors Error reporter for errors.
- * \retval 0 on success.
*
* If values have already been provided, it is checked that there are
* not too many. If called together with setMinValueCount(), only
* Cannot be called for options with ::efMulti set, because it is
* impossible to check the requirement after the values have been set.
*/
- int setMaxValueCount(int count, AbstractErrorReporter *errors);
+ void setMaxValueCount(int count);
//! Returns the Options object that houses the option.
Options &hostOptions() { return *_options; }
* Adds a new value, converting it from a string.
*
* \param[in] value String value to convert.
- * \param[in] errors Error reporter object.
- * \retval 0 if the value was successfully converted.
*
* This function may be called multiple times if the underlying
* option is defined to accept multiple values.
*/
- virtual int convertValue(const std::string &value,
- AbstractErrorReporter *errors) = 0;
+ virtual void convertValue(const std::string &value) = 0;
/*! \brief
* Performs validation and/or actions once a set of values has been
* added.
*
* \param[in] nvalues Number of values added since the previous call
* to finishSet().
- * \param[in] errors Error reporter object.
- * \retval 0 on success.
*
* This function may be called multiple times of the underlying option
* can be specified multiple times.
*/
- virtual int processSet(int nvalues, AbstractErrorReporter *errors) = 0;
+ virtual void processSet(int nvalues) = 0;
/*! \brief
* Performs validation and/or actions once all values have been added.
*
- * \param[in] errors Error reporter object.
- * \retval 0 if final option values are valid.
- *
* This function is always called once.
*/
- virtual int processAll(AbstractErrorReporter *errors) = 0;
+ virtual void processAll() = 0;
/*! \brief
* Increments the number of values for the current set.
- *
- * \retval 0 on success.
- * \retval ::eeInvalidInput if the maximum value count has been reached.
*/
- int incrementValueCount();
+ void incrementValueCount();
private:
std::string _name;
return *this;
}
-int AsciiHelpWriter::writeHelp(FILE *fp)
+void AsciiHelpWriter::writeHelp(FILE *fp)
{
if (_impl->_flags.test(Impl::efShowDescriptions))
{
fprintf(fp, "\n");
}
}
- return 0;
}
} // namespace gmx
* Writes the help.
*
* \param[in] fp File to write the help to.
- * \retval 0 on success.
*/
- int writeHelp(FILE *fp);
+ void writeHelp(FILE *fp);
private:
class Impl;
#include <string>
#include <vector>
-#include "gromacs/errorreporting/abstracterrorreporter.h"
-#include "gromacs/fatalerror/fatalerror.h"
+#include "gromacs/fatalerror/exceptions.h"
#include "gromacs/options/globalproperties.h"
#include "gromacs/options/options.h"
+#include "gromacs/utility/format.h"
#include "basicoptionstorage.h"
template <typename T> static
-int expandVector(int length, int *nvalues, gmx::AbstractErrorReporter *errors,
- std::vector<T> *values)
+void expandVector(int length, int *nvalues, std::vector<T> *values)
{
if (length > 0 && *nvalues > 0 && *nvalues != length)
{
if (*nvalues != 1)
{
- char err_buf[256];
- std::sprintf(err_buf, "Expected 1 or %d values, got %d",
- length, *nvalues);
- errors->error(err_buf);
values->resize(values->size() - *nvalues);
- return gmx::eeInvalidInput;
+ GMX_THROW(gmx::InvalidInputError(gmx::formatString(
+ "Expected 1 or %d values, got %d", length, *nvalues)));
}
const T &value = (*values)[values->size() - 1];
values->resize(values->size() + length - 1, value);
*nvalues = length;
}
- return 0;
}
namespace gmx
return value ? "yes" : "no";
}
-int BooleanOptionStorage::convertValue(const std::string &value,
- AbstractErrorReporter *errors)
+void BooleanOptionStorage::convertValue(const std::string &value)
{
// TODO: Case-independence
if (value == "1" || value == "yes" || value == "true")
{
addValue(true);
- return 0;
+ return;
}
else if (value == "0" || value == "no" || value == "false")
{
addValue(false);
- return 0;
+ return;
}
- errors->error("Invalid value: '" + value + "'; supported values are: 1, 0, yes, no, true, false");
- return eeInvalidInput;
+ GMX_THROW(InvalidInputError("Invalid value: '" + value + "'; supported values are: 1, 0, yes, no, true, false"));
}
/********************************************************************
* BooleanOption
*/
-int BooleanOption::createDefaultStorage(Options *options,
- AbstractOptionStorage **storage) const
+AbstractOptionStorage *BooleanOption::createDefaultStorage(Options *options) const
{
- return createOptionStorage<BooleanOption, BooleanOptionStorage>(this, options, storage);
+ return new BooleanOptionStorage(*this, options);
}
* IntegerOptionStorage
*/
-IntegerOptionStorage::IntegerOptionStorage()
-{
-}
-
std::string IntegerOptionStorage::formatValue(int i) const
{
- char buf[64];
int value = values()[i];
- std::sprintf(buf, "%d", value);
- return std::string(buf);
+ return formatString("%d", value);
}
-int IntegerOptionStorage::convertValue(const std::string &value,
- AbstractErrorReporter *errors)
+void IntegerOptionStorage::convertValue(const std::string &value)
{
const char *ptr = value.c_str();
char *endptr = NULL;
long int ival = std::strtol(ptr, &endptr, 10);
- if (*endptr == '\0')
+ if (*endptr != '\0')
{
- addValue(ival);
- return 0;
+ GMX_THROW(InvalidInputError("Invalid value: " + value));
}
- errors->error("Invalid value: " + value);
- return eeInvalidInput;
+ addValue(ival);
}
-int IntegerOptionStorage::processSet(int nvalues, AbstractErrorReporter *errors)
+void IntegerOptionStorage::processSet(int nvalues)
{
if (hasFlag(efVector))
{
- int rc = expandVector(maxValueCount(), &nvalues, errors, &values());
- if (rc != 0)
- {
- return rc;
- }
+ expandVector(maxValueCount(), &nvalues, &values());
}
- return MyBase::processSet(nvalues, errors);
+ MyBase::processSet(nvalues);
}
/********************************************************************
* IntegerOption
*/
-int IntegerOption::createDefaultStorage(Options *options,
- AbstractOptionStorage **storage) const
+AbstractOptionStorage *IntegerOption::createDefaultStorage(Options *options) const
{
- return createOptionStorage<IntegerOption, IntegerOptionStorage>(this, options, storage);
+ return new IntegerOptionStorage(*this, options);
}
* DoubleOptionStorage
*/
-DoubleOptionStorage::DoubleOptionStorage()
- : _bTime(false)
+DoubleOptionStorage::DoubleOptionStorage(const DoubleOption &settings, Options *options)
+ : MyBase(settings, options), _bTime(settings._bTime)
{
-}
-
-int DoubleOptionStorage::init(const DoubleOption &settings, Options *options)
-{
- _bTime = settings._bTime;
if (_bTime)
{
options->globalProperties().request(eogpTimeScaleFactor);
}
- return MyBase::init(settings, options);
}
const char *DoubleOptionStorage::typeString() const
std::string DoubleOptionStorage::formatValue(int i) const
{
- char buf[64];
double value = values()[i];
if (_bTime)
{
double factor = hostOptions().globalProperties().timeScaleFactor();
value /= factor;
}
- std::sprintf(buf, "%g", value);
- return std::string(buf);
+ return formatString("%g", value);
}
-int DoubleOptionStorage::convertValue(const std::string &value,
- AbstractErrorReporter *errors)
+void DoubleOptionStorage::convertValue(const std::string &value)
{
const char *ptr = value.c_str();
char *endptr = NULL;
double dval = std::strtod(ptr, &endptr);
- if (*endptr == '\0')
+ if (*endptr != '\0')
{
- addValue(dval);
- return 0;
+ GMX_THROW(InvalidInputError("Invalid value: " + value));
}
- errors->error("Invalid value: " + value);
- return eeInvalidInput;
+ addValue(dval);
}
-int DoubleOptionStorage::processSet(int nvalues, AbstractErrorReporter *errors)
+void DoubleOptionStorage::processSet(int nvalues)
{
if (hasFlag(efVector))
{
- int rc = expandVector(maxValueCount(), &nvalues, errors, &values());
- if (rc != 0)
- {
- return rc;
- }
+ expandVector(maxValueCount(), &nvalues, &values());
}
- return MyBase::processSet(nvalues, errors);
+ MyBase::processSet(nvalues);
}
-int DoubleOptionStorage::processAll(AbstractErrorReporter *errors)
+void DoubleOptionStorage::processAll()
{
if (_bTime)
{
(*i) *= factor;
}
}
- return MyBase::processAll(errors);
+ MyBase::processAll();
}
/********************************************************************
* DoubleOption
*/
-int DoubleOption::createDefaultStorage(Options *options,
- AbstractOptionStorage **storage) const
+AbstractOptionStorage *DoubleOption::createDefaultStorage(Options *options) const
{
- return createOptionStorage<DoubleOption, DoubleOptionStorage>(this, options, storage);
+ return new DoubleOptionStorage(*this, options);
}
* StringOptionStorage
*/
-StringOptionStorage::StringOptionStorage()
- : _enumIndexStore(NULL)
-{
-}
-
-int StringOptionStorage::init(const StringOption &settings, Options *options)
+StringOptionStorage::StringOptionStorage(const StringOption &settings, Options *options)
+ : MyBase(settings, options), _enumIndexStore(NULL)
{
if (settings._defaultEnumIndex >= 0 && settings._enumValues == NULL)
{
- GMX_ERROR(eeInvalidValue,
- "Cannot set default enum index without enum values");
+ GMX_THROW(APIError("Cannot set default enum index without enum values"));
}
if (settings._enumIndexStore != NULL && settings._enumValues == NULL)
{
- GMX_ERROR(eeInvalidValue,
- "Cannot set enum index store without enum values");
+ GMX_THROW(APIError("Cannot set enum index store without enum values"));
}
if (settings._enumIndexStore != NULL && settings._maxValueCount < 0)
{
- GMX_ERROR(eeInvalidValue,
- "Cannot set enum index store with arbitrary number of values");
+ GMX_THROW(APIError("Cannot set enum index store with arbitrary number of values"));
}
if (settings._enumValues != NULL)
{
int match = -1;
for (int i = 0; settings._enumValues[i] != NULL; ++i)
{
- if (defaultValue && settings._enumValues[i] == *defaultValue)
+ if (defaultValue != NULL && settings._enumValues[i] == *defaultValue)
{
match = i;
}
_allowed.push_back(settings._enumValues[i]);
}
- if (defaultValue)
+ if (defaultValue != NULL)
{
if (match < 0)
{
- GMX_ERROR(eeInvalidValue,
- "Default value is not one of allowed values");
+ GMX_THROW(APIError("Default value is not one of allowed values"));
}
}
if (settings._defaultEnumIndex >= 0)
{
if (settings._defaultEnumIndex >= static_cast<int>(_allowed.size()))
{
- GMX_ERROR(eeInvalidValue,
- "Default enumeration index is out of range");
+ GMX_THROW(APIError("Default enumeration index is out of range"));
}
- if (defaultValue && *defaultValue != _allowed[settings._defaultEnumIndex])
+ if (defaultValue != NULL && *defaultValue != _allowed[settings._defaultEnumIndex])
{
- GMX_ERROR(eeInvalidValue,
- "Conflicting default values");
+ GMX_THROW(APIError("Conflicting default values"));
}
}
// If there is no default value, match is still -1.
*_enumIndexStore = match;
}
}
- int rc = MyBase::init(settings, options);
- if (rc == 0)
+ if (settings._defaultEnumIndex >= 0)
{
- if (settings._defaultEnumIndex >= 0)
+ clear();
+ addValue(_allowed[settings._defaultEnumIndex]);
+ if (_enumIndexStore != NULL)
{
- clear();
- addValue(_allowed[settings._defaultEnumIndex]);
- if (_enumIndexStore != NULL)
- {
- *_enumIndexStore = settings._defaultEnumIndex;
- }
- processValues(1, false);
+ *_enumIndexStore = settings._defaultEnumIndex;
}
+ processValues(1, false);
}
- return rc;
}
std::string StringOptionStorage::formatValue(int i) const
return values()[i];
}
-int StringOptionStorage::convertValue(const std::string &value,
- AbstractErrorReporter *errors)
+void StringOptionStorage::convertValue(const std::string &value)
{
if (_allowed.size() == 0)
{
}
if (match == _allowed.end())
{
- errors->error("Invalid value: " + value);
- return eeInvalidInput;
+ GMX_THROW(InvalidInputError("Invalid value: " + value));
}
addValue(*match);
- if (_enumIndexStore)
+ if (_enumIndexStore != NULL)
{
_enumIndexStore[valueCount() - 1] = (match - _allowed.begin());
}
}
- return 0;
}
/********************************************************************
* StringOption
*/
-int StringOption::createDefaultStorage(Options *options,
- AbstractOptionStorage **storage) const
+AbstractOptionStorage *StringOption::createDefaultStorage(Options *options) const
{
- return createOptionStorage<StringOption, StringOptionStorage>(this, options, storage);
+ return new StringOptionStorage(*this, options);
}
std::string StringOption::createDescription() const
* FileNameOptionStorage
*/
-FileNameOptionStorage::FileNameOptionStorage()
- : _filetype(eftUnknown)
-{
-}
-
-int FileNameOptionStorage::init(const FileNameOption &settings, Options *options)
+FileNameOptionStorage::FileNameOptionStorage(const FileNameOption &settings, Options *options)
+ : MyBase(settings, options), _filetype(settings._filetype)
{
- _filetype = settings._filetype;
if (_filetype == eftPlot)
{
options->globalProperties().request(eogpPlotFormat);
}
- return MyBase::init(settings, options);
}
std::string FileNameOptionStorage::formatValue(int i) const
return values()[i];
}
-int FileNameOptionStorage::convertValue(const std::string &value,
- AbstractErrorReporter * /*errors*/)
+void FileNameOptionStorage::convertValue(const std::string &value)
{
// TODO: Proper implementation.
addValue(value);
- return 0;
}
/********************************************************************
* FileNameOption
*/
-int FileNameOption::createDefaultStorage(Options *options,
- AbstractOptionStorage **storage) const
+AbstractOptionStorage *FileNameOption::createDefaultStorage(Options *options) const
{
- return createOptionStorage<FileNameOption, FileNameOptionStorage>(this, options, storage);
+ return new FileNameOptionStorage(*this, options);
}
} // namespace gmx
#ifndef GMX_OPTIONS_BASICOPTIONS_H
#define GMX_OPTIONS_BASICOPTIONS_H
-#include <cassert>
-
#include <string>
+#include "../fatalerror/gmxassert.h"
+
#include "abstractoption.h"
#include "optionfiletype.h"
}
protected:
- virtual int createDefaultStorage(Options *options,
- AbstractOptionStorage **storage) const;
+ virtual AbstractOptionStorage *createDefaultStorage(Options *options) const;
};
/*! \brief
MyClass &vector() { setVector(); return me(); }
protected:
- virtual int createDefaultStorage(Options *options,
- AbstractOptionStorage **storage) const;
+ virtual AbstractOptionStorage *createDefaultStorage(Options *options) const;
/*! \brief
* Needed to initialize IntegerOptionStorage from this class without
MyClass &timeValue() { _bTime = true; return me(); }
private:
- virtual int createDefaultStorage(Options *options,
- AbstractOptionStorage **storage) const;
+ virtual AbstractOptionStorage *createDefaultStorage(Options *options) const;
bool _bTime;
* Cannot be specified without enumValue().
*/
MyClass &defaultEnumIndex(int index)
- { assert(index >= 0); _defaultEnumIndex = index; return me(); }
+ {
+ GMX_RELEASE_ASSERT(index >= 0, "Invalid enumeration index");
+ _defaultEnumIndex = index;
+ return me();
+ }
/*! \brief
* Stores the index of the selected value into the provided memory
* location.
{ _enumIndexStore = store; return me(); }
protected:
- virtual int createDefaultStorage(Options *options,
- AbstractOptionStorage **storage) const;
+ virtual AbstractOptionStorage *createDefaultStorage(Options *options) const;
virtual std::string createDescription() const;
private:
MyClass &libraryFile() { setFlag(efFileLibrary); return me(); }
protected:
- virtual int createDefaultStorage(Options *options,
- AbstractOptionStorage **storage) const;
+ virtual AbstractOptionStorage *createDefaultStorage(Options *options) const;
private:
OptionFileType _filetype;
namespace gmx
{
+class BooleanOption;
class IntegerOption;
class DoubleOption;
class StringOption;
class BooleanOptionStorage : public OptionStorageTemplate<bool>
{
public:
+ /*! \brief
+ * Initializes the storage from option settings.
+ *
+ * \param[in] settings Storage settings.
+ * \param[in] options Options object.
+ */
+ BooleanOptionStorage(const BooleanOption &settings, Options *options)
+ : MyBase(settings, options)
+ {
+ }
+
virtual const char *typeString() const { return "bool"; }
virtual std::string formatValue(int i) const;
private:
- virtual int convertValue(const std::string &value,
- AbstractErrorReporter *errors);
+ virtual void convertValue(const std::string &value);
};
/*! \internal \brief
class IntegerOptionStorage : public OptionStorageTemplate<int>
{
public:
- IntegerOptionStorage();
+ //! \copydoc BooleanOptionStorage::BooleanOptionStorage()
+ IntegerOptionStorage(const IntegerOption &settings, Options *options)
+ : MyBase(settings, options)
+ {
+ }
virtual const char *typeString() const
{ return hasFlag(efVector) ? "vector" : "int"; }
virtual std::string formatValue(int i) const;
private:
- virtual int convertValue(const std::string &value,
- AbstractErrorReporter *errors);
- virtual int processSet(int nvalues, AbstractErrorReporter *errors);
+ virtual void convertValue(const std::string &value);
+ virtual void processSet(int nvalues);
};
/*! \internal \brief
class DoubleOptionStorage : public OptionStorageTemplate<double>
{
public:
- DoubleOptionStorage();
-
- /*! \brief
- * Initializes the storage from option settings.
- *
- * \param[in] settings Storage settings.
- * \param[in] options Options object.
- * \retval 0 on success.
- */
- int init(const DoubleOption &settings, Options *options);
+ //! \copydoc IntegerOptionStorage::IntegerOptionStorage()
+ DoubleOptionStorage(const DoubleOption &settings, Options *options);
virtual const char *typeString() const;
virtual std::string formatValue(int i) const;
private:
- virtual int convertValue(const std::string &value,
- AbstractErrorReporter *errors);
- virtual int processSet(int nvalues, AbstractErrorReporter *errors);
- virtual int processAll(AbstractErrorReporter *errors);
+ virtual void convertValue(const std::string &value);
+ virtual void processSet(int nvalues);
+ virtual void processAll();
bool _bTime;
};
class StringOptionStorage : public OptionStorageTemplate<std::string>
{
public:
- StringOptionStorage();
-
- //! \copydoc DoubleOptionStorage::init()
- int init(const StringOption &settings, Options *options);
+ //! \copydoc DoubleOptionStorage::DoubleOptionStorage()
+ StringOptionStorage(const StringOption &settings, Options *options);
virtual const char *typeString() const { return _allowed.empty() ? "string" : "enum"; }
virtual std::string formatValue(int i) const;
private:
- virtual int convertValue(const std::string &value,
- AbstractErrorReporter *errors);
+ virtual void convertValue(const std::string &value);
ValueList _allowed;
int *_enumIndexStore;
class FileNameOptionStorage : public OptionStorageTemplate<std::string>
{
public:
- FileNameOptionStorage();
-
- //! \copydoc StringOptionStorage::init()
- int init(const FileNameOption &settings, Options *options);
+ //! \copydoc StringOptionStorage::StringOptionStorage()
+ FileNameOptionStorage(const FileNameOption &settings, Options *options);
virtual const char *typeString() const { return "file"; }
virtual std::string formatValue(int i) const;
private:
- virtual int convertValue(const std::string &value,
- AbstractErrorReporter *errors);
+ virtual void convertValue(const std::string &value);
OptionFileType _filetype;
};
{
public:
//! Sets the options object to parse to.
- Impl(Options *options, AbstractErrorReporter *errors);
+ Impl(Options *options);
//! Helper object for assigning the options.
OptionsAssigner _assigner;
*/
#include "gromacs/options/cmdlineparser.h"
-#include "gromacs/errorreporting/abstracterrorreporter.h"
+#include "gromacs/fatalerror/exceptions.h"
+#include "gromacs/fatalerror/messagestringcollector.h"
#include "gromacs/options/optionsassigner.h"
#include "cmdlineparser-impl.h"
* CommandLineParser::Impl
*/
-CommandLineParser::Impl::Impl(Options *options, AbstractErrorReporter *errors)
- : _assigner(options, errors)
+CommandLineParser::Impl::Impl(Options *options)
+ : _assigner(options)
{
_assigner.setAcceptBooleanNoPrefix(true);
_assigner.setNoStrictSectioning(true);
* CommandLineParser
*/
-CommandLineParser::CommandLineParser(Options *options,
- AbstractErrorReporter *errors)
- : _impl(new Impl(options, errors))
+CommandLineParser::CommandLineParser(Options *options)
+ : _impl(new Impl(options))
{
}
delete _impl;
}
-int CommandLineParser::parse(int *argc, char *argv[])
+void CommandLineParser::parse(int *argc, char *argv[])
{
- AbstractErrorReporter *errors = _impl->_assigner.errorReporter();
+ MessageStringCollector errors;
int i = 1;
// Start in the discard phase to skip options that can't be understood.
bool bDiscard = true;
{
if (!bDiscard)
{
- _impl->_assigner.finishOption();
- errors->finishContext();
+ try
+ {
+ _impl->_assigner.finishOption();
+ }
+ catch (UserInputError &ex)
+ {
+ errors.append(ex.what());
+ }
+ errors.finishContext();
}
- errors->startContext("In command-line option " + std::string(argv[i]));
- const char *name = &argv[i][1];
- int rc = _impl->_assigner.startOption(name);
- bDiscard = (rc != 0);
- if (bDiscard)
+ errors.startContext("In command-line option " + std::string(argv[i]));
+ bDiscard = false;
+ try
{
- errors->finishContext();
+ const char *name = &argv[i][1];
+ _impl->_assigner.startOption(name);
+ }
+ catch (UserInputError &ex)
+ {
+ bDiscard = true;
+ errors.append(ex.what());
+ errors.finishContext();
}
}
else if (!bDiscard)
{
- _impl->_assigner.appendValue(argv[i]);
+ try
+ {
+ _impl->_assigner.appendValue(argv[i]);
+ }
+ catch (UserInputError &ex)
+ {
+ errors.append(ex.what());
+ }
}
++i;
}
if (!bDiscard)
{
- _impl->_assigner.finishOption();
- errors->finishContext();
+ try
+ {
+ _impl->_assigner.finishOption();
+ }
+ catch (UserInputError &ex)
+ {
+ errors.append(ex.what());
+ }
+ errors.finishContext();
+ }
+ _impl->_assigner.finish();
+ if (!errors.isEmpty())
+ {
+ // TODO: This exception type may not always be appropriate.
+ GMX_THROW(InvalidInputError(errors.toString()));
}
- return _impl->_assigner.finish();
}
} // namespace gmx
namespace gmx
{
-class AbstractErrorReporter;
-
class Options;
/*! \brief
gmx::Options options("name", "description");
// Fill up options
-gmx::StandardErrorReporter errors;
-gmx::CommandLineParser(&options, &errors).parse(&argc, argv);
-options.finish(&errors);
+gmx::CommandLineParser(&options).parse(&argc, argv);
+options.finish();
* \endcode
*
* \inpublicapi
* Creates a command-line parser that sets values for options.
*
* \param[in] options Options object whose options should be set.
- * \param[in] errors Error reporter object.
*/
- CommandLineParser(Options *options, AbstractErrorReporter *errors);
+ CommandLineParser(Options *options);
~CommandLineParser();
/*! \brief
* Parses the command-line.
- *
- * \retval 0 if there were no errors.
*/
- int parse(int *argc, char *argv[]);
+ void parse(int *argc, char *argv[]);
private:
class Impl;
*/
#include "gromacs/options/globalproperties.h"
-#include <cassert>
#include <cstddef>
#include <smalloc.h>
#include <statutil.h>
+#include "gromacs/fatalerror/gmxassert.h"
#include "gromacs/options/basicoptions.h"
#include "gromacs/options/options.h"
double OptionsGlobalProperties::timeScaleFactor() const
{
- assert(_timeUnit >= 0
- && (size_t)_timeUnit < sizeof(timeScaleFactors)/sizeof(timeScaleFactors[0]));
+ GMX_RELEASE_ASSERT(_timeUnit >= 0
+ && (size_t)_timeUnit < sizeof(timeScaleFactors)/sizeof(timeScaleFactors[0]),
+ "Time unit index has become out of range");
return timeScaleFactors[_timeUnit];
}
/*! \brief
* Calls Option::startSource() for all options, including subsections.
- *
- * \returns 0 on success, or the first non-zero return value of the
- * called functions.
*/
- int startSource();
+ void startSource();
//! Name for the Options object.
std::string _name;
*/
#include "gromacs/options/options.h"
-#include <cassert>
#include <cctype>
#include <cstring>
+#include "gromacs/fatalerror/exceptions.h"
+#include "gromacs/fatalerror/gmxassert.h"
+#include "gromacs/fatalerror/messagestringcollector.h"
#include "gromacs/options/abstractoption.h"
#include "gromacs/options/abstractoptionstorage.h"
#include "gromacs/options/globalproperties.h"
return NULL;
}
-int Options::Impl::startSource()
+void Options::Impl::startSource()
{
- int rc = 0;
OptionList::const_iterator i;
for (i = _options.begin(); i != _options.end(); ++i)
{
AbstractOptionStorage *option = *i;
- int rc1 = option->startSource();
- rc = (rc != 0 ? rc : rc1);
+ option->startSource();
}
SubSectionList::const_iterator j;
for (j = _subSections.begin(); j != _subSections.end(); ++j)
{
Options *section = *j;
- int rc1 = section->_impl->startSource();
- rc = (rc != 0 ? rc : rc1);
+ section->_impl->startSource();
}
- return rc;
}
/********************************************************************
void Options::addSubSection(Options *section)
{
// Make sure that section is not already inserted somewhere.
- assert(section->_impl->_parent == NULL);
+ GMX_RELEASE_ASSERT(section->_impl->_parent == NULL,
+ "Cannot add as subsection twice");
// Make sure that there are no duplicate sections.
- assert(_impl->findSubSection(section->name().c_str()) == NULL);
+ GMX_RELEASE_ASSERT(_impl->findSubSection(section->name().c_str()) == NULL,
+ "Duplicate subsection name");
_impl->_subSections.push_back(section);
section->_impl->_parent = this;
void Options::addOption(const AbstractOption &settings)
{
- AbstractOptionStorage *option = NULL;
- int rc = settings.createDefaultStorage(this, &option);
- // Caller code should be fixed if option initialization fails.
- assert(rc == 0);
- // Make sure that there are no duplicate options.
- assert(_impl->findOption(option->name().c_str()) == NULL);
- _impl->_options.push_back(option);
+ std::auto_ptr<AbstractOptionStorage> option(settings.createDefaultStorage(this));
+ if (_impl->findOption(option->name().c_str()) != NULL)
+ {
+ GMX_THROW(APIError("Duplicate option: " + option->name()));
+ }
+ _impl->_options.push_back(option.get());
+ option.release();
}
void Options::addDefaultOptions()
return (option != NULL ? option->isSet() : false);
}
-int Options::finish(AbstractErrorReporter *errors)
+void Options::finish()
{
- int rc = 0;
+ MessageStringCollector errors;
Impl::OptionList::const_iterator i;
for (i = _impl->_options.begin(); i != _impl->_options.end(); ++i)
{
AbstractOptionStorage *option = *i;
- int rc1 = option->finish(errors);
- rc = (rc != 0 ? rc : rc1);
+ try
+ {
+ option->finish();
+ }
+ catch (UserInputError &ex)
+ {
+ MessageStringContext context(&errors, "In option " + option->name());
+ errors.append(ex.what());
+ }
}
Impl::SubSectionList::const_iterator j;
for (j = _impl->_subSections.begin(); j != _impl->_subSections.end(); ++j)
{
Options *section = *j;
- int rc1 = section->finish(errors);
- rc = (rc != 0 ? rc : rc1);
+ try
+ {
+ section->finish();
+ }
+ catch (UserInputError &ex)
+ {
+ errors.append(ex.what());
+ }
}
if (_impl->_parent == NULL)
{
- assert(_impl->_globalProperties != NULL);
+ GMX_RELEASE_ASSERT(_impl->_globalProperties != NULL,
+ "Global properties should exist for the top-level options");
_impl->_globalProperties->finish();
}
- return rc;
+ if (!errors.isEmpty())
+ {
+ // TODO: This exception type may not always be appropriate.
+ GMX_THROW(InvalidInputError(errors.toString()));
+ }
}
OptionsGlobalProperties &Options::globalProperties()
{
section = section->_impl->_parent;
}
+ GMX_RELEASE_ASSERT(section->_impl->_globalProperties != NULL,
+ "Global properties should exist for the top-level options");
return *section->_impl->_globalProperties;
}
namespace gmx
{
-class AbstractErrorReporter;
-
class AbstractOption;
class OptionsGlobalProperties;
class OptionsAssigner;
* to be assigned. Values in storage variables are guaranteed to be
* available only after this call.
*/
- int finish(AbstractErrorReporter *errors);
+ void finish();
/*! \brief
* Returns the global property object for this collection.
namespace gmx
{
-class AbstractErrorReporter;
-
class AbstractOptionStorage;
class Options;
efNoStrictSectioning = 1<<1,
};
//! Sets the option object to assign to.
- Impl(Options *options, AbstractErrorReporter *errors);
-
- /*! \brief
- * Stores error code for later retrieval if it is the first error.
- *
- * \param[in] code Error code to store.
- * \returns \p code
- *
- * The first call with a non-zero \p code sets the \p _errorCode
- * attribute; later calls do nothing The return value allows the
- * function to be used like \c "return keepError(rc);"
- */
- int keepError(int code)
- {
- if (_errorCode == 0)
- {
- _errorCode = code;
- }
- return code;
- }
+ Impl(Options *options);
//! Sets or clears the given flag.
void setFlag(Flag flag, bool bSet);
//! Options object to assign to.
Options &_options;
- //! Error reporter to use for errors.
- AbstractErrorReporter *_errors;
//! Flags that control assignment behavior.
unsigned long _flags;
/*! \brief
std::vector<Options *> _sectionStack;
//! Current option being assigned to, or NULL if none.
AbstractOptionStorage *_currentOption;
- //! Keeps the error code of the first error encountered, or 0 if none.
- int _errorCode;
//! Number of values assigned so far to the current option.
int _currentValueCount;
//! If true, a "no" prefix was given for the current boolean option.
#include <deque>
-#include <cassert>
-
-#include "gromacs/errorreporting/abstracterrorreporter.h"
-#include "gromacs/fatalerror/fatalerror.h"
+#include "gromacs/fatalerror/exceptions.h"
+#include "gromacs/fatalerror/gmxassert.h"
#include "gromacs/options/abstractoptionstorage.h"
#include "gromacs/options/options.h"
* OptionsAssigner::Impl
*/
-OptionsAssigner::Impl::Impl(Options *options, AbstractErrorReporter *errors)
- : _options(*options), _errors(errors), _flags(0), _currentOption(NULL),
- _errorCode(0), _currentValueCount(0), _reverseBoolean(false)
+OptionsAssigner::Impl::Impl(Options *options)
+ : _options(*options), _flags(0), _currentOption(NULL),
+ _currentValueCount(0), _reverseBoolean(false)
{
_sectionStack.push_back(&_options);
}
AbstractOptionStorage *
OptionsAssigner::Impl::findOption(const char *name)
{
- assert(_currentOption == NULL);
+ GMX_RELEASE_ASSERT(_currentOption == NULL,
+ "Cannot search for another option while processing one");
AbstractOptionStorage *option = NULL;
Options *section = NULL;
Options *root = ¤tSection();
* OptionsAssigner
*/
-OptionsAssigner::OptionsAssigner(Options *options, AbstractErrorReporter *errors)
- : _impl(new Impl(options, errors))
+OptionsAssigner::OptionsAssigner(Options *options)
+ : _impl(new Impl(options))
{
}
delete _impl;
}
-AbstractErrorReporter *OptionsAssigner::errorReporter() const
-{
- return _impl->_errors;
-}
-
void OptionsAssigner::setAcceptBooleanNoPrefix(bool enabled)
{
_impl->setFlag(Impl::efAcceptBooleanNoPrefix, enabled);
_impl->setFlag(Impl::efNoStrictSectioning, enabled);
}
-int OptionsAssigner::start()
+void OptionsAssigner::start()
{
- return _impl->keepError(_impl->_options._impl->startSource());
+ _impl->_options._impl->startSource();
}
-int OptionsAssigner::startSubSection(const char *name)
+void OptionsAssigner::startSubSection(const char *name)
{
- if (_impl->_currentOption != NULL)
- {
- // The return code is ignored to keep on assigning, but any error is
- // stored to be returned in finish().
- finishOption();
- }
-
Options *section = _impl->currentSection()._impl->findSubSection(name);
if (section == NULL)
{
- // TODO: Print an error
- return _impl->keepError(eeInvalidInput);
+ GMX_THROW(InvalidInputError("Unknown subsection"));
}
_impl->_sectionStack.push_back(section);
- return 0;
}
-int OptionsAssigner::startOption(const char *name)
+void OptionsAssigner::startOption(const char *name)
{
- if (_impl->_currentOption != NULL)
- {
- // The return code is ignored to keep on assigning, but any error is
- // stored to be returned in finish().
- finishOption();
- }
-
+ GMX_RELEASE_ASSERT(_impl->_currentOption == NULL, "finishOption() not called");
AbstractOptionStorage *option = _impl->findOption(name);
if (option == NULL)
{
- _impl->_errors->error("Unknown option");
- return _impl->keepError(eeInvalidInput);
- }
- int rc = option->startSet(_impl->_errors);
- if (rc != 0)
- {
- return _impl->keepError(rc);
+ GMX_THROW(InvalidInputError("Unknown option"));
}
+ option->startSet();
_impl->_currentOption = option;
_impl->_currentValueCount = 0;
- return 0;
}
-int OptionsAssigner::appendValue(const std::string &value)
+void OptionsAssigner::appendValue(const std::string &value)
{
AbstractOptionStorage *option = _impl->_currentOption;
- // The option should have been successfully started.
- assert(option != NULL);
+ GMX_RELEASE_ASSERT(option != NULL, "startOption() not called");
++_impl->_currentValueCount;
- return _impl->keepError(option->appendValue(value, _impl->_errors));
+ option->appendValue(value);
}
-int OptionsAssigner::finishOption()
+void OptionsAssigner::finishOption()
{
AbstractOptionStorage *option = _impl->_currentOption;
- // The option should have been successfully started.
- assert(option != NULL);
- int rc = 0;
+ GMX_RELEASE_ASSERT(option != NULL, "startOption() not called");
+ bool bBoolReverseValue = false;
if (option->isBoolean())
{
if (_impl->_currentValueCount == 0)
{
- // TODO: Get rid of the hard-coded strings.
- rc = option->appendValue(_impl->_reverseBoolean ? "0" : "1",
- _impl->_errors);
- // If the above fails, there is something wrong.
- assert(rc == 0);
+ option->appendValue(_impl->_reverseBoolean ? "0" : "1");
}
else if (_impl->_reverseBoolean)
{
- _impl->_errors->error("Cannot specify a value together with 'no' prefix");
- rc = eeInvalidInput;
+ bBoolReverseValue = true;
}
}
- int rc1 = _impl->_currentOption->finishSet(_impl->_errors);
- rc = (rc != 0 ? rc : rc1);
_impl->_currentOption = NULL;
_impl->_reverseBoolean = false;
- return _impl->keepError(rc);
+ option->finishSet();
+ if (bBoolReverseValue)
+ {
+ GMX_THROW(InvalidInputError("Cannot specify a value together with 'no' prefix"));
+ }
}
-int OptionsAssigner::finishSubSection()
+void OptionsAssigner::finishSubSection()
{
// Should only be called if we are in a subsection.
- assert(_impl->inSubSection());
- if (_impl->_currentOption != NULL)
- {
- // Possible error codes are stored and returned in the end.
- finishOption();
- }
+ GMX_RELEASE_ASSERT(_impl->inSubSection(), "startSubSection() not called");
_impl->_sectionStack.pop_back();
- return 0;
}
-int OptionsAssigner::finish()
+void OptionsAssigner::finish()
{
- if (_impl->_currentOption != NULL)
- {
- // Possible error codes are stored and returned in the end.
- finishOption();
- }
- while (_impl->inSubSection())
+ GMX_RELEASE_ASSERT(_impl->_currentOption == NULL, "finishOption() not called");
+ if (_impl->hasFlag(Impl::efNoStrictSectioning))
{
- // Possible error codes are stored and returned in the end.
- finishSubSection();
+ while (_impl->inSubSection())
+ {
+ finishSubSection();
+ }
}
- return _impl->_errorCode;
+ GMX_RELEASE_ASSERT(!_impl->inSubSection(), "finishSubSection() not called");
}
} // namespace gmx
namespace gmx
{
-class AbstractErrorReporter;
-
class Options;
/*! \libinternal \brief
gmx::options::Options options("name", "Title");
// Set up options
-gmx::error::StandardReporter errors;
-gmx::options::OptionsAssigner assigner(&options, &errors);
+gmx::options::OptionsAssigner assigner(&options);
assigner.startOption("opt1");
assigner.appendValue("3");
assigner.startSubSection("section");
/*! \brief
* Creates an object that assigns to the given object.
*/
- OptionsAssigner(Options *options, AbstractErrorReporter *errors);
+ OptionsAssigner(Options *options);
~OptionsAssigner();
- /*! \brief
- * Returns the error reporter object passed to the constructor.
- *
- * This method is provided for convenience such that users of this
- * class do not need to store a separate pointer to the error reporter
- * if they need to use it.
- */
- AbstractErrorReporter *errorReporter() const;
-
/*! \brief
* Sets the assigner to recognize boolean options with a "no" prefix.
*
/*! \brief
* Start assigning values.
- *
- * \retval 0 on success.
*/
- int start();
+ void start();
/*! \brief
* Start assigning values to options in a subsection.
*
* \param[in] name Name of the subsection to start assigning to.
- * \retval 0 if assignment can proceed.
- *
- * Does not call finishSubSection() automatically to enable nested
- * sections.
*/
- int startSubSection(const char *name);
+ void startSubSection(const char *name);
/*! \brief
* Start assigning values for an option.
*
* \param[in] name Name of the option to start assigning to.
- * \retval 0 if assignment can proceed.
*/
- int startOption(const char *name);
+ void startOption(const char *name);
/*! \brief
* Appends a value to the value list of the current option.
*
* \param[in] value String representation of the value to assign.
- * \retval 0 if assignment was successful.
*/
- int appendValue(const std::string &value);
+ void appendValue(const std::string &value);
/*! \brief
* Finish assigning values for the current option.
- *
- * \retval 0 if there were no errors in the assignment.
- *
- * This function returns non-zero only if the error could not have been
- * detected earlier, i.e., from the return value of appendValue().
*/
- int finishOption();
+ void finishOption();
/*! \brief
* Finish assigning values to a subsection.
- *
- * \retval 0 for success.
- *
- * This function returns non-zero only if the error could not have been
- * detected earlier.
*/
- int finishSubSection();
+ void finishSubSection();
/*! \brief
* Finish assigning options through the object.
- *
- * \retval 0 if there were no errors in the assignment.
- *
- * If an error was detected in any of the other calls to this class,
- * this function returns the error code of the first of such errors.
*/
- int finish();
+ void finish();
private:
class Impl;
#ifndef GMX_OPTIONS_OPTIONSTORAGETEMPLATE_H
#define GMX_OPTIONS_OPTIONSTORAGETEMPLATE_H
-#include <cassert>
-
#include <string>
#include <vector>
+#include "../fatalerror/gmxassert.h"
+
#include "abstractoption.h"
#include "abstractoptionstorage.h"
virtual ~OptionStorageTemplate();
+ // No implementation in this class for the pure virtual methods, but
+ // the declarations are still included for clarity.
+ virtual const char *typeString() const = 0;
+ virtual int valueCount() const { return _values->size(); }
+ virtual std::string formatValue(int i) const = 0;
+
+ protected:
/*! \brief
* Initializes the storage from option settings.
*
* \see OptionTemplate::createDefaultStorage()
*/
template <class U>
- int init(const OptionTemplate<T, U> &settings, Options *options);
-
- // No implementation in this class for the pure virtual methods, but
- // the declarations are still included for clarity.
- virtual const char *typeString() const = 0;
- virtual int valueCount() const { return _values->size(); }
- virtual std::string formatValue(int i) const = 0;
+ OptionStorageTemplate(const OptionTemplate<T, U> &settings, Options *options,
+ OptionFlags staticFlags = OptionFlags());
- protected:
- //! Initializes default values (no storage).
- OptionStorageTemplate();
virtual void clear();
/*! \copydoc AbstractOptionStorage::convertValue()
* Derived classes should call addValue() after they have converted
* \p value to the storage type.
*/
- virtual int convertValue(const std::string &value,
- AbstractErrorReporter *errors) = 0;
+ virtual void convertValue(const std::string &value) = 0;
/*! \copydoc AbstractOptionStorage::processSet()
*
* The implementation in OptionStorageTemplate copies the values
* succeeds. Derived classes should always call the base class
* implementation if they override this method.
*/
- virtual int processSet(int nvalues,
- AbstractErrorReporter * /*errors*/)
+ virtual void processSet(int nvalues)
{
processValues(nvalues, true);
- return 0;
}
/*! \copydoc AbstractOptionStorage::processAll()
*
- * The implementation in OptionStorageTemplate does nothing, and always
- * returns zero. Derived classes should still always call the base
- * class implementation if they override this method.
+ * The implementation in OptionStorageTemplate does nothing.
+ * Derived classes should still always call the base class
+ * implementation if they override this method.
*/
- virtual int processAll(AbstractErrorReporter * /*errors*/)
- { return 0; }
+ virtual void processAll()
+ {
+ }
/*! \brief
* Adds a value to the storage.
* called more than once from one convertValue() invocation, or if
* ::efConversionMayNotAddValues is specified.
*/
- int addValue(const T &value);
+ void addValue(const T &value);
/*! \brief
* Store values in alternate locations.
*
// Copy and assign disallowed by base.
};
-/*! \brief
- * Helper function for creating storage objects.
- *
- * \tparam T Type of the settings object (derived from OptionTemplate).
- * \tparam S Type of the storage object (derived from OptionStorageTemplate).
- * \param[in] settings Settings object to pass to S::init().
- * \param[in] options Options object to pass to S::init().
- * \param[out] output Pointer to the created storage object.
- * \returns The return value of S::init().
- *
- * Creates a new instance of S and calls the init() method with the provided
- * parameters. If the initialization fails, destroys the partially constructed
- * object.
- *
- * \inlibraryapi
- */
-template <class T, class S> int
-createOptionStorage(const T *settings, Options *options,
- AbstractOptionStorage **output)
-{
- S *storage = new S;
- int rc = storage->init(*settings, options);
- if (rc != 0)
- {
- delete storage;
- return rc;
- }
- *output = storage;
- return 0;
-}
-
-
-template <typename T>
-OptionStorageTemplate<T>::OptionStorageTemplate()
- : _values(NULL), _store(NULL), _storeArray(NULL), _nvalptr(NULL),
- _defaultValueIfSet(NULL)
-{
-}
-
-
-template <typename T>
-OptionStorageTemplate<T>::~OptionStorageTemplate()
-{
- if (!hasFlag(efExternalValueVector))
- {
- delete _values;
- }
- delete _defaultValueIfSet;
-}
-
template <typename T>
template <class U>
-int OptionStorageTemplate<T>::init(const OptionTemplate<T, U> &settings, Options *options)
+OptionStorageTemplate<T>::OptionStorageTemplate(const OptionTemplate<T, U> &settings,
+ Options *options,
+ OptionFlags staticFlags)
+ : AbstractOptionStorage(settings, options, staticFlags),
+ _values(settings._storeVector),
+ _store(settings._store),
+ _storeArray(settings._storeArray),
+ _nvalptr(settings._nvalptr),
+ _defaultValueIfSet(NULL)
{
// It's impossible for the caller to do proper memory management if
// the provided memory is not initialized as NULL.
- assert(settings._storeArray == NULL || *settings._storeArray == NULL);
- int rc = AbstractOptionStorage::init(settings, options);
- if (rc != 0)
- {
- return rc;
- }
- _store = settings._store;
- _storeArray = settings._storeArray;
- _nvalptr = settings._nvalptr;
- _values = settings._storeVector;
+ GMX_RELEASE_ASSERT(settings._storeArray == NULL || *settings._storeArray == NULL,
+ "Incorrect or unsafe usage");
if (!_values)
{
// The flag should be set for proper error checking.
- assert(!hasFlag(efExternalValueVector));
+ GMX_RELEASE_ASSERT(!hasFlag(efExternalValueVector),
+ "Internal inconsistency");
_values = new std::vector<T>;
}
- // If the option does not support default values, one should not be set.
- assert(!hasFlag(efNoDefaultValue)
- || (settings._defaultValue == NULL
- && settings._defaultValueIfSet == NULL));
+ GMX_RELEASE_ASSERT(!hasFlag(efNoDefaultValue)
+ || (settings._defaultValue == NULL
+ && settings._defaultValueIfSet == NULL),
+ "Option does not support default value, but one is set");
if (!hasFlag(efNoDefaultValue))
{
if (settings._defaultValue != NULL)
_defaultValueIfSet = new T(*settings._defaultValueIfSet);
}
}
- return 0;
+}
+
+
+template <typename T>
+OptionStorageTemplate<T>::~OptionStorageTemplate()
+{
+ if (!hasFlag(efExternalValueVector))
+ {
+ delete _values;
+ }
+ delete _defaultValueIfSet;
}
template <typename T>
-int OptionStorageTemplate<T>::addValue(const T &value)
+void OptionStorageTemplate<T>::addValue(const T &value)
{
- int rc = incrementValueCount();
- if (rc == 0)
- {
- _values->push_back(value);
- }
- return rc;
+ incrementValueCount();
+ _values->push_back(value);
}
}
if (bDoArray && _storeArray != NULL)
{
- assert(*_storeArray == NULL);
+ GMX_RELEASE_ASSERT(*_storeArray == NULL,
+ "processValues() called more than once with bDoArray == true");
*_storeArray = new T[_values->size()];
}
for (size_t i = _values->size() - nvalues; i < _values->size(); ++i)
#include <gmock/gmock.h>
#include <gtest/gtest.h>
-#include "gromacs/fatalerror/fatalerror.h"
-#include "gromacs/errorreporting/emptyerrorreporter.h"
+#include "gromacs/fatalerror/exceptions.h"
#include "gromacs/options/abstractoption.h"
#include "gromacs/options/options.h"
#include "gromacs/options/optionstoragetemplate.h"
*
* \param[in] settings Storage settings.
* \param[in] options Options object.
- * \retval 0 on success.
*/
- int init(const MockOption &settings, gmx::Options *options);
+ MockOptionStorage(const MockOption &settings, gmx::Options *options);
- /*! \brief
- * Calls addValue() in the base class and expects it to succeed.
- */
- void addValue(const std::string &value)
- {
- EXPECT_EQ(0, MyBase::addValue(value));
- }
- /*! \brief
- * Calls addValue() in the base class and expects it to fail.
- */
- void addValueExpectFail(const std::string &value)
- {
- EXPECT_NE(0, MyBase::addValue(value));
- }
/*! \brief
* Calls processAll() in the base class.
*/
- int processAllBase(gmx::AbstractErrorReporter *errors)
+ void processAllBase()
{
- return MyBase::processAll(errors);
+ MyBase::processAll();
}
/*! \brief
- * Calls addValue("dummy") in the base class and expects it to succeed.
+ * Calls addValue("dummy") in the base class.
*/
void addDummyValue()
{
addValue("dummy");
}
- /*! \brief
- * Calls addValue("dummy") in the base class and expects it to fail.
- */
- void addDummyValueExpectFail()
- {
- addValueExpectFail("dummy");
- }
/*! \brief
* Calls setFlag(efSet).
*/
{
setFlag(gmx::efSet);
}
+ using MyBase::addValue;
virtual const char *typeString() const { return "mock"; }
virtual std::string formatValue(int /*i*/) const { return ""; }
- MOCK_METHOD2(convertValue, int(const std::string &value,
- gmx::AbstractErrorReporter *errors));
- MOCK_METHOD2(processSet, int(int nvalues,
- gmx::AbstractErrorReporter *errors));
- MOCK_METHOD1(processAll, int(gmx::AbstractErrorReporter *errors));
+ MOCK_METHOD1(convertValue, void(const std::string &value));
+ MOCK_METHOD1(processSet, void(int nvalues));
+ MOCK_METHOD0(processAll, void());
};
/*! \internal \brief
{ _storagePtr = storagePtr; return me(); }
private:
- virtual int createDefaultStorage(gmx::Options *options,
- gmx::AbstractOptionStorage **storage) const
+ virtual gmx::AbstractOptionStorage *createDefaultStorage(gmx::Options *options) const
{
- int rc = gmx::createOptionStorage<MockOption, MockOptionStorage>(this, options, storage);
+ MockOptionStorage *storage = new MockOptionStorage(*this, options);
if (_storagePtr != NULL)
{
- *_storagePtr = static_cast<MockOptionStorage *>(*storage);
+ *_storagePtr = storage;
}
- return rc;
+ return storage;
}
MockOptionStorage **_storagePtr;
};
-int MockOptionStorage::init(const MockOption &settings, gmx::Options *options)
+MockOptionStorage::MockOptionStorage(const MockOption &settings, gmx::Options *options)
+ : MyBase(settings, options)
{
using ::testing::_;
- using ::testing::DoAll;
using ::testing::Invoke;
- using ::testing::Return;
using ::testing::WithArg;
- ON_CALL(*this, convertValue(_, _))
- .WillByDefault(DoAll(WithArg<0>(Invoke(this, &MockOptionStorage::addValue)),
- Return(0)));
- ON_CALL(*this, processAll(_))
+ ON_CALL(*this, convertValue(_))
+ .WillByDefault(WithArg<0>(Invoke(this, &MockOptionStorage::addValue)));
+ ON_CALL(*this, processAll())
.WillByDefault(Invoke(this, &MockOptionStorage::processAllBase));
- return MyBase::init(settings, options);
}
namespace
gmx::Options options(NULL, NULL);
std::vector<std::string> values;
MockOptionStorage *mock;
- options.addOption(MockOption("name").storageObject(&mock).required()
- .storeVector(&values));
+ ASSERT_NO_THROW(options.addOption(
+ MockOption("name").storageObject(&mock).required()
+ .storeVector(&values)));
{
::testing::InSequence dummy;
- using ::testing::_;
using ::testing::DoAll;
- using ::testing::Return;
using ::testing::InvokeWithoutArgs;
- EXPECT_CALL(*mock, processAll(_))
+ EXPECT_CALL(*mock, processAll())
.WillOnce(DoAll(InvokeWithoutArgs(mock, &MockOptionStorage::setOption),
- InvokeWithoutArgs(mock, &MockOptionStorage::addDummyValue),
- Return(0)));
+ InvokeWithoutArgs(mock, &MockOptionStorage::addDummyValue)));
}
- gmx::EmptyErrorReporter errors;
- gmx::OptionsAssigner assigner(&options, &errors);
- EXPECT_EQ(0, assigner.finish());
- EXPECT_EQ(0, options.finish(&errors));
+ gmx::OptionsAssigner assigner(&options);
+ EXPECT_NO_THROW(assigner.start());
+ EXPECT_NO_THROW(assigner.finish());
+ EXPECT_NO_THROW(options.finish());
ASSERT_EQ(1U, values.size());
EXPECT_EQ("dummy", values[0]);
gmx::Options options(NULL, NULL);
std::vector<std::string> values;
MockOptionStorage *mock;
- options.addOption(MockOption("name").storageObject(&mock).mayNotAddValues()
- .storeVector(&values).multiValue());
+ ASSERT_NO_THROW(options.addOption(
+ MockOption("name").storageObject(&mock).mayNotAddValues()
+ .storeVector(&values).multiValue()));
{
::testing::InSequence dummy;
- using ::testing::_;
using ::testing::Return;
- EXPECT_CALL(*mock, convertValue("a", _));
- EXPECT_CALL(*mock, convertValue("b", _))
- .WillOnce(Return(0));
- EXPECT_CALL(*mock, convertValue("c", _));
- EXPECT_CALL(*mock, processSet(2, _));
- EXPECT_CALL(*mock, processAll(_));
+ EXPECT_CALL(*mock, convertValue("a"));
+ EXPECT_CALL(*mock, convertValue("b"))
+ .WillOnce(Return());
+ EXPECT_CALL(*mock, convertValue("c"));
+ EXPECT_CALL(*mock, processSet(2));
+ EXPECT_CALL(*mock, processAll());
}
- gmx::EmptyErrorReporter errors;
- gmx::OptionsAssigner assigner(&options, &errors);
- EXPECT_EQ(0, assigner.startOption("name"));
- EXPECT_EQ(0, assigner.appendValue("a"));
- EXPECT_EQ(0, assigner.appendValue("b"));
- EXPECT_EQ(0, assigner.appendValue("c"));
- EXPECT_EQ(0, assigner.finish());
- EXPECT_EQ(0, options.finish(&errors));
+ gmx::OptionsAssigner assigner(&options);
+ EXPECT_NO_THROW(assigner.start());
+ ASSERT_NO_THROW(assigner.startOption("name"));
+ EXPECT_NO_THROW(assigner.appendValue("a"));
+ EXPECT_NO_THROW(assigner.appendValue("b"));
+ EXPECT_NO_THROW(assigner.appendValue("c"));
+ EXPECT_NO_THROW(assigner.finishOption());
+ EXPECT_NO_THROW(assigner.finish());
+ EXPECT_NO_THROW(options.finish());
ASSERT_EQ(2U, values.size());
EXPECT_EQ("a", values[0]);
gmx::Options options(NULL, NULL);
std::vector<std::string> values;
MockOptionStorage *mock;
- options.addOption(MockOption("name").storageObject(&mock)
- .storeVector(&values).multiValue());
+ ASSERT_NO_THROW(options.addOption(
+ MockOption("name").storageObject(&mock)
+ .storeVector(&values).multiValue()));
{
::testing::InSequence dummy;
- using ::testing::_;
using ::testing::DoAll;
using ::testing::InvokeWithoutArgs;
- using ::testing::Return;
- EXPECT_CALL(*mock, convertValue("a", _));
- EXPECT_CALL(*mock, convertValue("b", _))
+ EXPECT_CALL(*mock, convertValue("a"));
+ EXPECT_CALL(*mock, convertValue("b"))
.WillOnce(DoAll(InvokeWithoutArgs(mock, &MockOptionStorage::addDummyValue),
- InvokeWithoutArgs(mock, &MockOptionStorage::addDummyValue),
- Return(0)));
- EXPECT_CALL(*mock, processSet(3, _));
- EXPECT_CALL(*mock, processAll(_));
+ InvokeWithoutArgs(mock, &MockOptionStorage::addDummyValue)));
+ EXPECT_CALL(*mock, processSet(3));
+ EXPECT_CALL(*mock, processAll());
}
- gmx::EmptyErrorReporter errors;
- gmx::OptionsAssigner assigner(&options, &errors);
- EXPECT_EQ(0, assigner.startOption("name"));
- EXPECT_EQ(0, assigner.appendValue("a"));
- EXPECT_EQ(0, assigner.appendValue("b"));
- EXPECT_EQ(0, assigner.finish());
- EXPECT_EQ(0, options.finish(&errors));
+ gmx::OptionsAssigner assigner(&options);
+ EXPECT_NO_THROW(assigner.start());
+ ASSERT_NO_THROW(assigner.startOption("name"));
+ EXPECT_NO_THROW(assigner.appendValue("a"));
+ EXPECT_NO_THROW(assigner.appendValue("b"));
+ EXPECT_NO_THROW(assigner.finishOption());
+ EXPECT_NO_THROW(assigner.finish());
+ EXPECT_NO_THROW(options.finish());
ASSERT_EQ(3U, values.size());
EXPECT_EQ("a", values[0]);
gmx::Options options(NULL, NULL);
std::vector<std::string> values;
MockOptionStorage *mock;
- options.addOption(MockOption("name").storageObject(&mock)
- .storeVector(&values).valueCount(2));
+ ASSERT_NO_THROW(options.addOption(
+ MockOption("name").storageObject(&mock)
+ .storeVector(&values).valueCount(2)));
{
::testing::InSequence dummy;
- using ::testing::_;
using ::testing::DoAll;
using ::testing::InvokeWithoutArgs;
- using ::testing::Return;
- EXPECT_CALL(*mock, convertValue("a", _));
- EXPECT_CALL(*mock, convertValue("b", _))
+ EXPECT_CALL(*mock, convertValue("a"));
+ EXPECT_CALL(*mock, convertValue("b"))
.WillOnce(DoAll(InvokeWithoutArgs(mock, &MockOptionStorage::addDummyValue),
- InvokeWithoutArgs(mock, &MockOptionStorage::addDummyValueExpectFail),
- Return(gmx::eeInvalidInput)));
- EXPECT_CALL(*mock, processSet(2, _));
- EXPECT_CALL(*mock, processAll(_));
+ InvokeWithoutArgs(mock, &MockOptionStorage::addDummyValue)));
+ EXPECT_CALL(*mock, processSet(2));
+ EXPECT_CALL(*mock, processAll());
}
- gmx::EmptyErrorReporter errors;
- gmx::OptionsAssigner assigner(&options, &errors);
- EXPECT_EQ(0, assigner.startOption("name"));
- EXPECT_EQ(0, assigner.appendValue("a"));
- EXPECT_NE(0, assigner.appendValue("b"));
- EXPECT_NE(0, assigner.finish());
- EXPECT_EQ(0, options.finish(&errors));
+ gmx::OptionsAssigner assigner(&options);
+ EXPECT_NO_THROW(assigner.start());
+ ASSERT_NO_THROW(assigner.startOption("name"));
+ EXPECT_NO_THROW(assigner.appendValue("a"));
+ EXPECT_THROW(assigner.appendValue("b"), gmx::InvalidInputError);
+ EXPECT_NO_THROW(assigner.finishOption());
+ EXPECT_NO_THROW(assigner.finish());
+ EXPECT_NO_THROW(options.finish());
ASSERT_EQ(2U, values.size());
EXPECT_EQ("a", values[0]);
gmx::Options options(NULL, NULL);
std::vector<std::string> values;
MockOptionStorage *mock;
- options.addOption(MockOption("name").storageObject(&mock).mayNotAddValues()
- .storeVector(&values).valueCount(0));
+ ASSERT_NO_THROW(options.addOption(
+ MockOption("name").storageObject(&mock).mayNotAddValues()
+ .storeVector(&values).valueCount(0)));
{
::testing::InSequence dummy;
using ::testing::_;
using ::testing::DoAll;
- using ::testing::InvokeWithoutArgs;
using ::testing::Return;
- EXPECT_CALL(*mock, convertValue("a", _))
- .WillOnce(Return(0));
- EXPECT_CALL(*mock, processSet(0, _));
- EXPECT_CALL(*mock, processAll(_));
+ EXPECT_CALL(*mock, convertValue("a"))
+ .WillOnce(Return());
+ EXPECT_CALL(*mock, processSet(0));
+ EXPECT_CALL(*mock, processAll());
}
- gmx::EmptyErrorReporter errors;
- gmx::OptionsAssigner assigner(&options, &errors);
- EXPECT_EQ(0, assigner.startOption("name"));
- EXPECT_EQ(0, assigner.appendValue("a"));
- EXPECT_EQ(0, assigner.finish());
- EXPECT_EQ(0, options.finish(&errors));
+ gmx::OptionsAssigner assigner(&options);
+ EXPECT_NO_THROW(assigner.start());
+ EXPECT_NO_THROW(assigner.startOption("name"));
+ EXPECT_NO_THROW(assigner.appendValue("a"));
+ EXPECT_NO_THROW(assigner.finishOption());
+ EXPECT_NO_THROW(assigner.finish());
+ EXPECT_NO_THROW(options.finish());
ASSERT_EQ(0U, values.size());
}
#include <gtest/gtest.h>
-#include "gromacs/errorreporting/emptyerrorreporter.h"
#include "gromacs/options/basicoptions.h"
#include "gromacs/options/cmdlineparser.h"
#include "gromacs/options/options.h"
void createArguments(const char *cmdline[]);
gmx::Options _options;
- gmx::EmptyErrorReporter _errors;
gmx::CommandLineParser _parser;
bool _flag;
std::vector<int> _ivalues;
};
CommandLineParserTest::CommandLineParserTest()
- : _options(NULL, NULL), _parser(&_options, &_errors),
+ : _options(NULL, NULL), _parser(&_options),
_flag(false),
_argc(0), _argv(NULL)
{
{
const char *cmdline[] = {"-flag", "yes", "-mvi", "2", "-mvd", "2.7", NULL};
createArguments(cmdline);
- ASSERT_EQ(0, _parser.parse(&_argc, _argv));
- ASSERT_EQ(0, _options.finish(&_errors));
+ ASSERT_NO_THROW(_parser.parse(&_argc, _argv));
+ ASSERT_NO_THROW(_options.finish());
EXPECT_TRUE(_flag);
ASSERT_EQ(1U, _ivalues.size());
*/
/*! \internal \file
* \brief
- * Tests construction of basic option types.
+ * Tests creation of basic option types.
*
* Most of the tests for the basic options are in optionsassigner.cpp.
- * This file only tests behavior that should fail in parameter construction,
- * which would result in higher-level code asserting.
+ * This file only tests behavior that should fail in initialization.
*
* \author Teemu Murtola <teemu.murtola@cbr.su.se>
* \ingroup module_options
#include <gtest/gtest.h>
+#include "gromacs/fatalerror/exceptions.h"
#include "gromacs/options/basicoptions.h"
-
-#include "../basicoptionstorage.h"
+#include "gromacs/options/options.h"
namespace
{
-TEST(OptionTest, SetsNameAndDescription)
-{
- gmx::IntegerOptionStorage option;
- int value = -1;
- using gmx::IntegerOption;
- ASSERT_EQ(0, option.init(IntegerOption("name").store(&value)
- .description("Description"), NULL));
- EXPECT_EQ("name", option.name());
- EXPECT_EQ("Description", option.description());
- EXPECT_FALSE(option.isSet());
-}
-
-TEST(OptionTest, FailsOnNonsafeStorage)
+TEST(OptionsTest, FailsOnNonsafeStorage)
{
- gmx::IntegerOptionStorage option;
+ gmx::Options options(NULL, NULL);
int value = -1;
using gmx::IntegerOption;
- ASSERT_NE(0, option.init(IntegerOption("name").store(&value)
- .multiValue(), NULL));
+ ASSERT_THROW(options.addOption(IntegerOption("name").store(&value)
+ .multiValue()),
+ gmx::APIError);
}
-TEST(OptionTest, FailsOnIncorrectEnumDefaultValue)
+TEST(OptionsTest, FailsOnIncorrectEnumDefaultValue)
{
- gmx::StringOptionStorage option;
+ gmx::Options options(NULL, NULL);
std::string value;
const char * const allowed[] = { "none", "test", "value", NULL };
using gmx::StringOption;
- ASSERT_NE(0, option.init(StringOption("name").store(&value)
- .enumValue(allowed)
- .defaultValue("unknown"), NULL));
+ ASSERT_THROW(options.addOption(StringOption("name").store(&value)
+ .enumValue(allowed)
+ .defaultValue("unknown")),
+ gmx::APIError);
}
} // namespace
#include <gtest/gtest.h>
-#include "gromacs/errorreporting/emptyerrorreporter.h"
+#include "gromacs/fatalerror/exceptions.h"
#include "gromacs/options/basicoptions.h"
#include "gromacs/options/options.h"
#include "gromacs/options/optionsassigner.h"
gmx::Options options(NULL, NULL);
int value = 0;
using gmx::IntegerOption;
- options.addOption(IntegerOption("p").store(&value).required());
+ ASSERT_NO_THROW(options.addOption(
+ IntegerOption("p").store(&value).required()));
- gmx::EmptyErrorReporter errors;
- EXPECT_NE(0, options.finish(&errors));
+ EXPECT_THROW(options.finish(), gmx::InvalidInputError);
}
TEST(OptionsAssignerTest, HandlesInvalidMultipleParameter)
gmx::Options options(NULL, NULL);
std::vector<int> values;
using gmx::IntegerOption;
- options.addOption(IntegerOption("p").storeVector(&values).multiValue());
-
- gmx::EmptyErrorReporter errors;
- gmx::OptionsAssigner assigner(&options, &errors);
- EXPECT_EQ(0, assigner.startOption("p"));
- EXPECT_EQ(0, assigner.appendValue("1"));
- EXPECT_NE(0, assigner.startOption("p"));
- EXPECT_NE(0, assigner.finish());
+ ASSERT_NO_THROW(options.addOption(
+ IntegerOption("p").storeVector(&values).multiValue()));
+
+ gmx::OptionsAssigner assigner(&options);
+ EXPECT_NO_THROW(assigner.start());
+ ASSERT_NO_THROW(assigner.startOption("p"));
+ ASSERT_NO_THROW(assigner.appendValue("1"));
+ ASSERT_NO_THROW(assigner.finishOption());
+ EXPECT_THROW(assigner.startOption("p"), gmx::InvalidInputError);
+ EXPECT_NO_THROW(assigner.finish());
+ EXPECT_NO_THROW(options.finish());
}
TEST(OptionsAssignerTest, HandlesMultipleParameter)
gmx::Options options(NULL, NULL);
std::vector<int> values;
using gmx::IntegerOption;
- options.addOption(IntegerOption("p").storeVector(&values).allowMultiple());
-
- gmx::EmptyErrorReporter errors;
- gmx::OptionsAssigner assigner(&options, &errors);
- EXPECT_EQ(0, assigner.startOption("p"));
- EXPECT_EQ(0, assigner.appendValue("1"));
- EXPECT_EQ(0, assigner.startOption("p"));
- EXPECT_EQ(0, assigner.appendValue("2"));
- EXPECT_EQ(0, assigner.finish());
- EXPECT_EQ(0, options.finish(&errors));
+ ASSERT_NO_THROW(options.addOption(
+ IntegerOption("p").storeVector(&values).allowMultiple()));
+
+ gmx::OptionsAssigner assigner(&options);
+ EXPECT_NO_THROW(assigner.start());
+ ASSERT_NO_THROW(assigner.startOption("p"));
+ ASSERT_NO_THROW(assigner.appendValue("1"));
+ EXPECT_NO_THROW(assigner.finishOption());
+ ASSERT_NO_THROW(assigner.startOption("p"));
+ ASSERT_NO_THROW(assigner.appendValue("2"));
+ EXPECT_NO_THROW(assigner.finishOption());
+ EXPECT_NO_THROW(assigner.finish());
+ EXPECT_NO_THROW(options.finish());
+
EXPECT_TRUE(options.isSet("p"));
ASSERT_EQ(2U, values.size());
EXPECT_EQ(1, values[0]);
gmx::Options options(NULL, NULL);
int value1 = 0, value2 = 0;
using gmx::IntegerOption;
- options.addOption(IntegerOption("p").store(&value1));
- options.addOption(IntegerOption("q").store(&value2));
-
- gmx::EmptyErrorReporter errors;
- gmx::OptionsAssigner assigner(&options, &errors);
- EXPECT_EQ(0, assigner.startOption("p"));
- EXPECT_EQ(0, assigner.startOption("q"));
- EXPECT_EQ(0, assigner.appendValue("2"));
- EXPECT_NE(0, assigner.finish());
+ ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value1)));
+ ASSERT_NO_THROW(options.addOption(IntegerOption("q").store(&value2)));
+
+ gmx::OptionsAssigner assigner(&options);
+ EXPECT_NO_THROW(assigner.start());
+ ASSERT_NO_THROW(assigner.startOption("p"));
+ EXPECT_THROW(assigner.finishOption(), gmx::InvalidInputError);
+ ASSERT_NO_THROW(assigner.startOption("q"));
+ ASSERT_NO_THROW(assigner.appendValue("2"));
+ EXPECT_NO_THROW(assigner.finishOption());
+ EXPECT_NO_THROW(assigner.finish());
+ EXPECT_NO_THROW(options.finish());
}
TEST(OptionsAssignerTest, HandlesExtraValue)
gmx::Options options(NULL, NULL);
int value1 = 0;
using gmx::IntegerOption;
- options.addOption(IntegerOption("p").store(&value1));
-
- gmx::EmptyErrorReporter errors;
- gmx::OptionsAssigner assigner(&options, &errors);
- EXPECT_EQ(0, assigner.startOption("p"));
- EXPECT_EQ(0, assigner.appendValue("2"));
- EXPECT_NE(0, assigner.appendValue("3"));
- EXPECT_NE(0, assigner.finish());
+ ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value1)));
+
+ gmx::OptionsAssigner assigner(&options);
+ EXPECT_NO_THROW(assigner.start());
+ ASSERT_NO_THROW(assigner.startOption("p"));
+ ASSERT_NO_THROW(assigner.appendValue("2"));
+ EXPECT_THROW(assigner.appendValue("3"), gmx::InvalidInputError);
+ EXPECT_NO_THROW(assigner.finishOption());
+ EXPECT_NO_THROW(assigner.finish());
+ EXPECT_NO_THROW(options.finish());
}
TEST(OptionsAssignerTest, HandlesSubSections)
int value1 = 1;
int value2 = 2;
using gmx::IntegerOption;
- options.addOption(IntegerOption("p").store(&value));
- sub1.addOption(IntegerOption("p").store(&value1));
- sub2.addOption(IntegerOption("p").store(&value2));
- options.addSubSection(&sub1);
- options.addSubSection(&sub2);
-
- gmx::EmptyErrorReporter errors;
- gmx::OptionsAssigner assigner(&options, &errors);
- EXPECT_EQ(0, assigner.startSubSection("section1"));
- EXPECT_EQ(0, assigner.startOption("p"));
- EXPECT_EQ(0, assigner.appendValue("5"));
- EXPECT_EQ(0, assigner.finishSubSection());
- EXPECT_EQ(0, assigner.startOption("p"));
- EXPECT_EQ(0, assigner.appendValue("4"));
- EXPECT_EQ(0, assigner.startSubSection("section2"));
- EXPECT_EQ(0, assigner.startOption("p"));
- EXPECT_EQ(0, assigner.appendValue("6"));
- EXPECT_EQ(0, assigner.finish());
- EXPECT_EQ(0, options.finish(&errors));
+ ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
+ ASSERT_NO_THROW(sub1.addOption(IntegerOption("p").store(&value1)));
+ ASSERT_NO_THROW(sub2.addOption(IntegerOption("p").store(&value2)));
+ ASSERT_NO_THROW(options.addSubSection(&sub1));
+ ASSERT_NO_THROW(options.addSubSection(&sub2));
+
+ gmx::OptionsAssigner assigner(&options);
+ EXPECT_NO_THROW(assigner.start());
+ ASSERT_NO_THROW(assigner.startSubSection("section1"));
+ ASSERT_NO_THROW(assigner.startOption("p"));
+ EXPECT_NO_THROW(assigner.appendValue("5"));
+ EXPECT_NO_THROW(assigner.finishOption());
+ EXPECT_NO_THROW(assigner.finishSubSection());
+ ASSERT_NO_THROW(assigner.startOption("p"));
+ EXPECT_NO_THROW(assigner.appendValue("4"));
+ EXPECT_NO_THROW(assigner.finishOption());
+ ASSERT_NO_THROW(assigner.startSubSection("section2"));
+ ASSERT_NO_THROW(assigner.startOption("p"));
+ EXPECT_NO_THROW(assigner.appendValue("6"));
+ EXPECT_NO_THROW(assigner.finishOption());
+ EXPECT_NO_THROW(assigner.finishSubSection());
+ EXPECT_NO_THROW(assigner.finish());
+ EXPECT_NO_THROW(options.finish());
EXPECT_EQ(4, value);
EXPECT_EQ(5, value1);
int pvalue2 = 2;
int rvalue = 5;
using gmx::IntegerOption;
- options.addOption(IntegerOption("p").store(&pvalue));
- sub1.addOption(IntegerOption("p").store(&pvalue1));
- sub1.addOption(IntegerOption("q").store(&qvalue));
- sub2.addOption(IntegerOption("p").store(&pvalue2));
- sub2.addOption(IntegerOption("r").store(&rvalue));
- options.addSubSection(&sub1);
- options.addSubSection(&sub2);
-
- gmx::EmptyErrorReporter errors;
- gmx::OptionsAssigner assigner(&options, &errors);
+ ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&pvalue)));
+ ASSERT_NO_THROW(sub1.addOption(IntegerOption("p").store(&pvalue1)));
+ ASSERT_NO_THROW(sub1.addOption(IntegerOption("q").store(&qvalue)));
+ ASSERT_NO_THROW(sub2.addOption(IntegerOption("p").store(&pvalue2)));
+ ASSERT_NO_THROW(sub2.addOption(IntegerOption("r").store(&rvalue)));
+ ASSERT_NO_THROW(options.addSubSection(&sub1));
+ ASSERT_NO_THROW(options.addSubSection(&sub2));
+
+ gmx::OptionsAssigner assigner(&options);
assigner.setNoStrictSectioning(true);
- EXPECT_EQ(0, assigner.startOption("q"));
- EXPECT_EQ(0, assigner.appendValue("6"));
- EXPECT_EQ(0, assigner.startOption("p"));
- EXPECT_EQ(0, assigner.appendValue("7"));
- EXPECT_EQ(0, assigner.startOption("r"));
- EXPECT_EQ(0, assigner.appendValue("8"));
- EXPECT_EQ(0, assigner.startOption("p"));
- EXPECT_EQ(0, assigner.appendValue("9"));
- EXPECT_EQ(0, assigner.finishSubSection());
- EXPECT_EQ(0, assigner.startOption("p"));
- EXPECT_EQ(0, assigner.appendValue("10"));
- EXPECT_EQ(0, assigner.finish());
- EXPECT_EQ(0, options.finish(&errors));
+ EXPECT_NO_THROW(assigner.start());
+ ASSERT_NO_THROW(assigner.startOption("q"));
+ EXPECT_NO_THROW(assigner.appendValue("6"));
+ EXPECT_NO_THROW(assigner.finishOption());
+ ASSERT_NO_THROW(assigner.startOption("p"));
+ EXPECT_NO_THROW(assigner.appendValue("7"));
+ EXPECT_NO_THROW(assigner.finishOption());
+ ASSERT_NO_THROW(assigner.startOption("r"));
+ EXPECT_NO_THROW(assigner.appendValue("8"));
+ EXPECT_NO_THROW(assigner.finishOption());
+ ASSERT_NO_THROW(assigner.startOption("p"));
+ EXPECT_NO_THROW(assigner.appendValue("9"));
+ EXPECT_NO_THROW(assigner.finishOption());
+ EXPECT_NO_THROW(assigner.finishSubSection());
+ ASSERT_NO_THROW(assigner.startOption("p"));
+ EXPECT_NO_THROW(assigner.appendValue("10"));
+ EXPECT_NO_THROW(assigner.finishOption());
+ EXPECT_NO_THROW(assigner.finish());
+ EXPECT_NO_THROW(options.finish());
EXPECT_EQ(6, qvalue);
EXPECT_EQ(7, pvalue1);
gmx::Options options(NULL, NULL);
int value = -1;
using gmx::IntegerOption;
- options.addOption(IntegerOption("p").store(&value));
-
- gmx::EmptyErrorReporter errors;
- gmx::OptionsAssigner assigner(&options, &errors);
- EXPECT_EQ(0, assigner.start());
- EXPECT_EQ(0, assigner.startOption("p"));
- EXPECT_EQ(0, assigner.appendValue("1"));
- EXPECT_EQ(0, assigner.finish());
- gmx::OptionsAssigner assigner2(&options, &errors);
- EXPECT_EQ(0, assigner2.start());
- EXPECT_EQ(0, assigner2.startOption("p"));
- EXPECT_EQ(0, assigner2.appendValue("2"));
- EXPECT_EQ(0, assigner2.finish());
- EXPECT_EQ(0, options.finish(&errors));
+ ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
+
+ {
+ gmx::OptionsAssigner assigner(&options);
+ EXPECT_NO_THROW(assigner.start());
+ ASSERT_NO_THROW(assigner.startOption("p"));
+ EXPECT_NO_THROW(assigner.appendValue("1"));
+ EXPECT_NO_THROW(assigner.finishOption());
+ EXPECT_NO_THROW(assigner.finish());
+ }
+ {
+ gmx::OptionsAssigner assigner2(&options);
+ EXPECT_NO_THROW(assigner2.start());
+ ASSERT_NO_THROW(assigner2.startOption("p"));
+ EXPECT_NO_THROW(assigner2.appendValue("2"));
+ EXPECT_NO_THROW(assigner2.finishOption());
+ EXPECT_NO_THROW(assigner2.finish());
+ }
+ EXPECT_NO_THROW(options.finish());
EXPECT_EQ(2, value);
}
gmx::Options options(NULL, NULL);
bool value = false;
using gmx::BooleanOption;
- options.addOption(BooleanOption("p").store(&value));
+ ASSERT_NO_THROW(options.addOption(BooleanOption("p").store(&value)));
- gmx::EmptyErrorReporter errors;
- gmx::OptionsAssigner assigner(&options, &errors);
- EXPECT_EQ(0, assigner.startOption("p"));
- EXPECT_EQ(0, assigner.appendValue("yes"));
- EXPECT_EQ(0, assigner.finish());
- EXPECT_EQ(0, options.finish(&errors));
+ gmx::OptionsAssigner assigner(&options);
+ EXPECT_NO_THROW(assigner.start());
+ ASSERT_NO_THROW(assigner.startOption("p"));
+ EXPECT_NO_THROW(assigner.appendValue("yes"));
+ EXPECT_NO_THROW(assigner.finishOption());
+ EXPECT_NO_THROW(assigner.finish());
+ EXPECT_NO_THROW(options.finish());
EXPECT_TRUE(value);
}
gmx::Options options(NULL, NULL);
bool value = false;
using gmx::BooleanOption;
- options.addOption(BooleanOption("p").store(&value));
+ ASSERT_NO_THROW(options.addOption(BooleanOption("p").store(&value)));
- gmx::EmptyErrorReporter errors;
- gmx::OptionsAssigner assigner(&options, &errors);
- EXPECT_EQ(0, assigner.startOption("p"));
- EXPECT_EQ(0, assigner.finish());
- EXPECT_EQ(0, options.finish(&errors));
+ gmx::OptionsAssigner assigner(&options);
+ EXPECT_NO_THROW(assigner.start());
+ ASSERT_NO_THROW(assigner.startOption("p"));
+ EXPECT_NO_THROW(assigner.finishOption());
+ EXPECT_NO_THROW(assigner.finish());
+ EXPECT_NO_THROW(options.finish());
EXPECT_TRUE(value);
}
gmx::Options options(NULL, NULL);
bool value = true;
using gmx::BooleanOption;
- options.addOption(BooleanOption("p").store(&value));
+ ASSERT_NO_THROW(options.addOption(BooleanOption("p").store(&value)));
- gmx::EmptyErrorReporter errors;
- gmx::OptionsAssigner assigner(&options, &errors);
+ gmx::OptionsAssigner assigner(&options);
assigner.setAcceptBooleanNoPrefix(true);
- EXPECT_EQ(0, assigner.startOption("nop"));
- EXPECT_EQ(0, assigner.finish());
- EXPECT_EQ(0, options.finish(&errors));
+ EXPECT_NO_THROW(assigner.start());
+ ASSERT_NO_THROW(assigner.startOption("nop"));
+ EXPECT_NO_THROW(assigner.finishOption());
+ EXPECT_NO_THROW(assigner.finish());
+ EXPECT_NO_THROW(options.finish());
EXPECT_FALSE(value);
}
gmx::Options options(NULL, NULL);
bool value = false;
using gmx::BooleanOption;
- options.addOption(BooleanOption("p").store(&value));
+ ASSERT_NO_THROW(options.addOption(BooleanOption("p").store(&value)));
- gmx::EmptyErrorReporter errors;
- gmx::OptionsAssigner assigner(&options, &errors);
+ gmx::OptionsAssigner assigner(&options);
assigner.setAcceptBooleanNoPrefix(true);
- EXPECT_EQ(0, assigner.startOption("nop"));
- assigner.appendValue("no");
- int rc = assigner.finish();
+ EXPECT_NO_THROW(assigner.start());
+ ASSERT_NO_THROW(assigner.startOption("nop"));
// It's OK to fail, but if it doesn't, it should work.
- if (rc == 0)
+ try
{
- EXPECT_EQ(0, options.finish(&errors));
+ assigner.appendValue("no");
+ assigner.finishOption();
+ EXPECT_NO_THROW(assigner.finish());
EXPECT_TRUE(value);
}
+ catch (gmx::InvalidInputError &)
+ {
+ }
}
gmx::Options options(NULL, NULL);
int value = 1;
using gmx::IntegerOption;
- options.addOption(IntegerOption("p").store(&value));
+ ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(&value)));
- gmx::EmptyErrorReporter errors;
- gmx::OptionsAssigner assigner(&options, &errors);
- ASSERT_EQ(0, assigner.startOption("p"));
- ASSERT_EQ(0, assigner.appendValue("3"));
- EXPECT_EQ(0, assigner.finish());
- EXPECT_EQ(0, options.finish(&errors));
+ gmx::OptionsAssigner assigner(&options);
+ EXPECT_NO_THROW(assigner.start());
+ ASSERT_NO_THROW(assigner.startOption("p"));
+ ASSERT_NO_THROW(assigner.appendValue("3"));
+ EXPECT_NO_THROW(assigner.finishOption());
+ EXPECT_NO_THROW(assigner.finish());
+ EXPECT_NO_THROW(options.finish());
EXPECT_EQ(3, value);
}
gmx::Options options(NULL, NULL);
int value = -1;
using gmx::IntegerOption;
- options.addOption(IntegerOption("p").store(&value).defaultValue(2));
+ ASSERT_NO_THROW(options.addOption(
+ IntegerOption("p").store(&value).defaultValue(2)));
EXPECT_EQ(2, value);
- gmx::EmptyErrorReporter errors;
- gmx::OptionsAssigner assigner(&options, &errors);
- EXPECT_EQ(0, assigner.finish());
- EXPECT_EQ(0, options.finish(&errors));
+ gmx::OptionsAssigner assigner(&options);
+ EXPECT_NO_THROW(assigner.start());
+ EXPECT_NO_THROW(assigner.finish());
+ EXPECT_NO_THROW(options.finish());
EXPECT_EQ(2, value);
}
gmx::Options options(NULL, NULL);
int value = -1;
using gmx::IntegerOption;
- options.addOption(IntegerOption("p").store(&value).defaultValueIfSet(2));
+ ASSERT_NO_THROW(options.addOption(
+ IntegerOption("p").store(&value).defaultValueIfSet(2)));
EXPECT_EQ(-1, value);
- gmx::EmptyErrorReporter errors;
- gmx::OptionsAssigner assigner(&options, &errors);
- EXPECT_EQ(0, assigner.startOption("p"));
- EXPECT_EQ(0, assigner.finish());
- EXPECT_EQ(0, options.finish(&errors));
+ gmx::OptionsAssigner assigner(&options);
+ EXPECT_NO_THROW(assigner.start());
+ ASSERT_NO_THROW(assigner.startOption("p"));
+ EXPECT_NO_THROW(assigner.finishOption());
+ EXPECT_NO_THROW(assigner.finish());
+ EXPECT_NO_THROW(options.finish());
EXPECT_EQ(2, value);
}
gmx::Options options(NULL, NULL);
int value = -1;
using gmx::IntegerOption;
- options.addOption(IntegerOption("p").store(&value).defaultValueIfSet(2));
+ ASSERT_NO_THROW(options.addOption(
+ IntegerOption("p").store(&value).defaultValueIfSet(2)));
EXPECT_EQ(-1, value);
- gmx::EmptyErrorReporter errors;
- gmx::OptionsAssigner assigner(&options, &errors);
- EXPECT_EQ(0, assigner.finish());
- EXPECT_EQ(0, options.finish(&errors));
+ gmx::OptionsAssigner assigner(&options);
+ EXPECT_NO_THROW(assigner.start());
+ EXPECT_NO_THROW(assigner.finish());
+ EXPECT_NO_THROW(options.finish());
EXPECT_EQ(-1, value);
}
gmx::Options options(NULL, NULL);
int value = -1;
using gmx::IntegerOption;
- options.addOption(IntegerOption("p").store(&value).defaultValue(1).defaultValueIfSet(2));
+ ASSERT_NO_THROW(options.addOption(
+ IntegerOption("p").store(&value)
+ .defaultValue(1).defaultValueIfSet(2)));
EXPECT_EQ(1, value);
- gmx::EmptyErrorReporter errors;
- gmx::OptionsAssigner assigner(&options, &errors);
- EXPECT_EQ(0, assigner.startOption("p"));
- EXPECT_EQ(0, assigner.finish());
- EXPECT_EQ(0, options.finish(&errors));
+ gmx::OptionsAssigner assigner(&options);
+ EXPECT_NO_THROW(assigner.start());
+ ASSERT_NO_THROW(assigner.startOption("p"));
+ EXPECT_NO_THROW(assigner.finishOption());
+ EXPECT_NO_THROW(assigner.finish());
+ EXPECT_NO_THROW(options.finish());
EXPECT_EQ(2, value);
}
int *values = NULL;
int nval = -1;
using gmx::IntegerOption;
- options.addOption(IntegerOption("p").storeArray(&values, &nval).multiValue());
-
- gmx::EmptyErrorReporter errors;
- gmx::OptionsAssigner assigner(&options, &errors);
- ASSERT_EQ(0, assigner.startOption("p"));
- ASSERT_EQ(0, assigner.appendValue("-2"));
- ASSERT_EQ(0, assigner.appendValue("1"));
- ASSERT_EQ(0, assigner.appendValue("4"));
- EXPECT_EQ(0, assigner.finish());
- EXPECT_EQ(0, options.finish(&errors));
+ ASSERT_NO_THROW(options.addOption(
+ IntegerOption("p").storeArray(&values, &nval)
+ .multiValue()));
+
+ gmx::OptionsAssigner assigner(&options);
+ EXPECT_NO_THROW(assigner.start());
+ ASSERT_NO_THROW(assigner.startOption("p"));
+ ASSERT_NO_THROW(assigner.appendValue("-2"));
+ ASSERT_NO_THROW(assigner.appendValue("1"));
+ ASSERT_NO_THROW(assigner.appendValue("4"));
+ EXPECT_NO_THROW(assigner.finishOption());
+ EXPECT_NO_THROW(assigner.finish());
+ EXPECT_NO_THROW(options.finish());
EXPECT_EQ(3, nval);
EXPECT_EQ(-2, values[0]);
gmx::Options options(NULL, NULL);
std::vector<int> values;
using gmx::IntegerOption;
- options.addOption(IntegerOption("p").storeVector(&values).multiValue());
-
- gmx::EmptyErrorReporter errors;
- gmx::OptionsAssigner assigner(&options, &errors);
- ASSERT_EQ(0, assigner.startOption("p"));
- ASSERT_EQ(0, assigner.appendValue("-2"));
- ASSERT_EQ(0, assigner.appendValue("1"));
- ASSERT_EQ(0, assigner.appendValue("4"));
- EXPECT_EQ(0, assigner.finish());
- EXPECT_EQ(0, options.finish(&errors));
+ ASSERT_NO_THROW(options.addOption(
+ IntegerOption("p").storeVector(&values).multiValue()));
+
+ gmx::OptionsAssigner assigner(&options);
+ EXPECT_NO_THROW(assigner.start());
+ ASSERT_NO_THROW(assigner.startOption("p"));
+ ASSERT_NO_THROW(assigner.appendValue("-2"));
+ ASSERT_NO_THROW(assigner.appendValue("1"));
+ ASSERT_NO_THROW(assigner.appendValue("4"));
+ EXPECT_NO_THROW(assigner.finishOption());
+ EXPECT_NO_THROW(assigner.finish());
+ EXPECT_NO_THROW(options.finish());
EXPECT_EQ(3U, values.size());
EXPECT_EQ(-2, values[0]);
gmx::Options options(NULL, NULL);
int vec[3] = {0, 0, 0};
using gmx::IntegerOption;
- options.addOption(IntegerOption("p").store(vec).vector());
-
- gmx::EmptyErrorReporter errors;
- gmx::OptionsAssigner assigner(&options, &errors);
- ASSERT_EQ(0, assigner.startOption("p"));
- ASSERT_EQ(0, assigner.appendValue("-2"));
- ASSERT_EQ(0, assigner.appendValue("1"));
- ASSERT_EQ(0, assigner.appendValue("4"));
- EXPECT_EQ(0, assigner.finish());
- EXPECT_EQ(0, options.finish(&errors));
+ ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(vec).vector()));
+
+ gmx::OptionsAssigner assigner(&options);
+ EXPECT_NO_THROW(assigner.start());
+ ASSERT_NO_THROW(assigner.startOption("p"));
+ ASSERT_NO_THROW(assigner.appendValue("-2"));
+ ASSERT_NO_THROW(assigner.appendValue("1"));
+ ASSERT_NO_THROW(assigner.appendValue("4"));
+ EXPECT_NO_THROW(assigner.finishOption());
+ EXPECT_NO_THROW(assigner.finish());
+ EXPECT_NO_THROW(options.finish());
EXPECT_EQ(-2, vec[0]);
EXPECT_EQ(1, vec[1]);
gmx::Options options(NULL, NULL);
int vec[3] = {0, 0, 0};
using gmx::IntegerOption;
- options.addOption(IntegerOption("p").store(vec).vector());
+ ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(vec).vector()));
- gmx::EmptyErrorReporter errors;
- gmx::OptionsAssigner assigner(&options, &errors);
- ASSERT_EQ(0, assigner.startOption("p"));
- ASSERT_EQ(0, assigner.appendValue("2"));
- EXPECT_EQ(0, assigner.finish());
- EXPECT_EQ(0, options.finish(&errors));
+ gmx::OptionsAssigner assigner(&options);
+ EXPECT_NO_THROW(assigner.start());
+ ASSERT_NO_THROW(assigner.startOption("p"));
+ ASSERT_NO_THROW(assigner.appendValue("2"));
+ EXPECT_NO_THROW(assigner.finishOption());
+ EXPECT_NO_THROW(assigner.finish());
+ EXPECT_NO_THROW(options.finish());
EXPECT_EQ(2, vec[0]);
EXPECT_EQ(2, vec[1]);
gmx::Options options(NULL, NULL);
int vec[3] = {3, 2, 1};
using gmx::IntegerOption;
- options.addOption(IntegerOption("p").store(vec).vector());
+ ASSERT_NO_THROW(options.addOption(IntegerOption("p").store(vec).vector()));
- gmx::EmptyErrorReporter errors;
- EXPECT_EQ(0, options.finish(&errors));
+ EXPECT_NO_THROW(options.finish());
EXPECT_EQ(3, vec[0]);
EXPECT_EQ(2, vec[1]);
gmx::Options options(NULL, NULL);
double value = 0.0;
using gmx::DoubleOption;
- options.addOption(DoubleOption("p").store(&value));
+ ASSERT_NO_THROW(options.addOption(DoubleOption("p").store(&value)));
- gmx::EmptyErrorReporter errors;
- gmx::OptionsAssigner assigner(&options, &errors);
- ASSERT_EQ(0, assigner.startOption("p"));
- ASSERT_EQ(0, assigner.appendValue("2.7"));
- ASSERT_EQ(0, assigner.finish());
- ASSERT_EQ(0, options.finish(&errors));
+ gmx::OptionsAssigner assigner(&options);
+ EXPECT_NO_THROW(assigner.start());
+ ASSERT_NO_THROW(assigner.startOption("p"));
+ ASSERT_NO_THROW(assigner.appendValue("2.7"));
+ EXPECT_NO_THROW(assigner.finishOption());
+ EXPECT_NO_THROW(assigner.finish());
+ EXPECT_NO_THROW(options.finish());
EXPECT_DOUBLE_EQ(2.7, value);
}
gmx::Options options(NULL, NULL);
std::string value;
using gmx::StringOption;
- options.addOption(StringOption("p").store(&value));
+ ASSERT_NO_THROW(options.addOption(StringOption("p").store(&value)));
- gmx::EmptyErrorReporter errors;
- gmx::OptionsAssigner assigner(&options, &errors);
- ASSERT_EQ(0, assigner.startOption("p"));
- ASSERT_EQ(0, assigner.appendValue("value"));
- ASSERT_EQ(0, assigner.finish());
- ASSERT_EQ(0, options.finish(&errors));
+ gmx::OptionsAssigner assigner(&options);
+ EXPECT_NO_THROW(assigner.start());
+ ASSERT_NO_THROW(assigner.startOption("p"));
+ ASSERT_NO_THROW(assigner.appendValue("value"));
+ EXPECT_NO_THROW(assigner.finishOption());
+ EXPECT_NO_THROW(assigner.finish());
+ EXPECT_NO_THROW(options.finish());
EXPECT_EQ("value", value);
}
const char * const allowed[] = { "none", "test", "value", NULL };
int index = -1;
using gmx::StringOption;
- options.addOption(StringOption("p").store(&value)
- .enumValue(allowed)
- .storeEnumIndex(&index));
-
- gmx::EmptyErrorReporter errors;
- gmx::OptionsAssigner assigner(&options, &errors);
- ASSERT_EQ(0, assigner.startOption("p"));
- ASSERT_EQ(0, assigner.appendValue("test"));
- ASSERT_EQ(0, assigner.finish());
- ASSERT_EQ(0, options.finish(&errors));
+ ASSERT_NO_THROW(options.addOption(
+ StringOption("p").store(&value)
+ .enumValue(allowed).storeEnumIndex(&index)));
+
+ gmx::OptionsAssigner assigner(&options);
+ EXPECT_NO_THROW(assigner.start());
+ ASSERT_NO_THROW(assigner.startOption("p"));
+ ASSERT_NO_THROW(assigner.appendValue("test"));
+ EXPECT_NO_THROW(assigner.finishOption());
+ EXPECT_NO_THROW(assigner.finish());
+ EXPECT_NO_THROW(options.finish());
EXPECT_EQ("test", value);
EXPECT_EQ(1, index);
const char * const allowed[] = { "none", "test", "value", NULL };
int index = -1;
using gmx::StringOption;
- options.addOption(StringOption("p").store(&value)
- .enumValue(allowed)
- .storeEnumIndex(&index));
-
- gmx::EmptyErrorReporter errors;
- gmx::OptionsAssigner assigner(&options, &errors);
- ASSERT_EQ(0, assigner.startOption("p"));
- ASSERT_NE(0, assigner.appendValue("unknown"));
+ ASSERT_NO_THROW(options.addOption(
+ StringOption("p").store(&value)
+ .enumValue(allowed).storeEnumIndex(&index)));
+
+ gmx::OptionsAssigner assigner(&options);
+ EXPECT_NO_THROW(assigner.start());
+ ASSERT_NO_THROW(assigner.startOption("p"));
+ ASSERT_THROW(assigner.appendValue("unknown"), gmx::InvalidInputError);
}
TEST(OptionsAssignerStringTest, CompletesEnumValue)
const char * const allowed[] = { "none", "test", "value", NULL };
int index = -1;
using gmx::StringOption;
- options.addOption(StringOption("p").store(&value)
- .enumValue(allowed)
- .storeEnumIndex(&index));
-
- gmx::EmptyErrorReporter errors;
- gmx::OptionsAssigner assigner(&options, &errors);
- ASSERT_EQ(0, assigner.startOption("p"));
- ASSERT_EQ(0, assigner.appendValue("te"));
- ASSERT_EQ(0, assigner.finish());
- ASSERT_EQ(0, options.finish(&errors));
+ ASSERT_NO_THROW(options.addOption(
+ StringOption("p").store(&value)
+ .enumValue(allowed).storeEnumIndex(&index)));
+
+ gmx::OptionsAssigner assigner(&options);
+ EXPECT_NO_THROW(assigner.start());
+ ASSERT_NO_THROW(assigner.startOption("p"));
+ ASSERT_NO_THROW(assigner.appendValue("te"));
+ EXPECT_NO_THROW(assigner.finishOption());
+ EXPECT_NO_THROW(assigner.finish());
+ EXPECT_NO_THROW(options.finish());
EXPECT_EQ("test", value);
EXPECT_EQ(1, index);
const char * const allowed[] = { "none", "test", "value", NULL };
int index = -3;
using gmx::StringOption;
- options.addOption(StringOption("p").store(&value)
- .enumValue(allowed)
- .storeEnumIndex(&index));
+ ASSERT_NO_THROW(options.addOption(
+ StringOption("p").store(&value)
+ .enumValue(allowed).storeEnumIndex(&index)));
EXPECT_TRUE(value.empty());
EXPECT_EQ(-1, index);
- gmx::EmptyErrorReporter errors;
- ASSERT_EQ(0, options.finish(&errors));
+ ASSERT_NO_THROW(options.finish());
EXPECT_TRUE(value.empty());
EXPECT_EQ(-1, index);
const char * const allowed[] = { "none", "test", "value", NULL };
int index = -1;
using gmx::StringOption;
- options.addOption(StringOption("p").store(&value)
- .enumValue(allowed)
- .defaultValue("test")
- .storeEnumIndex(&index));
+ ASSERT_NO_THROW(options.addOption(
+ StringOption("p").store(&value)
+ .enumValue(allowed).defaultValue("test")
+ .storeEnumIndex(&index)));
EXPECT_EQ("test", value);
EXPECT_EQ(1, index);
- gmx::EmptyErrorReporter errors;
- gmx::OptionsAssigner assigner(&options, &errors);
- ASSERT_EQ(0, assigner.finish());
- ASSERT_EQ(0, options.finish(&errors));
+ gmx::OptionsAssigner assigner(&options);
+ EXPECT_NO_THROW(assigner.start());
+ EXPECT_NO_THROW(assigner.finish());
+ EXPECT_NO_THROW(options.finish());
EXPECT_EQ("test", value);
EXPECT_EQ(1, index);
const char * const allowed[] = { "none", "test", "value", NULL };
int index = -1;
using gmx::StringOption;
- options.addOption(StringOption("p").store(&value)
- .enumValue(allowed)
- .defaultEnumIndex(1)
- .storeEnumIndex(&index));
+ ASSERT_NO_THROW(options.addOption(
+ StringOption("p").store(&value)
+ .enumValue(allowed).defaultEnumIndex(1)
+ .storeEnumIndex(&index)));
EXPECT_EQ("test", value);
EXPECT_EQ(1, index);
- gmx::EmptyErrorReporter errors;
- gmx::OptionsAssigner assigner(&options, &errors);
- ASSERT_EQ(0, assigner.finish());
- ASSERT_EQ(0, options.finish(&errors));
+ gmx::OptionsAssigner assigner(&options);
+ EXPECT_NO_THROW(assigner.start());
+ EXPECT_NO_THROW(assigner.finish());
+ EXPECT_NO_THROW(options.finish());
EXPECT_EQ("test", value);
EXPECT_EQ(1, index);
/*!
* \param[in,out] sc The selection collection to evaluate.
* \param[in] nframes Total number of frames.
- * \returns 0 on successful evaluation, a non-zero error code on error.
*/
-int
+void
gmx_ana_selcollection_evaluate_fin(gmx_ana_selcollection_t *sc, int nframes)
{
t_selelem *sel;
sel->avecfrac /= nframes;
}
}
- return 0;
}
/*!
#include <string2.h>
#include <vec.h>
-#include "gromacs/errorreporting/errorcontext.h"
#include "gromacs/fatalerror/fatalerror.h"
+#include "gromacs/fatalerror/messagestringcollector.h"
#include "gromacs/selection/position.h"
#include "gromacs/selection/selmethod.h"
#include "gromacs/selection/selparam.h"
+#include "gromacs/utility/format.h"
#include "parsetree.h"
#include "position.h"
{
if (value->type != param->val.type)
{
- _gmx_selparser_warning(scanner, "incorrect value skipped");
+ _gmx_selparser_error(scanner, "incorrect value skipped");
value = value->next;
continue;
}
}
if (j != value->u.i.i2 + 1)
{
- _gmx_selparser_warning(scanner, "extra values skipped");
+ _gmx_selparser_error(scanner, "extra values skipped");
}
}
else
}
if (j != value->u.i.i2 - 1)
{
- _gmx_selparser_warning(scanner, "extra values skipped");
+ _gmx_selparser_error(scanner, "extra values skipped");
}
}
--i;
_gmx_sel_parse_params(t_selexpr_param *pparams, int nparam, gmx_ana_selparam_t *params,
t_selelem *root, void *scanner)
{
- gmx::AbstractErrorReporter *errors = _gmx_sel_lexer_error_reporter(scanner);
+ gmx::MessageStringCollector *errors = _gmx_sel_lexer_error_reporter(scanner);
t_selexpr_param *pparam;
gmx_ana_selparam_t *oparam;
gmx_bool bOk, rc;
bOk = TRUE;
for (i = 0; i < nparam; ++i)
{
- char buf[128];
- sprintf(buf, "In parameter '%s'", params[i].name);
- gmx::ErrorContext context(errors, buf);
+ std::string contextStr = gmx::formatString("In parameter '%s'", params[i].name);
+ gmx::MessageStringContext context(errors, contextStr);
if (params[i].val.type != POS_VALUE && (params[i].flags & (SPAR_VARNUM | SPAR_ATOMVAL)))
{
if (params[i].val.u.ptr != NULL)
{
- _gmx_selparser_warning(scanner, "value pointer is not NULL "
- "although it should be for SPAR_VARNUM "
- "and SPAR_ATOMVAL parameters");
+ _gmx_selparser_error(scanner, "value pointer is not NULL "
+ "although it should be for SPAR_VARNUM "
+ "and SPAR_ATOMVAL parameters");
}
if ((params[i].flags & SPAR_VARNUM)
&& (params[i].flags & SPAR_DYNAMIC) && !params[i].nvalptr)
i = 0;
while (pparam)
{
- char buf[128];
+ std::string contextStr;
/* Find the parameter and make some checks */
if (pparam->name != NULL)
{
- sprintf(buf, "In parameter '%s'", pparam->name);
+ contextStr = gmx::formatString("In parameter '%s'", pparam->name);
i = -1;
oparam = gmx_ana_selparam_find(pparam->name, nparam, params);
}
else if (i >= 0)
{
- sprintf(buf, "In value %d", i + 1);
+ contextStr = gmx::formatString("In value %d", i + 1);
oparam = ¶ms[i];
if (oparam->name != NULL)
{
pparam = pparam->next;
continue;
}
- gmx::ErrorContext context(errors, buf);
+ gmx::MessageStringContext context(errors, contextStr);
if (!oparam)
{
_gmx_selparser_error(scanner, "unknown parameter skipped");
#include <smalloc.h>
#include <string2.h>
-#include "gromacs/errorreporting/abstracterrorreporter.h"
-#include "gromacs/errorreporting/errorcontext.h"
#include "gromacs/fatalerror/fatalerror.h"
-
+#include "gromacs/fatalerror/messagestringcollector.h"
#include "gromacs/selection/poscalc.h"
#include "gromacs/selection/selection.h"
#include "gromacs/selection/selmethod.h"
#include "scanner.h"
-void
-_gmx_selparser_warning(yyscan_t scanner, const char *fmt, ...)
-{
- gmx::AbstractErrorReporter *errors = _gmx_sel_lexer_error_reporter(scanner);
- char buf[1024];
- va_list ap;
- va_start(ap, fmt);
- vsprintf(buf, fmt, ap);
- va_end(ap);
- errors->warning(buf);
-}
-
void
_gmx_selparser_error(yyscan_t scanner, const char *fmt, ...)
{
- gmx::AbstractErrorReporter *errors = _gmx_sel_lexer_error_reporter(scanner);
+ gmx::MessageStringCollector *errors = _gmx_sel_lexer_error_reporter(scanner);
+ // FIXME: Use an arbitrary length buffer.
char buf[1024];
va_list ap;
va_start(ap, fmt);
vsprintf(buf, fmt, ap);
va_end(ap);
- errors->error(buf);
+ errors->append(buf);
}
/*!
}
else
{
- _gmx_selparser_warning(scanner, "modifier '%s' for '%s' ignored",
- rpost, sel->u.expr.method->name);
+ _gmx_selparser_error(scanner, "modifier '%s' is not applicable for '%s'",
+ rpost, sel->u.expr.method->name);
}
return rc;
}
const char *name;
int rc;
- gmx::AbstractErrorReporter *errors = _gmx_sel_lexer_error_reporter(scanner);
- gmx::ErrorContext context(errors, "In comparison initialization");
+ gmx::MessageStringCollector *errors = _gmx_sel_lexer_error_reporter(scanner);
+ gmx::MessageStringContext context(errors, "In comparison initialization");
sel = _gmx_selelem_create(SEL_EXPRESSION);
_gmx_selelem_set_method(sel, &sm_compare, scanner);
int nargs;
int rc;
- gmx::AbstractErrorReporter *errors = _gmx_sel_lexer_error_reporter(scanner);
+ gmx::MessageStringCollector *errors = _gmx_sel_lexer_error_reporter(scanner);
char buf[128];
sprintf(buf, "In keyword '%s'", method->name);
- gmx::ErrorContext context(errors, buf);
+ gmx::MessageStringContext context(errors, buf);
if (method->nparams > 0)
{
t_selelem *root;
int rc;
- gmx::AbstractErrorReporter *errors = _gmx_sel_lexer_error_reporter(scanner);
+ gmx::MessageStringCollector *errors = _gmx_sel_lexer_error_reporter(scanner);
char buf[128];
sprintf(buf, "In keyword '%s'", method->name);
- gmx::ErrorContext context(errors, buf);
+ gmx::MessageStringContext context(errors, buf);
_gmx_sel_finish_method(scanner);
/* The "same" keyword needs some custom massaging of the parameters. */
t_selexpr_param *vparam;
int i;
- gmx::AbstractErrorReporter *errors = _gmx_sel_lexer_error_reporter(scanner);
+ gmx::MessageStringCollector *errors = _gmx_sel_lexer_error_reporter(scanner);
char buf[128];
sprintf(buf, "In keyword '%s'", method->name);
- gmx::ErrorContext context(errors, buf);
+ gmx::MessageStringContext context(errors, buf);
_gmx_sel_finish_method(scanner);
mod = _gmx_selelem_create(SEL_MODIFIER);
t_selelem *root;
t_selexpr_param *params;
- gmx::AbstractErrorReporter *errors = _gmx_sel_lexer_error_reporter(scanner);
+ gmx::MessageStringCollector *errors = _gmx_sel_lexer_error_reporter(scanner);
char buf[128];
sprintf(buf, "In position evaluation");
- gmx::ErrorContext context(errors, buf);
+ gmx::MessageStringContext context(errors, buf);
root = _gmx_selelem_create(SEL_EXPRESSION);
_gmx_selelem_set_method(root, &sm_keyword_pos, scanner);
t_selelem *
_gmx_sel_init_group_by_name(const char *name, yyscan_t scanner)
{
- gmx::AbstractErrorReporter *errors = _gmx_sel_lexer_error_reporter(scanner);
- char buf[256];
gmx_ana_indexgrps_t *grps = _gmx_sel_lexer_indexgrps(scanner);
t_selelem *sel;
}
if (!grps)
{
- sprintf(buf, "No index groups set; cannot match 'group %s'", name);
- errors->error(buf);
+ _gmx_selparser_error(scanner, "No index groups set; cannot match 'group %s'", name);
return NULL;
}
sel = _gmx_selelem_create(SEL_CONST);
/* FIXME: The constness should not be cast away */
if (!gmx_ana_indexgrps_find(&sel->u.cgrp, grps, (char *)name))
{
- sprintf(buf, "Cannot match 'group %s'", name);
- errors->error(buf);
+ _gmx_selparser_error(scanner, "Cannot match 'group %s'", name);
_gmx_selelem_free(sel);
return NULL;
}
t_selelem *
_gmx_sel_init_group_by_id(int id, yyscan_t scanner)
{
- gmx::AbstractErrorReporter *errors = _gmx_sel_lexer_error_reporter(scanner);
- char buf[128];
gmx_ana_indexgrps_t *grps = _gmx_sel_lexer_indexgrps(scanner);
t_selelem *sel;
}
if (!grps)
{
- sprintf(buf, "No index groups set; cannot match 'group %d'", id);
- errors->error(buf);
+ _gmx_selparser_error(scanner, "No index groups set; cannot match 'group %d'", id);
return NULL;
}
sel = _gmx_selelem_create(SEL_CONST);
_gmx_selelem_set_vtype(sel, GROUP_VALUE);
if (!gmx_ana_indexgrps_extract(&sel->u.cgrp, grps, id))
{
- sprintf(buf, "Cannot match 'group %d'", id);
- errors->error(buf);
+ _gmx_selparser_error(scanner, "Cannot match 'group %d'", id);
_gmx_selelem_free(sel);
return NULL;
}
t_selelem *root;
int rc;
- gmx::AbstractErrorReporter *errors = _gmx_sel_lexer_error_reporter(scanner);
+ gmx::MessageStringCollector *errors = _gmx_sel_lexer_error_reporter(scanner);
char buf[1024];
sprintf(buf, "In selection '%s'", _gmx_sel_lexer_pselstr(scanner));
- gmx::ErrorContext context(errors, buf);
+ gmx::MessageStringContext context(errors, buf);
if (sel->v.type != POS_VALUE)
{
t_selelem *root = NULL;
int rc;
- gmx::AbstractErrorReporter *errors = _gmx_sel_lexer_error_reporter(scanner);
+ gmx::MessageStringCollector *errors = _gmx_sel_lexer_error_reporter(scanner);
char buf[1024];
sprintf(buf, "In selection '%s'", pselstr);
- gmx::ErrorContext context(errors, buf);
+ gmx::MessageStringContext context(errors, buf);
rc = _gmx_selelem_update_flags(expr, scanner);
if (rc != 0)
struct t_selexpr_param *next;
} t_selexpr_param;
-/** Error reporting function for the selection parser. */
-void
-_gmx_selparser_warning(void *scanner, const char *fmt, ...);
/** Error reporting function for the selection parser. */
void
_gmx_selparser_error(void *scanner, const char *fmt, ...);
namespace gmx
{
-class AbstractErrorReporter;
+class MessageStringCollector;
}
#include "parser.h"
#endif
/** Initializes the selection scanner. */
-int
+void
_gmx_sel_init_lexer(yyscan_t *scannerp, struct gmx_ana_selcollection_t *sc,
- gmx::AbstractErrorReporter *errors,
bool bInteractive, int maxnr, bool bGroups,
struct gmx_ana_indexgrps_t *grps);
/** Frees memory allocated for the selection scanner. */
struct gmx_ana_selcollection_t *
_gmx_sel_lexer_selcollection(yyscan_t scanner);
/** Returns the error reporter for the scanner. */
-gmx::AbstractErrorReporter *
+gmx::MessageStringCollector *
_gmx_sel_lexer_error_reporter(yyscan_t scanner);
/** Returns true if the external index groups for the scanner are set. */
bool
#include "string2.h"
+#include "gromacs/fatalerror/exceptions.h"
#include "gromacs/fatalerror/fatalerror.h"
+#include "gromacs/fatalerror/messagestringcollector.h"
#include "gromacs/selection/selmethod.h"
#include "scanner.h"
#include "scanner_internal.h"
-//! Step in which the allocated memory for pretty-printed input is incremeted.
+//! Step in which the allocated memory for pretty-printed input is incremented.
#define STRSTORE_ALLOCSTEP 1000
/* These are defined as macros in the generated scanner_flex.h.
}
if (state->bInteractive)
{
+ if (!state->errors->isEmpty())
+ {
+ fprintf(stderr, "%s", state->errors->toString().c_str());
+ state->errors->clear();
+ }
fprintf(stderr, "> ");
}
/* For some reason (at least on my Linux), fgets() doesn't return until
state->pselstr[state->pslen] = 0;
}
-int
+void
_gmx_sel_init_lexer(yyscan_t *scannerp, struct gmx_ana_selcollection_t *sc,
- gmx::AbstractErrorReporter *errors,
bool bInteractive, int maxnr, bool bGroups,
struct gmx_ana_indexgrps_t *grps)
{
gmx_sel_lexer_t *state;
- int rc;
- rc = _gmx_sel_yylex_init(scannerp);
+ int rc = _gmx_sel_yylex_init(scannerp);
if (rc != 0)
{
- return rc;
+ // TODO: Throw a more representative exception.
+ GMX_THROW(gmx::InternalError("Lexer initialization failed"));
}
+ gmx::MessageStringCollector *errors = new gmx::MessageStringCollector;
+
snew(state, 1);
state->sc = sc;
state->errors = errors;
state->bBuffer = FALSE;
_gmx_sel_yyset_extra(state, *scannerp);
- return 0;
}
void
return state->sc;
}
-gmx::AbstractErrorReporter *
+gmx::MessageStringCollector *
_gmx_sel_lexer_error_reporter(yyscan_t scanner)
{
gmx_sel_lexer_t *state = _gmx_sel_yyget_extra(scanner);
namespace gmx
{
-class AbstractErrorReporter;
+class MessageStringCollector;
}
#include "parser.h"
//! Selection collection to put parsed selections in.
struct gmx_ana_selcollection_t *sc;
//! Error reporter object.
- gmx::AbstractErrorReporter *errors;
+ gmx::MessageStringCollector *errors;
//! Whether external index groups have been set.
bool bGroups;
//! External index groups for resolving \c group keywords.
namespace gmx
{
+class MessageStringCollector;
class SelectionOptionStorage;
/*! \internal \brief
bool hasFlag(Flag flag) const { return _flags.test(flag); }
//! Clears the symbol table of the selection collection.
void clearSymbolTable();
- //! Registers the default selection methods for the collection.
- int registerDefaultMethods();
/*! \brief
* Helper function that runs the parser once the tokenizer has been
* initialized.
* (if -1, parse as many as provided by the user).
* \param[out] output Vector to which parsed selections are
* appended.
- * \retval 0 on success.
- * \retval ::eeInvalidInput on error.
*
* Does not clear \p output.
*/
- int runParser(void *scanner, int maxnr,
- std::vector<Selection *> *output);
+ void runParser(void *scanner, int maxnr,
+ std::vector<Selection *> *output);
void requestSelections(const std::string &name,
const std::string &descr,
SelectionOptionStorage *storage);
- int resolveExternalGroups(struct t_selelem *root);
+ void resolveExternalGroups(struct t_selelem *root,
+ MessageStringCollector *errors);
//! Internal data, used for interfacing with old C code.
gmx_ana_selcollection_t _sc;
/*! \internal \brief
* Evaluates the largest possible index groups from dynamic selections.
*/
-int
+void
gmx_ana_selcollection_evaluate_fin(gmx_ana_selcollection_t *sc, int nframes);
/*!\}*/
#include <config.h>
#endif
-#include <cassert>
#include <cstdio>
#include <smalloc.h>
#include "poscalc.h"
#include "selmethod.h"
-#include "gromacs/errorreporting/abstracterrorreporter.h"
+#include "gromacs/fatalerror/exceptions.h"
#include "gromacs/fatalerror/fatalerror.h"
+#include "gromacs/fatalerror/gmxassert.h"
+#include "gromacs/fatalerror/messagestringcollector.h"
#include "gromacs/options/basicoptions.h"
#include "gromacs/options/options.h"
#include "gromacs/selection/selection.h"
_sc.pcc = pcc;
_sc.mempool = NULL;
_sc.symtab = NULL;
+
+ if (_sc.pcc == NULL)
+ {
+ int rc = gmx_ana_poscalc_coll_create(&_sc.pcc);
+ if (rc != 0)
+ {
+ // TODO: A more reasonable error
+ GMX_THROW(InternalError("Failed to create position calculation collection"));
+ }
+ _flags.set(Impl::efOwnPositionCollection);
+ }
+ _gmx_sel_symtab_create(&_sc.symtab);
+ gmx_ana_selmethod_register_defaults(_sc.symtab);
}
}
-int
+void
SelectionCollection::Impl::runParser(yyscan_t scanner, int maxnr,
std::vector<Selection *> *output)
{
gmx_ana_selcollection_t *sc = &_sc;
- assert(sc == _gmx_sel_lexer_selcollection(scanner));
+ MessageStringCollector *errors = _gmx_sel_lexer_error_reporter(scanner);
+ GMX_ASSERT(sc == _gmx_sel_lexer_selcollection(scanner),
+ "Incorrectly initialized lexer");
int oldCount = sc->sel.size();
int bOk = !_gmx_sel_yybparse(scanner);
int nr = sc->sel.size() - oldCount;
if (maxnr > 0 && nr != maxnr)
{
- return eeInvalidInput;
+ bOk = false;
+ errors->append("Too few selections provided");
}
if (bOk)
}
}
- return bOk ? 0 : eeInvalidInput;
+ if (!bOk || !errors->isEmpty())
+ {
+ GMX_ASSERT(bOk && !errors->isEmpty(), "Inconsistent error reporting");
+ GMX_THROW(InvalidInputError(errors->toString()));
+ }
}
}
-int SelectionCollection::Impl::resolveExternalGroups(t_selelem *root)
+void SelectionCollection::Impl::resolveExternalGroups(
+ t_selelem *root, MessageStringCollector *errors)
{
- int rc = 0;
if (root->type == SEL_GROUPREF)
{
+ bool bOk = true;
if (root->u.gref.name != NULL)
{
char *name = root->u.gref.name;
if (!gmx_ana_indexgrps_find(&root->u.cgrp, _grps, name))
{
// TODO: Improve error messages
- GMX_ERROR_NORET(eeInvalidInput,
- "Unknown group referenced in a selection");
- rc = eeInvalidInput;
+ errors->append("Unknown group referenced in a selection");
+ bOk = false;
}
else
{
root->u.gref.id))
{
// TODO: Improve error messages
- GMX_ERROR_NORET(eeInvalidInput,
- "Unknown group referenced in a selection");
- rc = eeInvalidInput;
+ errors->append("Unknown group referenced in a selection");
+ bOk = false;
}
}
- if (rc == 0)
+ if (bOk)
{
root->type = SEL_CONST;
root->name = root->u.cgrp.name;
t_selelem *child = root->child;
while (child != NULL)
{
- int rc1 = resolveExternalGroups(child);
- rc = (rc == 0 ? rc1 : rc);
+ resolveExternalGroups(child, errors);
child = child->next;
}
- return rc;
}
}
-int
-SelectionCollection::init()
-{
- if (_impl->_sc.pcc == NULL)
- {
- int rc = gmx_ana_poscalc_coll_create(&_impl->_sc.pcc);
- if (rc != 0)
- {
- return rc;
- }
- _impl->_flags.set(Impl::efOwnPositionCollection);
- }
- _gmx_sel_symtab_create(&_impl->_sc.symtab);
- gmx_ana_selmethod_register_defaults(_impl->_sc.symtab);
- return 0;
-}
-
-
-int
-SelectionCollection::create(SelectionCollection **scp,
- gmx_ana_poscalc_coll_t *pcc)
-{
- SelectionCollection *sc = new SelectionCollection(pcc);
-
- int rc = sc->init();
- if (rc != 0)
- {
- *scp = NULL;
- delete sc;
- return rc;
- }
- *scp = sc;
- return 0;
-}
-
-
Options *
SelectionCollection::initOptions()
{
const char **postypes = gmx_ana_poscalc_create_type_enum(TRUE);
if (postypes == NULL)
{
- return NULL;
+ // TODO: Use an out-of-memory exception here
+ GMX_THROW(InternalError("Could not create position calculation enum"));
}
options.addOption(StringOption("selrpos").enumValue(postypes + 1)
.store(&_impl->_rpost).defaultValue(postypes[1])
options.addOption(StringOption("seltype").enumValue(postypes + 1)
.store(&_impl->_spost).defaultValue(postypes[1])
.description("Default selection output positions"));
- assert(_impl->_debugLevel >= 0 && _impl->_debugLevel <= 4);
+ GMX_RELEASE_ASSERT(_impl->_debugLevel >= 0 && _impl->_debugLevel <= 4,
+ "Debug level out of range");
options.addOption(StringOption("seldebug").hidden(_impl->_debugLevel == 0)
.enumValue(debug_levels)
.defaultValue(debug_levels[_impl->_debugLevel])
void
SelectionCollection::setReferencePosType(const char *type)
{
- assert(type != NULL);
+ GMX_RELEASE_ASSERT(type != NULL, "Cannot assign NULL position type");
_impl->_rpost = type;
}
void
SelectionCollection::setOutputPosType(const char *type)
{
- assert(type != NULL);
+ GMX_RELEASE_ASSERT(type != NULL, "Cannot assign NULL position type");
_impl->_spost = type;
}
}
-int
+void
SelectionCollection::setTopology(t_topology *top, int natoms)
{
gmx_ana_selcollection_t *sc = &_impl->_sc;
{
if (sc->top == NULL)
{
- GMX_ERROR(eeInvalidValue,
- "Selections need either the topology or the number of atoms");
+ GMX_THROW(APIError("Selections need either the topology or the number of atoms"));
}
natoms = sc->top->atoms.nr;
}
+
gmx_ana_index_init_simple(&sc->gall, natoms, NULL);
- return 0;
}
-int
+void
SelectionCollection::setIndexGroups(gmx_ana_indexgrps_t *grps)
{
- assert(grps == NULL || !_impl->hasFlag(Impl::efExternalGroupsSet));
+ GMX_RELEASE_ASSERT(grps == NULL || !_impl->hasFlag(Impl::efExternalGroupsSet),
+ "Can only set external groups once or clear them afterwards");
_impl->_grps = grps;
_impl->_flags.set(Impl::efExternalGroupsSet);
- int rc = 0;
+ MessageStringCollector errors;
t_selelem *root = _impl->_sc.root;
while (root != NULL)
{
- int rc1 = _impl->resolveExternalGroups(root);
- rc = (rc == 0 ? rc1 : rc);
+ _impl->resolveExternalGroups(root, &errors);
root = root->next;
}
- return rc;
+ if (!errors.isEmpty())
+ {
+ GMX_THROW(InvalidInputError(errors.toString()));
+ }
}
}
-int
-SelectionCollection::parseRequestedFromStdin(bool bInteractive,
- AbstractErrorReporter *errors)
+class RequestsClearer
{
- int rc = 0;
+ public:
+ RequestsClearer(SelectionCollection::Impl::RequestList *requests)
+ : _requests(requests)
+ {
+ }
+ ~RequestsClearer()
+ {
+ _requests->clear();
+ }
+
+ private:
+ SelectionCollection::Impl::RequestList *_requests;
+};
+
+
+void
+SelectionCollection::parseRequestedFromStdin(bool bInteractive)
+{
+ RequestsClearer clearRequestsOnExit(&_impl->_requests);
+
Impl::RequestList::const_iterator i;
for (i = _impl->_requests.begin(); i != _impl->_requests.end(); ++i)
{
request.count() < 0 ? ", Ctrl-D to end" : "");
}
std::vector<Selection *> selections;
- rc = parseFromStdin(request.count(), bInteractive, errors, &selections);
- if (rc != 0)
- {
- break;
- }
- rc = request.storage->addSelections(selections, true, errors);
- if (rc != 0)
- {
- break;
- }
+ parseFromStdin(request.count(), bInteractive, &selections);
+ request.storage->addSelections(selections, true);
}
- _impl->_requests.clear();
- return rc;
}
-int
-SelectionCollection::parseRequestedFromString(const std::string &str,
- AbstractErrorReporter *errors)
+void
+SelectionCollection::parseRequestedFromString(const std::string &str)
{
+ RequestsClearer clearRequestsOnExit(&_impl->_requests);
+
std::vector<Selection *> selections;
- int rc = parseFromString(str, errors, &selections);
- if (rc != 0)
- {
- return rc;
- }
+ parseFromString(str, &selections);
+
std::vector<Selection *>::const_iterator first = selections.begin();
std::vector<Selection *>::const_iterator last = first;
Impl::RequestList::const_iterator i;
{
if (selections.end() - first < request.count())
{
- errors->error("Too few selections provided");
- rc = eeInvalidInput;
- break;
+ GMX_THROW(InvalidInputError("Too few selections provided"));
}
last = first + request.count();
}
{
if (i != _impl->_requests.end() - 1)
{
- GMX_ERROR_NORET(eeInvalidValue,
- "Request for all selections not the last option");
- rc = eeInvalidValue;
- break;
+ GMX_THROW(APIError("Request for all selections not the last option"));
}
last = selections.end();
}
std::vector<Selection *> curr(first, last);
- rc = request.storage->addSelections(curr, true, errors);
- if (rc != 0)
- {
- break;
- }
+ request.storage->addSelections(curr, true);
first = last;
}
- _impl->_requests.clear();
if (last != selections.end())
{
- errors->error("Too many selections provided");
- rc = eeInvalidInput;
+ GMX_THROW(InvalidInputError("Too many selections provided"));
}
- return rc;
}
-int
+void
SelectionCollection::parseFromStdin(int nr, bool bInteractive,
- AbstractErrorReporter *errors,
std::vector<Selection *> *output)
{
yyscan_t scanner;
- int rc;
- rc = _gmx_sel_init_lexer(&scanner, &_impl->_sc, errors, bInteractive, nr,
- _impl->hasFlag(Impl::efExternalGroupsSet),
- _impl->_grps);
- if (rc != 0)
- {
- return rc;
- }
+ _gmx_sel_init_lexer(&scanner, &_impl->_sc, bInteractive, nr,
+ _impl->hasFlag(Impl::efExternalGroupsSet),
+ _impl->_grps);
/* We don't set the lexer input here, which causes it to use a special
* internal implementation for reading from stdin. */
- return _impl->runParser(scanner, nr, output);
+ _impl->runParser(scanner, nr, output);
}
-int
+void
SelectionCollection::parseFromFile(const std::string &filename,
- AbstractErrorReporter *errors,
std::vector<Selection *> *output)
{
yyscan_t scanner;
FILE *fp;
- int rc;
- rc = _gmx_sel_init_lexer(&scanner, &_impl->_sc, errors, false, -1,
- _impl->hasFlag(Impl::efExternalGroupsSet),
- _impl->_grps);
- if (rc != 0)
- {
- return rc;
- }
+ _gmx_sel_init_lexer(&scanner, &_impl->_sc, false, -1,
+ _impl->hasFlag(Impl::efExternalGroupsSet),
+ _impl->_grps);
fp = ffopen(filename.c_str(), "r");
_gmx_sel_set_lex_input_file(scanner, fp);
- rc = _impl->runParser(scanner, -1, output);
+ // TODO: Use RAII
+ try
+ {
+ _impl->runParser(scanner, -1, output);
+ }
+ catch (std::exception &)
+ {
+ ffclose(fp);
+ throw;
+ }
ffclose(fp);
- return rc;
}
-int
+void
SelectionCollection::parseFromString(const std::string &str,
- AbstractErrorReporter *errors,
std::vector<Selection *> *output)
{
yyscan_t scanner;
- int rc;
- rc = _gmx_sel_init_lexer(&scanner, &_impl->_sc, errors, false, -1,
- _impl->hasFlag(Impl::efExternalGroupsSet),
- _impl->_grps);
- if (rc != 0)
- {
- return rc;
- }
+ _gmx_sel_init_lexer(&scanner, &_impl->_sc, false, -1,
+ _impl->hasFlag(Impl::efExternalGroupsSet),
+ _impl->_grps);
_gmx_sel_set_lex_input_str(scanner, str.c_str());
- return _impl->runParser(scanner, -1, output);
+ _impl->runParser(scanner, -1, output);
}
{
if (!_impl->hasFlag(Impl::efExternalGroupsSet))
{
- int rc = setIndexGroups(NULL);
- if (rc != 0)
- {
- return rc;
- }
+ setIndexGroups(NULL);
}
if (_impl->_debugLevel >= 1)
{
}
-int
+void
SelectionCollection::evaluateFinal(int nframes)
{
- return gmx_ana_selcollection_evaluate_fin(&_impl->_sc, nframes);
+ gmx_ana_selcollection_evaluate_fin(&_impl->_sc, nframes);
}
namespace gmx
{
-class AbstractErrorReporter;
class Options;
class Selection;
class SelectionOptionStorage;
explicit SelectionCollection(gmx_ana_poscalc_coll_t *pcc);
~SelectionCollection();
- /*! \brief
- * Initializes the object.
- *
- * \retval 0 on success.
- *
- * Should be called immediately after construction.
- */
- int init();
/*! \brief
* Initializes options for setting global properties on the collection.
*
*/
Options *initOptions();
- /*! \brief
- * Convenience function that creates a new selection collection and
- * calls init().
- *
- * \param[out] scp Pointer to a newly created selection collection.
- * \param[in] pcc Position calculation data structure to use for
- * selection evaluation.
- * \returns 0 on success.
- */
- static int create(SelectionCollection **scp, gmx_ana_poscalc_coll_t *pcc);
-
/*! \brief
* Sets the default reference position handling for a selection
* collection.
* the selection: even if the topology contains more atoms, they will
* not be selected.
*/
- int setTopology(t_topology *top, int natoms);
+ void setTopology(t_topology *top, int natoms);
/*! \brief
* Sets the external index groups to use for the selections.
*
* Can be called only once with non-NULL \p grps.
*/
- int setIndexGroups(gmx_ana_indexgrps_t *grps);
+ void setIndexGroups(gmx_ana_indexgrps_t *grps);
/*! \brief
* Parses selection(s) from standard input for options not yet
* provided.
*
* \param[in] bInteractive Whether the parser should behave
* interactively.
- * \param[in] errors Error reporter object.
*
* This method cooperates with SelectionOption to allow interactive
* input of missing selections after all options have been processed.
* It should be called after the Options::finish() method has been
* called on all options that add selections to this collection.
*/
- int parseRequestedFromStdin(bool bInteractive,
- AbstractErrorReporter *errors);
+ void parseRequestedFromStdin(bool bInteractive);
/*! \brief
* Parses selection(s) from a string for options not yet provided.
*
* \param[in] str String to parse.
- * \param[in] errors Error reporter object.
*
* \see parseRequestedFromStdin()
*/
- int parseRequestedFromString(const std::string &str,
- AbstractErrorReporter *errors);
+ void parseRequestedFromString(const std::string &str);
/*! \brief
* Parses selection(s) from standard input.
*
* (if -1, parse as many as provided by the user).
* \param[in] bInteractive Whether the parser should behave
* interactively.
- * \param[in] errors Error reporter object.
* \param[out] output Vector to which parsed selections are appended.
* \retval 0 on success.
* \retval ::eeInvalidInput on syntax error (an interactive parser
* Some information about the selections only becomes available once
* compile() has been called.
*/
- int parseFromStdin(int count, bool bInteractive,
- AbstractErrorReporter *errors,
- std::vector<Selection *> *output);
+ void parseFromStdin(int count, bool bInteractive,
+ std::vector<Selection *> *output);
/*! \brief
* Parses selection(s) from a file.
*
* \param[in] filename Name of the file to parse selections from.
- * \param[in] errors Error reporter object.
* \param[out] output Vector to which parsed selections are appended.
* \retval 0 on success.
* \retval ::eeInvalidInput on syntax error.
* Some information about the selections only becomes available once
* compile() has been called.
*/
- int parseFromFile(const std::string &filename,
- AbstractErrorReporter *errors,
- std::vector<Selection *> *output);
+ void parseFromFile(const std::string &filename,
+ std::vector<Selection *> *output);
/*! \brief
* Parses selection(s) from a string.
*
* \param[in] str String to parse selections from.
- * \param[in] errors Error reporter object.
* \param[out] output Vector to which parsed selections are appended.
* \retval 0 on success.
* \retval ::eeInvalidInput on syntax error.
* Some information about the selections only becomes available once
* compile() has been called.
*/
- int parseFromString(const std::string &str,
- AbstractErrorReporter *errors,
- std::vector<Selection *> *output);
+ void parseFromString(const std::string &str,
+ std::vector<Selection *> *output);
/*! \brief
* Prepares the selections for evaluation and performs optimizations.
*
* Evaluates the largest possible index groups from dynamic selections.
*
* \param[in] nframes Total number of frames.
- * \returns 0 on successful evaluation, a non-zero error code on error.
+ *
+ * This function does not throw.
*/
- int evaluateFinal(int nframes);
+ void evaluateFinal(int nframes);
/*! \brief
* Prints a human-readable version of the internal selection element
*/
#include "gromacs/selection/selectionoption.h"
-#include <cassert>
-
#include <string>
#include <vector>
-#include "gromacs/errorreporting/abstracterrorreporter.h"
-#include "gromacs/errorreporting/errorcontext.h"
-#include "gromacs/fatalerror/fatalerror.h"
+#include "gromacs/fatalerror/exceptions.h"
+#include "gromacs/fatalerror/gmxassert.h"
+#include "gromacs/fatalerror/messagestringcollector.h"
#include "gromacs/options/globalproperties.h"
#include "gromacs/options/options.h"
#include "gromacs/selection/selection.h"
* SelectionOptionStorage
*/
-SelectionOptionStorage::SelectionOptionStorage()
- : _adjuster(NULL)
+SelectionOptionStorage::SelectionOptionStorage(const SelectionOption &settings,
+ Options *options)
+ : MyBase(settings, options,
+ OptionFlags() | efNoDefaultValue | efConversionMayNotAddValues
+ | efDontCheckMinimumCount),
+ _selectionFlags(settings._selectionFlags), _adjuster(NULL)
{
- MyBase::setFlag(efNoDefaultValue);
- MyBase::setFlag(efConversionMayNotAddValues);
- MyBase::setFlag(efDontCheckMinimumCount);
+ options->globalProperties().request(eogpSelectionCollection);
+ if (settings._adjuster != NULL)
+ {
+ _adjuster = new SelectionOptionAdjuster(this);
+ *settings._adjuster = _adjuster;
+ }
}
}
-int SelectionOptionStorage::init(const SelectionOption &settings,
- Options *options)
-{
- _selectionFlags = settings._selectionFlags;
- int rc = MyBase::init(settings, options);
- if (rc == 0)
- {
- options->globalProperties().request(eogpSelectionCollection);
- if (settings._adjuster)
- {
- _adjuster = new SelectionOptionAdjuster(this);
- *settings._adjuster = _adjuster;
- }
- }
- return rc;
-}
-
-
std::string SelectionOptionStorage::formatValue(int i) const
{
Selection *sel = values().at(i);
}
-int SelectionOptionStorage::addSelections(
+void SelectionOptionStorage::addSelections(
const std::vector<Selection *> &selections,
- bool bFullValue, AbstractErrorReporter *errors)
+ bool bFullValue)
{
if (bFullValue && selections.size() < static_cast<size_t>(minValueCount()))
{
- errors->error("Too few selections provided");
- return eeInvalidInput;
+ GMX_THROW(InvalidInputError("Too few selections provided"));
}
std::vector<Selection *>::const_iterator i;
for (i = selections.begin(); i != selections.end(); ++i)
// behave better.
if (_selectionFlags.test(efOnlyStatic) && (*i)->isDynamic())
{
- errors->error("Dynamic selections not supported");
- return eeInvalidInput;
+ GMX_THROW(InvalidInputError("Dynamic selections not supported"));
}
(*i)->setFlags(_selectionFlags);
- int rc = addValue(*i);
- if (rc != 0)
- {
- return rc;
- }
+ addValue(*i);
}
if (bFullValue)
{
processValues(selections.size(), true);
}
- return 0;
}
-int SelectionOptionStorage::convertValue(const std::string &value,
- AbstractErrorReporter *errors)
+void SelectionOptionStorage::convertValue(const std::string &value)
{
SelectionCollection *sc =
hostOptions().globalProperties().selectionCollection();
- assert(sc != NULL);
+ GMX_RELEASE_ASSERT(sc != NULL, "Selection collection is not set");
std::vector<Selection *> selections;
// TODO: Implement reading from a file.
- int rc = sc->parseFromString(value, errors, &selections);
- if (rc == 0)
- {
- rc = addSelections(selections, false, errors);
- }
- return rc;
+ sc->parseFromString(value, &selections);
+ addSelections(selections, false);
}
-int SelectionOptionStorage::processSet(int nvalues,
- AbstractErrorReporter *errors)
+void SelectionOptionStorage::processSet(int nvalues)
{
if (nvalues > 0 && nvalues < minValueCount())
{
// TODO: Remove the invalid values
- errors->error("Too few (valid) values provided");
- return eeInvalidInput;
+ GMX_THROW(InvalidInputError("Too few (valid) values provided"));
}
- return MyBase::processSet(nvalues, errors);
+ MyBase::processSet(nvalues);
}
-int SelectionOptionStorage::processAll(AbstractErrorReporter *errors)
+void SelectionOptionStorage::processAll()
{
if ((hasFlag(efRequired) || hasFlag(efSet)) && valueCount() == 0)
{
SelectionCollection *sc =
hostOptions().globalProperties().selectionCollection();
- assert(sc != NULL);
+ GMX_RELEASE_ASSERT(sc != NULL, "Selection collection is not set");
sc->_impl->requestSelections(name(), description(), this);
setFlag(efSet);
}
- return MyBase::processAll(errors);
+ MyBase::processAll();
}
-int SelectionOptionStorage::setAllowedValueCount(int count,
- AbstractErrorReporter *errors)
+void SelectionOptionStorage::setAllowedValueCount(int count)
{
- ErrorContext context(errors, "In option '" + name() + "'");
- int rc = 0;
- if (count > 0)
+ MessageStringCollector errors;
+ errors.startContext("In option '" + name() + "'");
+ if (count >= 0)
{
- rc = setMinValueCount(count, errors);
- if (rc == 0 && valueCount() > 0 && valueCount() < count)
+ // Should not throw because efDontCheckMinimumCount is set
+ setMinValueCount(count);
+ if (valueCount() > 0 && valueCount() < count)
{
- errors->error("Too few (valid) values provided");
- rc = eeInvalidInput;
+ errors.append("Too few (valid) values provided");
}
}
- int rc1 = setMaxValueCount(count, errors);
- return rc != 0 ? rc : rc1;
+ try
+ {
+ setMaxValueCount(count);
+ }
+ catch (UserInputError &ex)
+ {
+ errors.append(ex.what());
+ }
+ errors.finishContext();
+ if (!errors.isEmpty())
+ {
+ GMX_THROW(InvalidInputError(errors.toString()));
+ }
}
-int SelectionOptionStorage::setSelectionFlag(SelectionFlag flag, bool bSet,
- AbstractErrorReporter *errors)
+void SelectionOptionStorage::setSelectionFlag(SelectionFlag flag, bool bSet)
{
- ErrorContext context(errors, "In option '" + name() + "'");
_selectionFlags.set(flag, bSet);
ValueList::const_iterator i;
for (i = values().begin(); i != values().end(); ++i)
{
if (_selectionFlags.test(efOnlyStatic) && (*i)->isDynamic())
{
- errors->error("Dynamic selections not supported");
- return eeInvalidInput;
+ MessageStringCollector errors;
+ errors.startContext("In option '" + name() + "'");
+ errors.append("Dynamic selections not supported");
+ errors.finishContext();
+ GMX_THROW(InvalidInputError(errors.toString()));
}
(*i)->setFlags(_selectionFlags);
}
- return 0;
}
*/
SelectionOptionAdjuster::SelectionOptionAdjuster(SelectionOptionStorage *storage)
- : _storage(*storage), _errors(NULL)
-{
-}
-
-AbstractErrorReporter *
-SelectionOptionAdjuster::setErrorReporter(AbstractErrorReporter *errors)
+ : _storage(*storage)
{
- AbstractErrorReporter *old = _errors;
- _errors = errors;
- return old;
}
-int SelectionOptionAdjuster::setValueCount(int count)
+void SelectionOptionAdjuster::setValueCount(int count)
{
- return storage().setAllowedValueCount(count, errors());
+ return storage().setAllowedValueCount(count);
}
-int SelectionOptionAdjuster::setEvaluateVelocities(bool bEnabled)
+void SelectionOptionAdjuster::setEvaluateVelocities(bool bEnabled)
{
- return storage().setSelectionFlag(efEvaluateVelocities, bEnabled, errors());
+ return storage().setSelectionFlag(efEvaluateVelocities, bEnabled);
}
-int SelectionOptionAdjuster::setEvaluateForces(bool bEnabled)
+void SelectionOptionAdjuster::setEvaluateForces(bool bEnabled)
{
- return storage().setSelectionFlag(efEvaluateForces, bEnabled, errors());
+ return storage().setSelectionFlag(efEvaluateForces, bEnabled);
}
-int SelectionOptionAdjuster::setOnlyAtoms(bool bEnabled)
+void SelectionOptionAdjuster::setOnlyAtoms(bool bEnabled)
{
- return storage().setSelectionFlag(efOnlyAtoms, bEnabled, errors());
+ return storage().setSelectionFlag(efOnlyAtoms, bEnabled);
}
-int SelectionOptionAdjuster::setOnlyStatic(bool bEnabled)
+void SelectionOptionAdjuster::setOnlyStatic(bool bEnabled)
{
- return storage().setSelectionFlag(efOnlyStatic, bEnabled, errors());
+ return storage().setSelectionFlag(efOnlyStatic, bEnabled);
}
-int SelectionOptionAdjuster::setDynamicMask(bool bEnabled)
+void SelectionOptionAdjuster::setDynamicMask(bool bEnabled)
{
- return storage().setSelectionFlag(efDynamicMask, bEnabled, errors());
+ return storage().setSelectionFlag(efDynamicMask, bEnabled);
}
-int SelectionOptionAdjuster::setDynamicOnlyWhole(bool bEnabled)
+void SelectionOptionAdjuster::setDynamicOnlyWhole(bool bEnabled)
{
- return storage().setSelectionFlag(efDynamicOnlyWhole, bEnabled, errors());
+ return storage().setSelectionFlag(efDynamicOnlyWhole, bEnabled);
}
* SelectionOption
*/
-int SelectionOption::createDefaultStorage(Options *options,
- AbstractOptionStorage **storage) const
+AbstractOptionStorage *SelectionOption::createDefaultStorage(Options *options) const
{
- return createOptionStorage<SelectionOption, SelectionOptionStorage>(this, options, storage);
+ return new SelectionOptionStorage(*this, options);
}
} // namespace gmx
#ifndef GMX_SELECTION_SELECTIONOPTION_H
#define GMX_SELECTION_SELECTIONOPTION_H
-#include <cassert>
-
#include "../options/abstractoption.h"
#include "selectionenums.h"
namespace gmx
{
-class AbstractErrorReporter;
class Selection;
class SelectionOptionAdjuster;
class SelectionOptionStorage;
using MyBase::defaultValue;
using MyBase::defaultValueIfSet;
- virtual int createDefaultStorage(Options *options,
- AbstractOptionStorage **storage) const;
+ virtual AbstractOptionStorage *createDefaultStorage(Options *options) const;
SelectionFlags _selectionFlags;
SelectionOptionAdjuster **_adjuster;
*/
SelectionOptionAdjuster(SelectionOptionStorage *storage);
- /*! \brief
- * Sets an error reporter for all subsequent operations.
- *
- * \param[in] errors Error reporter object.
- * \returns The previously set error reporter (may be NULL).
- *
- * Caller must ensure that the error reporter is valid as long as it
- * is assigned to the adjuster.
- *
- * There must be a valid error reporter associated with the adjuster
- * before any other method in the object is called.
- *
- * \see OptionAdjusterErrorContext
- */
- AbstractErrorReporter *setErrorReporter(AbstractErrorReporter *errors);
-
/*! \brief
* Sets the number of selections allowed for the option.
*
* \param[in] count Number of allowed selections.
- * \retval 0 on success.
*/
- int setValueCount(int count);
+ void setValueCount(int count);
//! \copydoc SelectionOption::evaluateVelocities()
- int setEvaluateVelocities(bool bEnabled);
+ void setEvaluateVelocities(bool bEnabled);
//! \copydoc SelectionOption::evaluateForces()
- int setEvaluateForces(bool bEnabled);
+ void setEvaluateForces(bool bEnabled);
//! \copydoc SelectionOption::onlyAtoms()
- int setOnlyAtoms(bool bEnabled);
+ void setOnlyAtoms(bool bEnabled);
//! \copydoc SelectionOption::onlyStatic()
- int setOnlyStatic(bool bEnabled);
+ void setOnlyStatic(bool bEnabled);
//! \copydoc SelectionOption::dynamicMask()
- int setDynamicMask(bool bEnabled);
+ void setDynamicMask(bool bEnabled);
//! \copydoc SelectionOption::dynamicOnlyWhole()
- int setDynamicOnlyWhole(bool bEnabled);
+ void setDynamicOnlyWhole(bool bEnabled);
private:
//! Returns the storage object associated with this adjuster.
SelectionOptionStorage &storage() { return _storage; }
//! Returns the storage object associated with this adjuster.
const SelectionOptionStorage &storage() const { return _storage; }
- //! Returns the current error reporter object, asserts if there is none.
- AbstractErrorReporter *errors()
- { assert(_errors != NULL); return _errors; }
SelectionOptionStorage &_storage;
- AbstractErrorReporter *_errors;
-};
-
-
-/*! \brief
- * Convenience class for providing an error reporter for an option adjuster.
- *
- * This class implements a RAII-type interface over
- * SelectionOptionAdjuster::setErrorReporter(): the constructor sets a new
- * error reporter, and the destructor restores the old reporter.
- *
- * Example use:
- * \code
-{
- OptionAdjusterErrorContext context(adjuster, errors);
- adjuster->setValueCount(2); // Errors are reported using 'errors'.
-} // Previous reporter is automatically restored on scope exit.
- * \endcode
- *
- * \inpublicapi
- * \ingroup module_selection
- */
-class OptionAdjusterErrorContext
-{
- public:
- //! Sets error reporter for an adjuster and stores the old reporter.
- OptionAdjusterErrorContext(SelectionOptionAdjuster *adjuster,
- AbstractErrorReporter *errors)
- : _adjuster(adjuster)
- {
- _oldReporter = adjuster->setErrorReporter(errors);
- }
- //! Restores the old error reporter.
- ~OptionAdjusterErrorContext()
- {
- _adjuster->setErrorReporter(_oldReporter);
- }
-
- private:
- SelectionOptionAdjuster *_adjuster;
- AbstractErrorReporter *_oldReporter;
};
} // namespace gmx
class SelectionOptionStorage : public OptionStorageTemplate<Selection *>
{
public:
- SelectionOptionStorage();
- virtual ~SelectionOptionStorage();
-
/*! \brief
* Initializes the storage from option settings.
*
* \param[in] settings Storage settings.
* \param[in] options Options object.
- * \retval 0 on success.
*/
- int init(const SelectionOption &settings, Options *options);
+ SelectionOptionStorage(const SelectionOption &settings, Options *options);
+ virtual ~SelectionOptionStorage();
virtual const char *typeString() const { return "sel"; }
virtual std::string formatValue(int i) const;
* \param[in] selections List of selections to add.
* \param[in] bFullValue If true, the provided selections are the full
* value of the option, and additional checks are performed.
- * \param[in] errors Error reporter object.
*
* This function is used to implement the methods
* SelectionCollection::parseRequestedFromStdin() and
* \p bFullValue set to true), as well as internally by the storage
* class (called with \p bFullValue set to false).
*/
- int addSelections(const std::vector<Selection *> &selections,
- bool bFullValue, AbstractErrorReporter *errors);
+ void addSelections(const std::vector<Selection *> &selections,
+ bool bFullValue);
// Required to access the number of values in selection requests.
// See SelectionCollection::Impl.
* Sets the number of selections allowed for this selection.
*
* \param[in] count Required number of selections for this option.
- * \param[in] errors Error reporter object.
- * \retval 0 on success.
*
* If values have already been provided, it is checked that a correct
* number has been provided. If requests have already been made, but
* have not yet been processed, they are also affected.
*/
- int setAllowedValueCount(int count, AbstractErrorReporter *errors);
+ void setAllowedValueCount(int count);
/*! \brief
* Alters flags for the selections created by this option.
*
* \param[in] flag Flag to change.
* \param[in] bSet Whether to set or clear the flag.
- * \param[in] errors Error reporter object.
- * \retval 0 on success.
*
* If values have already been provided, it is checked that they match
* the limitations enforced by the flags. If requests have already
* been made, but have not yet been processed, they are also affected.
*/
- int setSelectionFlag(SelectionFlag flag, bool bSet,
- AbstractErrorReporter *errors);
+ void setSelectionFlag(SelectionFlag flag, bool bSet);
private:
- virtual int convertValue(const std::string &value,
- AbstractErrorReporter *errors);
- virtual int processSet(int nvalues, AbstractErrorReporter *errors);
- virtual int processAll(AbstractErrorReporter *errors);
+ virtual void convertValue(const std::string &value);
+ virtual void processSet(int nvalues);
+ virtual void processAll();
SelectionFlags _selectionFlags;
//! Pointer to the adjuster (there can be only one, can be NULL).
#include <smalloc.h>
#include <string2.h>
-#include "gromacs/errorreporting/errorcontext.h"
#include "gromacs/fatalerror/fatalerror.h"
+#include "gromacs/fatalerror/messagestringcollector.h"
#include "gromacs/selection/selmethod.h"
#include "keywords.h"
t_selelem *sel;
t_methoddata_kweval *data;
- gmx::AbstractErrorReporter *errors = _gmx_sel_lexer_error_reporter(scanner);
+ gmx::MessageStringCollector *errors = _gmx_sel_lexer_error_reporter(scanner);
char buf[1024];
sprintf(buf, "In evaluation of '%s'", method->name);
- gmx::ErrorContext context(errors, buf);
+ gmx::MessageStringContext context(errors, buf);
if ((method->flags & (SMETH_SINGLEVAL | SMETH_VARNUMVAL))
|| method->outinit || method->pupdate)
#include "tpxio.h"
#include "vec.h"
-#include "gromacs/errorreporting/emptyerrorreporter.h"
#include "gromacs/selection/poscalc.h"
#include "gromacs/selection/selectioncollection.h"
#include "gromacs/selection/selection.h"
void setAtomCount(int natoms)
{
- _sc.setTopology(NULL, natoms);
+ ASSERT_NO_THROW(_sc.setTopology(NULL, natoms));
}
void loadTopology(const char *filename);
gmx::SelectionCollection _sc;
- gmx::EmptyErrorReporter _errors;
t_topology *_top;
t_trxframe *_frame;
};
SelectionCollectionTest::SelectionCollectionTest()
: _sc(NULL), _top(NULL), _frame(NULL)
{
- _sc.init();
_sc.setReferencePosType("atom");
_sc.setOutputPosType("atom");
}
_frame->bBox = TRUE;
copy_mat(box, _frame->box);
- ASSERT_EQ(0, _sc.setTopology(_top, -1));
+ ASSERT_NO_THROW(_sc.setTopology(_top, -1));
}
{
SCOPED_TRACE(std::string("Parsing selection \"")
+ selections[i] + "\"");
- ASSERT_EQ(0, _sc.parseFromString(selections[i], &_errors, &_sel));
+ ASSERT_NO_THROW(_sc.parseFromString(selections[i], &_sel));
char buf[50];
if (_sel.size() == _count)
{
void
SelectionCollectionDataTest::runEvaluateFinal()
{
- ASSERT_EQ(0, _sc.evaluateFinal(_framenr));
+ ASSERT_NO_THROW(_sc.evaluateFinal(_framenr));
if (!_data.isWriteMode())
{
checkCompiled();
SelectionCollectionDataTest::runTest(int natoms, const char * const *selections)
{
ASSERT_NO_FATAL_FAILURE(runParser(selections));
- setAtomCount(natoms);
+ ASSERT_NO_FATAL_FAILURE(setAtomCount(natoms));
ASSERT_NO_FATAL_FAILURE(runCompiler());
}
SelectionCollectionDataTest::runTest(const char *filename, const char * const *selections)
{
ASSERT_NO_FATAL_FAILURE(runParser(selections));
- loadTopology(filename);
+ ASSERT_NO_FATAL_FAILURE(loadTopology(filename));
ASSERT_NO_FATAL_FAILURE(runCompiler());
if (_flags.test(efTestEvaluation))
{
#include <gtest/gtest.h>
-#include "gromacs/errorreporting/emptyerrorreporter.h"
+#include "gromacs/fatalerror/exceptions.h"
#include "gromacs/options/globalproperties.h"
#include "gromacs/options/options.h"
#include "gromacs/options/optionsassigner.h"
SelectionOptionTest::SelectionOptionTest()
: _sc(NULL), _options(NULL, NULL)
{
- _sc.init();
_sc.setReferencePosType("atom");
_sc.setOutputPosType("atom");
_options.globalProperties().setSelectionCollection(&_sc);
{
gmx::Selection *sel = NULL;
using gmx::SelectionOption;
- _options.addOption(SelectionOption("sel").store(&sel));
-
- gmx::EmptyErrorReporter errors;
- gmx::OptionsAssigner assigner(&_options, &errors);
- ASSERT_EQ(0, assigner.startOption("sel"));
- EXPECT_EQ(0, assigner.appendValue("resname RA RB"));
- EXPECT_EQ(0, assigner.finish());
- EXPECT_EQ(0, _options.finish(&errors));
+ ASSERT_NO_THROW(_options.addOption(SelectionOption("sel").store(&sel)));
+
+ gmx::OptionsAssigner assigner(&_options);
+ EXPECT_NO_THROW(assigner.start());
+ ASSERT_NO_THROW(assigner.startOption("sel"));
+ EXPECT_NO_THROW(assigner.appendValue("resname RA RB"));
+ EXPECT_NO_THROW(assigner.finishOption());
+ EXPECT_NO_THROW(assigner.finish());
+ EXPECT_NO_THROW(_options.finish());
+
ASSERT_TRUE(sel != NULL);
ASSERT_FALSE(sel->isDynamic());
}
{
gmx::Selection *sel = NULL;
using gmx::SelectionOption;
- _options.addOption(SelectionOption("sel").store(&sel).onlyStatic());
-
- gmx::EmptyErrorReporter errors;
- gmx::OptionsAssigner assigner(&_options, &errors);
- ASSERT_EQ(0, assigner.startOption("sel"));
- EXPECT_NE(0, assigner.appendValue("resname RA RB and x < 5"));
- EXPECT_NE(0, assigner.finish());
- EXPECT_EQ(0, _options.finish(&errors));
+ ASSERT_NO_THROW(_options.addOption(
+ SelectionOption("sel").store(&sel).onlyStatic()));
+
+ gmx::OptionsAssigner assigner(&_options);
+ EXPECT_NO_THROW(assigner.start());
+ ASSERT_NO_THROW(assigner.startOption("sel"));
+ EXPECT_THROW(assigner.appendValue("resname RA RB and x < 5"), gmx::InvalidInputError);
+ EXPECT_NO_THROW(assigner.finishOption());
+ EXPECT_NO_THROW(assigner.finish());
+ EXPECT_NO_THROW(_options.finish());
}
{
gmx::Selection *sel = NULL;
using gmx::SelectionOption;
- _options.addOption(SelectionOption("sel").store(&sel));
-
- gmx::EmptyErrorReporter errors;
- gmx::OptionsAssigner assigner(&_options, &errors);
- ASSERT_EQ(0, assigner.startOption("sel"));
- EXPECT_EQ(0, assigner.appendValue("resname RA RB"));
- EXPECT_NE(0, assigner.appendValue("resname RB RC"));
- EXPECT_NE(0, assigner.finish());
- EXPECT_EQ(0, _options.finish(&errors));
+ ASSERT_NO_THROW(_options.addOption(SelectionOption("sel").store(&sel)));
+
+ gmx::OptionsAssigner assigner(&_options);
+ EXPECT_NO_THROW(assigner.start());
+ ASSERT_NO_THROW(assigner.startOption("sel"));
+ EXPECT_NO_THROW(assigner.appendValue("resname RA RB"));
+ EXPECT_THROW(assigner.appendValue("resname RB RC"), gmx::InvalidInputError);
+ EXPECT_NO_THROW(assigner.finishOption());
+ EXPECT_NO_THROW(assigner.finish());
+ EXPECT_NO_THROW(_options.finish());
ASSERT_TRUE(sel != NULL);
}
{
gmx::Selection *sel[2] = {NULL, NULL};
using gmx::SelectionOption;
- _options.addOption(SelectionOption("sel").store(sel).valueCount(2));
-
- gmx::EmptyErrorReporter errors;
- gmx::OptionsAssigner assigner(&_options, &errors);
- ASSERT_EQ(0, assigner.startOption("sel"));
- EXPECT_EQ(0, assigner.appendValue("resname RA RB"));
- EXPECT_NE(0, assigner.finish());
- EXPECT_EQ(0, _options.finish(&errors));
+ ASSERT_NO_THROW(_options.addOption(
+ SelectionOption("sel").store(sel).valueCount(2)));
+
+ gmx::OptionsAssigner assigner(&_options);
+ EXPECT_NO_THROW(assigner.start());
+ ASSERT_NO_THROW(assigner.startOption("sel"));
+ EXPECT_NO_THROW(assigner.appendValue("resname RA RB"));
+ EXPECT_THROW(assigner.finishOption(), gmx::InvalidInputError);
+ EXPECT_NO_THROW(assigner.finish());
+ EXPECT_NO_THROW(_options.finish());
}
std::vector<gmx::Selection *> sel;
gmx::SelectionOptionAdjuster *adjuster;
using gmx::SelectionOption;
- _options.addOption(SelectionOption("sel").storeVector(&sel).multiValue()
- .getAdjuster(&adjuster));
-
- gmx::EmptyErrorReporter errors;
- gmx::OptionsAssigner assigner(&_options, &errors);
- ASSERT_EQ(0, assigner.startOption("sel"));
- EXPECT_EQ(0, assigner.appendValue("resname RA RB"));
- EXPECT_EQ(0, assigner.appendValue("resname RB RC"));
- EXPECT_EQ(0, assigner.finish());
- EXPECT_EQ(0, _options.finish(&errors));
- gmx::OptionAdjusterErrorContext context(adjuster, &errors);
- EXPECT_EQ(0, adjuster->setValueCount(2));
+ ASSERT_NO_THROW(_options.addOption(
+ SelectionOption("sel").storeVector(&sel).multiValue()
+ .getAdjuster(&adjuster)));
+
+ gmx::OptionsAssigner assigner(&_options);
+ EXPECT_NO_THROW(assigner.start());
+ ASSERT_NO_THROW(assigner.startOption("sel"));
+ EXPECT_NO_THROW(assigner.appendValue("resname RA RB"));
+ EXPECT_NO_THROW(assigner.appendValue("resname RB RC"));
+ EXPECT_NO_THROW(assigner.finishOption());
+ EXPECT_NO_THROW(assigner.finish());
+ EXPECT_NO_THROW(_options.finish());
+ EXPECT_NO_THROW(adjuster->setValueCount(2));
}
gmx::Selection *sel;
gmx::SelectionOptionAdjuster *adjuster;
using gmx::SelectionOption;
- _options.addOption(SelectionOption("sel").store(&sel)
- .getAdjuster(&adjuster));
-
- gmx::EmptyErrorReporter errors;
- gmx::OptionsAssigner assigner(&_options, &errors);
- ASSERT_EQ(0, assigner.startOption("sel"));
- EXPECT_EQ(0, assigner.appendValue("x < 5"));
- EXPECT_EQ(0, assigner.finish());
- EXPECT_EQ(0, _options.finish(&errors));
- gmx::OptionAdjusterErrorContext context(adjuster, &errors);
- EXPECT_NE(0, adjuster->setOnlyStatic(true));
+ ASSERT_NO_THROW(_options.addOption(
+ SelectionOption("sel").store(&sel)
+ .getAdjuster(&adjuster)));
+
+ gmx::OptionsAssigner assigner(&_options);
+ EXPECT_NO_THROW(assigner.start());
+ ASSERT_NO_THROW(assigner.startOption("sel"));
+ EXPECT_NO_THROW(assigner.appendValue("x < 5"));
+ EXPECT_NO_THROW(assigner.finishOption());
+ EXPECT_NO_THROW(assigner.finish());
+ EXPECT_NO_THROW(_options.finish());
+ EXPECT_THROW(adjuster->setOnlyStatic(true), gmx::InvalidInputError);
}
std::vector<gmx::Selection *> sel;
gmx::SelectionOptionAdjuster *adjuster;
using gmx::SelectionOption;
- _options.addOption(SelectionOption("sel").storeVector(&sel).multiValue()
- .getAdjuster(&adjuster));
-
- gmx::EmptyErrorReporter errors;
- gmx::OptionsAssigner assigner(&_options, &errors);
- ASSERT_EQ(0, assigner.startOption("sel"));
- EXPECT_EQ(0, assigner.appendValue("resname RA RB"));
- EXPECT_EQ(0, assigner.appendValue("resname RB RC"));
- EXPECT_EQ(0, assigner.finish());
- EXPECT_EQ(0, _options.finish(&errors));
- gmx::OptionAdjusterErrorContext context(adjuster, &errors);
- EXPECT_NE(0, adjuster->setValueCount(1));
- EXPECT_EQ(1, errors.errorCount(gmx::AbstractErrorReporter::etError));
+ ASSERT_NO_THROW(_options.addOption(
+ SelectionOption("sel").storeVector(&sel).multiValue()
+ .getAdjuster(&adjuster)));
+
+ gmx::OptionsAssigner assigner(&_options);
+ EXPECT_NO_THROW(assigner.start());
+ ASSERT_NO_THROW(assigner.startOption("sel"));
+ EXPECT_NO_THROW(assigner.appendValue("resname RA RB"));
+ EXPECT_NO_THROW(assigner.appendValue("resname RB RC"));
+ EXPECT_NO_THROW(assigner.finishOption());
+ EXPECT_NO_THROW(assigner.finish());
+ EXPECT_NO_THROW(_options.finish());
+ EXPECT_THROW(adjuster->setValueCount(1), gmx::InvalidInputError);
}
std::vector<gmx::Selection *> sel;
gmx::SelectionOptionAdjuster *adjuster;
using gmx::SelectionOption;
- _options.addOption(SelectionOption("sel").storeVector(&sel).multiValue()
- .getAdjuster(&adjuster));
-
- gmx::EmptyErrorReporter errors;
- gmx::OptionsAssigner assigner(&_options, &errors);
- ASSERT_EQ(0, assigner.startOption("sel"));
- EXPECT_EQ(0, assigner.appendValue("resname RA RB"));
- EXPECT_EQ(0, assigner.finish());
- EXPECT_EQ(0, _options.finish(&errors));
- gmx::OptionAdjusterErrorContext context(adjuster, &errors);
- EXPECT_NE(0, adjuster->setValueCount(2));
- EXPECT_EQ(1, errors.errorCount(gmx::AbstractErrorReporter::etError));
+ ASSERT_NO_THROW(_options.addOption(
+ SelectionOption("sel").storeVector(&sel).multiValue()
+ .getAdjuster(&adjuster)));
+
+ gmx::OptionsAssigner assigner(&_options);
+ EXPECT_NO_THROW(assigner.start());
+ ASSERT_NO_THROW(assigner.startOption("sel"));
+ EXPECT_NO_THROW(assigner.appendValue("resname RA RB"));
+ EXPECT_NO_THROW(assigner.finishOption());
+ EXPECT_NO_THROW(assigner.finish());
+ EXPECT_NO_THROW(_options.finish());
+ EXPECT_THROW(adjuster->setValueCount(2), gmx::InvalidInputError);
}
{
gmx::Selection *sel = NULL;
using gmx::SelectionOption;
- _options.addOption(SelectionOption("sel").store(&sel).required());
-
- gmx::EmptyErrorReporter errors;
- gmx::OptionsAssigner assigner(&_options, &errors);
- EXPECT_EQ(0, assigner.finish());
- EXPECT_EQ(0, _options.finish(&errors));
- EXPECT_EQ(0, _sc.parseRequestedFromString("resname RA RB", &errors));
+ ASSERT_NO_THROW(_options.addOption(
+ SelectionOption("sel").store(&sel).required()));
+
+ gmx::OptionsAssigner assigner(&_options);
+ EXPECT_NO_THROW(assigner.start());
+ EXPECT_NO_THROW(assigner.finish());
+ EXPECT_NO_THROW(_options.finish());
+ EXPECT_NO_THROW(_sc.parseRequestedFromString("resname RA RB"));
ASSERT_TRUE(sel != NULL);
}
{
gmx::Selection *sel[2] = {NULL, NULL};
using gmx::SelectionOption;
- _options.addOption(SelectionOption("sel").store(sel).required()
- .valueCount(2));
-
- gmx::EmptyErrorReporter errors;
- gmx::OptionsAssigner assigner(&_options, &errors);
- EXPECT_EQ(0, assigner.finish());
- EXPECT_EQ(0, _options.finish(&errors));
- EXPECT_NE(0, _sc.parseRequestedFromString("resname RA RB", &errors));
+ ASSERT_NO_THROW(_options.addOption(
+ SelectionOption("sel").store(sel).required()
+ .valueCount(2)));
+
+ gmx::OptionsAssigner assigner(&_options);
+ EXPECT_NO_THROW(assigner.start());
+ EXPECT_NO_THROW(assigner.finish());
+ EXPECT_NO_THROW(_options.finish());
+ EXPECT_THROW(_sc.parseRequestedFromString("resname RA RB"), gmx::InvalidInputError);
}
{
gmx::Selection *sel = NULL;
using gmx::SelectionOption;
- _options.addOption(SelectionOption("sel").store(&sel));
-
- gmx::EmptyErrorReporter errors;
- gmx::OptionsAssigner assigner(&_options, &errors);
- ASSERT_EQ(0, assigner.startOption("sel"));
- EXPECT_EQ(0, assigner.finish());
- EXPECT_EQ(0, _options.finish(&errors));
- EXPECT_EQ(0, _sc.parseRequestedFromString("resname RA RB", &errors));
+ ASSERT_NO_THROW(_options.addOption(SelectionOption("sel").store(&sel)));
+
+ gmx::OptionsAssigner assigner(&_options);
+ EXPECT_NO_THROW(assigner.start());
+ ASSERT_NO_THROW(assigner.startOption("sel"));
+ EXPECT_NO_THROW(assigner.finishOption());
+ EXPECT_NO_THROW(assigner.finish());
+ EXPECT_NO_THROW(_options.finish());
+ EXPECT_NO_THROW(_sc.parseRequestedFromString("resname RA RB"));
ASSERT_TRUE(sel != NULL);
}
std::vector<gmx::Selection *> sel;
gmx::SelectionOptionAdjuster *adjuster;
using gmx::SelectionOption;
- _options.addOption(SelectionOption("sel").storeVector(&sel).valueCount(3)
- .getAdjuster(&adjuster));
-
- gmx::EmptyErrorReporter errors;
- gmx::OptionsAssigner assigner(&_options, &errors);
- ASSERT_EQ(0, assigner.startOption("sel"));
- EXPECT_EQ(0, assigner.finish());
- EXPECT_EQ(0, _options.finish(&errors));
- gmx::OptionAdjusterErrorContext context(adjuster, &errors);
- EXPECT_EQ(0, adjuster->setValueCount(2));
- EXPECT_EQ(0, _sc.parseRequestedFromString("resname RA RB; resname RB RC", &errors));
+ ASSERT_NO_THROW(_options.addOption(
+ SelectionOption("sel").storeVector(&sel).valueCount(3)
+ .getAdjuster(&adjuster)));
+
+ gmx::OptionsAssigner assigner(&_options);
+ EXPECT_NO_THROW(assigner.start());
+ ASSERT_NO_THROW(assigner.startOption("sel"));
+ EXPECT_NO_THROW(assigner.finishOption());
+ EXPECT_NO_THROW(assigner.finish());
+ EXPECT_NO_THROW(_options.finish());
+ EXPECT_NO_THROW(adjuster->setValueCount(2));
+ EXPECT_NO_THROW(_sc.parseRequestedFromString("resname RA RB; resname RB RC"));
}
} // namespace
#include "options.h"
#include "selection.h"
-#include "errorreporting/abstracterrorreporter.h"
-#include "errorreporting/errorcontext.h"
+#include "fatalerror/exceptions.h"
#include "trajectoryanalysis/analysismodule.h"
#include "trajectoryanalysis/analysissettings.h"
#include "trajectoryanalysis/cmdlinerunner.h"
Impl() : _selections(NULL) {}
~Impl();
- int finishHandles();
+ void finishHandles();
HandleContainer _handles;
const SelectionCollection *_selections;
class TrajectoryAnalysisModuleDataBasic : public TrajectoryAnalysisModuleData
{
public:
- virtual int finish();
+ TrajectoryAnalysisModuleDataBasic(TrajectoryAnalysisModule *module,
+ /*AnalysisDataParallelOptions*/ void* opt,
+ const SelectionCollection &selections);
+
+ virtual void finish();
};
} // namespace gmx
*/
#include "gromacs/trajectoryanalysis/analysismodule.h"
-#include <cassert>
-
#include "gromacs/analysisdata/analysisdata.h"
+#include "gromacs/fatalerror/gmxassert.h"
#include "analysismodule-impl.h"
TrajectoryAnalysisModuleData::Impl::~Impl()
{
- finishHandles();
+ try
+ {
+ finishHandles();
+ }
+ catch (...)
+ {
+ }
}
-int TrajectoryAnalysisModuleData::Impl::finishHandles()
+void TrajectoryAnalysisModuleData::Impl::finishHandles()
{
- int rc = 0;
+ // FIXME: Call finishData() for all handles even if one throws
HandleContainer::const_iterator i;
for (i = _handles.begin(); i != _handles.end(); ++i)
{
- int rc1 = i->second->finishData();
- rc = (rc == 0 ? rc1 : rc);
+ i->second->finishData();
}
_handles.clear();
- return rc;
}
* TrajectoryAnalysisModuleData
*/
-TrajectoryAnalysisModuleData::TrajectoryAnalysisModuleData()
+TrajectoryAnalysisModuleData::TrajectoryAnalysisModuleData(
+ TrajectoryAnalysisModule *module,
+ AnalysisDataParallelOptions opt,
+ const SelectionCollection &selections)
: _impl(new Impl)
-{
-}
-
-
-TrajectoryAnalysisModuleData::~TrajectoryAnalysisModuleData()
-{
- delete _impl;
-}
-
-
-int TrajectoryAnalysisModuleData::init(TrajectoryAnalysisModule *module,
- AnalysisDataParallelOptions opt,
- const SelectionCollection &selections)
{
TrajectoryAnalysisModule::Impl::AnalysisDatasetContainer::const_iterator i;
for (i = module->_impl->_analysisDatasets.begin();
i != module->_impl->_analysisDatasets.end(); ++i)
{
- AnalysisDataHandle *handle = NULL;
- int rc = i->second->startData(&handle, opt);
- if (rc != 0)
- {
- return rc;
- }
- _impl->_handles[i->first] = handle;
+ _impl->_handles[i->first] = i->second->startData(opt);
}
_impl->_selections = &selections;
- return 0;
}
-int TrajectoryAnalysisModuleData::finishDataHandles()
+TrajectoryAnalysisModuleData::~TrajectoryAnalysisModuleData()
{
- return _impl->finishHandles();
+ delete _impl;
+}
+
+
+void TrajectoryAnalysisModuleData::finishDataHandles()
+{
+ _impl->finishHandles();
}
AnalysisDataHandle *TrajectoryAnalysisModuleData::dataHandle(const char *name)
{
Impl::HandleContainer::const_iterator i = _impl->_handles.find(name);
- assert(i != _impl->_handles.end() || !"Data handle requested on unknown dataset");
+ GMX_RELEASE_ASSERT(i != _impl->_handles.end(),
+ "Data handle requested on unknown dataset");
return (i != _impl->_handles.end()) ? (*i).second : NULL;
}
/********************************************************************
* TrajectoryAnalysisModuleDataBasic
*/
+TrajectoryAnalysisModuleDataBasic::TrajectoryAnalysisModuleDataBasic(
+ TrajectoryAnalysisModule *module,
+ /*AnalysisDataParallelOptions*/ void* opt,
+ const SelectionCollection &selections)
+ : TrajectoryAnalysisModuleData(module, opt, selections)
+{
+}
-int
+
+void
TrajectoryAnalysisModuleDataBasic::finish()
{
- return finishDataHandles();
+ finishDataHandles();
}
}
-int TrajectoryAnalysisModule::initOptionsDone(TrajectoryAnalysisSettings * /*settings*/,
- AbstractErrorReporter * /*errors*/)
+void TrajectoryAnalysisModule::initOptionsDone(TrajectoryAnalysisSettings * /*settings*/)
{
- return 0;
}
-int TrajectoryAnalysisModule::initAfterFirstFrame(const t_trxframe &/*fr*/)
+void TrajectoryAnalysisModule::initAfterFirstFrame(const t_trxframe &/*fr*/)
{
- return 0;
}
-int TrajectoryAnalysisModule::startFrames(AnalysisDataParallelOptions opt,
- const SelectionCollection &selections,
- TrajectoryAnalysisModuleData **pdatap)
+TrajectoryAnalysisModuleData *
+TrajectoryAnalysisModule::startFrames(AnalysisDataParallelOptions opt,
+ const SelectionCollection &selections)
{
- TrajectoryAnalysisModuleDataBasic *pdata
- = new TrajectoryAnalysisModuleDataBasic();
- *pdatap = pdata;
- int rc = pdata->init(this, opt, selections);
- if (rc != 0)
- {
- delete pdata;
- *pdatap = NULL;
- }
- return rc;
+ return new TrajectoryAnalysisModuleDataBasic(this, opt, selections);
}
-int TrajectoryAnalysisModule::finishFrames(TrajectoryAnalysisModuleData * /*pdata*/)
+void TrajectoryAnalysisModule::finishFrames(TrajectoryAnalysisModuleData * /*pdata*/)
{
- return 0;
}
{
class AbstractAnalysisData;
-class AbstractErrorReporter;
class AnalysisData;
class AnalysisDataHandle;
class Options;
public:
virtual ~TrajectoryAnalysisModuleData();
- /*! \brief
- * Initializes thread-local storage for data handles and selections.
- *
- * \param[in] module Analysis module to use for data objects.
- * \param[in] opt Data parallelization options.
- * \param[in] selections Thread-local selection collection.
- *
- * Calls AnalysisData::startData() on all data objects registered with
- * TrajectoryAnalysisModule::registerAnalysisDataset() in \p module.
- * The handles are accessible through dataHandle().
- */
- int init(TrajectoryAnalysisModule *module, /*AnalysisDataParallelOptions*/ void* opt,
- const SelectionCollection &selections);
-
/*! \brief
* Performs any finishing actions after all frames have been processed.
*
- * \returns 0 on success, a non-zero error code on error.
- *
* This function is called immediately before the destructor.
* All implementations should call finishDataHandles().
*/
- virtual int finish() = 0;
+ virtual void finish() = 0;
/*! \brief
* Returns a data handle for a dataset with a given name.
std::vector<Selection *> parallelSelections(const std::vector<Selection *> &selections);
protected:
- //! Initializes data.
- TrajectoryAnalysisModuleData();
+ /*! \brief
+ * Initializes thread-local storage for data handles and selections.
+ *
+ * \param[in] module Analysis module to use for data objects.
+ * \param[in] opt Data parallelization options.
+ * \param[in] selections Thread-local selection collection.
+ *
+ * Calls AnalysisData::startData() on all data objects registered with
+ * TrajectoryAnalysisModule::registerAnalysisDataset() in \p module.
+ * The handles are accessible through dataHandle().
+ */
+ TrajectoryAnalysisModuleData(TrajectoryAnalysisModule *module,
+ /*AnalysisDataParallelOptions*/ void* opt,
+ const SelectionCollection &selections);
/*! \brief
* Calls finishData() on all data handles.
*
- * \returns 0 on success, a non-zero error code on error.
- *
* This function should be called from the implementation of finish()
* in all subclasses.
*/
- int finishDataHandles();
+ void finishDataHandles();
private:
class Impl;
/*! \brief
* Called after all option values have been set.
*
- * \returns Zero on success, a non-zero error code on error.
- *
* If the module needs to change settings that affect topology loading
* or selection initialization based on option values, this function
* has to be overridden.
*
* The default implementation does nothing.
*/
- virtual int initOptionsDone(TrajectoryAnalysisSettings *settings,
- AbstractErrorReporter *errors);
+ virtual void initOptionsDone(TrajectoryAnalysisSettings *settings);
/*! \brief
* Initializes the analysis.
*
- * \returns Zero on success, a non-zero error code on error.
- *
* When this function is called, selections have been initialized based
* on user input, and a topology has been loaded if provided by the
* user. For dynamic selections, the selections have been evaluated to
* the largest possible selection, i.e., the selections passed to
* analyzeFrame() are always a subset of the selections provided here.
*/
- virtual int initAnalysis(const TopologyInformation &top) = 0;
+ virtual void initAnalysis(const TopologyInformation &top) = 0;
/*! \brief
* Performs additional initialization after reading the first frame.
*
- * \returns Zero on success, a non-zero error code on error.
- *
* When this function is called, selections are the same as in
* initAnalysis(), i.e., they have not been evaluated for the first
* frame.
*
* The default implementation does nothing.
*/
- virtual int initAfterFirstFrame(const t_trxframe &fr);
+ virtual void initAfterFirstFrame(const t_trxframe &fr);
/*! \brief
* Starts the analysis of frames.
*
* \param[in] opt
* \param[in] selections Frame-local selection collection object.
- * \param[out] pdatap Data structure for thread-local data.
+ * \returns Data structure for thread-local data.
*
* This function is necessary only for threaded parallelization.
* It is called once for each thread and should initialize a class that
- * contains any required frame-local data in \p *pdatap.
+ * contains any required frame-local data in the returned value.
* The default implementation creates a basic data structure that holds
* thread-local data handles for all data objects registered with
* registerAnalysisDataset(), as well as the thread-local selection
*
* \see TrajectoryAnalysisModuleData
*/
- virtual int startFrames(/*AnalysisDataParallelOptions*/ void* opt,
- const SelectionCollection &selections,
- TrajectoryAnalysisModuleData **pdatap);
+ virtual TrajectoryAnalysisModuleData *startFrames(
+ /*AnalysisDataParallelOptions*/ void* opt,
+ const SelectionCollection &selections);
/*! \brief
* Analyzes a single frame.
*
* \param[in] fr Current frame.
* \param[in] pbc Periodic boundary conditions for \p fr.
* \param[in,out] pdata Data structure for frame-local data.
- * \return 0 on success, a non-zero error code or error.
*
* This function is called once for each frame to be analyzed,
* and should analyze the positions provided in \p sel.
* Any access to data structures not stored in \p pdata should be
* designed to be thread-safe.
*/
- virtual int analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc,
- TrajectoryAnalysisModuleData *pdata) = 0;
+ virtual void analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc,
+ TrajectoryAnalysisModuleData *pdata) = 0;
/*! \brief
* Finishes the analysis of frames.
*
*
* \see startFrames()
*/
- virtual int finishFrames(TrajectoryAnalysisModuleData *pdata);
+ virtual void finishFrames(TrajectoryAnalysisModuleData *pdata);
/*! \brief
* Postprocesses data after frames have been read.
* This function is called after all finishFrames() calls have been
* called.
*/
- virtual int finishAnalysis(int nframes) = 0;
+ virtual void finishAnalysis(int nframes) = 0;
/*! \brief
* Writes output into files and/or standard output/error.
*
* This function is guaranteed to be called only after
* finishAnalysis().
*/
- virtual int writeOutput() = 0;
+ virtual void writeOutput() = 0;
/*! \brief
* Returns the number of datasets provided by the module.
#include <statutil.h>
#include <vec.h>
-#include "gromacs/fatalerror/fatalerror.h"
+#include "gromacs/fatalerror/exceptions.h"
#include "gromacs/trajectoryanalysis/analysissettings.h"
#include "analysissettings-impl.h"
}
-int
+void
TrajectoryAnalysisSettings::setFlags(unsigned long flags)
{
_impl->flags = flags;
- return 0;
}
-int
+void
TrajectoryAnalysisSettings::setFlag(unsigned long flag, bool bSet)
{
if (bSet)
{
_impl->flags &= ~flag;
}
- return 0;
}
-int
+void
TrajectoryAnalysisSettings::setPBC(bool bPBC)
{
_impl->bPBC = bPBC;
- return 0;
}
-int
+void
TrajectoryAnalysisSettings::setRmPBC(bool bRmPBC)
{
_impl->bRmPBC = bRmPBC;
- return 0;
}
-int
+void
TrajectoryAnalysisSettings::setFrameFlags(int frflags)
{
_impl->frflags = frflags;
- return 0;
}
clear_mat(_boxtop);
}
+
TopologyInformation::~TopologyInformation()
{
if (_top)
sfree(_xtop);
}
-int
+
+void
TopologyInformation::getTopologyConf(rvec **x, matrix box) const
{
if (box)
if (!_xtop)
{
*x = NULL;
- GMX_ERROR(eeInvalidValue,
- "Topology coordinates requested without setting efUseTopX");
- return -1;
+ GMX_THROW(APIError("Topology coordinates requested without setting efUseTopX"));
}
*x = _xtop;
}
- return 0;
}
} // namespace gmx
* Overrides any earlier set flags.
* By default, no flags are set.
*/
- int setFlags(unsigned long flags);
+ void setFlags(unsigned long flags);
//! Sets or clears an individual flag.
- int setFlag(unsigned long flag, bool bSet = true);
+ void setFlag(unsigned long flag, bool bSet = true);
/*! \brief
* Sets whether PBC are used.
*
* \param[in] bPBC TRUE if PBC should be used.
- * \returns 0 on success.
*
* If called in TrajectoryAnalysisModule::initOptions(), this function
* sets the default for whether PBC are used in the analysis.
*
* \see ::efNoUserPBC
*/
- int setPBC(bool bPBC);
+ void setPBC(bool bPBC);
/*! \brief
* Sets whether molecules are made whole.
*
* \param[in] bRmPBC TRUE if molecules should be made whole.
- * \returns 0 on success.
*
* If called in TrajectoryAnalysisModule::initOptions(), this function
* sets the default for whether molecules are made whole.
*
* \see ::efNoUserRmPBC
*/
- int setRmPBC(bool bRmPBC);
+ void setRmPBC(bool bRmPBC);
/*! \brief
* Sets flags that determine what to read from the trajectory.
*
* \param[in] frflags Flags for what to read from the trajectory file.
- * \returns 0 on success, an error code on error.
*
* If this function is not called, the flags default to TRX_NEED_X.
* If the analysis module needs some other information (velocities,
* forces), it can call this function to load additional information
* from the trajectory.
*/
- int setFrameFlags(int frflags);
+ void setFrameFlags(int frflags);
private:
class Impl;
* (can be NULL, in which case it is not used).
* \param[out] box Box size from the topology file
* (can be NULL, in which case it is not used).
- * \returns 0 on success, a non-zero error code on error.
*
* If TrajectoryAnalysisSettings::efUseTopX has not been specified,
* \p x should be NULL.
*
* The pointer returned in \p *x should not be freed.
*/
- int getTopologyConf(rvec **x, matrix box) const;
+ void getTopologyConf(rvec **x, matrix box) const;
private:
TopologyInformation();
#include <config.h>
#endif
+#include <memory>
+
#include <copyrite.h>
#include <pbc.h>
#include <rmpbc.h>
#include <statutil.h>
-#include "gromacs/errorreporting/standarderrorreporter.h"
-#include "gromacs/fatalerror/fatalerror.h"
+#include "gromacs/fatalerror/exceptions.h"
+#include "gromacs/fatalerror/gmxassert.h"
#include "gromacs/options/asciihelpwriter.h"
#include "gromacs/options/cmdlineparser.h"
#include "gromacs/options/globalproperties.h"
void printHelp(const Options &options,
const TrajectoryAnalysisRunnerCommon &common);
- int parseOptions(TrajectoryAnalysisSettings *settings,
- TrajectoryAnalysisRunnerCommon *common,
- SelectionCollection *selections,
- Options *options,
- int *argc, char *argv[]);
+ bool parseOptions(TrajectoryAnalysisSettings *settings,
+ TrajectoryAnalysisRunnerCommon *common,
+ SelectionCollection *selections,
+ Options *options,
+ int *argc, char *argv[]);
TrajectoryAnalysisModule *_module;
int _debugLevel;
}
-int
+bool
TrajectoryAnalysisCommandLineRunner::Impl::parseOptions(
TrajectoryAnalysisSettings *settings,
TrajectoryAnalysisRunnerCommon *common,
Options *options,
int *argc, char *argv[])
{
- StandardErrorReporter errors;
int rc;
Options *moduleOptions = _module->initOptions(settings);
- if (moduleOptions == NULL)
- {
- GMX_ERROR(eeOutOfMemory,
- "Could not allocate memory for option storage");
- }
-
+ GMX_RELEASE_ASSERT(moduleOptions != NULL, "Module returned NULL options");
Options *commonOptions = common->initOptions();
- if (moduleOptions == NULL)
- {
- GMX_ERROR(eeOutOfMemory,
- "Could not allocate memory for option storage");
- }
-
Options *selectionOptions = selections->initOptions();
- if (selectionOptions == NULL)
- {
- GMX_ERROR(eeOutOfMemory,
- "Could not allocate memory for option storage");
- }
options->addSubSection(commonOptions);
options->addSubSection(selectionOptions);
commonOptions->addDefaultOptions();
{
- CommandLineParser parser(options, &errors);
- rc = parser.parse(argc, argv);
- printHelp(*options, *common);
- if (rc != 0)
+ CommandLineParser parser(options);
+ try
{
- GMX_ERROR(rc, "Command-line option parsing failed, "
- "see higher up for detailed error messages");
+ parser.parse(argc, argv);
}
- rc = options->finish(&errors);
- if (rc != 0)
+ catch (UserInputError &ex)
{
- GMX_ERROR(rc, "Command-line option parsing failed, "
- "see higher up for detailed error messages");
+ printHelp(*options, *common);
+ throw;
}
+ printHelp(*options, *common);
+ options->finish();
}
- rc = common->initOptionsDone();
- if (rc != 0)
+ if (!common->initOptionsDone())
{
- return rc;
+ return false;
}
- rc = _module->initOptionsDone(settings, &errors);
+ _module->initOptionsDone(settings);
+ /*
if (rc != 0)
{
if (rc == eeInconsistentInput)
}
return rc;
}
+ */
- rc = common->initIndexGroups(selections);
- if (rc != 0)
- {
- return rc;
- }
+ common->initIndexGroups(selections);
// TODO: Check whether the input is a pipe.
bool bInteractive = true;
- rc = selections->parseRequestedFromStdin(bInteractive, &errors);
+ selections->parseRequestedFromStdin(bInteractive);
common->doneIndexGroups(selections);
- return rc;
+
+ return true;
}
CopyRight(stderr, argv[0]);
SelectionCollection selections(NULL);
- rc = selections.init();
- if (rc != 0)
- {
- return rc;
- }
selections.setDebugLevel(_impl->_debugLevel);
TrajectoryAnalysisSettings settings;
TrajectoryAnalysisRunnerCommon common(&settings);
Options options(NULL, NULL);
- rc = _impl->parseOptions(&settings, &common, &selections, &options,
- &argc, argv);
- if (rc != 0)
+ if (!_impl->parseOptions(&settings, &common, &selections, &options,
+ &argc, argv))
{
- return rc;
+ return 0;
}
- rc = common.initTopology(&selections);
- if (rc != 0)
- {
- return rc;
- }
+ common.initTopology(&selections);
rc = selections.compile();
if (rc != 0)
{
- return rc;
+ // Error message has already been printed.
+ return 1;
}
const TopologyInformation &topology = common.topologyInformation();
- rc = module->initAnalysis(topology);
- if (rc != 0)
- {
- return rc;
- }
+ module->initAnalysis(topology);
// Load first frame.
- rc = common.initFirstFrame();
- if (rc != 0)
- {
- return rc;
- }
- rc = module->initAfterFirstFrame(common.frame());
- if (rc != 0)
- {
- return rc;
- }
+ common.initFirstFrame();
+ module->initAfterFirstFrame(common.frame());
t_pbc pbc;
- t_pbc *ppbc = settings.hasPBC() ? &pbc : 0;
+ t_pbc *ppbc = settings.hasPBC() ? &pbc : NULL;
int nframes = 0;
- TrajectoryAnalysisModuleData *pdata = NULL;
- rc = module->startFrames(NULL, selections, &pdata);
- if (rc != 0)
- {
- return rc;
- }
+ std::auto_ptr<TrajectoryAnalysisModuleData>
+ pdata(module->startFrames(NULL, selections));
do
{
- rc = common.initFrame();
- if (rc != 0)
- {
- return rc;
- }
+ common.initFrame();
t_trxframe &frame = common.frame();
- if (ppbc)
+ if (ppbc != NULL)
{
set_pbc(ppbc, topology.ePBC(), frame.box);
}
rc = selections.evaluate(&frame, ppbc);
if (rc != 0)
{
- return rc;
- }
- rc = module->analyzeFrame(nframes, frame, ppbc, pdata);
- if (rc != 0)
- {
- return rc;
+ // Error message has already been printed.
+ return 1;
}
+ module->analyzeFrame(nframes, frame, ppbc, pdata.get());
nframes++;
}
while (common.readNextFrame());
- rc = module->finishFrames(pdata);
- if (rc != 0)
+ module->finishFrames(pdata.get());
+ if (pdata.get() != NULL)
{
- return rc;
- }
- if (pdata)
- {
- rc = pdata->finish();
- delete pdata;
- if (rc != 0)
- {
- return rc;
- }
+ pdata->finish();
}
+ pdata.reset();
if (common.hasTrajectory())
{
}
// Restore the maximal groups for dynamic selections.
- rc = selections.evaluateFinal(nframes);
- if (rc != 0)
- {
- return rc;
- }
+ selections.evaluateFinal(nframes);
- rc = module->finishAnalysis(nframes);
- if (rc == 0)
- {
- rc = module->writeOutput();
- }
+ module->finishAnalysis(nframes);
+ module->writeOutput();
- return rc;
+ return 0;
}
} // namespace gmx
#include <pbc.h>
#include <vec.h>
+// FIXME: This kind of hackery should not be necessary
+#undef min
+#undef max
#include "gromacs/analysisdata/analysisdata.h"
#include "gromacs/analysisdata/modules/plot.h"
-#include "gromacs/errorreporting/abstracterrorreporter.h"
-#include "gromacs/fatalerror/fatalerror.h"
+#include "gromacs/fatalerror/exceptions.h"
#include "gromacs/options/basicoptions.h"
#include "gromacs/options/options.h"
#include "gromacs/selection/selection.h"
#include "gromacs/selection/selectionoption.h"
+#include "gromacs/utility/format.h"
namespace gmx
{
}
-int
-Angle::initOptionsDone(TrajectoryAnalysisSettings *settings,
- AbstractErrorReporter *errors)
+void
+Angle::initOptionsDone(TrajectoryAnalysisSettings *settings)
{
// Validity checks.
bool bSingle = (_g1type[0] == 'a' || _g1type[0] == 'd');
if (bSingle && _g2type[0] != 'n')
{
- errors->error("Cannot use a second group (-g2) with -g1 angle or dihedral");
- return eeInconsistentInput;
+ GMX_THROW(InconsistentInputError("Cannot use a second group (-g2) with "
+ "-g1 angle or dihedral"));
}
if (bSingle && _options.isSet("group2"))
{
- errors->error("Cannot provide a second selection (-group2) with "
- "-g1 angle or dihedral");
- return eeInconsistentInput;
+ GMX_THROW(InconsistentInputError("Cannot provide a second selection "
+ "(-group2) with -g1 angle or dihedral"));
}
if (!bSingle && _g2type[0] == 'n')
{
- errors->error("Should specify a second group (-g2) if the first group "
- "is not an angle or a dihedral");
- return eeInconsistentInput;
+ GMX_THROW(InconsistentInputError("Should specify a second group (-g2) "
+ "if the first group is not an angle or a dihedral"));
}
if (bSingle && _bDumpDist)
{
- errors->warning("Cannot calculate distances with -g1 angle or dihedral");
- _bDumpDist = false;
+ GMX_THROW(InconsistentInputError("Cannot calculate distances with -g1 angle or dihedral"));
+ // _bDumpDist = false;
}
- if (_bMulti && _bSplit1)
+ if (_bMulti && !bSingle)
{
- errors->error("-mult can only be combined with -g1 angle or dihedral");
- return eeInconsistentInput;
+ GMX_THROW(InconsistentInputError("-mult can only be combined with -g1 angle or dihedral"));
}
- if (!bSingle && _bMulti)
+ if (_bMulti && _bSplit1)
{
- errors->error("-mult can only be combined with -g1 angle or dihedral");
- return eeInconsistentInput;
+ GMX_THROW(InconsistentInputError("-mult can not be combined with -split1"));
}
if (_bMulti && _bAll)
{
- errors->error("-mult and -all are mutually exclusive options");
- return eeInconsistentInput;
+ GMX_THROW(InconsistentInputError("-mult and -all are mutually exclusive options"));
}
+
if (_bAll)
{
- int rc = _sel1Adj->setOnlyStatic(true);
- if (rc != 0)
- {
- return rc;
- }
+ _sel1Adj->setOnlyStatic(true);
}
// Set up the number of positions per angle.
case 'v': _natoms1 = 2; break;
case 'p': _natoms1 = 3; break;
default:
- GMX_ERROR(eeInternalError, "invalid -g1 value");
+ GMX_THROW(InternalError("invalid -g1 value"));
}
switch (_g2type[0])
{
case 'z': _natoms2 = 0; break;
case 's': _natoms2 = 1; break;
default:
- GMX_ERROR(eeInternalError, "invalid -g2 value");
+ GMX_THROW(InternalError("invalid -g2 value"));
}
if (_natoms2 == 0 && _options.isSet("group2"))
{
- errors->error("Cannot provide a second selection (-group2) with -g2 t0 or z");
- return eeInconsistentInput;
+ GMX_THROW(InconsistentInputError("Cannot provide a second selection (-group2) with -g2 t0 or z"));
}
if (!_bMulti)
{
- OptionAdjusterErrorContext context(_sel1Adj, errors);
- int rc = _sel1Adj->setValueCount(_bSplit1 ? _natoms1 : 1);
- if (rc != 0)
- {
- return rc;
- }
+ _sel1Adj->setValueCount(_bSplit1 ? _natoms1 : 1);
}
if (_natoms2 > 0)
{
- OptionAdjusterErrorContext context(_sel2Adj, errors);
- int rc = _sel2Adj->setValueCount(_bSplit2 ? _natoms2 : 1);
- if (rc != 0)
- {
- return rc;
- }
+ _sel2Adj->setValueCount(_bSplit2 ? _natoms2 : 1);
}
-
- return 0;
}
-int
+void
Angle::checkSelections(const std::vector<Selection *> &sel1,
const std::vector<Selection *> &sel2) const
{
{
if (sel1[g]->posCount() % _natoms1 != 0)
{
- fatalErrorFormatted(eeInconsistentInput, GMX_ERRORLOC,
+ GMX_THROW(InconsistentInputError(formatString(
"Number of positions in selection %d not divisible by %d",
- static_cast<int>(g + 1), _natoms1);
- return eeInconsistentInput;
+ static_cast<int>(g + 1), _natoms1)));
}
}
- return 0;
+ return;
}
int na1 = sel1[0]->posCount();
if (!_bSplit1 && _natoms1 > 1 && na1 % _natoms1 != 0)
{
- fatalErrorFormatted(eeInconsistentInput, GMX_ERRORLOC,
+ GMX_THROW(InconsistentInputError(formatString(
"Number of positions in the first group not divisible by %d",
- _natoms1);
- return eeInconsistentInput;
+ _natoms1)));
}
if (!_bSplit2 && _natoms2 > 1 && na2 % _natoms2 != 0)
{
- fatalErrorFormatted(eeInconsistentInput, GMX_ERRORLOC,
+ GMX_THROW(InconsistentInputError(formatString(
"Number of positions in the second group not divisible by %d",
- _natoms2);
- return eeInconsistentInput;
+ _natoms2)));
}
if (_bSplit1)
{
if (sel1[g]->posCount() != na1)
{
- GMX_ERROR(eeInconsistentInput,
+ GMX_THROW(InconsistentInputError(
"All selections in the first group should contain "
- "the same number of positions");
+ "the same number of positions"));
}
}
}
{
if (sel2[g]->posCount() != na2)
{
- GMX_ERROR(eeInconsistentInput,
+ GMX_THROW(InconsistentInputError(
"All selections in the second group should contain "
- "the same number of positions");
+ "the same number of positions"));
}
}
}
}
if (_natoms1 > 0 && _natoms2 > 1 && na1 != na2)
{
- GMX_ERROR(eeInconsistentInput,
- "Number of vectors defined by the two groups are not the same");
+ GMX_THROW(InconsistentInputError(
+ "Number of vectors defined by the two groups are not the same"));
}
if (_g2type[0] == 's' && sel2[0]->posCount() != 1)
{
- GMX_ERROR(eeInconsistentInput,
- "The second group should contain a single position with -g2 sphnorm");
+ GMX_THROW(InconsistentInputError(
+ "The second group should contain a single position with -g2 sphnorm"));
}
- return 0;
}
-int
+void
Angle::initAnalysis(const TopologyInformation &top)
{
- int rc = checkSelections(_sel1, _sel2);
- if (rc != 0)
- {
- return rc;
- }
+ checkSelections(_sel1, _sel2);
if (_bMulti)
{
plotm->setXTimeLabel();
plotm->setYLabel("Angle [degrees]");
_data.addModule(plotm);
-
- return 0;
}
}
-int
+void
Angle::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc,
TrajectoryAnalysisModuleData *pdata)
{
std::vector<Selection *> sel1 = pdata->parallelSelections(_sel1);
std::vector<Selection *> sel2 = pdata->parallelSelections(_sel2);
- int rc = checkSelections(sel1, sel2);
- if (rc != 0)
- {
- return rc;
- }
+ checkSelections(sel1, sel2);
rvec v1, v2;
rvec c1, c2;
}
break;
default:
- GMX_ERROR(eeInternalError, "invalid -g2 value");
+ GMX_THROW(InternalError("invalid -g2 value"));
}
angle = gmx_angle(v1, v2);
break;
default:
- GMX_ERROR(eeInternalError, "invalid -g1 value");
+ GMX_THROW(InternalError("invalid -g1 value"));
}
angle *= RAD2DEG;
real dist = 0.0;
dh->addPoint(g, ave);
}
dh->finishFrame();
- return 0;
}
-int
+void
Angle::finishAnalysis(int /*nframes*/)
{
- return 0;
}
-int
+void
Angle::writeOutput()
{
- return 0;
}
static TrajectoryAnalysisModule *create();
virtual Options *initOptions(TrajectoryAnalysisSettings *settings);
- virtual int initOptionsDone(TrajectoryAnalysisSettings *settings,
- AbstractErrorReporter *errors);
- virtual int initAnalysis(const TopologyInformation &top);
+ virtual void initOptionsDone(TrajectoryAnalysisSettings *settings);
+ virtual void initAnalysis(const TopologyInformation &top);
- virtual int analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc,
- TrajectoryAnalysisModuleData *pdata);
+ virtual void analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc,
+ TrajectoryAnalysisModuleData *pdata);
- virtual int finishAnalysis(int nframes);
- virtual int writeOutput();
+ virtual void finishAnalysis(int nframes);
+ virtual void writeOutput();
private:
- int checkSelections(const std::vector<Selection *> &sel1,
- const std::vector<Selection *> &sel2) const;
+ void checkSelections(const std::vector<Selection *> &sel1,
+ const std::vector<Selection *> &sel2) const;
Options _options;
#include <pbc.h>
#include <vec.h>
+// FIXME: This kind of hackery should not be necessary
+#undef min
+#undef max
#include "gromacs/analysisdata/analysisdata.h"
#include "gromacs/analysisdata/modules/average.h"
#include "gromacs/analysisdata/modules/plot.h"
-#include "gromacs/fatalerror/fatalerror.h"
+#include "gromacs/fatalerror/exceptions.h"
#include "gromacs/options/basicoptions.h"
#include "gromacs/options/options.h"
#include "gromacs/selection/selection.h"
}
-int
+void
Distance::initAnalysis(const TopologyInformation & /*top*/)
{
if (_sel[0]->posCount() != 1)
{
- GMX_ERROR(eeInvalidInput,
- "The first selection does not define a single position");
+ GMX_THROW(InvalidInputError("The first selection does not define a single position"));
}
if (_sel[1]->posCount() != 1)
{
- GMX_ERROR(eeInvalidInput,
- "The second selection does not define a single position");
+ GMX_THROW(InvalidInputError("The second selection does not define a single position"));
}
_data.setColumns(4);
registerAnalysisDataset(&_data, "distance");
_plotm->setXLabel("Time [ps]");
_plotm->setYLabel("Distance [nm]");
_data.addModule(_plotm);
-
- return 0;
}
-int
+void
Distance::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc,
TrajectoryAnalysisModuleData *pdata)
{
dh->addPoint(0, r);
dh->addPoints(1, 3, dx);
dh->finishFrame();
- return 0;
}
-int
+void
Distance::finishAnalysis(int /*nframes*/)
{
- return 0;
}
-int
+void
Distance::writeOutput()
{
const real *ave;
_avem->getData(0, NULL, &ave, NULL);
fprintf(stderr, "Average distance: %f\n", ave[0]);
fprintf(stderr, "Std. deviation: %f\n", ave[1]);
- return 0;
}
static TrajectoryAnalysisModule *create();
virtual Options *initOptions(TrajectoryAnalysisSettings *settings);
- virtual int initAnalysis(const TopologyInformation &top);
+ virtual void initAnalysis(const TopologyInformation &top);
- virtual int analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc,
- TrajectoryAnalysisModuleData *pdata);
+ virtual void analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc,
+ TrajectoryAnalysisModuleData *pdata);
- virtual int finishAnalysis(int nframes);
- virtual int writeOutput();
+ virtual void finishAnalysis(int nframes);
+ virtual void writeOutput();
private:
Options _options;
#include "gromacs/analysisdata/analysisdata.h"
#include "gromacs/analysisdata/datamodule.h"
#include "gromacs/analysisdata/modules/plot.h"
-#include "gromacs/fatalerror/fatalerror.h"
+#include "gromacs/fatalerror/exceptions.h"
#include "gromacs/options/basicoptions.h"
#include "gromacs/options/options.h"
#include "gromacs/selection/selection.h"
#include "gromacs/selection/selectionoption.h"
#include "gromacs/trajectoryanalysis/analysissettings.h"
+#include "gromacs/utility/format.h"
namespace gmx
{
virtual int flags() const;
- virtual int dataStarted(AbstractAnalysisData *data);
- virtual int frameStarted(real x, real dx);
- virtual int pointsAdded(real x, real dx, int firstcol, int n,
- const real *y, const real *dy,
- const bool *present);
- virtual int frameFinished();
- virtual int dataFinished();
+ virtual void dataStarted(AbstractAnalysisData *data);
+ virtual void frameStarted(real x, real dx);
+ virtual void pointsAdded(real x, real dx, int firstcol, int n,
+ const real *y, const real *dy,
+ const bool *present);
+ virtual void frameFinished();
+ virtual void dataFinished();
private:
void closeFile();
}
-int IndexFileWriterModule::dataStarted(AbstractAnalysisData * /*data*/)
+void IndexFileWriterModule::dataStarted(AbstractAnalysisData * /*data*/)
{
if (!_fnm.empty())
{
_fp = gmx_fio_fopen(_fnm.c_str(), "w");
}
- return 0;
}
-int IndexFileWriterModule::frameStarted(real /*x*/, real /*dx*/)
+void IndexFileWriterModule::frameStarted(real /*x*/, real /*dx*/)
{
_bAnyWritten = false;
_currentGroup = -1;
- return 0;
}
-int
+void
IndexFileWriterModule::pointsAdded(real x, real /*dx*/, int firstcol, int n,
const real *y, const real * /*dy*/,
const bool * /*present*/)
{
if (_fp == NULL)
{
- return 0;
+ return;
}
if (firstcol == 0)
{
std::string name = _groups[_currentGroup].name;
if (_groups[_currentGroup].bDynamic)
{
- char tbuf[50];
- snprintf(tbuf, 50, "_f%d_t%.3f", _framenr, x);
- name += tbuf;
+ name += formatString("_f%d_t%.3f", _framenr, x);
}
std::fprintf(_fp, "[ %s ]", name.c_str());
_bAnyWritten = true;
++_currentSize;
}
}
- return 0;
}
-int IndexFileWriterModule::frameFinished()
+void IndexFileWriterModule::frameFinished()
{
++_framenr;
- return 0;
}
-int IndexFileWriterModule::dataFinished()
+void IndexFileWriterModule::dataFinished()
{
if (_fp != NULL)
{
std::fprintf(_fp, "\n");
}
closeFile();
- return 0;
}
class Select::ModuleData : public TrajectoryAnalysisModuleData
{
public:
- ModuleData() : _mmap(NULL)
+ ModuleData(TrajectoryAnalysisModule *module,
+ AnalysisDataParallelOptions opt,
+ const SelectionCollection &selections)
+ : TrajectoryAnalysisModuleData(module, opt, selections),
+ _mmap(NULL)
{
}
}
}
- virtual int finish()
+ virtual void finish()
{
- return finishDataHandles();
+ finishDataHandles();
}
gmx_ana_indexmap_t *_mmap;
}
-int
+void
Select::initAnalysis(const TopologyInformation &top)
{
if (!_fnIndex.empty() && _bDump && _sel.size() > 1U)
{
- GMX_ERROR(eeInconsistentInput,
- "With -oi and -dump, there can be only one selection");
+ GMX_THROW(InconsistentInputError("With -oi and -dump, there can be only one selection"));
}
_bResInd = (_resNumberType == "index");
}
_top = top.topology();
-
- return 0;
}
-int
+TrajectoryAnalysisModuleData *
Select::startFrames(AnalysisDataParallelOptions opt,
- const SelectionCollection &selections,
- TrajectoryAnalysisModuleData **pdatap)
+ const SelectionCollection &selections)
{
- ModuleData *pdata = new ModuleData();
-
- *pdatap = pdata;
- int rc = pdata->init(this, opt, selections);
- if (rc != 0)
- {
- delete pdata;
- *pdatap = NULL;
- return rc;
- }
+ ModuleData *pdata = new ModuleData(this, opt, selections);
snew(pdata->_mmap, 1);
gmx_ana_indexmap_init(pdata->_mmap, pdata->parallelSelection(_sel[0])->indexGroup(),
_top, _sel[0]->type());
- return 0;
+ return pdata;
}
-int
+void
Select::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc,
TrajectoryAnalysisModuleData *pdata)
{
}
mdh->finishFrame();
}
- return 0;
}
-int
+void
Select::finishAnalysis(int /*nframes*/)
{
- return 0;
}
-int
+void
Select::writeOutput()
{
- return 0;
}
static TrajectoryAnalysisModule *create();
virtual Options *initOptions(TrajectoryAnalysisSettings *settings);
- virtual int initAnalysis(const TopologyInformation &top);
+ virtual void initAnalysis(const TopologyInformation &top);
- virtual int startFrames(AnalysisDataParallelOptions opt,
- const SelectionCollection &selections,
- TrajectoryAnalysisModuleData **pdatap);
- virtual int analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc,
- TrajectoryAnalysisModuleData *pdata);
+ virtual TrajectoryAnalysisModuleData *startFrames(
+ AnalysisDataParallelOptions opt,
+ const SelectionCollection &selections);
+ virtual void analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc,
+ TrajectoryAnalysisModuleData *pdata);
- virtual int finishAnalysis(int nframes);
- virtual int writeOutput();
+ virtual void finishAnalysis(int nframes);
+ virtual void writeOutput();
private:
class ModuleData;
#include <config.h>
#endif
-#include <cassert>
#include <string.h>
#include <rmpbc.h>
#include <tpxio.h>
#include <vec.h>
-#include "gromacs/fatalerror/fatalerror.h"
+#include "gromacs/fatalerror/exceptions.h"
+#include "gromacs/fatalerror/gmxassert.h"
#include "gromacs/options/basicoptions.h"
#include "gromacs/options/globalproperties.h"
#include "gromacs/options/options.h"
#include "gromacs/selection/selectioncollection.h"
#include "gromacs/trajectoryanalysis/analysissettings.h"
#include "gromacs/trajectoryanalysis/runnercommon.h"
+#include "gromacs/utility/format.h"
#include "analysissettings-impl.h"
}
-int
+bool
TrajectoryAnalysisRunnerCommon::initOptionsDone()
{
if (_impl->_bHelp)
{
- // TODO: Proper error code for graceful exit
- return -1;
+ return false;
}
if (_impl->_trjfile.empty() && _impl->_topfile.empty())
{
- GMX_ERROR(eeInconsistentInput,
- "No trajectory or topology provided, nothing to do!");
+ GMX_THROW(InconsistentInputError("No trajectory or topology provided, nothing to do!"));
}
if (_impl->_options.isSet("b"))
if (_impl->_options.isSet("dt"))
setTimeValue(TDELTA, _impl->_deltaTime);
- return 0;
+ return true;
}
-int
+void
TrajectoryAnalysisRunnerCommon::initIndexGroups(SelectionCollection *selections)
{
- int rc = 0;
-
if (_impl->_ndxfile.empty())
{
// TODO: Initialize default selections
else
{
gmx_ana_indexgrps_init(&_impl->_grps, NULL, _impl->_ndxfile.c_str());
- rc = selections->setIndexGroups(_impl->_grps);
+ selections->setIndexGroups(_impl->_grps);
}
- return rc;
}
}
-int
+void
TrajectoryAnalysisRunnerCommon::initTopology(SelectionCollection *selections)
{
const TrajectoryAnalysisSettings &settings = _impl->_settings;
|| selections->requiresTopology();
if (bRequireTop && _impl->_topfile.empty())
{
- GMX_ERROR(eeInconsistentInput,
- "No topology provided, but one is required for analysis");
+ GMX_THROW(InconsistentInputError("No topology provided, but one is required for analysis"));
}
// Load the topology if requested.
int natoms = -1;
if (!_impl->_topInfo.hasTopology())
{
- int rc = initFirstFrame();
- if (rc != 0)
- {
- return rc;
- }
+ initFirstFrame();
natoms = _impl->fr->natoms;
}
- int rc = selections->setTopology(_impl->_topInfo.topology(), natoms);
- if (rc != 0)
- {
- return rc;
- }
+ selections->setTopology(_impl->_topInfo.topology(), natoms);
/*
if (_impl->bSelDump)
fprintf(stderr, "\n");
}
*/
-
- return 0;
}
-int
+void
TrajectoryAnalysisRunnerCommon::initFirstFrame()
{
// Return if we have already initialized the trajectory.
if (_impl->fr)
{
- return 0;
+ return;
}
_impl->_oenv = _impl->_options.globalProperties().output_env();
if (!read_first_frame(_impl->_oenv, &_impl->_status,
_impl->_trjfile.c_str(), _impl->fr, frflags))
{
- GMX_ERROR(eeFileNotFound,
- "Could not read coordinates from trajectory");
+ GMX_THROW(FileIOError("Could not read coordinates from trajectory"));
}
_impl->_bTrajOpen = true;
if (top.hasTopology() && _impl->fr->natoms > top.topology()->atoms.nr)
{
- fatalErrorFormatted(eeInconsistentInput, GMX_ERRORLOC,
- "Trajectory (%d atoms) does not match topology (%d atoms)",
- _impl->fr->natoms, top.topology()->atoms.nr);
- return eeInconsistentInput;
+ GMX_THROW(InconsistentInputError(formatString(
+ "Trajectory (%d atoms) does not match topology (%d atoms)",
+ _impl->fr->natoms, top.topology()->atoms.nr)));
}
// Check index groups if they have been initialized based on the topology.
/*
// TODO: Initialize more of the fields.
if (frflags & (TRX_NEED_V))
{
- GMX_ERROR(eeNotImplemented,
- "Velocity reading from a topology not implemented");
+ GMX_THROW(NotImplementedError("Velocity reading from a topology not implemented"));
}
if (frflags & (TRX_NEED_F))
{
- GMX_ERROR(eeInvalidInput,
- "Forces cannot be read from a topology");
+ GMX_THROW(InvalidInputError("Forces cannot be read from a topology"));
}
_impl->fr->flags = frflags;
_impl->fr->natoms = top.topology()->atoms.nr;
_impl->_gpbc = gmx_rmpbc_init(&top.topology()->idef, top.ePBC(),
_impl->fr->natoms, _impl->fr->box);
}
-
- return 0;
}
}
-int
+void
TrajectoryAnalysisRunnerCommon::initFrame()
{
if (_impl->_gpbc != NULL)
{
gmx_rmpbc_trxfr(_impl->_gpbc, _impl->fr);
}
- return 0;
}
~TrajectoryAnalysisRunnerCommon();
Options *initOptions();
- int initOptionsDone();
- int initIndexGroups(SelectionCollection *selections);
+ bool initOptionsDone();
+ void initIndexGroups(SelectionCollection *selections);
void doneIndexGroups(SelectionCollection *selections);
- int initTopology(SelectionCollection *selections);
- int initFirstFrame();
+ void initTopology(SelectionCollection *selections);
+ void initFirstFrame();
bool readNextFrame();
- int initFrame();
+ void initFrame();
//! Returns flags for help printing.
HelpFlags helpFlags() const;
#include <vector>
+#include <gromacs/fatalerror/exceptions.h>
#include <gromacs/options/basicoptions.h>
#include <gromacs/options/options.h>
#include <gromacs/selection/selection.h>
~SelectionTester();
Options *initOptions(TrajectoryAnalysisSettings *settings);
- int initAnalysis(const TopologyInformation &top);
+ void initAnalysis(const TopologyInformation &top);
- int analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc,
- TrajectoryAnalysisModuleData *pdata);
+ void analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc,
+ TrajectoryAnalysisModuleData *pdata);
- int finishAnalysis(int nframes);
- int writeOutput();
+ void finishAnalysis(int nframes);
+ void writeOutput();
private:
void printSelections();
return &_options;
}
-int
+void
SelectionTester::initAnalysis(const TopologyInformation &/*top*/)
{
printSelections();
- return 0;
}
-int
+void
SelectionTester::analyzeFrame(int /*frnr*/, const t_trxframe &/*fr*/, t_pbc * /*pbc*/,
TrajectoryAnalysisModuleData * /*pdata*/)
{
}
}
fprintf(stderr, "\n");
- return 0;
}
-int
+void
SelectionTester::finishAnalysis(int /*nframes*/)
{
printSelections();
- return 0;
}
-int
+void
SelectionTester::writeOutput()
{
- return 0;
}
}
int
main(int argc, char *argv[])
{
- gmx::SelectionTester module;
- gmx::TrajectoryAnalysisCommandLineRunner runner(&module);
- runner.setSelectionDebugLevel(1);
- return runner.run(argc, argv);
+ try
+ {
+ gmx::SelectionTester module;
+ gmx::TrajectoryAnalysisCommandLineRunner runner(&module);
+ runner.setSelectionDebugLevel(1);
+ return runner.run(argc, argv);
+ }
+ catch (std::exception &ex)
+ {
+ fprintf(stderr, "%s", gmx::formatErrorMessage(ex).c_str());
+ return 1;
+ }
}
int
main(int argc, char *argv[])
{
- if (argc < 2)
+ try
{
- CopyRight(stderr, argv[0]);
- GMX_ERROR(gmx::eeInvalidInput,
- "Not enough command-line arguments");
- }
+ if (argc < 2)
+ {
+ CopyRight(stderr, argv[0]);
+ GMX_THROW(gmx::InvalidInputError("Not enough command-line arguments"));
+ }
+
+ std::auto_ptr<gmx::TrajectoryAnalysisModule>
+ mod(gmx::createTrajectoryAnalysisModule(argv[1]));
+ if (mod.get() == NULL)
+ {
+ CopyRight(stderr, argv[0]);
+ GMX_THROW(gmx::InvalidInputError(
+ "Unknown analysis module given as the first command-line argument"));
+ }
+ --argc;
+ ++argv;
- std::auto_ptr<gmx::TrajectoryAnalysisModule>
- mod(gmx::createTrajectoryAnalysisModule(argv[1]));
- if (mod.get() == NULL)
+ gmx::TrajectoryAnalysisCommandLineRunner runner(mod.get());
+ return runner.run(argc, argv);
+ }
+ catch (std::exception &ex)
{
- CopyRight(stderr, argv[0]);
- GMX_ERROR(gmx::eeInvalidInput,
- "Unknown analysis module given as the first command-line argument");
+ fprintf(stderr, "%s", gmx::formatErrorMessage(ex).c_str());
+ return 1;
}
- --argc;
- ++argv;
-
- gmx::TrajectoryAnalysisCommandLineRunner runner(mod.get());
- return runner.run(argc, argv);
}