From 9cc0230cfc1ae9b9c1c905cd9ac613bc98bfa43a Mon Sep 17 00:00:00 2001
From: practicalswift <practicalswift@users.noreply.github.com>
Date: Tue, 25 Sep 2018 07:00:36 +0200
Subject: [PATCH] Add NODISCARD to all {Decode,Parse}[...](...) functions
 returning bool. Sort includes.

---
 src/Makefile.am           |  1 +
 src/attributes.h          | 22 ++++++++++++++++++++++
 src/base58.h              | 10 ++++++----
 src/core_io.h             |  7 ++++---
 src/outputtype.h          |  3 ++-
 src/rest.cpp              |  5 +++--
 src/script/descriptor.cpp |  2 +-
 src/util/moneystr.h       | 11 ++++++-----
 src/util/strencodings.cpp |  2 +-
 src/util/strencodings.h   | 18 ++++++++++--------
 src/util/system.h         |  3 ++-
 11 files changed, 58 insertions(+), 26 deletions(-)
 create mode 100644 src/attributes.h

diff --git a/src/Makefile.am b/src/Makefile.am
index 703304ceb..be2d56917 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -95,6 +95,7 @@ endif
 BITCOIN_CORE_H = \
   addrdb.h \
   addrman.h \
+  attributes.h \
   base58.h \
   bech32.h \
   bloom.h \
diff --git a/src/attributes.h b/src/attributes.h
new file mode 100644
index 000000000..45099bd8b
--- /dev/null
+++ b/src/attributes.h
@@ -0,0 +1,22 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-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_ATTRIBUTES_H
+#define BITCOIN_ATTRIBUTES_H
+
+#if defined(__has_cpp_attribute)
+#  if __has_cpp_attribute(nodiscard)
+#    define NODISCARD [[nodiscard]]
+#  endif
+#endif
+#ifndef NODISCARD
+#  if defined(_MSC_VER) && _MSC_VER >= 1700
+#    define NODISCARD _Check_return_
+#  else
+#    define NODISCARD __attribute__((warn_unused_result))
+#  endif
+#endif
+
+#endif // BITCOIN_ATTRIBUTES_H
diff --git a/src/base58.h b/src/base58.h
index 9d3f90652..d6e0299a1 100644
--- a/src/base58.h
+++ b/src/base58.h
@@ -14,6 +14,8 @@
 #ifndef BITCOIN_BASE58_H
 #define BITCOIN_BASE58_H
 
+#include <attributes.h>
+
 #include <string>
 #include <vector>
 
@@ -33,13 +35,13 @@ std::string EncodeBase58(const std::vector<unsigned char>& vch);
  * return true if decoding is successful.
  * psz cannot be nullptr.
  */
-bool DecodeBase58(const char* psz, std::vector<unsigned char>& vchRet);
+NODISCARD bool DecodeBase58(const char* psz, std::vector<unsigned char>& vchRet);
 
 /**
  * Decode a base58-encoded string (str) into a byte vector (vchRet).
  * return true if decoding is successful.
  */
-bool DecodeBase58(const std::string& str, std::vector<unsigned char>& vchRet);
+NODISCARD bool DecodeBase58(const std::string& str, std::vector<unsigned char>& vchRet);
 
 /**
  * Encode a byte vector into a base58-encoded string, including checksum
@@ -50,12 +52,12 @@ std::string EncodeBase58Check(const std::vector<unsigned char>& vchIn);
  * Decode a base58-encoded string (psz) that includes a checksum into a byte
  * vector (vchRet), return true if decoding is successful
  */
-bool DecodeBase58Check(const char* psz, std::vector<unsigned char>& vchRet);
+NODISCARD bool DecodeBase58Check(const char* psz, std::vector<unsigned char>& vchRet);
 
 /**
  * Decode a base58-encoded string (str) that includes a checksum into a byte
  * vector (vchRet), return true if decoding is successful
  */
-bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRet);
+NODISCARD bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRet);
 
 #endif // BITCOIN_BASE58_H
diff --git a/src/core_io.h b/src/core_io.h
index 2c3b64d81..6f87161f4 100644
--- a/src/core_io.h
+++ b/src/core_io.h
@@ -6,6 +6,7 @@
 #define BITCOIN_CORE_IO_H
 
 #include <amount.h>
+#include <attributes.h>
 
 #include <string>
 #include <vector>
@@ -22,8 +23,8 @@ class UniValue;
 // core_read.cpp
 CScript ParseScript(const std::string& s);
 std::string ScriptToAsmStr(const CScript& script, const bool fAttemptSighashDecode = false);
