diff --git a/src/base58.cpp b/src/base58.cpp index 306547ce1e..849293634a 100644 --- a/src/base58.cpp +++ b/src/base58.cpp @@ -36,7 +36,7 @@ static const int8_t mapBase58[256] = { bool DecodeBase58(const char* psz, std::vector& vch) { // Skip leading spaces. - while (*psz && isspace(*psz)) + while (*psz && IsSpace(*psz)) psz++; // Skip and count leading '1's. int zeroes = 0; @@ -50,7 +50,7 @@ bool DecodeBase58(const char* psz, std::vector& vch) std::vector b256(size); // Process the characters. static_assert(sizeof(mapBase58)/sizeof(mapBase58[0]) == 256, "mapBase58.size() should be 256"); // guarantee not out of range - while (*psz && !isspace(*psz)) { + while (*psz && !IsSpace(*psz)) { // Decode base58 character int carry = mapBase58[(uint8_t)*psz]; if (carry == -1) // Invalid b58 character @@ -66,7 +66,7 @@ bool DecodeBase58(const char* psz, std::vector& vch) psz++; } // Skip trailing spaces. - while (isspace(*psz)) + while (IsSpace(*psz)) psz++; if (*psz != 0) return false; diff --git a/src/governance/governance-validators.cpp b/src/governance/governance-validators.cpp index 379771d59c..1e1936a1fc 100644 --- a/src/governance/governance-validators.cpp +++ b/src/governance/governance-validators.cpp @@ -100,7 +100,7 @@ bool CProposalValidator::ValidateName() static const std::string strAllowedChars = "-_abcdefghijklmnopqrstuvwxyz0123456789"; - std::transform(strName.begin(), strName.end(), strName.begin(), ::tolower); + std::transform(strName.begin(), strName.end(), strName.begin(), ToLower); if (strName.find_first_not_of(strAllowedChars) != std::string::npos) { strErrorMessages += "name contains invalid characters;"; @@ -168,7 +168,7 @@ bool CProposalValidator::ValidatePaymentAddress() return false; } - if (std::find_if(strPaymentAddress.begin(), strPaymentAddress.end(), ::isspace) != strPaymentAddress.end()) { + if (std::find_if(strPaymentAddress.begin(), strPaymentAddress.end(), IsSpace) != strPaymentAddress.end()) { strErrorMessages += "payment_address can't have whitespaces;"; return false; } @@ -196,7 +196,7 @@ bool CProposalValidator::ValidateURL() return false; } - if (std::find_if(strURL.begin(), strURL.end(), ::isspace) != strURL.end()) { + if (std::find_if(strURL.begin(), strURL.end(), IsSpace) != strURL.end()) { strErrorMessages += "url can't have whitespaces;"; return false; } diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 54f0fe8665..708c4f0e56 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -229,7 +230,7 @@ bool RPCConsole::RPCParseCommandLine(interfaces::Node* node, std::string &strRes if (lastResult.isArray()) { for(char argch: curarg) - if (!std::isdigit(argch)) + if (!IsDigit(argch)) throw std::runtime_error("Invalid result query"); subelement = lastResult[atoi(curarg.c_str())]; } diff --git a/src/rpc/masternode.cpp b/src/rpc/masternode.cpp index bf3c6882b6..4b18dabe33 100644 --- a/src/rpc/masternode.cpp +++ b/src/rpc/masternode.cpp @@ -557,7 +557,7 @@ static UniValue masternodelist(const JSONRPCRequest& request) if (!request.params[0].isNull()) strMode = request.params[0].get_str(); if (!request.params[1].isNull()) strFilter = request.params[1].get_str(); - std::transform(strMode.begin(), strMode.end(), strMode.begin(), ::tolower); + std::transform(strMode.begin(), strMode.end(), strMode.begin(), ToLower); if (request.fHelp || ( strMode != "addr" && strMode != "full" && strMode != "info" && strMode != "json" && diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 6ac222c0f5..1be07ef686 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -187,7 +187,7 @@ bool ParseBoolV(const UniValue& v, const std::string &strName) else if (v.isStr()) strBool = v.get_str(); - std::transform(strBool.begin(), strBool.end(), strBool.begin(), ::tolower); + std::transform(strBool.begin(), strBool.end(), strBool.begin(), ToLower); if (strBool == "true" || strBool == "yes" || strBool == "1") { return true; diff --git a/src/test/getarg_tests.cpp b/src/test/getarg_tests.cpp index f3ad0fe94b..311956bb5f 100644 --- a/src/test/getarg_tests.cpp +++ b/src/test/getarg_tests.cpp @@ -2,6 +2,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include #include #include @@ -17,7 +18,7 @@ static void ResetArgs(const std::string& strArg) { std::vector vecArg; if (strArg.size()) - boost::split(vecArg, strArg, boost::is_space(), boost::token_compress_on); + boost::split(vecArg, strArg, IsSpace, boost::token_compress_on); // Insert dummy executable name: vecArg.insert(vecArg.begin(), "testdash"); diff --git a/src/uint256.cpp b/src/uint256.cpp index dfd9218b86..2872901a65 100644 --- a/src/uint256.cpp +++ b/src/uint256.cpp @@ -33,11 +33,11 @@ void base_blob::SetHex(const char* psz) memset(m_data, 0, sizeof(m_data)); // skip leading spaces - while (isspace(*psz)) + while (IsSpace(*psz)) psz++; // skip 0x - if (psz[0] == '0' && tolower(psz[1]) == 'x') + if (psz[0] == '0' && ToLower((unsigned char)psz[1]) == 'x') psz += 2; // hex string to uint diff --git a/src/util/moneystr.cpp b/src/util/moneystr.cpp index bc376f1dc1..5d2f372d23 100644 --- a/src/util/moneystr.cpp +++ b/src/util/moneystr.cpp @@ -20,7 +20,7 @@ std::string FormatMoney(const CAmount& n) // Right-trim excess zeros before the decimal point: int nTrim = 0; - for (int i = str.size()-1; (str[i] == '0' && isdigit(str[i-2])); --i) + for (int i = str.size()-1; (str[i] == '0' && IsDigit(str[i-2])); --i) ++nTrim; if (nTrim) str.erase(str.size()-nTrim, nTrim); @@ -41,7 +41,7 @@ bool ParseMoney(const char* pszIn, CAmount& nRet) std::string strWhole; int64_t nUnits = 0; const char* p = pszIn; - while (isspace(*p)) + while (IsSpace(*p)) p++; for (; *p; p++) { @@ -49,21 +49,21 @@ bool ParseMoney(const char* pszIn, CAmount& nRet) { p++; int64_t nMult = COIN / 10; - while (isdigit(*p) && (nMult > 0)) + while (IsDigit(*p) && (nMult > 0)) { nUnits += nMult * (*p++ - '0'); nMult /= 10; } break; } - if (isspace(*p)) + if (IsSpace(*p)) break; - if (!isdigit(*p)) + if (!IsDigit(*p)) return false; strWhole.insert(strWhole.end(), *p); } for (; *p; p++) - if (!isspace(*p)) + if (!IsSpace(*p)) return false; if (strWhole.size() > 10) // guard against 63 bit overflow return false; diff --git a/src/util/strencodings.cpp b/src/util/strencodings.cpp index 27d757ef46..9481ca4573 100644 --- a/src/util/strencodings.cpp +++ b/src/util/strencodings.cpp @@ -87,7 +87,7 @@ std::vector ParseHex(const char* psz) std::vector vch; while (true) { - while (isspace(*psz)) + while (IsSpace(*psz)) psz++; signed char c = HexDigit(*psz++); if (c == (signed char)-1) @@ -272,7 +272,7 @@ std::string DecodeBase32(const std::string& str, bool* pf_invalid) { if (str.empty()) // No empty string allowed return false; - if (str.size() >= 1 && (isspace(str[0]) || isspace(str[str.size()-1]))) // No padding allowed + if (str.size() >= 1 && (IsSpace(str[0]) || IsSpace(str[str.size()-1]))) // No padding allowed return false; if (!ValidAsCString(str)) // No embedded NUL characters allowed return false; diff --git a/src/util/strencodings.h b/src/util/strencodings.h index f4a359854f..79a5937713 100644 --- a/src/util/strencodings.h +++ b/src/util/strencodings.h @@ -84,6 +84,21 @@ constexpr bool IsDigit(char c) return c >= '0' && c <= '9'; } +/** + * Tests if the given character is a whitespace character. The whitespace characters + * are: space, form-feed ('\f'), newline ('\n'), carriage return ('\r'), horizontal + * tab ('\t'), and vertical tab ('\v'). + * + * This function is locale independent. Under the C locale this function gives the + * same result as std::isspace. + * + * @param[in] c character to test + * @return true if the argument is a whitespace character; otherwise false + */ +constexpr inline bool IsSpace(char c) noexcept { + return c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v'; +} + /** * Convert string to signed 32-bit integer with strict parse error feedback. * @returns true if the entire string could be parsed as valid integer, diff --git a/src/util/system.cpp b/src/util/system.cpp index df605a6046..42f6cdc353 100644 --- a/src/util/system.cpp +++ b/src/util/system.cpp @@ -458,7 +458,7 @@ bool ArgsManager::ParseParameters(int argc, const char* const argv[], std::strin key.erase(is_index); } #ifdef WIN32 - std::transform(key.begin(), key.end(), key.begin(), ::tolower); + std::transform(key.begin(), key.end(), key.begin(), ToLower); if (key[0] == '/') key[0] = '-'; #endif diff --git a/test/lint/lint-locale-dependence.sh b/test/lint/lint-locale-dependence.sh index cd6e93eb32..79f5b2bb82 100755 --- a/test/lint/lint-locale-dependence.sh +++ b/test/lint/lint-locale-dependence.sh @@ -3,46 +3,30 @@ export LC_ALL=C KNOWN_VIOLATIONS=( - "src/base58.cpp:.*isspace" "src/bench/string_cast.cpp.*atoi" "src/dash-tx.cpp.*stoul" "src/dash-tx.cpp.*trim_right" - "src/dash-tx.cpp:.*atoi" - "src/core_read.cpp.*is_digit" "src/dbwrapper.cpp.*stoul" "src/dbwrapper.cpp:.*vsnprintf" - "src/governance/governance-validators.cpp.*isspace" - "src/governance/governance-validators.cpp.*tolower" "src/httprpc.cpp.*trim" "src/init.cpp:.*atoi" "src/init.cpp:.*fprintf" "src/qt/rpcconsole.cpp:.*atoi" - "src/qt/rpcconsole.cpp:.*isdigit" "src/rest.cpp:.*strtol" "src/rpc/blockchain.cpp.*atoi" "src/rpc/governance.cpp.*atoi" "src/rpc/masternode.cpp.*atoi" - "src/rpc/masternode.cpp.*tolower" - "src/rpc/server.cpp.*tolower" "src/statsd_client.cpp:.*snprintf" "src/test/dbwrapper_tests.cpp:.*snprintf" - "src/test/getarg_tests.cpp.*split" "src/torcontrol.cpp:.*atoi" "src/torcontrol.cpp:.*strtol" - "src/uint256.cpp:.*isspace" - "src/uint256.cpp:.*tolower" - "src/util/system.cpp:.*atoi" - "src/util/system.cpp:.*tolower" - "src/util/moneystr.cpp:.*isdigit" - "src/util/moneystr.cpp:.*isspace" "src/util/strencodings.cpp:.*atoi" - "src/util/strencodings.cpp:.*isspace" "src/util/strencodings.cpp:.*strtol" - "src/util/strencodings.cpp:.*strtoll" "src/util/strencodings.cpp:.*strtoul" - "src/util/strencodings.cpp:.*strtoull" "src/util/strencodings.h:.*atoi" "src/wallet/wallet.cpp:.*atoi" + "src/util/system.cpp:.*atoi" + "src/util/system.cpp:.*fprintf" ) REGEXP_IGNORE_EXTERNAL_DEPENDENCIES="^src/(crypto/ctaes/|leveldb/|secp256k1/|tinyformat.h|univalue/)"