Merge release-5-0 into master
[alexxy/gromacs.git] / src / gromacs / selection / sm_same.cpp
index cef245c5d928991e510e7436cefdbd856aa16fd7..01450da98f516905f7ecd4ebc0743bcb63d5b1f6 100644 (file)
  * \author Teemu Murtola <teemu.murtola@gmail.com>
  * \ingroup module_selection
  */
+#include "gmxpre.h"
+
 #include <stdlib.h>
 
 #include "gromacs/legacyheaders/macros.h"
-
-#include "gromacs/selection/selmethod.h"
 #include "gromacs/utility/exceptions.h"
 #include "gromacs/utility/smalloc.h"
 
 #include "keywords.h"
 #include "parsetree.h"
 #include "selelem.h"
+#include "selmethod.h"
 
 /*! \internal
  * \brief
@@ -230,12 +231,11 @@ init_data_same(int /* npar */, gmx_ana_selparam_t *param)
  * \param[in,out] method  The method to initialize.
  * \param[in,out] params  Pointer to the first parameter.
  * \param[in]     scanner Scanner data structure.
- * \returns       0 on success, a non-zero error code on error.
  *
- * If \p *method is not a \c same method, this function returns zero
+ * If \p *method is not a \c same method, this function returns
  * immediately.
  */
-int
+void
 _gmx_selelem_custom_init_same(gmx_ana_selmethod_t                           **method,
                               const gmx::SelectionParserParameterListPointer &params,
                               void                                           *scanner)
@@ -244,15 +244,14 @@ _gmx_selelem_custom_init_same(gmx_ana_selmethod_t                           **me
     /* Do nothing if this is not a same method. */
     if (!*method || (*method)->name != sm_same.name || params->empty())
     {
-        return 0;
+        return;
     }
 
     const gmx::SelectionParserValueList &kwvalues = params->front().values();
     if (kwvalues.size() != 1 || !kwvalues.front().hasExpressionValue()
         || kwvalues.front().expr->type != SEL_EXPRESSION)
     {
-        _gmx_selparser_error(scanner, "'same' should be followed by a single keyword");
-        return -1;
+        GMX_THROW(gmx::InvalidInputError("'same' should be followed by a single keyword"));
     }
     gmx_ana_selmethod_t *kwmethod = kwvalues.front().expr->u.expr.method;
     if (kwmethod->type == STR_VALUE)
@@ -264,27 +263,22 @@ _gmx_selelem_custom_init_same(gmx_ana_selmethod_t                           **me
     gmx::SelectionParserParameterList::iterator asparam = ++params->begin();
     if (asparam != params->end() && asparam->name() == sm_same.param[1].name)
     {
-        gmx::SelectionParserParameterList    kwparams;
-        gmx::SelectionParserValueListPointer values(
-                new gmx::SelectionParserValueList(asparam->values()));
-        kwparams.push_back(
-                gmx::SelectionParserParameter::create(NULL, move(values)));
-
+        const gmx::SelectionParserValueList &asvalues = asparam->values();
+        if (asvalues.size() != 1 || !asvalues.front().hasExpressionValue())
+        {
+            // TODO: Think about providing more informative context.
+            GMX_THROW(gmx::InvalidInputError("'same ... as' should be followed by a single expression"));
+        }
+        const gmx::SelectionTreeElementPointer &child = asvalues.front().expr;
         /* Create a second keyword evaluation element for the keyword given as
          * the first parameter, evaluating the keyword in the group given by the
          * second parameter. */
         gmx::SelectionTreeElementPointer kwelem
-            = _gmx_sel_init_keyword_evaluator(kwmethod, kwparams, scanner);
-        // FIXME: Use exceptions.
-        if (!kwelem)
-        {
-            return -1;
-        }
+            = _gmx_sel_init_keyword_evaluator(kwmethod, child, scanner);
         /* Replace the second parameter with one with a value from \p kwelem. */
         std::string pname = asparam->name();
         *asparam = gmx::SelectionParserParameter::createFromExpression(pname, kwelem);
     }
-    return 0;
 }
 
 static void