Convert existing C++ code to use exceptions.
authorTeemu Murtola <teemu.murtola@cbr.su.se>
Mon, 1 Aug 2011 16:18:24 +0000 (19:18 +0300)
committerTeemu Murtola <teemu.murtola@cbr.su.se>
Mon, 1 Aug 2011 16:18:24 +0000 (19:18 +0300)
Some additional cleanup and improvements will be made in subsequent
commits, but this set of changes does result in functional code.

Merged from old development history.

76 files changed:
share/template/template.cpp
src/gromacs/analysisdata/abstractdata-impl.h
src/gromacs/analysisdata/abstractdata.cpp
src/gromacs/analysisdata/abstractdata.h
src/gromacs/analysisdata/analysisdata-impl.h
src/gromacs/analysisdata/analysisdata.cpp
src/gromacs/analysisdata/analysisdata.h
src/gromacs/analysisdata/arraydata.cpp
src/gromacs/analysisdata/arraydata.h
src/gromacs/analysisdata/datamodule.h
src/gromacs/analysisdata/dataproxy.cpp
src/gromacs/analysisdata/dataproxy.h
src/gromacs/analysisdata/modules/average.cpp
src/gromacs/analysisdata/modules/average.h
src/gromacs/analysisdata/modules/displacement.cpp
src/gromacs/analysisdata/modules/displacement.h
src/gromacs/analysisdata/modules/histogram.cpp
src/gromacs/analysisdata/modules/histogram.h
src/gromacs/analysisdata/modules/plot.cpp
src/gromacs/analysisdata/modules/plot.h
src/gromacs/options/abstractoption.cpp
src/gromacs/options/abstractoption.h
src/gromacs/options/abstractoptionstorage.h
src/gromacs/options/asciihelpwriter.cpp
src/gromacs/options/asciihelpwriter.h
src/gromacs/options/basicoptions.cpp
src/gromacs/options/basicoptions.h
src/gromacs/options/basicoptionstorage.h
src/gromacs/options/cmdlineparser-impl.h
src/gromacs/options/cmdlineparser.cpp
src/gromacs/options/cmdlineparser.h
src/gromacs/options/globalproperties.cpp
src/gromacs/options/options-impl.h
src/gromacs/options/options.cpp
src/gromacs/options/options.h
src/gromacs/options/optionsassigner-impl.h
src/gromacs/options/optionsassigner.cpp
src/gromacs/options/optionsassigner.h
src/gromacs/options/optionstoragetemplate.h
src/gromacs/options/tests/abstractoptionstorage.cpp
src/gromacs/options/tests/cmdlineparser.cpp
src/gromacs/options/tests/option.cpp
src/gromacs/options/tests/optionsassigner.cpp
src/gromacs/selection/evaluate.cpp
src/gromacs/selection/params.cpp
src/gromacs/selection/parsetree.cpp
src/gromacs/selection/parsetree.h
src/gromacs/selection/scanner.h
src/gromacs/selection/scanner_internal.cpp
src/gromacs/selection/scanner_internal.h
src/gromacs/selection/selectioncollection-impl.h
src/gromacs/selection/selectioncollection.cpp
src/gromacs/selection/selectioncollection.h
src/gromacs/selection/selectionoption.cpp
src/gromacs/selection/selectionoption.h
src/gromacs/selection/selectionoptionstorage.h
src/gromacs/selection/sm_keywords.cpp
src/gromacs/selection/tests/selectioncollection.cpp
src/gromacs/selection/tests/selectionoption.cpp
src/gromacs/trajectoryanalysis.h
src/gromacs/trajectoryanalysis/analysismodule-impl.h
src/gromacs/trajectoryanalysis/analysismodule.cpp
src/gromacs/trajectoryanalysis/analysismodule.h
src/gromacs/trajectoryanalysis/analysissettings.cpp
src/gromacs/trajectoryanalysis/analysissettings.h
src/gromacs/trajectoryanalysis/cmdlinerunner.cpp
src/gromacs/trajectoryanalysis/modules/angle.cpp
src/gromacs/trajectoryanalysis/modules/angle.h
src/gromacs/trajectoryanalysis/modules/distance.cpp
src/gromacs/trajectoryanalysis/modules/distance.h
src/gromacs/trajectoryanalysis/modules/select.cpp
src/gromacs/trajectoryanalysis/modules/select.h
src/gromacs/trajectoryanalysis/runnercommon.cpp
src/gromacs/trajectoryanalysis/runnercommon.h
src/gromacs/trajectoryanalysis/tests/test_selection.cpp
src/programs/g_ana/g_ana.cpp

index 15f209a5eaf74b4c56e111c28ccbf61780551904..e91b90adb8e8ccac5e99f377e77d977152981f06 100644 (file)
@@ -44,16 +44,16 @@ class AnalysisTemplate : public TrajectoryAnalysisModule
         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;
@@ -73,7 +73,11 @@ class AnalysisTemplate : public TrajectoryAnalysisModule
 class AnalysisTemplate::ModuleData : public TrajectoryAnalysisModuleData
 {
     public:
-        ModuleData() : _nb(NULL)
+        ModuleData(TrajectoryAnalysisModule *module,
+                   AnalysisDataParallelOptions opt,
+                   const SelectionCollection &selections)
+            : TrajectoryAnalysisModuleData(module, opt, selections),
+              _nb(NULL)
         {
         }
 
@@ -82,9 +86,9 @@ class AnalysisTemplate::ModuleData : public TrajectoryAnalysisModuleData
             delete _nb;
         }
 
-        virtual int finish()
+        virtual void finish()
         {
-            return finishDataHandles();
+            finishDataHandles();
         }
 
         NeighborhoodSearch          *_nb;
@@ -141,7 +145,7 @@ AnalysisTemplate::initOptions(TrajectoryAnalysisSettings *settings)
 }
 
 
-int
+void
 AnalysisTemplate::initAnalysis(const TopologyInformation & /*top*/)
 {
     _data.setColumns(_sel.size());
@@ -159,35 +163,26 @@ AnalysisTemplate::initAnalysis(const TopologyInformation & /*top*/)
         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)
 {
@@ -197,7 +192,8 @@ AnalysisTemplate::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc,
     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)
@@ -213,18 +209,16 @@ AnalysisTemplate::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc,
         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.
@@ -233,7 +227,6 @@ AnalysisTemplate::writeOutput()
         fprintf(stderr, "Average mean distance for '%s': %.3f nm\n",
                 _sel[g]->name(), _avem->average(g));
     }
-    return 0;
 }
 
 /*! \brief
@@ -242,7 +235,15 @@ AnalysisTemplate::writeOutput()
 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;
+    }
 }
index 3bce302b82ade07f070d89fbcb98ca4aa1294cfe..eb768271040ac4fca0b8a32c30b588c91cb0fa0c 100644 (file)
@@ -75,8 +75,8 @@ class AbstractAnalysisData::Impl
          * 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;
index 67eb4b7623839db9a91f571c8f0ef7eec81cca6a..3b00edeeca6e223b9eec6052439a3c4e407fafcf 100644 (file)
  */
 #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"
@@ -70,15 +71,11 @@ AbstractAnalysisData::Impl::~Impl()
 }
 
 
-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();
@@ -88,40 +85,28 @@ AbstractAnalysisData::Impl::presentData(AbstractAnalysisData *data,
         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;
 }
 
 
@@ -141,7 +126,7 @@ AbstractAnalysisData::~AbstractAnalysisData()
 }
 
 
-int
+bool
 AbstractAnalysisData::getData(int index, real *x, const real **y,
                               const bool **missing) const
 {
@@ -149,97 +134,81 @@ AbstractAnalysisData::getData(int index, real *x, const real **y,
 }
 
 
-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;
 }
 
@@ -247,8 +216,10 @@ AbstractAnalysisData::setColumnCount(int 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;
 }
 
@@ -257,11 +228,12 @@ AbstractAnalysisData::setMultipoint(bool 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;
@@ -270,23 +242,19 @@ AbstractAnalysisData::notifyDataStart()
     {
         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;
@@ -294,31 +262,26 @@ AbstractAnalysisData::notifyFrameStart(real x, real dx) const
     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"));
             }
         }
     }
@@ -326,54 +289,42 @@ AbstractAnalysisData::notifyPointsAdd(int firstcol, int n,
     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;
 }
 
 
@@ -471,7 +422,7 @@ AbstractAnalysisDataStored::frameCount() const
 }
 
 
-int
+bool
 AbstractAnalysisDataStored::getDataWErr(int index, real *x, real *dx,
                                         const real **y, const real **dy,
                                         const bool **present) const
@@ -479,7 +430,7 @@ AbstractAnalysisDataStored::getDataWErr(int index, real *x, real *dx,
     index = _impl->getStoreIndex(index);
     if (index < 0)
     {
-        return eedataDataNotAvailable;
+        return false;
     }
 
     // Retrieve the data.
@@ -504,59 +455,52 @@ AbstractAnalysisDataStored::getDataWErr(int index, real *x, real *dx,
     {
         *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();
 
@@ -571,11 +515,10 @@ AbstractAnalysisDataStored::startDataStore()
         }
         _impl->_nextind = 0;
     }
-    return 0;
 }
 
 
-int
+void
 AbstractAnalysisDataStored::startNextFrame(real x, real dx)
 {
     // Start storing the frame if needed.
@@ -606,11 +549,11 @@ AbstractAnalysisDataStored::startNextFrame(real x, real dx)
     }
 
     // Notify any modules.
-    return notifyFrameStart(x, dx);
+    notifyFrameStart(x, dx);
 }
 
 
-int
+void
 AbstractAnalysisDataStored::storeThisFrame(const real *y, const real *dy,
                                            const bool *present)
 {
@@ -637,31 +580,23 @@ AbstractAnalysisDataStored::storeThisFrame(const real *y, const real *dy,
     ++_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
index 25942c8ad85c3fe1571cb9ae393b9091c6e32374..ca1dec6eebdf9e7cefc6d6aadd7a79c05a776587 100644 (file)
 namespace gmx
 {
 
-//! Additional error codes for functions in the analysis data module.
-enum AnalysisDataErrorCode
-{
-    eedataDataNotAvailable = -1,
-};
-
 class AnalysisDataModuleInterface;
 
 /*! \libinternal \brief
@@ -76,6 +70,15 @@ class AnalysisDataModuleInterface;
  * 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
  */
@@ -133,78 +136,79 @@ class AbstractAnalysisData
          * \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.
          *
@@ -216,7 +220,7 @@ class AbstractAnalysisData
          * It is provided for additional flexibility in postprocessing
          * in-memory data.
          */
-        int applyModule(AnalysisDataModuleInterface *module);
+        void applyModule(AnalysisDataModuleInterface *module);
 
     protected:
         AbstractAnalysisData();
@@ -255,14 +259,14 @@ class 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.
@@ -275,22 +279,22 @@ class AbstractAnalysisData
          * 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;
@@ -331,10 +335,10 @@ class AbstractAnalysisDataStored : public AbstractAnalysisData
         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();
@@ -347,14 +351,14 @@ class AbstractAnalysisDataStored : public AbstractAnalysisData
         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;
index a8c49e38f6abd25b475e9d385f85d5642ed9e110..935717b171936e582f3097735794356ae456ca16 100644 (file)
@@ -71,11 +71,11 @@ class AnalysisData::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();
 
index 1e5a7f8ac7dc923e6c6f9cf11f558cbaf2467e73..55d685770c92d3c375875b99a5514a356a6ee856 100644 (file)
 #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"
@@ -82,22 +82,16 @@ AnalysisData::Impl::~Impl()
 }
 
 
-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
@@ -124,27 +118,21 @@ AnalysisData::Impl::addPendingFrame(AnalysisDataFrame *fr)
         }
         _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;
 }
 
 
