X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Futil.cpp;h=5ba650420b8837149cedc40b5d123c4be451b753;hb=3374c3ef094b328e6c6957fdaf5a9abff0c53a33;hp=a45ce33a1c0caacef41af3681fb29546113bc57b;hpb=387c8e3c5b1e00c6e9e57bfb069a6bfed09411d9;p=novacoin.git diff --git a/src/util.cpp b/src/util.cpp index a45ce33..5ba6504 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -1,10 +1,21 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2011 The Bitcoin developers +// Copyright (c) 2009-2012 The Bitcoin developers // Distributed under the MIT/X11 software license, see the accompanying // file license.txt or http://www.opensource.org/licenses/mit-license.php. #include "headers.h" #include "strlcpy.h" #include + +// Work around clang compilation problem in Boost 1.46: +// /usr/include/boost/program_options/detail/config_file.hpp:163:17: error: call to function 'to_internal' that is neither visible in the template definition nor found by argument-dependent lookup +// See also: http://stackoverflow.com/questions/10020179/compilation-fail-in-boost-librairies-program-options +// http://clang.debian.net/status.php?version=3.0&key=CANNOT_FIND_FUNCTION +namespace boost { + namespace program_options { + std::string to_internal(const std::string&); + } +} + #include #include #include @@ -400,26 +411,36 @@ bool ParseMoney(const char* pszIn, int64& nRet) } -vector ParseHex(const char* psz) +static char phexdigit[256] = +{ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + 0,1,2,3,4,5,6,7,8,9,-1,-1,-1,-1,-1,-1, + -1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1 + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, }; + +bool IsHex(const string& str) { - static char phexdigit[256] = - { -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - 0,1,2,3,4,5,6,7,8,9,-1,-1,-1,-1,-1,-1, - -1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1 - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, }; + BOOST_FOREACH(unsigned char c, str) + { + if (phexdigit[c] < 0) + return false; + } + return (str.size() > 0) && (str.size()%2 == 0); +} +vector ParseHex(const char* psz) +{ // convert hex dump to vector vector vch; loop @@ -444,7 +465,22 @@ vector ParseHex(const string& str) return ParseHex(str.c_str()); } -void ParseParameters(int argc, char* argv[]) +static void InterpretNegativeSetting(string name, map& mapSettingsRet) +{ + // interpret -nofoo as -foo=0 (and -nofoo=0 as -foo=1) as long as -foo not set + if (name.find("-no") == 0) + { + std::string positive("-"); + positive.append(name.begin()+3, name.end()); + if (mapSettingsRet.count(positive) == 0) + { + bool value = !GetBoolArg(name); + mapSettingsRet[positive] = (value ? "1" : "0"); + } + } +} + +void ParseParameters(int argc, const char*const argv[]) { mapArgs.clear(); mapMultiArgs.clear(); @@ -465,11 +501,72 @@ void ParseParameters(int argc, char* argv[]) #endif if (psz[0] != '-') break; + mapArgs[psz] = pszValue; mapMultiArgs[psz].push_back(pszValue); } + + // New 0.6 features: + BOOST_FOREACH(const PAIRTYPE(string,string)& entry, mapArgs) + { + string name = entry.first; + + // interpret --foo as -foo (as long as both are not set) + if (name.find("--") == 0) + { + std::string singleDash(name.begin()+1, name.end()); + if (mapArgs.count(singleDash) == 0) + mapArgs[singleDash] = entry.second; + name = singleDash; + } + + // interpret -nofoo as -foo=0 (and -nofoo=0 as -foo=1) as long as -foo not set + InterpretNegativeSetting(name, mapArgs); + } +} + +std::string GetArg(const std::string& strArg, const std::string& strDefault) +{ + if (mapArgs.count(strArg)) + return mapArgs[strArg]; + return strDefault; +} + +int64 GetArg(const std::string& strArg, int64 nDefault) +{ + if (mapArgs.count(strArg)) + return atoi64(mapArgs[strArg]); + return nDefault; } +bool GetBoolArg(const std::string& strArg, bool fDefault) +{ + if (mapArgs.count(strArg)) + { + if (mapArgs[strArg].empty()) + return true; + return (atoi(mapArgs[strArg]) != 0); + } + return fDefault; +} + +bool SoftSetArg(const std::string& strArg, const std::string& strValue) +{ + if (mapArgs.count(strArg)) + return false; + mapArgs[strArg] = strValue; + return true; +} + +bool SoftSetBoolArg(const std::string& strArg, bool fValue) +{ + if (fValue) + return SoftSetArg(strArg, std::string("1")); + else + return SoftSetArg(strArg, std::string("0")); +} + + string EncodeBase64(const unsigned char* pch, size_t len) { static const char *pbase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; @@ -551,7 +648,7 @@ vector DecodeBase64(const char* p, bool* pfInvalid) while (1) { - int dec = decode64_table[*p]; + int dec = decode64_table[(unsigned char)*p]; if (dec == -1) break; p++; switch (mode) @@ -591,12 +688,12 @@ vector DecodeBase64(const char* p, bool* pfInvalid) break; case 2: // 4n+2 base64 characters processed: require '==' - if (left || p[0] != '=' || p[1] != '=' || decode64_table[p[2]] != -1) + if (left || p[0] != '=' || p[1] != '=' || decode64_table[(unsigned char)p[2]] != -1) *pfInvalid = true; break; case 3: // 4n+3 base64 characters processed: require '=' - if (left || p[0] != '=' || decode64_table[p[1]] != -1) + if (left || p[0] != '=' || decode64_table[(unsigned char)p[1]] != -1) *pfInvalid = true; break; } @@ -681,17 +778,6 @@ void PrintException(std::exception* pex, const char* pszThread) throw; } -void ThreadOneMessageBox(string strMessage) -{ - // Skip message boxes if one is already open - static bool fMessageBoxOpen; - if (fMessageBoxOpen) - return; - fMessageBoxOpen = true; - ThreadSafeMessageBox(strMessage, "Bitcoin", wxOK | wxICON_EXCLAMATION); - fMessageBoxOpen = false; -} - void PrintExceptionContinue(std::exception* pex, const char* pszThread) { char pszMessage[10000]; @@ -701,46 +787,23 @@ void PrintExceptionContinue(std::exception* pex, const char* pszThread) strMiscWarning = pszMessage; } - - - - - - - #ifdef WIN32 -typedef WINSHELLAPI BOOL (WINAPI *PSHGETSPECIALFOLDERPATHA)(HWND hwndOwner, LPSTR lpszPath, int nFolder, BOOL fCreate); - string MyGetSpecialFolderPath(int nFolder, bool fCreate) { - char pszPath[MAX_PATH+100] = ""; - - // SHGetSpecialFolderPath isn't always available on old Windows versions - HMODULE hShell32 = LoadLibraryA("shell32.dll"); - if (hShell32) + char pszPath[MAX_PATH] = ""; + if(SHGetSpecialFolderPathA(NULL, pszPath, nFolder, fCreate)) { - PSHGETSPECIALFOLDERPATHA pSHGetSpecialFolderPath = - (PSHGETSPECIALFOLDERPATHA)GetProcAddress(hShell32, "SHGetSpecialFolderPathA"); - if (pSHGetSpecialFolderPath) - (*pSHGetSpecialFolderPath)(NULL, pszPath, nFolder, fCreate); - FreeModule(hShell32); + return pszPath; } - - // Backup option - if (pszPath[0] == '\0') + else if (nFolder == CSIDL_STARTUP) { - if (nFolder == CSIDL_STARTUP) - { - strcpy(pszPath, getenv("USERPROFILE")); - strcat(pszPath, "\\Start Menu\\Programs\\Startup"); - } - else if (nFolder == CSIDL_APPDATA) - { - strcpy(pszPath, getenv("APPDATA")); - } + return string(getenv("USERPROFILE")) + "\\Start Menu\\Programs\\Startup"; } - - return pszPath; + else if (nFolder == CSIDL_APPDATA) + { + return getenv("APPDATA"); + } + return ""; } #endif @@ -822,15 +885,28 @@ string GetConfigFile() return pathConfig.string(); } -void ReadConfigFile(map& mapSettingsRet, +bool ReadConfigFile(map& mapSettingsRet, map >& mapMultiSettingsRet) { namespace fs = boost::filesystem; namespace pod = boost::program_options::detail; + if (mapSettingsRet.count("-datadir")) + { + if (fs::is_directory(fs::system_complete(mapSettingsRet["-datadir"]))) + { + fs::path pathDataDir = fs::system_complete(mapSettingsRet["-datadir"]); + strlcpy(pszSetDataDir, pathDataDir.string().c_str(), sizeof(pszSetDataDir)); + } + else + { + return false; + } + } + fs::ifstream streamConfig(GetConfigFile()); if (!streamConfig.good()) - return; + return true; // No bitcoin.conf file is OK set setOptions; setOptions.insert("*"); @@ -840,9 +916,14 @@ void ReadConfigFile(map& mapSettingsRet, // Don't overwrite existing settings so command line settings override bitcoin.conf string strKey = string("-") + it->string_key; if (mapSettingsRet.count(strKey) == 0) + { mapSettingsRet[strKey] = it->value[0]; + // interpret nofoo=1 as foo=0 (and nofoo=0 as foo=1) as long as foo not set) + InterpretNegativeSetting(strKey, mapSettingsRet); + } mapMultiSettingsRet[strKey].push_back(it->value[0]); } + return true; } string GetPidFile() @@ -931,12 +1012,12 @@ int64 GetAdjustedTime() return GetTime() + nTimeOffset; } -void AddTimeData(unsigned int ip, int64 nTime) +void AddTimeData(const CNetAddr& ip, int64 nTime) { int64 nOffsetSample = nTime - GetTime(); // Ignore duplicates - static set setKnown; + static set setKnown; if (!setKnown.insert(ip).second) return; @@ -991,7 +1072,6 @@ void AddTimeData(unsigned int ip, int64 nTime) - string FormatVersion(int nVersion) { if (nVersion%100 == 0) @@ -1127,7 +1207,18 @@ static void pop_lock() void CCriticalSection::Enter(const char* pszName, const char* pszFile, int nLine) { push_lock(this, CLockLocation(pszName, pszFile, nLine)); +#ifdef DEBUG_LOCKCONTENTION + bool result = mutex.try_lock(); + if (!result) + { + printf("LOCKCONTENTION: %s\n", pszName); + printf("Locker: %s:%d\n", pszFile, nLine); + mutex.lock(); + printf("Locked\n"); + } +#else mutex.lock(); +#endif } void CCriticalSection::Leave() { @@ -1144,9 +1235,19 @@ bool CCriticalSection::TryEnter(const char* pszName, const char* pszFile, int nL #else -void CCriticalSection::Enter(const char*, const char*, int) +void CCriticalSection::Enter(const char* pszName, const char* pszFile, int nLine) { +#ifdef DEBUG_LOCKCONTENTION + bool result = mutex.try_lock(); + if (!result) + { + printf("LOCKCONTENTION: %s\n", pszName); + printf("Locker: %s:%d\n", pszFile, nLine); + mutex.lock(); + } +#else mutex.lock(); +#endif } void CCriticalSection::Leave() @@ -1161,3 +1262,4 @@ bool CCriticalSection::TryEnter(const char*, const char*, int) } #endif /* DEBUG_LOCKORDER */ +