From: José Fonseca Date: Thu, 24 Nov 2011 20:09:41 +0000 (+0000) Subject: Cleanup and generalize os string class. X-Git-Tag: 2.0_alpha^2~463 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=447b3d5c7402b0a9e780a26dfed76376e723ac94;p=tools%2Fapitrace.git Cleanup and generalize os string class. --- diff --git a/cli/cli_diff.cpp b/cli/cli_diff.cpp index 4d24973..d9d6257 100644 --- a/cli/cli_diff.cpp +++ b/cli/cli_diff.cpp @@ -29,7 +29,7 @@ #include #include "cli.hpp" -#include "os_path.hpp" +#include "os_string.hpp" #include "os_process.hpp" #include "trace_tools.hpp" @@ -83,7 +83,7 @@ command(int argc, char *argv[]) #define CLI_DIFF_TRACEDIFF_COMMAND "tracediff.sh" - os::Path command = trace::findFile("scripts/" CLI_DIFF_TRACEDIFF_COMMAND, + os::String command = trace::findFile("scripts/" CLI_DIFF_TRACEDIFF_COMMAND, APITRACE_SCRIPTS_INSTALL_DIR "/" CLI_DIFF_TRACEDIFF_COMMAND, true); @@ -98,7 +98,7 @@ command(int argc, char *argv[]) std::cerr << "The 'apitrace diff' command is not yet supported on this O/S.\n"; return 1; #else - os::Path apitrace = os::getProcessName(); + os::String apitrace = os::getProcessName(); setenv("APITRACE", apitrace.str(), 1); return os::execute(args); diff --git a/cli/cli_diff_images.cpp b/cli/cli_diff_images.cpp index 390174c..91f07c1 100644 --- a/cli/cli_diff_images.cpp +++ b/cli/cli_diff_images.cpp @@ -29,12 +29,12 @@ #include #include "cli.hpp" -#include "os_path.hpp" +#include "os_string.hpp" #include "trace_tools.hpp" static const char *synopsis = "Identify differences between two image dumps."; -static os::Path +static os::String find_command(void) { #define CLI_DIFF_IMAGES_COMMAND "snapdiff.py" @@ -50,7 +50,7 @@ usage(void) { char *args[3]; - os::Path command = find_command(); + os::String command = find_command(); args[0] = (char *) command.str(); args[1] = (char *) "--help"; @@ -71,7 +71,7 @@ command(int argc, char *argv[]) int i; char **args = new char* [argc+2]; - os::Path command = find_command(); + os::String command = find_command(); args[0] = (char *) command.str(); diff --git a/cli/cli_diff_state.cpp b/cli/cli_diff_state.cpp index 5dd0fbe..55d8083 100644 --- a/cli/cli_diff_state.cpp +++ b/cli/cli_diff_state.cpp @@ -29,7 +29,7 @@ #include #include "cli.hpp" -#include "os_path.hpp" +#include "os_string.hpp" #include "os_process.hpp" #include "trace_tools.hpp" @@ -83,7 +83,7 @@ command(int argc, char *argv[]) #define CLI_DIFF_STATE_COMMAND "jsondiff.py" - os::Path command = trace::findFile("scripts/" CLI_DIFF_STATE_COMMAND, + os::String command = trace::findFile("scripts/" CLI_DIFF_STATE_COMMAND, APITRACE_SCRIPTS_INSTALL_DIR "/" CLI_DIFF_STATE_COMMAND, true); diff --git a/common/os_posix.cpp b/common/os_posix.cpp index da78783..7dc2bb4 100644 --- a/common/os_posix.cpp +++ b/common/os_posix.cpp @@ -52,7 +52,7 @@ #endif #include "os.hpp" -#include "os_path.hpp" +#include "os_string.hpp" namespace os { @@ -76,10 +76,10 @@ releaseMutex(void) } -Path +String getProcessName(void) { - Path path; + String path; size_t size = PATH_MAX; char *buf = path.buf(size); @@ -113,10 +113,10 @@ getProcessName(void) return path; } -Path +String getCurrentDir(void) { - Path path; + String path; size_t size = PATH_MAX; char *buf = path.buf(size); @@ -128,7 +128,7 @@ getCurrentDir(void) } bool -Path::exists(void) const +String::exists(void) const { struct stat st; int err; diff --git a/common/os_path.hpp b/common/os_string.hpp similarity index 65% rename from common/os_path.hpp rename to common/os_string.hpp index ffb4fd2..c92e6a8 100644 --- a/common/os_path.hpp +++ b/common/os_string.hpp @@ -24,11 +24,11 @@ **************************************************************************/ /* - * Path manipulation. + * String manipulation. */ -#ifndef _OS_PATH_HPP_ -#define _OS_PATH_HPP_ +#ifndef _OS_STRING_HPP_ +#define _OS_STRING_HPP_ #include @@ -65,14 +65,22 @@ extern "C" _CRTIMP int _vscprintf(const char *format, va_list argptr); namespace os { -class Path { +/** + * Vector based zero-terminate string, suitable for passing strings or paths + * to/from OS calls. + */ +class String { protected: typedef std::vector Buffer; + + /** + * The buffer's last element is always the '\0' character, therefore the + * buffer must never be empty. + */ Buffer buffer; Buffer::iterator find(char c) { Buffer::iterator it = buffer.begin(); - /* Why do we make these functions fail on empty paths? */ assert(it != buffer.end()); while (it != buffer.end()) { if (*it == c) { @@ -85,8 +93,6 @@ protected: Buffer::iterator rfind(char c) { Buffer::iterator it = buffer.end(); - assert(it != buffer.begin()); - --it; // skip null while (it != buffer.begin()) { --it; if (*it == c) { @@ -96,7 +102,7 @@ protected: return buffer.end(); } - Path(size_t size) : + String(size_t size) : buffer(size) { } @@ -105,28 +111,183 @@ protected: } public: - Path() { + + /* + * Constructors + */ + + String() { buffer.push_back(0); } - Path(const char *s) : + String(const char *s) : buffer(s, s + strlen(s) + 1) {} + String(const String &other) : + buffer(other.buffer) + {} + template - Path(InputIterator first, InputIterator last) : + String(InputIterator first, InputIterator last) : buffer(first, last) { buffer.push_back(0); } + /** + * From a printf-like format string + */ + static String + 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 _WIN32 + /* 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; + + String path(size); + + va_start(args, format); + vsnprintf(path.buf(), size, format, args); + va_end(args); + + return path; + } + + /* + * Conversion to ordinary C strings. + */ + + const char *str(void) const { + assert(buffer.back() == 0); + return &buffer[0]; + } + + operator const char *(void) const { + return str(); + } + + /* + * Iterators + */ + + typedef Buffer::const_iterator const_iterator; + typedef Buffer::iterator iterator; + + const_iterator begin(void) const { + return buffer.begin(); + } + + iterator begin(void) { + return buffer.begin(); + } + + const_iterator end(void) const { + const_iterator it = buffer.end(); + assert(it != buffer.begin()); + --it; // skip null + return it; + } + + iterator end(void) { + iterator it = buffer.end(); + assert(it != buffer.begin()); + --it; // skip null + return it; + } + + /* + * Operations + */ + + void insert(iterator position, char c) { + buffer.insert(position, c); + } + + template + void insert(iterator position, InputIterator first, InputIterator last) { + buffer.insert(position, first, last); + } + + void insert(iterator position, const char *s) { + assert(s); + insert(position, s, s + strlen(s)); + } + + void insert(iterator position, const String & other) { + insert(position, other.begin(), other.end()); + } + + void append(char c) { + insert(end(), c); + } + + template + void append(InputIterator first, InputIterator last) { + insert(end(), first, last); + } + + void append(const char *s) { + insert(end(), s); + } + + void append(const String & other) { + insert(end(), other); + } + char *buf(size_t size) { buffer.resize(size); return &buffer[0]; } + 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())); + } + + + /* + * String manipulation + */ + + bool + exists(void) const; + void trimDirectory(void) { - Buffer::iterator sep = rfind(OS_DIR_SEP); + iterator sep = rfind(OS_DIR_SEP); if (sep != buffer.end()) { buffer.erase(buffer.begin(), sep + 1); } @@ -145,107 +306,38 @@ public: * 3. A path of just the root directory is unchaged. */ void trimFilename(void) { - Buffer::iterator first = find(OS_DIR_SEP); - Buffer::iterator last = rfind(OS_DIR_SEP); + iterator first = find(OS_DIR_SEP); + iterator last = rfind(OS_DIR_SEP); if (last == buffer.end()) { return; } if (last == first) { - buffer.erase(first + 1, buffer.end() - 1); + buffer.erase(first + 1, end()); } else { - buffer.erase(last, buffer.end() - 1); + buffer.erase(last, end()); } } void trimExtension(void) { - Buffer::iterator dot = rfind('.'); + iterator dot = rfind('.'); if (dot != buffer.end()) { - buffer.erase(dot, buffer.end() - 1); + buffer.erase(dot, 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); + void join(const String & other) { + if (length() && end()[-1] != OS_DIR_SEP) { + append(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 _WIN32 - /* 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; + append(other.begin(), other.end()); } - - bool exists(void) const; }; -Path getProcessName(); -Path getCurrentDir(); +String getProcessName(); +String getCurrentDir(); } /* namespace os */ -#endif /* _OS_PATH_HPP_ */ +#endif /* _OS_STRING_HPP_ */ diff --git a/common/os_win32.cpp b/common/os_win32.cpp index e156c77..13dd4f8 100644 --- a/common/os_win32.cpp +++ b/common/os_win32.cpp @@ -32,7 +32,7 @@ #include #include "os.hpp" -#include "os_path.hpp" +#include "os_string.hpp" namespace os { @@ -61,10 +61,10 @@ releaseMutex(void) } -Path +String getProcessName(void) { - Path path; + String path; size_t size = MAX_PATH; char *buf = path.buf(size); @@ -76,10 +76,10 @@ getProcessName(void) return path; } -Path +String getCurrentDir(void) { - Path path; + String path; size_t size = MAX_PATH; char *buf = path.buf(size); @@ -93,7 +93,7 @@ getCurrentDir(void) } bool -Path::exists(void) const +String::exists(void) const { DWORD attrs = GetFileAttributesA(str()); return attrs != INVALID_FILE_ATTRIBUTES; diff --git a/common/trace_tools.hpp b/common/trace_tools.hpp index ed786e9..7ca908a 100644 --- a/common/trace_tools.hpp +++ b/common/trace_tools.hpp @@ -29,10 +29,7 @@ #include - -namespace os { - class Path; -}; +#include "os_string.hpp" namespace trace { @@ -44,7 +41,7 @@ enum API { }; -os::Path +os::String findFile(const char *relPath, // path relative to the current program const char *absPath, // absolute path bool verbose); diff --git a/common/trace_tools_trace.cpp b/common/trace_tools_trace.cpp index 146f19f..f14617d 100644 --- a/common/trace_tools_trace.cpp +++ b/common/trace_tools_trace.cpp @@ -30,7 +30,7 @@ #include -#include "os_path.hpp" +#include "os_string.hpp" #include "os_process.hpp" #include "trace_tools.hpp" @@ -52,17 +52,17 @@ namespace trace { #endif -os::Path +os::String findFile(const char *relPath, const char *absPath, bool verbose) { - os::Path complete; + os::String complete; /* First look in the same directory from which this process is * running, (to support developers running a compiled program that * has not been installed. */ - os::Path process_dir = os::getProcessName(); + os::String process_dir = os::getProcessName(); process_dir.trimFilename(); @@ -113,7 +113,7 @@ traceProgram(API api, return 1; } - os::Path wrapper; + os::String wrapper; wrapper = findFile(relPath, absPath, verbose); if (!wrapper.length()) { diff --git a/common/trace_writer_local.cpp b/common/trace_writer_local.cpp index 9d0429b..0730150 100644 --- a/common/trace_writer_local.cpp +++ b/common/trace_writer_local.cpp @@ -31,7 +31,7 @@ #include #include "os.hpp" -#include "os_path.hpp" +#include "os_string.hpp" #include "trace_file.hpp" #include "trace_writer.hpp" #include "trace_format.hpp" @@ -74,7 +74,7 @@ LocalWriter::~LocalWriter() void LocalWriter::open(void) { - os::Path szFileName; + os::String szFileName; const char *lpFileName; @@ -82,22 +82,22 @@ LocalWriter::open(void) { if (!lpFileName) { static unsigned dwCounter = 0; - os::Path process = os::getProcessName(); + os::String process = os::getProcessName(); #ifdef _WIN32 process.trimExtension(); #endif process.trimDirectory(); - os::Path prefix = os::getCurrentDir(); + os::String prefix = os::getCurrentDir(); prefix.join(process); for (;;) { FILE *file; if (dwCounter) - szFileName = os::Path::format("%s.%u.trace", prefix.str(), dwCounter); + szFileName = os::String::format("%s.%u.trace", prefix.str(), dwCounter); else - szFileName = os::Path::format("%s.trace", prefix.str()); + szFileName = os::String::format("%s.trace", prefix.str()); lpFileName = szFileName; file = fopen(lpFileName, "rb"); diff --git a/glretrace_main.cpp b/glretrace_main.cpp index dfb051c..3c010d2 100644 --- a/glretrace_main.cpp +++ b/glretrace_main.cpp @@ -26,7 +26,7 @@ #include -#include "os_path.hpp" +#include "os_string.hpp" #include "image.hpp" #include "retrace.hpp" #include "glproc.hpp" @@ -140,7 +140,7 @@ void snapshot(unsigned call_no) { image::Image *ref = NULL; if (compare_prefix) { - os::Path filename = os::Path::format("%s%010u.png", compare_prefix, call_no); + os::String filename = os::String::format("%s%010u.png", compare_prefix, call_no); ref = image::readPNG(filename); if (!ref) { return; @@ -161,7 +161,7 @@ void snapshot(unsigned call_no) { snprintf(comment, sizeof comment, "%u", call_no); src->writePNM(std::cout, comment); } else { - os::Path filename = os::Path::format("%s%010u.png", snapshot_prefix, call_no); + os::String filename = os::String::format("%s%010u.png", snapshot_prefix, call_no); if (src->writePNG(filename) && retrace::verbosity >= 0) { std::cout << "Wrote " << filename << "\n"; }