From f9e0a2d92f2695a87d7a78d365e36c89de8a4103 Mon Sep 17 00:00:00 2001 From: Gavin Halliday Date: Tue, 27 Sep 2022 09:04:25 +0100 Subject: [PATCH] HPCC-28315 Fix compile problems with isalpha() in windows builds Signed-off-by: Gavin Halliday --- common/thorhelper/thorrparse.cpp | 10 ++-- .../configmgrlib/XSDSchemaParser.cpp | 5 +- ecl/hqlcpp/hqlregex.cpp | 10 ++-- system/include/platform.h | 55 ++++++++++--------- 4 files changed, 44 insertions(+), 36 deletions(-) diff --git a/common/thorhelper/thorrparse.cpp b/common/thorhelper/thorrparse.cpp index 841d60b991a..7301b7840fa 100644 --- a/common/thorhelper/thorrparse.cpp +++ b/common/thorhelper/thorrparse.cpp @@ -105,8 +105,9 @@ static const char * resultText[] = { "Done", "Backtrack", "TokenBack", "Continue static unsigned patternDepth; #endif -bool isAsciiMatch(unsigned code, unsigned next) +bool isAsciiMatch(unsigned code, unsigned _next) { + int next = (int)_next; switch (code) { case RCCalnum: return isalnum(next) != 0; @@ -143,7 +144,7 @@ bool isUnicodeMatch(unsigned code, unsigned next) case RCCblank: return u_isspace(next) != 0 || (next == '\t'); case RCCgraph: return u_isprint(next) && !u_isspace(next); case RCCpunct: return u_isprint(next) && !(u_isspace(next) || u_isalnum(next)); - case RCCxdigit: return (next < 128) && isxdigit(next); // should be good enough. + case RCCxdigit: return (next < 128) && isxdigit((int)next); // should be good enough. case RCCany: return true; default: UNIMPLEMENTED; @@ -1333,8 +1334,9 @@ void RegexAsciiISetPattern::addRange(unsigned low, unsigned high) assertex(low < 256 && high < 256); for (unsigned i = low; i <= high; i++) { - include[tolower(i)] = !inverted; - include[toupper(i)] = !inverted; + int cur = (int)i; + include[tolower(cur)] = !inverted; + include[toupper(cur)] = !inverted; } } } diff --git a/configuration/configmgr/configmgrlib/XSDSchemaParser.cpp b/configuration/configmgr/configmgrlib/XSDSchemaParser.cpp index 7a47079deb7..cde4036e606 100644 --- a/configuration/configmgr/configmgrlib/XSDSchemaParser.cpp +++ b/configuration/configmgr/configmgrlib/XSDSchemaParser.cpp @@ -666,7 +666,10 @@ void XSDSchemaParser::processXSDFiles(const std::string &path, const std::string // If the file has an XSD extension and not previously processed, build the fully // qualified name and parse it. std::string ext = filename.substr(dotPos + 1); - std::transform(ext.begin(), ext.end(), ext.begin(), tolower); + //Ugly. Because we overload tolower in windows the std::transform resolution fails. + //Therefore assign the function to a variable to force the disambiguation. + int (*func)(int) = tolower; + std::transform(ext.begin(), ext.end(), ext.begin(), func); if (ext == "xsd" && m_pSchemaItem->addUniqueName(filename)) { std::string fullyQualifiedFilePath = path; diff --git a/ecl/hqlcpp/hqlregex.cpp b/ecl/hqlcpp/hqlregex.cpp index cf2d621e0d7..9a6c62332d2 100644 --- a/ecl/hqlcpp/hqlregex.cpp +++ b/ecl/hqlcpp/hqlregex.cpp @@ -843,7 +843,7 @@ static bool canConsume(const ParseInformation & options, unsigned nextChar, unsi rtlThrowNoUnicode(); #endif - return (nextChar == (unsigned)tolower(matcherChar)) || (nextChar == (unsigned)toupper(matcherChar)); + return (nextChar == (unsigned)tolower((int)matcherChar)) || (nextChar == (unsigned)toupper((int)matcherChar)); } bool HqlRegexExpr::canConsume(unsigned nextChar) @@ -895,9 +895,9 @@ bool HqlRegexExpr::canConsume(unsigned nextChar) } else { - if (nextChar >= (unsigned)tolower(low) && nextChar <= (unsigned)tolower(high)) + if (nextChar >= (unsigned)tolower((int)low) && nextChar <= (unsigned)tolower((int)high)) return !invert; - if (nextChar >= (unsigned)toupper(low) && nextChar <= (unsigned)toupper(high)) + if (nextChar >= (unsigned)toupper((int)low) && nextChar <= (unsigned)toupper((int)high)) return !invert; } } @@ -956,8 +956,8 @@ void HqlRegexExpr::gatherConsumeSymbols(SymbolArray & symbols) else { - symbols.addUnique(tolower(charValue)); - symbols.addUnique(toupper(charValue)); + symbols.addUnique(tolower((int)charValue)); + symbols.addUnique(toupper((int)charValue)); } } else diff --git a/system/include/platform.h b/system/include/platform.h index 8b4b29dca4b..b3ccbf287ae 100644 --- a/system/include/platform.h +++ b/system/include/platform.h @@ -213,44 +213,47 @@ typedef unsigned long MaxCard; // MSVC 2008 in debug (perhaps other versions too) will throw exception if negative passed (see bug: #32013) #if (_MSC_VER>=1400) // >=vs2005 -#define strictmsvc_isalpha(c) isalpha(c) -#define isalpha(c) isalpha((const unsigned char)(c)) -#define strictmsvc_isupper(c) isupper(c) -#define isupper(c) isupper((const unsigned char)(c)) +//Defining overloaded versions of these functions is almost certainly undefined behaviour in the c++ standard. +//However it causes fewer problems than the previous fix using macros to redefine the functions. +#undef isalpha +inline bool isalpha(char c) { return isalpha((int)(unsigned char)c); } -#define strictmsvc_islower(c) islower(c) -#define islower(c) islower((const unsigned char)(c)) +#undef isupper +inline bool isupper(char c) { return isupper((int)(unsigned char)(c)); } -#define strictmsvc_isdigit(c) isdigit(c) -#define isdigit(c) isdigit((const unsigned char)(c)) +#undef islower +inline bool islower(char c) { return islower((int)(unsigned char)(c)); } -#define strictmsvc_isxdigit(c) isxdigit(c) -#define isxdigit(c) isxdigit((const unsigned char)(c)) +#undef isdigit +inline bool isdigit(char c) { return isdigit((int)(unsigned char)(c)); } -#define strictmsvc_isspace(c) isspace(c) -#define isspace(c) isspace((const unsigned char)(c)) +#undef isxdigit +inline bool isxdigit(char c) { return isxdigit((int)(unsigned char)(c)); } -#define strictmsvc_ispunct(c) ispunct(c) -#define ispunct(c) ispunct((const unsigned char)(c)) +#undef isspace +inline bool isspace(char c) { return isspace((int)(unsigned char)(c)); } -#define strictmsvc_isalnum(c) isalnum(c) -#define isalnum(c) isalnum((const unsigned char)(c)) +#undef ispunct +inline bool ispunct(char c) { return ispunct((int)(unsigned char)(c)); } -#define strictmsvc_isprint(c) isprint(c) -#define isprint(c) isprint((const unsigned char)(c)) +#undef isalnum +inline bool isalnum(char c) { return isalnum((int)(unsigned char)(c)); } -#define strictmsvc_isgraph(c) isgraph(c) -#define isgraph(c) isgraph((const unsigned char)(c)) +#undef isprint +inline bool isprint(char c) { return isprint((int)(unsigned char)(c)); } -#define strictmsvc_iscntrl(c) iscntrl(c) -#define iscntrl(c) iscntrl((const unsigned char)(c)) +#undef isgraph +inline bool isgraph(char c) { return isgraph((int)(unsigned char)(c)); } -#define strictmsvc_tolower(c) tolower(c) -#define tolower(c) tolower((const unsigned char)(c)) +#undef iscntrl +inline bool iscntrl(char c) { return iscntrl((int)(unsigned char)(c)); } -#define strictmsvc_toupper(c) toupper(c) -#define toupper(c) toupper((const unsigned char)(c)) +#undef tolower +inline int tolower(char c) { return tolower((int)(unsigned char)(c)); } + +#undef toupper +inline int toupper(char c) { return toupper((int)(unsigned char)(c)); } #endif // (_MSC_VER>=1400)