@@ -181,34 +169,28 @@ AnalysisData::~AnalysisData()
 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;
@@ -219,26 +201,26 @@ AnalysisData::startData(AnalysisDataHandle **handlep,
         (*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;
 }
 
 
@@ -279,12 +261,12 @@ AnalysisDataHandle::~AnalysisDataHandle()
 }
 
 
-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
     {
@@ -297,37 +279,36 @@ AnalysisDataHandle::startFrame(int index, real x, real dx)
             _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
     {
@@ -336,56 +317,48 @@ AnalysisDataHandle::addPoints(int firstcol, int n,
             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
index 0564333f283afbbcdb6685e916fcf211cc5db162..61f81c7eef85dbd7cd26d574f29456546abc01a1 100644 (file)
@@ -83,12 +83,11 @@ class AnalysisData : public AbstractAnalysisDataStored
         /*! \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.
          *
@@ -96,7 +95,7 @@ class AnalysisData : public AbstractAnalysisDataStored
          *
          * The pointer \p handle is invalid after the call.
          */
-        int finishData(AnalysisDataHandle *handle);
+        void finishData(AnalysisDataHandle *handle);
 
     private:
         class Impl;
@@ -121,25 +120,33 @@ class AnalysisData : public AbstractAnalysisDataStored
 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
@@ -151,13 +158,6 @@ class AnalysisDataHandle
          * 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;
 
index 04e0703f76783206c04eca5ab79b82717ca409ee..f1f24110e2b3298d73066768e3ebb20167df0a5b 100644 (file)
  */
 #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
 {
@@ -65,7 +64,7 @@ AbstractAnalysisArrayData::frameCount() const
 }
 
 
-int
+bool
 AbstractAnalysisArrayData::getDataWErr(int index, real *x, real *dx,
                                        const real **y, const real **dy,
                                        const bool **present) const
@@ -75,50 +74,51 @@ AbstractAnalysisArrayData::getDataWErr(int index, real *x, real *dx,
         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);
 }
 
@@ -126,8 +126,10 @@ AbstractAnalysisArrayData::setColumnCount(int 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());
 }
@@ -136,47 +138,32 @@ AbstractAnalysisArrayData::setRowCount(int nrows)
 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();
 }
 
 
@@ -184,8 +171,9 @@ void
 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);
index 4c7d4b38c1e77a01f83311ce7cc6e6fb922126a9..d283258af4caf45ac433053897efb25fe645f5d8 100644 (file)
@@ -39,7 +39,9 @@
 #ifndef GMX_ANALYSISDATA_ARRAYDATA_H
 #define GMX_ANALYSISDATA_ARRAYDATA_H
 
-#include <cassert>
+#include <cstddef>
+
+#include "../fatalerror/gmxassert.h"
 
 #include "abstractdata.h"
 
@@ -62,10 +64,10 @@ class AbstractAnalysisArrayData : public AbstractAnalysisData
         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();
@@ -96,17 +98,17 @@ class AbstractAnalysisArrayData : public AbstractAnalysisData
         //! 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
@@ -123,7 +125,7 @@ class AbstractAnalysisArrayData : public AbstractAnalysisData
          * 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.
index 93dbd9ed646cf2a77d64cc55d813a59899219a1b..17f32663b0897071c2f93b919639d0a889a17f19 100644 (file)
@@ -104,28 +104,32 @@ class AnalysisDataModuleInterface
          * (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() {}
index becb5d8a88b470ec540ca1d24976dee88c5cd63a..60828b6a03a154332a856c61dabc56f87c8eae65 100644 (file)
@@ -37,7 +37,7 @@
  */
 #include "dataproxy.h"
 
-#include <cassert>
+#include "gromacs/fatalerror/gmxassert.h"
 
 namespace gmx
 {
@@ -46,8 +46,8 @@ AnalysisDataProxy::AnalysisDataProxy(int col, int span,
                                      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());
 }
@@ -60,13 +60,13 @@ AnalysisDataProxy::frameCount() const
 }
 
 
-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)
         {
@@ -81,11 +81,11 @@ AnalysisDataProxy::getDataWErr(int index, real *x, real *dx,
             *missing += _col;
         }
     }
-    return rc;
+    return bExists;
 }
 
 
-int
+bool
 AnalysisDataProxy::requestStorage(int nframes)
 {
     return _source.requestStorage(nframes);
@@ -99,30 +99,31 @@ AnalysisDataProxy::flags() const
 }
 
 
-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)
@@ -146,21 +147,21 @@ AnalysisDataProxy::pointsAdded(real x, real dx, int firstcol, int n,
     {
         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
index 7e6365647198e169557dc0c0fffe582cbc974294..d9237cf06d54c4801f7f8218def3c0fcf0d3a829 100644 (file)
@@ -66,20 +66,20 @@ class AnalysisDataProxy : public AbstractAnalysisData,
         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;
index da7ad9059fe17e915aae535028738487207173fb..93327b29ac610aaa5c70b82f39345360356847e9 100644 (file)
@@ -67,24 +67,22 @@ AnalysisDataAverageModule::flags() const
 }
 
 
-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)
@@ -98,18 +96,16 @@ AnalysisDataAverageModule::pointsAdded(real x, real dx, int firstcol, int n,
             _nsamples[firstcol + i] += 1;
         }
     }
-    return 0;
 }
 
 
-int
+void
 AnalysisDataAverageModule::frameFinished()
 {
-    return 0;
 }
 
 
-int
+void
 AnalysisDataAverageModule::dataFinished()
 {
     for (int i = 0; i < rowCount(); ++i)
@@ -119,7 +115,7 @@ AnalysisDataAverageModule::dataFinished()
         setValue(i, 0, ave);
         setValue(i, 1, std);
     }
-    return valuesReady();
+    valuesReady();
 }
 
 
index 1aa5151da2f954b6d42402493dbfedfe4cee981f..644ddaa3af1f39d8007e219315452b12ced115f6 100644 (file)
@@ -71,13 +71,13 @@ class AnalysisDataAverageModule : public AbstractAnalysisArrayData,
 
         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;
index c20c11d6a0cd39cfca8e5fce6723779253e6f3a0..a799522d77a45c171471db4203cfe7ed4b08baa9 100644 (file)
@@ -46,7 +46,8 @@
 
 #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"
 
@@ -95,13 +96,13 @@ AnalysisDataDisplacementModule::setMaxTime(real tmax)
 }
 
 
-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);
 }
 
 
@@ -112,19 +113,19 @@ AnalysisDataDisplacementModule::frameCount() const
 }
 
 
-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;
 }
 
 
@@ -135,12 +136,12 @@ AnalysisDataDisplacementModule::flags() const
 }
 
 
-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);
@@ -149,12 +150,10 @@ AnalysisDataDisplacementModule::dataStarted(AbstractAnalysisData *data)
     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.
@@ -167,14 +166,14 @@ AnalysisDataDisplacementModule::frameStarted(real x, real dx)
         _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;
@@ -201,33 +200,31 @@ AnalysisDataDisplacementModule::frameStarted(real x, real dx)
 */
     _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;
@@ -240,18 +237,9 @@ AnalysisDataDisplacementModule::frameFinished()
             _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;
@@ -274,25 +262,20 @@ AnalysisDataDisplacementModule::frameFinished()
             }
             _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
index dbbd9c8efcaf45ddbd9979d1e81e5563c0644383..9c44dc0996e12123e44281742b73676886b2060a 100644 (file)
@@ -77,23 +77,23 @@ class AnalysisDataDisplacementModule : public AbstractAnalysisData,
          *
          * 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;
index b7732c9c1a832dbfee905a9b82ef2ae9a4a76b15..220bfe36307cb213e3f9b0a202d3726de0c40579 100644 (file)
 #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
 {
@@ -68,11 +70,11 @@ AbstractHistogramModule::~AbstractHistogramModule()
 }
 
 
-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;
@@ -83,15 +85,14 @@ AbstractHistogramModule::initNBins(real miny, real binw, int nbins,
     _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;
@@ -114,7 +115,6 @@ AbstractHistogramModule::initRange(real miny, real maxy, real binw,
     _binwidth = binw;
     _invbw    = 1.0/binw;
     setColumnCount(_nbins);
-    return 0;
 }
 
 
@@ -158,7 +158,7 @@ AbstractHistogramModule::flags() const
 }
 
 
-int
+void
 AbstractHistogramModule::dataStarted(AbstractAnalysisData *data)
 {
     if (!_averager)
@@ -167,32 +167,32 @@ AbstractHistogramModule::dataStarted(AbstractAnalysisData *data)
     }
     _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();
 }
 
 
@@ -231,22 +231,20 @@ HistogramAverageModule::flags() const
 }
 
 
-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)
@@ -258,7 +256,7 @@ HistogramAverageModule::pointsAdded(real x, real dx, int firstcol, int n,
     }
     if (_bIgnoreMissing)
     {
-        assert(present != NULL);
+        GMX_ASSERT(present != NULL, "Required data not available");
         for (int i = 0; i < n; ++i)
         {
             if (present[i])
@@ -267,19 +265,17 @@ HistogramAverageModule::pointsAdded(real x, real dx, int firstcol, int n,
             }
         }
     }
-    return 0;
 }
 
 
-int
+void
 HistogramAverageModule::frameFinished()
 {
     ++_nframes;
-    return 0;
 }
 
 
-int
+void
 HistogramAverageModule::dataFinished()
 {
     for (int i = 0; i < rowCount(); ++i)
@@ -302,14 +298,13 @@ HistogramAverageModule::dataFinished()
         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;
@@ -339,16 +334,16 @@ HistogramAverageModule::resampleDoubleBinWidth(bool bIntegerBins) const
         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();
 }
 
 
@@ -390,7 +385,7 @@ HistogramAverageModule::scaleVector(real norm[])
  * AnalysisDataSimpleHistogramModule
  */
 
