From 46b8284dcbcda773ecc34f510b5e288e4e5cbda4 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Fonseca?= Date: Sun, 30 Oct 2011 12:59:40 +0000 Subject: [PATCH] Move os::Path to a separate header. Much less re-compiles. Also eliminate wide-spread use of PATH_MAX. --- common/os.hpp | 97 ----------------- common/os_path.hpp | 192 ++++++++++++++++++++++++++++++++++ common/os_posix.cpp | 34 ++++-- common/os_win32.cpp | 27 +++-- common/trace_writer_local.cpp | 12 ++- glretrace_main.cpp | 7 +- glsnapshot.cpp | 6 +- 7 files changed, 246 insertions(+), 129 deletions(-) create mode 100644 common/os_path.hpp diff --git a/common/os.hpp b/common/os.hpp index b97f330..6a3b8c8 100644 --- a/common/os.hpp +++ b/common/os.hpp @@ -30,14 +30,11 @@ #ifndef _OS_HPP_ #define _OS_HPP_ -#include #include #include #include #include -#include - #ifdef _WIN32 #ifndef snprintf #define snprintf _snprintf @@ -45,108 +42,14 @@ #ifndef vsnprintf #define vsnprintf _vsnprintf #endif -#define PATH_SEP '\\' -#else /* !_WIN32 */ -#define PATH_SEP '/' #endif /* !_WIN32 */ -#ifndef PATH_MAX -#define PATH_MAX 1024 -#endif - namespace os { void acquireMutex(void); void releaseMutex(void); - -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 length) { - assert(length < buffer.size()); - buffer[length] = 0; - buffer.resize(length + 1); - } - - 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__ __attribute__ ((format (printf, 1, 2))) diff --git a/common/os_path.hpp b/common/os_path.hpp new file mode 100644 index 0000000..33f9f33 --- /dev/null +++ b/common/os_path.hpp @@ -0,0 +1,192 @@ +/************************************************************************** + * + * Copyright 2011 Jose Fonseca + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + **************************************************************************/ + +/* + * Path manipulation. + */ + +#ifndef _OS_PATH_HPP_ +#define _OS_PATH_HPP_ + + +#include + +#include + +#include "os.hpp" + + +#ifdef _WIN32 +#define OS_DIR_SEP '\\' +#else /* !_WIN32 */ +#define OS_DIR_SEP '/' +#endif /* !_WIN32 */ + + +namespace os { + + +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(); + } + + Path(size_t size) : + buffer(size) { + } + + char *buf(void) { + return &buffer[0]; + } + +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(OS_DIR_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 length) { + assert(length < buffer.size()); + buffer[length] = 0; + buffer.resize(length + 1); + } + + void truncate(void) { + truncate(strlen(str())); + } + + const char *str(void) const { + assert(buffer[buffer.size() - 1] == 0); + return &buffer[0]; + } + + operator const char *(void) const { + return str(); + } + + void join(const Path & other) { + size_t len = length(); + if (len > 0 && buffer[len - 1] != OS_DIR_SEP) { + buffer.insert(buffer.begin() + len++, OS_DIR_SEP); + } + buffer.insert(buffer.begin() + len, other.buffer.begin(), other.buffer.end() - 1); + } + + /** + * Create a path from a printf-like format string + */ + static Path + format(const char *format, ...) +#ifdef __GNUC__ + __attribute__ ((format (printf, 1, 2))) +#endif + { + + va_list args; + + va_start(args, format); + + int length; + va_list args_copy; + va_copy(args_copy, args); +#ifdef _MSC_VER + /* We need to use _vcsprintf to calculate the length as vsnprintf returns -1 + * if the number of characters to write is greater than count. + */ + length = _vscprintf(format, args_copy); +#else + char dummy; + length = vsnprintf(&dummy, sizeof dummy, format, args_copy); +#endif + va_end(args_copy); + + assert(length >= 0); + size_t size = length + 1; + + Path path(size); + + va_start(args, format); + vsnprintf(path.buf(), size, format, args); + va_end(args); + + return path; + } +}; + + +Path getProcessName(); +Path getCurrentDir(); + + +} /* namespace os */ + +#endif /* _OS_PATH_HPP_ */ diff --git a/common/os_posix.cpp b/common/os_posix.cpp index 37dd364..ef329d0 100644 --- a/common/os_posix.cpp +++ b/common/os_posix.cpp @@ -36,11 +36,21 @@ #include #include +#if defined(__linux__) +#include // PATH_MAX +#endif + #ifdef __APPLE__ #include #endif +#ifndef PATH_MAX +#warning PATH_MAX undefined +#define PATH_MAX 4096 +#endif + #include "os.hpp" +#include "os_path.hpp" namespace os { @@ -68,30 +78,30 @@ Path getProcessName(void) { Path path; - - char *szProcessPath = path.buf(PATH_MAX); + size_t size = PATH_MAX; + char *buf = path.buf(size); // http://stackoverflow.com/questions/1023306/finding-current-executables-path-without-proc-self-exe #ifdef __APPLE__ - uint32_t len = PATH_MAX; - if (_NSGetExecutablePath(szProcessPath, &len) != 0) { - *szProcessPath = 0; + uint32_t len = size; + if (_NSGetExecutablePath(buf, &len) != 0) { + *buf = 0; return path; } #else ssize_t len; - len = readlink("/proc/self/exe", szProcessPath, PATH_MAX - 1); + len = readlink("/proc/self/exe", buf, size - 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, PATH_MAX - 1); + len = read(fd, buf, size - 1); close(fd); } } if (len <= 0) { - snprintf(szProcessPath, PATH_MAX, "%i", (int)getpid()); + snprintf(buf, size, "%i", (int)getpid()); return path; } #endif @@ -105,9 +115,11 @@ getCurrentDir(void) { Path path; size_t size = PATH_MAX; - char *str = path.buf(size); - getcwd(str, size); - str[size - 1] = 0; + char *buf = path.buf(size); + + getcwd(buf, size); + buf[size - 1] = 0; + path.truncate(); return path; } diff --git a/common/os_win32.cpp b/common/os_win32.cpp index 3bee070..f33e175 100644 --- a/common/os_win32.cpp +++ b/common/os_win32.cpp @@ -30,6 +30,7 @@ #include #include "os.hpp" +#include "os_path.hpp" namespace os { @@ -62,23 +63,31 @@ Path getProcessName(void) { Path path; + size_t size = MAX_PATH; + char *buf = path.buf(size); - char *szProcessPath = path.buf(PATH_MAX); - - DWORD nWritten = GetModuleFileNameA(NULL, szProcessPath, PATH_MAX); + DWORD nWritten = GetModuleFileNameA(NULL, buf, size); + (void)nWritten; path.truncate(); return path; } -bool -getCurrentDir(char *str, size_t size) +Path +getCurrentDir(void) { - DWORD ret; - ret = GetCurrentDirectoryA(size, str); - str[size - 1] = 0; - return ret == 0 ? false : true; + Path path; + size_t size = MAX_PATH; + char *buf = path.buf(size); + + DWORD ret = GetCurrentDirectoryA(size, buf); + (void)ret; + + buf[size - 1] = 0; + path.truncate(); + + return path; } void diff --git a/common/trace_writer_local.cpp b/common/trace_writer_local.cpp index f50dd21..350a130 100644 --- a/common/trace_writer_local.cpp +++ b/common/trace_writer_local.cpp @@ -31,6 +31,7 @@ #include #include "os.hpp" +#include "os_path.hpp" #include "trace_file.hpp" #include "trace_writer.hpp" #include "trace_format.hpp" @@ -75,11 +76,10 @@ void LocalWriter::open(void) { os::Path szFileName; - char *lpFileName; + const char *lpFileName; - lpFileName = const_cast(getenv("TRACE_FILE")); + lpFileName = getenv("TRACE_FILE"); if (!lpFileName) { - lpFileName = szFileName.buf(PATH_MAX); static unsigned dwCounter = 0; os::Path process = os::getProcessName(); @@ -95,9 +95,9 @@ LocalWriter::open(void) { FILE *file; if (dwCounter) - snprintf(lpFileName, PATH_MAX, "%s.%u.trace", prefix.str(), dwCounter); + szFileName = os::Path::format("%s.%u.trace", prefix.str(), dwCounter); else - snprintf(lpFileName, PATH_MAX, "%s.trace", prefix.str()); + szFileName = os::Path::format("%s.trace", prefix.str()); file = fopen(lpFileName, "rb"); if (file == NULL) @@ -107,6 +107,8 @@ LocalWriter::open(void) { ++dwCounter; } + + lpFileName = szFileName; } os::log("apitrace: tracing to %s\n", lpFileName); diff --git a/glretrace_main.cpp b/glretrace_main.cpp index 2f6d371..c23f664 100644 --- a/glretrace_main.cpp +++ b/glretrace_main.cpp @@ -26,6 +26,7 @@ #include +#include "os_path.hpp" #include "image.hpp" #include "retrace.hpp" #include "glproc.hpp" @@ -139,8 +140,7 @@ void snapshot(unsigned call_no) { image::Image *ref = NULL; if (compare_prefix) { - char filename[PATH_MAX]; - snprintf(filename, sizeof filename, "%s%010u.png", compare_prefix, call_no); + os::Path filename = os::Path::format("%s%010u.png", compare_prefix, call_no); ref = image::readPNG(filename); if (!ref) { return; @@ -161,8 +161,7 @@ void snapshot(unsigned call_no) { snprintf(comment, sizeof comment, "%u", call_no); src->writePNM(std::cout, comment); } else { - char filename[PATH_MAX]; - snprintf(filename, sizeof filename, "%s%010u.png", snapshot_prefix, call_no); + os::Path filename = os::Path::format("%s%010u.png", snapshot_prefix, call_no); if (src->writePNG(filename) && retrace::verbosity >= 0) { std::cout << "Wrote " << filename << "\n"; } diff --git a/glsnapshot.cpp b/glsnapshot.cpp index 1f95db1..97bf77e 100644 --- a/glsnapshot.cpp +++ b/glsnapshot.cpp @@ -27,6 +27,7 @@ #include #include +#include "os_path.hpp" #include "image.hpp" #include "glproc.hpp" #include "glsize.hpp" @@ -205,10 +206,9 @@ void snapshot(unsigned call_no) { if (snapshot_prefix) { image::Image *src = getDrawableImage(); if (src) { - char filename[PATH_MAX]; - snprintf(filename, sizeof filename, "%s%010u.png", snapshot_prefix, call_no); + os::Path filename = os::Path::format("%s%010u.png", snapshot_prefix, call_no); if (src->writePNG(filename)) { - os::log("apitrace: wrote %s\n", filename); + os::log("apitrace: wrote %s\n", filename.str()); } delete src; -- 2.45.2