From cd005c759a52b253b7694988399621ea56b314bc Mon Sep 17 00:00:00 2001 From: Nigel Stewart Date: Sun, 10 Dec 2023 11:36:15 +1000 Subject: [PATCH] Opt-out of std::locale via cmake -DENABLE_LOCALE=N --- CMakeLists.txt | 7 +++++++ include/muParserBase.h | 9 ++++++++- src/muParser.cpp | 2 ++ src/muParserBase.cpp | 11 ++++++++++- src/muParserDLL.cpp | 2 ++ 5 files changed, 29 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a33eb47..51374bf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,6 +18,7 @@ set(MUPARSER_VERSION ${MUPARSER_VERSION_MAJOR}.${MUPARSER_VERSION_MINOR}.${MUPAR # Build options option(ENABLE_SAMPLES "Build the samples" ON) +option(ENABLE_LOCALE "Enable std::locale support" ON) option(ENABLE_OPENMP "Enable OpenMP for multithreading" ON) option(ENABLE_WIDE_CHAR "Enable wide character support" OFF) option(BUILD_SHARED_LIBS "Build shared/static libs" ON) @@ -72,6 +73,12 @@ if(ENABLE_WIDE_CHAR) target_compile_definitions(muparser PUBLIC _UNICODE) endif() +if(ENABLE_LOCALE) +else() + target_compile_definitions(muparser PUBLIC MUPARSER_NO_LOCALE) + add_definitions( -DMUPARSER_NO_LOCALE ) +endif() + set_target_properties(muparser PROPERTIES VERSION ${MUPARSER_VERSION} SOVERSION ${MUPARSER_VERSION_MAJOR} diff --git a/include/muParserBase.h b/include/muParserBase.h index 15ac151..4a563f7 100644 --- a/include/muParserBase.h +++ b/include/muParserBase.h @@ -35,9 +35,12 @@ #include #include #include -#include #include +#if !defined(MUPARSER_NO_LOCALE) +#include +#endif + //--- Parser includes -------------------------------------------------------------------------- #include "muParserDef.h" #include "muParserTokenReader.h" @@ -119,9 +122,11 @@ namespace mu void SetExpr(const string_type& a_sExpr); void SetVarFactory(facfun_type a_pFactory, void* pUserData = nullptr); +#if !defined(MUPARSER_NO_LOCALE) void SetDecSep(char_type cDecSep); void SetThousandsSep(char_type cThousandsSep = 0); void ResetLocale(); +#endif void EnableOptimizer(bool a_bIsOn = true); void EnableBuiltInOprt(bool a_bIsOn = true); @@ -205,7 +210,9 @@ namespace mu virtual void OnDetectVar(string_type* pExpr, int& nStart, int& nEnd); static const char_type* c_DefaultOprt[]; +#if !defined(MUPARSER_NO_LOCALE) static std::locale s_locale; ///< The locale used by the parser +#endif static bool g_DbgDumpCmdCode; static bool g_DbgDumpStack; diff --git a/src/muParser.cpp b/src/muParser.cpp index d58a410..6c866f3 100644 --- a/src/muParser.cpp +++ b/src/muParser.cpp @@ -75,7 +75,9 @@ namespace mu stringstream_type stream(a_szExpr); stream.seekg(0); // todo: check if this really is necessary +#if !defined(MUPARSER_NO_LOCALE) stream.imbue(Parser::s_locale); +#endif stream >> fVal; stringstream_type::pos_type iEnd = stream.tellg(); // Position after reading diff --git a/src/muParserBase.cpp b/src/muParserBase.cpp index 5ffbb49..71a2816 100644 --- a/src/muParserBase.cpp +++ b/src/muParserBase.cpp @@ -36,10 +36,13 @@ #include #include #include -#include #include #include +#if !defined(MUPARSER_NO_LOCALE) +#include +#endif + #ifdef MUP_USE_OPENMP #include @@ -59,7 +62,9 @@ using namespace std; namespace mu { +#if !defined(MUPARSER_NO_LOCALE) std::locale ParserBase::s_locale = std::locale(std::locale::classic(), new change_dec_sep('.')); +#endif bool ParserBase::g_DbgDumpCmdCode = false; bool ParserBase::g_DbgDumpStack = false; @@ -193,6 +198,7 @@ namespace mu m_sInfixOprtChars = a_Parser.m_sInfixOprtChars; } +#if !defined(MUPARSER_NO_LOCALE) //--------------------------------------------------------------------------- /** \brief Set the decimal separator. \param cDecSep Decimal separator as a character value. @@ -232,6 +238,7 @@ namespace mu s_locale = std::locale(std::locale("C"), new change_dec_sep('.')); SetArgSep(','); } +#endif //--------------------------------------------------------------------------- /** \brief Initialize the token reader. @@ -440,9 +447,11 @@ namespace mu */ void ParserBase::SetExpr(const string_type& a_sExpr) { +#if !defined(MUPARSER_NO_LOCALE) // Check locale compatibility if (m_pTokenReader->GetArgSep() == std::use_facet >(s_locale).decimal_point()) Error(ecLOCALE); +#endif // Check maximum allowed expression length. An arbitrary value small enough so i can debug expressions sent to me if (a_sExpr.length() >= MaxLenExpression) diff --git a/src/muParserDLL.cpp b/src/muParserDLL.cpp index 5730f71..d27fda3 100644 --- a/src/muParserDLL.cpp +++ b/src/muParserDLL.cpp @@ -1093,6 +1093,7 @@ API_EXPORT(void) mupSetArgSep(muParserHandle_t a_hParser, const muChar_t cArgSep } +#if !defined(MUPARSER_NO_LOCALE) API_EXPORT(void) mupResetLocale(muParserHandle_t a_hParser) { MU_TRY @@ -1118,6 +1119,7 @@ API_EXPORT(void) mupSetThousandsSep(muParserHandle_t a_hParser, const muChar_t c p->SetThousandsSep(cThousandsSep); MU_CATCH } +#endif //--------------------------------------------------------------------------- /** \brief Retrieve name and value of a single parser constant.