-int
+void
 AnalysisDataSimpleHistogramModule::pointsAdded(real /*x*/, real /*dx*/,
                                                int /*firstcol*/, int n,
                                                const real *y, const real * /*dy*/,
@@ -401,7 +396,6 @@ AnalysisDataSimpleHistogramModule::pointsAdded(real /*x*/, real /*dx*/,
         int bin = findBin(y[i]);
         _hist[bin] += 1;
     }
-    return 0;
 }
 
 
@@ -416,21 +410,20 @@ AnalysisDataWeightedHistogramModule::flags() const
 }
 
 
-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;
 }
 
 
@@ -454,7 +447,7 @@ void
 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);
 }
@@ -467,34 +460,34 @@ AnalysisDataBinAverageModule::flags() const
 }
 
 
-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)
@@ -502,11 +495,10 @@ AnalysisDataBinAverageModule::pointsAdded(real x, real dx, int firstcol, int n,
         _hist[bin] += y[i];
     }
     _n[bin] += n - 1;
-    return 0;
 }
 
 
-int
+void
 AnalysisDataBinAverageModule::frameFinished()
 {
     for (int i = 0; i < nbins(); ++i)
@@ -519,9 +511,9 @@ AnalysisDataBinAverageModule::frameFinished()
     }
     if (!_bIgnoreMissing)
     {
-        return AbstractHistogramModule::frameFinished();
+        AbstractHistogramModule::frameFinished();
     }
-    return storeThisFrame(_hist, NULL, _present);
+    storeThisFrame(_hist, NULL, _present);
 }
 
 } // namespace gmx
index 233d3bd9fab2d3ee98eee306207d171ce7a60ae4..e6bc67e1de0d0dbdff2d2e63a2321bcd1db45762 100644 (file)
@@ -62,13 +62,13 @@ class AbstractHistogramModule : public AbstractAnalysisDataStored,
         /*! \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.
          *
@@ -96,13 +96,13 @@ class AbstractHistogramModule : public AbstractAnalysisDataStored,
 
         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();
@@ -144,13 +144,13 @@ class HistogramAverageModule : public AbstractAnalysisArrayData,
     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.
@@ -175,7 +175,7 @@ class HistogramAverageModule : public AbstractAnalysisArrayData,
          * 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();
@@ -203,9 +203,9 @@ class HistogramAverageModule : public AbstractAnalysisArrayData,
 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.
 };
@@ -230,9 +230,9 @@ class AnalysisDataWeightedHistogramModule : public AbstractHistogramModule
     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.
 };
@@ -264,12 +264,12 @@ class AnalysisDataBinAverageModule : public AbstractHistogramModule
 
         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;
index 943b1ce61207dea9cddb259e8c517bbe93413880..a378261b1ec37a24987e58613fccc364d9c8a099 100644 (file)
@@ -44,7 +44,6 @@
 #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"
@@ -85,7 +88,7 @@ AbstractPlotModule::Impl::~Impl()
 void
 AbstractPlotModule::Impl::closeFile()
 {
-    if (fp)
+    if (fp != NULL)
     {
         if (bPlain)
         {
@@ -193,8 +196,10 @@ AbstractPlotModule::appendLegend(const char *setname)
 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);
 }
 
@@ -202,8 +207,10 @@ AbstractPlotModule::setXFormat(int width, int prec, char 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);
 }
 
@@ -215,7 +222,7 @@ AbstractPlotModule::flags() const
 }
 
 
-int
+void
 AbstractPlotModule::dataStarted(AbstractAnalysisData *data)
 {
     if (!_impl->fnm.empty())
@@ -252,43 +259,38 @@ AbstractPlotModule::dataStarted(AbstractAnalysisData *data)
             }
         }
     }
-
-    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;
 }
 
 
@@ -302,7 +304,7 @@ AbstractPlotModule::isFileOpen() const
 void
 AbstractPlotModule::writeValue(real value) const
 {
-    assert(isFileOpen());
+    GMX_ASSERT(isFileOpen(), "File not opened, but write attempted");
     std::fprintf(_impl->fp, _impl->yfmt, value);
 }
 
@@ -317,20 +319,19 @@ AnalysisDataPlotModule::AnalysisDataPlotModule(const Options &options)
 }
 
 
-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;
 }
 
 
@@ -378,7 +379,7 @@ AnalysisDataVectorPlotModule::setWriteNorm(bool bWrite)
 
 
 void
-AnalysisDataVectorPlotModule::setWriteMask(bool bWrite[4])
+AnalysisDataVectorPlotModule::setWriteMask(bool bWrite[DIM + 1])
 {
     for (int i = 0; i < DIM + 1; ++i)
     {
@@ -387,18 +388,18 @@ AnalysisDataVectorPlotModule::setWriteMask(bool bWrite[4])
 }
 
 
-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)
     {
@@ -414,7 +415,6 @@ AnalysisDataVectorPlotModule::pointsAdded(real x, real dx, int firstcol, int n,
             writeValue(norm(&y[i]));
         }
     }
-    return 0;
 }
 
 } // namespace gmx
index db13317b77f34675068c9639dd561a253fc99f96..9f7b396a3af20234f8de360bd71cfafea83b44c4 100644 (file)
@@ -139,13 +139,13 @@ class AbstractPlotModule : public AnalysisDataModuleInterface
 
         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);
@@ -177,9 +177,9 @@ class AnalysisDataPlotModule : public AbstractPlotModule
     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.
 };
@@ -204,9 +204,9 @@ class AnalysisDataVectorPlotModule : public AbstractPlotModule
         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];
index b5c76cee8dbbb1fc670c7dfa3efb69ffd87ee204..1a831085cc43ca35eb51484759e06e8f61b091f4 100644 (file)
  */
 #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"
 
@@ -51,37 +49,25 @@ namespace gmx
  * 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)
@@ -89,17 +75,18 @@ int AbstractOptionStorage::init(const AbstractOption &settings,
         _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))
     {
@@ -108,102 +95,102 @@ int AbstractOptionStorage::startSet(AbstractErrorReporter *errors)
     }
     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
index 03b80f03199c5a52107863276195833df4e7831e..fecb01c7648d9e44a011be4a5e0374259ed07628 100644 (file)
@@ -94,8 +94,7 @@ class AbstractOption
          * 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.
@@ -107,8 +106,7 @@ class AbstractOption
          *
          * \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.
index 5d5de9917283206384ce6775f6e26e6908b3899e..73e460e6dea8d0e291cc3874eebda6c47a486729 100644 (file)
@@ -46,7 +46,6 @@
 namespace gmx
 {
 
-class AbstractErrorReporter;
 class AbstractOption;
 class Options;
 
@@ -82,16 +81,6 @@ class AbstractOptionStorage
     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.
@@ -122,57 +111,50 @@ class AbstractOptionStorage
         /*! \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); }
@@ -189,8 +171,6 @@ class AbstractOptionStorage
          * 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
@@ -200,14 +180,12 @@ class AbstractOptionStorage
          * 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
@@ -217,7 +195,7 @@ class AbstractOptionStorage
          * 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; }
@@ -235,44 +213,33 @@ class AbstractOptionStorage
          * 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;
index f19a263ad3e35ad29ac25b72ad92cdafc4f50873..c3832e2a753a5d980db70eb44a09fb7021720c25 100644 (file)
@@ -248,7 +248,7 @@ AsciiHelpWriter &AsciiHelpWriter::setShowDescriptions(bool bSet)
     return *this;
 }
 
-int AsciiHelpWriter::writeHelp(FILE *fp)
+void AsciiHelpWriter::writeHelp(FILE *fp)
 {
     if (_impl->_flags.test(Impl::efShowDescriptions))
     {
@@ -273,7 +273,6 @@ int AsciiHelpWriter::writeHelp(FILE *fp)
             fprintf(fp, "\n");
         }
     }
-    return 0;
 }
 
 } // namespace gmx
index 255de4c001b1c8cf7297b1744162ff7ae21729ee..ff190e52c1f88968f71e539e94088d6e870ffbeb 100644 (file)
@@ -76,9 +76,8 @@ class AsciiHelpWriter
          * 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;
index 466290d41741044cc795755b6afb04ccfdeefadc..828bc992fbf737dce02b0c0e5a7ce823e42a5cdf 100644 (file)
 #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
@@ -85,32 +80,29 @@ std::string BooleanOptionStorage::formatValue(int i) const
     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);
 }
 
 
@@ -118,54 +110,40 @@ int BooleanOption::createDefaultStorage(Options *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);
 }
 
 
@@ -173,19 +151,13 @@ int IntegerOption::createDefaultStorage(Options *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
@@ -195,46 +167,37 @@ 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)
     {
@@ -245,17 +208,16 @@ int DoubleOptionStorage::processAll(AbstractErrorReporter *errors)
             (*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);
 }
 
 
@@ -263,27 +225,20 @@ int DoubleOption::createDefaultStorage(Options *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)
     {
@@ -292,31 +247,28 @@ int StringOptionStorage::init(const StringOption &settings, Options *options)
         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.
@@ -325,21 +277,16 @@ int StringOptionStorage::init(const StringOption &settings, Options *options)
             *_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
@@ -347,8 +294,7 @@ 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)
     {
@@ -371,26 +317,23 @@ int StringOptionStorage::convertValue(const std::string &value,
         }
         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
@@ -417,19 +360,13 @@ 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
@@ -437,22 +374,19 @@ 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
index dc3456742da45b751431cd950edd5c9699279d84..1cf69dc5a5c20eae2dac813767911b90b3f4e2a2 100644 (file)
 #ifndef GMX_OPTIONS_BASICOPTIONS_H
 #define GMX_OPTIONS_BASICOPTIONS_H
 
-#include <cassert>
-
 #include <string>
 
+#include "../fatalerror/gmxassert.h"
+
 #include "abstractoption.h"
 #include "optionfiletype.h"
 
@@ -84,8 +84,7 @@ class BooleanOption : public OptionTemplate<bool, BooleanOption>
         }
 
     protected:
-        virtual int createDefaultStorage(Options *options,
-                                         AbstractOptionStorage **storage) const;
+        virtual AbstractOptionStorage *createDefaultStorage(Options *options) const;
 };
 
 /*! \brief
@@ -121,8 +120,7 @@ class IntegerOption : public OptionTemplate<int, IntegerOption>
         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
@@ -152,8 +150,7 @@ class DoubleOption : public OptionTemplate<double, DoubleOption>
         MyClass &timeValue() { _bTime = true; return me(); }
 
     private:
-        virtual int createDefaultStorage(Options *options,
-                                         AbstractOptionStorage **storage) const;
+        virtual AbstractOptionStorage *createDefaultStorage(Options *options) const;
 
         bool _bTime;
 
@@ -216,7 +213,11 @@ class StringOption : public OptionTemplate<std::string, StringOption>
          * 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.
@@ -232,8 +233,7 @@ class StringOption : public OptionTemplate<std::string, StringOption>
         { _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:
@@ -289,8 +289,7 @@ class FileNameOption : public OptionTemplate<std::string, FileNameOption>
         MyClass &libraryFile() { setFlag(efFileLibrary); return me(); }
 
     protected:
-        virtual int createDefaultStorage(Options *options,
-                                         AbstractOptionStorage **storage) const;
+        virtual AbstractOptionStorage *createDefaultStorage(Options *options) const;
 
     private:
         OptionFileType          _filetype;
index 85f19b9cf040bc5c17baf603a46e95abe210e1c8..96cb2a109330d22d03d58558ee0cc33b0c1bbb75 100644 (file)
@@ -47,6 +47,7 @@
 namespace gmx
 {
 
+class BooleanOption;
 class IntegerOption;
 class DoubleOption;
 class StringOption;
@@ -62,12 +63,22 @@ class FileNameOption;
 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
@@ -76,16 +87,19 @@ class BooleanOptionStorage : public OptionStorageTemplate<bool>
 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
@@ -94,25 +108,16 @@ class IntegerOptionStorage : public OptionStorageTemplate<int>
 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;
 };
@@ -123,17 +128,14 @@ class DoubleOptionStorage : public OptionStorageTemplate<double>
 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;
@@ -145,17 +147,14 @@ class StringOptionStorage : public OptionStorageTemplate<std::string>
 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;
 };
index a1865c4d91a601348b23e572c2ac83eb521aafe5..b87f458a25cf13217fe9dbde783b2b052f6cdda8 100644 (file)
@@ -53,7 +53,7 @@ class CommandLineParser::Impl
 {
     public:
         //! Sets the options object to parse to.
-        Impl(Options *options, AbstractErrorReporter *errors);
+        Impl(Options *options);
 
         //! Helper object for assigning the options.
         OptionsAssigner         _assigner;
index 68d5b47acbb52bdfafd44337aa8e6099e953367e..15cebfe5e3d2d3526fc64fd61b24f50e8204902c 100644 (file)
@@ -37,7 +37,8 @@
  */
 #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"
@@ -49,8 +50,8 @@ namespace gmx
  * 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);