-bool DecodeHexTx(CMutableTransaction& tx, const std::string& hex_tx, bool try_no_witness = false, bool try_witness = true);
-bool DecodeHexBlk(CBlock&, const std::string& strHexBlk);
+NODISCARD bool DecodeHexTx(CMutableTransaction& tx, const std::string& hex_tx, bool try_no_witness = false, bool try_witness = true);
+NODISCARD bool DecodeHexBlk(CBlock&, const std::string& strHexBlk);
 bool DecodeHexBlockHeader(CBlockHeader&, const std::string& hex_header);
 
 /**
@@ -36,7 +37,7 @@ bool DecodeHexBlockHeader(CBlockHeader&, const std::string& hex_header);
  */
 bool ParseHashStr(const std::string& strHex, uint256& result);
 std::vector<unsigned char> ParseHexUV(const UniValue& v, const std::string& strName);
-bool DecodePSBT(PartiallySignedTransaction& psbt, const std::string& base64_tx, std::string& error);
+NODISCARD bool DecodePSBT(PartiallySignedTransaction& psbt, const std::string& base64_tx, std::string& error);
 int ParseSighashString(const UniValue& sighash);
 
 // core_write.cpp
diff --git a/src/outputtype.h b/src/outputtype.h
index 4c4d93bc8..6c30fd195 100644
--- a/src/outputtype.h
+++ b/src/outputtype.h
@@ -6,6 +6,7 @@
 #ifndef BITCOIN_OUTPUTTYPE_H
 #define BITCOIN_OUTPUTTYPE_H
 
+#include <attributes.h>
 #include <keystore.h>
 #include <script/standard.h>
 
@@ -26,7 +27,7 @@ enum class OutputType {
     CHANGE_AUTO,
 };
 
-bool ParseOutputType(const std::string& str, OutputType& output_type);
+NODISCARD bool ParseOutputType(const std::string& str, OutputType& output_type);
 const std::string& FormatOutputType(OutputType type);
 
 /**
diff --git a/src/rest.cpp b/src/rest.cpp
index 6c7e0384c..4988e6ed2 100644
--- a/src/rest.cpp
+++ b/src/rest.cpp
@@ -3,20 +3,21 @@
 // Distributed under the MIT software license, see the accompanying
 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
 
+#include <attributes.h>
 #include <chain.h>
 #include <chainparams.h>
 #include <core_io.h>
+#include <httpserver.h>
 #include <index/txindex.h>
 #include <primitives/block.h>
 #include <primitives/transaction.h>
-#include <validation.h>
-#include <httpserver.h>
 #include <rpc/blockchain.h>
 #include <rpc/server.h>
 #include <streams.h>
 #include <sync.h>
 #include <txmempool.h>
 #include <util/strencodings.h>
+#include <validation.h>
 #include <version.h>
 
 #include <boost/algorithm/string.hpp>
diff --git a/src/script/descriptor.cpp b/src/script/descriptor.cpp
index 90c4ddcc1..d343972c4 100644
--- a/src/script/descriptor.cpp
+++ b/src/script/descriptor.cpp
@@ -478,7 +478,7 @@ std::vector<Span<const char>> Split(const Span<const char>& sp, char sep)
 }
 
 /** Parse a key path, being passed a split list of elements (the first element is ignored). */
