From 89b5022f9b9d32fa03188b677896f3ff831fb594 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= Date: Wed, 16 Feb 2011 11:08:40 +0100 Subject: [PATCH] Preprocessor: more explicit error message when users enter invalid floating point numbers (like "1e-10000") --- preprocessor/DataTree.cc | 2 +- preprocessor/DataTree.hh | 2 +- preprocessor/NumericalConstants.cc | 10 ++++--- preprocessor/NumericalConstants.hh | 11 ++++++-- preprocessor/ParsingDriver.cc | 42 +++++++++++++++++++++++------- 5 files changed, 51 insertions(+), 16 deletions(-) diff --git a/preprocessor/DataTree.cc b/preprocessor/DataTree.cc index 4f3ad4a36..87052a6e1 100644 --- a/preprocessor/DataTree.cc +++ b/preprocessor/DataTree.cc @@ -51,7 +51,7 @@ DataTree::~DataTree() } expr_t -DataTree::AddNonNegativeConstant(const string &value) +DataTree::AddNonNegativeConstant(const string &value) throw (NumericalConstants::InvalidFloatingPointNumberException) { int id = num_constants.AddNonNegativeConstant(value); diff --git a/preprocessor/DataTree.hh b/preprocessor/DataTree.hh index 1a8b9f6de..1456e9c86 100644 --- a/preprocessor/DataTree.hh +++ b/preprocessor/DataTree.hh @@ -110,7 +110,7 @@ public: }; //! Adds a non-negative numerical constant (possibly Inf or NaN) - expr_t AddNonNegativeConstant(const string &value); + expr_t AddNonNegativeConstant(const string &value) throw (NumericalConstants::InvalidFloatingPointNumberException); //! Adds a variable /*! The default implementation of the method refuses any lag != 0 */ virtual VariableNode *AddVariable(int symb_id, int lag = 0); diff --git a/preprocessor/NumericalConstants.cc b/preprocessor/NumericalConstants.cc index 58f1d2822..6efe1fc06 100644 --- a/preprocessor/NumericalConstants.cc +++ b/preprocessor/NumericalConstants.cc @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2010 Dynare Team + * Copyright (C) 2003-2011 Dynare Team * * This file is part of Dynare. * @@ -26,7 +26,7 @@ #include "NumericalConstants.hh" int -NumericalConstants::AddNonNegativeConstant(const string &iConst) +NumericalConstants::AddNonNegativeConstant(const string &iConst) throw (InvalidFloatingPointNumberException) { map::const_iterator iter = numConstantsIndex.find(iConst); @@ -39,7 +39,11 @@ NumericalConstants::AddNonNegativeConstant(const string &iConst) errno = 0; double val = strtod(iConst.c_str(), NULL); - assert(errno == 0); // Check that the conversion succeeded + + // We check that the number is valid (e.g. not like "1e-10000") + if (errno != 0) + throw InvalidFloatingPointNumberException(iConst); + assert(val >= 0 || isnan(val)); // Check we have a positive constant or a NaN double_vals.push_back(val); diff --git a/preprocessor/NumericalConstants.hh b/preprocessor/NumericalConstants.hh index ceacc94b9..0a54616a2 100644 --- a/preprocessor/NumericalConstants.hh +++ b/preprocessor/NumericalConstants.hh @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2010 Dynare Team + * Copyright (C) 2003-2011 Dynare Team * * This file is part of Dynare. * @@ -37,8 +37,15 @@ private: //! Map matching constants to their id map numConstantsIndex; public: + class InvalidFloatingPointNumberException + { + public: + const string fp; + InvalidFloatingPointNumberException(const string &fp_arg) : fp(fp_arg) {} + }; + //! Adds a non-negative constant (possibly Inf or NaN) and returns its ID - int AddNonNegativeConstant(const string &iConst); + int AddNonNegativeConstant(const string &iConst) throw (InvalidFloatingPointNumberException); //! Get a constant in string form string get(int ID) const; //! Get a constant in double form diff --git a/preprocessor/ParsingDriver.cc b/preprocessor/ParsingDriver.cc index 214cbf84b..7fb56ce7d 100644 --- a/preprocessor/ParsingDriver.cc +++ b/preprocessor/ParsingDriver.cc @@ -227,7 +227,15 @@ ParsingDriver::add_equation_tags(string *key, string *value) expr_t ParsingDriver::add_non_negative_constant(string *constant) { - expr_t id = data_tree->AddNonNegativeConstant(*constant); + expr_t id; + try + { + id = data_tree->AddNonNegativeConstant(*constant); + } + catch (NumericalConstants::InvalidFloatingPointNumberException &e) + { + error("Invalid floating point number: " + *constant); + } delete constant; return id; } @@ -703,10 +711,18 @@ void ParsingDriver::add_value(string *v) { expr_t id; - if (v->at(0) == '-') - id = data_tree->AddUMinus(data_tree->AddNonNegativeConstant(v->substr(1, string::npos))); - else - id = data_tree->AddNonNegativeConstant(*v); + try + { + if (v->at(0) == '-') + id = data_tree->AddUMinus(data_tree->AddNonNegativeConstant(v->substr(1, string::npos))); + else + id = data_tree->AddNonNegativeConstant(*v); + } + catch (NumericalConstants::InvalidFloatingPointNumberException &e) + { + error("Invalid floating point number: " + *v); + } + delete v; det_shocks_values.push_back(id); } @@ -817,10 +833,18 @@ void ParsingDriver::add_to_row_const(string *v) { expr_t id; - if (v->at(0) == '-') - id = data_tree->AddUMinus(data_tree->AddNonNegativeConstant(v->substr(1, string::npos))); - else - id = data_tree->AddNonNegativeConstant(*v); + try + { + if (v->at(0) == '-') + id = data_tree->AddUMinus(data_tree->AddNonNegativeConstant(v->substr(1, string::npos))); + else + id = data_tree->AddNonNegativeConstant(*v); + } + catch (NumericalConstants::InvalidFloatingPointNumberException &e) + { + error("Invalid floating point number: " + *v); + } + delete v; sigmae_row.push_back(id); }