@@ -60,9 +61,8 @@ CommandLineParser::Impl::Impl(Options *options, AbstractErrorReporter *errors)
  * CommandLineParser
  */
 
-CommandLineParser::CommandLineParser(Options *options,
-                                     AbstractErrorReporter *errors)
-    : _impl(new Impl(options, errors))
+CommandLineParser::CommandLineParser(Options *options)
+    : _impl(new Impl(options))
 {
 }
 
@@ -71,9 +71,9 @@ CommandLineParser::~CommandLineParser()
     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;
@@ -86,30 +86,61 @@ int CommandLineParser::parse(int *argc, char *argv[])
         {
             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
index 5f7bc28eabee6fd84d329de84666f5cafc2c9683..5698b49dcf732244ddc1e10e69e90e3e6f084a6b 100644 (file)
@@ -42,8 +42,6 @@
 namespace gmx
 {
 
-class AbstractErrorReporter;
-
 class Options;
 
 /*! \brief
@@ -54,9 +52,8 @@ class Options;
 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
@@ -69,17 +66,14 @@ class CommandLineParser
          * 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;
index 377b097e3a5c24be7e498e6fed37d69851ecce05..4096788d24ad882a3a98bd84f48234bd847859cf 100644 (file)
  */
 #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"
 
@@ -80,8 +80,9 @@ OptionsGlobalProperties::~OptionsGlobalProperties()
 
 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];
 }
 
index 99e992ca1103a47f9087b5b670c8121681b84177..53d1159280bded8bb141b62b8a71c5f35c232f21 100644 (file)
@@ -86,11 +86,8 @@ class Options::Impl
 
         /*! \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;
index e41229a986bb47e764fdccc781a3e22074f4bc48..b5e157038086e34eb486cdd340245cd520774829 100644 (file)
  */
 #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"
@@ -116,24 +118,20 @@ AbstractOptionStorage *Options::Impl::findOption(const char *name) const
     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;
 }
 
 /********************************************************************
@@ -173,9 +171,11 @@ void Options::setDescription(const char *const *desc)
 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;
 
@@ -187,13 +187,13 @@ void Options::addSubSection(Options *section)
 
 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()
@@ -207,29 +207,47 @@ bool Options::isSet(const char *name) const
     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()
@@ -239,6 +257,8 @@ 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;
 }
 
index c0ffeb4aa4a4e36bc5a8926d599650239395eded..e71498b1c0dbef76b0a92d9e43dfc9067a797975 100644 (file)
@@ -47,8 +47,6 @@
 namespace gmx
 {
 
-class AbstractErrorReporter;
-
 class AbstractOption;
 class OptionsGlobalProperties;
 class OptionsAssigner;
@@ -165,7 +163,7 @@ class Options
          * 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.
index 378422f3da4420cf6a483daa3cef8c2ddcb1f83b..3db1c01b427db64bc78c8ff998acd0f79d1162c5 100644 (file)
@@ -45,8 +45,6 @@
 namespace gmx
 {
 
-class AbstractErrorReporter;
-
 class AbstractOptionStorage;
 class Options;
 
@@ -67,26 +65,7 @@ class OptionsAssigner::Impl
             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);
@@ -111,8 +90,6 @@ class OptionsAssigner::Impl
 
         //! Options object to assign to.
         Options                &_options;
-        //! Error reporter to use for errors.
-        AbstractErrorReporter  *_errors;
         //! Flags that control assignment behavior.
         unsigned long           _flags;
         /*! \brief
@@ -123,8 +100,6 @@ class OptionsAssigner::Impl
         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.
index e8c7dd2fbf47c5a6b7b18f876c702625e29330b2..809e2b42c69f216abc4722eef00033eb065e6349 100644 (file)
 
 #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"
 
@@ -56,9 +54,9 @@ namespace gmx
  * 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);
 }
@@ -78,7 +76,8 @@ void OptionsAssigner::Impl::setFlag(OptionsAssigner::Impl::Flag flag, bool bSet)
 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 = &currentSection();
@@ -152,8 +151,8 @@ OptionsAssigner::Impl::findOption(const char *name)
  * OptionsAssigner
  */
 
-OptionsAssigner::OptionsAssigner(Options *options, AbstractErrorReporter *errors)
-    : _impl(new Impl(options, errors))
+OptionsAssigner::OptionsAssigner(Options *options)
+    : _impl(new Impl(options))
 {
 }
 
@@ -162,11 +161,6 @@ OptionsAssigner::~OptionsAssigner()
     delete _impl;
 }
 
-AbstractErrorReporter *OptionsAssigner::errorReporter() const
-{
-    return _impl->_errors;
-}
-
 void OptionsAssigner::setAcceptBooleanNoPrefix(bool enabled)
 {
     _impl->setFlag(Impl::efAcceptBooleanNoPrefix, enabled);
@@ -177,119 +171,85 @@ void OptionsAssigner::setNoStrictSectioning(bool 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
index fd81977ebe3dfcc2adee06bd8c120fac424bcb98..9872dee730f3fc12a40ae12a60a87a29ba241e2c 100644 (file)
@@ -46,8 +46,6 @@
 namespace gmx
 {
 
-class AbstractErrorReporter;
-
 class Options;
 
 /*! \libinternal \brief
@@ -61,8 +59,7 @@ class Options;
 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");
@@ -92,18 +89,9 @@ class OptionsAssigner
         /*! \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.
          *
@@ -135,61 +123,38 @@ class OptionsAssigner
 
         /*! \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;
index 134630884580140c0563992e0a768be35fd95ac0..f624a6f7f69a4a002de0ae928b0edc08dfbe4eaf 100644 (file)
 #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"
 
@@ -76,6 +76,13 @@ class OptionStorageTemplate : public AbstractOptionStorage
 
         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.
          *
@@ -84,17 +91,9 @@ class OptionStorageTemplate : public AbstractOptionStorage
          * \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()
@@ -102,8 +101,7 @@ class OptionStorageTemplate : public AbstractOptionStorage
          * 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
@@ -111,20 +109,19 @@ class OptionStorageTemplate : public AbstractOptionStorage
          * 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.
@@ -139,7 +136,7 @@ class OptionStorageTemplate : public AbstractOptionStorage
          * 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.
          *
@@ -182,83 +179,34 @@ class OptionStorageTemplate : public AbstractOptionStorage
         // 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)
@@ -284,7 +232,17 @@ int OptionStorageTemplate<T>::init(const OptionTemplate<T, U> &settings, Options
             _defaultValueIfSet = new T(*settings._defaultValueIfSet);
         }
     }
-    return 0;
+}
+
+
+template <typename T>
+OptionStorageTemplate<T>::~OptionStorageTemplate()
+{
+    if (!hasFlag(efExternalValueVector))
+    {
+        delete _values;
+    }
+    delete _defaultValueIfSet;
 }
 
 
@@ -296,14 +254,10 @@ void OptionStorageTemplate<T>::clear()
 
 
 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);
 }
 
 
@@ -321,7 +275,8 @@ void OptionStorageTemplate<T>::processValues(int nvalues, bool bDoArray)
     }
     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)
index e03576eea1da52ee61c7363a6fe828620ac708dc..5eb8a2ccd5d74f7efd1b3fa459098acbc7504498 100644 (file)
@@ -44,8 +44,7 @@
 #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"
@@ -69,45 +68,23 @@ class MockOptionStorage : public gmx::OptionStorageTemplate<std::string>
          *
          * \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).
          */
@@ -115,15 +92,14 @@ class MockOptionStorage : public gmx::OptionStorageTemplate<std::string>
         {
             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
@@ -148,33 +124,29 @@ class MockOption : public gmx::OptionTemplate<std::string, MockOption>
         { _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
@@ -189,25 +161,23 @@ TEST(AbstractOptionStorageTest, HandlesSetInFinish)
     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]);
@@ -222,29 +192,30 @@ TEST(AbstractOptionStorageTest, HandlesValueRemoval)
     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]);
@@ -260,31 +231,30 @@ TEST(AbstractOptionStorageTest, HandlesValueAddition)
     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]);
@@ -301,31 +271,30 @@ TEST(AbstractOptionStorageTest, HandlesTooManyValueAddition)
     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]);
@@ -341,27 +310,28 @@ TEST(AbstractOptionStorageTest, AllowsEmptyValues)
     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());
 }
index 1a41faac7aa8160c482ed34652b13672bb3e2aed..a2409eb3636691233c0db3838ce191801a76cab5 100644 (file)
@@ -44,7 +44,6 @@
 
 #include <gtest/gtest.h>
 
