diff options
Diffstat (limited to 'lib/common/Utils.cpp')
-rw-r--r-- | lib/common/Utils.cpp | 190 |
1 files changed, 102 insertions, 88 deletions
diff --git a/lib/common/Utils.cpp b/lib/common/Utils.cpp index decc80e8..0915f29a 100644 --- a/lib/common/Utils.cpp +++ b/lib/common/Utils.cpp @@ -15,7 +15,7 @@ #include <cstdlib> -#ifdef SHOW_BACKTRACE_ON_EXCEPTION +#ifdef HAVE_EXECINFO_H #include <execinfo.h> #include <stdlib.h> #endif @@ -51,25 +51,40 @@ std::string GetBoxBackupVersion() // Created: 2003/07/31 // // -------------------------------------------------------------------------- -void SplitString(const std::string &String, char SplitOn, std::vector<std::string> &rOutput) +void SplitString(std::string String, char SplitOn, std::vector<std::string> &rOutput) { // Split it up. - std::string::size_type b = 0; - std::string::size_type e = 0; - while(e = String.find_first_of(SplitOn, b), e != String.npos) + std::string::size_type begin = 0, end = 0, pos = 0; + + while(end = String.find_first_of(SplitOn, pos), end != String.npos) { - // Get this string - unsigned int len = e - b; - if(len >= 1) + // Is it preceded by the escape character? + if(end > 0 && String[end - 1] == '\\') + { + // Ignore this one, don't change begin, let the next + // match/fallback consume it instead. But remove the + // backslash from the string, and set pos to the + // current position, which no longer contains a + // separator character. + String.erase(end - 1, 1); + pos = end; + } + else { - rOutput.push_back(String.substr(b, len)); + // Extract the substring and move past it. + unsigned int len = end - begin; + if(len >= 1) + { + rOutput.push_back(String.substr(begin, len)); + } + begin = end + 1; + pos = begin; } - b = e + 1; } // Last string - if(b < String.size()) + if(begin < String.size()) { - rOutput.push_back(String.substr(b)); + rOutput.push_back(String.substr(begin)); } /*#ifndef BOX_RELEASE_BUILD BOX_TRACE("Splitting string '" << String << " on " << (char)SplitOn); @@ -80,71 +95,95 @@ void SplitString(const std::string &String, char SplitOn, std::vector<std::strin #endif*/ } -#ifdef SHOW_BACKTRACE_ON_EXCEPTION +bool StartsWith(const std::string& prefix, const std::string& haystack) +{ + return haystack.size() >= prefix.size() && + haystack.substr(0, prefix.size()) == prefix; +} + +bool EndsWith(const std::string& suffix, const std::string& haystack) +{ + return haystack.size() >= suffix.size() && + haystack.substr(haystack.size() - suffix.size()) == suffix; +} + +std::string RemovePrefix(const std::string& prefix, const std::string& haystack) +{ + if(StartsWith(prefix, haystack)) + { + return haystack.substr(prefix.size()); + } + else + { + return ""; + } +} + +std::string RemoveSuffix(const std::string& suffix, const std::string& haystack) +{ + if(EndsWith(suffix, haystack)) + { + return haystack.substr(0, haystack.size() - suffix.size()); + } + else + { + return ""; + } +} + static std::string demangle(const std::string& mangled_name) { + std::string demangled_name = mangled_name; + #ifdef HAVE_CXXABI_H + char buffer[1024]; int status; + size_t length = sizeof(buffer); -#include "MemLeakFindOff.h" char* result = abi::__cxa_demangle(mangled_name.c_str(), - NULL, NULL, &status); -#include "MemLeakFindOn.h" + buffer, &length, &status); - if (result == NULL) + if (status == 0) { - if (status == 0) - { - BOX_WARNING("Demangle failed but no error: " << - mangled_name); - } - else if (status == -1) - { - BOX_WARNING("Demangle failed with " - "memory allocation error: " << - mangled_name); - } - else if (status == -2) - { - // Probably non-C++ name, don't demangle - /* - BOX_WARNING("Demangle failed with " - "with invalid name: " << - mangled_name); - */ - } - else if (status == -3) - { - BOX_WARNING("Demangle failed with " - "with invalid argument: " << - mangled_name); - } - else - { - BOX_WARNING("Demangle failed with " - "with unknown error " << status << - ": " << mangled_name); - } - - return std::string(mangled_name); + demangled_name = result; + } + else if (status == -1) + { + BOX_WARNING("Demangle failed with " + "memory allocation error: " << + mangled_name); + } + else if (status == -2) + { + // Probably non-C++ name, don't demangle + /* + BOX_WARNING("Demangle failed with " + "with invalid name: " << + mangled_name); + */ + } + else if (status == -3) + { + BOX_WARNING("Demangle failed with " + "with invalid argument: " << + mangled_name); } else { - std::string output = result; -#include "MemLeakFindOff.h" - free(result); -#include "MemLeakFindOn.h" - return output; + BOX_WARNING("Demangle failed with " + "with unknown error " << status << + ": " << mangled_name); } - #else // !HAVE_CXXABI_H - return mangled_name; #endif // HAVE_CXXABI_H + + return demangled_name; } void DumpStackBacktrace() { - void *array[10]; - size_t size = backtrace(array, 10); +#ifdef HAVE_EXECINFO_H + void *array[20]; + size_t size = backtrace(array, 20); BOX_TRACE("Obtained " << size << " stack frames."); for(size_t i = 0; i < size; i++) @@ -179,8 +218,10 @@ void DumpStackBacktrace() BOX_TRACE(output.str()); } +#else // !HAVE_EXECINFO_H + BOX_TRACE("Backtrace support was not compiled in"); +#endif // HAVE_EXECINFO_H } -#endif // SHOW_BACKTRACE_ON_EXCEPTION @@ -340,30 +381,3 @@ std::string FormatUsageLineStart(const std::string& rName, return result.str(); } -std::string BoxGetTemporaryDirectoryName() -{ -#ifdef WIN32 - // http://msdn.microsoft.com/library/default.asp? - // url=/library/en-us/fileio/fs/creating_and_using_a_temporary_file.asp - - DWORD dwRetVal; - char lpPathBuffer[1024]; - DWORD dwBufSize = sizeof(lpPathBuffer); - - // Get the temp path. - dwRetVal = GetTempPath(dwBufSize, // length of the buffer - lpPathBuffer); // buffer for path - if (dwRetVal > dwBufSize) - { - THROW_EXCEPTION(CommonException, TempDirPathTooLong) - } - - return std::string(lpPathBuffer); -#elif defined TEMP_DIRECTORY_NAME - return std::string(TEMP_DIRECTORY_NAME); -#else - #error non-static temporary directory names not supported yet -#endif -} - - |