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.cpp179
1 files changed, 162 insertions, 17 deletions
diff --git a/lib/common/Utils.cpp b/lib/common/Utils.cpp
index 83a12ccf..f45ed26b 100644
--- a/lib/common/Utils.cpp
+++ b/lib/common/Utils.cpp
@@ -13,11 +13,17 @@
#include <sys/stat.h>
#include <errno.h>
+#include <cstdlib>
+
#ifdef SHOW_BACKTRACE_ON_EXCEPTION
#include <execinfo.h>
#include <stdlib.h>
#endif
+#ifdef HAVE_CXXABI_H
+ #include <cxxabi.h>
+#endif
+
#include "Utils.h"
#include "CommonException.h"
#include "Logging.h"
@@ -52,11 +58,11 @@ void SplitString(const std::string &String, char SplitOn, std::vector<std::strin
{
rOutput.push_back(String.substr(b));
}
-/*#ifndef NDEBUG
- TRACE2("Splitting string '%s' on %c\n", String.c_str(), SplitOn);
+/*#ifndef BOX_RELEASE_BUILD
+ BOX_TRACE("Splitting string '" << String << " on " << (char)SplitOn);
for(unsigned int l = 0; l < rOutput.size(); ++l)
{
- TRACE2("%d = '%s'\n", l, rOutput[l].c_str());
+ BOX_TRACE(l << " = '" << rOutput[l] << "'");
}
#endif*/
}
@@ -64,23 +70,83 @@ void SplitString(const std::string &String, char SplitOn, std::vector<std::strin
#ifdef SHOW_BACKTRACE_ON_EXCEPTION
void DumpStackBacktrace()
{
- void *array[10];
- size_t size;
- char **strings;
- size_t i;
-
- size = backtrace (array, 10);
- strings = backtrace_symbols (array, size);
+ void *array[10];
+ size_t size = backtrace (array, 10);
+ char **strings = backtrace_symbols (array, size);
BOX_TRACE("Obtained " << size << " stack frames.");
- for(i = 0; i < size; i++)
+ for(size_t i = 0; i < size; i++)
{
- BOX_TRACE(strings[i]);
+ // Demangling code copied from
+ // cctbx_sources/boost_adaptbx/meta_ext.cpp, BSD license
+
+ std::string mangled_frame = strings[i];
+ std::string output_frame = strings[i]; // default
+
+ #ifdef HAVE_CXXABI_H
+ int start = mangled_frame.find('(');
+ int end = mangled_frame.find('+', start);
+ std::string mangled_func = mangled_frame.substr(start + 1,
+ end - start - 1);
+
+ int status;
+
+#include "MemLeakFindOff.h"
+ char* result = abi::__cxa_demangle(mangled_func.c_str(),
+ NULL, NULL, &status);
+#include "MemLeakFindOn.h"
+
+ if (result == NULL)
+ {
+ if (status == 0)
+ {
+ BOX_WARNING("Demangle failed but no error: " <<
+ mangled_func);
+ }
+ else if (status == -1)
+ {
+ BOX_WARNING("Demangle failed with "
+ "memory allocation error: " <<
+ mangled_func);
+ }
+ else if (status == -2)
+ {
+ // Probably non-C++ name, don't demangle
+ /*
+ BOX_WARNING("Demangle failed with "
+ "with invalid name: " <<
+ mangled_func);
+ */
+ }
+ else if (status == -3)
+ {
+ BOX_WARNING("Demangle failed with "
+ "with invalid argument: " <<
+ mangled_func);
+ }
+ else
+ {
+ BOX_WARNING("Demangle failed with "
+ "with unknown error " << status <<
+ ": " << mangled_func);
+ }
+ }
+ else
+ {
+ output_frame = mangled_frame.substr(0, start + 1) +
+ result + mangled_frame.substr(end);
+#include "MemLeakFindOff.h"
+ std::free(result);
+#include "MemLeakFindOn.h"
+ }
+ #endif // HAVE_CXXABI_H
+
+ BOX_TRACE("Stack frame " << i << ": " << output_frame);
}
#include "MemLeakFindOff.h"
- free (strings);
+ std::free (strings);
#include "MemLeakFindOn.h"
}
#endif
@@ -97,8 +163,8 @@ void DumpStackBacktrace()
// --------------------------------------------------------------------------
bool FileExists(const char *Filename, int64_t *pFileSize, bool TreatLinksAsNotExisting)
{
- struct stat st;
- if(::lstat(Filename, &st) != 0)
+ EMU_STRUCT_STAT st;
+ if(EMU_LSTAT(Filename, &st) != 0)
{
if(errno == ENOENT)
{
@@ -142,8 +208,8 @@ bool FileExists(const char *Filename, int64_t *pFileSize, bool TreatLinksAsNotEx
// --------------------------------------------------------------------------
int ObjectExists(const std::string& rFilename)
{
- struct stat st;
- if(::stat(rFilename.c_str(), &st) != 0)
+ EMU_STRUCT_STAT st;
+ if(EMU_STAT(rFilename.c_str(), &st) != 0)
{
if(errno == ENOENT)
{
@@ -159,6 +225,85 @@ int ObjectExists(const std::string& rFilename)
return ((st.st_mode & S_IFDIR) == 0)?ObjectExists_File:ObjectExists_Dir;
}
+std::string HumanReadableSize(int64_t Bytes)
+{
+ double readableValue = Bytes;
+ std::string units = " B";
+
+ if (readableValue > 1024)
+ {
+ readableValue /= 1024;
+ units = "kB";
+ }
+
+ if (readableValue > 1024)
+ {
+ readableValue /= 1024;
+ units = "MB";
+ }
+
+ if (readableValue > 1024)
+ {
+ readableValue /= 1024;
+ units = "GB";
+ }
+
+ std::ostringstream result;
+ result << std::fixed << std::setprecision(2) << readableValue <<
+ " " << units;
+ return result.str();
+}
+
+std::string FormatUsageBar(int64_t Blocks, int64_t Bytes, int64_t Max,
+ bool MachineReadable)
+{
+ std::ostringstream result;
+
+
+ if (MachineReadable)
+ {
+ result << (Bytes >> 10) << " kB, " <<
+ std::setprecision(0) << ((Bytes*100)/Max) << "%";
+ }
+ else
+ {
+ // Bar graph
+ char bar[17];
+ unsigned int b = (int)((Bytes * (sizeof(bar)-1)) / Max);
+ if(b > sizeof(bar)-1) {b = sizeof(bar)-1;}
+ for(unsigned int l = 0; l < b; l++)
+ {
+ bar[l] = '*';
+ }
+ for(unsigned int l = b; l < sizeof(bar) - 1; l++)
+ {
+ bar[l] = ' ';
+ }
+ bar[sizeof(bar)-1] = '\0';
+
+ result << std::fixed <<
+ std::setw(10) << Blocks << " blocks, " <<
+ std::setw(10) << HumanReadableSize(Bytes) << ", " <<
+ std::setw(3) << std::setprecision(0) <<
+ ((Bytes*100)/Max) << "% |" << bar << "|";
+ }
+
+ return result.str();
+}
+std::string FormatUsageLineStart(const std::string& rName,
+ bool MachineReadable)
+{
+ std::ostringstream result;
+ if (MachineReadable)
+ {
+ result << rName << ": ";
+ }
+ else
+ {
+ result << std::setw(20) << std::right << rName << ": ";
+ }
+ return result.str();
+}