-#include "gromacs/errorreporting/emptyerrorreporter.h"
 #include "gromacs/options/basicoptions.h"
 #include "gromacs/options/cmdlineparser.h"
 #include "gromacs/options/options.h"
@@ -61,7 +60,6 @@ class CommandLineParserTest : public ::testing::Test
         void createArguments(const char *cmdline[]);
 
         gmx::Options            _options;
-        gmx::EmptyErrorReporter _errors;
         gmx::CommandLineParser  _parser;
         bool                    _flag;
         std::vector<int>        _ivalues;
@@ -71,7 +69,7 @@ class CommandLineParserTest : public ::testing::Test
 };
 
 CommandLineParserTest::CommandLineParserTest()
-    : _options(NULL, NULL), _parser(&_options, &_errors),
+    : _options(NULL, NULL), _parser(&_options),
       _flag(false),
       _argc(0), _argv(NULL)
 {
@@ -113,8 +111,8 @@ TEST_F(CommandLineParserTest, HandlesSingleValues)
 {
     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());
index 3146cdc2a1d027556011a6088968a938df08693c..b3e2cfab2cce96a17a3e6d4f308b64506d7e1f59 100644 (file)
  */
 /*! \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
index c1a2fd29d17c9959579a5db5b30e7e64946a3d3f..e9b7f2595e6695be0dc692eef11b3ba28a24ce0c 100644 (file)
@@ -45,7 +45,7 @@
 
 #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"
@@ -58,10 +58,10 @@ TEST(OptionsAssignerTest, HandlesMissingRequiredParameter)
     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)
@@ -69,14 +69,17 @@ 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)
@@ -84,16 +87,20 @@ 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]);
@@ -105,15 +112,18 @@ TEST(OptionsAssignerTest, HandlesMissingValue)
     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)
@@ -121,14 +131,16 @@ 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)
@@ -140,25 +152,29 @@ 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);
@@ -176,30 +192,35 @@ TEST(OptionsAssignerTest, HandlesNoStrictSubSections)
     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);
@@ -213,20 +234,25 @@ TEST(OptionsAssignerTest, HandlesMultipleSources)
     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);
 }
@@ -237,14 +263,15 @@ TEST(OptionsAssignerBooleanTest, StoresYesValue)
     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);
 }
@@ -254,13 +281,14 @@ TEST(OptionsAssignerBooleanTest, SetsBooleanWithoutExplicitValue)
     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);
 }
@@ -270,14 +298,15 @@ TEST(OptionsAssignerBooleanTest, ClearsBooleanWithPrefixNo)
     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);
 }
@@ -287,20 +316,23 @@ TEST(OptionsAssignerBooleanTest, HandlesBooleanWithPrefixAndValue)
     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 &)
+    {
+    }
 }
 
 
@@ -309,14 +341,15 @@ TEST(OptionsAssignerIntegerTest, StoresSingleValue)
     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);
 }
@@ -326,13 +359,14 @@ TEST(OptionsAssignerIntegerTest, StoresDefaultValue)
     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);
 }
@@ -342,14 +376,16 @@ TEST(OptionsAssignerIntegerTest, StoresDefaultValueIfSet)
     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);
 }
@@ -359,13 +395,14 @@ TEST(OptionsAssignerIntegerTest, HandlesDefaultValueIfSetWhenNotSet)
     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);
 }
@@ -375,14 +412,17 @@ TEST(OptionsAssignerIntegerTest, HandlesBothDefaultValues)
     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);
 }
@@ -393,16 +433,19 @@ TEST(OptionsAssignerIntegerTest, StoresToArray)
     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]);
@@ -416,16 +459,18 @@ TEST(OptionsAssignerIntegerTest, StoresToVector)
     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]);
@@ -438,16 +483,17 @@ TEST(OptionsAssignerIntegerTest, HandlesVectors)
     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]);
@@ -459,14 +505,15 @@ TEST(OptionsAssignerIntegerTest, HandlesVectorFromSingleValue)
     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]);
@@ -478,10 +525,9 @@ TEST(OptionsAssignerIntegerTest, HandlesVectorsWithDefaultValue)
     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]);
@@ -494,14 +540,15 @@ TEST(OptionsAssignerDoubleTest, StoresSingleValue)
     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);
 }
@@ -512,14 +559,15 @@ TEST(OptionsAssignerStringTest, StoresSingleValue)
     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);
 }
@@ -531,16 +579,17 @@ TEST(OptionsAssignerStringTest, HandlesEnumValue)
     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);
@@ -553,14 +602,14 @@ TEST(OptionsAssignerStringTest, HandlesIncorrectEnumValue)
     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)
@@ -570,16 +619,17 @@ 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);
@@ -592,14 +642,13 @@ TEST(OptionsAssignerStringTest, HandlesEnumWithNoValue)
     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);
@@ -612,17 +661,17 @@ TEST(OptionsAssignerStringTest, HandlesEnumDefaultValue)
     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);
@@ -635,17 +684,17 @@ TEST(OptionsAssignerStringTest, HandlesEnumDefaultIndex)
     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);
index d54f92d730b229c2452b35c05125137f5750e9b7..bc3e6984bf372890e424317c49126665fd7f6025 100644 (file)
@@ -234,9 +234,8 @@ gmx_ana_selcollection_evaluate(gmx_ana_selcollection_t *sc,
 /*!
  * \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;
@@ -259,7 +258,6 @@ gmx_ana_selcollection_evaluate_fin(gmx_ana_selcollection_t *sc, int nframes)
             sel->avecfrac /= nframes;
         }
     }
-    return 0;
 }
 
 /*!
index fabbc0ba33505f30c5254c23c385a6d92bb66670..31e024b863a149ddd7b63b2fe2b8c777ed28dd30 100644 (file)
 #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"
@@ -865,7 +866,7 @@ parse_values_std(int nval, t_selexpr_value *values, gmx_ana_selparam_t *param,
     {
         if (value->type != param->val.type)
         {
-            _gmx_selparser_warning(scanner, "incorrect value skipped");
+            _gmx_selparser_error(scanner, "incorrect value skipped");
             value = value->next;
             continue;
         }
@@ -902,7 +903,7 @@ parse_values_std(int nval, t_selexpr_value *values, gmx_ana_selparam_t *param,
                         }
                         if (j != value->u.i.i2 + 1)
                         {
-                            _gmx_selparser_warning(scanner, "extra values skipped");
+                            _gmx_selparser_error(scanner, "extra values skipped");
                         }
                     }
                     else
@@ -913,7 +914,7 @@ parse_values_std(int nval, t_selexpr_value *values, gmx_ana_selparam_t *param,
                         }
                         if (j != value->u.i.i2 - 1)
                         {
-                            _gmx_selparser_warning(scanner, "extra values skipped");
+                            _gmx_selparser_error(scanner, "extra values skipped");
                         }
                     }
                     --i;
@@ -1135,7 +1136,7 @@ gmx_bool
 _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;
@@ -1146,16 +1147,15 @@ _gmx_sel_parse_params(t_selexpr_param *pparams, int nparam, gmx_ana_selparam_t *
     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)
@@ -1184,17 +1184,17 @@ _gmx_sel_parse_params(t_selexpr_param *pparams, int nparam, gmx_ana_selparam_t *
     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 = &params[i];
             if (oparam->name != NULL)
             {
@@ -1213,7 +1213,7 @@ _gmx_sel_parse_params(t_selexpr_param *pparams, int nparam, gmx_ana_selparam_t *
             pparam = pparam->next;
             continue;
         }
-        gmx::ErrorContext context(errors, buf);
+        gmx::MessageStringContext  context(errors, contextStr);
         if (!oparam)
         {
             _gmx_selparser_error(scanner, "unknown parameter skipped");
index 4597b193aab6165c513d590de75a50e3dc84141a..ace32d7b172a86f3e0c33dc15fc9490655a311ed 100644 (file)
 #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);
 }
 
 /*!
@@ -606,8 +593,8 @@ set_refpos_type(gmx_ana_poscalc_coll_t *pcc, t_selelem *sel, const char *rpost,
     }
     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;
 }
@@ -667,8 +654,8 @@ _gmx_sel_init_comparison(t_selelem *left, t_selelem *right, char *cmpop,
     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);
@@ -720,10 +707,10 @@ _gmx_sel_init_keyword(gmx_ana_selmethod_t *method, t_selexpr_value *args,
     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)
     {
@@ -812,10 +799,10 @@ _gmx_sel_init_method(gmx_ana_selmethod_t *method, t_selexpr_param *params,
     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. */
@@ -863,10 +850,10 @@ _gmx_sel_init_modifier(gmx_ana_selmethod_t *method, t_selexpr_param *params,
     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);
@@ -918,10 +905,10 @@ _gmx_sel_init_position(t_selelem *expr, const char *type, yyscan_t scanner)
     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);
@@ -973,8 +960,6 @@ _gmx_sel_init_const_position(real x, real y, real z)
 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;
 
@@ -989,8 +974,7 @@ _gmx_sel_init_group_by_name(const char *name, yyscan_t scanner)
     }
     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);
@@ -998,8 +982,7 @@ _gmx_sel_init_group_by_name(const char *name, yyscan_t scanner)
     /* 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;
     }
@@ -1016,8 +999,6 @@ _gmx_sel_init_group_by_name(const char *name, yyscan_t scanner)
 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;
 
@@ -1031,16 +1012,14 @@ _gmx_sel_init_group_by_id(int id, yyscan_t scanner)
     }
     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;
     }
@@ -1092,10 +1071,10 @@ _gmx_sel_init_selection(char *name, t_selelem *sel, yyscan_t scanner)
     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)
     {
@@ -1184,10 +1163,10 @@ _gmx_sel_assign_variable(char *name, t_selelem *expr, yyscan_t scanner)
     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)
index 525be818f18b67f7678387320e6b4f7b9e059971..452dd2c13353e7f49f918df3193657dc61f08db7 100644 (file)
@@ -107,9 +107,6 @@ typedef struct t_selexpr_param
     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, ...);
index 6ab55e5e175158f33a5892fffa3d060017ccab19..af6c56bab48c29bf0f43df484321a95b397bb0d1 100644 (file)
@@ -40,7 +40,7 @@
 
 namespace gmx
 {
-class AbstractErrorReporter;
+class MessageStringCollector;
 }
 
 #include "parser.h"
@@ -54,9 +54,8 @@ typedef void *yyscan_t;
 #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. */
@@ -70,7 +69,7 @@ _gmx_sel_is_lexer_interactive(yyscan_t 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
index 6753680487be04245a9ff0b4b42358ad631aa73b..243ddfa102d4cbf33557a606ca2f3ab31fa1fd0a 100644 (file)
@@ -56,7 +56,9 @@
 
 #include "string2.h"
 
+#include "gromacs/fatalerror/exceptions.h"
 #include "gromacs/fatalerror/fatalerror.h"
+#include "gromacs/fatalerror/messagestringcollector.h"
 
 #include "gromacs/selection/selmethod.h"
 
@@ -69,7 +71,7 @@
 #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.
@@ -92,6 +94,11 @@ read_stdin_line(gmx_sel_lexer_t *state)
     }
     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
