From: José Fonseca Date: Fri, 28 Oct 2011 07:39:06 +0000 (+0100) Subject: Add a path manipulating class. X-Git-Url: https://git.cworth.org/git?a=commitdiff_plain;h=7257d46c8a6938428750e9272dfb4ac47b9b4404;p=apitrace Add a path manipulating class. --- diff --git a/common/os.hpp b/common/os.hpp index 02625c2..b914405 100644 --- a/common/os.hpp +++ b/common/os.hpp @@ -30,9 +30,13 @@ #ifndef _OS_HPP_ #define _OS_HPP_ +#include #include #include #include +#include + +#include #ifdef _WIN32 #ifndef snprintf @@ -56,8 +60,93 @@ void acquireMutex(void); void releaseMutex(void); -bool getProcessName(char *str, size_t size); -bool getCurrentDir(char *str, size_t size); + +class Path { +protected: + typedef std::vector Buffer; + Buffer buffer; + + Buffer::iterator rfind(char c) { + Buffer::iterator it = buffer.end(); + while (it != buffer.begin()) { + --it; + if (*it == c) { + return it; + } + } + return buffer.end(); + } + +public: + Path() { + buffer.push_back(0); + } + + Path(const char *s) : + buffer(s, s + strlen(s) + 1) + {} + + template + Path(InputIterator first, InputIterator last) : + buffer(first, last) + { + buffer.push_back(0); + } + + char *buf(size_t size) { + buffer.resize(size); + return &buffer[0]; + } + + void trimDirectory(void) { + Buffer::iterator sep = rfind(PATH_SEP); + if (sep != buffer.end()) { + buffer.erase(buffer.begin(), sep + 1); + } + } + + void trimExtension(void) { + Buffer::iterator dot = rfind('.'); + if (dot != buffer.end()) { + buffer.erase(dot, buffer.end()); + } + } + + size_t length(void) const { + size_t size = buffer.size(); + assert(size > 0); + assert(buffer[size - 1] == 0); + return size - 1; + } + + void truncate(size_t size) { + assert(size > 0); + assert(size <= buffer.size()); + assert(buffer[size - 1] == 0); + buffer.resize(size); + } + + void truncate(void) { + truncate(strlen(str())); + } + + const char *str(void) const { + assert(buffer[buffer.size() - 1] == 0); + return &buffer[0]; + } + + void join(const Path & other) { + size_t len = length(); + if (len > 0 && buffer[len - 1] != PATH_SEP) { + buffer.insert(buffer.begin() + len, PATH_SEP); + } + buffer.insert(buffer.begin() + len, other.buffer.begin(), other.buffer.end() - 1); + } + +}; + +Path getProcessName(); +Path getCurrentDir(); void log(const char *format, ...) #ifdef __GNUC__ diff --git a/common/os_posix.cpp b/common/os_posix.cpp index e797220..78fefee 100644 --- a/common/os_posix.cpp +++ b/common/os_posix.cpp @@ -64,55 +64,53 @@ releaseMutex(void) } -bool -getProcessName(char *str, size_t size) +Path +getProcessName(void) { - char szProcessPath[PATH_MAX + 1]; - char *lpProcessName; + Path path; + + char *szProcessPath = path.buf(PATH_MAX); // http://stackoverflow.com/questions/1023306/finding-current-executables-path-without-proc-self-exe #ifdef __APPLE__ - uint32_t len = sizeof szProcessPath; + uint32_t len = PATH_MAX; if (_NSGetExecutablePath(szProcessPath, &len) != 0) { - *str = 0; - return false; + *szProcessPath = 0; + return path; } #else ssize_t len; - len = readlink("/proc/self/exe", szProcessPath, sizeof(szProcessPath) - 1); + len = readlink("/proc/self/exe", szProcessPath, PATH_MAX - 1); if (len == -1) { // /proc/self/exe is not available on setuid processes, so fallback to // /proc/self/cmdline. int fd = open("/proc/self/cmdline", O_RDONLY); if (fd >= 0) { - len = read(fd, szProcessPath, sizeof(szProcessPath) - 1); + len = read(fd, szProcessPath, PATH_MAX - 1); close(fd); } } if (len <= 0) { - snprintf(str, size, "%i", (int)getpid()); - return true; + snprintf(szProcessPath, PATH_MAX, "%i", (int)getpid()); + return path; } #endif szProcessPath[len] = 0; + path.truncate(len); - lpProcessName = strrchr(szProcessPath, '/'); - lpProcessName = lpProcessName ? lpProcessName + 1 : szProcessPath; - - strncpy(str, lpProcessName, size); - if (size) - str[size - 1] = 0; - - return true; + return path; } -bool -getCurrentDir(char *str, size_t size) +Path +getCurrentDir(void) { - char *ret; - ret = getcwd(str, size); + Path path; + size_t size = PATH_MAX; + char *str = path.buf(size); + getcwd(str, size); str[size - 1] = 0; - return ret ? true : false; + path.truncate(); + return path; } void diff --git a/common/os_win32.cpp b/common/os_win32.cpp index 27b8c0a..66c8232 100644 --- a/common/os_win32.cpp +++ b/common/os_win32.cpp @@ -58,26 +58,20 @@ releaseMutex(void) } -bool -getProcessName(char *str, size_t size) +Path +getProcessName(void) { - char szProcessPath[PATH_MAX]; - char *lpProcessName; - char *lpProcessExt; - - GetModuleFileNameA(NULL, szProcessPath, sizeof(szProcessPath)/sizeof(szProcessPath[0])); + Path path; - lpProcessName = strrchr(szProcessPath, '\\'); - lpProcessName = lpProcessName ? lpProcessName + 1 : szProcessPath; + char *szProcessPath = path.buf(PATH_MAX); - lpProcessExt = strrchr(lpProcessName, '.'); - if (lpProcessExt) { - *lpProcessExt = '\0'; - } + DWORD nWritten = GetModuleFileNameA(NULL, szProcessPath, PATH_MAX); - strncpy(str, lpProcessName, size); + path.truncate(); + path.trimExtension(); + path.trimDirectory(); - return true; + return path; } bool diff --git a/common/trace_writer_local.cpp b/common/trace_writer_local.cpp index d03e1ae..4d39490 100644 --- a/common/trace_writer_local.cpp +++ b/common/trace_writer_local.cpp @@ -85,18 +85,16 @@ LocalWriter::open(void) { strncpy(szFileName, lpFileName, PATH_MAX); } else { - char szProcessName[PATH_MAX]; - char szCurrentDir[PATH_MAX]; - os::getProcessName(szProcessName, PATH_MAX); - os::getCurrentDir(szCurrentDir, PATH_MAX); + os::Path szProcessName = os::getProcessName(); + os::Path szCurrentDir = os::getCurrentDir(); for (;;) { FILE *file; if (dwCounter) - snprintf(szFileName, PATH_MAX, "%s%c%s.%u.%s", szCurrentDir, PATH_SEP, szProcessName, dwCounter, szExtension); + snprintf(szFileName, PATH_MAX, "%s%c%s.%u.%s", szCurrentDir.str(), PATH_SEP, szProcessName.str(), dwCounter, szExtension); else - snprintf(szFileName, PATH_MAX, "%s%c%s.%s", szCurrentDir, PATH_SEP, szProcessName, szExtension); + snprintf(szFileName, PATH_MAX, "%s%c%s.%s", szCurrentDir.str(), PATH_SEP, szProcessName.str(), szExtension); file = fopen(szFileName, "rb"); if (file == NULL)