]>
Commit | Line | Data |
---|---|---|
1f2e0df8 | 1 | // Copyright (c) 2009-2010 Satoshi Nakamoto |
f914f1a7 | 2 | // Copyright (c) 2009-2014 The Bitcoin Core developers |
c63a73d1 | 3 | // Distributed under the MIT software license, see the accompanying |
3a25a2b9 | 4 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. |
51ed9ec9 | 5 | |
ad49c256 WL |
6 | /** |
7 | * Server/client environment: argument handling, config file parsing, | |
8 | * logging, thread wrappers | |
9 | */ | |
1f2e0df8 WL |
10 | #ifndef BITCOIN_UTIL_H |
11 | #define BITCOIN_UTIL_H | |
12 | ||
51ed9ec9 | 13 | #if defined(HAVE_CONFIG_H) |
f3967bcc | 14 | #include "config/bitcoin-config.h" |
51ed9ec9 BD |
15 | #endif |
16 | ||
17 | #include "compat.h" | |
b77dfdc9 | 18 | #include "tinyformat.h" |
611116d4 | 19 | #include "utiltime.h" |
1f2e0df8 | 20 | |
51ed9ec9 | 21 | #include <exception> |
51ed9ec9 | 22 | #include <map> |
51ed9ec9 BD |
23 | #include <stdint.h> |
24 | #include <string> | |
51ed9ec9 | 25 | #include <vector> |
65ec9eab | 26 | |
ee12c3d6 | 27 | #include <boost/filesystem/path.hpp> |
b74dcb3b | 28 | #include <boost/signals2/signal.hpp> |
ad49c256 | 29 | #include <boost/thread/exceptions.hpp> |
1f2e0df8 | 30 | |
b74dcb3b JT |
31 | /** Signals for translation. */ |
32 | class CTranslationInterface | |
33 | { | |
34 | public: | |
35 | /** Translate a message to the native language of the user. */ | |
36 | boost::signals2::signal<std::string (const char* psz)> Translate; | |
37 | }; | |
38 | ||
1f2e0df8 WL |
39 | extern std::map<std::string, std::string> mapArgs; |
40 | extern std::map<std::string, std::vector<std::string> > mapMultiArgs; | |
41 | extern bool fDebug; | |
42 | extern bool fPrintToConsole; | |
9e9056cd | 43 | extern bool fPrintToDebugLog; |
1f2e0df8 | 44 | extern bool fServer; |
1f2e0df8 | 45 | extern std::string strMiscWarning; |
1f2e0df8 | 46 | extern bool fLogTimestamps; |
2e36866f | 47 | extern bool fLogIPs; |
ee337423 | 48 | extern volatile bool fReopenDebugLog; |
b74dcb3b JT |
49 | extern CTranslationInterface translationInterface; |
50 | ||
51 | /** | |
52 | * Translation function: Call Translate signal on UI interface, which returns a boost::optional result. | |
53 | * If no translation slot is registered, nothing is returned, and simply return the input. | |
54 | */ | |
55 | inline std::string _(const char* psz) | |
56 | { | |
57 | boost::optional<std::string> rv = translationInterface.Translate(psz); | |
58 | return rv ? (*rv) : psz; | |
59 | } | |
1f2e0df8 | 60 | |
5248ff40 | 61 | void SetupEnvironment(); |
e51321fb | 62 | |
c63a73d1 | 63 | /** Return true if log accepts specified category */ |
b77dfdc9 | 64 | bool LogAcceptCategory(const char* category); |
c63a73d1 | 65 | /** Send a string to the log output */ |
b77dfdc9 WL |
66 | int LogPrintStr(const std::string &str); |
67 | ||
881a85a2 | 68 | #define LogPrintf(...) LogPrint(NULL, __VA_ARGS__) |
52d3a481 | 69 | |
c63a73d1 MF |
70 | /** |
71 | * When we switch to C++11, this can be switched to variadic templates instead | |
b77dfdc9 | 72 | * of this macro-based construction (see tinyformat.h). |
b0a90fbb | 73 | */ |
b77dfdc9 | 74 | #define MAKE_ERROR_AND_LOG_FUNC(n) \ |
c63a73d1 | 75 | /** Print to debug.log if -debug=category switch is given OR category is NULL. */ \ |
b77dfdc9 WL |
76 | template<TINYFORMAT_ARGTYPES(n)> \ |
77 | static inline int LogPrint(const char* category, const char* format, TINYFORMAT_VARARGS(n)) \ | |
78 | { \ | |
79 | if(!LogAcceptCategory(category)) return 0; \ | |
80 | return LogPrintStr(tfm::format(format, TINYFORMAT_PASSARGS(n))); \ | |
81 | } \ | |
c63a73d1 | 82 | /** Log error and return false */ \ |
b77dfdc9 WL |
83 | template<TINYFORMAT_ARGTYPES(n)> \ |
84 | static inline bool error(const char* format, TINYFORMAT_VARARGS(n)) \ | |
85 | { \ | |
2383e488 | 86 | LogPrintStr("ERROR: " + tfm::format(format, TINYFORMAT_PASSARGS(n)) + "\n"); \ |
b77dfdc9 WL |
87 | return false; \ |
88 | } | |
89 | ||
90 | TINYFORMAT_FOREACH_ARGNUM(MAKE_ERROR_AND_LOG_FUNC) | |
91 | ||
c63a73d1 MF |
92 | /** |
93 | * Zero-arg versions of logging and error, these are not covered by | |
b77dfdc9 WL |
94 | * TINYFORMAT_FOREACH_ARGNUM |
95 | */ | |
96 | static inline int LogPrint(const char* category, const char* format) | |
97 | { | |
98 | if(!LogAcceptCategory(category)) return 0; | |
99 | return LogPrintStr(format); | |
100 | } | |
101 | static inline bool error(const char* format) | |
102 | { | |
2383e488 | 103 | LogPrintStr(std::string("ERROR: ") + format + "\n"); |
b77dfdc9 WL |
104 | return false; |
105 | } | |
b0a90fbb | 106 | |
4f1c3798 SB |
107 | const boost::filesystem::path &ZC_GetParamsDir(); |
108 | ||
27df4123 | 109 | void PrintExceptionContinue(const std::exception *pex, const char* pszThread); |
3ae07355 | 110 | void ParseParameters(int argc, const char*const argv[]); |
768e5d52 | 111 | void FileCommit(FILE *fileout); |
1eb57879 | 112 | bool TruncateFile(FILE *file, unsigned int length); |
ba29a559 | 113 | int RaiseFileDescriptorLimit(int nMinFD); |
bba89aa8 | 114 | void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length); |
768e5d52 | 115 | bool RenameOver(boost::filesystem::path src, boost::filesystem::path dest); |
2b7709dc | 116 | bool TryCreateDirectory(const boost::filesystem::path& p); |
ee12c3d6 PW |
117 | boost::filesystem::path GetDefaultDataDir(); |
118 | const boost::filesystem::path &GetDataDir(bool fNetSpecific = true); | |
51598b26 | 119 | void ClearDatadirCache(); |
ee12c3d6 | 120 | boost::filesystem::path GetConfigFile(); |
a034c7eb | 121 | #ifndef WIN32 |
d6712db3 | 122 | boost::filesystem::path GetPidFile(); |
ee12c3d6 | 123 | void CreatePidFile(const boost::filesystem::path &path, pid_t pid); |
a034c7eb | 124 | #endif |
f4203de3 | 125 | void ReadConfigFile(std::map<std::string, std::string>& mapSettingsRet, std::map<std::string, std::vector<std::string> >& mapMultiSettingsRet); |
3e468840 PK |
126 | #ifdef WIN32 |
127 | boost::filesystem::path GetSpecialFolderPath(int nFolder, bool fCreate = true); | |
128 | #endif | |
597fa4cd | 129 | boost::filesystem::path GetTempPath(); |
1f2e0df8 | 130 | void ShrinkDebugFile(); |
429039d4 | 131 | void runCommand(std::string strCommand); |
1f2e0df8 | 132 | |
1f2e0df8 WL |
133 | inline bool IsSwitchChar(char c) |
134 | { | |
6853e627 | 135 | #ifdef WIN32 |
1f2e0df8 WL |
136 | return c == '-' || c == '/'; |
137 | #else | |
138 | return c == '-'; | |
139 | #endif | |
140 | } | |
141 | ||
3ae07355 GA |
142 | /** |
143 | * Return string argument or default value | |
144 | * | |
145 | * @param strArg Argument to get (e.g. "-foo") | |
146 | * @param default (e.g. "1") | |
147 | * @return command-line argument or default value | |
148 | */ | |
149 | std::string GetArg(const std::string& strArg, const std::string& strDefault); | |
1f2e0df8 | 150 | |
3ae07355 GA |
151 | /** |
152 | * Return integer argument or default value | |
153 | * | |
154 | * @param strArg Argument to get (e.g. "-foo") | |
155 | * @param default (e.g. 1) | |
156 | * @return command-line argument (0 if invalid number) or default value | |
157 | */ | |
51ed9ec9 | 158 | int64_t GetArg(const std::string& strArg, int64_t nDefault); |
1f2e0df8 | 159 | |
3ae07355 GA |
160 | /** |
161 | * Return boolean argument or default value | |
162 | * | |
163 | * @param strArg Argument to get (e.g. "-foo") | |
164 | * @param default (true or false) | |
165 | * @return command-line argument or default value | |
166 | */ | |
3260b4c0 | 167 | bool GetBoolArg(const std::string& strArg, bool fDefault); |
1f2e0df8 | 168 | |
0fcf91ea GA |
169 | /** |
170 | * Set an argument if it doesn't already have a value | |
171 | * | |
172 | * @param strArg Argument to set (e.g. "-foo") | |
173 | * @param strValue Value (e.g. "1") | |
174 | * @return true if argument gets set, false if it already had a value | |
175 | */ | |
176 | bool SoftSetArg(const std::string& strArg, const std::string& strValue); | |
177 | ||
178 | /** | |
179 | * Set a boolean argument if it doesn't already have a value | |
180 | * | |
181 | * @param strArg Argument to set (e.g. "-foo") | |
182 | * @param fValue Value (e.g. false) | |
183 | * @return true if argument gets set, false if it already had a value | |
184 | */ | |
7bf8b7c2 | 185 | bool SoftSetBoolArg(const std::string& strArg, bool fValue); |
1f2e0df8 | 186 | |
1fdb9fa3 LV |
187 | /** |
188 | * Format a string to be used as group of options in help messages | |
189 | * | |
190 | * @param message Group name (e.g. "RPC server options:") | |
191 | * @return the formatted string | |
192 | */ | |
193 | std::string HelpMessageGroup(const std::string& message); | |
194 | ||
195 | /** | |
196 | * Format a string to be used as option description in help messages | |
197 | * | |
198 | * @param option Option message (e.g. "-rpcuser=<user>") | |
199 | * @param message Option description (e.g. "Username for JSON-RPC connections") | |
200 | * @return the formatted string | |
201 | */ | |
202 | std::string HelpMessageOpt(const std::string& option, const std::string& message); | |
203 | ||
610a8c07 | 204 | void SetThreadPriority(int nPriority); |
96931d6f | 205 | void RenameThread(const char* name); |
1f2e0df8 | 206 | |
c63a73d1 MF |
207 | /** |
208 | * .. and a wrapper that just calls func once | |
209 | */ | |
72f14d26 GA |
210 | template <typename Callable> void TraceThread(const char* name, Callable func) |
211 | { | |
212 | std::string s = strprintf("bitcoin-%s", name); | |
213 | RenameThread(s.c_str()); | |
214 | try | |
215 | { | |
881a85a2 | 216 | LogPrintf("%s thread start\n", name); |
72f14d26 | 217 | func(); |
881a85a2 | 218 | LogPrintf("%s thread exit\n", name); |
72f14d26 | 219 | } |
27df4123 | 220 | catch (const boost::thread_interrupted&) |
72f14d26 | 221 | { |
881a85a2 | 222 | LogPrintf("%s thread interrupt\n", name); |
72f14d26 GA |
223 | throw; |
224 | } | |
27df4123 | 225 | catch (const std::exception& e) { |
44235713 WL |
226 | PrintExceptionContinue(&e, name); |
227 | throw; | |
72f14d26 GA |
228 | } |
229 | catch (...) { | |
44235713 WL |
230 | PrintExceptionContinue(NULL, name); |
231 | throw; | |
72f14d26 GA |
232 | } |
233 | } | |
234 | ||
093303a8 | 235 | #endif // BITCOIN_UTIL_H |