@@ -452,21 +459,22 @@ _gmx_sel_lexer_add_token(const char *str, int len, gmx_sel_lexer_t *state)
     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;
@@ -497,7 +505,6 @@ _gmx_sel_init_lexer(yyscan_t *scannerp, struct gmx_ana_selcollection_t *sc,
     state->bBuffer      = FALSE;
 
     _gmx_sel_yyset_extra(state, *scannerp);
-    return 0;
 }
 
 void
@@ -530,7 +537,7 @@ _gmx_sel_lexer_selcollection(yyscan_t scanner)
     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);
index 4ab10846f98f7f5d70361da9c457cffc11fc19ef..ef0b247dc28f22f1255af54bf91b5ea669d530c2 100644 (file)
@@ -39,7 +39,7 @@
 
 namespace gmx
 {
-class AbstractErrorReporter;
+class MessageStringCollector;
 }
 
 #include "parser.h"
@@ -71,7 +71,7 @@ typedef struct gmx_sel_lexer_t
     //! 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.
index 240645a4f9aff1988a09ff6680fa715cda9af798..f30414f905cf84e571d3b3e97a55aed614612f35 100644 (file)
@@ -87,6 +87,7 @@ struct gmx_ana_selcollection_t
 namespace gmx
 {
 
+class MessageStringCollector;
 class SelectionOptionStorage;
 
 /*! \internal \brief
@@ -133,8 +134,6 @@ class SelectionCollection::Impl
         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.
@@ -144,17 +143,16 @@ class SelectionCollection::Impl
          *      (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;
@@ -206,7 +204,7 @@ gmx_ana_selcollection_evaluate(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);
 
 /*!\}*/
index 78d58de53443c499c3bc24cd2678668609c0052f..e57ddd8379044bb31ff0cbaa7ac0db4a191ffdef 100644 (file)
@@ -39,7 +39,6 @@
 #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"
@@ -96,6 +97,19 @@ SelectionCollection::Impl::Impl(gmx_ana_poscalc_coll_t *pcc)
     _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);
 }
 
 
@@ -136,12 +150,14 @@ SelectionCollection::Impl::clearSymbolTable()
 }
 
 
-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);
@@ -149,7 +165,8 @@ SelectionCollection::Impl::runParser(yyscan_t scanner, int maxnr,
     int nr = sc->sel.size() - oldCount;
     if (maxnr > 0 && nr != maxnr)
     {
-        return eeInvalidInput;
+        bOk = false;
+        errors->append("Too few selections provided");
     }
 
     if (bOk)
@@ -161,7 +178,11 @@ SelectionCollection::Impl::runParser(yyscan_t scanner, int maxnr,
         }
     }
 
-    return bOk ? 0 : eeInvalidInput;
+    if (!bOk || !errors->isEmpty())
+    {
+        GMX_ASSERT(bOk && !errors->isEmpty(), "Inconsistent error reporting");
+        GMX_THROW(InvalidInputError(errors->toString()));
+    }
 }
 
 
@@ -173,21 +194,21 @@ void SelectionCollection::Impl::requestSelections(
 }
 
 
-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
             {
@@ -200,12 +221,11 @@ int SelectionCollection::Impl::resolveExternalGroups(t_selelem *root)
                                            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;
@@ -215,11 +235,9 @@ int SelectionCollection::Impl::resolveExternalGroups(t_selelem *root)
     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;
 }
 
 
@@ -239,42 +257,6 @@ SelectionCollection::~SelectionCollection()
 }
 
 
-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()
 {
@@ -294,7 +276,8 @@ 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])
@@ -302,7 +285,8 @@ SelectionCollection::initOptions()
     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])
@@ -317,7 +301,7 @@ SelectionCollection::initOptions()
 void
 SelectionCollection::setReferencePosType(const char *type)
 {
-    assert(type != NULL);
+    GMX_RELEASE_ASSERT(type != NULL, "Cannot assign NULL position type");
     _impl->_rpost = type;
 }
 
@@ -325,7 +309,7 @@ SelectionCollection::setReferencePosType(const char *type)
 void
 SelectionCollection::setOutputPosType(const char *type)
 {
-    assert(type != NULL);
+    GMX_RELEASE_ASSERT(type != NULL, "Cannot assign NULL position type");
     _impl->_spost = type;
 }
 
@@ -337,7 +321,7 @@ SelectionCollection::setDebugLevel(int debuglevel)
 }
 
 
-int
+void
 SelectionCollection::setTopology(t_topology *top, int natoms)
 {
     gmx_ana_selcollection_t *sc = &_impl->_sc;
@@ -349,32 +333,34 @@ SelectionCollection::setTopology(t_topology *top, int natoms)
     {
         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()));
+    }
 }
 
 
@@ -418,11 +404,28 @@ SelectionCollection::requiresTopology() const
 }
 
 
-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)
     {
@@ -448,32 +451,20 @@ SelectionCollection::parseRequestedFromStdin(bool bInteractive,
                          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;
@@ -484,9 +475,7 @@ SelectionCollection::parseRequestedFromString(const std::string &str,
         {
             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();
         }
@@ -494,93 +483,73 @@ SelectionCollection::parseRequestedFromString(const std::string &str,
         {
             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);
 }
 
 
@@ -589,11 +558,7 @@ SelectionCollection::compile()
 {
     if (!_impl->hasFlag(Impl::efExternalGroupsSet))
     {
-        int rc = setIndexGroups(NULL);
-        if (rc != 0)
-        {
-            return rc;
-        }
+        setIndexGroups(NULL);
     }
     if (_impl->_debugLevel >= 1)
     {
@@ -638,10 +603,10 @@ SelectionCollection::evaluate(t_trxframe *fr, t_pbc *pbc)
 }
 
 
-int
+void
 SelectionCollection::evaluateFinal(int nframes)
 {
-    return gmx_ana_selcollection_evaluate_fin(&_impl->_sc, nframes);
+    gmx_ana_selcollection_evaluate_fin(&_impl->_sc, nframes);
 }
 
 
index d13c8c14625cd9cc05fcde492f170947c82cd28a..f7528e532f7fd70983e52b239e6e601e2eaa5a58 100644 (file)
@@ -50,7 +50,6 @@ struct gmx_ana_poscalc_coll_t;
 namespace gmx
 {
 
-class AbstractErrorReporter;
 class Options;
 class Selection;
 class SelectionOptionStorage;
@@ -97,14 +96,6 @@ class SelectionCollection
         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.
          *
@@ -112,17 +103,6 @@ class SelectionCollection
          */
         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.
@@ -183,38 +163,34 @@ class SelectionCollection
          * 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.
          *
@@ -222,7 +198,6 @@ class SelectionCollection
          *      (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
@@ -237,14 +212,12 @@ class SelectionCollection
          * 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.
@@ -257,14 +230,12 @@ class SelectionCollection
          * 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.
@@ -277,9 +248,8 @@ class SelectionCollection
          * 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.
          *
@@ -307,9 +277,10 @@ class SelectionCollection
          * 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
index a82e8cae0c8544681812ddb12c5d8af42ceaa73d..76fe2a033ed69578d02d8b1f86c0563aef4e54ff 100644 (file)
  */
 #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"
@@ -60,12 +58,19 @@ namespace gmx
  * 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;
+    }
 }
 
 
@@ -75,24 +80,6 @@ SelectionOptionStorage::~SelectionOptionStorage()
 }
 
 
-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);
@@ -100,14 +87,13 @@ std::string SelectionOptionStorage::formatValue(int i) const
 }
 
 
-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)
@@ -116,101 +102,98 @@ int SelectionOptionStorage::addSelections(
         // 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;
 }
 
 
@@ -219,51 +202,43 @@ int SelectionOptionStorage::setSelectionFlag(SelectionFlag flag, bool bSet,
  */
 
 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);
 }
 
 
@@ -271,10 +246,9 @@ int SelectionOptionAdjuster::setDynamicOnlyWhole(bool 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
index 683bdcecf42b7f121e126dd2567e3775a773bfb9..eff1457cd961217847f0032b956cd74fc898289d 100644 (file)
 #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;
@@ -117,8 +114,7 @@ class SelectionOption : public OptionTemplate<Selection *, SelectionOption>
         using MyBase::defaultValue;
         using MyBase::defaultValueIfSet;
 
-        virtual int createDefaultStorage(Options *options,
-                                         AbstractOptionStorage **storage) const;
+        virtual AbstractOptionStorage *createDefaultStorage(Options *options) const;
 
         SelectionFlags          _selectionFlags;
         SelectionOptionAdjuster **_adjuster;
@@ -190,94 +186,33 @@ class SelectionOptionAdjuster
          */
         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
index 37f2b9d8961e3326d3df7b8a3d4a8e45f8772175..b62b7945b7cb5f47a38900152bd40ca8fe7dd1a7 100644 (file)
@@ -56,17 +56,14 @@ class SelectionOptionAdjuster;
 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;
@@ -77,7 +74,6 @@ class SelectionOptionStorage : public OptionStorageTemplate<Selection *>
          * \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
@@ -85,8 +81,8 @@ class SelectionOptionStorage : public OptionStorageTemplate<Selection *>
          * \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.
@@ -95,34 +91,28 @@ class SelectionOptionStorage : public OptionStorageTemplate<Selection *>
          * 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).
index eeaff1ff95f3e2d9ac22deba2834d654ee06521a..6156d932687514125c9f06cfe9deb96b183b456a 100644 (file)
@@ -53,8 +53,8 @@
 #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"
@@ -705,10 +705,10 @@ _gmx_sel_init_keyword_evaluator(t_selelem **selp, gmx_ana_selmethod_t *method,
     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)
index 768d75275fe3abeea4ff9753cf7bf0e44fc5fc18..70ed345cda5f41400b353521e87826214bc1a7b4 100644 (file)
@@ -44,7 +44,6 @@
 #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"
@@ -68,12 +67,11 @@ class SelectionCollectionTest : public ::testing::Test
 
         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;
 };
@@ -82,7 +80,6 @@ class SelectionCollectionTest : public ::testing::Test
 SelectionCollectionTest::SelectionCollectionTest()
     : _sc(NULL), _top(NULL), _frame(NULL)
 {
-    _sc.init();
     _sc.setReferencePosType("atom");
     _sc.setOutputPosType("atom");
 }
@@ -125,7 +122,7 @@ SelectionCollectionTest::loadTopology(const char *filename)
     _frame->bBox   = TRUE;
     copy_mat(box, _frame->box);
 
