diff --git a/DDCore/include/DD4hep/detail/Grammar_parsed.h b/DDCore/include/DD4hep/detail/Grammar_parsed.h index 3f466bb99f8028f2f818c92fa1708f3d1ae96007..2b22fc35263bbeb34f898b9b70c649fadb10c9b1 100644 --- a/DDCore/include/DD4hep/detail/Grammar_parsed.h +++ b/DDCore/include/DD4hep/detail/Grammar_parsed.h @@ -45,8 +45,8 @@ #endif -namespace dd4hep { dd4hep::tools::Evaluator& g4Evaluator(); } -namespace { static dd4hep::tools::Evaluator& s__eval(dd4hep::g4Evaluator()); } +namespace dd4hep { const dd4hep::tools::Evaluator& g4Evaluator(); } +namespace { static const dd4hep::tools::Evaluator& s__eval(dd4hep::g4Evaluator()); } // Forward declarations /// Namespace for the AIDA detector description toolkit @@ -199,11 +199,11 @@ namespace dd4hep { val.erase(idx, 5); while (val[0] == ' ') val.erase(0, 1); - double result = s__eval.evaluate(val.c_str()); - if (s__eval.status() != tools::Evaluator::OK) { + auto result = s__eval.evaluate(val.c_str()); + if (result.first != tools::Evaluator::OK) { return 0; } - *ptr = (T)result; + *ptr = (T)result.second; return 1; } diff --git a/DDCore/src/Handle.cpp b/DDCore/src/Handle.cpp index 5b58f34ccf01b2963f43c60718866773de4d976a..abd6f3f46eb456818467f5ceba40b576783a048a 100644 --- a/DDCore/src/Handle.cpp +++ b/DDCore/src/Handle.cpp @@ -30,7 +30,7 @@ namespace dd4hep { } namespace { - dd4hep::tools::Evaluator& eval(dd4hep::evaluator()); + const dd4hep::tools::Evaluator& eval(dd4hep::evaluator()); } using namespace std; @@ -38,51 +38,47 @@ using namespace dd4hep; using namespace dd4hep::detail; namespace { - void check_evaluation(const string& value, int status) { - if (status != tools::Evaluator::OK) { - stringstream str; - eval.print_error(str); - throw runtime_error("dd4hep: "+str.str()+" : value="+value+" [Evaluation error]"); + + void check_evaluation(const string& value, std::pair<int,double> res, stringstream& err) { + if ( res.first != tools::Evaluator::OK) { + throw runtime_error("dd4hep: "+err.str()+" : value="+value+" [Evaluation error]"); } } + } namespace dd4hep { - short _toShort(const string& value) { + std::pair<int, double> _toFloatingPoint(const string& value) { + stringstream err; + auto result = eval.evaluate(value, err); + check_evaluation(value, result, err); + return result; + } + + std::pair<int, double> _toInteger(const string& value) { string s(value); size_t idx = s.find("(int)"); if (idx != string::npos) s.erase(idx, 5); + idx = s.find("(long)"); + if (idx != string::npos) + s.erase(idx, 6); while (s[0] == ' ') s.erase(0, 1); - double result = eval.evaluate(s.c_str()); - check_evaluation(value, eval.status()); - return (short) result; + return _toFloatingPoint(s); + } + + short _toShort(const string& value) { + return (short) _toInteger(value).second; } int _toInt(const string& value) { - string s(value); - size_t idx = s.find("(int)"); - if (idx != string::npos) - s.erase(idx, 5); - while (s[0] == ' ') - s.erase(0, 1); - double result = eval.evaluate(s.c_str()); - check_evaluation(value, eval.status()); - return (int) result; + return (int) _toInteger(value).second; } long _toLong(const string& value) { - string s(value); - size_t idx = s.find("(int)"); - if (idx != string::npos) - s.erase(idx, 5); - while (s[0] == ' ') - s.erase(0, 1); - double result = eval.evaluate(s.c_str()); - check_evaluation(value, eval.status()); - return (long) result; + return (long) _toInteger(value).second; } bool _toBool(const string& value) { @@ -91,16 +87,12 @@ namespace dd4hep { /// String conversions: string to float value float _toFloat(const string& value) { - double result = eval.evaluate(value.c_str()); - check_evaluation(value, eval.status()); - return (float) result; + return (float) _toFloatingPoint(value).second; } /// String conversions: string to double value double _toDouble(const string& value) { - double result = eval.evaluate(value.c_str()); - check_evaluation(value, eval.status()); - return result; + return _toFloatingPoint(value).second; } /// Generic type conversion from string to primitive value \ingroup DD4HEP_CORE @@ -234,6 +226,7 @@ namespace dd4hep { return; } else { + stringstream err; string n = name, v = value; size_t idx = v.find("(int)"); if (idx != string::npos) @@ -243,9 +236,31 @@ namespace dd4hep { v.erase(idx, 7); while (v[0] == ' ') v.erase(0, 1); - double result = eval.evaluate(v.c_str()); - check_evaluation(v, eval.status()); - eval.setVariable(n.c_str(), result); + auto result = eval.evaluate(v, err); + check_evaluation(v, result, err); + eval.setVariable(n, result.second); + } + } + + /// Evaluate string constant using environment stored in the evaluator + string _getEnviron(const string& env) { + size_t id1 = env.find("${"); + size_t id2 = env.rfind("}"); + if ( id1 == string::npos || id2 == string::npos ) { + return ""; + } + else { + stringstream err; + string v = env.substr(id1,id2-id1+1); + auto ret = eval.getEnviron(v, err); + if ( ret.first != tools::Evaluator::OK) { + cerr << env << ": " << err.str() << endl; + throw runtime_error("dd4hep: Severe error during environment lookup of " + env); + } + v = env.substr(0,id1); + v += ret.second; + v += env.substr(id2+1); + return v; } } diff --git a/DDCore/src/JSON/Elements.cpp b/DDCore/src/JSON/Elements.cpp index 9a8c70586953ee596f6e5bbfbdfb8c0aba58fd24..453af4ba5aca5d5f898df7df9fd715e83e3918f6 100644 --- a/DDCore/src/JSON/Elements.cpp +++ b/DDCore/src/JSON/Elements.cpp @@ -28,13 +28,17 @@ static const size_t INVALID_NODE = ~0U; // Forward declarations namespace dd4hep { - dd4hep::tools::Evaluator& evaluator(); + const dd4hep::tools::Evaluator& evaluator(); + std::pair<int, double> _toInteger(const string& value); + std::pair<int, double> _toFloatingPoint(const string& value); + void _toDictionary(const string& name, const string& value, const string& typ); + string _getEnviron(const string& env); } // Static storage namespace { - dd4hep::tools::Evaluator& eval(dd4hep::evaluator()); + const dd4hep::tools::Evaluator& eval(dd4hep::evaluator()); string _checkEnviron(const string& env) { - string r = getEnviron(env); + string r = dd4hep::_getEnviron(env); return r.empty() ? env : r; } } @@ -139,44 +143,11 @@ string dd4hep::json::_ptrToString(const void* v, const char* fmt) { } long dd4hep::json::_toLong(const char* value) { - if (value) { - string s = _toString(value); - size_t idx = s.find("(int)"); - if (idx != string::npos) - s.erase(idx, 5); - idx = s.find("(long)"); - if (idx != string::npos) - s.erase(idx, 6); - while (s[0] == ' ') - s.erase(0, 1); - double result = eval.evaluate(s.c_str()); - if (eval.status() != tools::Evaluator::OK) { - cerr << s << ": "; - eval.print_error(); - throw runtime_error("dd4hep: Severe error during expression evaluation of " + s); - } - return (long) result; - } - return -1; + return value ? (long)dd4hep::_toInteger(_toString(value)).second : -1L; } int dd4hep::json::_toInt(const char* value) { - if (value) { - string s = _toString(value); - size_t idx = s.find("(int)"); - if (idx != string::npos) - s.erase(idx, 5); - while (s[0] == ' ') - s.erase(0, 1); - double result = eval.evaluate(s.c_str()); - if (eval.status() != tools::Evaluator::OK) { - cerr << s << ": "; - eval.print_error(); - throw runtime_error("dd4hep: Severe error during expression evaluation of " + s); - } - return (int) result; - } - return -1; + return value ? (int)dd4hep::_toInteger(_toString(value)).second : -1; } bool dd4hep::json::_toBool(const char* value) { @@ -188,54 +159,19 @@ bool dd4hep::json::_toBool(const char* value) { } float dd4hep::json::_toFloat(const char* value) { - if (value) { - string s = _toString(value); - double result = eval.evaluate(s.c_str()); - - if (eval.status() != tools::Evaluator::OK) { - cerr << s << ": "; - eval.print_error(); - throw runtime_error("dd4hep: Severe error during expression evaluation of " + s); - } - return (float) result; - } - return 0.0; + return (float)(value ? dd4hep::_toFloatingPoint(_toString(value)).second : 0.0); } double dd4hep::json::_toDouble(const char* value) { - if (value) { - string s = _toString(value); - double result = eval.evaluate(s.c_str()); - if (eval.status() != tools::Evaluator::OK) { - cerr << s << ": "; - eval.print_error(); - throw runtime_error("dd4hep: Severe error during expression evaluation of " + s); - } - return result; - } - return 0.0; + return value ? dd4hep::_toFloatingPoint(_toString(value)).second : 0.0; } void dd4hep::json::_toDictionary(const char* name, const char* value) { - string n = _toString(name).c_str(), v = _toString(value); - size_t idx = v.find("(int)"); - if (idx != string::npos) - v.erase(idx, 5); - while (v[0] == ' ') - v.erase(0, 1); - double result = eval.evaluate(v.c_str()); - if (eval.status() != tools::Evaluator::OK) { - cerr << v << ": "; - eval.print_error(); - throw runtime_error("dd4hep: Severe error during expression evaluation of " + v); - } - eval.setVariable(n.c_str(), result); + dd4hep::_toDictionary(name, value, "number"); } -template <typename T> -void dd4hep::json::_toDictionary(const char* name, T value) { - string item = _toString(value); - _toDictionary(name, item.c_str()); +template <typename T> void dd4hep::json::_toDictionary(const char* name, T value) { + dd4hep::_toDictionary(name, _toString(value), "number"); } template void dd4hep::json::_toDictionary(const char* name, const string& value); @@ -250,24 +186,7 @@ template void dd4hep::json::_toDictionary(const char* name, double value); /// Evaluate string constant using environment stored in the evaluator string dd4hep::json::getEnviron(const string& env) { - size_t id1 = env.find("${"); - size_t id2 = env.rfind("}"); - if ( id1 == string::npos || id2 == string::npos ) { - return ""; - } - else { - string v = env.substr(0,id2+1); - const char* ret = eval.getEnviron(v.c_str()); - if (eval.status() != tools::Evaluator::OK) { - cerr << env << ": "; - eval.print_error(); - throw runtime_error("dd4hep: Severe error during environment lookup of " + env); - } - v = env.substr(0,id1); - v += ret; - v += env.substr(id2+1); - return v; - } + return dd4hep::_getEnviron(env); } /// Copy constructor diff --git a/DDCore/src/XML/XMLElements.cpp b/DDCore/src/XML/XMLElements.cpp index 251c5aa20b1c2b43697ff2f7ed8e6205f9bde965..ab3d8d2e935ea58060e1ca0fec5a9889a17aeb2a 100644 --- a/DDCore/src/XML/XMLElements.cpp +++ b/DDCore/src/XML/XMLElements.cpp @@ -41,13 +41,18 @@ static const size_t INVALID_NODE = ~0U; // Forward declarations namespace dd4hep { - dd4hep::tools::Evaluator& evaluator(); + const dd4hep::tools::Evaluator& evaluator(); + std::pair<int, double> _toInteger(const string& value); + std::pair<int, double> _toFloatingPoint(const string& value); + void _toDictionary(const string& name, const string& value, const string& typ); + string _getEnviron(const string& env); } + // Static storage namespace { bool s_resolve_environment = true; - dd4hep::tools::Evaluator& eval(dd4hep::evaluator()); + const dd4hep::tools::Evaluator& eval(dd4hep::evaluator()); string _checkEnviron(const string& env) { if ( s_resolve_environment ) { string r = getEnviron(env); @@ -290,21 +295,7 @@ string dd4hep::xml::_ptrToString(const void* v, const char* fmt) { long dd4hep::xml::_toLong(const XmlChar* value) { if (value) { string s = _toString(value); - size_t idx = s.find("(int)"); - if (idx != string::npos) - s.erase(idx, 5); - idx = s.find("(long)"); - if (idx != string::npos) - s.erase(idx, 6); - while (s[0] == ' ') - s.erase(0, 1); - double result = eval.evaluate(s.c_str()); - if (eval.status() != tools::Evaluator::OK) { - cerr << s << ": "; - eval.print_error(); - throw runtime_error("dd4hep: Severe error during expression evaluation of " + s); - } - return (long) result; + return dd4hep::_toInteger(s).second; } return -1; } @@ -325,7 +316,7 @@ unsigned int dd4hep::xml::_toUInt(const XmlChar* value) { } bool dd4hep::xml::_toBool(const XmlChar* value) { - if (value) { + if (value) { string s = _toString(value); char c = ::toupper(s[0]); if ( c == 'T' || c == '1' ) return true; @@ -336,48 +327,24 @@ bool dd4hep::xml::_toBool(const XmlChar* value) { } float dd4hep::xml::_toFloat(const XmlChar* value) { - if (value) { + if (value) { string s = _toString(value); - double result = eval.evaluate(s.c_str()); - - if (eval.status() != tools::Evaluator::OK) { - cerr << s << ": "; - eval.print_error(); - throw runtime_error("dd4hep: Severe error during expression evaluation of " + s); - } - return (float) result; + return (float) dd4hep::_toFloatingPoint(s).second; } return 0.0; } double dd4hep::xml::_toDouble(const XmlChar* value) { - if (value) { + if (value) { string s = _toString(value); - double result = eval.evaluate(s.c_str()); - if (eval.status() != tools::Evaluator::OK) { - cerr << s << ": "; - eval.print_error(); - throw runtime_error("dd4hep: Severe error during expression evaluation of " + s); - } - return result; + return dd4hep::_toFloatingPoint(s).second; } return 0.0; } void dd4hep::xml::_toDictionary(const XmlChar* name, const XmlChar* value) { string n = _toString(name).c_str(), v = _toString(value); - size_t idx = v.find("(int)"); - if (idx != string::npos) - v.erase(idx, 5); - while (v[0] == ' ') - v.erase(0, 1); - double result = eval.evaluate(v.c_str()); - if (eval.status() != tools::Evaluator::OK) { - cerr << v << ": "; - eval.print_error(); - throw runtime_error("dd4hep: Severe error during expression evaluation of " + v); - } - eval.setVariable(n.c_str(), result); + dd4hep::_toDictionary(n, v, "number"); } /// Helper function to populate the evaluator dictionary \ingroup DD4HEP_XML @@ -414,24 +381,7 @@ template void dd4hep::xml::_toDictionary(const XmlChar* name, double value); /// Evaluate string constant using environment stored in the evaluator string dd4hep::xml::getEnviron(const string& env) { - size_t id1 = env.find("${"); - size_t id2 = env.rfind("}"); - if ( id1 == string::npos || id2 == string::npos ) { - return ""; - } - else { - string v = env.substr(id1,id2-id1+1); - const char* ret = eval.getEnviron(v.c_str()); - if (eval.status() != tools::Evaluator::OK) { - cerr << env << ": "; - eval.print_error(); - throw runtime_error("dd4hep: Severe error during environment lookup of " + env); - } - v = env.substr(0,id1); - v += ret; - v += env.substr(id2+1); - return v; - } + return dd4hep::_getEnviron(env); } /// Enable/disable environment resolution when parsing strings diff --git a/DDG4/src/Geant4Converter.cpp b/DDG4/src/Geant4Converter.cpp index 4f9462ecf3ca076dfa5da5085209687edcda1054..ce9a0d0e1f76a85c4ed3d67572689e71ee034093 100644 --- a/DDG4/src/Geant4Converter.cpp +++ b/DDG4/src/Geant4Converter.cpp @@ -594,7 +594,7 @@ void* Geant4Converter::handleSolid(const string& name, const TGeoShape* shape) c if ( scal.xx()>0e0 && scal.yy()>0e0 && scal.zz()>0e0 ) solid = new G4ScaledSolid(sh->GetName(), g4solid, scal); else - solid = new G4ReflectedSolid(sh->GetName(), g4solid, scal); + solid = new G4ReflectedSolid(g4solid->GetName()+"_refl", g4solid, scal); } else if (isa == TGeoCompositeShape::Class()) { const TGeoCompositeShape* sh = (const TGeoCompositeShape*) shape; diff --git a/DDParsers/include/Evaluator/Evaluator.h b/DDParsers/include/Evaluator/Evaluator.h index 6c3e107f28c96b05af05717da4537da2fd86b3bd..e509708b6b369e1d344cda1ab287d335f3aa7910 100644 --- a/DDParsers/include/Evaluator/Evaluator.h +++ b/DDParsers/include/Evaluator/Evaluator.h @@ -8,12 +8,11 @@ // For the list of contributors see $DD4hepINSTALL/doc/CREDITS. // //========================================================================== -// -*- C++ -*- -// --------------------------------------------------------------------------- #ifndef EVALUATOR_EVALUATOR_H #define EVALUATOR_EVALUATOR_H +/// C/C++ include files #include <ostream> /// Namespace for the AIDA detector description toolkit @@ -52,18 +51,18 @@ namespace dd4hep { * @see print_error */ enum { - OK, /**< Everything OK */ - WARNING_EXISTING_VARIABLE, /**< Redefinition of existing variable */ - WARNING_EXISTING_FUNCTION, /**< Redefinition of existing function */ - WARNING_BLANK_STRING, /**< Empty input string */ - ERROR_NOT_A_NAME, /**< Not allowed sysmbol in the name of variable or function */ - ERROR_SYNTAX_ERROR, /**< Systax error */ + OK, /**< Everything OK */ + WARNING_EXISTING_VARIABLE, /**< Redefinition of existing variable */ + WARNING_EXISTING_FUNCTION, /**< Redefinition of existing function */ + WARNING_BLANK_STRING, /**< Empty input string */ + ERROR_NOT_A_NAME, /**< Not allowed sysmbol in the name of variable or function */ + ERROR_SYNTAX_ERROR, /**< Systax error */ ERROR_UNPAIRED_PARENTHESIS, /**< Unpaired parenthesis */ - ERROR_UNEXPECTED_SYMBOL, /**< Unexpected sysbol */ - ERROR_UNKNOWN_VARIABLE, /**< Non-existing variable */ - ERROR_UNKNOWN_FUNCTION, /**< Non-existing function */ - ERROR_EMPTY_PARAMETER, /**< Function call has empty parameter */ - ERROR_CALCULATION_ERROR /**< Error during calculation */ + ERROR_UNEXPECTED_SYMBOL, /**< Unexpected sysbol */ + ERROR_UNKNOWN_VARIABLE, /**< Non-existing variable */ + ERROR_UNKNOWN_FUNCTION, /**< Non-existing function */ + ERROR_EMPTY_PARAMETER, /**< Function call has empty parameter */ + ERROR_CALCULATION_ERROR /**< Error during calculation */ }; /** @@ -83,46 +82,47 @@ namespace dd4hep { * operators (==, !=, >, >=, <, <=, &&, ||). * * @param expression input expression. - * @return result of the evaluation. - * @see status - * @see error_position - * @see print_error - */ - double evaluate(const char * expression); - - /** - * Returns status of the last operation with the evaluator. - */ - int status() const; - - /** - * Returns position in the input string where the problem occured. + * @return pair(status,result) of the evaluation. */ - int error_position() const; + std::pair<int,double> evaluate(const std::string& expression) const; /** - * Prints error message if status() is an ERROR. + * Evaluates the arithmetic expression given as character string. + * The expression may consist of numbers, variables and functions + * separated by arithmetic (+, - , /, *, ^, **) and logical + * operators (==, !=, >, >=, <, <=, &&, ||). + * + * @param expression input expression. + * @param Possible stream identifier for error message + * @return pair(status,result) of the evaluation. */ - void print_error(std::ostream& os) const; + std::pair<int,double> evaluate(const std::string& expression, std::ostream& os) const; /** - * Prints error message if status() is an ERROR using std::cerr. + * Adds to the dictionary a string constant + * + * @param name name of the variable. + * @param value value assigned to the variable. */ - void print_error() const; + void setEnviron(const std::string& name, const std::string& value) const; /** - * Adds to the dictionary a string constant + * Lookup the dictionary for a string constant * * @param name name of the variable. - * @param value value assigned to the variable. + * @return pair(status,result) of the evaluation. */ - void setEnviron(const char* name, const char* value); + std::pair<int,std::string> getEnviron(const std::string& name) const; + /** * Lookup the dictionary for a string constant * * @param name name of the variable. + * @param Possible stream identifier for error message + * @return pair(status,result) of the evaluation. */ - const char* getEnviron(const char* name); + std::pair<int,std::string> getEnviron(const std::string& name, std::ostream& os) const; + /** * Adds to the dictionary a variable with given value. * If a variable with such a name already exist in the dictionary, @@ -131,7 +131,7 @@ namespace dd4hep { * @param name name of the variable. * @param value value assigned to the variable. */ - void setVariable(const char * name, double value); + void setVariable(const std::string& name, double value) const; /** * Adds to the dictionary a variable with an arithmetic expression @@ -142,67 +142,7 @@ namespace dd4hep { * @param name name of the variable. * @param expression arithmetic expression. */ - void setVariable(const char * name, const char * expression); - - /** - * Adds to the dictionary a function without parameters. - * If such a function already exist in the dictionary, - * then status will be set to WARNING_EXISTING_FUNCTION. - * - * @param name function name. - * @param fun pointer to the real function in the user code. - */ - void setFunction(const char * name, double (*fun)()); - - /** - * Adds to the dictionary a function with one parameter. - * If such a function already exist in the dictionary, - * then status will be set to WARNING_EXISTING_FUNCTION. - * - * @param name function name. - * @param fun pointer to the real function in the user code. - */ - void setFunction(const char * name, double (*fun)(double)); - - /** - * Adds to the dictionary a function with two parameters. - * If such a function already exist in the dictionary, - * then status will be set to WARNING_EXISTING_FUNCTION. - * - * @param name function name. - * @param fun pointer to the real function in the user code. - */ - void setFunction(const char * name, double (*fun)(double, double)); - - /** - * Adds to the dictionary a function with three parameters. - * If such a function already exist in the dictionary, - * then status will be set to WARNING_EXISTING_FUNCTION. - * - * @param name function name. - * @param fun pointer to the real function in the user code. - */ - void setFunction(const char * name, double (*fun)(double, double, double)); - - /** - * Adds to the dictionary a function with four parameters. - * If such a function already exist in the dictionary, - * then status will be set to WARNING_EXISTING_FUNCTION. - * - * @param name function name. - * @param fun pointer to the real function in the user code. - */ - void setFunction(const char * name, double (*fun)(double, double, double, double)); - - /** - * Adds to the dictionary a function with five parameters. - * If such a function already exist in the dictionary, - * then status will be set to WARNING_EXISTING_FUNCTION. - * - * @param name function name. - * @param fun pointer to the real function in the user code. - */ - void setFunction(const char * name, double (*fun)(double, double, double, double, double)); + void setVariable(const std::string& name, const std::string& expression) const; /** * Finds the variable in the dictionary. @@ -210,75 +150,14 @@ namespace dd4hep { * @param name name of the variable. * @return true if such a variable exists, false otherwise. */ - bool findVariable(const char * name) const; + bool findVariable(const std::string& name) const; - /** - * Finds the function in the dictionary. - * - * @param name name of the function to be unset. - * @param npar number of parameters of the function. - * @return true if such a function exists, false otherwise. - */ - bool findFunction(const char * name, int npar) const; - - /** - * Removes the variable from the dictionary. - * - * @param name name of the variable. - */ - void removeVariable(const char * name); - - /** - * Removes the function from the dictionary. - * - * @param name name of the function to be unset. - * @param npar number of parameters of the function. - */ - void removeFunction(const char * name, int npar); - - /** - * Clear all settings. - */ - void clear(); - - /** - * Sets standard mathematical functions and constants. - */ - void setStdMath(); - - /** - * Sets system of units. Default is the SI system of units. - * To set the CGS (Centimeter-Gram-Second) system of units - * one should call: - * setSystemOfUnits(100., 1000., 1.0, 1.0, 1.0, 1.0, 1.0); - * - * To set system of units accepted in the GEANT4 simulation toolkit - * one should call: - * @code - * setSystemOfUnits(1.e+3, 1./1.60217733e-25, 1.e+9, 1./1.60217733e-10, - * 1.0, 1.0, 1.0); - * @endcode - * - * The basic units in GEANT4 are: - * @code - * millimeter (millimeter = 1.) - * nanosecond (nanosecond = 1.) - * Mega electron Volt (MeV = 1.) - * positron charge (eplus = 1.) - * degree Kelvin (kelvin = 1.) - * the amount of substance (mole = 1.) - * luminous intensity (candela = 1.) - * radian (radian = 1.) - * steradian (steradian = 1.) - * @endcode - */ - void setSystemOfUnits(double meter = 1.0, double kilogram = 1.0, double second = 1.0, double ampere = 1.0, double kelvin = - 1.0, double mole = 1.0, double candela = 1.0, double radians = 1.0 ); + class Object; + Object* object = 0; // private data private: - void * p; // private data - Evaluator(const Evaluator &); // copy constructor is not allowed - Evaluator & operator=(const Evaluator &); // assignment is not allowed + Evaluator(const Evaluator &) = delete; // copy constructor is not allowed + Evaluator & operator=(const Evaluator &) = delete; // assignment is not allowed }; } // namespace tools diff --git a/DDParsers/include/Evaluator/detail/Evaluator.h b/DDParsers/include/Evaluator/detail/Evaluator.h new file mode 100644 index 0000000000000000000000000000000000000000..56387b849ec715cfa70b9c6b1cc8e59f380ce736 --- /dev/null +++ b/DDParsers/include/Evaluator/detail/Evaluator.h @@ -0,0 +1,279 @@ +//========================================================================== +// AIDA Detector description implementation +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +//========================================================================== +// -*- C++ -*- +// --------------------------------------------------------------------------- + +#ifndef EVALUATOR_DETAIL_EVALUATOROBJECT_H +#define EVALUATOR_DETAIL_EVALUATOROBJECT_H + +#include <ostream> + +/// Namespace for the AIDA detector description toolkit +namespace dd4hep { + + /// Namespace containing XML tools. + namespace tools { + + /// Evaluator of arithmetic expressions with an extendable dictionary. + /** + * Taken from CLHEP 1.9.2.1 + * + * Example: + * @code + * #include "XmlTools/Evaluator.h" + * XmlTools::Evaluator eval; + * eval.setStdMath(); + * double res = eval.evaluate("sin(30*degree)"); + * if (eval.status() != XmlTools::Evaluator::OK) eval.print_error(); + * @endcode + * + * @author Evgeni Chernyaev <Evgueni.Tcherniaev@cern.ch> + * @ingroup evaluator + */ + class Evaluator::Object { + public: + + /** + * List of possible statuses. + * Status of the last operation can be obtained with status(). + * In case if status() is an ERROR the corresponding error message + * can be printed with print_error(). + * + * @see status + * @see error_position + * @see print_error + */ + + /** + * Constructor. + */ + Object(); + + /** + * Destructor. + */ + ~Object(); + + /** + * Evaluates the arithmetic expression given as character string. + * The expression may consist of numbers, variables and functions + * separated by arithmetic (+, - , /, *, ^, **) and logical + * operators (==, !=, >, >=, <, <=, &&, ||). + * + * @param expression input expression. + * @return result of the evaluation. + * @see status + * @see error_position + * @see print_error + */ + double evaluate(const char * expression); + + /** + * Returns status of the last operation with the evaluator. + */ + int status() const; + + /** + * Returns position in the input string where the problem occured. + */ + int error_position() const; + + /** + * Prints error message if status() is an ERROR. + */ + void print_error(std::ostream& os) const; + + /** + * Prints error message if status() is an ERROR using std::cerr. + */ + void print_error() const; + + /** + * Adds to the dictionary a string constant + * + * @param name name of the variable. + * @param value value assigned to the variable. + */ + void setEnviron(const char* name, const char* value); + + /** + * Lookup the dictionary for a string constant + * + * @param name name of the variable. + */ + const char* getEnviron(const char* name); + + /** + * Adds to the dictionary a variable with given value. + * If a variable with such a name already exist in the dictionary, + * then status will be set to WARNING_EXISTING_VARIABLE. + * + * @param name name of the variable. + * @param value value assigned to the variable. + */ + void setVariable(const char * name, double value); + + /** + * Adds to the dictionary a variable with an arithmetic expression + * assigned to it. + * If a variable with such a name already exist in the dictionary, + * then status will be set to WARNING_EXISTING_VARIABLE. + * + * @param name name of the variable. + * @param expression arithmetic expression. + */ + void setVariable(const char * name, const char * expression); + + /** + * Adds to the dictionary a function without parameters. + * If such a function already exist in the dictionary, + * then status will be set to WARNING_EXISTING_FUNCTION. + * + * @param name function name. + * @param fun pointer to the real function in the user code. + */ + void setFunction(const char * name, double (*fun)()); + + /** + * Adds to the dictionary a function with one parameter. + * If such a function already exist in the dictionary, + * then status will be set to WARNING_EXISTING_FUNCTION. + * + * @param name function name. + * @param fun pointer to the real function in the user code. + */ + void setFunction(const char * name, double (*fun)(double)); + + /** + * Adds to the dictionary a function with two parameters. + * If such a function already exist in the dictionary, + * then status will be set to WARNING_EXISTING_FUNCTION. + * + * @param name function name. + * @param fun pointer to the real function in the user code. + */ + void setFunction(const char * name, double (*fun)(double, double)); + + /** + * Adds to the dictionary a function with three parameters. + * If such a function already exist in the dictionary, + * then status will be set to WARNING_EXISTING_FUNCTION. + * + * @param name function name. + * @param fun pointer to the real function in the user code. + */ + void setFunction(const char * name, double (*fun)(double, double, double)); + + /** + * Adds to the dictionary a function with four parameters. + * If such a function already exist in the dictionary, + * then status will be set to WARNING_EXISTING_FUNCTION. + * + * @param name function name. + * @param fun pointer to the real function in the user code. + */ + void setFunction(const char * name, double (*fun)(double, double, double, double)); + + /** + * Adds to the dictionary a function with five parameters. + * If such a function already exist in the dictionary, + * then status will be set to WARNING_EXISTING_FUNCTION. + * + * @param name function name. + * @param fun pointer to the real function in the user code. + */ + void setFunction(const char * name, double (*fun)(double, double, double, double, double)); + + /** + * Finds the variable in the dictionary. + * + * @param name name of the variable. + * @return true if such a variable exists, false otherwise. + */ + bool findVariable(const char * name) const; + + /** + * Finds the function in the dictionary. + * + * @param name name of the function to be unset. + * @param npar number of parameters of the function. + * @return true if such a function exists, false otherwise. + */ + bool findFunction(const char * name, int npar) const; + + /** + * Removes the variable from the dictionary. + * + * @param name name of the variable. + */ + void removeVariable(const char * name); + + /** + * Removes the function from the dictionary. + * + * @param name name of the function to be unset. + * @param npar number of parameters of the function. + */ + void removeFunction(const char * name, int npar); + + /** + * Clear all settings. + */ + void clear(); + + /** + * Sets standard mathematical functions and constants. + */ + void setStdMath(); + + /** + * Sets system of units. Default is the SI system of units. + * To set the CGS (Centimeter-Gram-Second) system of units + * one should call: + * setSystemOfUnits(100., 1000., 1.0, 1.0, 1.0, 1.0, 1.0); + * + * To set system of units accepted in the GEANT4 simulation toolkit + * one should call: + * @code + * setSystemOfUnits(1.e+3, 1./1.60217733e-25, 1.e+9, 1./1.60217733e-10, + * 1.0, 1.0, 1.0); + * @endcode + * + * The basic units in GEANT4 are: + * @code + * millimeter (millimeter = 1.) + * nanosecond (nanosecond = 1.) + * Mega electron Volt (MeV = 1.) + * positron charge (eplus = 1.) + * degree Kelvin (kelvin = 1.) + * the amount of substance (mole = 1.) + * luminous intensity (candela = 1.) + * radian (radian = 1.) + * steradian (steradian = 1.) + * @endcode + */ + void setSystemOfUnits(double meter = 1.0, double kilogram = 1.0, double second = 1.0, double ampere = 1.0, double kelvin = + 1.0, double mole = 1.0, double candela = 1.0, double radians = 1.0 ); + + + void lock(); + void unlock(); + + private: + void * p; // private data + Object(const Object &); // copy constructor is not allowed + Object & operator=(const Object &); // assignment is not allowed + }; + + } // namespace tools +} // namespace dd4hep + +#endif // EVALUATOR_DETAIL_EVALUATOROBJECT_H diff --git a/DDParsers/src/Evaluator/Evaluator.cpp b/DDParsers/src/Evaluator/Evaluator.cpp index 6e9898731a21fc351b141843709c8b91122ec573..48ca552292ac214da99eb538d6f2b2cf78954707 100644 --- a/DDParsers/src/Evaluator/Evaluator.cpp +++ b/DDParsers/src/Evaluator/Evaluator.cpp @@ -3,17 +3,19 @@ // --------------------------------------------------------------------------- #include "Evaluator/Evaluator.h" +#include "Evaluator/detail/Evaluator.h" #include <iostream> #include <cmath> // for pow() -#include "stack.src" -#include "string.src" -#include "hash_map.src" #include <sstream> -#include <cstring> +#include <mutex> #include <cctype> #include <cerrno> +#include <cstring> #include <cstdlib> // for strtod() +#include "stack.src" +#include "string.src" +#include "hash_map.src" // Disable some diagnostics, which we know, but need to ignore #if defined(__GNUC__) && !defined(__APPLE__) && !defined(__llvm__) @@ -59,11 +61,12 @@ namespace { /// Internal expression evaluator helper class struct Struct { - dic_type theDictionary; - pchar theExpression; - pchar thePosition; - int theStatus; - double theResult; + dic_type theDictionary; + pchar theExpression; + pchar thePosition; + int theStatus; + double theResult; + std::mutex theLock; }; /// Internal expression evaluator helper union @@ -610,7 +613,7 @@ static void setItem(const char * prefix, const char * name, using namespace dd4hep::tools; //--------------------------------------------------------------------------- -Evaluator::Evaluator() { +Evaluator::Object::Object() { Struct * s = new Struct(); p = (void *) s; s->theExpression = 0; @@ -620,17 +623,17 @@ Evaluator::Evaluator() { } //--------------------------------------------------------------------------- -Evaluator::~Evaluator() { +Evaluator::Object::~Object() { Struct * s = reinterpret_cast<Struct*>(p); if (s->theExpression != 0) { delete[] s->theExpression; s->theExpression = 0; } - delete reinterpret_cast<Struct*>(p); + delete s; } //--------------------------------------------------------------------------- -double Evaluator::evaluate(const char * expression) { +double Evaluator::Object::evaluate(const char * expression) { Struct * s = reinterpret_cast<Struct*>(p); if (s->theExpression != 0) { delete[] s->theExpression; } s->theExpression = 0; @@ -650,17 +653,17 @@ double Evaluator::evaluate(const char * expression) { } //--------------------------------------------------------------------------- -int Evaluator::status() const { +int Evaluator::Object::status() const { return (reinterpret_cast<Struct*>(p))->theStatus; } //--------------------------------------------------------------------------- -int Evaluator::error_position() const { +int Evaluator::Object::error_position() const { return (reinterpret_cast<Struct*>(p))->thePosition - (reinterpret_cast<Struct*>(p))->theExpression; } //--------------------------------------------------------------------------- -void Evaluator::print_error() const { +void Evaluator::Object::print_error() const { std::stringstream str; print_error(str); if ( str.str().empty() ) return; @@ -668,8 +671,8 @@ void Evaluator::print_error() const { } //--------------------------------------------------------------------------- -void Evaluator::print_error(std::ostream& os) const { - static char prefix[] = "Evaluator : "; +void Evaluator::Object::print_error(std::ostream& os) const { + static char prefix[] = "Evaluator::Object : "; Struct * s = reinterpret_cast<Struct*>(p); const char* opt = (s->thePosition ? s->thePosition : ""); switch (s->theStatus) { @@ -703,7 +706,7 @@ void Evaluator::print_error(std::ostream& os) const { } //--------------------------------------------------------------------------- -void Evaluator::setEnviron(const char* name, const char* value) { +void Evaluator::Object::setEnviron(const char* name, const char* value) { Struct* s = reinterpret_cast<Struct*>(p); string prefix = "${"; string item_name = prefix + string(name) + string("}"); @@ -727,7 +730,7 @@ void Evaluator::setEnviron(const char* name, const char* value) { } } //--------------------------------------------------------------------------- -const char* Evaluator::getEnviron(const char* name) { +const char* Evaluator::Object::getEnviron(const char* name) { Struct* s = reinterpret_cast<Struct*>(p); string item_name = name; //std::cout << " ++++++++++++++++++++++++++++ Try to resolve env:" << name << std::endl; @@ -750,45 +753,45 @@ const char* Evaluator::getEnviron(const char* name) { } //--------------------------------------------------------------------------- -void Evaluator::setVariable(const char * name, double value) +void Evaluator::Object::setVariable(const char * name, double value) { setItem("", name, Item(value), reinterpret_cast<Struct*>(p)); } -void Evaluator::setVariable(const char * name, const char * expression) +void Evaluator::Object::setVariable(const char * name, const char * expression) { setItem("", name, Item(expression), reinterpret_cast<Struct*>(p)); } //--------------------------------------------------------------------------- -void Evaluator::setFunction(const char * name,double (*fun)()) { +void Evaluator::Object::setFunction(const char * name,double (*fun)()) { FCN fcn(fun); setItem("0", name, Item(fcn.ptr), reinterpret_cast<Struct*>(p)); } -void Evaluator::setFunction(const char * name,double (*fun)(double)) { +void Evaluator::Object::setFunction(const char * name,double (*fun)(double)) { FCN fcn(fun); setItem("1", name, Item(fcn.ptr), reinterpret_cast<Struct*>(p)); } -void Evaluator::setFunction(const char * name, double (*fun)(double,double)) { +void Evaluator::Object::setFunction(const char * name, double (*fun)(double,double)) { FCN fcn(fun); setItem("2", name, Item(fcn.ptr), reinterpret_cast<Struct*>(p)); } -void Evaluator::setFunction(const char * name, double (*fun)(double,double,double)) { +void Evaluator::Object::setFunction(const char * name, double (*fun)(double,double,double)) { FCN fcn(fun); setItem("3", name, Item(fcn.ptr), reinterpret_cast<Struct*>(p)); } -void Evaluator::setFunction(const char * name, double (*fun)(double,double,double,double)) { +void Evaluator::Object::setFunction(const char * name, double (*fun)(double,double,double,double)) { FCN fcn(fun); setItem("4", name, Item(fcn.ptr), reinterpret_cast<Struct*>(p)); } -void Evaluator::setFunction(const char * name, double (*fun)(double,double,double,double,double)) { +void Evaluator::Object::setFunction(const char * name, double (*fun)(double,double,double,double,double)) { FCN fcn(fun); setItem("5", name, Item(fcn.ptr), reinterpret_cast<Struct*>(p)); } //--------------------------------------------------------------------------- -bool Evaluator::findVariable(const char * name) const { +bool Evaluator::Object::findVariable(const char * name) const { if (name == 0 || *name == '\0') return false; const char * pointer; int n; REMOVE_BLANKS; if (n == 0) return false; @@ -799,7 +802,7 @@ bool Evaluator::findVariable(const char * name) const { } //--------------------------------------------------------------------------- -bool Evaluator::findFunction(const char * name, int npar) const { +bool Evaluator::Object::findFunction(const char * name, int npar) const { if (name == 0 || *name == '\0') return false; if (npar < 0 || npar > MAX_N_PAR) return false; const char * pointer; int n; REMOVE_BLANKS; @@ -810,7 +813,7 @@ bool Evaluator::findFunction(const char * name, int npar) const { } //--------------------------------------------------------------------------- -void Evaluator::removeVariable(const char * name) { +void Evaluator::Object::removeVariable(const char * name) { if (name == 0 || *name == '\0') return; const char * pointer; int n; REMOVE_BLANKS; if (n == 0) return; @@ -819,7 +822,7 @@ void Evaluator::removeVariable(const char * name) { } //--------------------------------------------------------------------------- -void Evaluator::removeFunction(const char * name, int npar) { +void Evaluator::Object::removeFunction(const char * name, int npar) { if (name == 0 || *name == '\0') return; if (npar < 0 || npar > MAX_N_PAR) return; const char * pointer; int n; REMOVE_BLANKS; @@ -829,11 +832,106 @@ void Evaluator::removeFunction(const char * name, int npar) { } //--------------------------------------------------------------------------- -void Evaluator::clear() { +void Evaluator::Object::lock() { Struct * s = reinterpret_cast<Struct*>(p); - s->theDictionary.clear(); - s->theExpression = 0; - s->thePosition = 0; - s->theStatus = OK; - s->theResult = 0.0; + s->theLock.lock(); +} + +//--------------------------------------------------------------------------- +void Evaluator::Object::unlock() { + Struct * s = reinterpret_cast<Struct*>(p); + s->theLock.unlock(); +} + +//--------------------------------------------------------------------------- +Evaluator::Evaluator() { + object = new Object(); +} + +//--------------------------------------------------------------------------- +Evaluator::~Evaluator() { + delete object; +} + +//--------------------------------------------------------------------------- +std::pair<int,double> Evaluator::evaluate(const std::string& expression) const { + object->lock(); + double result = object->evaluate(expression.c_str()); + int status = object->status(); + object->unlock(); + return std::make_pair(status,result); +} + +//--------------------------------------------------------------------------- +std::pair<int,double> Evaluator::evaluate(const std::string& expression, std::ostream& os) const { + object->lock(); + double result = object->evaluate(expression.c_str()); + int status = object->status(); + if ( status != OK ) { + object->print_error(os); + } + object->unlock(); + return std::make_pair(status,result); +} + +//--------------------------------------------------------------------------- +void Evaluator::setEnviron(const std::string& name, const std::string& value) const { + object->lock(); + object->setEnviron(name.c_str(), value.c_str()); + object->unlock(); +} + +//--------------------------------------------------------------------------- +std::pair<int,std::string> Evaluator::getEnviron(const std::string& name) const { + const char* env = nullptr; + std::pair<int,std::string> result; + object->lock(); + env = object->getEnviron(name.c_str()); + result.first = object->status(); + if ( env ) result.second = env; + object->unlock(); + return result; +} + +//--------------------------------------------------------------------------- +std::pair<int,std::string> Evaluator::getEnviron(const std::string& name, std::ostream& os) const { + const char* env = nullptr; + std::pair<int,std::string> result; + object->lock(); + env = object->getEnviron(name.c_str()); + result.first = object->status(); + if ( env ) { + result.second = env; + } + if ( result.first != OK ) { + object->print_error(os); + } + object->unlock(); + return result; +} + +//--------------------------------------------------------------------------- +void Evaluator::setVariable(const std::string& name, double value) const { + object->lock(); + object->setVariable(name.c_str(), value); + object->unlock(); +} + +//--------------------------------------------------------------------------- +void Evaluator::setVariable(const std::string& name, const std::string& value) const { + object->lock(); + object->setVariable(name.c_str(), value.c_str()); + object->unlock(); } + +//--------------------------------------------------------------------------- +bool Evaluator::findVariable(const std::string& name) const { + bool ret; + object->lock(); + ret = object->findVariable(name.c_str()); + object->unlock(); + return ret; +} + + + diff --git a/DDParsers/src/Evaluator/ExpressionEvaluator.cpp b/DDParsers/src/Evaluator/ExpressionEvaluator.cpp index 577daa2db72b058d1a24e56c7b178bf9d552936a..098c3adb27620087b69d62179b71836dd29c0848 100644 --- a/DDParsers/src/Evaluator/ExpressionEvaluator.cpp +++ b/DDParsers/src/Evaluator/ExpressionEvaluator.cpp @@ -12,20 +12,29 @@ //========================================================================== #include "Parsers/config.h" #include "Evaluator/Evaluator.h" +#include "Evaluator/detail/Evaluator.h" #include "Evaluator/DD4hepUnits.h" + namespace units = dd4hep; namespace { + void _init(dd4hep::tools::Evaluator& e) { // Initialize numerical expressions parser with the standard math functions // and the system of units used by Gaudi (Geant4) - e.setStdMath(); + e.object->lock(); + e.object->setStdMath(); + e.object->unlock(); } + void _cgsUnits(dd4hep::tools::Evaluator& e) { // =================================================================================== // CGS units - e.setSystemOfUnits(100., 1000., 1.0, 1.0, 1.0, 1.0, 1.0); + e.object->lock(); + e.object->setSystemOfUnits(100., 1000., 1.0, 1.0, 1.0, 1.0, 1.0); + e.object->unlock(); } + void _tgeoUnits(dd4hep::tools::Evaluator& e) { // =================================================================================== // DDG4 units (TGeo) 1 sec = 10^9 [nsec] @@ -35,28 +44,33 @@ namespace { // e.setSystemOfUnits(1.e+2, 1./1.60217733e-6, 1.0, 1./1.60217733e-19, 1.0, 1.0, 1.0); // use the units as defined in DD4hepUnits.h: - e.setSystemOfUnits( units::meter, - units::kilogram, - units::second, - units::ampere, - units::kelvin, - units::mole, - units::candela, - units::rad ); + e.object->lock(); + e.object->setSystemOfUnits( units::meter, + units::kilogram, + units::second, + units::ampere, + units::kelvin, + units::mole, + units::candela, + units::rad ); + e.object->unlock(); } + void _g4Units(dd4hep::tools::Evaluator& e) { // =================================================================================== // Geant4 units // Geant4: kilogram = joule*s*s/(m*m) 1/e_SI * 1e-6 * 1e9 1e9 / 1e3 / 1e3 = 1. / 1.60217733e-25 - e.setSystemOfUnits(1.e+3, 1./1.60217733e-25, 1.e+9, 1./1.60217733e-10, 1.0, 1.0, 1.0); + e.object->lock(); + e.object->setSystemOfUnits(1.e+3, 1./1.60217733e-25, 1.e+9, 1./1.60217733e-10, 1.0, 1.0, 1.0); + e.object->unlock(); } } /// Namespace for the AIDA detector description toolkit namespace dd4hep { - tools::Evaluator& evaluator() { - static tools::Evaluator* e = 0; + const tools::Evaluator& evaluator() { + static const tools::Evaluator* e = 0; if ( !e ) { static tools::Evaluator ev; _init(ev); @@ -67,8 +81,8 @@ namespace dd4hep { } /// Access to G4 evaluator. Note: Uses Geant4 units! - tools::Evaluator& g4Evaluator() { - static tools::Evaluator* e = 0; + const tools::Evaluator& g4Evaluator() { + static const tools::Evaluator* e = 0; if ( !e ) { static tools::Evaluator ev; _init(ev); @@ -79,8 +93,8 @@ namespace dd4hep { } /// Access to G4 evaluator. Note: Uses cgs units! - tools::Evaluator& cgsEvaluator() { - static tools::Evaluator* e = 0; + const tools::Evaluator& cgsEvaluator() { + static const tools::Evaluator* e = 0; if ( !e ) { static tools::Evaluator ev; _init(ev); diff --git a/DDParsers/src/Evaluator/setStdMath.cpp b/DDParsers/src/Evaluator/setStdMath.cpp index 3d353983c6d56922fe18f85f55d8fc7f812a5640..e5fecd2556800a41ad47b185fe2f52c9ef3dd57e 100644 --- a/DDParsers/src/Evaluator/setStdMath.cpp +++ b/DDParsers/src/Evaluator/setStdMath.cpp @@ -2,6 +2,7 @@ // ---------------------------------------------------------------------- #include "Evaluator/Evaluator.h" +#include "Evaluator/detail/Evaluator.h" #include <limits> #ifdef DD4HEP_NONE @@ -68,7 +69,7 @@ namespace dd4hep { namespace tools { - void Evaluator::setStdMath() { + void Evaluator::Object::setStdMath() { // S E T S T A N D A R D C O N S T A N T S diff --git a/DDParsers/src/Evaluator/setSystemOfUnits.cpp b/DDParsers/src/Evaluator/setSystemOfUnits.cpp index 5bf5a5fff0556da483b3407b2cb5a313bee38484..b1308cc95919af4bfab743367c0906bdb541b1ca 100644 --- a/DDParsers/src/Evaluator/setSystemOfUnits.cpp +++ b/DDParsers/src/Evaluator/setSystemOfUnits.cpp @@ -2,20 +2,21 @@ // ---------------------------------------------------------------------- #include "Evaluator/Evaluator.h" +#include "Evaluator/detail/Evaluator.h" /// Namespace for the AIDA detector description toolkit namespace dd4hep { namespace tools { - void Evaluator::setSystemOfUnits(double meter, - double kilogram, - double second, - double ampere, - double kelvin, - double mole, - double candela, - double radians) + void Evaluator::Object::setSystemOfUnits(double meter, + double kilogram, + double second, + double ampere, + double kelvin, + double mole, + double candela, + double radians) { const double kilo_ = 1.e+03; // chilioi (Greek) "thousand" const double mega_ = 1.e+06; // megas (Greek) "large" diff --git a/DDParsers/src/Spirit/Evaluators.cpp b/DDParsers/src/Spirit/Evaluators.cpp index 43cfc137dfba230f5b12d41934f511e62f3231ba..c88e40ebc4e1a6cd0267c485c7798bf3ec616c9c 100755 --- a/DDParsers/src/Spirit/Evaluators.cpp +++ b/DDParsers/src/Spirit/Evaluators.cpp @@ -30,14 +30,15 @@ #include "Evaluator/Evaluator.h" // C/C++ include files +#include <sstream> #include <iostream> #include <stdexcept> namespace dd4hep { - dd4hep::tools::Evaluator& g4Evaluator(); + const dd4hep::tools::Evaluator& g4Evaluator(); } namespace { - dd4hep::tools::Evaluator& eval(dd4hep::g4Evaluator()); + const dd4hep::tools::Evaluator& eval(dd4hep::g4Evaluator()); } //============================================================================== @@ -47,22 +48,22 @@ namespace dd4hep { namespace Parsers { } template <> double evaluate_string<double>(const std::string& value) { - double result = eval.evaluate(value.c_str()); - if (eval.status() != tools::Evaluator::OK) { - std::cerr << value << ": "; - eval.print_error(); + std::stringstream err; + auto result = eval.evaluate(value, err); + if (result.first != tools::Evaluator::OK) { + std::cerr << value << ": " << err.str() << std::endl; throw std::runtime_error("dd4hep::Properties: Severe error during expression evaluation of " + value); } - return result; + return result.second; } template <> float evaluate_string<float>(const std::string& value) { - double result = eval.evaluate(value.c_str()); - if (eval.status() != tools::Evaluator::OK) { - std::cerr << value << ": "; - eval.print_error(); + std::stringstream err; + auto result = eval.evaluate(value, err); + if (result.first != tools::Evaluator::OK) { + std::cerr << value << ": " << err.str() << std::endl; throw std::runtime_error("dd4hep::Properties: Severe error during expression evaluation of " + value); } - return (float) result; + return (float) result.second; } } }