+++ /dev/null
-/*\r
- __________ \r
- _____ __ __\______ \_____ _______ ______ ____ _______ \r
- / \ | | \| ___/\__ \ \_ __ \/ ___/_/ __ \\_ __ \\r
- | Y Y \| | /| | / __ \_| | \/\___ \ \ ___/ | | \/\r
- |__|_| /|____/ |____| (____ /|__| /____ > \___ >|__| \r
- \/ \/ \/ \/ \r
- Copyright (C) 2011 Ingo Berg\r
-\r
- Permission is hereby granted, free of charge, to any person obtaining a copy of this \r
- software and associated documentation files (the "Software"), to deal in the Software\r
- without restriction, including without limitation the rights to use, copy, modify, \r
- merge, publish, distribute, sublicense, and/or sell copies of the Software, and to \r
- permit persons to whom the Software is furnished to do so, subject to the following conditions:\r
-\r
- The above copyright notice and this permission notice shall be included in all copies or \r
- substantial portions of the Software.\r
-\r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT\r
- NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND \r
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, \r
- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, \r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \r
-*/\r
-#ifndef MU_PARSER_DLL_H\r
-#define MU_PARSER_DLL_H\r
-\r
-#if defined(WIN32) || defined(_WIN32)\r
- #ifdef MUPARSERLIB_EXPORTS\r
- #define API_EXPORT(TYPE) __declspec(dllexport) TYPE __cdecl\r
- #else\r
- #define API_EXPORT(TYPE) __declspec(dllimport) TYPE __cdecl\r
- #endif\r
-#else\r
- #define API_EXPORT(TYPE) TYPE\r
-#endif\r
-\r
-\r
-#ifdef __cplusplus\r
-extern "C"\r
-{\r
-#endif\r
-\r
-/** \file \r
- \brief This file contains the DLL interface of muparser.\r
-*/\r
-\r
-// Basic types\r
-typedef void* muParserHandle_t; // parser handle\r
-typedef char muChar_t; // character type\r
-typedef int muBool_t; // boolean type\r
-typedef int muInt_t; // integer type \r
-typedef double muFloat_t; // floating point type\r
-\r
-// function types for calculation\r
-typedef muFloat_t (*muFun0_t )(); \r
-typedef muFloat_t (*muFun1_t )(muFloat_t); \r
-typedef muFloat_t (*muFun2_t )(muFloat_t, muFloat_t); \r
-typedef muFloat_t (*muFun3_t )(muFloat_t, muFloat_t, muFloat_t); \r
-typedef muFloat_t (*muFun4_t )(muFloat_t, muFloat_t, muFloat_t, muFloat_t); \r
-typedef muFloat_t (*muFun5_t )(muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t); \r
-typedef muFloat_t (*muFun6_t )(muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t); \r
-typedef muFloat_t (*muFun7_t )(muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t); \r
-typedef muFloat_t (*muFun8_t )(muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t); \r
-typedef muFloat_t (*muFun9_t )(muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t); \r
-typedef muFloat_t (*muFun10_t)(muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t); \r
-\r
-// Function prototypes for bulkmode functions\r
-typedef muFloat_t (*muBulkFun0_t )(int, int); \r
-typedef muFloat_t (*muBulkFun1_t )(int, int, muFloat_t); \r
-typedef muFloat_t (*muBulkFun2_t )(int, int, muFloat_t, muFloat_t); \r
-typedef muFloat_t (*muBulkFun3_t )(int, int, muFloat_t, muFloat_t, muFloat_t); \r
-typedef muFloat_t (*muBulkFun4_t )(int, int, muFloat_t, muFloat_t, muFloat_t, muFloat_t); \r
-typedef muFloat_t (*muBulkFun5_t )(int, int, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t); \r
-typedef muFloat_t (*muBulkFun6_t )(int, int, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t); \r
-typedef muFloat_t (*muBulkFun7_t )(int, int, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t); \r
-typedef muFloat_t (*muBulkFun8_t )(int, int, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t); \r
-typedef muFloat_t (*muBulkFun9_t )(int, int, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t); \r
-typedef muFloat_t (*muBulkFun10_t)(int, int, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t); \r
-\r
-typedef muFloat_t (*muMultFun_t)(const muFloat_t*, muInt_t);\r
-typedef muFloat_t (*muStrFun1_t)(const muChar_t*);\r
-typedef muFloat_t (*muStrFun2_t)(const muChar_t*, muFloat_t);\r
-typedef muFloat_t (*muStrFun3_t)(const muChar_t*, muFloat_t, muFloat_t);\r
-\r
-// Functions for parser management\r
-typedef void (*muErrorHandler_t)(muParserHandle_t a_hParser); // [optional] callback to an error handler\r
-typedef muFloat_t* (*muFacFun_t)(const muChar_t*, void*); // [optional] callback for creating new variables\r
-typedef muInt_t (*muIdentFun_t)(const muChar_t*, muInt_t*, muFloat_t*); // [optional] value identification callbacks\r
-\r
-//-----------------------------------------------------------------------------------------------------\r
-// Constants\r
-static const int muOPRT_ASCT_LEFT = 0;\r
-static const int muOPRT_ASCT_RIGHT = 1;\r
-\r
-static const int muBASETYPE_FLOAT = 0;\r
-static const int muBASETYPE_INT = 1;\r
-\r
-//-----------------------------------------------------------------------------------------------------\r
-//\r
-//\r
-// muParser C compatible bindings\r
-//\r
-//\r
-//-----------------------------------------------------------------------------------------------------\r
-\r
-\r
-// Basic operations / initialization \r
-API_EXPORT(muParserHandle_t) mupCreate(int nBaseType);\r
-API_EXPORT(void) mupRelease(muParserHandle_t a_hParser);\r
-API_EXPORT(const muChar_t*) mupGetExpr(muParserHandle_t a_hParser);\r
-API_EXPORT(void) mupSetExpr(muParserHandle_t a_hParser, const muChar_t *a_szExpr);\r
-API_EXPORT(void) mupSetVarFactory(muParserHandle_t a_hParser, muFacFun_t a_pFactory, void* pUserData);\r
-API_EXPORT(const muChar_t*) mupGetVersion(muParserHandle_t a_hParser);\r
-API_EXPORT(muFloat_t) mupEval(muParserHandle_t a_hParser);\r
-API_EXPORT(muFloat_t*) mupEvalMulti(muParserHandle_t a_hParser, int *nNum);\r
-API_EXPORT(void) mupEvalBulk(muParserHandle_t a_hParser, muFloat_t *a_fResult, int nSize);\r
-\r
-// Defining callbacks / variables / constants\r
-API_EXPORT(void) mupDefineFun0(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun0_t a_pFun, muBool_t a_bOptimize);\r
-API_EXPORT(void) mupDefineFun1(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun1_t a_pFun, muBool_t a_bOptimize);\r
-API_EXPORT(void) mupDefineFun2(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun2_t a_pFun, muBool_t a_bOptimize);\r
-API_EXPORT(void) mupDefineFun3(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun3_t a_pFun, muBool_t a_bOptimize);\r
-API_EXPORT(void) mupDefineFun4(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun4_t a_pFun, muBool_t a_bOptimize);\r
-API_EXPORT(void) mupDefineFun5(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun5_t a_pFun, muBool_t a_bOptimize);\r
-API_EXPORT(void) mupDefineFun6(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun6_t a_pFun, muBool_t a_bOptimize);\r
-API_EXPORT(void) mupDefineFun7(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun7_t a_pFun, muBool_t a_bOptimize);\r
-API_EXPORT(void) mupDefineFun8(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun8_t a_pFun, muBool_t a_bOptimize);\r
-API_EXPORT(void) mupDefineFun9(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun9_t a_pFun, muBool_t a_bOptimize);\r
-API_EXPORT(void) mupDefineFun10(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun10_t a_pFun, muBool_t a_bOptimize);\r
-\r
-// Defining bulkmode functions\r
-API_EXPORT(void) mupDefineBulkFun0(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun0_t a_pFun);\r
-API_EXPORT(void) mupDefineBulkFun1(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun1_t a_pFun);\r
-API_EXPORT(void) mupDefineBulkFun2(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun2_t a_pFun);\r
-API_EXPORT(void) mupDefineBulkFun3(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun3_t a_pFun);\r
-API_EXPORT(void) mupDefineBulkFun4(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun4_t a_pFun);\r
-API_EXPORT(void) mupDefineBulkFun5(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun5_t a_pFun);\r
-API_EXPORT(void) mupDefineBulkFun6(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun6_t a_pFun);\r
-API_EXPORT(void) mupDefineBulkFun7(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun7_t a_pFun);\r
-API_EXPORT(void) mupDefineBulkFun8(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun8_t a_pFun);\r
-API_EXPORT(void) mupDefineBulkFun9(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun9_t a_pFun);\r
-API_EXPORT(void) mupDefineBulkFun10(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun10_t a_pFun);\r
-\r
-// string functions\r
-API_EXPORT(void) mupDefineStrFun1(muParserHandle_t a_hParser, const muChar_t *a_szName, muStrFun1_t a_pFun);\r
-API_EXPORT(void) mupDefineStrFun2(muParserHandle_t a_hParser, const muChar_t *a_szName, muStrFun2_t a_pFun);\r
-API_EXPORT(void) mupDefineStrFun3(muParserHandle_t a_hParser, const muChar_t *a_szName, muStrFun3_t a_pFun);\r
-\r
-API_EXPORT(void) mupDefineMultFun( muParserHandle_t a_hParser, \r
- const muChar_t* a_szName, \r
- muMultFun_t a_pFun, \r
- muBool_t a_bOptimize);\r
-\r
-API_EXPORT(void) mupDefineOprt( muParserHandle_t a_hParser, \r
- const muChar_t* a_szName, \r
- muFun2_t a_pFun, \r
- muInt_t a_nPrec, \r
- muInt_t a_nOprtAsct,\r
- muBool_t a_bOptimize);\r
-\r
-API_EXPORT(void) mupDefineConst( muParserHandle_t a_hParser, \r
- const muChar_t* a_szName, \r
- muFloat_t a_fVal );\r
-\r
-API_EXPORT(void) mupDefineStrConst( muParserHandle_t a_hParser, \r
- const muChar_t* a_szName, \r
- const muChar_t *a_sVal );\r
-\r
-API_EXPORT(void) mupDefineVar( muParserHandle_t a_hParser, \r
- const muChar_t* a_szName, \r
- muFloat_t *a_fVar);\r
-\r
-API_EXPORT(void) mupDefineBulkVar( muParserHandle_t a_hParser, \r
- const muChar_t* a_szName, \r
- muFloat_t *a_fVar);\r
-\r
-API_EXPORT(void) mupDefinePostfixOprt( muParserHandle_t a_hParser, \r
- const muChar_t* a_szName, \r
- muFun1_t a_pOprt, \r
- muBool_t a_bOptimize);\r
-\r
-\r
-API_EXPORT(void) mupDefineInfixOprt( muParserHandle_t a_hParser, \r
- const muChar_t* a_szName, \r
- muFun1_t a_pOprt, \r
- muBool_t a_bOptimize);\r
-\r
-// Define character sets for identifiers\r
-API_EXPORT(void) mupDefineNameChars(muParserHandle_t a_hParser, const muChar_t* a_szCharset);\r
-API_EXPORT(void) mupDefineOprtChars(muParserHandle_t a_hParser, const muChar_t* a_szCharset);\r
-API_EXPORT(void) mupDefineInfixOprtChars(muParserHandle_t a_hParser, const muChar_t* a_szCharset);\r
-\r
-// Remove all / single variables\r
-API_EXPORT(void) mupRemoveVar(muParserHandle_t a_hParser, const muChar_t* a_szName);\r
-API_EXPORT(void) mupClearVar(muParserHandle_t a_hParser);\r
-API_EXPORT(void) mupClearConst(muParserHandle_t a_hParser);\r
-API_EXPORT(void) mupClearOprt(muParserHandle_t a_hParser);\r
-API_EXPORT(void) mupClearFun(muParserHandle_t a_hParser);\r
-\r
-// Querying variables / expression variables / constants\r
-API_EXPORT(int) mupGetExprVarNum(muParserHandle_t a_hParser);\r
-API_EXPORT(int) mupGetVarNum(muParserHandle_t a_hParser);\r
-API_EXPORT(int) mupGetConstNum(muParserHandle_t a_hParser);\r
-API_EXPORT(void) mupGetExprVar(muParserHandle_t a_hParser, unsigned a_iVar, const muChar_t** a_pszName, muFloat_t** a_pVar);\r
-API_EXPORT(void) mupGetVar(muParserHandle_t a_hParser, unsigned a_iVar, const muChar_t** a_pszName, muFloat_t** a_pVar);\r
-API_EXPORT(void) mupGetConst(muParserHandle_t a_hParser, unsigned a_iVar, const muChar_t** a_pszName, muFloat_t* a_pVar);\r
-API_EXPORT(void) mupSetArgSep(muParserHandle_t a_hParser, const muChar_t cArgSep);\r
-API_EXPORT(void) mupSetDecSep(muParserHandle_t a_hParser, const muChar_t cArgSep);\r
-API_EXPORT(void) mupSetThousandsSep(muParserHandle_t a_hParser, const muChar_t cArgSep);\r
-API_EXPORT(void) mupResetLocale(muParserHandle_t a_hParser);\r
-\r
-// Add value recognition callbacks\r
-API_EXPORT(void) mupAddValIdent(muParserHandle_t a_hParser, muIdentFun_t);\r
-\r
-// Error handling\r
-API_EXPORT(muBool_t) mupError(muParserHandle_t a_hParser);\r
-API_EXPORT(void) mupErrorReset(muParserHandle_t a_hParser);\r
-API_EXPORT(void) mupSetErrorHandler(muParserHandle_t a_hParser, muErrorHandler_t a_pErrHandler);\r
-API_EXPORT(const muChar_t*) mupGetErrorMsg(muParserHandle_t a_hParser);\r
-API_EXPORT(muInt_t) mupGetErrorCode(muParserHandle_t a_hParser);\r
-API_EXPORT(muInt_t) mupGetErrorPos(muParserHandle_t a_hParser);\r
-API_EXPORT(const muChar_t*) mupGetErrorToken(muParserHandle_t a_hParser);\r
-//API_EXPORT(const muChar_t*) mupGetErrorExpr(muParserHandle_t a_hParser);\r
-\r
-// This is used for .NET only. It creates a new variable allowing the dll to\r
-// manage the variable rather than the .NET garbage collector.\r
-API_EXPORT(muFloat_t*) mupCreateVar();\r
-API_EXPORT(void) mupReleaseVar(muFloat_t*);\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-#endif // include guard\r
+++ /dev/null
-/*\r
- __________ \r
- _____ __ __\______ \_____ _______ ______ ____ _______ \r
- / \ | | \| ___/\__ \ \_ __ \/ ___/_/ __ \\_ __ \\r
- | Y Y \| | /| | / __ \_| | \/\___ \ \ ___/ | | \/\r
- |__|_| /|____/ |____| (____ /|__| /____ > \___ >|__| \r
- \/ \/ \/ \/ \r
- Copyright (C) 2004-2011 Ingo Berg\r
-\r
- Permission is hereby granted, free of charge, to any person obtaining a copy of this \r
- software and associated documentation files (the "Software"), to deal in the Software\r
- without restriction, including without limitation the rights to use, copy, modify, \r
- merge, publish, distribute, sublicense, and/or sell copies of the Software, and to \r
- permit persons to whom the Software is furnished to do so, subject to the following conditions:\r
-\r
- The above copyright notice and this permission notice shall be included in all copies or \r
- substantial portions of the Software.\r
-\r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT\r
- NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND \r
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, \r
- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, \r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \r
-*/\r
-#if defined(MUPARSER_DLL) \r
-\r
-#if defined(_WIN32)\r
- #define WIN32_LEAN_AND_MEAN\r
- #include <windows.h>\r
-#endif\r
-\r
-#include "muParserDLL.h"\r
-#include "muParser.h"\r
-#include "muParserInt.h"\r
-#include "muParserError.h"\r
-\r
-\r
-#define MU_TRY \\r
- try \\r
- {\r
-\r
-#define MU_CATCH \\r
- } \\r
- catch(muError_t &e) \\r
- { \\r
- ParserTag *pTag = static_cast<ParserTag*>(a_hParser); \\r
- pTag->exc = e; \\r
- pTag->bError = true; \\r
- if (pTag->errHandler) \\r
- (pTag->errHandler)(a_hParser); \\r
- } \\r
- catch(...) \\r
- { \\r
- ParserTag *pTag = static_cast<ParserTag*>(a_hParser); \\r
- pTag->exc = muError_t(mu::ecINTERNAL_ERROR); \\r
- pTag->bError = true; \\r
- if (pTag->errHandler) \\r
- (pTag->errHandler)(a_hParser); \\r
- }\r
-\r
-/** \file \r
- \brief This file contains the implementation of the DLL interface of muparser.\r
-*/\r
-\r
-//---------------------------------------------------------------------------\r
-// private types\r
-typedef mu::ParserBase::exception_type muError_t;\r
-typedef mu::ParserBase muParser_t;\r
-\r
-int g_nBulkSize;\r
-\r
-//---------------------------------------------------------------------------\r
-class ParserTag\r
-{\r
-public:\r
- ParserTag(int nType)\r
- :pParser( (nType==muBASETYPE_FLOAT) ? (mu::ParserBase*)new mu::Parser() : \r
- (nType==muBASETYPE_INT) ? (mu::ParserBase*)new mu::ParserInt() : NULL)\r
- ,exc()\r
- ,errHandler(NULL)\r
- ,bError(false)\r
- ,m_nParserType(nType)\r
- {}\r
- \r
- ~ParserTag()\r
- {\r
- delete pParser;\r
- }\r
-\r
- mu::ParserBase *pParser;\r
- mu::ParserBase::exception_type exc;\r
- muErrorHandler_t errHandler;\r
- bool bError;\r
-\r
-private:\r
- ParserTag(const ParserTag &ref);\r
- ParserTag& operator=(const ParserTag &ref);\r
-\r
- int m_nParserType;\r
-};\r
-\r
-static muChar_t s_tmpOutBuf[2048];\r
-\r
-//---------------------------------------------------------------------------\r
-//\r
-//\r
-// unexported functions\r
-//\r
-//\r
-//---------------------------------------------------------------------------\r
-\r
-//---------------------------------------------------------------------------\r
-muParser_t* AsParser(muParserHandle_t a_hParser)\r
-{\r
- return static_cast<ParserTag*>(a_hParser)->pParser;\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-ParserTag* AsParserTag(muParserHandle_t a_hParser)\r
-{\r
- return static_cast<ParserTag*>(a_hParser);\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-#if defined(_WIN32)\r
- #define _CRT_SECURE_NO_DEPRECATE\r
-\r
- BOOL APIENTRY DllMain( HANDLE /*hModule*/, \r
- DWORD ul_reason_for_call, \r
- LPVOID /*lpReserved*/ )\r
- {\r
- switch (ul_reason_for_call)\r
- {\r
- case DLL_PROCESS_ATTACH:\r
- break;\r
-\r
- case DLL_THREAD_ATTACH:\r
- case DLL_THREAD_DETACH:\r
- case DLL_PROCESS_DETACH:\r
- break;\r
- }\r
-\r
- return TRUE;\r
- }\r
-\r
-#endif\r
-\r
-//---------------------------------------------------------------------------\r
-//\r
-//\r
-// exported functions\r
-//\r
-//\r
-//---------------------------------------------------------------------------\r
-\r
-API_EXPORT(void) mupSetVarFactory(muParserHandle_t a_hParser, muFacFun_t a_pFactory, void *pUserData)\r
-{\r
- MU_TRY\r
- muParser_t* p(AsParser(a_hParser));\r
- p->SetVarFactory(a_pFactory, pUserData);\r
- MU_CATCH\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-/** \brief Create a new Parser instance and return its handle.\r
-*/\r
-API_EXPORT(muParserHandle_t) mupCreate(int nBaseType)\r
-{\r
- switch(nBaseType)\r
- {\r
- case muBASETYPE_FLOAT: return (void*)(new ParserTag(muBASETYPE_FLOAT));\r
- case muBASETYPE_INT: return (void*)(new ParserTag(muBASETYPE_INT));\r
- default: return NULL;\r
- }\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-/** \brief Release the parser instance related with a parser handle.\r
-*/\r
-API_EXPORT(void) mupRelease(muParserHandle_t a_hParser)\r
-{\r
- MU_TRY\r
- ParserTag* p = static_cast<ParserTag*>(a_hParser);\r
- delete p;\r
- MU_CATCH\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-API_EXPORT(const muChar_t*) mupGetVersion(muParserHandle_t a_hParser)\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- sprintf(s_tmpOutBuf, "%s", p->GetVersion().c_str());\r
- return s_tmpOutBuf;\r
- MU_CATCH\r
-\r
- return "";\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-/** \brief Evaluate the expression.\r
-*/\r
-API_EXPORT(muFloat_t) mupEval(muParserHandle_t a_hParser)\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- return p->Eval();\r
- MU_CATCH\r
-\r
- return 0;\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-API_EXPORT(muFloat_t*) mupEvalMulti(muParserHandle_t a_hParser, int *nNum)\r
-{\r
- MU_TRY\r
- assert(nNum!=NULL);\r
-\r
- muParser_t* const p(AsParser(a_hParser));\r
- return p->Eval(*nNum);\r
- MU_CATCH\r
-\r
- return 0;\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-API_EXPORT(void) mupEvalBulk(muParserHandle_t a_hParser, muFloat_t *a_res, int nSize)\r
-{\r
- MU_TRY\r
- muParser_t* p(AsParser(a_hParser));\r
- p->Eval(a_res, nSize);\r
- MU_CATCH\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-API_EXPORT(void) mupSetExpr(muParserHandle_t a_hParser, const muChar_t* a_szExpr)\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- p->SetExpr(a_szExpr);\r
- MU_CATCH\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-API_EXPORT(void) mupRemoveVar(muParserHandle_t a_hParser, const muChar_t* a_szName)\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- p->RemoveVar( a_szName );\r
- MU_CATCH\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-/** \brief Release all parser variables.\r
- \param a_hParser Handle to the parser instance.\r
-*/\r
-API_EXPORT(void) mupClearVar(muParserHandle_t a_hParser)\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- p->ClearVar();\r
- MU_CATCH\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-/** \brief Release all parser variables.\r
- \param a_hParser Handle to the parser instance.\r
-*/\r
-API_EXPORT(void) mupClearConst(muParserHandle_t a_hParser)\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- p->ClearConst();\r
- MU_CATCH\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-/** \brief Clear all user defined operators.\r
- \param a_hParser Handle to the parser instance.\r
-*/\r
-API_EXPORT(void) mupClearOprt(muParserHandle_t a_hParser)\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- p->ClearOprt();\r
- MU_CATCH\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-API_EXPORT(void) mupClearFun(muParserHandle_t a_hParser)\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- p->ClearFun();\r
- MU_CATCH\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-API_EXPORT(void) mupDefineFun0( muParserHandle_t a_hParser, \r
- const muChar_t* a_szName, \r
- muFun0_t a_pFun, \r
- muBool_t a_bAllowOpt )\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- p->DefineFun(a_szName, a_pFun, a_bAllowOpt!=0);\r
- MU_CATCH\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-API_EXPORT(void) mupDefineFun1( muParserHandle_t a_hParser, \r
- const muChar_t* a_szName, \r
- muFun1_t a_pFun, \r
- muBool_t a_bAllowOpt )\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- p->DefineFun(a_szName, a_pFun, a_bAllowOpt!=0);\r
- MU_CATCH\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-API_EXPORT(void) mupDefineFun2( muParserHandle_t a_hParser, \r
- const muChar_t* a_szName, \r
- muFun2_t a_pFun, \r
- muBool_t a_bAllowOpt )\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- p->DefineFun(a_szName, a_pFun, a_bAllowOpt!=0);\r
- MU_CATCH\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-API_EXPORT(void) mupDefineFun3( muParserHandle_t a_hParser, \r
- const muChar_t *a_szName, \r
- muFun3_t a_pFun, \r
- muBool_t a_bAllowOpt )\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- p->DefineFun(a_szName, a_pFun, a_bAllowOpt!=0);\r
- MU_CATCH\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-API_EXPORT(void) mupDefineFun4( muParserHandle_t a_hParser, \r
- const muChar_t *a_szName, \r
- muFun4_t a_pFun, \r
- muBool_t a_bAllowOpt )\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- p->DefineFun(a_szName, a_pFun, a_bAllowOpt!=0);\r
- MU_CATCH\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-API_EXPORT(void) mupDefineFun5( muParserHandle_t a_hParser, \r
- const muChar_t *a_szName, \r
- muFun5_t a_pFun, \r
- muBool_t a_bAllowOpt )\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- p->DefineFun(a_szName, a_pFun, a_bAllowOpt!=0);\r
- MU_CATCH\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-API_EXPORT(void) mupDefineFun6( muParserHandle_t a_hParser, \r
- const muChar_t *a_szName, \r
- muFun6_t a_pFun, \r
- muBool_t a_bAllowOpt )\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- p->DefineFun(a_szName, a_pFun, a_bAllowOpt!=0);\r
- MU_CATCH\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-API_EXPORT(void) mupDefineFun7( muParserHandle_t a_hParser, \r
- const muChar_t *a_szName, \r
- muFun7_t a_pFun, \r
- muBool_t a_bAllowOpt )\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- p->DefineFun(a_szName, a_pFun, a_bAllowOpt!=0);\r
- MU_CATCH\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-API_EXPORT(void) mupDefineFun8( muParserHandle_t a_hParser, \r
- const muChar_t *a_szName, \r
- muFun8_t a_pFun, \r
- muBool_t a_bAllowOpt )\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- p->DefineFun(a_szName, a_pFun, a_bAllowOpt!=0);\r
- MU_CATCH\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-API_EXPORT(void) mupDefineFun9( muParserHandle_t a_hParser, \r
- const muChar_t *a_szName, \r
- muFun9_t a_pFun, \r
- muBool_t a_bAllowOpt )\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- p->DefineFun(a_szName, a_pFun, a_bAllowOpt!=0);\r
- MU_CATCH\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-API_EXPORT(void) mupDefineFun10( muParserHandle_t a_hParser, \r
- const muChar_t *a_szName, \r
- muFun10_t a_pFun, \r
- muBool_t a_bAllowOpt )\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- p->DefineFun(a_szName, a_pFun, a_bAllowOpt!=0);\r
- MU_CATCH\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-API_EXPORT(void) mupDefineBulkFun0(muParserHandle_t a_hParser, \r
- const muChar_t* a_szName, \r
- muBulkFun0_t a_pFun)\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- p->DefineFun(a_szName, a_pFun, false);\r
- MU_CATCH\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-API_EXPORT(void) mupDefineBulkFun1(muParserHandle_t a_hParser, \r
- const muChar_t* a_szName, \r
- muBulkFun1_t a_pFun)\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- p->DefineFun(a_szName, a_pFun, false);\r
- MU_CATCH\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-API_EXPORT(void) mupDefineBulkFun2(muParserHandle_t a_hParser, \r
- const muChar_t* a_szName, \r
- muBulkFun2_t a_pFun)\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- p->DefineFun(a_szName, a_pFun, false);\r
- MU_CATCH\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-API_EXPORT(void) mupDefineBulkFun3(muParserHandle_t a_hParser, \r
- const muChar_t *a_szName, \r
- muBulkFun3_t a_pFun)\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- p->DefineFun(a_szName, a_pFun, false);\r
- MU_CATCH\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-API_EXPORT(void) mupDefineBulkFun4(muParserHandle_t a_hParser, \r
- const muChar_t *a_szName, \r
- muBulkFun4_t a_pFun)\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- p->DefineFun(a_szName, a_pFun, false);\r
- MU_CATCH\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-API_EXPORT(void) mupDefineBulkFun5(muParserHandle_t a_hParser, \r
- const muChar_t *a_szName, \r
- muBulkFun5_t a_pFun)\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- p->DefineFun(a_szName, a_pFun, false);\r
- MU_CATCH\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-API_EXPORT(void) mupDefineBulkFun6(muParserHandle_t a_hParser, \r
- const muChar_t *a_szName, \r
- muBulkFun6_t a_pFun)\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- p->DefineFun(a_szName, a_pFun, false);\r
- MU_CATCH\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-API_EXPORT(void) mupDefineBulkFun7(muParserHandle_t a_hParser, \r
- const muChar_t *a_szName, \r
- muBulkFun7_t a_pFun)\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- p->DefineFun(a_szName, a_pFun, false);\r
- MU_CATCH\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-API_EXPORT(void) mupDefineBulkFun8(muParserHandle_t a_hParser, \r
- const muChar_t *a_szName, \r
- muBulkFun8_t a_pFun)\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- p->DefineFun(a_szName, a_pFun, false);\r
- MU_CATCH\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-API_EXPORT(void) mupDefineBulkFun9(muParserHandle_t a_hParser, \r
- const muChar_t *a_szName, \r
- muBulkFun9_t a_pFun)\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- p->DefineFun(a_szName, a_pFun, false);\r
- MU_CATCH\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-API_EXPORT(void) mupDefineBulkFun10( muParserHandle_t a_hParser, \r
- const muChar_t *a_szName, \r
- muBulkFun10_t a_pFun)\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- p->DefineFun(a_szName, a_pFun, false);\r
- MU_CATCH\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-API_EXPORT(void) mupDefineStrFun1( muParserHandle_t a_hParser, \r
- const muChar_t *a_szName, \r
- muStrFun1_t a_pFun )\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- p->DefineFun(a_szName, a_pFun, false);\r
- MU_CATCH\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-API_EXPORT(void) mupDefineStrFun2( muParserHandle_t a_hParser, \r
- const muChar_t* a_szName, \r
- muStrFun2_t a_pFun )\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- p->DefineFun(a_szName, a_pFun, false);\r
- MU_CATCH\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-API_EXPORT(void) mupDefineStrFun3( muParserHandle_t a_hParser, \r
- const muChar_t* a_szName, \r
- muStrFun3_t a_pFun )\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- p->DefineFun(a_szName, a_pFun, false);\r
- MU_CATCH\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-API_EXPORT(void) mupDefineMultFun( muParserHandle_t a_hParser, \r
- const muChar_t *a_szName, \r
- muMultFun_t a_pFun, \r
- muBool_t a_bAllowOpt )\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- p->DefineFun(a_szName, a_pFun, a_bAllowOpt!=0);\r
- MU_CATCH\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-API_EXPORT(void) mupDefineOprt( muParserHandle_t a_hParser, \r
- const muChar_t* a_szName, \r
- muFun2_t a_pFun, \r
- muInt_t a_nPrec, \r
- muInt_t a_nOprtAsct,\r
- muBool_t a_bAllowOpt)\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- p->DefineOprt(a_szName, \r
- a_pFun, \r
- a_nPrec, \r
- (mu::EOprtAssociativity)a_nOprtAsct, \r
- a_bAllowOpt!=0);\r
- MU_CATCH\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-API_EXPORT(void) mupDefineVar(muParserHandle_t a_hParser, \r
- const muChar_t *a_szName, \r
- muFloat_t *a_pVar)\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- p->DefineVar(a_szName, a_pVar);\r
- MU_CATCH\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-API_EXPORT(void) mupDefineBulkVar(muParserHandle_t a_hParser, \r
- const muChar_t *a_szName, \r
- muFloat_t *a_pVar)\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- p->DefineVar(a_szName, a_pVar);\r
- MU_CATCH\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-API_EXPORT(void) mupDefineConst(muParserHandle_t a_hParser, \r
- const muChar_t *a_szName, \r
- muFloat_t a_fVal)\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- p->DefineConst(a_szName, a_fVal);\r
- MU_CATCH\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-API_EXPORT(void) mupDefineStrConst(muParserHandle_t a_hParser, \r
- const muChar_t *a_szName, \r
- const muChar_t *a_szVal)\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- p->DefineStrConst(a_szName, a_szVal);\r
- MU_CATCH\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-API_EXPORT(const muChar_t*) mupGetExpr(muParserHandle_t a_hParser)\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
-\r
- // C# explodes when pMsg is returned directly. For some reason it can't access\r
- // the memory where the message lies directly.\r
- sprintf(s_tmpOutBuf, "%s", p->GetExpr().c_str());\r
- return s_tmpOutBuf;\r
- \r
- MU_CATCH\r
-\r
- return "";\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-API_EXPORT(void) mupDefinePostfixOprt( muParserHandle_t a_hParser,\r
- const muChar_t* a_szName,\r
- muFun1_t a_pOprt,\r
- muBool_t a_bAllowOpt )\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- p->DefinePostfixOprt(a_szName, a_pOprt, a_bAllowOpt!=0);\r
- MU_CATCH\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-API_EXPORT(void) mupDefineInfixOprt( muParserHandle_t a_hParser,\r
- const muChar_t* a_szName,\r
- muFun1_t a_pOprt,\r
- muBool_t a_bAllowOpt )\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- p->DefineInfixOprt(a_szName, a_pOprt, a_bAllowOpt!=0);\r
- MU_CATCH\r
-}\r
-\r
-// Define character sets for identifiers\r
-//---------------------------------------------------------------------------\r
-API_EXPORT(void) mupDefineNameChars( muParserHandle_t a_hParser, \r
- const muChar_t* a_szCharset )\r
-{\r
- muParser_t* const p(AsParser(a_hParser));\r
- p->DefineNameChars(a_szCharset);\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-API_EXPORT(void) mupDefineOprtChars( muParserHandle_t a_hParser, \r
- const muChar_t* a_szCharset )\r
-{\r
- muParser_t* const p(AsParser(a_hParser));\r
- p->DefineOprtChars(a_szCharset);\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-API_EXPORT(void) mupDefineInfixOprtChars(muParserHandle_t a_hParser, \r
- const muChar_t *a_szCharset)\r
-{\r
- muParser_t* const p(AsParser(a_hParser));\r
- p->DefineInfixOprtChars(a_szCharset);\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-/** \brief Get the number of variables defined in the parser.\r
- \param a_hParser [in] Must be a valid parser handle.\r
- \return The number of used variables.\r
- \sa mupGetExprVar\r
-*/\r
-API_EXPORT(int) mupGetVarNum(muParserHandle_t a_hParser)\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- const mu::varmap_type VarMap = p->GetVar();\r
- return (int)VarMap.size();\r
- MU_CATCH\r
-\r
- return 0; // never reached\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-/** \brief Return a variable that is used in an expression.\r
- \param a_hParser [in] A valid parser handle.\r
- \param a_iVar [in] The index of the variable to return.\r
- \param a_szName [out] Pointer to the variable name.\r
- \param a_pVar [out] Pointer to the variable.\r
- \throw nothrow\r
-\r
- Prior to calling this function call mupGetExprVarNum in order to get the\r
- number of variables in the expression. If the parameter a_iVar is greater\r
- than the number of variables both a_szName and a_pVar will be set to zero.\r
- As a side effect this function will trigger an internal calculation of the\r
- expression undefined variables will be set to zero during this calculation.\r
- During the calculation user defined callback functions present in the expression\r
- will be called, this is unavoidable.\r
-*/\r
-API_EXPORT(void) mupGetVar(muParserHandle_t a_hParser, \r
- unsigned a_iVar, \r
- const muChar_t **a_szName, \r
- muFloat_t **a_pVar)\r
-{\r
- // A static buffer is needed for the name since i cant return the\r
- // pointer from the map.\r
- static muChar_t szName[1024];\r
-\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- const mu::varmap_type VarMap = p->GetVar();\r
-\r
- if (a_iVar>=VarMap.size())\r
- {\r
- *a_szName = 0;\r
- *a_pVar = 0;\r
- return;\r
- }\r
- mu::varmap_type::const_iterator item;\r
-\r
- item = VarMap.begin();\r
- for (unsigned i=0; i<a_iVar; ++i)\r
- item++;\r
-\r
- strncpy(szName, item->first.c_str(), sizeof(szName));\r
- szName[sizeof(szName)-1] = 0;\r
-\r
- *a_szName = &szName[0];\r
- *a_pVar = item->second;\r
- return;\r
-\r
- MU_CATCH\r
-\r
- *a_szName = 0;\r
- *a_pVar = 0;\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-/** \brief Get the number of variables used in the expression currently set in the parser.\r
- \param a_hParser [in] Must be a valid parser handle.\r
- \return The number of used variables.\r
- \sa mupGetExprVar\r
-*/\r
-API_EXPORT(int) mupGetExprVarNum(muParserHandle_t a_hParser)\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- const mu::varmap_type VarMap = p->GetUsedVar();\r
- return (int)VarMap.size();\r
- MU_CATCH\r
-\r
- return 0; // never reached\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-/** \brief Return a variable that is used in an expression.\r
-\r
- Prior to calling this function call mupGetExprVarNum in order to get the\r
- number of variables in the expression. If the parameter a_iVar is greater\r
- than the number of variables both a_szName and a_pVar will be set to zero.\r
- As a side effect this function will trigger an internal calculation of the\r
- expression undefined variables will be set to zero during this calculation.\r
- During the calculation user defined callback functions present in the expression\r
- will be called, this is unavoidable.\r
-\r
- \param a_hParser [in] A valid parser handle.\r
- \param a_iVar [in] The index of the variable to return.\r
- \param a_szName [out] Pointer to the variable name.\r
- \param a_pVar [out] Pointer to the variable.\r
- \throw nothrow\r
-*/\r
-API_EXPORT(void) mupGetExprVar(muParserHandle_t a_hParser, \r
- unsigned a_iVar, \r
- const muChar_t **a_szName, \r
- muFloat_t **a_pVar)\r
-{\r
- // A static buffer is needed for the name since i cant return the\r
- // pointer from the map.\r
- static muChar_t szName[1024];\r
-\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- const mu::varmap_type VarMap = p->GetUsedVar();\r
-\r
- if (a_iVar>=VarMap.size())\r
- {\r
- *a_szName = 0;\r
- *a_pVar = 0;\r
- return;\r
- }\r
- mu::varmap_type::const_iterator item;\r
-\r
- item = VarMap.begin();\r
- for (unsigned i=0; i<a_iVar; ++i)\r
- item++;\r
-\r
- strncpy(szName, item->first.c_str(), sizeof(szName));\r
- szName[sizeof(szName)-1] = 0;\r
-\r
- *a_szName = &szName[0];\r
- *a_pVar = item->second;\r
- return;\r
-\r
- MU_CATCH\r
-\r
- *a_szName = 0;\r
- *a_pVar = 0;\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-/** \brief Return the number of constants defined in a parser. */\r
-API_EXPORT(int) mupGetConstNum(muParserHandle_t a_hParser)\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- const mu::valmap_type ValMap = p->GetConst();\r
- return (int)ValMap.size();\r
- MU_CATCH\r
-\r
- return 0; // never reached\r
-}\r
-\r
-//-----------------------------------------------------------------------------------------------------\r
-API_EXPORT(void) mupSetArgSep(muParserHandle_t a_hParser, const muChar_t cArgSep)\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- p->SetArgSep(cArgSep);\r
- MU_CATCH\r
-}\r
-\r
-//-----------------------------------------------------------------------------------------------------\r
-API_EXPORT(void) mupResetLocale(muParserHandle_t a_hParser)\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- p->ResetLocale();\r
- MU_CATCH\r
-}\r
-\r
-//-----------------------------------------------------------------------------------------------------\r
-API_EXPORT(void) mupSetDecSep(muParserHandle_t a_hParser, const muChar_t cDecSep)\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- p->SetDecSep(cDecSep);\r
- MU_CATCH\r
-}\r
-\r
-//-----------------------------------------------------------------------------------------------------\r
-API_EXPORT(void) mupSetThousandsSep(muParserHandle_t a_hParser, const muChar_t cThousandsSep)\r
-{\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- p->SetThousandsSep(cThousandsSep);\r
- MU_CATCH\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-/** \brief Retrieve name and value of a single parser constant.\r
- \param a_hParser [in] a valid parser handle\r
- \param a_iVar [in] Index of the constant to query\r
- \param a_pszName [out] pointer to a null terminated string with the constant name\r
- \param [out] The constant value\r
-*/\r
-API_EXPORT(void) mupGetConst( muParserHandle_t a_hParser, \r
- unsigned a_iVar,\r
- const muChar_t **a_pszName, \r
- muFloat_t *a_fVal)\r
-{\r
- // A static buffer is needed for the name since i cant return the\r
- // pointer from the map.\r
- static muChar_t szName[1024];\r
-\r
- MU_TRY\r
- muParser_t* const p(AsParser(a_hParser));\r
- const mu::valmap_type ValMap = p->GetConst();\r
-\r
- if (a_iVar>=ValMap.size())\r
- {\r
- *a_pszName = 0;\r
- *a_fVal = 0;\r
- return;\r
- }\r
-\r
- mu::valmap_type::const_iterator item;\r
- item = ValMap.begin();\r
- for (unsigned i=0; i<a_iVar; ++i)\r
- item++;\r
-\r
- strncpy(szName, item->first.c_str(), sizeof(szName));\r
- szName[sizeof(szName)-1] = 0;\r
-\r
- *a_pszName = &szName[0];\r
- *a_fVal = item->second;\r
- return;\r
-\r
- MU_CATCH\r
-\r
- *a_pszName = 0;\r
- *a_fVal = 0;\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-/** \brief Add a custom value regognition function.\r
-*/\r
-API_EXPORT(void) mupAddValIdent(muParserHandle_t a_hParser, \r
- muIdentFun_t a_pFun)\r
-{\r
- MU_TRY\r
- muParser_t* p(AsParser(a_hParser));\r
- p->AddValIdent(a_pFun);\r
- MU_CATCH\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-/** \brief Query if an error occured.\r
-\r
- After querying the internal error bit will be reset. So a consecutive call\r
- will return false.\r
-*/\r
-API_EXPORT(muBool_t) mupError(muParserHandle_t a_hParser)\r
-{\r
- bool bError( AsParserTag(a_hParser)->bError );\r
- AsParserTag(a_hParser)->bError = false;\r
- return bError;\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-/** \brief Reset the internal error flag.\r
-*/\r
-API_EXPORT(void) mupErrorReset(muParserHandle_t a_hParser)\r
-{\r
- AsParserTag(a_hParser)->bError = false;\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-API_EXPORT(void) mupSetErrorHandler(muParserHandle_t a_hParser, muErrorHandler_t a_pHandler)\r
-{\r
- AsParserTag(a_hParser)->errHandler = a_pHandler;\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-/** \brief Return the message associated with the last error.\r
-*/\r
-API_EXPORT(const muChar_t*) mupGetErrorMsg(muParserHandle_t a_hParser)\r
-{\r
- ParserTag* const p(AsParserTag(a_hParser));\r
- const muChar_t *pMsg = p->exc.GetMsg().c_str();\r
-\r
- // C# explodes when pMsg is returned directly. For some reason it can't access\r
- // the memory where the message lies directly.\r
- sprintf(s_tmpOutBuf, "%s", pMsg);\r
- return s_tmpOutBuf;\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-/** \brief Return the message associated with the last error.\r
-*/\r
-API_EXPORT(const muChar_t*) mupGetErrorToken(muParserHandle_t a_hParser)\r
-{\r
- ParserTag* const p(AsParserTag(a_hParser));\r
- const muChar_t *pToken = p->exc.GetToken().c_str();\r
-\r
- // C# explodes when pMsg is returned directly. For some reason it can't access\r
- // the memory where the message lies directly.\r
- sprintf(s_tmpOutBuf, "%s", pToken);\r
- return s_tmpOutBuf;\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-/** \brief Return the code associated with the last error.\r
-*/\r
-API_EXPORT(int) mupGetErrorCode(muParserHandle_t a_hParser)\r
-{\r
- return AsParserTag(a_hParser)->exc.GetCode();\r
-}\r
-\r
-//---------------------------------------------------------------------------\r
-/** \brief Return the postion associated with the last error. */\r
-API_EXPORT(int) mupGetErrorPos(muParserHandle_t a_hParser)\r
-{\r
- return (int)AsParserTag(a_hParser)->exc.GetPos();\r
-}\r
-\r
-////-----------------------------------------------------------------------------------------------------\r
-//API_EXPORT(const muChar_t*) mupGetErrorExpr(muParserHandle_t a_hParser)\r
-//{\r
-// return AsParserTag(a_hParser)->exc.GetExpr().c_str();\r
-//}\r
-\r
-//-----------------------------------------------------------------------------------------------------\r
-API_EXPORT(muFloat_t*) mupCreateVar()\r
-{\r
- return new muFloat_t(0);\r
-}\r
-\r
-//-----------------------------------------------------------------------------------------------------\r
-API_EXPORT(void) mupReleaseVar(muFloat_t *ptr)\r
-{\r
- delete ptr;\r
-}\r
-\r
-#endif // MUPARSER_DLL\r
# \/ \/ \/ \/ #\r
# Fast math parser Library #\r
# #\r
-# Copyright (C) 2013 Ingo Berg #\r
+# Copyright (C) 2014 Ingo Berg #\r
# #\r
# Web: muparser.beltoforion.de #\r
# e-mail: muparser@beltoforion.de #\r
# #\r
# #\r
#######################################################################\r
-\r
+ \r
\r
History:\r
--------\r
\r
+Rev 2.2.4: 02.10.2014\r
+---------------------\r
+ Changes:\r
+ * explicit positive sign allowed\r
+\r
+ Bugfixes:\r
+ * Fix for Issue 6 (https://code.google.com/p/muparser/issues/detail?id=6)\r
+ * String constants did not work properly. Using more than a single one \r
+ was impossible.\r
+ * Project Files for VS2008 and VS2010 removed from the repository \r
+ * Fix for Issue 4 (https://code.google.com/p/muparser/issues/detail?id=4)\r
+ * Fix for VS2013 64 bit build option\r
+ * return type of ParserError::GetPos changed to int\r
+ * OpenMP support enabled in the VS2013 project files and precompiled windows DLL's\r
+ * Bulkmode did not evaluate properly if "=" and "," operator was used in the expression\r
+ \r
Rev 2.2.3: 22.12.2012\r
---------------------\r
\r
\r
<small>\r
(C) 2011 Ingo Berg<br>\r
- muparser(at)gmx.de\r
+ muparser(at)beltoforion.de\r
</small>\r
*/\r
/* final */ class Parser : public ParserBase\r
// Prefix operators\r
// !!! Unary Minus is a MUST if you want to use negative signs !!!\r
static value_type UnaryMinus(value_type);\r
+ static value_type UnaryPlus(value_type);\r
\r
// Functions with variable number of arguments\r
static value_type Sum(const value_type*, int); // sum\r
#include <map>\r
#include <memory>\r
#include <locale>\r
+#include <limits.h>\r
\r
//--- Parser includes --------------------------------------------------------------------------\r
#include "muParserDef.h"\r
typedef ParserToken<value_type, string_type> token_type;\r
\r
/** \brief Maximum number of threads spawned by OpenMP when using the bulk mode. */\r
- static const int s_MaxNumOpenMPThreads = 4;\r
+ static const int s_MaxNumOpenMPThreads = 16;\r
\r
public:\r
\r
\r
virtual std::string do_grouping() const \r
{ \r
- return std::string(1, m_nGroup); \r
+ // fix for issue 4: https://code.google.com/p/muparser/issues/detail?id=4\r
+ // courtesy of Jens Bartsch\r
+ // original code:\r
+ // return std::string(1, (char)m_nGroup); \r
+ // new code:\r
+ return std::string(1, (char)(m_cThousandsSep > 0 ? m_nGroup : CHAR_MAX));\r
}\r
\r
private:\r
ECmdCode Cmd;\r
int StackPos;\r
\r
- union u\r
+ union\r
{\r
- struct sVal\r
+ struct //SValData\r
{\r
value_type *ptr;\r
value_type data;\r
value_type data2;\r
} Val;\r
\r
- struct sFun\r
+ struct //SFunData\r
{\r
// Note: generic_fun_type is merely a placeholder. The real type could be \r
// anything between gun_type1 and fun_type9. I can't use a void\r
int idx;\r
} Fun;\r
\r
- struct sOprt\r
+ struct //SOprtData\r
{\r
value_type *ptr;\r
int offset;\r
} Oprt;\r
- } u;\r
+ };\r
};\r
\r
\r
| Y Y \| | /| | / __ \_| | \/\___ \ \ ___/ | | \/\r
|__|_| /|____/ |____| (____ /|__| /____ > \___ >|__| \r
\/ \/ \/ \/ \r
- Copyright (C) 2013 Ingo Berg\r
+ Copyright (C) 2014 Ingo Berg\r
\r
Permission is hereby granted, free of charge, to any person obtaining a copy of this \r
software and associated documentation files (the "Software"), to deal in the Software\r
\brief This file contains standard definitions used by the parser.\r
*/\r
\r
-#define MUP_VERSION _T("2.2.3")\r
-#define MUP_VERSION_DATE _T("20121222; SF")\r
+#define MUP_VERSION _T("2.2.4")\r
+#define MUP_VERSION_DATE _T("20141210; GC")\r
\r
#define MUP_CHARS _T("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")\r
\r
ecMISSING_ELSE_CLAUSE = 33, \r
ecMISPLACED_COLON = 34,\r
\r
+ ecUNREASONABLE_NUMBER_OF_COMPUTATIONS = 35,\r
+\r
// internal errors\r
- ecINTERNAL_ERROR = 35, ///< Internal error of any kind.\r
+ ecINTERNAL_ERROR = 36, ///< Internal error of any kind.\r
\r
// The last two are special entries \r
ecCOUNT, ///< This is no error code, It just stores just the total number of error codes\r
void SetFormula(const string_type &a_strFormula);\r
const string_type& GetExpr() const;\r
const string_type& GetMsg() const;\r
- std::size_t GetPos() const;\r
+ int GetPos() const;\r
const string_type& GetToken() const;\r
EErrorCodes GetCode() const;\r
\r
\r
virtual std::string do_grouping() const \r
{ \r
- return std::string(1, m_nGroup); \r
+ // fix for issue 4: https://code.google.com/p/muparser/issues/detail?id=4\r
+ // courtesy of Jens Bartsch\r
+ // original code:\r
+ // return std::string(1, (char)m_nGroup); \r
+ // new code:\r
+ return std::string(1, (char)(m_cThousandsSep > 0 ? m_nGroup : CHAR_MAX));\r
}\r
\r
private:\r
ParserInt();\r
\r
virtual void InitFun();\r
- virtual void InitOprt();\r
+ virtual void InitOprt();\r
virtual void InitConst();\r
virtual void InitCharSets();\r
};\r
/** \brief Returns true if stack is empty false otherwise. */\r
bool empty() const\r
{\r
- return m_Stack.size()==0; \r
+ return m_Stack.empty(); \r
}\r
\r
/** \brief Return reference to the top object in the stack. \r
static T Sign(T v) { return (T)((v<0) ? -1 : (v>0) ? 1 : 0); }\r
static T Pow(T v1, T v2) { return std::pow(v1, v2); }\r
};\r
-\r
- // Create (mostly) dummy math function definitions for integer types. They are mostly\r
- // empty since they are not applicable for integer values.\r
-#define MAKE_MATH_DUMMY(TYPE) \\r
- template<> \\r
- struct MathImpl<TYPE> \\r
- { \\r
- static TYPE Sin(TYPE) { throw ParserError(_T("unimplemented function.")); } \\r
- static TYPE Cos(TYPE) { throw ParserError(_T("unimplemented function.")); } \\r
- static TYPE Tan(TYPE) { throw ParserError(_T("unimplemented function.")); } \\r
- static TYPE ASin(TYPE) { throw ParserError(_T("unimplemented function.")); } \\r
- static TYPE ACos(TYPE) { throw ParserError(_T("unimplemented function.")); } \\r
- static TYPE ATan(TYPE) { throw ParserError(_T("unimplemented function.")); } \\r
- static TYPE ATan2(TYPE, TYPE) { throw ParserError(_T("unimplemented function.")); } \\r
- static TYPE Sinh(TYPE) { throw ParserError(_T("unimplemented function.")); } \\r
- static TYPE Cosh(TYPE) { throw ParserError(_T("unimplemented function.")); } \\r
- static TYPE Tanh(TYPE) { throw ParserError(_T("unimplemented function.")); } \\r
- static TYPE ASinh(TYPE) { throw ParserError(_T("unimplemented function.")); } \\r
- static TYPE ACosh(TYPE) { throw ParserError(_T("unimplemented function.")); } \\r
- static TYPE ATanh(TYPE) { throw ParserError(_T("unimplemented function.")); } \\r
- static TYPE Log(TYPE) { throw ParserError(_T("unimplemented function.")); } \\r
- static TYPE Log2(TYPE) { throw ParserError(_T("unimplemented function.")); } \\r
- static TYPE Log10(TYPE) { throw ParserError(_T("unimplemented function.")); } \\r
- static TYPE Exp(TYPE) { throw ParserError(_T("unimplemented function.")); } \\r
- static TYPE Abs(TYPE) { throw ParserError(_T("unimplemented function.")); } \\r
- static TYPE Sqrt(TYPE) { throw ParserError(_T("unimplemented function.")); } \\r
- static TYPE Rint(TYPE) { throw ParserError(_T("unimplemented function.")); } \\r
- static TYPE Sign(TYPE v) { return (TYPE)((v<0) ? -1 : (v>0) ? 1 : 0); } \\r
- static TYPE Pow(TYPE v1, TYPE v2) { return (TYPE)std::pow((double)v1, (double)v2); } \\r
- };\r
-\r
- MAKE_MATH_DUMMY(char)\r
- MAKE_MATH_DUMMY(short)\r
- MAKE_MATH_DUMMY(int)\r
- MAKE_MATH_DUMMY(long)\r
-\r
-#undef MAKE_MATH_DUMMY\r
}\r
\r
#endif\r
static value_type f3of4(value_type , value_type, value_type v, value_type ) {return v;}\r
static value_type f4of4(value_type , value_type, value_type , value_type v) {return v;}\r
\r
- static value_type f1of5(value_type v, value_type, value_type , value_type , value_type ) { return v; }\r
- static value_type f2of5(value_type , value_type v, value_type , value_type , value_type ) { return v; }\r
- static value_type f3of5(value_type , value_type, value_type v, value_type , value_type ) { return v; }\r
- static value_type f4of5(value_type , value_type, value_type , value_type v, value_type ) { return v; }\r
- static value_type f5of5(value_type , value_type, value_type , value_type , value_type v) { return v; }\r
+ static value_type f1of5(value_type v, value_type, value_type , value_type , value_type ) { return v; }\r
+ static value_type f2of5(value_type , value_type v, value_type , value_type , value_type ) { return v; }\r
+ static value_type f3of5(value_type , value_type, value_type v, value_type , value_type ) { return v; }\r
+ static value_type f4of5(value_type , value_type, value_type , value_type v, value_type ) { return v; }\r
+ static value_type f5of5(value_type , value_type, value_type , value_type , value_type v) { return v; }\r
\r
static value_type Min(value_type a_fVal1, value_type a_fVal2) { return (a_fVal1<a_fVal2) ? a_fVal1 : a_fVal2; }\r
static value_type Max(value_type a_fVal1, value_type a_fVal2) { return (a_fVal1>a_fVal2) ? a_fVal1 : a_fVal2; }\r
static int IsHexVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fVal);\r
\r
int TestNames();\r
- int TestSyntax();\r
- int TestMultiArg();\r
- int TestPostFix();\r
- int TestExpression();\r
- int TestInfixOprt();\r
- int TestBinOprt();\r
- int TestVarConst();\r
- int TestInterface();\r
- int TestException();\r
+ int TestSyntax();\r
+ int TestMultiArg();\r
+ int TestPostFix();\r
+ int TestExpression();\r
+ int TestInfixOprt();\r
+ int TestBinOprt();\r
+ int TestVarConst();\r
+ int TestInterface();\r
+ int TestException();\r
int TestStrArg();\r
int TestIfThenElse();\r
+ int TestBulkMode();\r
\r
void Abort() const;\r
\r
\r
// Test Int Parser\r
int EqnTestInt(const string_type& a_str, double a_fRes, bool a_fPass);\r
+\r
+ // Test Bulkmode\r
+ int EqnTestBulk(const string_type& a_str, double a_fRes[4], bool a_fPass);\r
};\r
} // namespace Test\r
} // namespace mu\r
,m_pTok(0)\r
,m_iIdx(-1)\r
,m_strTok()\r
+ ,m_strVal()\r
+ ,m_fVal(0)\r
,m_pCallback()\r
{}\r
\r
return -v; \r
}\r
\r
+ //---------------------------------------------------------------------------\r
+ /** \brief Callback for the unary minus operator.\r
+ \param v The value to negate\r
+ \return -v\r
+ */\r
+ value_type Parser::UnaryPlus(value_type v) \r
+ { \r
+ return v; \r
+ }\r
+\r
//---------------------------------------------------------------------------\r
/** \brief Callback for adding multiple values. \r
\param [in] a_afArg Vector with the function arguments\r
// Logarithm functions\r
DefineFun(_T("log2"), Log2);\r
DefineFun(_T("log10"), Log10);\r
- DefineFun(_T("log"), Log10);\r
+ DefineFun(_T("log"), Ln);\r
DefineFun(_T("ln"), Ln);\r
// misc\r
DefineFun(_T("exp"), Exp);\r
void Parser::InitOprt()\r
{\r
DefineInfixOprt(_T("-"), UnaryMinus);\r
+ DefineInfixOprt(_T("+"), UnaryPlus);\r
}\r
\r
//---------------------------------------------------------------------------\r
\r
//--- Standard includes ------------------------------------------------------------------------\r
#include <cassert>\r
+#include <algorithm>\r
#include <cmath>\r
#include <memory>\r
#include <vector>\r
*/\r
string_type ParserBase::GetVersion(EParserVersionInfo eInfo) const\r
{\r
- string_type sCompileTimeSettings;\r
- \r
stringstream_type ss;\r
\r
ss << MUP_VERSION;\r
\r
CheckName(a_strName, ValidNameChars());\r
\r
- m_vStringVarBuf.push_back(a_strVal); // Store variable string in internal buffer\r
- m_StrVarDef[a_strName] = m_vStringBuf.size(); // bind buffer index to variable name\r
+ m_vStringVarBuf.push_back(a_strVal); // Store variable string in internal buffer\r
+ m_StrVarDef[a_strName] = m_vStringVarBuf.size()-1; // bind buffer index to variable name\r
\r
ReInit();\r
}\r
m_pParseFormula = &ParserBase::ParseString;\r
m_pTokenReader->IgnoreUndefVar(false);\r
}\r
- catch(exception_type &e)\r
+ catch(exception_type & /*e*/)\r
{\r
// Make sure to stay in string parse mode, dont call ReInit()\r
// because it deletes the array with the used variables\r
m_pParseFormula = &ParserBase::ParseString;\r
m_pTokenReader->IgnoreUndefVar(false);\r
- throw e;\r
+ throw;\r
}\r
\r
return m_pTokenReader->GetUsedVar();\r
case cmLOR: --sidx; Stack[sidx] = Stack[sidx] || Stack[sidx+1]; continue;\r
\r
case cmASSIGN: \r
- --sidx; Stack[sidx] = *pTok->u.Oprt.ptr = Stack[sidx+1]; continue;\r
+ // Bugfix for Bulkmode:\r
+ // for details see:\r
+ // https://groups.google.com/forum/embed/?place=forum/muparser-dev&showsearch=true&showpopout=true&showtabs=false&parenturl=http://muparser.beltoforion.de/mup_forum.html&afterlogin&pli=1#!topic/muparser-dev/szgatgoHTws\r
+ --sidx; Stack[sidx] = *(pTok->Oprt.ptr + nOffset) = Stack[sidx + 1]; continue;\r
+ // original code:\r
+ //--sidx; Stack[sidx] = *pTok->Oprt.ptr = Stack[sidx+1]; continue;\r
\r
//case cmBO: // unused, listed for compiler optimization purposes\r
//case cmBC:\r
\r
case cmIF:\r
if (Stack[sidx--]==0)\r
- pTok += pTok->u.Oprt.offset;\r
+ pTok += pTok->Oprt.offset;\r
continue;\r
\r
case cmELSE:\r
- pTok += pTok->u.Oprt.offset;\r
+ pTok += pTok->Oprt.offset;\r
continue;\r
\r
case cmENDIF:\r
// continue;\r
\r
// value and variable tokens\r
- case cmVAR: Stack[++sidx] = *(pTok->u.Val.ptr + nOffset); continue;\r
- case cmVAL: Stack[++sidx] = pTok->u.Val.data2; continue;\r
+ case cmVAR: Stack[++sidx] = *(pTok->Val.ptr + nOffset); continue;\r
+ case cmVAL: Stack[++sidx] = pTok->Val.data2; continue;\r
\r
- case cmVARPOW2: buf = *(pTok->u.Val.ptr + nOffset);\r
+ case cmVARPOW2: buf = *(pTok->Val.ptr + nOffset);\r
Stack[++sidx] = buf*buf;\r
continue;\r
\r
- case cmVARPOW3: buf = *(pTok->u.Val.ptr + nOffset);\r
+ case cmVARPOW3: buf = *(pTok->Val.ptr + nOffset);\r
Stack[++sidx] = buf*buf*buf;\r
continue;\r
\r
- case cmVARPOW4: buf = *(pTok->u.Val.ptr + nOffset);\r
+ case cmVARPOW4: buf = *(pTok->Val.ptr + nOffset);\r
Stack[++sidx] = buf*buf*buf*buf;\r
continue;\r
\r
- case cmVARMUL: Stack[++sidx] = *(pTok->u.Val.ptr + nOffset) * pTok->u.Val.data + pTok->u.Val.data2;\r
+ case cmVARMUL: Stack[++sidx] = *(pTok->Val.ptr + nOffset) * pTok->Val.data + pTok->Val.data2;\r
continue;\r
\r
// Next is treatment of numeric functions\r
case cmFUNC:\r
{\r
- int iArgCount = pTok->u.Fun.argc;\r
+ int iArgCount = pTok->Fun.argc;\r
\r
// switch according to argument count\r
switch(iArgCount) \r
{\r
- case 0: sidx += 1; Stack[sidx] = (*(fun_type0)pTok->u.Fun.ptr)(); continue;\r
- case 1: Stack[sidx] = (*(fun_type1)pTok->u.Fun.ptr)(Stack[sidx]); continue;\r
- case 2: sidx -= 1; Stack[sidx] = (*(fun_type2)pTok->u.Fun.ptr)(Stack[sidx], Stack[sidx+1]); continue;\r
- case 3: sidx -= 2; Stack[sidx] = (*(fun_type3)pTok->u.Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2]); continue;\r
- case 4: sidx -= 3; Stack[sidx] = (*(fun_type4)pTok->u.Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3]); continue;\r
- case 5: sidx -= 4; Stack[sidx] = (*(fun_type5)pTok->u.Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4]); continue;\r
- case 6: sidx -= 5; Stack[sidx] = (*(fun_type6)pTok->u.Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5]); continue;\r
- case 7: sidx -= 6; Stack[sidx] = (*(fun_type7)pTok->u.Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6]); continue;\r
- case 8: sidx -= 7; Stack[sidx] = (*(fun_type8)pTok->u.Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7]); continue;\r
- case 9: sidx -= 8; Stack[sidx] = (*(fun_type9)pTok->u.Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], Stack[sidx+8]); continue;\r
- case 10:sidx -= 9; Stack[sidx] = (*(fun_type10)pTok->u.Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], Stack[sidx+8], Stack[sidx+9]); continue;\r
+ case 0: sidx += 1; Stack[sidx] = (*(fun_type0)pTok->Fun.ptr)(); continue;\r
+ case 1: Stack[sidx] = (*(fun_type1)pTok->Fun.ptr)(Stack[sidx]); continue;\r
+ case 2: sidx -= 1; Stack[sidx] = (*(fun_type2)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1]); continue;\r
+ case 3: sidx -= 2; Stack[sidx] = (*(fun_type3)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2]); continue;\r
+ case 4: sidx -= 3; Stack[sidx] = (*(fun_type4)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3]); continue;\r
+ case 5: sidx -= 4; Stack[sidx] = (*(fun_type5)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4]); continue;\r
+ case 6: sidx -= 5; Stack[sidx] = (*(fun_type6)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5]); continue;\r
+ case 7: sidx -= 6; Stack[sidx] = (*(fun_type7)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6]); continue;\r
+ case 8: sidx -= 7; Stack[sidx] = (*(fun_type8)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7]); continue;\r
+ case 9: sidx -= 8; Stack[sidx] = (*(fun_type9)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], Stack[sidx+8]); continue;\r
+ case 10:sidx -= 9; Stack[sidx] = (*(fun_type10)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], Stack[sidx+8], Stack[sidx+9]); continue;\r
default:\r
if (iArgCount>0) // function with variable arguments store the number as a negative value\r
Error(ecINTERNAL_ERROR, 1);\r
\r
sidx -= -iArgCount - 1;\r
- Stack[sidx] =(*(multfun_type)pTok->u.Fun.ptr)(&Stack[sidx], -iArgCount);\r
+ Stack[sidx] =(*(multfun_type)pTok->Fun.ptr)(&Stack[sidx], -iArgCount);\r
continue;\r
}\r
}\r
// Next is treatment of string functions\r
case cmFUNC_STR:\r
{\r
- sidx -= pTok->u.Fun.argc -1;\r
+ sidx -= pTok->Fun.argc -1;\r
\r
// The index of the string argument in the string table\r
- int iIdxStack = pTok->u.Fun.idx; \r
+ int iIdxStack = pTok->Fun.idx; \r
MUP_ASSERT( iIdxStack>=0 && iIdxStack<(int)m_vStringBuf.size() );\r
\r
- switch(pTok->u.Fun.argc) // switch according to argument count\r
+ switch(pTok->Fun.argc) // switch according to argument count\r
{\r
- case 0: Stack[sidx] = (*(strfun_type1)pTok->u.Fun.ptr)(m_vStringBuf[iIdxStack].c_str()); continue;\r
- case 1: Stack[sidx] = (*(strfun_type2)pTok->u.Fun.ptr)(m_vStringBuf[iIdxStack].c_str(), Stack[sidx]); continue;\r
- case 2: Stack[sidx] = (*(strfun_type3)pTok->u.Fun.ptr)(m_vStringBuf[iIdxStack].c_str(), Stack[sidx], Stack[sidx+1]); continue;\r
+ case 0: Stack[sidx] = (*(strfun_type1)pTok->Fun.ptr)(m_vStringBuf[iIdxStack].c_str()); continue;\r
+ case 1: Stack[sidx] = (*(strfun_type2)pTok->Fun.ptr)(m_vStringBuf[iIdxStack].c_str(), Stack[sidx]); continue;\r
+ case 2: Stack[sidx] = (*(strfun_type3)pTok->Fun.ptr)(m_vStringBuf[iIdxStack].c_str(), Stack[sidx], Stack[sidx+1]); continue;\r
}\r
\r
continue;\r
\r
case cmFUNC_BULK:\r
{\r
- int iArgCount = pTok->u.Fun.argc;\r
+ int iArgCount = pTok->Fun.argc;\r
\r
// switch according to argument count\r
switch(iArgCount) \r
{\r
- case 0: sidx += 1; Stack[sidx] = (*(bulkfun_type0 )pTok->u.Fun.ptr)(nOffset, nThreadID); continue;\r
- case 1: Stack[sidx] = (*(bulkfun_type1 )pTok->u.Fun.ptr)(nOffset, nThreadID, Stack[sidx]); continue;\r
- case 2: sidx -= 1; Stack[sidx] = (*(bulkfun_type2 )pTok->u.Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1]); continue;\r
- case 3: sidx -= 2; Stack[sidx] = (*(bulkfun_type3 )pTok->u.Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2]); continue;\r
- case 4: sidx -= 3; Stack[sidx] = (*(bulkfun_type4 )pTok->u.Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3]); continue;\r
- case 5: sidx -= 4; Stack[sidx] = (*(bulkfun_type5 )pTok->u.Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4]); continue;\r
- case 6: sidx -= 5; Stack[sidx] = (*(bulkfun_type6 )pTok->u.Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5]); continue;\r
- case 7: sidx -= 6; Stack[sidx] = (*(bulkfun_type7 )pTok->u.Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6]); continue;\r
- case 8: sidx -= 7; Stack[sidx] = (*(bulkfun_type8 )pTok->u.Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7]); continue;\r
- case 9: sidx -= 8; Stack[sidx] = (*(bulkfun_type9 )pTok->u.Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], Stack[sidx+8]); continue;\r
- case 10:sidx -= 9; Stack[sidx] = (*(bulkfun_type10)pTok->u.Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], Stack[sidx+8], Stack[sidx+9]); continue;\r
+ case 0: sidx += 1; Stack[sidx] = (*(bulkfun_type0 )pTok->Fun.ptr)(nOffset, nThreadID); continue;\r
+ case 1: Stack[sidx] = (*(bulkfun_type1 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx]); continue;\r
+ case 2: sidx -= 1; Stack[sidx] = (*(bulkfun_type2 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1]); continue;\r
+ case 3: sidx -= 2; Stack[sidx] = (*(bulkfun_type3 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2]); continue;\r
+ case 4: sidx -= 3; Stack[sidx] = (*(bulkfun_type4 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3]); continue;\r
+ case 5: sidx -= 4; Stack[sidx] = (*(bulkfun_type5 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4]); continue;\r
+ case 6: sidx -= 5; Stack[sidx] = (*(bulkfun_type6 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5]); continue;\r
+ case 7: sidx -= 6; Stack[sidx] = (*(bulkfun_type7 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6]); continue;\r
+ case 8: sidx -= 7; Stack[sidx] = (*(bulkfun_type8 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7]); continue;\r
+ case 9: sidx -= 8; Stack[sidx] = (*(bulkfun_type9 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], Stack[sidx+8]); continue;\r
+ case 10:sidx -= 9; Stack[sidx] = (*(bulkfun_type10)pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], Stack[sidx+8], Stack[sidx+9]); continue;\r
default:\r
Error(ecINTERNAL_ERROR, 2);\r
continue;\r
}\r
}\r
\r
- //case cmSTRING:\r
- //case cmOPRT_BIN:\r
- //case cmOPRT_POSTFIX:\r
- //case cmOPRT_INFIX:\r
- // MUP_FAIL(INVALID_CODE_IN_BYTECODE);\r
- // continue;\r
-\r
- //case cmEND:\r
- // return Stack[m_nFinalResultIdx]; \r
-\r
default:\r
Error(ecINTERNAL_ERROR, 3);\r
return 0;\r
ParserStack<int> stArgCount;\r
token_type opta, opt; // for storing operators\r
token_type val, tval; // for storing value\r
- string_type strBuf; // buffer for string function arguments\r
\r
ReInit();\r
\r
break;\r
\r
case cmVAL:\r
- stVal.push(opt);\r
+ stVal.push(opt);\r
m_vRPN.AddVal( opt.GetVal() );\r
break;\r
\r
//---------------------------------------------------------------------------\r
void ParserBase::Eval(value_type *results, int nBulkSize)\r
{\r
+/* <ibg 2014-09-24/> Commented because it is making a unit test impossible\r
+\r
+ // Parallelization does not make sense for fewer than 10000 computations \r
+ // due to thread creation overhead. If the bulk size is below 2000\r
+ // computation is refused. \r
+ if (nBulkSize<2000)\r
+ {\r
+ throw ParserError(ecUNREASONABLE_NUMBER_OF_COMPUTATIONS);\r
+ }\r
+*/\r
CreateRPN();\r
\r
int i = 0;\r
#endif\r
\r
int nMaxThreads = std::min(omp_get_max_threads(), s_MaxNumOpenMPThreads);\r
- int nThreadID, ct=0;\r
+ int nThreadID = 0, ct = 0;\r
omp_set_num_threads(nMaxThreads);\r
\r
#pragma omp parallel for schedule(static, nBulkSize/nMaxThreads) private(nThreadID)\r
\r
#include "muParserBytecode.h"\r
\r
+#include <algorithm>\r
#include <cassert>\r
#include <string>\r
#include <stack>\r
#include <vector>\r
#include <iostream>\r
-#include <algorithm>\r
\r
#include "muParserDef.h"\r
#include "muParserError.h"\r
m_iStackPos = a_ByteCode.m_iStackPos;\r
m_vRPN = a_ByteCode.m_vRPN;\r
m_iMaxStackSize = a_ByteCode.m_iMaxStackSize;\r
+ m_bEnableOptimizer = a_ByteCode.m_bEnableOptimizer;\r
}\r
\r
//---------------------------------------------------------------------------\r
// optimization does not apply\r
SToken tok;\r
tok.Cmd = cmVAR;\r
- tok.u.Val.ptr = a_pVar;\r
- tok.u.Val.data = 1;\r
- tok.u.Val.data2 = 0;\r
+ tok.Val.ptr = a_pVar;\r
+ tok.Val.data = 1;\r
+ tok.Val.data2 = 0;\r
m_vRPN.push_back(tok);\r
}\r
\r
// If optimization does not apply\r
SToken tok;\r
tok.Cmd = cmVAL;\r
- tok.u.Val.ptr = NULL;\r
- tok.u.Val.data = 0;\r
- tok.u.Val.data2 = a_fVal;\r
+ tok.Val.ptr = NULL;\r
+ tok.Val.data = 0;\r
+ tok.Val.data2 = a_fVal;\r
m_vRPN.push_back(tok);\r
}\r
\r
void ParserByteCode::ConstantFolding(ECmdCode a_Oprt)\r
{\r
std::size_t sz = m_vRPN.size();\r
- value_type &x = m_vRPN[sz-2].u.Val.data2,\r
- &y = m_vRPN[sz-1].u.Val.data2;\r
+ value_type &x = m_vRPN[sz-2].Val.data2,\r
+ &y = m_vRPN[sz-1].Val.data2;\r
switch (a_Oprt)\r
{\r
case cmLAND: x = (int)x && (int)y; m_vRPN.pop_back(); break;\r
// Optimization for ploynomials of low order\r
if (m_vRPN[sz-2].Cmd == cmVAR && m_vRPN[sz-1].Cmd == cmVAL)\r
{\r
- if (m_vRPN[sz-1].u.Val.data2==2)\r
+ if (m_vRPN[sz-1].Val.data2==2)\r
m_vRPN[sz-2].Cmd = cmVARPOW2;\r
- else if (m_vRPN[sz-1].u.Val.data2==3)\r
+ else if (m_vRPN[sz-1].Val.data2==3)\r
m_vRPN[sz-2].Cmd = cmVARPOW3;\r
- else if (m_vRPN[sz-1].u.Val.data2==4)\r
+ else if (m_vRPN[sz-1].Val.data2==4)\r
m_vRPN[sz-2].Cmd = cmVARPOW4;\r
else\r
break;\r
(m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVAR) || \r
(m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVARMUL) ||\r
(m_vRPN[sz-1].Cmd == cmVARMUL && m_vRPN[sz-2].Cmd == cmVAL) ||\r
- (m_vRPN[sz-1].Cmd == cmVAR && m_vRPN[sz-2].Cmd == cmVAR && m_vRPN[sz-2].u.Val.ptr == m_vRPN[sz-1].u.Val.ptr) ||\r
- (m_vRPN[sz-1].Cmd == cmVAR && m_vRPN[sz-2].Cmd == cmVARMUL && m_vRPN[sz-2].u.Val.ptr == m_vRPN[sz-1].u.Val.ptr) ||\r
- (m_vRPN[sz-1].Cmd == cmVARMUL && m_vRPN[sz-2].Cmd == cmVAR && m_vRPN[sz-2].u.Val.ptr == m_vRPN[sz-1].u.Val.ptr) ||\r
- (m_vRPN[sz-1].Cmd == cmVARMUL && m_vRPN[sz-2].Cmd == cmVARMUL && m_vRPN[sz-2].u.Val.ptr == m_vRPN[sz-1].u.Val.ptr) )\r
+ (m_vRPN[sz-1].Cmd == cmVAR && m_vRPN[sz-2].Cmd == cmVAR && m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) ||\r
+ (m_vRPN[sz-1].Cmd == cmVAR && m_vRPN[sz-2].Cmd == cmVARMUL && m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) ||\r
+ (m_vRPN[sz-1].Cmd == cmVARMUL && m_vRPN[sz-2].Cmd == cmVAR && m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) ||\r
+ (m_vRPN[sz-1].Cmd == cmVARMUL && m_vRPN[sz-2].Cmd == cmVARMUL && m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) )\r
{\r
- assert( (m_vRPN[sz-2].u.Val.ptr==NULL && m_vRPN[sz-1].u.Val.ptr!=NULL) ||\r
- (m_vRPN[sz-2].u.Val.ptr!=NULL && m_vRPN[sz-1].u.Val.ptr==NULL) || \r
- (m_vRPN[sz-2].u.Val.ptr == m_vRPN[sz-1].u.Val.ptr) );\r
+ assert( (m_vRPN[sz-2].Val.ptr==NULL && m_vRPN[sz-1].Val.ptr!=NULL) ||\r
+ (m_vRPN[sz-2].Val.ptr!=NULL && m_vRPN[sz-1].Val.ptr==NULL) || \r
+ (m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) );\r
\r
m_vRPN[sz-2].Cmd = cmVARMUL;\r
- m_vRPN[sz-2].u.Val.ptr = (value_type*)((long long)(m_vRPN[sz-2].u.Val.ptr) | (long long)(m_vRPN[sz-1].u.Val.ptr)); // variable\r
- m_vRPN[sz-2].u.Val.data2 += ((a_Oprt==cmSUB) ? -1 : 1) * m_vRPN[sz-1].u.Val.data2; // offset\r
- m_vRPN[sz-2].u.Val.data += ((a_Oprt==cmSUB) ? -1 : 1) * m_vRPN[sz-1].u.Val.data; // multiplikatior\r
+ m_vRPN[sz-2].Val.ptr = (value_type*)((long long)(m_vRPN[sz-2].Val.ptr) | (long long)(m_vRPN[sz-1].Val.ptr)); // variable\r
+ m_vRPN[sz-2].Val.data2 += ((a_Oprt==cmSUB) ? -1 : 1) * m_vRPN[sz-1].Val.data2; // offset\r
+ m_vRPN[sz-2].Val.data += ((a_Oprt==cmSUB) ? -1 : 1) * m_vRPN[sz-1].Val.data; // multiplikatior\r
m_vRPN.pop_back();\r
bOptimized = true;\r
} \r
(m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVAR) ) \r
{\r
m_vRPN[sz-2].Cmd = cmVARMUL;\r
- m_vRPN[sz-2].u.Val.ptr = (value_type*)((long long)(m_vRPN[sz-2].u.Val.ptr) | (long long)(m_vRPN[sz-1].u.Val.ptr));\r
- m_vRPN[sz-2].u.Val.data = m_vRPN[sz-2].u.Val.data2 + m_vRPN[sz-1].u.Val.data2;\r
- m_vRPN[sz-2].u.Val.data2 = 0;\r
+ m_vRPN[sz-2].Val.ptr = (value_type*)((long long)(m_vRPN[sz-2].Val.ptr) | (long long)(m_vRPN[sz-1].Val.ptr));\r
+ m_vRPN[sz-2].Val.data = m_vRPN[sz-2].Val.data2 + m_vRPN[sz-1].Val.data2;\r
+ m_vRPN[sz-2].Val.data2 = 0;\r
m_vRPN.pop_back();\r
bOptimized = true;\r
} \r
{\r
// Optimization: 2*(3*b+1) or (3*b+1)*2 -> 6*b+2\r
m_vRPN[sz-2].Cmd = cmVARMUL;\r
- m_vRPN[sz-2].u.Val.ptr = (value_type*)((long long)(m_vRPN[sz-2].u.Val.ptr) | (long long)(m_vRPN[sz-1].u.Val.ptr));\r
+ m_vRPN[sz-2].Val.ptr = (value_type*)((long long)(m_vRPN[sz-2].Val.ptr) | (long long)(m_vRPN[sz-1].Val.ptr));\r
if (m_vRPN[sz-1].Cmd == cmVAL)\r
{\r
- m_vRPN[sz-2].u.Val.data *= m_vRPN[sz-1].u.Val.data2;\r
- m_vRPN[sz-2].u.Val.data2 *= m_vRPN[sz-1].u.Val.data2;\r
+ m_vRPN[sz-2].Val.data *= m_vRPN[sz-1].Val.data2;\r
+ m_vRPN[sz-2].Val.data2 *= m_vRPN[sz-1].Val.data2;\r
}\r
else\r
{\r
- m_vRPN[sz-2].u.Val.data = m_vRPN[sz-1].u.Val.data * m_vRPN[sz-2].u.Val.data2;\r
- m_vRPN[sz-2].u.Val.data2 = m_vRPN[sz-1].u.Val.data2 * m_vRPN[sz-2].u.Val.data2;\r
+ m_vRPN[sz-2].Val.data = m_vRPN[sz-1].Val.data * m_vRPN[sz-2].Val.data2;\r
+ m_vRPN[sz-2].Val.data2 = m_vRPN[sz-1].Val.data2 * m_vRPN[sz-2].Val.data2;\r
}\r
m_vRPN.pop_back();\r
bOptimized = true;\r
}\r
else if (m_vRPN[sz-1].Cmd == cmVAR && m_vRPN[sz-2].Cmd == cmVAR &&\r
- m_vRPN[sz-1].u.Val.ptr == m_vRPN[sz-2].u.Val.ptr)\r
+ m_vRPN[sz-1].Val.ptr == m_vRPN[sz-2].Val.ptr)\r
{\r
// Optimization: a*a -> a^2\r
m_vRPN[sz-2].Cmd = cmVARPOW2;\r
break;\r
\r
case cmDIV:\r
- if (m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVARMUL && m_vRPN[sz-1].u.Val.data2!=0)\r
+ if (m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVARMUL && m_vRPN[sz-1].Val.data2!=0)\r
{\r
// Optimization: 4*a/2 -> 2*a\r
- m_vRPN[sz-2].u.Val.data /= m_vRPN[sz-1].u.Val.data2;\r
- m_vRPN[sz-2].u.Val.data2 /= m_vRPN[sz-1].u.Val.data2;\r
+ m_vRPN[sz-2].Val.data /= m_vRPN[sz-1].Val.data2;\r
+ m_vRPN[sz-2].Val.data2 /= m_vRPN[sz-1].Val.data2;\r
m_vRPN.pop_back();\r
bOptimized = true;\r
}\r
\r
SToken tok;\r
tok.Cmd = cmASSIGN;\r
- tok.u.Val.ptr = a_pVar;\r
+ tok.Oprt.ptr = a_pVar;\r
m_vRPN.push_back(tok);\r
}\r
\r
\r
SToken tok;\r
tok.Cmd = cmFUNC;\r
- tok.u.Fun.argc = a_iArgc;\r
- tok.u.Fun.ptr = a_pFun;\r
+ tok.Fun.argc = a_iArgc;\r
+ tok.Fun.ptr = a_pFun;\r
m_vRPN.push_back(tok);\r
}\r
\r
\r
SToken tok;\r
tok.Cmd = cmFUNC_BULK;\r
- tok.u.Fun.argc = a_iArgc;\r
- tok.u.Fun.ptr = a_pFun;\r
+ tok.Fun.argc = a_iArgc;\r
+ tok.Fun.ptr = a_pFun;\r
m_vRPN.push_back(tok);\r
}\r
\r
\r
SToken tok;\r
tok.Cmd = cmFUNC_STR;\r
- tok.u.Fun.argc = a_iArgc;\r
- tok.u.Fun.idx = a_iIdx;\r
- tok.u.Fun.ptr = a_pFun;\r
+ tok.Fun.argc = a_iArgc;\r
+ tok.Fun.idx = a_iIdx;\r
+ tok.Fun.ptr = a_pFun;\r
m_vRPN.push_back(tok);\r
\r
m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos);\r
case cmELSE:\r
stElse.push(i);\r
idx = stIf.pop();\r
- m_vRPN[idx].u.Oprt.offset = i - idx;\r
+ m_vRPN[idx].Oprt.offset = i - idx;\r
break;\r
\r
case cmENDIF:\r
idx = stElse.pop();\r
- m_vRPN[idx].u.Oprt.offset = i - idx;\r
+ m_vRPN[idx].Oprt.offset = i - idx;\r
break;\r
\r
default:\r
switch (m_vRPN[i].Cmd)\r
{\r
case cmVAL: mu::console() << _T("VAL \t");\r
- mu::console() << _T("[") << m_vRPN[i].u.Val.data2 << _T("]\n");\r
+ mu::console() << _T("[") << m_vRPN[i].Val.data2 << _T("]\n");\r
break;\r
\r
case cmVAR: mu::console() << _T("VAR \t");\r
- mu::console() << _T("[ADDR: 0x") << std::hex << m_vRPN[i].u.Val.ptr << _T("]\n"); \r
+ mu::console() << _T("[ADDR: 0x") << std::hex << m_vRPN[i].Val.ptr << _T("]\n"); \r
break;\r
\r
case cmVARPOW2: mu::console() << _T("VARPOW2 \t");\r
- mu::console() << _T("[ADDR: 0x") << std::hex << m_vRPN[i].u.Val.ptr << _T("]\n"); \r
+ mu::console() << _T("[ADDR: 0x") << std::hex << m_vRPN[i].Val.ptr << _T("]\n"); \r
break;\r
\r
case cmVARPOW3: mu::console() << _T("VARPOW3 \t");\r
- mu::console() << _T("[ADDR: 0x") << std::hex << m_vRPN[i].u.Val.ptr << _T("]\n"); \r
+ mu::console() << _T("[ADDR: 0x") << std::hex << m_vRPN[i].Val.ptr << _T("]\n"); \r
break;\r
\r
case cmVARPOW4: mu::console() << _T("VARPOW4 \t");\r
- mu::console() << _T("[ADDR: 0x") << std::hex << m_vRPN[i].u.Val.ptr << _T("]\n"); \r
+ mu::console() << _T("[ADDR: 0x") << std::hex << m_vRPN[i].Val.ptr << _T("]\n"); \r
break;\r
\r
case cmVARMUL: mu::console() << _T("VARMUL \t");\r
- mu::console() << _T("[ADDR: 0x") << std::hex << m_vRPN[i].u.Val.ptr << _T("]"); \r
- mu::console() << _T(" * [") << m_vRPN[i].u.Val.data << _T("]");\r
- mu::console() << _T(" + [") << m_vRPN[i].u.Val.data2 << _T("]\n");\r
+ mu::console() << _T("[ADDR: 0x") << std::hex << m_vRPN[i].Val.ptr << _T("]"); \r
+ mu::console() << _T(" * [") << m_vRPN[i].Val.data << _T("]");\r
+ mu::console() << _T(" + [") << m_vRPN[i].Val.data2 << _T("]\n");\r
break;\r
\r
case cmFUNC: mu::console() << _T("CALL\t");\r
- mu::console() << _T("[ARG:") << std::dec << m_vRPN[i].u.Fun.argc << _T("]"); \r
- mu::console() << _T("[ADDR: 0x") << std::hex << m_vRPN[i].u.Fun.ptr << _T("]"); \r
+ mu::console() << _T("[ARG:") << std::dec << m_vRPN[i].Fun.argc << _T("]"); \r
+ mu::console() << _T("[ADDR: 0x") << std::hex << m_vRPN[i].Fun.ptr << _T("]"); \r
mu::console() << _T("\n");\r
break;\r
\r
case cmFUNC_STR:\r
mu::console() << _T("CALL STRFUNC\t");\r
- mu::console() << _T("[ARG:") << std::dec << m_vRPN[i].u.Fun.argc << _T("]");\r
- mu::console() << _T("[IDX:") << std::dec << m_vRPN[i].u.Fun.idx << _T("]");\r
- mu::console() << _T("[ADDR: 0x") << m_vRPN[i].u.Fun.ptr << _T("]\n"); \r
+ mu::console() << _T("[ARG:") << std::dec << m_vRPN[i].Fun.argc << _T("]");\r
+ mu::console() << _T("[IDX:") << std::dec << m_vRPN[i].Fun.idx << _T("]");\r
+ mu::console() << _T("[ADDR: 0x") << m_vRPN[i].Fun.ptr << _T("]\n"); \r
break;\r
\r
case cmLT: mu::console() << _T("LT\n"); break;\r
case cmPOW: mu::console() << _T("POW\n"); break;\r
\r
case cmIF: mu::console() << _T("IF\t");\r
- mu::console() << _T("[OFFSET:") << std::dec << m_vRPN[i].u.Oprt.offset << _T("]\n");\r
+ mu::console() << _T("[OFFSET:") << std::dec << m_vRPN[i].Oprt.offset << _T("]\n");\r
break;\r
\r
case cmELSE: mu::console() << _T("ELSE\t");\r
- mu::console() << _T("[OFFSET:") << std::dec << m_vRPN[i].u.Oprt.offset << _T("]\n");\r
+ mu::console() << _T("[OFFSET:") << std::dec << m_vRPN[i].Oprt.offset << _T("]\n");\r
break;\r
\r
case cmENDIF: mu::console() << _T("ENDIF\n"); break;\r
\r
case cmASSIGN: \r
mu::console() << _T("ASSIGN\t");\r
- mu::console() << _T("[ADDR: 0x") << m_vRPN[i].u.Oprt.ptr << _T("]\n"); \r
+ mu::console() << _T("[ADDR: 0x") << m_vRPN[i].Oprt.ptr << _T("]\n"); \r
break; \r
\r
default: mu::console() << _T("(unknown code: ") << m_vRPN[i].Cmd << _T(")\n"); \r
m_vErrMsg[ecUNEXPECTED_CONDITIONAL] = _T("The \"$TOK$\" operator must be preceeded by a closing bracket.");\r
m_vErrMsg[ecMISSING_ELSE_CLAUSE] = _T("If-then-else operator is missing an else clause");\r
m_vErrMsg[ecMISPLACED_COLON] = _T("Misplaced colon at position $POS$");\r
-\r
+ m_vErrMsg[ecUNREASONABLE_NUMBER_OF_COMPUTATIONS] = _T("Number of computations to small for bulk mode. (Vectorisation overhead too costly)");\r
+ \r
#if defined(_DEBUG)\r
for (int i=0; i<ecCOUNT; ++i)\r
if (!m_vErrMsg[i].length())\r
\r
If the error is not related to a distinct position this will return -1\r
*/\r
- std::size_t ParserError::GetPos() const\r
+ int ParserError::GetPos() const\r
{\r
return m_iPos;\r
}\r
AddTest(&ParserTester::TestBinOprt);\r
AddTest(&ParserTester::TestException);\r
AddTest(&ParserTester::TestStrArg);\r
+ AddTest(&ParserTester::TestBulkMode);\r
\r
ParserTester::c_iCount = 0;\r
}\r
iStat += EqnTest(_T("strfun1(\"100\")"), 100, true);\r
iStat += EqnTest(_T("strfun2(\"100\",1)"), 101, true);\r
iStat += EqnTest(_T("strfun3(\"99\",1,2)"), 102, true);\r
+ // string constants\r
+ iStat += EqnTest(_T("atof(str1)+atof(str2)"), 3.33, true);\r
\r
if (iStat==0)\r
mu::console() << _T("passed") << endl;\r
return iStat;\r
}\r
\r
+ //---------------------------------------------------------------------------------------------\r
+ int ParserTester::TestBulkMode()\r
+ {\r
+ int iStat = 0;\r
+ mu::console() << _T("testing bulkmode...");\r
+\r
+#define EQN_TEST_BULK(EXPR, R1, R2, R3, R4, PASS) \\r
+ { \\r
+ double res[] = { R1, R2, R3, R4 }; \\r
+ iStat += EqnTestBulk(_T(EXPR), res, (PASS)); \\r
+ }\r
+\r
+ // Bulk Variables for the test:\r
+ // a: 1,2,3,4\r
+ // b: 2,2,2,2\r
+ // c: 3,3,3,3\r
+ // d: 5,4,3,2\r
+ EQN_TEST_BULK("a", 1, 1, 1, 1, false)\r
+ EQN_TEST_BULK("a", 1, 2, 3, 4, true)\r
+ EQN_TEST_BULK("b=a", 1, 2, 3, 4, true)\r
+ EQN_TEST_BULK("b=a, b*10", 10, 20, 30, 40, true)\r
+ EQN_TEST_BULK("b=a, b*10, a", 1, 2, 3, 4, true)\r
+ EQN_TEST_BULK("a+b", 3, 4, 5, 6, true)\r
+ EQN_TEST_BULK("c*(a+b)", 9, 12, 15, 18, true)\r
+#undef EQN_TEST_BULK\r
+\r
+ if (iStat == 0)\r
+ mu::console() << _T("passed") << endl;\r
+ else\r
+ mu::console() << _T("\n failed with ") << iStat << _T(" errors") << endl;\r
+\r
+ return iStat;\r
+ }\r
+\r
//---------------------------------------------------------------------------------------------\r
int ParserTester::TestBinOprt()\r
{\r
\r
// built in operators\r
// xor operator\r
- //iStat += EqnTest(_T("1 xor 2"), 3, true); \r
- //iStat += EqnTest(_T("a xor b"), 3, true); // with a=1 and b=2\r
- //iStat += EqnTest(_T("1 xor 2 xor 3"), 0, true); \r
- //iStat += EqnTest(_T("a xor b xor 3"), 0, true); // with a=1 and b=2\r
- //iStat += EqnTest(_T("a xor b xor c"), 0, true); // with a=1 and b=2\r
- //iStat += EqnTest(_T("(1 xor 2) xor 3"), 0, true); \r
- //iStat += EqnTest(_T("(a xor b) xor c"), 0, true); // with a=1 and b=2\r
- //iStat += EqnTest(_T("(a) xor (b) xor c"), 0, true); // with a=1 and b=2\r
- //iStat += EqnTest(_T("1 or 2"), 3, true); \r
- //iStat += EqnTest(_T("a or b"), 3, true); // with a=1 and b=2\r
+\r
iStat += EqnTest(_T("a++b"), 3, true);\r
iStat += EqnTest(_T("a ++ b"), 3, true);\r
iStat += EqnTest(_T("1++2"), 3, true);\r
iStat += EqnTest(_T("2*(a=b)"), 4, true);\r
iStat += EqnTest(_T("2*(a=b+1)"), 6, true);\r
iStat += EqnTest(_T("(a=b+1)*2"), 6, true);\r
+ iStat += EqnTest(_T("a=c, a*10"), 30, true);\r
\r
iStat += EqnTest(_T("2^2^3"), 256, true); \r
iStat += EqnTest(_T("1/2/3"), 1.0/6.0, true); \r
int iStat(0);\r
mu::console() << "testing infix operators...";\r
\r
+ iStat += EqnTest( _T("+1"), +1, true);\r
+ iStat += EqnTest( _T("-(+1)"), -1, true);\r
+ iStat += EqnTest( _T("-(+1)*2"), -2, true);\r
+ iStat += EqnTest( _T("-(+2)*sqrt(4)"), -4, true);\r
+ iStat += EqnTest( _T("3-+a"), 2, true);\r
+ iStat += EqnTest( _T("+1*3"), 3, true);\r
+\r
iStat += EqnTest( _T("-1"), -1, true);\r
iStat += EqnTest( _T("-(-1)"), 1, true);\r
iStat += EqnTest( _T("-(-1)*2"), 2, true);\r
iStat += EqnTest( _T("(e^(ln(7)))"), 7, true);\r
iStat += EqnTest( _T("1-(e^(ln(7)))"), -6, true);\r
iStat += EqnTest( _T("2*(e^(ln(7)))"), 14, true);\r
- iStat += EqnTest( _T("10^log(5)"), 5, true);\r
+ iStat += EqnTest( _T("10^log(5)"), pow(10.0, log(5.0)), true);\r
iStat += EqnTest( _T("10^log10(5)"), 5, true);\r
iStat += EqnTest( _T("2^log2(4)"), 4, true);\r
iStat += EqnTest( _T("-(sin(0)+1)"), -1, true);\r
iStat += ThrowTest(_T("sin(3)cos(3)"), ecUNEXPECTED_FUN);\r
iStat += ThrowTest(_T("a+b+c=10"), ecUNEXPECTED_OPERATOR);\r
iStat += ThrowTest(_T("a=b=3"), ecUNEXPECTED_OPERATOR);\r
-\r
+ \r
#if defined(MUP_MATH_EXCEPTIONS)\r
// divide by zero whilst constant folding\r
iStat += ThrowTest(_T("1/0"), ecDIV_BY_ZERO);\r
double a_fRes2)\r
{\r
ParserTester::c_iCount++;\r
- value_type fVal[2] = {-999, -999 }; // should be equalinitially\r
\r
try\r
{\r
+ value_type fVal[2] = {-999, -999 }; // should be equalinitially\r
+ \r
Parser p;\r
+ value_type var = 0;\r
\r
// variable\r
- value_type var = 0;\r
p.DefineVar( _T("a"), &var);\r
p.SetExpr(a_str);\r
\r
p1->DefineConst( _T("const"), 1);\r
p1->DefineConst( _T("const1"), 2);\r
p1->DefineConst( _T("const2"), 3);\r
+ // string constants\r
+ p1->DefineStrConst( _T("str1"), _T("1.11"));\r
+ p1->DefineStrConst( _T("str2"), _T("2.22"));\r
// variables\r
value_type vVarVal[] = { 1, 2, 3, -2};\r
p1->DefineVar( _T("a"), &vVarVal[0]);\r
// The tests equations never result in infinity, if they do thats a bug.\r
// reference:\r
// http://sourceforge.net/projects/muparser/forums/forum/462843/topic/5037825\r
- if (numeric_limits<value_type>::has_infinity)\r
+ #pragma warning(push)\r
+ #pragma warning(disable:4127)\r
+ if (std::numeric_limits<value_type>::has_infinity)\r
+ #pragma warning(pop)\r
+ {\r
bCloseEnough &= (fabs(fVal[i]) != numeric_limits<value_type>::infinity());\r
- }\r
+ }\r
+ }\r
\r
iRet = ((bCloseEnough && a_fPass) || (!bCloseEnough && !a_fPass)) ? 0 : 1;\r
\r
ParserTester::c_iCount++;\r
\r
value_type vVarVal[] = {1, 2, 3}; // variable values\r
- value_type fVal[2] = {-99, -999}; // results: initially should be different\r
int iRet(0);\r
\r
try\r
{\r
+ value_type fVal[2] = {-99, -999}; // results: initially should be different\r
ParserInt p;\r
p.DefineConst( _T("const1"), 1);\r
p.DefineConst( _T("const2"), 2);\r
return iRet;\r
}\r
\r
+ //---------------------------------------------------------------------------\r
+ /** \brief Test an expression in Bulk Mode. */\r
+ int ParserTester::EqnTestBulk(const string_type &a_str, double a_fRes[4], bool a_fPass)\r
+ {\r
+ ParserTester::c_iCount++;\r
+\r
+ // Define Bulk Variables\r
+ int nBulkSize = 4;\r
+ value_type vVariableA[] = { 1, 2, 3, 4 }; // variable values\r
+ value_type vVariableB[] = { 2, 2, 2, 2 }; // variable values\r
+ value_type vVariableC[] = { 3, 3, 3, 3 }; // variable values\r
+ value_type vResults[] = { 0, 0, 0, 0 }; // variable values\r
+ int iRet(0);\r
+\r
+ try\r
+ {\r
+ Parser p;\r
+ p.DefineConst(_T("const1"), 1);\r
+ p.DefineConst(_T("const2"), 2);\r
+ p.DefineVar(_T("a"), vVariableA);\r
+ p.DefineVar(_T("b"), vVariableB);\r
+ p.DefineVar(_T("c"), vVariableC);\r
+\r
+ p.SetExpr(a_str);\r
+ p.Eval(vResults, nBulkSize);\r
+\r
+ bool bCloseEnough(true);\r
+ for (int i = 0; i < nBulkSize; ++i)\r
+ {\r
+ bCloseEnough &= (fabs(a_fRes[i] - vResults[i]) <= fabs(a_fRes[i] * 0.00001));\r
+ }\r
+\r
+ iRet = ((bCloseEnough && a_fPass) || (!bCloseEnough && !a_fPass)) ? 0 : 1;\r
+ if (iRet == 1)\r
+ {\r
+ mu::console() << _T("\n fail: ") << a_str.c_str()\r
+ << _T(" (incorrect result; expected: {") << a_fRes[0] << _T(",") << a_fRes[1] << _T(",") << a_fRes[2] << _T(",") << a_fRes[3] << _T("}")\r
+ << _T(" ;calculated: ") << vResults[0] << _T(",") << vResults[1] << _T(",") << vResults[2] << _T(",") << vResults[3] << _T("}");\r
+ }\r
+ }\r
+ catch (Parser::exception_type &e)\r
+ {\r
+ if (a_fPass)\r
+ {\r
+ mu::console() << _T("\n fail: ") << e.GetExpr() << _T(" : ") << e.GetMsg();\r
+ iRet = 1;\r
+ }\r
+ }\r
+ catch (...)\r
+ {\r
+ mu::console() << _T("\n fail: ") << a_str.c_str() << _T(" (unexpected exception)");\r
+ iRet = 1; // exceptions other than ParserException are not allowed\r
+ }\r
+\r
+ return iRet;\r
+ }\r
+\r
//---------------------------------------------------------------------------\r
/** \brief Internal error in test class Test is going to be aborted. */\r
void ParserTester::Abort() const\r
m_pFactoryData = a_Reader.m_pFactoryData;\r
m_iBrackets = a_Reader.m_iBrackets;\r
m_cArgSep = a_Reader.m_cArgSep;\r
+ m_fZero = a_Reader.m_fZero;\r
+ m_lastTok = a_Reader.m_lastTok;\r
}\r
\r
//---------------------------------------------------------------------------\r
{\r
assert(m_pParser);\r
\r
- std::stack<int> FunArgs;\r
const char_type *szFormula = m_strFormula.c_str();\r
token_type tok;\r
\r
int ParserTokenReader::ExtractOperatorToken(string_type &a_sTok, \r
int a_iPos) const\r
{\r
- int iEnd = (int)m_strFormula.find_first_not_of(m_pParser->ValidInfixOprtChars(), a_iPos);\r
+ // Changed as per Issue 6: https://code.google.com/p/muparser/issues/detail?id=6\r
+ int iEnd = (int)m_strFormula.find_first_not_of(m_pParser->ValidOprtChars(), a_iPos);\r
if (iEnd==(int)string_type::npos)\r
iEnd = (int)m_strFormula.length();\r
\r
Error(ecUNEXPECTED_OPERATOR, m_iPos, pOprtDef[i]);\r
}\r
\r
- m_iSynFlags = noBC | noOPT | noARG_SEP | noPOSTOP | noASSIGN | noIF | noELSE;\r
- m_iSynFlags |= ( (i != cmEND) && ( i != cmBC) ) ? noEND : 0;\r
+ m_iSynFlags = noBC | noOPT | noARG_SEP | noPOSTOP | noASSIGN | noIF | noELSE | noEND;\r
break;\r
\r
case cmBO:\r
}\r
\r
m_iPos += (int)sID.length();\r
- m_iSynFlags = noBC | noOPT | noARG_SEP | noPOSTOP | noEND | noBC | noASSIGN;\r
+ m_iSynFlags = noBC | noOPT | noARG_SEP | noPOSTOP | noEND | noASSIGN;\r
return true;\r
}\r
}\r
int iStart = m_iPos;\r
if ( (*item)(m_strFormula.c_str() + m_iPos, &m_iPos, &fVal)==1 )\r
{\r
- strTok.assign(m_strFormula.c_str(), iStart, m_iPos);\r
+ // 2013-11-27 Issue 2: https://code.google.com/p/muparser/issues/detail?id=2\r
+ strTok.assign(m_strFormula.c_str(), iStart, m_iPos-iStart);\r
+\r
if (m_iSynFlags & noVAL)\r
Error(ecUNEXPECTED_VAL, m_iPos - (int)strTok.length(), strTok);\r
\r
*/\r
bool ParserTokenReader::IsVarTok(token_type &a_Tok)\r
{\r
- if (!m_pVarDef->size())\r
+ if (m_pVarDef->empty())\r
return false;\r
\r
string_type strTok;\r
//---------------------------------------------------------------------------\r
bool ParserTokenReader::IsStrVarTok(token_type &a_Tok)\r
{\r
- if (!m_pStrVarDef || !m_pStrVarDef->size())\r
+ if (!m_pStrVarDef || m_pStrVarDef->empty())\r
return false;\r
\r
string_type strTok;\r
"Always use the bundled functionparser library instead of an external one."
OFF)
-SET(MUPARSER_FOLDER "${CMAKE_SOURCE_DIR}/bundled/muparser_v2_2_3/")
+SET(MUPARSER_FOLDER "${CMAKE_SOURCE_DIR}/bundled/muparser_v2_2_4/")