-    ASSERT_EQ(0, _sc.setTopology(_top, -1));
+    ASSERT_NO_THROW(_sc.setTopology(_top, -1));
 }
 
 
@@ -175,7 +172,7 @@ SelectionCollectionDataTest::runParser(const char *const *selections)
     {
         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)
         {
@@ -283,7 +280,7 @@ SelectionCollectionDataTest::runEvaluate()
 void
 SelectionCollectionDataTest::runEvaluateFinal()
 {
-    ASSERT_EQ(0, _sc.evaluateFinal(_framenr));
+    ASSERT_NO_THROW(_sc.evaluateFinal(_framenr));
     if (!_data.isWriteMode())
     {
         checkCompiled();
@@ -295,7 +292,7 @@ void
 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());
 }
 
@@ -304,7 +301,7 @@ void
 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))
     {
index 6e8ecc203d6e8baba5b627a9f289e60b36480533..d531ccf017fcb40e7d59bc70d0b0f73684ba924e 100644 (file)
@@ -39,7 +39,7 @@
 
 #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"
@@ -62,7 +62,6 @@ class SelectionOptionTest : public ::testing::Test
 SelectionOptionTest::SelectionOptionTest()
     : _sc(NULL), _options(NULL, NULL)
 {
-    _sc.init();
     _sc.setReferencePosType("atom");
     _sc.setOutputPosType("atom");
     _options.globalProperties().setSelectionCollection(&_sc);
@@ -73,14 +72,16 @@ TEST_F(SelectionOptionTest, ParsesSimpleSelection)
 {
     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());
 }
@@ -90,14 +91,16 @@ TEST_F(SelectionOptionTest, HandlesDynamicSelectionWhenStaticRequired)
 {
     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());
 }
 
 
@@ -105,15 +108,16 @@ TEST_F(SelectionOptionTest, HandlesTooManySelections)
 {
     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);
 }
 
@@ -122,14 +126,16 @@ TEST_F(SelectionOptionTest, HandlesTooFewSelections)
 {
     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());
 }
 
 
@@ -138,18 +144,19 @@ TEST_F(SelectionOptionTest, HandlesAdjuster)
     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));
 }
 
 
@@ -158,17 +165,18 @@ TEST_F(SelectionOptionTest, HandlesDynamicWhenStaticRequiredWithAdjuster)
     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);
 }
 
 
@@ -177,19 +185,19 @@ TEST_F(SelectionOptionTest, HandlesTooManySelectionsWithAdjuster)
     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);
 }
 
 
@@ -198,18 +206,18 @@ TEST_F(SelectionOptionTest, HandlesTooFewSelectionsWithAdjuster)
     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);
 }
 
 
@@ -217,13 +225,14 @@ TEST_F(SelectionOptionTest, HandlesDelayedRequiredSelection)
 {
     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);
 }
 
@@ -232,14 +241,15 @@ TEST_F(SelectionOptionTest, HandlesTooFewDelayedRequiredSelections)
 {
     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);
 }
 
 
@@ -247,14 +257,15 @@ TEST_F(SelectionOptionTest, HandlesDelayedOptionalSelection)
 {
     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);
 }
 
@@ -264,17 +275,18 @@ TEST_F(SelectionOptionTest, HandlesDelayedSelectionWithAdjuster)
     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
index 65a2f5e2f1f5916c9cb4ae81cc98e5a8dfd50315..386c83048d01f25b5a1423e943b0c6dc32b1f693 100644 (file)
@@ -75,8 +75,7 @@
 #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"
index f87d457d7b66f55b50cab71125dc1ac146777f74..4e17f55cf1dcdf3f2682dc3a5748f08aa56507cf 100644 (file)
@@ -60,7 +60,7 @@ class TrajectoryAnalysisModuleData::Impl
         Impl() : _selections(NULL) {}
         ~Impl();
 
-        int finishHandles();
+        void finishHandles();
 
         HandleContainer         _handles;
         const SelectionCollection *_selections;
@@ -86,7 +86,11 @@ class TrajectoryAnalysisModule::Impl
 class TrajectoryAnalysisModuleDataBasic : public TrajectoryAnalysisModuleData
 {
     public:
-        virtual int finish();
+        TrajectoryAnalysisModuleDataBasic(TrajectoryAnalysisModule *module,
+                                          /*AnalysisDataParallelOptions*/ void* opt,
+                                          const SelectionCollection &selections);
+
+        virtual void finish();
 };
 
 } // namespace gmx
index f2133a6ff11ad75ccf430854dc9ccd630c05f782..fb6469951f798c3310d55755ce80fd35b1e45d4b 100644 (file)
@@ -37,9 +37,8 @@
  */
 #include "gromacs/trajectoryanalysis/analysismodule.h"
 
-#include <cassert>
-
 #include "gromacs/analysisdata/analysisdata.h"
+#include "gromacs/fatalerror/gmxassert.h"
 
 #include "analysismodule-impl.h"
 
@@ -52,21 +51,25 @@ namespace gmx
 
 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;
 }
 
 
@@ -74,49 +77,39 @@ int TrajectoryAnalysisModuleData::Impl::finishHandles()
  * 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;
 }
 
@@ -145,11 +138,19 @@ TrajectoryAnalysisModuleData::parallelSelections(const std::vector<Selection *>
 /********************************************************************
  * TrajectoryAnalysisModuleDataBasic
  */
+TrajectoryAnalysisModuleDataBasic::TrajectoryAnalysisModuleDataBasic(
+        TrajectoryAnalysisModule *module,
+        /*AnalysisDataParallelOptions*/ void* opt,
+        const SelectionCollection &selections)
+    : TrajectoryAnalysisModuleData(module, opt, selections)
+{
+}
 
-int
+
+void
 TrajectoryAnalysisModuleDataBasic::finish()
 {
-    return finishDataHandles();
+    finishDataHandles();
 }
 
 
@@ -169,39 +170,26 @@ TrajectoryAnalysisModule::~TrajectoryAnalysisModule()
 }
 
 
-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;
 }
 
 
index c76998fa11dc1ec7101a58af3b8e3497e8c672f6..e234cc79a0f4b80cdcfa1d6d5523aa9a515f4fec 100644 (file)
@@ -49,7 +49,6 @@ namespace gmx
 {
 
 class AbstractAnalysisData;
-class AbstractErrorReporter;
 class AnalysisData;
 class AnalysisDataHandle;
 class Options;
@@ -78,29 +77,13 @@ class TrajectoryAnalysisModuleData
     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.
@@ -119,18 +102,28 @@ class TrajectoryAnalysisModuleData
         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;
@@ -181,33 +174,26 @@ class TrajectoryAnalysisModule
         /*! \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.
@@ -217,18 +203,18 @@ class TrajectoryAnalysisModule
          *
          * 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
@@ -240,9 +226,9 @@ class TrajectoryAnalysisModule
          *
          * \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.
          *
@@ -251,7 +237,6 @@ class TrajectoryAnalysisModule
          * \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.
@@ -266,8 +251,8 @@ class TrajectoryAnalysisModule
          * 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.
          *
@@ -287,7 +272,7 @@ class TrajectoryAnalysisModule
          *
          * \see startFrames()
          */
-        virtual int finishFrames(TrajectoryAnalysisModuleData *pdata);
+        virtual void finishFrames(TrajectoryAnalysisModuleData *pdata);
 
         /*! \brief
          * Postprocesses data after frames have been read.
@@ -295,7 +280,7 @@ class TrajectoryAnalysisModule
          * 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.
          *
@@ -304,7 +289,7 @@ class TrajectoryAnalysisModule
          * 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.
index 3f6fac994e23cd93d8300451f5958621e785667c..3b0866ce569f945cf92332ffe22124d425e5795c 100644 (file)
@@ -43,7 +43,7 @@
 #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"
@@ -104,15 +104,14 @@ TrajectoryAnalysisSettings::frflags() const
 }
 
 
-int
+void
 TrajectoryAnalysisSettings::setFlags(unsigned long flags)
 {
     _impl->flags = flags;
-    return 0;
 }
 
 
-int
+void
 TrajectoryAnalysisSettings::setFlag(unsigned long flag, bool bSet)
 {
     if (bSet)
@@ -123,31 +122,27 @@ TrajectoryAnalysisSettings::setFlag(unsigned long flag, bool 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;
 }
 
 
@@ -161,6 +156,7 @@ TopologyInformation::TopologyInformation()
     clear_mat(_boxtop);
 }
 
+
 TopologyInformation::~TopologyInformation()
 {
     if (_top)
@@ -171,7 +167,8 @@ TopologyInformation::~TopologyInformation()
     sfree(_xtop);
 }
 
-int
+
+void
 TopologyInformation::getTopologyConf(rvec **x, matrix box) const
 {
     if (box)
@@ -183,13 +180,10 @@ TopologyInformation::getTopologyConf(rvec **x, matrix box) const
         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
index bd1b164a69d990a0dff69bc561995f13e108ebba..7715b1c36fc714b89a24b8d56dbea84104b837f1 100644 (file)
@@ -142,14 +142,13 @@ class TrajectoryAnalysisSettings
          * 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.
@@ -166,12 +165,11 @@ class TrajectoryAnalysisSettings
          *
          * \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.
@@ -192,19 +190,18 @@ class TrajectoryAnalysisSettings
          *
          * \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;
@@ -242,14 +239,13 @@ class TopologyInformation
          *      (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();
index 1d2e5d2351f389fe78c1d3567ff8672de48883c1..3c401f988a20a7aef25f18c4716ef57f1b22badb 100644 (file)
 #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"
@@ -71,11 +73,11 @@ class TrajectoryAnalysisCommandLineRunner::Impl
 
         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;
@@ -110,7 +112,7 @@ TrajectoryAnalysisCommandLineRunner::Impl::printHelp(
 }
 
 
-int
+bool
 TrajectoryAnalysisCommandLineRunner::Impl::parseOptions(
         TrajectoryAnalysisSettings *settings,
         TrajectoryAnalysisRunnerCommon *common,
@@ -118,29 +120,12 @@ TrajectoryAnalysisCommandLineRunner::Impl::parseOptions(
         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);
@@ -150,28 +135,26 @@ TrajectoryAnalysisCommandLineRunner::Impl::parseOptions(
     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)
@@ -181,18 +164,16 @@ TrajectoryAnalysisCommandLineRunner::Impl::parseOptions(
         }
         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;
 }
 
 
@@ -229,73 +210,44 @@ TrajectoryAnalysisCommandLineRunner::run(int argc, char *argv[])
     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);
         }
@@ -303,31 +255,20 @@ TrajectoryAnalysisCommandLineRunner::run(int argc, char *argv[])
         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())
     {
@@ -340,19 +281,12 @@ TrajectoryAnalysisCommandLineRunner::run(int argc, char *argv[])
     }
 
     // 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
index a5d69a300cd9a475b995c1d46fa4ce89e2aa2af8..fc9859a5b6b8a5efc7df77a5b51e5ac68b87e9ed 100644 (file)
 #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
 {
@@ -149,57 +152,48 @@ Angle::initOptions(TrajectoryAnalysisSettings *settings)
 }
 
 
-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.
@@ -210,7 +204,7 @@ Angle::initOptionsDone(TrajectoryAnalysisSettings *settings,
         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])
     {
@@ -221,38 +215,25 @@ Angle::initOptionsDone(TrajectoryAnalysisSettings *settings,
         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
 {
@@ -262,13 +243,12 @@ Angle::checkSelections(const std::vector<Selection *> &sel1,
         {
             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();
@@ -276,17 +256,15 @@ Angle::checkSelections(const std::vector<Selection *> &sel1,
 
     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)
@@ -295,9 +273,9 @@ Angle::checkSelections(const std::vector<Selection *> &sel1,
         {
             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"));
             }
         }
     }
@@ -313,9 +291,9 @@ Angle::checkSelections(const std::vector<Selection *> &sel1,
             {
                 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"));
                 }
             }
         }
@@ -326,26 +304,21 @@ Angle::checkSelections(const std::vector<Selection *> &sel1,
     }
     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)
     {
@@ -383,8 +356,6 @@ Angle::initAnalysis(const TopologyInformation &top)
     plotm->setXTimeLabel();
     plotm->setYLabel("Angle [degrees]");
     _data.addModule(plotm);
-
-    return 0;
 }
 
 
@@ -448,7 +419,7 @@ calc_vec(int natoms, rvec x[], t_pbc *pbc, rvec xout, rvec cout)
 }
 
 
-int
+void
 Angle::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc,
                     TrajectoryAnalysisModuleData *pdata)
 {
@@ -456,11 +427,7 @@ Angle::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc,
     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;
@@ -564,12 +531,12 @@ Angle::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc,
                             }
                             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;
@@ -600,21 +567,18 @@ Angle::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc,
         dh->addPoint(g, ave);
     }
     dh->finishFrame();
-    return 0;
 }
 
 
-int
+void
 Angle::finishAnalysis(int /*nframes*/)
 {
-    return 0;
 }
 
 