-bool ParseKeyPath(const std::vector<Span<const char>>& split, KeyPath& out)
+NODISCARD bool ParseKeyPath(const std::vector<Span<const char>>& split, KeyPath& out)
 {
     for (size_t i = 1; i < split.size(); ++i) {
         Span<const char> elem = split[i];
diff --git a/src/util/moneystr.h b/src/util/moneystr.h
index 9133f46d5..b8e2812a9 100644
--- a/src/util/moneystr.h
+++ b/src/util/moneystr.h
@@ -9,16 +9,17 @@
 #ifndef BITCOIN_UTIL_MONEYSTR_H
 #define BITCOIN_UTIL_MONEYSTR_H
 
-#include <stdint.h>
-#include <string>
-
 #include <amount.h>
+#include <attributes.h>
+
+#include <cstdint>
+#include <string>
 
 /* Do not use these functions to represent or parse monetary amounts to or from
  * JSON but use AmountFromValue and ValueFromAmount for that.
  */
 std::string FormatMoney(const CAmount& n);
-bool ParseMoney(const std::string& str, CAmount& nRet);
-bool ParseMoney(const char* pszIn, CAmount& nRet);
+NODISCARD bool ParseMoney(const std::string& str, CAmount& nRet);
+NODISCARD bool ParseMoney(const char* pszIn, CAmount& nRet);
 
 #endif // BITCOIN_UTIL_MONEYSTR_H
diff --git a/src/util/strencodings.cpp b/src/util/strencodings.cpp
index 2a2df4333..46146be66 100644
--- a/src/util/strencodings.cpp
+++ b/src/util/strencodings.cpp
@@ -263,7 +263,7 @@ std::string DecodeBase32(const std::string& str)
     return std::string((const char*)vchRet.data(), vchRet.size());
 }
 
-static bool ParsePrechecks(const std::string& str)
+NODISCARD static bool ParsePrechecks(const std::string& str)
 {
     if (str.empty()) // No empty string allowed
         return false;
diff --git a/src/util/strencodings.h b/src/util/strencodings.h
index 87ccf40a1..7d16d7dcf 100644
--- a/src/util/strencodings.h
+++ b/src/util/strencodings.h
@@ -9,7 +9,9 @@
 #ifndef BITCOIN_UTIL_STRENCODINGS_H
 #define BITCOIN_UTIL_STRENCODINGS_H
 
-#include <stdint.h>
+#include <attributes.h>
+
+#include <cstdint>
 #include <string>
 #include <vector>
 
@@ -92,35 +94,35 @@ constexpr inline bool IsSpace(char c) noexcept {
  * @returns true if the entire string could be parsed as valid integer,
  *   false if not the entire string could be parsed or when overflow or underflow occurred.
  */
-bool ParseInt32(const std::string& str, int32_t *out);
+NODISCARD bool ParseInt32(const std::string& str, int32_t *out);
 
 /**
  * Convert string to signed 64-bit integer with strict parse error feedback.
  * @returns true if the entire string could be parsed as valid integer,
  *   false if not the entire string could be parsed or when overflow or underflow occurred.
  */
-bool ParseInt64(const std::string& str, int64_t *out);
+NODISCARD bool ParseInt64(const std::string& str, int64_t *out);
 
 /**
  * Convert decimal string to unsigned 32-bit integer with strict parse error feedback.
  * @returns true if the entire string could be parsed as valid integer,
  *   false if not the entire string could be parsed or when overflow or underflow occurred.
  */
-bool ParseUInt32(const std::string& str, uint32_t *out);
+NODISCARD bool ParseUInt32(const std::string& str, uint32_t *out);
 
 /**
  * Convert decimal string to unsigned 64-bit integer with strict parse error feedback.
  * @returns true if the entire string could be parsed as valid integer,
  *   false if not the entire string could be parsed or when overflow or underflow occurred.
  */
-bool ParseUInt64(const std::string& str, uint64_t *out);
+NODISCARD bool ParseUInt64(const std::string& str, uint64_t *out);
 
 /**
  * Convert string to double with strict parse error feedback.
  * @returns true if the entire string could be parsed as valid double,
  *   false if not the entire string could be parsed or when overflow or underflow occurred.
  */
-bool ParseDouble(const std::string& str, double *out);
+NODISCARD bool ParseDouble(const std::string& str, double *out);
 
 template<typename T>
 std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
@@ -173,7 +175,7 @@ bool TimingResistantEqual(const T& a, const T& b)
  * @returns true on success, false on error.
  * @note The result must be in the range (-10^18,10^18), otherwise an overflow error will trigger.
  */
-bool ParseFixedPoint(const std::string &val, int decimals, int64_t *amount_out);
+NODISCARD bool ParseFixedPoint(const std::string &val, int decimals, int64_t *amount_out);
 
 /** Convert from one power-of-2 number base to another. */
 template<int frombits, int tobits, bool pad, typename O, typename I>
@@ -200,7 +202,7 @@ bool ConvertBits(const O& outfn, I it, I end) {
 }
 
 /** Parse an HD keypaths like "m/7/0'/2000". */
-bool ParseHDKeypath(const std::string& keypath_str, std::vector<uint32_t>& keypath);
+NODISCARD bool ParseHDKeypath(const std::string& keypath_str, std::vector<uint32_t>& keypath);
 
 /**
  * Converts the given character to its lowercase equivalent.
diff --git a/src/util/system.h b/src/util/system.h
index 5634b8dd6..bebb089a2 100644
--- a/src/util/system.h
+++ b/src/util/system.h
@@ -14,6 +14,7 @@
 #include <config/bitcoin-config.h>
 #endif
 
+#include <attributes.h>
 #include <compat.h>
 #include <fs.h>
 #include <logging.h>
@@ -159,7 +160,7 @@ public:
      */
     void SelectConfigNetwork(const std::string& network);
 
-    bool ParseParameters(int argc, const char* const argv[], std::string& error);
+    NODISCARD bool ParseParameters(int argc, const char* const argv[], std::string& error);
     bool ReadConfigFiles(std::string& error, bool ignore_invalid_keys = false);
 
     /**