/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2009,2010,2011,2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2009,2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
* methods and initializes the children of the method element.
* - selectioncollection.h, selectioncollection.cpp:
* These files define the high-level public interface to the parser
- * through SelectionCollection::parseFromStdin(),
- * SelectionCollection::parseFromFile() and
+ * through SelectionCollection::parseInteractive(),
+ * SelectionCollection::parseFromStdin(),
+ * SelectionCollection::parseFromFile(), and
* SelectionCollection::parseFromString().
*
* The basic control flow in the parser is as follows: when a parser function
#include "gromacs/selection/selection.h"
#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/exceptions.h"
-#include "gromacs/utility/file.h"
-#include "gromacs/utility/messagestringcollector.h"
#include "gromacs/utility/smalloc.h"
#include "gromacs/utility/stringutil.h"
+#include "gromacs/utility/textwriter.h"
#include "keywords.h"
#include "poscalc.h"
} // namespace
-void
-_gmx_selparser_error(yyscan_t scanner, const char *fmt, ...)
-{
- 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);
- vsnprintf(buf, 1024, fmt, ap);
- va_end(ap);
- errors->append(buf);
-}
-
bool
_gmx_selparser_handle_exception(yyscan_t scanner, std::exception *ex)
{
bool
_gmx_selparser_handle_error(yyscan_t scanner)
{
- std::string context(gmx::formatString("In selection '%s'",
+ std::string context(gmx::formatString("Invalid selection '%s'",
_gmx_sel_lexer_pselstr(scanner)));
// The only way to prepend context to the exception is to rethrow it.
try
catch (gmx::UserInputError &ex)
{
ex.prependContext(context);
- if (_gmx_sel_is_lexer_interactive(scanner))
+ gmx::TextWriter *statusWriter
+ = _gmx_sel_lexer_get_status_writer(scanner);
+ if (statusWriter != NULL)
{
- gmx::formatExceptionMessageToFile(stderr, ex);
+ gmx::formatExceptionMessageToWriter(statusWriter, ex);
return true;
}
throw;
ex.prependContext(context);
throw;
}
- // Do legacy processing for non-exception cases.
- // This is only reached if there was no active exception.
- _gmx_selparser_error(scanner, "Invalid selection '%s'",
- _gmx_sel_lexer_pselstr(scanner));
- return _gmx_sel_is_lexer_interactive(scanner);
+ GMX_RELEASE_ASSERT(false, "All parsing errors should result in a captured exception");
+ return false; // Some compilers will not believe that the above never returns.
}
namespace gmx
* \param[in,out] pcc Position calculation collection to use.
* \param[in,out] sel Selection element to initialize.
* \param[in] rpost Reference position type to use (NULL = default).
- * \param[in] scanner Scanner data structure.
- * \returns 0 on success, a non-zero error code on error.
*/
static void
set_refpos_type(gmx::PositionCalculationCollection *pcc,
- const SelectionTreeElementPointer &sel,
- const char *rpost, yyscan_t scanner)
+ const SelectionTreeElementPointer &sel,
+ const char *rpost)
{
if (!rpost)
{
}
else
{
- // TODO: Should this be treated as a real error?
- _gmx_selparser_error(scanner, "modifier '%s' is not applicable for '%s'",
- rpost, sel->u.expr.method->name);
+ std::string message
+ = gmx::formatString("Position modifiers ('%s') is not applicable for '%s'",
+ rpost, sel->u.expr.method->name);
+ GMX_THROW(gmx::InvalidInputError(message));
}
}
const gmx::SelectionTreeElementPointer &right,
const char *cmpop, yyscan_t scanner)
{
- gmx::MessageStringCollector *errors = _gmx_sel_lexer_error_reporter(scanner);
- gmx::MessageStringContext context(errors, formatCurrentErrorContext(scanner));
-
SelectionTreeElementPointer sel(
new SelectionTreeElement(
SEL_EXPRESSION, _gmx_sel_lexer_get_current_location(scanner)));
SelectionParserParameter::create(
"op", SelectionParserValue::createString(cmpop, location),
location));
- if (!_gmx_sel_parse_params(params, sel->u.expr.method->nparams,
- sel->u.expr.method->param, sel, scanner))
- {
- return SelectionTreeElementPointer();
- }
+ _gmx_sel_parse_params(params, sel->u.expr.method->nparams,
+ sel->u.expr.method->param, sel, scanner);
return sel;
}
{
gmx_ana_selcollection_t *sc = _gmx_sel_lexer_selcollection(scanner);
- gmx::MessageStringCollector *errors = _gmx_sel_lexer_error_reporter(scanner);
- gmx::MessageStringContext context(errors, formatCurrentErrorContext(scanner));
-
if (method->nparams > 0)
{
// TODO: Would assert be better?
SelectionParserParameter::createFromExpression(NULL, child));
params.push_back(
SelectionParserParameter::create(NULL, move(args), location));
- if (!_gmx_sel_parse_params(params, root->u.expr.method->nparams,
- root->u.expr.method->param, root, scanner))
- {
- return SelectionTreeElementPointer();
- }
+ _gmx_sel_parse_params(params, root->u.expr.method->nparams,
+ root->u.expr.method->param, root, scanner);
}
- set_refpos_type(&sc->pcc, child, rpost, scanner);
+ set_refpos_type(&sc->pcc, child, rpost);
return root;
}
const gmx::SelectionTreeElementPointer &group,
const char *rpost, yyscan_t scanner)
{
- gmx::MessageStringCollector *errors = _gmx_sel_lexer_error_reporter(scanner);
- gmx::MessageStringContext context(errors, formatCurrentErrorContext(scanner));
-
+ // TODO Provide an error if rpost is provided.
GMX_UNUSED_VALUE(rpost);
return _gmx_sel_init_keyword_evaluator(method, group, scanner);
}
const char *rpost, yyscan_t scanner)
{
gmx_ana_selcollection_t *sc = _gmx_sel_lexer_selcollection(scanner);
- int rc;
-
- gmx::MessageStringCollector *errors = _gmx_sel_lexer_error_reporter(scanner);
- gmx::MessageStringContext context(errors, formatCurrentErrorContext(scanner));
_gmx_sel_finish_method(scanner);
/* The "same" keyword needs some custom massaging of the parameters. */
- rc = _gmx_selelem_custom_init_same(&method, params, scanner);
- if (rc != 0)
- {
- return SelectionTreeElementPointer();
- }
+ _gmx_selelem_custom_init_same(&method, params, scanner);
SelectionTreeElementPointer root(
new SelectionTreeElement(
SEL_EXPRESSION, _gmx_sel_lexer_get_current_location(scanner)));
_gmx_selelem_set_method(root, method, scanner);
/* Process the parameters */
- if (!_gmx_sel_parse_params(*params, root->u.expr.method->nparams,
- root->u.expr.method->param, root, scanner))
- {
- return SelectionTreeElementPointer();
- }
- set_refpos_type(&sc->pcc, root, rpost, scanner);
+ _gmx_sel_parse_params(*params, root->u.expr.method->nparams,
+ root->u.expr.method->param, root, scanner);
+ set_refpos_type(&sc->pcc, root, rpost);
return root;
}
const gmx::SelectionTreeElementPointer &sel,
yyscan_t scanner)
{
- gmx::MessageStringCollector *errors = _gmx_sel_lexer_error_reporter(scanner);
- gmx::MessageStringContext context(errors, formatCurrentErrorContext(scanner));
-
_gmx_sel_finish_method(scanner);
SelectionTreeElementPointer modifier(
new SelectionTreeElement(
root = modifier;
}
/* Process the parameters */
- if (!_gmx_sel_parse_params(*params, modifier->u.expr.method->nparams,
- modifier->u.expr.method->param, modifier, scanner))
- {
- return SelectionTreeElementPointer();
- }
+ _gmx_sel_parse_params(*params, modifier->u.expr.method->nparams,
+ modifier->u.expr.method->param, modifier, scanner);
return root;
}
_gmx_sel_init_position(const gmx::SelectionTreeElementPointer &expr,
const char *type, yyscan_t scanner)
{
- gmx::MessageStringCollector *errors = _gmx_sel_lexer_error_reporter(scanner);
- gmx::MessageStringContext context(errors, formatCurrentErrorContext(scanner));
-
SelectionTreeElementPointer root(
new SelectionTreeElement(
SEL_EXPRESSION, _gmx_sel_lexer_get_current_location(scanner)));
SelectionParserParameterList params;
params.push_back(SelectionParserParameter::createFromExpression(NULL, expr));
/* Parse the parameters. */
- if (!_gmx_sel_parse_params(params, root->u.expr.method->nparams,
- root->u.expr.method->param, root, scanner))
- {
- return SelectionTreeElementPointer();
- }
+ _gmx_sel_parse_params(params, root->u.expr.method->nparams,
+ root->u.expr.method->param, root, scanner);
return root;
}
root->fillNameIfMissing(_gmx_sel_lexer_pselstr(scanner));
/* Print out some information if the parser is interactive */
- if (_gmx_sel_is_lexer_interactive(scanner))
+ gmx::TextWriter *statusWriter = _gmx_sel_lexer_get_status_writer(scanner);
+ if (statusWriter != NULL)
{
- fprintf(stderr, "Selection '%s' parsed\n",
- _gmx_sel_lexer_pselstr(scanner));
+ const std::string message
+ = gmx::formatString("Selection '%s' parsed",
+ _gmx_sel_lexer_pselstr(scanner));
+ statusWriter->writeLine(message);
}
return root;
srenew(sc->varstrs, sc->nvars + 1);
sc->varstrs[sc->nvars] = gmx_strdup(pselstr);
++sc->nvars;
- if (_gmx_sel_is_lexer_interactive(scanner))
+ gmx::TextWriter *statusWriter = _gmx_sel_lexer_get_status_writer(scanner);
+ if (statusWriter != NULL)
{
- fprintf(stderr, "Variable '%s' parsed\n", pselstr);
+ const std::string message
+ = gmx::formatString("Variable '%s' parsed", pselstr);
+ statusWriter->writeLine(message);
}
return root;
}