-int
+void
 Angle::writeOutput()
 {
-    return 0;
 }
 
 
index d30f9e05cff75a8c7bc8820a102bd98fabcbf89f..0e8573b02618b5bfdfd7933d31dedd4e43ba3156 100644 (file)
@@ -56,19 +56,18 @@ class Angle : public TrajectoryAnalysisModule
         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;
 
index e5366258babd3f7f2499ef485ce06cd56cbd7813..f676ac574e62c26b55183632c9f04bb24879695a 100644 (file)
 #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"
@@ -84,18 +87,16 @@ Distance::initOptions(TrajectoryAnalysisSettings *settings)
 }
 
 
-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");
@@ -109,12 +110,10 @@ Distance::initAnalysis(const TopologyInformation & /*top*/)
     _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)
 {
@@ -137,18 +136,16 @@ Distance::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc,
     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;
@@ -156,7 +153,6 @@ Distance::writeOutput()
     _avem->getData(0, NULL, &ave, NULL);
     fprintf(stderr, "Average distance: %f\n", ave[0]);
     fprintf(stderr, "Std. deviation:   %f\n", ave[1]);
-    return 0;
 }
 
 
index 689d73bd8a2b8a0d097d942fb1129eac7a232fd2..6ca211eac2a417d98b39f97ef416dcaf43b9a9ca 100644 (file)
@@ -57,13 +57,13 @@ class Distance : public TrajectoryAnalysisModule
         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;
index d4f50c4e7f2068afe9821608f9ea4ba49124deb2..7fad73e3f5d9443c33c7ffa241633cdb270ba81f 100644 (file)
 #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
 {
@@ -74,13 +75,13 @@ class IndexFileWriterModule : public AnalysisDataModuleInterface
 
         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();
@@ -149,32 +150,30 @@ int IndexFileWriterModule::flags() const
 }
 
 
-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)
     {
@@ -188,9 +187,7 @@ IndexFileWriterModule::pointsAdded(real x, real /*dx*/, int firstcol, int n,
             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;
@@ -209,25 +206,22 @@ IndexFileWriterModule::pointsAdded(real x, real /*dx*/, int firstcol, int n,
             ++_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;
 }
 
 
@@ -238,7 +232,11 @@ int IndexFileWriterModule::dataFinished()
 class Select::ModuleData : public TrajectoryAnalysisModuleData
 {
     public:
-        ModuleData() : _mmap(NULL)
+        ModuleData(TrajectoryAnalysisModule *module,
+                   AnalysisDataParallelOptions opt,
+                   const SelectionCollection &selections)
+            : TrajectoryAnalysisModuleData(module, opt, selections),
+              _mmap(NULL)
         {
         }
 
@@ -251,9 +249,9 @@ class Select::ModuleData : public TrajectoryAnalysisModuleData
             }
         }
 
-        virtual int finish()
+        virtual void finish()
         {
-            return finishDataHandles();
+            finishDataHandles();
         }
 
         gmx_ana_indexmap_t  *_mmap;
@@ -357,13 +355,12 @@ Select::initOptions(TrajectoryAnalysisSettings *settings)
 }
 
 
-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");
 
@@ -460,34 +457,22 @@ Select::initAnalysis(const TopologyInformation &top)
     }
 
     _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)
 {
@@ -551,21 +536,18 @@ Select::analyzeFrame(int frnr, const t_trxframe &fr, t_pbc *pbc,
         }
         mdh->finishFrame();
     }
-    return 0;
 }
 
 
-int
+void
 Select::finishAnalysis(int /*nframes*/)
 {
-    return 0;
 }
 
 
-int
+void
 Select::writeOutput()
 {
-    return 0;
 }
 
 
index 12825eff3e228f5ed8ab22dd69d901fe3fe93a40..5e070820c7ed3616d5a96753ada137968e82f87a 100644 (file)
@@ -56,16 +56,16 @@ class Select : public TrajectoryAnalysisModule
         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;
index 1543d3d61c8d9764ff3d25b8ef0b983ed2294c7d..161a0a738af22d9142d4bc279490cb6d08a1b31d 100644 (file)
@@ -39,7 +39,6 @@
 #include <config.h>
 #endif
 
-#include <cassert>
 #include <string.h>
 
 #include <rmpbc.h>
@@ -48,7 +47,8 @@
 #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"
@@ -56,6 +56,7 @@
 #include "gromacs/selection/selectioncollection.h"
 #include "gromacs/trajectoryanalysis/analysissettings.h"
 #include "gromacs/trajectoryanalysis/runnercommon.h"
+#include "gromacs/utility/format.h"
 
 #include "analysissettings-impl.h"
 
@@ -212,19 +213,17 @@ TrajectoryAnalysisRunnerCommon::initOptions()
 }
 
 
-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"))
@@ -234,15 +233,13 @@ TrajectoryAnalysisRunnerCommon::initOptionsDone()
     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
@@ -251,9 +248,8 @@ TrajectoryAnalysisRunnerCommon::initIndexGroups(SelectionCollection *selections)
     else
     {
         gmx_ana_indexgrps_init(&_impl->_grps, NULL, _impl->_ndxfile.c_str());
-        rc = selections->setIndexGroups(_impl->_grps);
+        selections->setIndexGroups(_impl->_grps);
     }
-    return rc;
 }
 
 
@@ -269,7 +265,7 @@ TrajectoryAnalysisRunnerCommon::doneIndexGroups(SelectionCollection *selections)
 }
 
 
-int
+void
 TrajectoryAnalysisRunnerCommon::initTopology(SelectionCollection *selections)
 {
     const TrajectoryAnalysisSettings &settings = _impl->_settings;
@@ -278,8 +274,7 @@ TrajectoryAnalysisRunnerCommon::initTopology(SelectionCollection *selections)
           || 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.
@@ -304,18 +299,10 @@ TrajectoryAnalysisRunnerCommon::initTopology(SelectionCollection *selections)
     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)
@@ -324,18 +311,16 @@ TrajectoryAnalysisRunnerCommon::initTopology(SelectionCollection *selections)
         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();
 
@@ -350,17 +335,15 @@ TrajectoryAnalysisRunnerCommon::initFirstFrame()
         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.
         /*
@@ -380,13 +363,11 @@ TrajectoryAnalysisRunnerCommon::initFirstFrame()
         // 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;
@@ -404,8 +385,6 @@ TrajectoryAnalysisRunnerCommon::initFirstFrame()
         _impl->_gpbc = gmx_rmpbc_init(&top.topology()->idef, top.ePBC(),
                                       _impl->fr->natoms, _impl->fr->box);
     }
-
-    return 0;
 }
 
 
@@ -425,14 +404,13 @@ TrajectoryAnalysisRunnerCommon::readNextFrame()
 }
 
 
-int
+void
 TrajectoryAnalysisRunnerCommon::initFrame()
 {
     if (_impl->_gpbc != NULL)
     {
         gmx_rmpbc_trxfr(_impl->_gpbc, _impl->fr);
     }
-    return 0;
 }
 
 
index 16e47dd0e39657a6ac02ab508b86399c40e2ad59..bf5317865fcdc532c6efcb8c4815750a72d08496 100644 (file)
@@ -75,13 +75,13 @@ class TrajectoryAnalysisRunnerCommon
         ~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;
index ea30c79352abf9c9dc2d38da341b9e99c57cb75b..f73aa283636aa873e5ee3edcf23ae618c2c7110c 100644 (file)
@@ -37,6 +37,7 @@
 
 #include <vector>
 
+#include <gromacs/fatalerror/exceptions.h>
 #include <gromacs/options/basicoptions.h>
 #include <gromacs/options/options.h>
 #include <gromacs/selection/selection.h>
@@ -55,13 +56,13 @@ class SelectionTester : public TrajectoryAnalysisModule
         ~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();
@@ -111,14 +112,13 @@ SelectionTester::initOptions(TrajectoryAnalysisSettings * /*settings*/)
     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*/)
 {
@@ -149,20 +149,17 @@ SelectionTester::analyzeFrame(int /*frnr*/, const t_trxframe &/*fr*/, t_pbc * /*
         }
     }
     fprintf(stderr, "\n");
-    return 0;
 }
 
-int
+void
 SelectionTester::finishAnalysis(int /*nframes*/)
 {
     printSelections();
-    return 0;
 }
 
-int
+void
 SelectionTester::writeOutput()
 {
-    return 0;
 }
 
 }
@@ -170,8 +167,16 @@ SelectionTester::writeOutput()
 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;
+    }
 }
index fce116fe95d11c4d19403f5efe5b2b8839409aa3..ee8ca5567683c471c4d6a47127cb834f4ebe42c6 100644 (file)
 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);
 }