X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Futil.cpp;h=4f34ab6163d6210018ce8eeebd2308643b39bddb;hb=7cfbe1fee465e82ddbdc8ed17dfcce791bd765f5;hp=ac7bacb7f5e455f9d611b9280807c064be89b056;hpb=67a42f929b1434f647c63922fd02dc2b93b28060;p=novacoin.git diff --git a/src/util.cpp b/src/util.cpp index ac7bacb..4f34ab6 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -1,5 +1,5 @@ // 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" @@ -265,7 +265,7 @@ int my_snprintf(char* buffer, size_t limit, const char* format, ...) return ret; } -string strprintf(const std::string &format, ...) +string real_strprintf(const std::string &format, int dummy, ...) { char buffer[50000]; char* p = buffer; @@ -274,7 +274,7 @@ string strprintf(const std::string &format, ...) loop { va_list arg_ptr; - va_start(arg_ptr, format); + va_start(arg_ptr, dummy); ret = _vsnprintf(p, limit, format.c_str(), arg_ptr); va_end(arg_ptr); if (ret >= 0 && ret < limit) @@ -292,13 +292,13 @@ string strprintf(const std::string &format, ...) return str; } -bool error(const std::string &format, ...) +bool error(const char *format, ...) { char buffer[50000]; int limit = sizeof(buffer); va_list arg_ptr; va_start(arg_ptr, format); - int ret = _vsnprintf(buffer, limit, format.c_str(), arg_ptr); + int ret = _vsnprintf(buffer, limit, format, arg_ptr); va_end(arg_ptr); if (ret < 0 || ret >= limit) { @@ -400,26 +400,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 +454,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,9 +490,53 @@ 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) @@ -478,7 +547,7 @@ bool SoftSetArg(const std::string& strArg, const std::string& strValue) return true; } -bool SoftSetArg(const std::string& strArg, bool fValue) +bool SoftSetBoolArg(const std::string& strArg, bool fValue) { if (fValue) return SoftSetArg(strArg, std::string("1")); @@ -698,17 +767,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]; @@ -718,46 +776,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 @@ -839,15 +874,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("*"); @@ -857,9 +905,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() @@ -988,7 +1041,7 @@ void AddTimeData(const CNetAddr& ip, int64 nTime) string strMessage = _("Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly."); strMiscWarning = strMessage; printf("*** %s\n", strMessage.c_str()); - boost::thread(boost::bind(ThreadSafeMessageBox, strMessage+" ", string("Bitcoin"), wxOK | wxICON_EXCLAMATION, (wxWindow*)NULL, -1, -1)); + ThreadSafeMessageBox(strMessage+" ", string("Bitcoin"), wxOK | wxICON_EXCLAMATION); } } } @@ -1143,7 +1196,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() { @@ -1160,9 +1224,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()