diff options
Diffstat (limited to 'src/util')
-rw-r--r-- | src/util/check.h | 41 | ||||
-rw-r--r-- | src/util/macros.h | 11 | ||||
-rw-r--r-- | src/util/moneystr.cpp | 1 | ||||
-rw-r--r-- | src/util/moneystr.h | 1 | ||||
-rw-r--r-- | src/util/spanparsing.cpp | 67 | ||||
-rw-r--r-- | src/util/spanparsing.h | 50 | ||||
-rw-r--r-- | src/util/string.h | 1 | ||||
-rw-r--r-- | src/util/system.cpp | 14 | ||||
-rw-r--r-- | src/util/threadnames.cpp | 1 | ||||
-rw-r--r-- | src/util/translation.h | 1 | ||||
-rw-r--r-- | src/util/validation.cpp | 5 | ||||
-rw-r--r-- | src/util/vector.h | 51 |
12 files changed, 233 insertions, 11 deletions
diff --git a/src/util/check.h b/src/util/check.h new file mode 100644 index 0000000000..d18887ae95 --- /dev/null +++ b/src/util/check.h @@ -0,0 +1,41 @@ +// Copyright (c) 2019 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_UTIL_CHECK_H +#define BITCOIN_UTIL_CHECK_H + +#include <tinyformat.h> + +#include <stdexcept> + +class NonFatalCheckError : public std::runtime_error +{ + using std::runtime_error::runtime_error; +}; + +/** + * Throw a NonFatalCheckError when the condition evaluates to false + * + * This should only be used + * - where the condition is assumed to be true, not for error handling or validating user input + * - where a failure to fulfill the condition is recoverable and does not abort the program + * + * For example in RPC code, where it is undersirable to crash the whole program, this can be generally used to replace + * asserts or recoverable logic errors. A NonFatalCheckError in RPC code is caught and passed as a string to the RPC + * caller, which can then report the issue to the developers. + */ +#define CHECK_NONFATAL(condition) \ + do { \ + if (!(condition)) { \ + throw NonFatalCheckError( \ + strprintf("%s:%d (%s)\n" \ + "Internal bug detected: '%s'\n" \ + "You may report this issue here: %s\n", \ + __FILE__, __LINE__, __func__, \ + (#condition), \ + PACKAGE_BUGREPORT)); \ + } \ + } while (false) + +#endif // BITCOIN_UTIL_CHECK_H diff --git a/src/util/macros.h b/src/util/macros.h new file mode 100644 index 0000000000..36ea87c0fe --- /dev/null +++ b/src/util/macros.h @@ -0,0 +1,11 @@ +// Copyright (c) 2019 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_UTIL_MACROS_H +#define BITCOIN_UTIL_MACROS_H + +#define PASTE(x, y) x ## y +#define PASTE2(x, y) PASTE(x, y) + +#endif // BITCOIN_UTIL_MACROS_H diff --git a/src/util/moneystr.cpp b/src/util/moneystr.cpp index f4e41eea4f..ba5a12e58c 100644 --- a/src/util/moneystr.cpp +++ b/src/util/moneystr.cpp @@ -5,7 +5,6 @@ #include <util/moneystr.h> -#include <primitives/transaction.h> #include <tinyformat.h> #include <util/strencodings.h> diff --git a/src/util/moneystr.h b/src/util/moneystr.h index b8e2812a96..4d0218911a 100644 --- a/src/util/moneystr.h +++ b/src/util/moneystr.h @@ -12,7 +12,6 @@ #include <amount.h> #include <attributes.h> -#include <cstdint> #include <string> /* Do not use these functions to represent or parse monetary amounts to or from diff --git a/src/util/spanparsing.cpp b/src/util/spanparsing.cpp new file mode 100644 index 0000000000..0c8575399a --- /dev/null +++ b/src/util/spanparsing.cpp @@ -0,0 +1,67 @@ +// Copyright (c) 2018 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include <util/spanparsing.h> + +#include <span.h> + +#include <string> +#include <vector> + +namespace spanparsing { + +bool Const(const std::string& str, Span<const char>& sp) +{ + if ((size_t)sp.size() >= str.size() && std::equal(str.begin(), str.end(), sp.begin())) { + sp = sp.subspan(str.size()); + return true; + } + return false; +} + +bool Func(const std::string& str, Span<const char>& sp) +{ + if ((size_t)sp.size() >= str.size() + 2 && sp[str.size()] == '(' && sp[sp.size() - 1] == ')' && std::equal(str.begin(), str.end(), sp.begin())) { + sp = sp.subspan(str.size() + 1, sp.size() - str.size() - 2); + return true; + } + return false; +} + +Span<const char> Expr(Span<const char>& sp) +{ + int level = 0; + auto it = sp.begin(); + while (it != sp.end()) { + if (*it == '(') { + ++level; + } else if (level && *it == ')') { + --level; + } else if (level == 0 && (*it == ')' || *it == ',')) { + break; + } + ++it; + } + Span<const char> ret = sp.first(it - sp.begin()); + sp = sp.subspan(it - sp.begin()); + return ret; +} + +std::vector<Span<const char>> Split(const Span<const char>& sp, char sep) +{ + std::vector<Span<const char>> ret; + auto it = sp.begin(); + auto start = it; + while (it != sp.end()) { + if (*it == sep) { + ret.emplace_back(start, it); + start = it + 1; + } + ++it; + } + ret.emplace_back(start, it); + return ret; +} + +} // namespace spanparsing diff --git a/src/util/spanparsing.h b/src/util/spanparsing.h new file mode 100644 index 0000000000..63f54758bd --- /dev/null +++ b/src/util/spanparsing.h @@ -0,0 +1,50 @@ +// Copyright (c) 2018 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_UTIL_SPANPARSING_H +#define BITCOIN_UTIL_SPANPARSING_H + +#include <span.h> + +#include <string> +#include <vector> + +namespace spanparsing { + +/** Parse a constant. + * + * If sp's initial part matches str, sp is updated to skip that part, and true is returned. + * Otherwise sp is unmodified and false is returned. + */ +bool Const(const std::string& str, Span<const char>& sp); + +/** Parse a function call. + * + * If sp's initial part matches str + "(", and sp ends with ")", sp is updated to be the + * section between the braces, and true is returned. Otherwise sp is unmodified and false + * is returned. + */ +bool Func(const std::string& str, Span<const char>& sp); + +/** Extract the expression that sp begins with. + * + * This function will return the initial part of sp, up to (but not including) the first + * comma or closing brace, skipping ones that are surrounded by braces. So for example, + * for "foo(bar(1),2),3" the initial part "foo(bar(1),2)" will be returned. sp will be + * updated to skip the initial part that is returned. + */ +Span<const char> Expr(Span<const char>& sp); + +/** Split a string on every instance of sep, returning a vector. + * + * If sep does not occur in sp, a singleton with the entirety of sp is returned. + * + * Note that this function does not care about braces, so splitting + * "foo(bar(1),2),3) on ',' will return {"foo(bar(1)", "2)", "3)"}. + */ +std::vector<Span<const char>> Split(const Span<const char>& sp, char sep); + +} // namespace spanparsing + +#endif // BITCOIN_UTIL_SPANPARSING_H diff --git a/src/util/string.h b/src/util/string.h index dec0c19b08..76a83a4949 100644 --- a/src/util/string.h +++ b/src/util/string.h @@ -5,7 +5,6 @@ #ifndef BITCOIN_UTIL_STRING_H #define BITCOIN_UTIL_STRING_H -#include <functional> #include <string> #include <vector> diff --git a/src/util/system.cpp b/src/util/system.cpp index 8098cde093..526bf559c3 100644 --- a/src/util/system.cpp +++ b/src/util/system.cpp @@ -9,7 +9,6 @@ #include <util/strencodings.h> #include <util/translation.h> -#include <stdarg.h> #if (defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)) #include <pthread.h> @@ -380,6 +379,15 @@ bool ArgsManager::ParseParameters(int argc, const char* const argv[], std::strin for (int i = 1; i < argc; i++) { std::string key(argv[i]); + +#ifdef MAC_OSX + // At the first time when a user gets the "App downloaded from the + // internet" warning, and clicks the Open button, macOS passes + // a unique process serial number (PSN) as -psn_... command-line + // argument, which we filter out. + if (key.substr(0, 5) == "-psn_") continue; +#endif + if (key == "-") break; //bitcoin-tx using stdin std::string val; size_t is_index = key.find('='); @@ -1153,12 +1161,12 @@ void SetupEnvironment() } #endif // On most POSIX systems (e.g. Linux, but not BSD) the environment's locale - // may be invalid, in which case the "C" locale is used as fallback. + // may be invalid, in which case the "C.UTF-8" locale is used as fallback. #if !defined(WIN32) && !defined(MAC_OSX) && !defined(__FreeBSD__) && !defined(__OpenBSD__) try { std::locale(""); // Raises a runtime error if current locale is invalid } catch (const std::runtime_error&) { - setenv("LC_ALL", "C", 1); + setenv("LC_ALL", "C.UTF-8", 1); } #elif defined(WIN32) // Set the default input/output charset is utf-8 diff --git a/src/util/threadnames.cpp b/src/util/threadnames.cpp index 168f9325d0..20df403a66 100644 --- a/src/util/threadnames.cpp +++ b/src/util/threadnames.cpp @@ -6,7 +6,6 @@ #include <config/bitcoin-config.h> #endif -#include <atomic> #include <thread> #if (defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)) diff --git a/src/util/translation.h b/src/util/translation.h index f100dab20d..0e6eb5a094 100644 --- a/src/util/translation.h +++ b/src/util/translation.h @@ -7,7 +7,6 @@ #include <tinyformat.h> -#include <utility> /** * Bilingual messages: diff --git a/src/util/validation.cpp b/src/util/validation.cpp index fe1f5a277e..9a0d889447 100644 --- a/src/util/validation.cpp +++ b/src/util/validation.cpp @@ -11,10 +11,9 @@ /** Convert CValidationState to a human-readable message for logging */ std::string FormatStateMessage(const CValidationState &state) { - return strprintf("%s%s (code %i)", + return strprintf("%s%s", state.GetRejectReason(), - state.GetDebugMessage().empty() ? "" : ", "+state.GetDebugMessage(), - state.GetRejectCode()); + state.GetDebugMessage().empty() ? "" : ", "+state.GetDebugMessage()); } const std::string strMessageMagic = "Bitcoin Signed Message:\n"; diff --git a/src/util/vector.h b/src/util/vector.h new file mode 100644 index 0000000000..dab65ded2a --- /dev/null +++ b/src/util/vector.h @@ -0,0 +1,51 @@ +// Copyright (c) 2019 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_UTIL_VECTOR_H +#define BITCOIN_UTIL_VECTOR_H + +#include <initializer_list> +#include <type_traits> +#include <vector> + +/** Construct a vector with the specified elements. + * + * This is preferable over the list initializing constructor of std::vector: + * - It automatically infers the element type from its arguments. + * - If any arguments are rvalue references, they will be moved into the vector + * (list initialization always copies). + */ +template<typename... Args> +inline std::vector<typename std::common_type<Args...>::type> Vector(Args&&... args) +{ + std::vector<typename std::common_type<Args...>::type> ret; + ret.reserve(sizeof...(args)); + // The line below uses the trick from https://www.experts-exchange.com/articles/32502/None-recursive-variadic-templates-with-std-initializer-list.html + (void)std::initializer_list<int>{(ret.emplace_back(std::forward<Args>(args)), 0)...}; + return ret; +} + +/** Concatenate two vectors, moving elements. */ +template<typename V> +inline V Cat(V v1, V&& v2) +{ + v1.reserve(v1.size() + v2.size()); + for (auto& arg : v2) { + v1.push_back(std::move(arg)); + } + return v1; +} + +/** Concatenate two vectors. */ +template<typename V> +inline V Cat(V v1, const V& v2) +{ + v1.reserve(v1.size() + v2.size()); + for (const auto& arg : v2) { + v1.push_back(arg); + } + return v1; +} + +#endif // BITCOIN_UTIL_VECTOR_H |