From 023d233c407b99199fc2d854df6e760d1ce24705 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Sun, 1 Feb 2015 19:42:16 -0500 Subject: [PATCH] cxx string_splitter --- bin/loader.cpp | 47 +++++++++---------------- cxx/string_splitter.h | 82 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+), 31 deletions(-) create mode 100644 cxx/string_splitter.h diff --git a/bin/loader.cpp b/bin/loader.cpp index be425d6..2f63d1a 100644 --- a/bin/loader.cpp +++ b/bin/loader.cpp @@ -59,6 +59,8 @@ #include "loader.h" #include "debugger.h" +#include + #define LOADER_LOAD @@ -687,43 +689,26 @@ std::string find_exe(const std::string &name) // otherwise, check the Commands variable for locations. - std::string command = MPW::GetEnv("Commands"); - if (command.empty()) return old_find_exe(name); + std::string commands = MPW::GetEnv("Commands"); + if (commands.empty()) return old_find_exe(name); // string is , separated, possibly in MacOS format. - std::string::size_type begin = 0; - std::string::size_type end = 0; - for(;;) + + for (auto iter = string_splitter(commands, ','); iter; ++iter) { - std::string path; - end = command.find(',', begin); + if (iter->empty()) continue; + std::string path = *iter; - if (end == std::string::npos) { - - if (begin >= command.length()) return ""; - - path = command.substr(begin); - } - else - { - size_t count = end - begin - 1; - path = command.substr(begin, count); - } - - if (!path.empty()) - { - // convert to unix. - path = ToolBox::MacToUnix(path); - // should always have a length... - if (path.length() && path.back() != '/') path.push_back('/'); - path.append(name); - if (file_exists(path)) return path; - } - - if (end == std::string::npos) return ""; - begin = end + 1; + // convert to unix. + path = ToolBox::MacToUnix(path); + // should always have a length... + if (path.length() && path.back() != '/') path.push_back('/'); + path.append(name); + if (file_exists(path)) return path; } + + return ""; } diff --git a/cxx/string_splitter.h b/cxx/string_splitter.h new file mode 100644 index 0000000..6473153 --- /dev/null +++ b/cxx/string_splitter.h @@ -0,0 +1,82 @@ +#ifndef __string_splitter__ +#define __string_splitter__ + +#include + +class string_splitter { +public: + string_splitter(const std::string &str, char sep) : + _parent(str), _sep(sep) + { + _begin = 0; + _end = _parent.find(_sep); + _str = _parent.substr(_begin, _end); + // _begin is 0, _end is either npos or offset from 0, + // so no need to calculate a count. + } + + operator bool() const { + return _begin != npos; + } + + string_splitter &operator++() { + increment(); + return *this; + } + + const std::string &operator *() const { + return _str; + } + + const std::string *operator ->() const { + return &_str; + } + +private: + void increment() { + _str.clear(); + if (_begin == npos) return; + if (_end == npos) { _begin = _end; return; } + + _begin = _end + 1; + _end = _parent.find(_sep, _begin); + auto count = _end == npos ? _end : _end - _begin; + _str = _parent.substr(_begin, count); + } + + const static auto npos = std::string::npos; + std::string _str; + const std::string &_parent; + char _sep; + std::string::size_type _begin = 0; + std::string::size_type _end = 0; +}; + + +#ifdef TEST +#include +#include + +int main(int argc, char **argv) +{ + if (argc != 3) { + fprintf(stderr, "Usage: %s sep string\n", argv[0]); + return 1; + } + if (strlen(argv[1]) != 1) { + fprintf(stderr, "Separator must be a single character\n"); + return 1; + } + char sep = argv[1][0]; + std::string str(argv[2]); + + for (auto iter = string_splitter(str, sep); iter; ++iter) { + printf("%s\n", iter->c_str()); + } + + return 0; +} +#endif + +#endif +