--- /dev/null
+// Copyright (C) 2007-2008 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#ifndef __INTERPKERNELEXPREVALDEFINES_HXX__
+#define __INTERPKERNELEXPREVALDEFINES_HXX__
+
+//export symbols
+#ifdef WIN32
+# if defined INTERPKERNELEXPREVAL_EXPORTS || defined interpkernelexpreval_EXPORTS
+# define INTERPKERNELEXPREVAL_EXPORT __declspec(dllexport)
+# else
+# define INTERPKERNELEXPREVAL_EXPORT __declspec(dllimport)
+# endif
+#else
+# define INTERPKERNELEXPREVAL_EXPORT
+#endif
+
+#endif
--- /dev/null
+#include "InterpKernelExprParser.hxx"
+#include "InterpKernelValue.hxx"
+
+#include <cctype>
+#include <sstream>
+#include <vector>
+#include <iterator>
+#include <algorithm>
+
+using namespace INTERP_KERNEL;
+
+const char LeafExprVar::END_OF_RECOGNIZED_VAR[]="Vec";
+
+const char ExprParser::WHITE_SPACES[]=" \n";
+
+const char ExprParser::EXPR_PARSE_ERR_MSG[]="Invalid expression detected : ";
+
+LeafExpr *LeafExpr::buildInstanceFrom(const std::string& expr) throw(INTERP_KERNEL::Exception)
+{
+ std::istringstream stream;
+ stream.str(expr);
+ double val;
+ stream >> val;
+ if(!stream.fail())
+ if(stream.eof())
+ return new LeafExprVal(val);
+ else
+ {
+ std::ostringstream errMsg;
+ char MSGTYP6[]="Error following expression is not consedered as a double value : ";
+ errMsg << MSGTYP6 << expr;
+ throw INTERP_KERNEL::Exception(errMsg.str().c_str());
+ }
+ else
+ return new LeafExprVar(expr);
+}
+
+LeafExpr::~LeafExpr()
+{
+}
+
+LeafExprVal::LeafExprVal(double value):_value(value)
+{
+}
+
+LeafExprVal::~LeafExprVal()
+{
+}
+
+void LeafExprVal::fillValue(Value *val) const throw(INTERP_KERNEL::Exception)
+{
+ val->setDouble(_value);
+}
+
+LeafExprVar::LeafExprVar(const std::string& var):_fast_pos(-1),_var_name(var)
+{
+}
+
+void LeafExprVar::fillValue(Value *val) const throw(INTERP_KERNEL::Exception)
+{
+ val->setVarname(_fast_pos,_var_name);
+}
+
+void LeafExprVar::prepareExprEvaluation(const std::vector<std::string>& vars) const throw(INTERP_KERNEL::Exception)
+{
+ std::vector<std::string>::const_iterator iter=std::find(vars.begin(),vars.end(),_var_name);
+ if(iter==vars.end())
+ {
+ if(!isRecognizedKeyVar(_var_name,_fast_pos))
+ {
+ std::ostringstream oss; oss << "Var : " << _var_name << " not in : ";
+ std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss,", "));
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ return;
+ }
+ _fast_pos=iter-vars.begin();
+}
+
+void LeafExprVar::prepareExprEvaluationVec() const throw(INTERP_KERNEL::Exception)
+{
+ if(!isRecognizedKeyVar(_var_name,_fast_pos))
+ _fast_pos=-2;
+}
+
+bool LeafExprVar::isRecognizedKeyVar(const std::string& var, int& pos)
+{
+ if(var.length()!=sizeof(END_OF_RECOGNIZED_VAR))
+ return false;
+ std::string end=var.substr(1);
+ if(end!=END_OF_RECOGNIZED_VAR)
+ return false;
+ char first=var[0];
+ if(first<'I' || first>'Z')
+ return false;
+ pos=-7-(first-'I');
+ return true;
+}
+
+LeafExprVar::~LeafExprVar()
+{
+}
+
+ExprParser::ExprParser(const char *expr):_is_parsed(false),_leaf(0),_is_parsing_ok(false),_expr(expr)
+{
+}
+
+//! For \b NOT null terminated strings coming from FORTRAN.
+ExprParser::ExprParser(const char *expr, int lgth):_is_parsed(false),_leaf(0),_is_parsing_ok(false)
+{
+ _expr=buildStringFromFortran(expr,lgth);
+}
+
+ExprParser::~ExprParser()
+{
+ delete _leaf;
+ releaseFunctions();
+}
+
+std::size_t ExprParser::findCorrespondingOpenBracket(const std::string& expr, std::size_t posOfCloseBracket)
+{
+ int level=0;
+ for(std::size_t iter=posOfCloseBracket-1;iter>=0;iter--)
+ if(expr[iter]==')')
+ level++;
+ else if(expr[iter]=='(')
+ {
+ if(level==0)
+ return iter;
+ else
+ level--;
+ }
+ return std::string::npos;
+}
+
+std::string ExprParser::buildStringFromFortran(const char *expr, int lgth)
+{
+ std::string ret(expr,lgth);
+ std::string whiteSpaces(WHITE_SPACES);
+ std::size_t found=ret.find_last_not_of(whiteSpaces);
+ if (found!=std::string::npos)
+ ret.erase(found+1);
+ else
+ ret.clear();//ret is all whitespace
+ return ret;
+}
+
+std::string ExprParser::deleteWhiteSpaces(const std::string& expr)
+{
+ std::string ret(expr);
+ std::string whiteSpaces(WHITE_SPACES);
+ std::size_t where1=0,where2=0;
+ while(where2!=std::string::npos && where1!=std::string::npos)
+ {
+ where1=ret.find_first_of(whiteSpaces.c_str(),where1,whiteSpaces.length());
+ if(where1!=std::string::npos)
+ {
+ where2=ret.find_first_not_of(whiteSpaces,where1);
+ if(where2!=std::string::npos)
+ ret.erase(ret.begin()+where1,ret.begin()+where2);
+ else
+ ret.erase(ret.begin()+where1,ret.end());
+ }
+ }
+ return ret;
+}
+
+void ExprParser::parse() throw(INTERP_KERNEL::Exception)
+{
+ _is_parsed=true;
+ _is_parsing_ok=false;
+ _sub_expr.clear();
+ releaseFunctions();
+ if(!_expr.empty())
+ {
+ checkBracketsParity();
+ if(!simplify())
+ parseDeeper();
+ }
+ _is_parsing_ok=true;
+}
+
+double ExprParser::evaluate() const throw(INTERP_KERNEL::Exception)
+{
+ Value *gen=new ValueDouble;
+ ValueDouble *res=(ValueDouble *)evaluateLowLev(gen);
+ delete gen;
+ double ret=res->getData();
+ delete res;
+ return ret;
+}
+
+DecompositionInUnitBase ExprParser::evaluateUnit() const throw(INTERP_KERNEL::Exception)
+{
+ Value *gen=new ValueUnit;
+ ValueUnit *res=0;
+ try
+ {
+ res=(ValueUnit *)evaluateLowLev(gen);
+ }
+ catch(INTERP_KERNEL::Exception& e)
+ {
+ delete gen;
+ throw e;
+ }
+ delete gen;
+ DecompositionInUnitBase ret=res->getData();
+ delete res;
+ return ret;
+}
+
+void ExprParser::evaluateExpr(int szOfOutParam, double *outParam, const double *inParam) const throw(INTERP_KERNEL::Exception)
+{
+ Value *gen=new ValueDoubleExpr(szOfOutParam,inParam);
+ ValueDoubleExpr *res=0;
+ try
+ {
+ res=(ValueDoubleExpr *)evaluateLowLev(gen);
+ }
+ catch(INTERP_KERNEL::Exception& e)
+ {
+ delete gen;
+ throw e;
+ }
+ delete gen;
+ std::copy(res->getData(),res->getData()+szOfOutParam,outParam);
+ delete res;
+}
+
+void ExprParser::prepareExprEvaluation(const std::vector<std::string>& vars) const throw(INTERP_KERNEL::Exception)
+{
+ if(_leaf)
+ {
+ LeafExprVar *leafC=dynamic_cast<LeafExprVar *>(_leaf);
+ if(leafC)
+ leafC->prepareExprEvaluation(vars);
+ }
+ else
+ for(std::list<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
+ (*iter).prepareExprEvaluation(vars);
+}
+
+void ExprParser::prepareExprEvaluationVec() const throw(INTERP_KERNEL::Exception)
+{
+ std::set<std::string> trueVars;
+ getTrueSetOfVars(trueVars);
+ if(trueVars.size()>1)
+ {
+ std::ostringstream oss; oss << "For this type of evaluation only one not keyword variable authorized : ";
+ oss << "having " << trueVars.size() << " : ";
+ std::copy(trueVars.begin(),trueVars.end(),std::ostream_iterator<std::string>(oss," ")); oss << " !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ prepareExprEvaluationVecLowLev();
+}
+
+void ExprParser::prepareExprEvaluationVecLowLev() const throw(INTERP_KERNEL::Exception)
+{
+ if(_leaf)
+ {
+ LeafExprVar *leafC=dynamic_cast<LeafExprVar *>(_leaf);
+ if(leafC)
+ leafC->prepareExprEvaluationVec();
+ }
+ else
+ for(std::list<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
+ (*iter).prepareExprEvaluationVecLowLev();
+}
+
+Value *ExprParser::evaluateLowLev(Value *valGen) const throw(INTERP_KERNEL::Exception)
+{
+ if(!_is_parsing_ok)
+ throw INTERP_KERNEL::Exception("Parsing fails ! Invalid expression !");
+ if(_sub_expr.empty() && !_leaf)
+ throw INTERP_KERNEL::Exception("Empty expression !");
+ std::vector<Value *> stackOfVal;
+ try
+ {
+ if(_leaf)
+ {
+ Value *ret=valGen->newInstance();
+ try
+ {
+ _leaf->fillValue(ret);
+ }
+ catch(INTERP_KERNEL::Exception& e)
+ {
+ delete ret;
+ throw e;
+ }
+ stackOfVal.resize(1);
+ stackOfVal[0]=ret;
+ }
+ else
+ {
+ stackOfVal.resize(_sub_expr.size());
+ std::vector<Value *>::reverse_iterator iter2=stackOfVal.rbegin();
+ for(std::list<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++,iter2++)
+ *iter2=(*iter).evaluateLowLev(valGen);
+ }
+ std::list<Function *>::const_iterator iter3;
+ for(iter3=_func_btw_sub_expr.begin();iter3!=_func_btw_sub_expr.end();iter3++)
+ (*iter3)->operate(stackOfVal);
+ }
+ catch(INTERP_KERNEL::Exception& e)
+ {
+ for(std::vector<Value *>::iterator iter4=stackOfVal.begin();iter4!=stackOfVal.end();iter4++)
+ delete *iter4;
+ throw e;
+ }
+ return stackOfVal.back();
+}
+
+void ExprParser::getSetOfVars(std::set<std::string>& vars) const
+{
+ if(_leaf)
+ {
+ LeafExprVar *leafC=dynamic_cast<LeafExprVar *>(_leaf);
+ if(leafC)
+ vars.insert(leafC->getVar());
+ }
+ else
+ for(std::list<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
+ (*iter).getSetOfVars(vars);
+}
+
+void ExprParser::getTrueSetOfVars(std::set<std::string>& trueVars) const
+{
+ std::set<std::string> vars;
+ getSetOfVars(vars);
+ trueVars.clear();
+ for(std::set<std::string>::const_iterator iter=vars.begin();iter!=vars.end();iter++)
+ {
+ int tmp;
+ if(!LeafExprVar::isRecognizedKeyVar(*iter,tmp))
+ trueVars.insert(*iter);
+ }
+}
+
+void ExprParser::parseDeeper() throw(INTERP_KERNEL::Exception)
+{
+ for(std::list<ExprParser>::iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
+ if(!(*iter).simplify())
+ (*iter).parseDeeper();
+}
+
+/*!
+ * This method has the responsability to see if this->_expr can be seen as a unary function of something.
+ * Something defined as the contain of highest level barckets.
+ * Typically '(3*x+2)' and 'cos(4*l+p*n)' will be intercepted by this method whereas '3*x+2' not...etc..
+ */
+void ExprParser::parseUnaryFunc() throw(INTERP_KERNEL::Exception)
+{
+ if(_expr[_expr.length()-1]!=')')
+ return ;
+ //at this level of code _expr
+ std::size_t pos1=_expr.find_first_of('(');
+ std::size_t pos4=findCorrespondingOpenBracket(_expr,_expr.length()-1);
+ if(pos4!=pos1)
+ return ;
+ std::string funcName=_expr.substr(0,pos1);
+ std::size_t pos2=funcName.find_first_of("+-*/^",0,5);
+ std::size_t pos3=funcName.find_first_not_of("+-*/^",0,5);
+ if(pos2!=std::string::npos && pos3!=std::string::npos)
+ return ;//Bracket group is not alone, can't conclude not recursively.
+ std::string newExp2=_expr.substr(pos1+1,_expr.length()-pos1-2);
+ int nbOfParamsInFunc=std::count(newExp2.begin(),newExp2.end(),',')+1;
+ if(pos3!=std::string::npos)
+ _func_btw_sub_expr.push_back(FunctionsFactory::buildFuncFromString(funcName.c_str(),nbOfParamsInFunc));
+ else
+ {
+ int lgth=funcName.length();
+ char tmp[2]; tmp[1]='\0';
+ for(int i=0;i<lgth;i++)
+ {
+ tmp[0]=funcName[i];
+ _func_btw_sub_expr.push_back(FunctionsFactory::buildFuncFromString(tmp,nbOfParamsInFunc));
+ }
+ }
+ std::size_t pos6=0;
+ for(int i=0;i<nbOfParamsInFunc;i++)
+ {
+ std::size_t pos5=newExp2.find_first_of(',');
+ std::size_t len=std::string::npos;
+ if(pos5!=std::string::npos)
+ len=pos5-pos6;
+ std::string newExp3=newExp2.substr(pos6,len);
+ _sub_expr.push_back(ExprParser(newExp3.c_str()));
+ pos6=pos5+1;
+ }
+ _is_parsing_ok=true;
+}
+
+/*!
+ * This method has the responsability to see if this->_expr is interpretable without any recursion.
+ * \return true if no recursion needed, false if this->_expr is too complex to be interpreted at this level.
+ * \throw exception if this->_expr is simple enough to try to interprate this and this expression contains an error.
+ */
+bool ExprParser::tryToInterpALeaf() throw(INTERP_KERNEL::Exception)
+{
+ std::size_t pos=_expr.find_first_not_of("+-",0,2);
+ std::string minimizedExpr=_expr.substr(pos);
+ std::size_t pos2=minimizedExpr.find_first_of("+-*/^()",0,7);
+ if(pos2!=std::string::npos)
+ return false;
+ delete _leaf;
+ _leaf=LeafExpr::buildInstanceFrom(minimizedExpr);
+ int nbOfNegs=0;
+ for(std::size_t i=0;i<pos;i++)
+ if(_expr[i]=='-')
+ nbOfNegs++;
+ if(nbOfNegs%2)
+ _func_btw_sub_expr.push_back(FunctionsFactory::buildUnaryFuncFromString("-"));
+ _is_parsing_ok=true;
+ return true;
+}
+
+void ExprParser::parseForAddMin() throw(INTERP_KERNEL::Exception)
+{
+ std::string::const_iterator iter;
+ int curLevel=0;
+ std::string curPart;
+ bool isParsingSucceed=false;
+ for(iter=_expr.begin();iter!=_expr.end();iter++)
+ {
+ switch(*iter)
+ {
+ case '+':
+ case '-':
+ if(curLevel!=0)
+ curPart+=*iter;
+ else
+ {
+ if(!curPart.empty())
+ {
+ std::string::reverse_iterator accessor=curPart.rbegin();
+ if(*accessor!='*' && *accessor!='/' && *accessor!='^')
+ {
+ isParsingSucceed=true;
+ _sub_expr.push_back(ExprParser(curPart.c_str()));
+ curPart.clear();
+ _func_btw_sub_expr.push_back(FunctionsFactory::buildBinaryFuncFromString(*iter));
+ }
+ else
+ curPart+=*iter;
+ }
+ else
+ curPart+=*iter;
+ }
+ break;
+ case '(':
+ curLevel++;
+ curPart+=*iter;
+ break;
+ case ')':
+ curLevel--;
+ curPart+=*iter;
+ break;
+ default:
+ curPart+=*iter;
+ }
+ }
+ if(isParsingSucceed)
+ {
+ if(!curPart.empty())
+ {
+ _sub_expr.push_back(ExprParser(curPart.c_str()));
+ _is_parsing_ok=true;
+ }
+ else
+ {
+ std::ostringstream errMsg;
+ char MSGTYP4[]="Error following expression finished by +/- without right part.";
+ errMsg << EXPR_PARSE_ERR_MSG << MSGTYP4 << _expr;
+ throw INTERP_KERNEL::Exception(errMsg.str().c_str());
+ }
+ }
+}
+
+void ExprParser::parseForMulDiv() throw(INTERP_KERNEL::Exception)
+{
+ std::string::const_iterator iter;
+ int curLevel=0;
+ std::string curPart;
+ bool isParsingSucceed=false;
+ for(iter=_expr.begin();iter!=_expr.end();iter++)
+ {
+ switch(*iter)
+ {
+ case '/':
+ case '*':
+ if(curLevel!=0)
+ curPart+=*iter;
+ else
+ {
+ isParsingSucceed=true;
+ if(!curPart.empty())
+ {
+ _sub_expr.push_back(ExprParser(curPart.c_str()));
+ curPart.clear();
+ _func_btw_sub_expr.push_back(FunctionsFactory::buildBinaryFuncFromString(*iter));
+ }
+ else
+ {
+ std::ostringstream errMsg;
+ char MSGTYP1[]="Error non unary function for '";
+ errMsg << EXPR_PARSE_ERR_MSG << MSGTYP1 << *iter << "'";
+ std::string tmp=_expr.substr(iter-_expr.begin());
+ locateError(errMsg,tmp,0);
+ throw INTERP_KERNEL::Exception(errMsg.str().c_str());
+ }
+ }
+ break;
+ case '(':
+ curLevel++;
+ curPart+=*iter;
+ break;
+ case ')':
+ curLevel--;
+ curPart+=*iter;
+ break;
+ default:
+ curPart+=*iter;
+ }
+ }
+ if(isParsingSucceed)
+ {
+ if(!curPart.empty())
+ {
+ _sub_expr.push_back(ExprParser(curPart.c_str()));
+ _is_parsing_ok=true;
+ }
+ else
+ {
+ std::ostringstream errMsg;
+ char MSGTYP5[]="Error following expression finished by *// without right part.";
+ errMsg << EXPR_PARSE_ERR_MSG << MSGTYP5 << _expr;
+ throw INTERP_KERNEL::Exception(errMsg.str().c_str());
+ }
+ }
+}
+
+void ExprParser::parseForPow() throw(INTERP_KERNEL::Exception)
+{
+ std::string::const_iterator iter;
+ int curLevel=0;
+ std::string curPart;
+ bool isParsingSucceed=false;
+ for(iter=_expr.begin();iter!=_expr.end();iter++)
+ {
+ switch(*iter)
+ {
+ case '^':
+ if(curLevel!=0)
+ curPart+=*iter;
+ else
+ if(!curPart.empty())
+ {
+ isParsingSucceed=true;
+ _sub_expr.push_back(ExprParser(curPart.c_str()));
+ curPart.clear();
+ _func_btw_sub_expr.push_back(FunctionsFactory::buildBinaryFuncFromString(*iter));
+ }
+ else
+ {
+ std::ostringstream errMsg;
+ char MSGTYP1[]="Error non unary function for '";
+ errMsg << EXPR_PARSE_ERR_MSG << MSGTYP1 << *iter << "'";
+ std::string tmp=_expr.substr(iter-_expr.begin());
+ locateError(errMsg,tmp,0);curPart+=*iter;
+ throw INTERP_KERNEL::Exception(errMsg.str().c_str());
+ }
+ break;
+ case '(':
+ curLevel++;
+ curPart+=*iter;
+ break;
+ case ')':
+ curLevel--;
+ curPart+=*iter;
+ break;
+ default:
+ curPart+=*iter;
+ }
+ }
+ if(isParsingSucceed)
+ {
+ if(!curPart.empty())
+ {
+ _sub_expr.push_back(ExprParser(curPart.c_str()));
+ _is_parsing_ok=true;
+ }
+ else
+ {
+ std::ostringstream errMsg;
+ char MSGTYP6[]="Error following expression finished by ^ without right part.";
+ errMsg << EXPR_PARSE_ERR_MSG << MSGTYP6 << _expr;
+ throw INTERP_KERNEL::Exception(errMsg.str().c_str());
+ }
+ }
+}
+
+void ExprParser::releaseFunctions()
+{
+ for(std::list<Function *>::iterator iter=_func_btw_sub_expr.begin();iter!=_func_btw_sub_expr.end();iter++)
+ delete *iter;
+ _func_btw_sub_expr.clear();
+}
+
+/*!
+ * This method parse this->_expr at the current level.
+ * This method first try to see if this->_expr is a leaf, if not it try a unary function of something (see INTERP_KERNEL::ExprParser::parseUnaryFunc method)
+ * If true is returned, no deeper parsing needed, if false is returned for a full parsing of this->_expr INTERP_KERNEL::ExprParser::parseDeeper call needed.
+ */
+bool ExprParser::simplify() throw(INTERP_KERNEL::Exception)
+{
+ if(tryToInterpALeaf())
+ return true;
+ parseUnaryFunc();
+ if(!_is_parsing_ok)
+ {
+ parseForAddMin();
+ if(!_is_parsing_ok)
+ {
+ parseForMulDiv();
+ if(!_is_parsing_ok)
+ parseForPow();
+ }
+ }
+ if(!_is_parsing_ok)
+ {
+ std::ostringstream errMsg;
+ char MSGTYP3[]="Error in interpreting : ";
+ errMsg << EXPR_PARSE_ERR_MSG << MSGTYP3 << _expr;
+ locateError(errMsg,_expr,0);
+ throw INTERP_KERNEL::Exception(errMsg.str().c_str());
+ }
+ return false;
+}
+
+void ExprParser::checkBracketsParity() const throw(INTERP_KERNEL::Exception)
+{
+ std::string::const_iterator iter;
+ int curLevel=0;
+ for(iter=_expr.begin();iter!=_expr.end();iter++)
+ {
+ if(*iter=='(')
+ curLevel++;
+ else if(*iter==')')
+ {
+ if(curLevel==0)
+ {
+ std::ostringstream errMsg;
+ char MSGTYP1[]="Error in brackets : closing brackets ')' before openning '('";
+ errMsg << EXPR_PARSE_ERR_MSG << MSGTYP1;
+ locateError(errMsg,_expr,iter-_expr.begin());
+ throw INTERP_KERNEL::Exception(errMsg.str().c_str());
+ }
+ curLevel--;
+ }
+ }
+ if(curLevel!=0)
+ {
+ std::ostringstream errMsg;
+ char MSGTYP2[]="Error in brackets : not finally closed expr.";
+ errMsg << EXPR_PARSE_ERR_MSG << MSGTYP2;
+ throw INTERP_KERNEL::Exception(errMsg.str().c_str());
+ }
+}
+
+void ExprParser::locateError(std::ostream& stringToDisp, const std::string& srcOfErr, int posOfErr)
+{
+ stringToDisp << "Position is " << posOfErr << " of string : \"" << srcOfErr << "\"" << std::endl;
+}
--- /dev/null
+#ifndef __INTERPKERNELEXPRPARSER_HXX__
+#define __INTERPKERNELEXPRPARSER_HXX__
+
+#include "INTERPKERNELEXPREVALDefines.hxx"
+#include "InterpKernelUnit.hxx"
+#include "InterpKernelException.hxx"
+#include "InterpKernelFunction.hxx"
+
+#include <string>
+#include <list>
+#include <map>
+#include <set>
+
+namespace INTERP_KERNEL
+{
+ class ValueDouble;
+
+ class INTERPKERNELEXPREVAL_EXPORT LeafExpr
+ {
+ public:
+ virtual ~LeafExpr();
+ virtual void fillValue(Value *val) const throw(INTERP_KERNEL::Exception) = 0;
+ static LeafExpr *buildInstanceFrom(const std::string& expr) throw(INTERP_KERNEL::Exception);
+ };
+
+ class INTERPKERNELEXPREVAL_EXPORT LeafExprVal : public LeafExpr
+ {
+ public:
+ LeafExprVal(double value);
+ ~LeafExprVal();
+ void fillValue(Value *val) const throw(INTERP_KERNEL::Exception);
+ private:
+ double _value;
+ };
+
+ class INTERPKERNELEXPREVAL_EXPORT LeafExprVar : public LeafExpr
+ {
+ public:
+ LeafExprVar(const std::string& var);
+ ~LeafExprVar();
+ void fillValue(Value *val) const throw(INTERP_KERNEL::Exception);
+ std::string getVar() const { return _var_name; }
+ void prepareExprEvaluation(const std::vector<std::string>& vars) const throw(INTERP_KERNEL::Exception);
+ void prepareExprEvaluationVec() const throw(INTERP_KERNEL::Exception);
+ static bool isRecognizedKeyVar(const std::string& var, int& pos);
+ public:
+ static const char END_OF_RECOGNIZED_VAR[];
+ private:
+ mutable int _fast_pos;
+ std::string _var_name;
+ };
+
+ class INTERPKERNELEXPREVAL_EXPORT ExprParser
+ {
+ public:
+ ExprParser(const char *expr);
+ ExprParser(const char *expr, int lgth);
+ ~ExprParser();
+ void parse() throw(INTERP_KERNEL::Exception);
+ bool isParsingSuccessfull() const { return _is_parsing_ok; }
+ double evaluate() const throw(INTERP_KERNEL::Exception);
+ DecompositionInUnitBase evaluateUnit() const throw(INTERP_KERNEL::Exception);
+ void prepareExprEvaluation(const std::vector<std::string>& vars) const throw(INTERP_KERNEL::Exception);
+ void evaluateExpr(int szOfOutParam, double *outParam, const double *inParam) const throw(INTERP_KERNEL::Exception);
+ void prepareExprEvaluationVec() const throw(INTERP_KERNEL::Exception);
+ void getSetOfVars(std::set<std::string>& vars) const;
+ void getTrueSetOfVars(std::set<std::string>& vars) const;
+ static std::string buildStringFromFortran(const char *expr, int lgth);
+ static std::string deleteWhiteSpaces(const std::string& expr);
+ private:
+ Value *evaluateLowLev(Value *valGen) const throw(INTERP_KERNEL::Exception);
+ private:
+ void prepareExprEvaluationVecLowLev() const throw(INTERP_KERNEL::Exception);
+ bool tryToInterpALeaf() throw(INTERP_KERNEL::Exception);
+ void parseUnaryFunc() throw(INTERP_KERNEL::Exception);
+ void parseForAddMin() throw(INTERP_KERNEL::Exception);
+ void parseForMulDiv() throw(INTERP_KERNEL::Exception);
+ void parseForPow() throw(INTERP_KERNEL::Exception);
+ void parseDeeper() throw(INTERP_KERNEL::Exception);
+ bool simplify() throw(INTERP_KERNEL::Exception);
+ void releaseFunctions();
+ void checkBracketsParity() const throw(INTERP_KERNEL::Exception);
+ static std::size_t findCorrespondingOpenBracket(const std::string& expr, std::size_t posOfCloseBracket);
+ static void locateError(std::ostream& stringToDisp, const std::string& srcOfErr, int posOfErr);
+ private:
+ bool _is_parsed;
+ LeafExpr *_leaf;
+ bool _is_parsing_ok;
+ std::string _expr;
+ std::list<ExprParser> _sub_expr;
+ std::list<Function *> _func_btw_sub_expr;
+ private:
+ static const char WHITE_SPACES[];
+ static const char EXPR_PARSE_ERR_MSG[];
+ };
+}
+
+#endif
--- /dev/null
+#include "InterpKernelFunction.hxx"
+#include "InterpKernelValue.hxx"
+
+#include <cmath>
+
+using namespace INTERP_KERNEL;
+
+const char IdentityFunction::REPR[]="Id";
+
+const char PositiveFunction::REPR[]="+";
+
+const char NegateFunction::REPR[]="-";
+
+const char CosFunction::REPR[]="cos";
+
+const char SinFunction::REPR[]="sin";
+
+const char TanFunction::REPR[]="tan";
+
+const char SqrtFunction::REPR[]="sqrt";
+
+const char AbsFunction::REPR[]="abs";
+
+const char PlusFunction::REPR[]="+";
+
+const char MinusFunction::REPR[]="-";
+
+const char MultFunction::REPR[]="*";
+
+const char DivFunction::REPR[]="/";
+
+const char PowFunction::REPR[]="^";
+
+const char ExpFunction::REPR[]="exp";
+
+const char LnFunction::REPR[]="ln";
+
+const char MaxFunction::REPR[]="max";
+
+const char MinFunction::REPR[]="min";
+
+Function *FunctionsFactory::buildFuncFromString(const char *type, int nbOfParams) throw(INTERP_KERNEL::Exception)
+{
+ switch(nbOfParams)
+ {
+ case 1:
+ return buildUnaryFuncFromString(type);
+ case 2:
+ return buildBinaryFuncFromString(type);
+ default:
+ throw INTERP_KERNEL::Exception("Invalid number of params detected : limited to 2 !");
+ }
+}
+
+Function *FunctionsFactory::buildUnaryFuncFromString(const char *type) throw(INTERP_KERNEL::Exception)
+{
+ std::string tmp(type);
+ if(tmp.empty())
+ return new IdentityFunction;
+ if(tmp==CosFunction::REPR)
+ return new CosFunction;
+ if(tmp==SinFunction::REPR)
+ return new SinFunction;
+ if(tmp==TanFunction::REPR)
+ return new TanFunction;
+ if(tmp==SqrtFunction::REPR)
+ return new SqrtFunction;
+ if(tmp==AbsFunction::REPR)
+ return new AbsFunction;
+ if(tmp==PositiveFunction::REPR)
+ return new PositiveFunction;
+ if(tmp==NegateFunction::REPR)
+ return new NegateFunction;
+ if(tmp==ExpFunction::REPR)
+ return new ExpFunction;
+ if(tmp==LnFunction::REPR)
+ return new LnFunction;
+ //
+ std::string msg("Invalid unary function detected : \"");
+ msg+=type; msg+="\"";
+ throw INTERP_KERNEL::Exception(msg.c_str());
+}
+
+Function *FunctionsFactory::buildBinaryFuncFromString(const char *type) throw(INTERP_KERNEL::Exception)
+{
+ std::string tmp(type);
+ if(tmp==PositiveFunction::REPR)
+ return new PlusFunction;
+ if(tmp==NegateFunction::REPR)
+ return new MinusFunction;
+ if(tmp==MultFunction::REPR)
+ return new MultFunction;
+ if(tmp==DivFunction::REPR)
+ return new DivFunction;
+ if(tmp==PowFunction::REPR)
+ return new PowFunction;
+ if(tmp==MaxFunction::REPR)
+ return new MaxFunction;
+ if(tmp==MinFunction::REPR)
+ return new MinFunction;
+ std::string msg("Invalid binary function detected : \"");
+ msg+=type; msg+="\"";
+ throw INTERP_KERNEL::Exception(msg.c_str());
+}
+
+Function *FunctionsFactory::buildBinaryFuncFromString(char type) throw(INTERP_KERNEL::Exception)
+{
+ char tmp[2]; tmp[0]=type; tmp[1]='\0';
+ return buildBinaryFuncFromString(tmp);
+}
+
+Function::~Function()
+{
+}
+
+IdentityFunction::~IdentityFunction()
+{
+}
+
+void IdentityFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception)
+{
+}
+
+const char *IdentityFunction::getRepr() const
+{
+ return REPR;
+}
+
+bool IdentityFunction::isACall() const
+{
+ return false;
+}
+
+PositiveFunction::~PositiveFunction()
+{
+}
+
+int UnaryFunction::getNbInputParams() const
+{
+ return 1;
+}
+
+void PositiveFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception)
+{
+}
+
+const char *PositiveFunction::getRepr() const
+{
+ return REPR;
+}
+
+bool PositiveFunction::isACall() const
+{
+ return false;
+}
+
+NegateFunction::~NegateFunction()
+{
+}
+
+void NegateFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception)
+{
+ Value *val=stack.back();
+ val->negate();
+}
+
+const char *NegateFunction::getRepr() const
+{
+ return REPR;
+}
+
+bool NegateFunction::isACall() const
+{
+ return false;
+}
+
+CosFunction::~CosFunction()
+{
+}
+
+void CosFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception)
+{
+ Value *val=stack.back();
+ val->cos();
+}
+
+const char *CosFunction::getRepr() const
+{
+ return REPR;
+}
+
+bool CosFunction::isACall() const
+{
+ return true;
+}
+
+SinFunction::~SinFunction()
+{
+}
+
+void SinFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception)
+{
+ Value *val=stack.back();
+ val->sin();
+}
+
+const char *SinFunction::getRepr() const
+{
+ return REPR;
+}
+
+bool SinFunction::isACall() const
+{
+ return true;
+}
+
+TanFunction::~TanFunction()
+{
+}
+
+void TanFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception)
+{
+ Value *val=stack.back();
+ val->tan();
+}
+
+const char *TanFunction::getRepr() const
+{
+ return REPR;
+}
+
+bool TanFunction::isACall() const
+{
+ return true;
+}
+
+SqrtFunction::~SqrtFunction()
+{
+}
+
+void SqrtFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception)
+{
+ Value *val=stack.back();
+ val->sqrt();
+}
+
+const char *SqrtFunction::getRepr() const
+{
+ return REPR;
+}
+
+bool SqrtFunction::isACall() const
+{
+ return true;
+}
+
+AbsFunction::~AbsFunction()
+{
+}
+
+void AbsFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception)
+{
+ Value *val=stack.back();
+ val->abs();
+}
+
+const char *AbsFunction::getRepr() const
+{
+ return REPR;
+}
+
+bool AbsFunction::isACall() const
+{
+ return false;
+}
+
+void ExpFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception)
+{
+ Value *val=stack.back();
+ val->exp();
+}
+
+const char *ExpFunction::getRepr() const
+{
+ return REPR;
+}
+
+bool ExpFunction::isACall() const
+{
+ return true;
+}
+
+LnFunction::~LnFunction()
+{
+}
+
+void LnFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception)
+{
+ Value *val=stack.back();
+ val->ln();
+}
+
+const char *LnFunction::getRepr() const
+{
+ return REPR;
+}
+
+bool LnFunction::isACall() const
+{
+ return true;
+}
+
+int BinaryFunction::getNbInputParams() const
+{
+ return 2;
+}
+
+PlusFunction::~PlusFunction()
+{
+}
+
+void PlusFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception)
+{
+ Value *val1=stack.back();
+ stack.pop_back();
+ Value *& val2=stack.back();
+ Value *val3;
+ try
+ {
+ val3=val1->plus(val2);
+ }
+ catch(INTERP_KERNEL::Exception& e)
+ {
+ delete val1;
+ throw e;
+ }
+ delete val1;
+ delete val2;
+ val2=val3;
+}
+
+const char *PlusFunction::getRepr() const
+{
+ return REPR;
+}
+
+bool PlusFunction::isACall() const
+{
+ return false;
+}
+
+MinusFunction::~MinusFunction()
+{
+}
+
+void MinusFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception)
+{
+ Value *val1=stack.back();
+ stack.pop_back();
+ Value *& val2=stack.back();
+ Value *val3;
+ try
+ {
+ val3=val1->minus(val2);
+ }
+ catch(INTERP_KERNEL::Exception& e)
+ {
+ delete val1;
+ throw e;
+ }
+ delete val1;
+ delete val2;
+ val2=val3;
+}
+
+const char *MinusFunction::getRepr() const
+{
+ return REPR;
+}
+
+bool MinusFunction::isACall() const
+{
+ return false;
+}
+
+MultFunction::~MultFunction()
+{
+}
+
+void MultFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception)
+{
+ Value *val1=stack.back();
+ stack.pop_back();
+ Value *& val2=stack.back();
+ Value *val3=val1->mult(val2);
+ delete val1;
+ delete val2;
+ val2=val3;
+}
+
+const char *MultFunction::getRepr() const
+{
+ return REPR;
+}
+
+bool MultFunction::isACall() const
+{
+ return false;
+}
+
+DivFunction::~DivFunction()
+{
+}
+
+void DivFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception)
+{
+ Value *val1=stack.back();
+ stack.pop_back();
+ Value *& val2=stack.back();
+ Value *val3;
+ try
+ {
+ val3=val1->div(val2);
+ }
+ catch(INTERP_KERNEL::Exception& e)
+ {
+ delete val1;
+ throw e;
+ }
+ delete val1;
+ delete val2;
+ val2=val3;
+}
+
+const char *DivFunction::getRepr() const
+{
+ return REPR;
+}
+
+bool DivFunction::isACall() const
+{
+ return false;
+}
+
+PowFunction::~PowFunction()
+{
+}
+
+void PowFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception)
+{
+ Value *val1=stack.back();
+ stack.pop_back();
+ Value *& val2=stack.back();
+ Value *val3;
+ try
+ {
+ val3=val1->pow(val2);
+ }
+ catch(INTERP_KERNEL::Exception& e)
+ {
+ delete val1;
+ throw e;
+ }
+ delete val1;
+ delete val2;
+ val2=val3;
+}
+
+const char *PowFunction::getRepr() const
+{
+ return REPR;
+}
+
+bool PowFunction::isACall() const
+{
+ return true;
+}
+
+ExpFunction::~ExpFunction()
+{
+}
+
+MaxFunction::~MaxFunction()
+{
+}
+
+void MaxFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception)
+{
+ Value *val1=stack.back();
+ stack.pop_back();
+ Value *& val2=stack.back();
+ Value *val3;
+ try
+ {
+ val3=val1->max(val2);
+ }
+ catch(INTERP_KERNEL::Exception& e)
+ {
+ delete val1;
+ throw e;
+ }
+ delete val1;
+ delete val2;
+ val2=val3;
+}
+
+const char *MaxFunction::getRepr() const
+{
+ return REPR;
+}
+
+bool MaxFunction::isACall() const
+{
+ return false;
+}
+
+MinFunction::~MinFunction()
+{
+}
+
+void MinFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception)
+{
+ Value *val1=stack.back();
+ stack.pop_back();
+ Value *& val2=stack.back();
+ Value *val3;
+ try
+ {
+ val3=val1->min(val2);
+ }
+ catch(INTERP_KERNEL::Exception& e)
+ {
+ delete val1;
+ throw e;
+ }
+ delete val1;
+ delete val2;
+ val2=val3;
+}
+
+const char *MinFunction::getRepr() const
+{
+ return REPR;
+}
+
+bool MinFunction::isACall() const
+{
+ return false;
+}
--- /dev/null
+#ifndef __INTERPKERNELFUNCTION_HXX__
+#define __INTERPKERNELFUNCTION_HXX__
+
+#include "INTERPKERNELEXPREVALDefines.hxx"
+#include "InterpKernelException.hxx"
+
+#include <vector>
+
+namespace INTERP_KERNEL
+{
+ class Value;
+ class Function;
+
+ class INTERPKERNELEXPREVAL_EXPORT FunctionsFactory
+ {
+ public:
+ static Function *buildFuncFromString(const char *type, int nbOfParams) throw(INTERP_KERNEL::Exception);
+ static Function *buildUnaryFuncFromString(const char *type) throw(INTERP_KERNEL::Exception);
+ //static Function *buildUnaryFuncFromString(char type) throw(INTERP_KERNEL::Exception);
+ static Function *buildBinaryFuncFromString(const char *type) throw(INTERP_KERNEL::Exception);
+ static Function *buildBinaryFuncFromString(char type) throw(INTERP_KERNEL::Exception);
+ };
+
+ class INTERPKERNELEXPREVAL_EXPORT Function
+ {
+ public:
+ virtual ~Function();
+ virtual int getNbInputParams() const = 0;
+ virtual void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception) = 0;
+ virtual const char *getRepr() const = 0;
+ virtual bool isACall() const = 0;
+ };
+
+ class INTERPKERNELEXPREVAL_EXPORT UnaryFunction : public Function
+ {
+ public:
+ int getNbInputParams() const;
+ };
+
+ class INTERPKERNELEXPREVAL_EXPORT IdentityFunction : public UnaryFunction
+ {
+ public:
+ ~IdentityFunction();
+ void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+ const char *getRepr() const;
+ bool isACall() const;
+ public:
+ static const char REPR[];
+ };
+
+ class INTERPKERNELEXPREVAL_EXPORT PositiveFunction : public UnaryFunction
+ {
+ public:
+ ~PositiveFunction();
+ void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+ const char *getRepr() const;
+ bool isACall() const;
+ public:
+ static const char REPR[];
+ };
+
+ class INTERPKERNELEXPREVAL_EXPORT NegateFunction : public UnaryFunction
+ {
+ public:
+ ~NegateFunction();
+ void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+ const char *getRepr() const;
+ bool isACall() const;
+ public:
+ static const char REPR[];
+ };
+
+ class INTERPKERNELEXPREVAL_EXPORT CosFunction : public UnaryFunction
+ {
+ public:
+ ~CosFunction();
+ void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+ const char *getRepr() const;
+ bool isACall() const;
+ public:
+ static const char REPR[];
+ };
+
+ class INTERPKERNELEXPREVAL_EXPORT SinFunction : public UnaryFunction
+ {
+ public:
+ ~SinFunction();
+ void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+ const char *getRepr() const;
+ bool isACall() const;
+ public:
+ static const char REPR[];
+ };
+
+ class INTERPKERNELEXPREVAL_EXPORT TanFunction : public UnaryFunction
+ {
+ public:
+ ~TanFunction();
+ void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+ const char *getRepr() const;
+ bool isACall() const;
+ public:
+ static const char REPR[];
+ };
+
+ class INTERPKERNELEXPREVAL_EXPORT SqrtFunction : public UnaryFunction
+ {
+ public:
+ ~SqrtFunction();
+ void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+ const char *getRepr() const;
+ bool isACall() const;
+ public:
+ static const char REPR[];
+ };
+
+ class INTERPKERNELEXPREVAL_EXPORT AbsFunction : public UnaryFunction
+ {
+ public:
+ ~AbsFunction();
+ void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+ const char *getRepr() const;
+ bool isACall() const;
+ public:
+ static const char REPR[];
+ };
+
+ class INTERPKERNELEXPREVAL_EXPORT ExpFunction : public UnaryFunction
+ {
+ public:
+ ~ExpFunction();
+ void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+ const char *getRepr() const;
+ bool isACall() const;
+ public:
+ static const char REPR[];
+ };
+
+ class INTERPKERNELEXPREVAL_EXPORT LnFunction : public UnaryFunction
+ {
+ public:
+ ~LnFunction();
+ void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+ const char *getRepr() const;
+ bool isACall() const;
+ public:
+ static const char REPR[];
+ };
+
+ class INTERPKERNELEXPREVAL_EXPORT BinaryFunction : public Function
+ {
+ public:
+ int getNbInputParams() const;
+ };
+
+ class PlusFunction : public BinaryFunction
+ {
+ public:
+ ~PlusFunction();
+ void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+ const char *getRepr() const;
+ bool isACall() const;
+ public:
+ static const char REPR[];
+ };
+
+ class INTERPKERNELEXPREVAL_EXPORT MinusFunction : public BinaryFunction
+ {
+ public:
+ ~MinusFunction();
+ void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+ const char *getRepr() const;
+ bool isACall() const;
+ public:
+ static const char REPR[];
+ };
+
+ class INTERPKERNELEXPREVAL_EXPORT MultFunction : public BinaryFunction
+ {
+ public:
+ ~MultFunction();
+ void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+ const char *getRepr() const;
+ bool isACall() const;
+ public:
+ static const char REPR[];
+ };
+
+ class INTERPKERNELEXPREVAL_EXPORT DivFunction : public BinaryFunction
+ {
+ public:
+ ~DivFunction();
+ void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+ const char *getRepr() const;
+ bool isACall() const;
+ public:
+ static const char REPR[];
+ };
+
+ class INTERPKERNELEXPREVAL_EXPORT PowFunction : public BinaryFunction
+ {
+ public:
+ ~PowFunction();
+ void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+ const char *getRepr() const;
+ bool isACall() const;
+ public:
+ static const char REPR[];
+ };
+
+ class INTERPKERNELEXPREVAL_EXPORT MaxFunction : public BinaryFunction
+ {
+ public:
+ ~MaxFunction();
+ void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+ const char *getRepr() const;
+ bool isACall() const;
+ public:
+ static const char REPR[];
+ };
+
+ class INTERPKERNELEXPREVAL_EXPORT MinFunction : public BinaryFunction
+ {
+ public:
+ ~MinFunction();
+ void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+ const char *getRepr() const;
+ bool isACall() const;
+ public:
+ static const char REPR[];
+ };
+}
+
+#endif
--- /dev/null
+#include "InterpKernelUnit.hxx"
+#include "InterpKernelExprParser.hxx"
+
+#include <cmath>
+#include <sstream>
+#include <iomanip>
+#include <limits>
+
+using namespace INTERP_KERNEL;
+
+UnitDataBase UnitDataBase::_uniqueMapForExpr;
+
+static const char InterpKernelMuAscii[2]={-0x4B,0x0};
+
+static const char InterpKernelMuUnicode[3]={-0x3E,-0x4B,0x0};
+
+const char *UnitDataBase::PREF_POW10[NB_OF_PREF_POW10]={"y","z","a","f","p","n",InterpKernelMuAscii,InterpKernelMuUnicode,"u","m","c","d",
+ "da","h","k","M","G","T","P","E","Z","Y"};
+
+const double UnitDataBase::POW10[NB_OF_PREF_POW10]={1e-24,1e-21,1e-18,1e-15,1e-12,1e-9,1e-6,1e-6,1e-6,1e-3,1e-2,1e-1,
+ 1e1,1e2,1e3,1e6,1e9,1e12,1e15,1e18,1e21,1e24};
+
+static const char InterpKernelDegreeCAscii[3]={-0x50,0x43,0x0};
+
+static const char InterpKernelDegreeCUnicode[4]={-0x3E,-0x50,0x43,0x0};
+
+static const char InterpKernelDegreeCUnicodeWin[3]={-0x08,0x43,0x0};
+
+const char *UnitDataBase::UNITS_RECOGN[NB_OF_UNITS_RECOGN]={"g","m","s","A","K",
+ "W","J","Hz","V","h","min","t","N","dyn",
+ "eV","Pa","atm","bar",InterpKernelDegreeCAscii,"C","ohm","F","S",
+ "T","H","P","St",InterpKernelDegreeCUnicode,InterpKernelDegreeCUnicodeWin};
+
+const short UnitDataBase::PROJ_IN_BASE[NB_OF_UNITS_RECOGN][SIZE_OF_UNIT_BASE]=
+ {
+ {1,0,0,0,0},//g
+ {0,1,0,0,0},//m
+ {0,0,1,0,0},//s
+ {0,0,0,1,0},//A
+ {0,0,0,0,1},//K
+ {1,2,-3,0,0},//W
+ {1,2,-2,0,0},//J
+ {0,0,-1,0,0},//Hz
+ {1,2,-3,-1,0},//V
+ {0,0,1,0,0},//h
+ {0,0,1,0,0},//min
+ {1,0,0,0,0},//t
+ {1,1,-2,0,0},//N
+ {1,1,-2,0,0},//dyn
+ {1,2,-2,0,0},//eV
+ {1,-1,-2,0,0},//Pa
+ {1,-1,-2,0,0},//atm
+ {1,-1,-2,0,0},//bar
+ {0,0,0,0,1},//degree C
+ {0,0,1,1,0},//C
+ {1,2,-3,-2,0},//ohm
+ {-1,-2,4,2,0},//F
+ {-1,-2,3,2,0},//S
+ {1,0,-2,-1,0},//T
+ {1,2,-2,-2,0},//H
+ {1,-1,-1,0,0},//P
+ {0,2,-1,0,0},//St
+ {0,0,0,0,1},//degree C
+ {0,0,0,0,1}//degree C
+ };
+
+const double UnitDataBase::MUL_COEFF[NB_OF_UNITS_RECOGN]=
+ { 1.,1.,1.,1.,1.,
+ 1000.,1000.,1.,1000.,3600.,3600.,1e6,1000.,1e-2,
+ 1.60217733e-16,1000.,1.01325e8,1e8,1.,1.,1000.,1e-3,
+ 1000.,1000.,100.,1.,1.,1.,1.};
+
+const double UnitDataBase::ADD_COEFF[NB_OF_UNITS_RECOGN]=
+ { 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 273.15, 0., 0., 0., 0., 0., 0., 0., 0., 273.15 ,273.15};
+
+UnitDataBase::UnitDataBase()
+{
+ for(int i=0;i<NB_OF_PREF_POW10;i++)
+ _prefix_pow_10[PREF_POW10[i]]=POW10[i];
+ for(int i=0;i<NB_OF_UNITS_RECOGN;i++)
+ {
+ _units_semantic[UNITS_RECOGN[i]]=PROJ_IN_BASE[i];
+ _units_mul[UNITS_RECOGN[i]]=MUL_COEFF[i];
+ _units_add[UNITS_RECOGN[i]]=ADD_COEFF[i];
+ }
+}
+
+const short *UnitDataBase::getInfoForUnit(const std::string& unit,
+ double& addFact, double& mFact) const throw(INTERP_KERNEL::Exception)
+{
+ std::size_t lgth=unit.length();
+ std::string work,work2;
+ const short *ret=0;
+ for(std::size_t i=0;i<lgth && !ret;i++)
+ {
+ work=unit.substr(i);
+ std::map<std::string,const short *>::const_iterator iter=_units_semantic.find(work);
+ if(iter!=_units_semantic.end())
+ {
+ ret=(*iter).second;
+ std::map<std::string,double>::const_iterator iter2=_units_add.find(work);
+ addFact=(*iter2).second;
+ std::map<std::string,double>::const_iterator iter3=_units_mul.find(work);
+ mFact=(*iter3).second;
+ work2=unit.substr(0,i);
+ }
+ }
+ if(!ret)
+ {
+ std::ostringstream os;
+ os << "Unit : " << unit << " not recognized !";
+ throw INTERP_KERNEL::Exception(os.str().c_str());
+ }
+ if(!work2.empty())
+ {
+ std::map<std::string,double>::const_iterator iter4=_prefix_pow_10.find(work2);
+ if(iter4==_prefix_pow_10.end())
+ {
+ std::ostringstream os;
+ os << "Unit : " << unit << " not fully recognized : \"" << work << "\" detected as core unit and \"";
+ os << work2 << "\" not recognized prefix !";
+ throw INTERP_KERNEL::Exception(os.str().c_str());
+ }
+ addFact=0.;
+ mFact*=(*iter4).second;
+ }
+ return ret;
+}
+
+DecompositionInUnitBase::DecompositionInUnitBase():_add_to_base(0.),_mult_fact_to_base(1.)
+{
+ _value[0]=0;
+ _value[1]=0;
+ _value[2]=0;
+ _value[3]=0;
+ _value[4]=0;
+}
+
+void DecompositionInUnitBase::setInfo(const short *vals, double addFact, double mFact)
+{
+ _add_to_base=addFact;
+ _mult_fact_to_base=mFact;
+ _value[0]=vals[0];
+ _value[1]=vals[1];
+ _value[2]=vals[2];
+ _value[3]=vals[3];
+ _value[4]=vals[4];
+}
+
+bool DecompositionInUnitBase::operator==(const DecompositionInUnitBase& other) const
+{
+ return _value[0]==other._value[0] && _value[1]==other._value[1] && _value[2]==other._value[2] && _value[3]==other._value[3] && _value[4]==other._value[4];
+}
+
+void DecompositionInUnitBase::getTranslationParams(const DecompositionInUnitBase& other, double& mul, double& add) const
+{
+ if((*this)==other)
+ {
+ mul=_mult_fact_to_base/other._mult_fact_to_base;
+ add=_add_to_base/other._mult_fact_to_base-other._add_to_base;
+ }
+ else
+ {
+ mul=std::numeric_limits<double>::max();
+ add=std::numeric_limits<double>::max();
+ }
+}
+
+bool DecompositionInUnitBase::isEqual(short mass, short lgth, short time, short intensity, short temp, double add, double mult)
+{
+ bool ret1=mass==_value[0];
+ bool ret2=lgth==_value[1];
+ bool ret3=time==_value[2];
+ bool ret4=intensity==_value[3];
+ bool ret5=temp==_value[4];
+ bool ret6=areDoubleEquals(add,_add_to_base);
+ bool ret7=areDoubleEquals(mult,_mult_fact_to_base);
+ return ret1 && ret2 && ret3 && ret4 && ret5 && ret6 && ret7;
+}
+
+void DecompositionInUnitBase::negate()
+{
+ _mult_fact_to_base=-_mult_fact_to_base;
+}
+
+bool DecompositionInUnitBase::isAdimensional() const
+{
+ return _value[0]==0 && _value[1]==0 && _value[2]==0 && _value[3]==0 && _value[4]==0;
+}
+
+bool DecompositionInUnitBase::isUnitary() const
+{
+ return areDoubleEquals(_add_to_base,0.) && areDoubleEquals(_mult_fact_to_base,1.);
+}
+
+void DecompositionInUnitBase::tryToConvertInUnit(double val) throw(INTERP_KERNEL::Exception)
+{
+ int valI=(int)val;
+ if((val-(double)valI)!=0.)
+ {
+ std::ostringstream os;
+ os << "Double value " << val << " can't be considered as integer. Not admitable for units !";
+ throw INTERP_KERNEL::Exception(os.str().c_str());
+ }
+ _value[0]=0;
+ _value[1]=0;
+ _value[2]=0;
+ _value[3]=0;
+ _value[4]=0;
+ _add_to_base=0;
+ _mult_fact_to_base=valI;
+}
+
+DecompositionInUnitBase &DecompositionInUnitBase::operator*(const DecompositionInUnitBase& other)
+{
+ _value[0]+=other._value[0]; _value[1]+=other._value[1]; _value[2]+=other._value[2]; _value[3]+=other._value[3]; _value[4]+=other._value[4];
+ _mult_fact_to_base*=other._mult_fact_to_base;
+ _add_to_base=0.;
+ return *this;
+}
+
+DecompositionInUnitBase &DecompositionInUnitBase::operator/(const DecompositionInUnitBase& other)
+{
+ _value[0]-=other._value[0]; _value[1]-=other._value[1]; _value[2]-=other._value[2]; _value[3]-=other._value[3]; _value[4]-=other._value[4];
+ _mult_fact_to_base/=other._mult_fact_to_base;
+ _add_to_base=0.;
+ return *this;
+}
+
+DecompositionInUnitBase &DecompositionInUnitBase::operator^(const DecompositionInUnitBase& other) throw(INTERP_KERNEL::Exception)
+{
+ if(!other.isAdimensional())
+ throw INTERP_KERNEL::Exception("Trying to execute operator ^ with a second member not adimensionnal");
+ int exp=couldItBeConsideredAsInt(other._mult_fact_to_base);
+ _value[0]*=exp; _value[1]*=exp; _value[2]*=exp; _value[3]*=exp; _value[4]*=exp;
+ _mult_fact_to_base=powInt(_mult_fact_to_base,exp);
+ _add_to_base=0.;
+ return *this;
+}
+
+void DecompositionInUnitBase::dealWithAddFactor(const DecompositionInUnitBase& other)
+{
+ if(!areDoubleEquals(_add_to_base,0.))
+ if(other.isAdimensional())
+ if(areDoubleEquals(other._mult_fact_to_base,1.))
+ return ;
+ if(!other.areDoubleEquals(_add_to_base,0.))
+ if(isAdimensional())
+ if(areDoubleEquals(_mult_fact_to_base,1.))
+ return ;
+ _add_to_base=0.;
+}
+
+double DecompositionInUnitBase::powInt(double val, int exp)
+{
+ double work=1.;
+ if(exp==0)
+ return 1.;
+ if(exp>0)
+ for(int i=0;i<exp;i++)
+ work*=val;
+ else
+ {
+ int tmp=-exp;
+ for(int i=0;i<tmp;i++)
+ work*=1/val;
+ }
+ return work;
+}
+
+bool DecompositionInUnitBase::areDoubleEquals(double a, double b)
+{
+ if(a==0. || b==0.)
+ return a==b;
+ double ref=fmax(a,b);
+ return fabs((a-b)/ref)<1e-7;
+}
+
+int DecompositionInUnitBase::couldItBeConsideredAsInt(double val) throw(INTERP_KERNEL::Exception)
+{
+ int ret=(int)val;
+ double valT=(double) ret;
+ if(valT==val)
+ return ret;
+ else
+ {
+ std::ostringstream stream; stream << "Invalid double number " << std::setprecision(16) << val << " can's be considered for ^ operation on unit.";
+ throw INTERP_KERNEL::Exception(stream.str().c_str());
+ }
+}
+
+Unit::Unit(const char *reprC, bool tryToInterp):_coarse_repr(reprC),
+ _is_interpreted(false),
+ _is_interpretation_ok(false)
+{
+ if(tryToInterp)
+ tryToInterprate();
+}
+
+Unit::Unit(const char *reprFortran, int sizeOfRepr, bool tryToInterp):_coarse_repr(ExprParser::buildStringFromFortran(reprFortran,sizeOfRepr)),
+ _is_interpreted(false),
+ _is_interpretation_ok(false)
+{
+}
+
+void Unit::tryToInterprate() const
+{
+ if(!_is_interpreted)
+ {
+ _is_interpreted=true;
+ _is_interpretation_ok=false;
+ try
+ {
+ ExprParser expr(_coarse_repr.c_str());
+ expr.parse();
+ _decomp_in_base=expr.evaluateUnit();
+ _is_interpretation_ok=true;
+ }
+ catch(INTERP_KERNEL::Exception& e) { }
+ }
+}
+
+bool Unit::isInterpretationOK() const
+{
+ return _is_interpretation_ok;
+}
+
+bool Unit::isCompatibleWith(const Unit& other) const
+{
+ tryToInterprate();
+ other.tryToInterprate();
+ if(_is_interpretation_ok && other._is_interpretation_ok)
+ return _decomp_in_base==other._decomp_in_base;
+ else
+ return false;
+}
+
+double Unit::convert(const Unit& target, double sourceVal) const
+{
+ if(isCompatibleWith(target))
+ {
+ double mult,add;
+ _decomp_in_base.getTranslationParams(target._decomp_in_base,mult,add);
+ return mult*sourceVal+add;
+ }
+ else
+ return std::numeric_limits<double>::max();
+}
+
+std::string Unit::getCoarseRepr() const
+{
+ return _coarse_repr;
+}
--- /dev/null
+#ifndef __INTERPKERNELUNIT_HXX__
+#define __INTERPKERNELUNIT_HXX__
+
+#include "INTERPKERNELEXPREVALDefines.hxx"
+#include "InterpKernelException.hxx"
+
+#include <map>
+#include <sstream>
+
+namespace INTERP_KERNEL
+{
+ class INTERPKERNELEXPREVAL_EXPORT UnitDataBase
+ {
+ public:
+ UnitDataBase();
+ const short *getInfoForUnit(const std::string& unit,
+ double& addFact, double& mFact) const throw(INTERP_KERNEL::Exception);
+ static UnitDataBase _uniqueMapForExpr;
+ static const int SIZE_OF_UNIT_BASE=5;
+ private:
+ std::map<std::string,double> _prefix_pow_10;
+ std::map<std::string,const short *> _units_semantic;
+ std::map<std::string,double> _units_mul;
+ std::map<std::string,double> _units_add;
+ private:
+ static const int NB_OF_PREF_POW10=22;
+ static const char *PREF_POW10[NB_OF_PREF_POW10];
+ static const double POW10[NB_OF_PREF_POW10];
+ static const int NB_OF_UNITS_RECOGN=29;
+ static const char *UNITS_RECOGN[NB_OF_UNITS_RECOGN];
+ static const short PROJ_IN_BASE[NB_OF_UNITS_RECOGN][SIZE_OF_UNIT_BASE];
+ static const double MUL_COEFF[NB_OF_UNITS_RECOGN];
+ static const double ADD_COEFF[NB_OF_UNITS_RECOGN];
+ };
+
+ class INTERPKERNELEXPREVAL_EXPORT DecompositionInUnitBase
+ {
+ public:
+ DecompositionInUnitBase();
+ void setInfo(const short *vals, double addFact, double mFact);
+ short operator[](int i) const { return _value[i]; }
+ bool operator==(const DecompositionInUnitBase& other) const;
+ void getTranslationParams(const DecompositionInUnitBase& other, double& mul, double& add) const;
+ bool isEqual(short mass, short lgth, short time, short intensity, short temp,
+ double add, double mult);
+ bool isUnitary() const;
+ //! \b WARNING no test is done on the fact that unit is adimensionnal.
+ void negate();
+ bool isAdimensional() const;
+ void tryToConvertInUnit(double val) throw(INTERP_KERNEL::Exception);
+ DecompositionInUnitBase &operator*(const DecompositionInUnitBase& other);
+ DecompositionInUnitBase &operator/(const DecompositionInUnitBase& other);
+ DecompositionInUnitBase &operator^(const DecompositionInUnitBase& other) throw(INTERP_KERNEL::Exception);
+ private:
+ void dealWithAddFactor(const DecompositionInUnitBase& other);
+ static int couldItBeConsideredAsInt(double val) throw(INTERP_KERNEL::Exception);
+ static bool areDoubleEquals(double a, double b);
+ static double powInt(double val, int exp);
+ private:
+ short _value[UnitDataBase::SIZE_OF_UNIT_BASE];
+ double _add_to_base;
+ double _mult_fact_to_base;
+ };
+
+ /*!
+ * This class deals with units.
+ * This class has two main responsabilities :
+ * - interprete units by giving simply their representation in string type.
+ * - performing operations on these units.
+ *
+ * All the possible units are represented with a unique tuple with 5 elements
+ * representing the unique decomposition of a unit in the following base.
+ *
+ * dimension 0 stands for mass in g (\b NOT kg to simplify parsing).
+ * dimension 1 stands for length in m.
+ * dimension 2 stands for time in s.
+ * dimension 3 stands for elec intensity A.
+ * dimension 4 stands for temperature in K.
+ */
+ class INTERPKERNELEXPREVAL_EXPORT Unit
+ {
+ public:
+ Unit(const char *reprC, bool tryToInterp=true);
+ Unit(const char *reprFortran, int sizeOfRepr, bool tryToInterp=true);
+ void tryToInterprate() const;
+ bool isInterpretationOK() const;
+ bool isCompatibleWith(const Unit& other) const;
+ double convert(const Unit& target, double sourceVal) const;
+ std::string getCoarseRepr() const;
+ private:
+ std::string _coarse_repr;
+ mutable bool _is_interpreted;
+ mutable bool _is_interpretation_ok;
+ mutable DecompositionInUnitBase _decomp_in_base;
+ };
+}
+
+#endif
--- /dev/null
+#include "InterpKernelValue.hxx"
+#include "InterpKernelFunction.hxx"
+
+#include <cmath>
+#include <limits>
+#include <algorithm>
+
+using namespace INTERP_KERNEL;
+
+ValueDouble::ValueDouble():_data(std::numeric_limits<double>::max())
+{
+}
+
+Value *ValueDouble::newInstance() const
+{
+ return new ValueDouble;
+}
+
+ValueDouble::ValueDouble(double val):_data(val)
+{
+}
+
+void ValueDouble::setDouble(double val) throw(INTERP_KERNEL::Exception)
+{
+ _data=val;
+}
+
+void ValueDouble::setVarname(int fastPos, const std::string& var) throw(INTERP_KERNEL::Exception)
+{
+ std::string msg("Error var : "); msg+=var; msg+=" not numeric : use another expression evaluator !";
+ throw INTERP_KERNEL::Exception(msg.c_str());
+}
+
+void ValueDouble::positive() throw(INTERP_KERNEL::Exception)
+{
+}
+
+void ValueDouble::negate() throw(INTERP_KERNEL::Exception)
+{
+ _data=-_data;
+}
+
+void ValueDouble::sqrt() throw(INTERP_KERNEL::Exception)
+{
+ _data=std::sqrt(_data);
+}
+
+void ValueDouble::cos() throw(INTERP_KERNEL::Exception)
+{
+ _data=std::cos(_data);
+}
+
+void ValueDouble::sin() throw(INTERP_KERNEL::Exception)
+{
+ _data=std::sin(_data);
+}
+
+void ValueDouble::tan() throw(INTERP_KERNEL::Exception)
+{
+ _data=std::tan(_data);
+}
+
+void ValueDouble::abs() throw(INTERP_KERNEL::Exception)
+{
+ if(_data<0.)
+ _data=-_data;
+}
+
+void ValueDouble::exp() throw(INTERP_KERNEL::Exception)
+{
+ _data=std::exp(_data);
+}
+
+void ValueDouble:: ln() throw(INTERP_KERNEL::Exception)
+{
+ _data=std::log(_data);
+}
+
+Value *ValueDouble::plus(const Value *other) const throw(INTERP_KERNEL::Exception)
+{
+ const ValueDouble *valC=checkSameType(other);
+ return new ValueDouble(_data+valC->_data);
+}
+
+Value *ValueDouble::minus(const Value *other) const throw(INTERP_KERNEL::Exception)
+{
+ const ValueDouble *valC=checkSameType(other);
+ return new ValueDouble(_data-valC->_data);
+}
+
+Value *ValueDouble::mult(const Value *other) const throw(INTERP_KERNEL::Exception)
+{
+ const ValueDouble *valC=checkSameType(other);
+ return new ValueDouble(_data*valC->_data);
+}
+
+Value *ValueDouble::div(const Value *other) const throw(INTERP_KERNEL::Exception)
+{
+ const ValueDouble *valC=checkSameType(other);
+ return new ValueDouble(_data/valC->_data);
+}
+
+Value *ValueDouble::pow(const Value *other) const throw(INTERP_KERNEL::Exception)
+{
+ const ValueDouble *valC=checkSameType(other);
+ return new ValueDouble(std::pow(_data,valC->_data));
+}
+
+Value *ValueDouble::max(const Value *other) const throw(INTERP_KERNEL::Exception)
+{
+ const ValueDouble *valC=checkSameType(other);
+ return new ValueDouble(std::max(_data,valC->_data));
+}
+
+Value *ValueDouble::min(const Value *other) const throw(INTERP_KERNEL::Exception)
+{
+ const ValueDouble *valC=checkSameType(other);
+ return new ValueDouble(std::min(_data,valC->_data));
+}
+
+const ValueDouble *ValueDouble::checkSameType(const Value *val) throw(INTERP_KERNEL::Exception)
+{
+ const ValueDouble *valC=dynamic_cast<const ValueDouble *>(val);
+ if(!valC)
+ throw INTERP_KERNEL::Exception("Trying to operate on non homogeneous Values (double with other type) !");
+ return valC;
+}
+
+ValueUnit::ValueUnit()
+{
+}
+
+Value *ValueUnit::newInstance() const
+{
+ return new ValueUnit;
+}
+
+ValueUnit::ValueUnit(const DecompositionInUnitBase& unit):_data(unit)
+{
+}
+
+void ValueUnit::setDouble(double val) throw(INTERP_KERNEL::Exception)
+{
+ _data.tryToConvertInUnit(val);
+}
+
+void ValueUnit::setVarname(int fastPos, const std::string& var) throw(INTERP_KERNEL::Exception)
+{
+ double add,mult;
+ const short *projInBase=UnitDataBase::_uniqueMapForExpr.getInfoForUnit(var,add,mult);
+ _data.setInfo(projInBase,add,mult);
+}
+
+void ValueUnit::positive() throw(INTERP_KERNEL::Exception)
+{
+ unsupportedOp(PositiveFunction::REPR);
+}
+
+void ValueUnit::negate() throw(INTERP_KERNEL::Exception)
+{
+ _data.negate();
+}
+
+void ValueUnit::sqrt() throw(INTERP_KERNEL::Exception)
+{
+ unsupportedOp(SqrtFunction::REPR);
+}
+
+void ValueUnit::cos() throw(INTERP_KERNEL::Exception)
+{
+ unsupportedOp(CosFunction::REPR);
+}
+
+void ValueUnit::sin() throw(INTERP_KERNEL::Exception)
+{
+ unsupportedOp(SinFunction::REPR);
+}
+
+void ValueUnit::tan() throw(INTERP_KERNEL::Exception)
+{
+ unsupportedOp(TanFunction::REPR);
+}
+
+void ValueUnit::abs() throw(INTERP_KERNEL::Exception)
+{
+ unsupportedOp(AbsFunction::REPR);
+}
+
+void ValueUnit::exp() throw(INTERP_KERNEL::Exception)
+{
+ unsupportedOp(ExpFunction::REPR);
+}
+
+void ValueUnit::ln() throw(INTERP_KERNEL::Exception)
+{
+ unsupportedOp(LnFunction::REPR);
+}
+
+Value *ValueUnit::plus(const Value *other) const throw(INTERP_KERNEL::Exception)
+{
+ unsupportedOp(PlusFunction::REPR);
+ return 0;
+}
+
+Value *ValueUnit::minus(const Value *other) const throw(INTERP_KERNEL::Exception)
+{
+ unsupportedOp(MinusFunction::REPR);
+ return 0;
+}
+
+Value *ValueUnit::mult(const Value *other) const throw(INTERP_KERNEL::Exception)
+{
+ const ValueUnit *valC=checkSameType(other);
+ DecompositionInUnitBase tmp=_data;
+ tmp*valC->getData();
+ return new ValueUnit(tmp);
+}
+
+Value *ValueUnit::div(const Value *other) const throw(INTERP_KERNEL::Exception)
+{
+ const ValueUnit *valC=checkSameType(other);
+ DecompositionInUnitBase tmp=_data;
+ tmp/valC->getData();
+ return new ValueUnit(tmp);
+}
+
+Value *ValueUnit::pow(const Value *other) const throw(INTERP_KERNEL::Exception)
+{
+ const ValueUnit *valC=checkSameType(other);
+ DecompositionInUnitBase tmp=_data;
+ tmp^valC->getData();
+ return new ValueUnit(tmp);
+}
+
+Value *ValueUnit::max(const Value *other) const throw(INTERP_KERNEL::Exception)
+{
+ unsupportedOp(MaxFunction::REPR);
+ return 0;
+}
+
+Value *ValueUnit::min(const Value *other) const throw(INTERP_KERNEL::Exception)
+{
+ unsupportedOp(MinFunction::REPR);
+ return 0;
+}
+
+const ValueUnit *ValueUnit::checkSameType(const Value *val) throw(INTERP_KERNEL::Exception)
+{
+ const ValueUnit *valC=dynamic_cast<const ValueUnit *>(val);
+ if(!valC)
+ throw INTERP_KERNEL::Exception("Trying to operate on non homogeneous Values (Units with other type) !");
+ return valC;
+}
+
+void ValueUnit::unsupportedOp(const char *type) throw(INTERP_KERNEL::Exception)
+{
+ const char msg[]="Unsupported operation for units :";
+ std::string msgStr(msg);
+ msgStr+=type;
+ throw INTERP_KERNEL::Exception(msgStr.c_str());
+}
+
+ValueDoubleExpr::ValueDoubleExpr(int szDestData, const double *srcData):_sz_dest_data(szDestData),_dest_data(new double[_sz_dest_data]),_src_data(srcData)
+{
+}
+
+ValueDoubleExpr::~ValueDoubleExpr()
+{
+ delete [] _dest_data;
+}
+
+Value *ValueDoubleExpr::newInstance() const
+{
+ return new ValueDoubleExpr(_sz_dest_data,_src_data);
+}
+
+void ValueDoubleExpr::setDouble(double val) throw(INTERP_KERNEL::Exception)
+{
+ std::fill(_dest_data,_dest_data+_sz_dest_data,val);
+}
+
+void ValueDoubleExpr::setVarname(int fastPos, const std::string& var) throw(INTERP_KERNEL::Exception)
+{
+ if(fastPos==-2)
+ std::copy(_src_data,_src_data+_sz_dest_data,_dest_data);
+ else if(fastPos>-2)
+ std::fill(_dest_data,_dest_data+_sz_dest_data,_src_data[fastPos]);
+ else
+ {
+ std::fill(_dest_data,_dest_data+_sz_dest_data,0.);
+ _dest_data[-7-fastPos]=1.;
+ }
+}
+
+void ValueDoubleExpr::positive() throw(INTERP_KERNEL::Exception)
+{
+}
+
+void ValueDoubleExpr::negate() throw(INTERP_KERNEL::Exception)
+{
+ std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::negate<double>());
+}
+
+void ValueDoubleExpr::sqrt() throw(INTERP_KERNEL::Exception)
+{
+ double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less<double>(),0.));
+ if(it!=_dest_data+_sz_dest_data)
+ throw INTERP_KERNEL::Exception("Trying to apply sqrt on < 0. value !");
+ std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::sqrt));
+}
+
+void ValueDoubleExpr::cos() throw(INTERP_KERNEL::Exception)
+{
+ std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::cos));
+}
+
+void ValueDoubleExpr::sin() throw(INTERP_KERNEL::Exception)
+{
+ std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::sin));
+}
+
+void ValueDoubleExpr::tan() throw(INTERP_KERNEL::Exception)
+{
+ std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::tan));
+}
+
+void ValueDoubleExpr::abs() throw(INTERP_KERNEL::Exception)
+{
+ std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun(fabs));
+}
+
+void ValueDoubleExpr::exp() throw(INTERP_KERNEL::Exception)
+{
+ std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::exp));
+}
+
+void ValueDoubleExpr::ln() throw(INTERP_KERNEL::Exception)
+{
+ double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less_equal<double>(),0.));
+ if(it!=_dest_data+_sz_dest_data)
+ throw INTERP_KERNEL::Exception("Trying to apply sqrt on < 0. value !");
+ std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::log));
+}
+
+Value *ValueDoubleExpr::plus(const Value *other) const throw(INTERP_KERNEL::Exception)
+{
+ const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
+ ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
+ std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::plus<double>());
+ return ret;
+}
+
+Value *ValueDoubleExpr::minus(const Value *other) const throw(INTERP_KERNEL::Exception)
+{
+ const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
+ ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
+ std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::minus<double>());
+ return ret;
+}
+
+Value *ValueDoubleExpr::mult(const Value *other) const throw(INTERP_KERNEL::Exception)
+{
+ const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
+ ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
+ std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::multiplies<double>());
+ return ret;
+}
+
+Value *ValueDoubleExpr::div(const Value *other) const throw(INTERP_KERNEL::Exception)
+{
+ const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
+ double *it=std::find(otherC->getData(),otherC->getData()+_sz_dest_data,0.);
+ if(it!=otherC->getData()+_sz_dest_data)
+ throw INTERP_KERNEL::Exception("Trying to operate division by 0. !");
+ ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
+ std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::divides<double>());
+ return ret;
+}
+
+Value *ValueDoubleExpr::pow(const Value *other) const throw(INTERP_KERNEL::Exception)
+{
+ const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
+ double p=otherC->getData()[0];
+ if(p<0.)
+ {
+ double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less<double>(),0.));
+ if(it!=_dest_data+_sz_dest_data)
+ throw INTERP_KERNEL::Exception("Trying to operate pow(a,b) with a<0. and b<0. !");
+ }
+ ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
+ std::transform(_dest_data,_dest_data+_sz_dest_data,ret->getData(),std::bind2nd(std::ptr_fun(powl),p));
+ return ret;
+}
+
+Value *ValueDoubleExpr::max(const Value *other) const throw(INTERP_KERNEL::Exception)
+{
+ const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
+ ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
+ std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::ptr_fun(fmax));
+ return ret;
+}
+
+Value *ValueDoubleExpr::min(const Value *other) const throw(INTERP_KERNEL::Exception)
+{
+ const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
+ ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
+ std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::ptr_fun(fmin));
+ return ret;
+}
--- /dev/null
+#ifndef __INTERPKERNELVALUE_HXX__
+#define __INTERPKERNELVALUE_HXX__
+
+#include "INTERPKERNELEXPREVALDefines.hxx"
+#include "InterpKernelException.hxx"
+#include "InterpKernelUnit.hxx"
+
+namespace INTERP_KERNEL
+{
+ class INTERPKERNELEXPREVAL_EXPORT Value
+ {
+ public:
+ virtual Value *newInstance() const = 0;
+ virtual ~Value() { }
+ virtual void setDouble(double val) throw(INTERP_KERNEL::Exception) = 0;
+ virtual void setVarname(int fastPos, const std::string& var) throw(INTERP_KERNEL::Exception) = 0;
+ //unary
+ virtual void positive() throw(INTERP_KERNEL::Exception) = 0;
+ virtual void negate() throw(INTERP_KERNEL::Exception) = 0;
+ virtual void sqrt() throw(INTERP_KERNEL::Exception) = 0;
+ virtual void cos() throw(INTERP_KERNEL::Exception) = 0;
+ virtual void sin() throw(INTERP_KERNEL::Exception) = 0;
+ virtual void tan() throw(INTERP_KERNEL::Exception) = 0;
+ virtual void abs() throw(INTERP_KERNEL::Exception) = 0;
+ virtual void exp() throw(INTERP_KERNEL::Exception) = 0;
+ virtual void ln() throw(INTERP_KERNEL::Exception) = 0;
+ //binary
+ virtual Value *plus(const Value *other) const throw(INTERP_KERNEL::Exception) = 0;
+ virtual Value *minus(const Value *other) const throw(INTERP_KERNEL::Exception) = 0;
+ virtual Value *mult(const Value *other) const throw(INTERP_KERNEL::Exception) = 0;
+ virtual Value *div(const Value *other) const throw(INTERP_KERNEL::Exception) = 0;
+ virtual Value *pow(const Value *other) const throw(INTERP_KERNEL::Exception) = 0;
+ virtual Value *max(const Value *other) const throw(INTERP_KERNEL::Exception) = 0;
+ virtual Value *min(const Value *other) const throw(INTERP_KERNEL::Exception) = 0;
+ };
+
+ class INTERPKERNELEXPREVAL_EXPORT ValueDouble : public Value
+ {
+ public:
+ ValueDouble();
+ Value *newInstance() const;
+ void setDouble(double val) throw(INTERP_KERNEL::Exception);
+ void setVarname(int fastPos, const std::string& var) throw(INTERP_KERNEL::Exception);
+ //
+ double getData() const { return _data; }
+ void positive() throw(INTERP_KERNEL::Exception);
+ void negate() throw(INTERP_KERNEL::Exception);
+ void sqrt() throw(INTERP_KERNEL::Exception);
+ void cos() throw(INTERP_KERNEL::Exception);
+ void sin() throw(INTERP_KERNEL::Exception);
+ void tan() throw(INTERP_KERNEL::Exception);
+ void abs() throw(INTERP_KERNEL::Exception);
+ void exp() throw(INTERP_KERNEL::Exception);
+ void ln() throw(INTERP_KERNEL::Exception);
+ //
+ Value *plus(const Value *other) const throw(INTERP_KERNEL::Exception);
+ Value *minus(const Value *other) const throw(INTERP_KERNEL::Exception);
+ Value *mult(const Value *other) const throw(INTERP_KERNEL::Exception);
+ Value *div(const Value *other) const throw(INTERP_KERNEL::Exception);
+ Value *pow(const Value *other) const throw(INTERP_KERNEL::Exception);
+ Value *max(const Value *other) const throw(INTERP_KERNEL::Exception);
+ Value *min(const Value *other) const throw(INTERP_KERNEL::Exception);
+ private:
+ ValueDouble(double val);
+ static const ValueDouble *checkSameType(const Value *val) throw(INTERP_KERNEL::Exception);
+ private:
+ double _data;
+ };
+
+ class INTERPKERNELEXPREVAL_EXPORT ValueUnit : public Value
+ {
+ public:
+ ValueUnit();
+ Value *newInstance() const;
+ void setDouble(double val) throw(INTERP_KERNEL::Exception);
+ void setVarname(int fastPos, const std::string& var) throw(INTERP_KERNEL::Exception);
+ //
+ DecompositionInUnitBase getData() const { return _data; }
+ void positive() throw(INTERP_KERNEL::Exception);
+ void negate() throw(INTERP_KERNEL::Exception);
+ void sqrt() throw(INTERP_KERNEL::Exception);
+ void cos() throw(INTERP_KERNEL::Exception);
+ void sin() throw(INTERP_KERNEL::Exception);
+ void tan() throw(INTERP_KERNEL::Exception);
+ void abs() throw(INTERP_KERNEL::Exception);
+ void exp() throw(INTERP_KERNEL::Exception);
+ void ln() throw(INTERP_KERNEL::Exception);
+ //
+ Value *plus(const Value *other) const throw(INTERP_KERNEL::Exception);
+ Value *minus(const Value *other) const throw(INTERP_KERNEL::Exception);
+ Value *mult(const Value *other) const throw(INTERP_KERNEL::Exception);
+ Value *div(const Value *other) const throw(INTERP_KERNEL::Exception);
+ Value *pow(const Value *other) const throw(INTERP_KERNEL::Exception);
+ Value *max(const Value *other) const throw(INTERP_KERNEL::Exception);
+ Value *min(const Value *other) const throw(INTERP_KERNEL::Exception);
+ private:
+ ValueUnit(const DecompositionInUnitBase& unit);
+ static void unsupportedOp(const char *type) throw(INTERP_KERNEL::Exception);
+ static const ValueUnit *checkSameType(const Value *val) throw(INTERP_KERNEL::Exception);
+ private:
+ DecompositionInUnitBase _data;
+ };
+
+ class INTERPKERNELEXPREVAL_EXPORT ValueDoubleExpr : public Value
+ {
+ public:
+ ValueDoubleExpr(int szDestData, const double *srcData);
+ ~ValueDoubleExpr();
+ double *getData() const { return _dest_data; }
+ Value *newInstance() const;
+ void setDouble(double val) throw(INTERP_KERNEL::Exception);
+ void setVarname(int fastPos, const std::string& var) throw(INTERP_KERNEL::Exception);
+ //
+ void positive() throw(INTERP_KERNEL::Exception);
+ void negate() throw(INTERP_KERNEL::Exception);
+ void sqrt() throw(INTERP_KERNEL::Exception);
+ void cos() throw(INTERP_KERNEL::Exception);
+ void sin() throw(INTERP_KERNEL::Exception);
+ void tan() throw(INTERP_KERNEL::Exception);
+ void abs() throw(INTERP_KERNEL::Exception);
+ void exp() throw(INTERP_KERNEL::Exception);
+ void ln() throw(INTERP_KERNEL::Exception);
+ //
+ Value *plus(const Value *other) const throw(INTERP_KERNEL::Exception);
+ Value *minus(const Value *other) const throw(INTERP_KERNEL::Exception);
+ Value *mult(const Value *other) const throw(INTERP_KERNEL::Exception);
+ Value *div(const Value *other) const throw(INTERP_KERNEL::Exception);
+ Value *pow(const Value *other) const throw(INTERP_KERNEL::Exception);
+ Value *max(const Value *other) const throw(INTERP_KERNEL::Exception);
+ Value *min(const Value *other) const throw(INTERP_KERNEL::Exception);
+ private:
+ int _sz_dest_data;
+ double *_dest_data;
+ const double *_src_data;
+ };
+}
+
+#endif
--- /dev/null
+# Copyright (C) 2007-2008 CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+# File : Makefile.am
+# Author : Anthony GEAY (CEA/DEN/DANS/DM2S/SFME/LGLS)
+# Module : MED
+#
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+lib_LTLIBRARIES = libinterpkernelexpreval.la
+
+salomeinclude_HEADERS = \
+INTERPKERNELEXPREVALDefines.hxx \
+InterpKernelExprParser.hxx \
+InterpKernelFunction.hxx \
+InterpKernelUnit.hxx \
+InterpKernelValue.hxx
+
+
+EXTRA_DIST += \
+INTERPKERNELEXPREVALDefines.hxx \
+InterpKernelExprParser.hxx \
+InterpKernelFunction.hxx \
+InterpKernelUnit.hxx \
+InterpKernelValue.hxx
+
+dist_libinterpkernelexpreval_la_SOURCES = \
+ InterpKernelExprParser.cxx \
+ InterpKernelFunction.cxx \
+ InterpKernelUnit.cxx \
+ InterpKernelValue.cxx
+
+libinterpkernelexpreval_la_CPPFLAGS=-I$(srcdir)/../Bases
+
+libinterpkernelexpreval_la_LDFLAGS=
+
+libinterpkernelexpreval_la_LIBADD= ../Bases/libinterpkernelbases.la
+
+AM_CPPFLAGS += $(libinterpkernelexpreval_la_CPPFLAGS)
+
+LDADD= $(libinterpkernelexpreval_la_LDFLAGS)
#
include $(top_srcdir)/adm_local/unix/make_common_starter.am
-SUBDIRS = Bases Geometric2D .
+SUBDIRS = Bases Geometric2D ExprEval .
-DIST_SUBDIRS = Bases Geometric2D
+DIST_SUBDIRS = Bases Geometric2D ExprEval
lib_LTLIBRARIES = libinterpkernel.la
libinterpkernel_la_LDFLAGS=
# the geom2D library is included in the interpkernel one
-libinterpkernel_la_LIBADD= ./Geometric2D/libInterpGeometric2DAlg.la Bases/libinterpkernelbases.la
+libinterpkernel_la_LIBADD= ./Geometric2D/libInterpGeometric2DAlg.la Bases/libinterpkernelbases.la ExprEval/libinterpkernelexpreval.la
AM_CPPFLAGS += $(libinterpkernel_la_CPPFLAGS)
LDADD= $(libinterpkernel_la_LDFLAGS)
--- /dev/null
+// Copyright (C) 2007-2008 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#include "ExprEvalInterpTest.hxx"
+#include "InterpKernelExprParser.hxx"
+
+using namespace std;
+using namespace INTERP_TEST;
+
+void ExprEvalInterpTest::testBuildStringFromFortran()
+{
+ char toto1[]="123456 ";
+ char result[]="123456";
+ string titi;
+ titi=INTERP_KERNEL::ExprParser::buildStringFromFortran(toto1,8);
+ CPPUNIT_ASSERT_EQUAL(6,(int)titi.length());
+ CPPUNIT_ASSERT(titi==result);
+ //
+ char toto2[]=" 23456 ";
+ char result2[]=" 23456";
+ titi=INTERP_KERNEL::ExprParser::buildStringFromFortran(toto2,8);
+ CPPUNIT_ASSERT(titi==result2);
+ CPPUNIT_ASSERT_EQUAL(6,(int)titi.length());
+ //
+ char toto3[]=" 3456 ";
+ char result3[]=" 3456";
+ titi=INTERP_KERNEL::ExprParser::buildStringFromFortran(toto3,8);
+ CPPUNIT_ASSERT(titi==result3);
+ CPPUNIT_ASSERT_EQUAL(6,(int)titi.length());
+ //
+ char toto4[]=" ";
+ titi=INTERP_KERNEL::ExprParser::buildStringFromFortran(toto4,8);
+ CPPUNIT_ASSERT_EQUAL(0,(int)titi.length());
+ //
+ char toto5[]=" 345677";
+ titi=INTERP_KERNEL::ExprParser::buildStringFromFortran(toto5,8);
+ CPPUNIT_ASSERT(titi==toto5);
+ CPPUNIT_ASSERT_EQUAL(8,(int)titi.length());
+}
+
+void ExprEvalInterpTest::testDeleteWhiteSpaces()
+{
+ char toto[]=" jkhjkh ooooppp l ";
+ char result[]="jkhjkhoooopppl";
+ string totoS(toto);
+ string totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS);
+ CPPUNIT_ASSERT(totoR==result);
+ CPPUNIT_ASSERT_EQUAL(14,(int)totoR.length());
+ //
+ char toto2[]=" jkhjkh ooooppp l ";
+ totoS=toto2;
+ totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS);
+ CPPUNIT_ASSERT(totoR==result);
+ CPPUNIT_ASSERT_EQUAL(14,(int)totoR.length());
+ //
+ char toto3[]=" jkhjkh oooo pppl ";
+ totoS=toto3;
+ totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS);
+ CPPUNIT_ASSERT(totoR==result);
+ CPPUNIT_ASSERT_EQUAL(14,(int)totoR.length());
+ //
+ char toto4[]=" jkhjkh oooo pppl";
+ totoS=toto4;
+ totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS);
+ CPPUNIT_ASSERT(totoR==result);
+ CPPUNIT_ASSERT_EQUAL(14,(int)totoR.length());
+ //
+ char toto5[]="jkhjkh oooo pppl";
+ totoS=toto5;
+ totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS);
+ CPPUNIT_ASSERT(totoR==result);
+ CPPUNIT_ASSERT_EQUAL(14,(int)totoR.length());
+ //
+ totoS=result;
+ totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS);
+ CPPUNIT_ASSERT(totoR==result);
+ CPPUNIT_ASSERT_EQUAL(14,(int)totoR.length());
+ //
+ char toto6[]="j k h j k h o o o o p p p l";
+ totoS=toto6;
+ totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS);
+ CPPUNIT_ASSERT(totoR==result);
+ CPPUNIT_ASSERT_EQUAL(14,(int)totoR.length());
+ //
+ char toto7[]="j k h j k h o o o o p pp l";
+ totoS=toto7;
+ totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS);
+ CPPUNIT_ASSERT(totoR==result);
+ CPPUNIT_ASSERT_EQUAL(14,(int)totoR.length());
+ //
+ char toto8[]=" ";
+ totoS=toto8;
+ totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS);
+ CPPUNIT_ASSERT(totoR.empty());
+ //
+ char toto9[]="";
+ totoS=toto9;
+ totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS);
+ CPPUNIT_ASSERT(totoR.empty());
+ //
+ char toto10[]="j\n k \nh\nj \n\n k\nh \n o \no\n o\n o \np\n\npp \n\n l";
+ totoS=toto10;
+ totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS);
+ CPPUNIT_ASSERT(totoR==result);
+ CPPUNIT_ASSERT_EQUAL(14,(int)totoR.length());
+}
+
+void ExprEvalInterpTest::testInterpreter0()
+{
+ INTERP_KERNEL::ExprParser expr1("3*-2");
+ expr1.parse();
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(-6.,expr1.evaluate(),1e-15);
+ INTERP_KERNEL::ExprParser expr2("-2.3");
+ expr2.parse();
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(-2.3,expr2.evaluate(),1e-15);
+ INTERP_KERNEL::ExprParser expr3("--2.3");
+ expr3.parse();
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(2.3,expr3.evaluate(),1e-15);
+ INTERP_KERNEL::ExprParser expr4("-++2.3");
+ expr4.parse();
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(-2.3,expr4.evaluate(),1e-15);
+ INTERP_KERNEL::ExprParser expr5("+2.3");
+ expr5.parse();
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(2.3,expr5.evaluate(),1e-15);
+ INTERP_KERNEL::ExprParser expr6("3^-1");
+ expr6.parse();
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(0.33333333333333333,expr6.evaluate(),1e-15);
+}
+
+void ExprEvalInterpTest::testInterpreter1()
+{
+ INTERP_KERNEL::ExprParser expr1("3+2*5");
+ expr1.parse();
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(13.,expr1.evaluate(),1e-14);
+ INTERP_KERNEL::ExprParser expr2("3+2^3*5");
+ expr2.parse();
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(43.,expr2.evaluate(),1e-14);
+ INTERP_KERNEL::ExprParser expr3("3+2^(2*5)");
+ expr3.parse();
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(1027.,expr3.evaluate(),1e-14);
+ INTERP_KERNEL::ExprParser expr4("(3.2+4.3)*(1.3+2.3*7.8)");
+ expr4.parse();
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(144.3,expr4.evaluate(),1e-10);
+ INTERP_KERNEL::ExprParser expr5("(3.2+4.3)*cos(1.3+2.3*7.8)");
+ expr5.parse();
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(6.9355510138337619,expr5.evaluate(),1e-14);
+ INTERP_KERNEL::ExprParser expr6("3+2-4-7+4.3");
+ expr6.parse();
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.7,expr6.evaluate(),1e-14);
+ INTERP_KERNEL::ExprParser expr7("3.2*4.5/3.3/2.2");
+ expr7.parse();
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(1.9834710743801653,expr7.evaluate(),1e-14);
+ INTERP_KERNEL::ExprParser expr8("3.2*4.5/3.3/2.2");
+ expr8.parse();
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(1.9834710743801653,expr8.evaluate(),1e-14);
+ INTERP_KERNEL::ExprParser expr9("(((1.23456789)))");
+ expr9.parse();
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(1.23456789,expr9.evaluate(),1e-14);
+ INTERP_KERNEL::ExprParser expr10("3.2*((2*5.2+6.)+(1.2*1.2+3.))");
+ expr10.parse();
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(66.688,expr10.evaluate(),1e-13);
+ INTERP_KERNEL::ExprParser expr11("((3.2*(((2*5.2+6.)+(1.2*1.2+3.)))))");
+ expr11.parse();
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(66.688,expr11.evaluate(),1e-13);
+ INTERP_KERNEL::ExprParser expr12("((3.2*(cos((2*5.2+6.)+(1.2*1.2+3.)))))");
+ expr12.parse();
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.3038041398761016,expr12.evaluate(),1e-14);
+ INTERP_KERNEL::ExprParser expr13("((3.2*(sin((2*5.2+6.)+(1.2*1.2+3.)))))");
+ expr13.parse();
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(2.9223440531261784,expr13.evaluate(),1e-14);
+ INTERP_KERNEL::ExprParser expr14("((3.2*(tan((2*5.2+6.)+(1.2*1.2+3.)))))");
+ expr14.parse();
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(-7.1724737512280257,expr14.evaluate(),1e-14);
+ INTERP_KERNEL::ExprParser expr15("((3.2*(sqrt((2*5.2+6.)+(1.2*1.2+3.)))))");
+ expr15.parse();
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(14.608271629457059,expr15.evaluate(),1e-13);
+ INTERP_KERNEL::ExprParser expr16("-((3.2*(sqrt((2*5.2+6.)+(1.2*1.2+3.)))))");
+ expr16.parse();
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(-14.608271629457059,expr16.evaluate(),1e-13);
+ INTERP_KERNEL::ExprParser expr17("(-(3.2*(sqrt((2*5.2+6.)+(1.2*1.2+3.)))))");
+ expr17.parse();
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(-14.608271629457059,expr17.evaluate(),1e-13);
+ INTERP_KERNEL::ExprParser expr18("((-3.2*(sqrt((2*5.2+6.)+(1.2*1.2+3.)))))");
+ expr18.parse();
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(-14.608271629457059,expr18.evaluate(),1e-13);
+ INTERP_KERNEL::ExprParser expr19("((3.2*(exp((6.+2*5.2)+(1.2*1.2+3.)))))");
+ expr19.parse();
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(3596226038.1784945,expr19.evaluate(),1e-6);
+ INTERP_KERNEL::ExprParser expr20("((3.2*(ln((2*5.2+6.)+(1.2*1.2+3.)))))");
+ expr20.parse();
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(9.7179974940325309,expr20.evaluate(),1e-14);
+ INTERP_KERNEL::ExprParser expr21("max(3.2,4.5)");
+ expr21.parse();
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(4.5,expr21.evaluate(),1e-14);
+ INTERP_KERNEL::ExprParser expr22("3.*max(((3.2*(ln((2*5.2+6.)+(1.2*1.2+3.))))),((3.2*(exp((6.+2*5.2)+(1.2*1.2+3.))))))");
+ expr22.parse();
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(10788678114.535484,expr22.evaluate(),1e-5);
+ INTERP_KERNEL::ExprParser expr23("min(3.2,4.5)");
+ expr23.parse();
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(3.2,expr23.evaluate(),1e-14);
+}
+
+void ExprEvalInterpTest::testInterpreter2()
+{
+ INTERP_KERNEL::ExprParser expr1("3.5*x+x*x*x/(2+x)+2*5*y");
+ expr1.parse();
+ std::set<std::string> res,expected;
+ expr1.getSetOfVars(res);
+ CPPUNIT_ASSERT_EQUAL(2,(int)res.size());
+ expected.insert("x"); expected.insert("y");
+ CPPUNIT_ASSERT(std::equal(res.begin(),res.end(),expected.begin()));
+ double xyValue[2]={1.,3.};
+ double res1;
+ std::vector<std::string> vars; vars.push_back("x"); vars.push_back("y");
+ expr1.prepareExprEvaluation(vars);
+ expr1.evaluateExpr(1,&res1,xyValue);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(33.833333333333336,res1,1e-13);
+ xyValue[0]=-2.;
+ CPPUNIT_ASSERT_THROW(expr1.evaluateExpr(1,&res1,xyValue),INTERP_KERNEL::Exception);
+ double res2[2];
+ xyValue[0]=1.;
+ expr1.evaluateExpr(2,res2,xyValue);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(33.833333333333336,res2[0],1e-13);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(33.833333333333336,res2[1],1e-13);
+ INTERP_KERNEL::ExprParser expr2("3.5*tan(2.3*x)*IVec+(cos(1.2+y/x)*JVec)");
+ expr2.parse();
+ res.clear(); expected.clear();
+ expr2.getSetOfVars(res);
+ CPPUNIT_ASSERT_EQUAL(4,(int)res.size());
+ expected.insert("x"); expected.insert("y"); expected.insert("IVec"); expected.insert("JVec");
+ CPPUNIT_ASSERT(std::equal(res.begin(),res.end(),expected.begin()));
+ expr2.prepareExprEvaluation(vars);
+ expr2.evaluateExpr(2,res2,xyValue);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(-3.9172477460694637,res2[0],1e-14);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.49026082134069943,res2[1],1e-14);
+ INTERP_KERNEL::ExprParser expr3("3.5*u+u^2.4+2.");
+ expr3.parse();
+ expr3.prepareExprEvaluationVec();
+ expr3.evaluateExpr(2,res2,xyValue);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(6.5,res2[0],1e-14);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(26.466610165238237,res2[1],1e-14);
+ INTERP_KERNEL::ExprParser expr4("3.5*v+u^2.4+2.");
+ expr4.parse();
+ CPPUNIT_ASSERT_THROW(expr4.prepareExprEvaluationVec(),INTERP_KERNEL::Exception);
+}
+
+void ExprEvalInterpTest::testInterpreterUnit0()
+{
+ INTERP_KERNEL::ExprParser expr1("kg");
+ expr1.parse();
+ INTERP_KERNEL::DecompositionInUnitBase unit=expr1.evaluateUnit();
+ CPPUNIT_ASSERT(unit.isEqual(1,0,0,0,0,0.,1000.));
+ INTERP_KERNEL::ExprParser expr2("kgT");
+ expr2.parse();
+ CPPUNIT_ASSERT_THROW(expr2.evaluateUnit(),INTERP_KERNEL::Exception);
+ INTERP_KERNEL::ExprParser expr3("g");
+ expr3.parse();
+ unit=expr3.evaluateUnit();
+ CPPUNIT_ASSERT(unit.isEqual(1,0,0,0,0,0.,1.));
+ INTERP_KERNEL::ExprParser expr4("g*m");
+ expr4.parse();
+ unit=expr4.evaluateUnit();
+ CPPUNIT_ASSERT(unit.isEqual(1,1,0,0,0,0.,1.));
+ INTERP_KERNEL::ExprParser expr5("g*m/K");
+ expr5.parse();
+ unit=expr5.evaluateUnit();
+ CPPUNIT_ASSERT(unit.isEqual(1,1,0,0,-1,0.,1.));
+ INTERP_KERNEL::ExprParser expr6("g*m/K^2");
+ expr6.parse();
+ unit=expr6.evaluateUnit();
+ CPPUNIT_ASSERT(unit.isEqual(1,1,0,0,-2,0.,1.));
+ INTERP_KERNEL::ExprParser expr7("g/K^2*m");
+ expr7.parse();
+ unit=expr7.evaluateUnit();
+ CPPUNIT_ASSERT(unit.isEqual(1,1,0,0,-2,0.,1.));
+ INTERP_KERNEL::ExprParser expr8("g/(K^2*m)");
+ expr8.parse();
+ unit=expr8.evaluateUnit();
+ CPPUNIT_ASSERT(unit.isEqual(1,-1,0,0,-2,0.,1.));
+ INTERP_KERNEL::ExprParser expr9("km/h");
+ expr9.parse();
+ unit=expr9.evaluateUnit();
+ CPPUNIT_ASSERT(unit.isEqual(0,1,-1,0,0,0.,0.27777777777777779));
+ INTERP_KERNEL::ExprParser expr10("m/s");
+ expr10.parse();
+ unit=expr10.evaluateUnit();
+ CPPUNIT_ASSERT(unit.isEqual(0,1,-1,0,0,0.,1.));
+ INTERP_KERNEL::ExprParser expr11("m+s");
+ expr11.parse();
+ CPPUNIT_ASSERT_THROW(expr11.evaluateUnit(),INTERP_KERNEL::Exception);
+ INTERP_KERNEL::ExprParser expr12("m-m");
+ expr12.parse();
+ CPPUNIT_ASSERT_THROW(expr12.evaluateUnit(),INTERP_KERNEL::Exception);
+ const char expr13C[3]={-0x50,0x43,0x0};
+ INTERP_KERNEL::ExprParser expr13(expr13C);
+ expr13.parse();
+ unit=expr13.evaluateUnit();
+ CPPUNIT_ASSERT(unit.isEqual(0,0,0,0,1,273.15,1.));
+ const char expr14C[4]={-0x3E,-0x50,0x43,0x0};
+ INTERP_KERNEL::ExprParser expr14(expr14C);
+ expr14.parse();
+ unit=expr14.evaluateUnit();
+ CPPUNIT_ASSERT(unit.isEqual(0,0,0,0,1,273.15,1.));
+ INTERP_KERNEL::ExprParser expr15("kN/kg");
+ expr15.parse();
+ unit=expr15.evaluateUnit();
+ CPPUNIT_ASSERT(unit.isEqual(0,1,-2,0,0,0.,1000.));
+ INTERP_KERNEL::ExprParser expr16("cm");
+ expr16.parse();
+ unit=expr16.evaluateUnit();
+ CPPUNIT_ASSERT(unit.isEqual(0,1,0,0,0,0.,0.01));
+ INTERP_KERNEL::ExprParser expr17("m");
+ expr17.parse();
+ unit=expr17.evaluateUnit();
+ CPPUNIT_ASSERT(unit.isEqual(0,1,0,0,0,0.,1));
+ const char expr18C[3]={-0x08,0x43,0x0};
+ INTERP_KERNEL::ExprParser expr18(expr18C);
+ expr18.parse();
+ unit=expr18.evaluateUnit();
+ CPPUNIT_ASSERT(unit.isEqual(0,0,0,0,1,273.15,1.));
+ const char expr19C[6]={-0x50,0x43,0x2F,-0x50,0x43,0x0};
+ INTERP_KERNEL::ExprParser expr19(expr19C);
+ expr19.parse();
+ unit=expr19.evaluateUnit();
+ CPPUNIT_ASSERT(unit.isEqual(0,0,0,0,0,0.,1.));
+ const char expr20C[9]={-0x50,0x43,0x2A,-0x50,0x43,0x2F,-0x50,0x43,0x0};
+ INTERP_KERNEL::ExprParser expr20(expr20C);
+ expr20.parse();
+ unit=expr20.evaluateUnit();
+ CPPUNIT_ASSERT(unit.isEqual(0,0,0,0,1,0.,1.));
+}
+
+void ExprEvalInterpTest::testInterpreterUnit1()
+{
+ INTERP_KERNEL::Unit unit1("m/s");
+ INTERP_KERNEL::Unit unit2("km/h");
+ CPPUNIT_ASSERT(unit1.isCompatibleWith(unit2) && unit2.isCompatibleWith(unit1));
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(360,unit1.convert(unit2,100.),1e-10);
+ INTERP_KERNEL::Unit unit3("J/s");
+ INTERP_KERNEL::Unit unit4("kW");
+ CPPUNIT_ASSERT(unit3.isCompatibleWith(unit4) && unit4.isCompatibleWith(unit3));
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,unit3.convert(unit4,1000.),1e-10);
+ CPPUNIT_ASSERT(unit4.getCoarseRepr()=="kW");
+ INTERP_KERNEL::Unit unit5("kpT");
+ CPPUNIT_ASSERT(!unit5.isInterpretationOK());
+ CPPUNIT_ASSERT(unit5.getCoarseRepr()=="kpT");
+ INTERP_KERNEL::Unit unit6("m*kpT");
+ CPPUNIT_ASSERT(!unit6.isInterpretationOK());
+ INTERP_KERNEL::Unit unit7("m*s^-1");
+ CPPUNIT_ASSERT(unit7.isCompatibleWith(unit2) && unit2.isCompatibleWith(unit7));
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(360,unit7.convert(unit2,100.),1e-10);
+ const char unit8C[3]={-0x50,0x43,0x0};
+ INTERP_KERNEL::Unit unit8(unit8C);
+ INTERP_KERNEL::Unit unit9("K");
+ CPPUNIT_ASSERT(unit9.isCompatibleWith(unit8) && unit8.isCompatibleWith(unit9));
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(335.15,unit8.convert(unit9,62.),1e-10);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(-16.37,unit9.convert(unit8,256.78),1e-10);
+ INTERP_KERNEL::Unit unit10("m");
+ INTERP_KERNEL::Unit unit11("cm");
+ CPPUNIT_ASSERT(unit10.isCompatibleWith(unit11) && unit11.isCompatibleWith(unit10));
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(6200.,unit10.convert(unit11,62.),1e-8);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(0.62,unit11.convert(unit10,62.),1e-15);
+ INTERP_KERNEL::Unit unit12("m-m");
+ CPPUNIT_ASSERT(!unit12.isInterpretationOK());
+}
--- /dev/null
+// Copyright (C) 2007-2008 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#ifndef _EXPREVALINTERPTEST_HXX_
+#define _EXPREVALINTERPTEST_HXX_
+
+#include <cppunit/extensions/HelperMacros.h>
+
+#include "InterpKernelTestExport.hxx"
+
+namespace INTERP_TEST
+{
+ class INTERPKERNELTEST_EXPORT ExprEvalInterpTest : public CppUnit::TestFixture
+ {
+ CPPUNIT_TEST_SUITE( ExprEvalInterpTest );
+ CPPUNIT_TEST( testBuildStringFromFortran );
+ CPPUNIT_TEST( testDeleteWhiteSpaces );
+ CPPUNIT_TEST( testInterpreter0 );
+ CPPUNIT_TEST( testInterpreter1 );
+ CPPUNIT_TEST( testInterpreter2 );
+ CPPUNIT_TEST( testInterpreterUnit0 );
+ CPPUNIT_TEST( testInterpreterUnit1 );
+ CPPUNIT_TEST_SUITE_END();
+ public:
+ void setUp() { }
+ void tearDown() { }
+ void cleanUp() { }
+ void testBuildStringFromFortran();
+ void testDeleteWhiteSpaces();
+ void testInterpreter0();
+ void testInterpreter1();
+ void testInterpreter2();
+ void testInterpreterUnit0();
+ void testInterpreterUnit1();
+ };
+}
+
+#endif
CppUnitTest.hxx \
CppUnitTest.cxx \
InterpolationPlanarTestSuite.hxx \
+ ExprEvalInterpTest.hxx \
+ ExprEvalInterpTest.cxx \
QuadraticPlanarInterpTest.hxx \
QuadraticPlanarInterpTest.cxx \
QuadraticPlanarInterpTest2.cxx \
-I$(srcdir)/../INTERP_KERNEL \
-I$(srcdir)/../INTERP_KERNEL/Geometric2D \
-I$(srcdir)/../INTERP_KERNEL/Bases \
+ -I$(srcdir)/../INTERP_KERNEL/ExprEval \
-DOPTIMIZE -DLOG_LEVEL=0
libInterpKernelTest_la_LDFLAGS = \
#include "CppUnitTest.hxx"
#include "BBTreeTest.hxx"
+#include "ExprEvalInterpTest.hxx"
#include "QuadraticPlanarInterpTest.hxx"
#include "SingleElementPlanarTests.hxx"
#include "TransformedTriangleIntersectTest.hxx"
//--- Registers the fixture into the 'registry'
CPPUNIT_TEST_SUITE_REGISTRATION( BBTreeTest);
+CPPUNIT_TEST_SUITE_REGISTRATION( ExprEvalInterpTest );
CPPUNIT_TEST_SUITE_REGISTRATION( QuadraticPlanarInterpTest );
CPPUNIT_TEST_SUITE_REGISTRATION( SingleElementPlanarTests );
CPPUNIT_TEST_SUITE_REGISTRATION( TransformedTriangleIntersectTest );