aboutsummaryrefslogtreecommitdiff
path: root/src/util.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/util.h')
-rw-r--r--src/util.h283
1 files changed, 217 insertions, 66 deletions
diff --git a/src/util.h b/src/util.h
index 08b23a9d38..a4aaf29f91 100644
--- a/src/util.h
+++ b/src/util.h
@@ -1,81 +1,232 @@
-/**********************************************************************
- * Copyright (c) 2013, 2014 Pieter Wuille *
- * Distributed under the MIT software license, see the accompanying *
- * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
- **********************************************************************/
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#ifndef _SECP256K1_UTIL_H_
-#define _SECP256K1_UTIL_H_
+/**
+ * Server/client environment: argument handling, config file parsing,
+ * logging, thread wrappers
+ */
+#ifndef BITCOIN_UTIL_H
+#define BITCOIN_UTIL_H
-#if defined HAVE_CONFIG_H
-#include "libsecp256k1-config.h"
+#if defined(HAVE_CONFIG_H)
+#include "config/bitcoin-config.h"
#endif
-#include <stdlib.h>
+#include "compat.h"
+#include "tinyformat.h"
+#include "utiltime.h"
+
+#include <exception>
+#include <map>
#include <stdint.h>
-#include <stdio.h>
+#include <string>
+#include <vector>
-#ifdef DETERMINISTIC
-#define TEST_FAILURE(msg) do { \
- fprintf(stderr, "%s\n", msg); \
- abort(); \
-} while(0);
-#else
-#define TEST_FAILURE(msg) do { \
- fprintf(stderr, "%s:%d: %s\n", __FILE__, __LINE__, msg); \
- abort(); \
-} while(0)
-#endif
+#include <boost/filesystem/path.hpp>
+#include <boost/thread/exceptions.hpp>
-#ifndef HAVE_BUILTIN_EXPECT
-#define EXPECT(x,c) __builtin_expect((x),(c))
-#else
-#define EXPECT(x,c) (x)
-#endif
+extern std::map<std::string, std::string> mapArgs;
+extern std::map<std::string, std::vector<std::string> > mapMultiArgs;
+extern bool fDebug;
+extern bool fPrintToConsole;
+extern bool fPrintToDebugLog;
+extern bool fServer;
+extern std::string strMiscWarning;
+extern bool fLogTimestamps;
+extern bool fLogIPs;
+extern volatile bool fReopenDebugLog;
-#ifdef DETERMINISTIC
-#define CHECK(cond) do { \
- if (EXPECT(!(cond), 0)) { \
- TEST_FAILURE("test condition failed"); \
- } \
-} while(0)
-#else
-#define CHECK(cond) do { \
- if (EXPECT(!(cond), 0)) { \
- TEST_FAILURE("test condition failed: " #cond); \
- } \
-} while(0)
-#endif
+void SetupEnvironment();
-/* Like assert(), but safe to use on expressions with side effects. */
-#ifndef NDEBUG
-#define DEBUG_CHECK CHECK
-#else
-#define DEBUG_CHECK(cond) do { (void)(cond); } while(0)
-#endif
+/** Return true if log accepts specified category */
+bool LogAcceptCategory(const char* category);
+/** Send a string to the log output */
+int LogPrintStr(const std::string &str);
-/* Like DEBUG_CHECK(), but when VERIFY is defined instead of NDEBUG not defined. */
-#ifdef VERIFY
-#define VERIFY_CHECK CHECK
-#else
-#define VERIFY_CHECK(cond) do { (void)(cond); } while(0)
+#define LogPrintf(...) LogPrint(NULL, __VA_ARGS__)
+
+/**
+ * When we switch to C++11, this can be switched to variadic templates instead
+ * of this macro-based construction (see tinyformat.h).
+ */
+#define MAKE_ERROR_AND_LOG_FUNC(n) \
+ /** Print to debug.log if -debug=category switch is given OR category is NULL. */ \
+ template<TINYFORMAT_ARGTYPES(n)> \
+ static inline int LogPrint(const char* category, const char* format, TINYFORMAT_VARARGS(n)) \
+ { \
+ if(!LogAcceptCategory(category)) return 0; \
+ return LogPrintStr(tfm::format(format, TINYFORMAT_PASSARGS(n))); \
+ } \
+ /** Log error and return false */ \
+ template<TINYFORMAT_ARGTYPES(n)> \
+ static inline bool error(const char* format, TINYFORMAT_VARARGS(n)) \
+ { \
+ LogPrintStr("ERROR: " + tfm::format(format, TINYFORMAT_PASSARGS(n)) + "\n"); \
+ return false; \
+ }
+
+TINYFORMAT_FOREACH_ARGNUM(MAKE_ERROR_AND_LOG_FUNC)
+
+/**
+ * Zero-arg versions of logging and error, these are not covered by
+ * TINYFORMAT_FOREACH_ARGNUM
+ */
+static inline int LogPrint(const char* category, const char* format)
+{
+ if(!LogAcceptCategory(category)) return 0;
+ return LogPrintStr(format);
+}
+static inline bool error(const char* format)
+{
+ LogPrintStr(std::string("ERROR: ") + format + "\n");
+ return false;
+}
+
+void PrintExceptionContinue(std::exception* pex, const char* pszThread);
+void ParseParameters(int argc, const char*const argv[]);
+void FileCommit(FILE *fileout);
+bool TruncateFile(FILE *file, unsigned int length);
+int RaiseFileDescriptorLimit(int nMinFD);
+void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length);
+bool RenameOver(boost::filesystem::path src, boost::filesystem::path dest);
+bool TryCreateDirectory(const boost::filesystem::path& p);
+boost::filesystem::path GetDefaultDataDir();
+const boost::filesystem::path &GetDataDir(bool fNetSpecific = true);
+boost::filesystem::path GetConfigFile();
+#ifndef WIN32
+boost::filesystem::path GetPidFile();
+void CreatePidFile(const boost::filesystem::path &path, pid_t pid);
+#endif
+void ReadConfigFile(std::map<std::string, std::string>& mapSettingsRet, std::map<std::string, std::vector<std::string> >& mapMultiSettingsRet);
+#ifdef WIN32
+boost::filesystem::path GetSpecialFolderPath(int nFolder, bool fCreate = true);
#endif
+boost::filesystem::path GetTempPath();
+void ShrinkDebugFile();
+void runCommand(std::string strCommand);
-/* Macro for restrict, when available and not in a VERIFY build. */
-#if defined(SECP256K1_BUILD) && defined(VERIFY)
-# define SECP256K1_RESTRICT
+inline bool IsSwitchChar(char c)
+{
+#ifdef WIN32
+ return c == '-' || c == '/';
#else
-# if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) )
-# if SECP256K1_GNUC_PREREQ(3,0)
-# define SECP256K1_RESTRICT __restrict__
-# elif (defined(_MSC_VER) && _MSC_VER >= 1400)
-# define SECP256K1_RESTRICT __restrict
-# else
-# define SECP256K1_RESTRICT
-# endif
-# else
-# define SECP256K1_RESTRICT restrict
-# endif
+ return c == '-';
#endif
+}
-#endif
+/**
+ * Return string argument or default value
+ *
+ * @param strArg Argument to get (e.g. "-foo")
+ * @param default (e.g. "1")
+ * @return command-line argument or default value
+ */
+std::string GetArg(const std::string& strArg, const std::string& strDefault);
+
+/**
+ * Return integer argument or default value
+ *
+ * @param strArg Argument to get (e.g. "-foo")
+ * @param default (e.g. 1)
+ * @return command-line argument (0 if invalid number) or default value
+ */
+int64_t GetArg(const std::string& strArg, int64_t nDefault);
+
+/**
+ * Return boolean argument or default value
+ *
+ * @param strArg Argument to get (e.g. "-foo")
+ * @param default (true or false)
+ * @return command-line argument or default value
+ */
+bool GetBoolArg(const std::string& strArg, bool fDefault);
+
+/**
+ * Set an argument if it doesn't already have a value
+ *
+ * @param strArg Argument to set (e.g. "-foo")
+ * @param strValue Value (e.g. "1")
+ * @return true if argument gets set, false if it already had a value
+ */
+bool SoftSetArg(const std::string& strArg, const std::string& strValue);
+
+/**
+ * Set a boolean argument if it doesn't already have a value
+ *
+ * @param strArg Argument to set (e.g. "-foo")
+ * @param fValue Value (e.g. false)
+ * @return true if argument gets set, false if it already had a value
+ */
+bool SoftSetBoolArg(const std::string& strArg, bool fValue);
+
+void SetThreadPriority(int nPriority);
+void RenameThread(const char* name);
+
+/**
+ * Standard wrapper for do-something-forever thread functions.
+ * "Forever" really means until the thread is interrupted.
+ * Use it like:
+ * new boost::thread(boost::bind(&LoopForever<void (*)()>, "dumpaddr", &DumpAddresses, 900000));
+ * or maybe:
+ * boost::function<void()> f = boost::bind(&FunctionWithArg, argument);
+ * threadGroup.create_thread(boost::bind(&LoopForever<boost::function<void()> >, "nothing", f, milliseconds));
+ */
+template <typename Callable> void LoopForever(const char* name, Callable func, int64_t msecs)
+{
+ std::string s = strprintf("bitcoin-%s", name);
+ RenameThread(s.c_str());
+ LogPrintf("%s thread start\n", name);
+ try
+ {
+ while (1)
+ {
+ MilliSleep(msecs);
+ func();
+ }
+ }
+ catch (boost::thread_interrupted)
+ {
+ LogPrintf("%s thread stop\n", name);
+ throw;
+ }
+ catch (std::exception& e) {
+ PrintExceptionContinue(&e, name);
+ throw;
+ }
+ catch (...) {
+ PrintExceptionContinue(NULL, name);
+ throw;
+ }
+}
+
+/**
+ * .. and a wrapper that just calls func once
+ */
+template <typename Callable> void TraceThread(const char* name, Callable func)
+{
+ std::string s = strprintf("bitcoin-%s", name);
+ RenameThread(s.c_str());
+ try
+ {
+ LogPrintf("%s thread start\n", name);
+ func();
+ LogPrintf("%s thread exit\n", name);
+ }
+ catch (boost::thread_interrupted)
+ {
+ LogPrintf("%s thread interrupt\n", name);
+ throw;
+ }
+ catch (std::exception& e) {
+ PrintExceptionContinue(&e, name);
+ throw;
+ }
+ catch (...) {
+ PrintExceptionContinue(NULL, name);
+ throw;
+ }
+}
+
+#endif // BITCOIN_UTIL_H