#ifndef _OS_HPP_
#define _OS_HPP_
+#include <assert.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
+#include <string.h>
+
+#include <vector>
#ifdef _WIN32
#ifndef snprintf
void releaseMutex(void);
-bool getProcessName(char *str, size_t size);
-bool getCurrentDir(char *str, size_t size);
+
+class Path {
+protected:
+ typedef std::vector<char> 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 <class InputIterator>
+ 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__
}
-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
}
-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
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)