summaryrefslogtreecommitdiff
path: root/lib/common/Utils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/common/Utils.cpp')
-rw-r--r--lib/common/Utils.cpp190
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
-}
-
-