diff options
author | John Hodge <tpg@mutabah.net> | 2017-08-21 21:44:35 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2017-08-21 21:44:35 +0800 |
commit | af317dcd9059ee78e4c8f36d9c67eb38fdf07709 (patch) | |
tree | 4e4c3330d75cd5c1d6952f67b87d6b2385223fc9 /tools | |
parent | 84c0019c3e7cf8932bfd74db8d4f0d10cd86811e (diff) | |
download | mrust-af317dcd9059ee78e4c8f36d9c67eb38fdf07709.tar.gz |
minicargo - move path code to its own file
Diffstat (limited to 'tools')
-rw-r--r-- | tools/minicargo/build.cpp | 2 | ||||
-rw-r--r-- | tools/minicargo/helpers.h | 245 | ||||
-rw-r--r-- | tools/minicargo/manifest.cpp | 2 | ||||
-rw-r--r-- | tools/minicargo/manifest.h | 2 | ||||
-rw-r--r-- | tools/minicargo/path.cpp | 157 | ||||
-rw-r--r-- | tools/minicargo/path.h | 126 |
6 files changed, 286 insertions, 248 deletions
diff --git a/tools/minicargo/build.cpp b/tools/minicargo/build.cpp index 762ccdd7..29b75328 100644 --- a/tools/minicargo/build.cpp +++ b/tools/minicargo/build.cpp @@ -5,7 +5,7 @@ #include <vector> #include <algorithm> #include <sstream> // stringstream -#include "helpers.h" // path +#include "path.h" #ifdef _WIN32 # include <Windows.h> #else diff --git a/tools/minicargo/helpers.h b/tools/minicargo/helpers.h index f2679ef4..1099778b 100644 --- a/tools/minicargo/helpers.h +++ b/tools/minicargo/helpers.h @@ -29,250 +29,5 @@ public: } }; -/// Path helper class (because I don't want to include boost) -class path -{ -#ifdef _WIN32 - static const char SEP = '\\'; -#else - static const char SEP = '/'; -#endif - - ::std::string m_str; - - path() - { - } -public: - path(const ::std::string& s): - path(s.c_str()) - { - } - path(const char* s): - m_str(s) - { - // 1. Normalise path separators to the system specified separator - for(size_t i = 0; i < m_str.size(); i ++) - { - if( m_str[i] == '/' || m_str[i] == '\\' ) - m_str[i] = SEP; - } - - // 2. Remove any trailing separators - if( !m_str.empty() ) - { - while(!m_str.empty() && m_str.back() == SEP ) - m_str.pop_back(); - if(m_str.empty()) - { - m_str.push_back(SEP); - } - } - else - { - throw ::std::runtime_error("Empty path being constructed"); - } - } - - path operator/(const path& p) const - { - if(p.m_str[0] == '/') - throw ::std::runtime_error("Appending an absolute path to another path"); - return *this / p.m_str.c_str(); - } - /// Append a relative path - path operator/(const char* o) const - { - if (o[0] == '/') - throw ::std::runtime_error("Appending an absolute path to another path"); - auto rv = *this; - rv.m_str.push_back(SEP); - rv.m_str.append(o); - return rv; - } - /// Add an arbitary string to the final component - path operator+(const char* o) const - { - if( ::std::strchr(o, SEP) != nullptr ) - throw ::std::runtime_error("Appending a string containing the path separator (with operator+)"); - auto rv = *this; - rv.m_str.append(o); - return rv; - } - - path parent() const - { - auto pos = m_str.find_last_of(SEP); - if(pos == ::std::string::npos) - { - return *this; - } - else - { - path rv; - rv.m_str = m_str.substr(0, pos); - return rv; - } - } - - operator ::std::string() const - { - return m_str; - } - - class ComponentsIter - { - const path& p; - size_t pos; - size_t end; - - friend class path; - ComponentsIter(const path& p, size_t i): p(p), pos(i) { - end = p.m_str.find(SEP, pos); - if(end == ::std::string::npos) - end = p.m_str.size(); - } - public: - string_view operator*() const { - return string_view(p.m_str.c_str() + pos, end - pos); - } - void operator++() { - if(end == p.m_str.size()) - pos = end; - else - { - pos = end+1; - end = p.m_str.find(SEP, pos); - if(end == ::std::string::npos) - end = p.m_str.size(); - } - } - bool operator!=(const ComponentsIter& x) const { - return pos != x.pos; - } - }; - ComponentsIter begin() const { - return ComponentsIter(*this, 0); - } - ComponentsIter end() const { - return ComponentsIter(*this, m_str.size()); - } - - path normalise() const - { - path rv; - rv.m_str.reserve( m_str.size()+1 ); - - for(auto comp : *this) - { - if( comp == "." ) { - // Ignore. - } - else if( comp == ".." ) - { - // If the path is empty, OR the last element is a "..", push the element - if( rv.m_str.empty() - || (rv.m_str.size() == 3 && rv.m_str[0] == '.' && rv.m_str[1] == '.' && rv.m_str[2] == SEP) - || (rv.m_str.size() > 4 && *(rv.m_str.end()-4) == SEP && *(rv.m_str.end()-3) == '.' && *(rv.m_str.end()-2) == '.' && *(rv.m_str.end()-1) == SEP ) - ) - { - // Push - rv.m_str += comp; - rv.m_str += SEP; - } - else - { - rv.m_str.pop_back(); - auto pos = rv.m_str.find_last_of(SEP); - if(pos == ::std::string::npos) - { - rv.m_str.resize(0); - } - else if( pos == 0 ) - { - // Keep. - } - else - { - rv.m_str.resize(pos+1); - } - } - } - else { - rv.m_str += comp; - rv.m_str += SEP; - } - } - rv.m_str.pop_back(); - return rv; - } -#if 0 - void normalise_in_place() - { - size_t insert_point = 0; - - for(size_t read_pos = 0; read_pos < m_str.size(); read_pos ++) - { - auto pos = m_str.find_first_of(SEP, read_pos); - if(pos == ::std::string::npos) - pos = m_str.size(); - auto comp = string_view(m_str.c_str() + read_pos, pos - read_pos); - - bool append; - if(comp == ".") - { - // Advance read without touching insert - append = false; - } - else if( comp == ".." ) - { - // Consume parent (if not a relative component already) - // Move insertion point back to the previous separator - auto pos = m_str.find_last_of(SEP, insert_point); - if(pos == ::std::string::npos) - { - // Only one component currently (or empty) - append = true; - } - else if(string_view(m_str.c_str() + pos+1, insert_point - pos-1) == "..") - { - // Last component is ".." - keep adding - append = true; - } - else - { - insert_point = pos; - append = false; - } - } - else - { - append = true; - } - - if(append) - { - if( read_pos != insert_point ) - { - //assert(read_pos > insert_point); - while(read_pos < pos) - { - m_str[insert_point++] = m_str[read_pos++]; - } - } - } - else - { - read_pos = pos; - } - } - } -#endif - - friend ::std::ostream& operator<<(::std::ostream& os, const path& p) - { - return os << p.m_str; - } -}; } // namespace helpers diff --git a/tools/minicargo/manifest.cpp b/tools/minicargo/manifest.cpp index 1bb815d8..d0eefcc6 100644 --- a/tools/minicargo/manifest.cpp +++ b/tools/minicargo/manifest.cpp @@ -3,7 +3,7 @@ #include "manifest.h" #include "toml.h" #include "debug.h" -#include "helpers.h" +#include "path.h" #include <cassert> #include <algorithm> #include "repository.h" diff --git a/tools/minicargo/manifest.h b/tools/minicargo/manifest.h index d94a219b..bf010804 100644 --- a/tools/minicargo/manifest.h +++ b/tools/minicargo/manifest.h @@ -3,7 +3,7 @@ #include <string> #include <vector> #include <memory> -#include "helpers.h" +#include "path.h" class PackageManifest; class Repository; diff --git a/tools/minicargo/path.cpp b/tools/minicargo/path.cpp new file mode 100644 index 00000000..d0316548 --- /dev/null +++ b/tools/minicargo/path.cpp @@ -0,0 +1,157 @@ +/* + */ +#include "path.h" + +helpers::path::path(const char* s): + m_str(s) +{ + // 1. Normalise path separators to the system specified separator + for(size_t i = 0; i < m_str.size(); i ++) + { + if( m_str[i] == '/' || m_str[i] == '\\' ) + m_str[i] = SEP; + } + + // 2. Remove any trailing separators + if( !m_str.empty() ) + { + while(!m_str.empty() && m_str.back() == SEP ) + m_str.pop_back(); + if(m_str.empty()) + { + m_str.push_back(SEP); + } + } + else + { + throw ::std::runtime_error("Empty path being constructed"); + } +} + +helpers::path helpers::path::normalise() const +{ + path rv; + rv.m_str.reserve( m_str.size()+1 ); + + for(auto comp : *this) + { + if( comp == "." ) { + // Ignore. + } + else if( comp == ".." ) + { + // If the path is empty, OR the last element is a "..", push the element + if( rv.m_str.empty() + || (rv.m_str.size() == 3 && rv.m_str[0] == '.' && rv.m_str[1] == '.' && rv.m_str[2] == SEP) + || (rv.m_str.size() > 4 && *(rv.m_str.end()-4) == SEP && *(rv.m_str.end()-3) == '.' && *(rv.m_str.end()-2) == '.' && *(rv.m_str.end()-1) == SEP ) + ) + { + // Push + rv.m_str += comp; + rv.m_str += SEP; + } + else + { + rv.m_str.pop_back(); + auto pos = rv.m_str.find_last_of(SEP); + if(pos == ::std::string::npos) + { + rv.m_str.resize(0); + } + else if( pos == 0 ) + { + // Keep. + } + else + { + rv.m_str.resize(pos+1); + } + } + } + else + { + rv.m_str += comp; + rv.m_str += SEP; + } + } + rv.m_str.pop_back(); + return rv; +} + +#if 0 +void helpers::path::normalise_in_place() +{ + size_t insert_point = 0; + + for(size_t read_pos = 0; read_pos < m_str.size(); read_pos ++) + { + auto pos = m_str.find_first_of(SEP, read_pos); + if(pos == ::std::string::npos) + pos = m_str.size(); + auto comp = string_view(m_str.c_str() + read_pos, pos - read_pos); + + bool append; + if(comp == ".") + { + // Advance read without touching insert + append = false; + } + else if( comp == ".." ) + { + // Consume parent (if not a relative component already) + // Move insertion point back to the previous separator + auto pos = m_str.find_last_of(SEP, insert_point); + if(pos == ::std::string::npos) + { + // Only one component currently (or empty) + append = true; + } + else if(string_view(m_str.c_str() + pos+1, insert_point - pos-1) == "..") + { + // Last component is ".." - keep adding + append = true; + } + else + { + insert_point = pos; + append = false; + } + } + else + { + append = true; + } + + if(append) + { + if( read_pos != insert_point ) + { + //assert(read_pos > insert_point); + while(read_pos < pos) + { + m_str[insert_point++] = m_str[read_pos++]; + } + } + } + else + { + read_pos = pos; + } + } +} +#endif + +void helpers::path::ComponentsIter::operator++() +{ + if(end == p.m_str.size()) + { + pos = end; + } + else + { + pos = end+1; + end = p.m_str.find(SEP, pos); + if(end == ::std::string::npos) + end = p.m_str.size(); + } +}
\ No newline at end of file diff --git a/tools/minicargo/path.h b/tools/minicargo/path.h new file mode 100644 index 00000000..73a520a9 --- /dev/null +++ b/tools/minicargo/path.h @@ -0,0 +1,126 @@ +#pragma once + +#include <string> +#include "helpers.h" + +namespace helpers { + +/// Path helper class (because I don't want to include boost) +class path +{ +#ifdef _WIN32 + static const char SEP = '\\'; +#else + static const char SEP = '/'; +#endif + + ::std::string m_str; + +public: + path() + { + } + path(const ::std::string& s): + path(s.c_str()) + { + } + path(const char* s); + + bool is_valid() const { + return m_str != ""; + } + + path operator/(const path& p) const + { + if(!this->is_valid()) + throw ::std::runtime_error("Appending to an invalid path"); + if(!p.is_valid()) + throw ::std::runtime_error("Appending from an invalid path"); + if(p.m_str[0] == '/') + throw ::std::runtime_error("Appending an absolute path to another path"); + return *this / p.m_str.c_str(); + } + /// Append a relative path + path operator/(const char* o) const + { + if(!this->is_valid()) + throw ::std::runtime_error("Appending to an invalid path"); + if (o[0] == '/') + throw ::std::runtime_error("Appending an absolute path to another path"); + auto rv = *this; + rv.m_str.push_back(SEP); + rv.m_str.append(o); + return rv; + } + /// Add an arbitary string to the final component + path operator+(const char* o) const + { + if(!this->is_valid()) + throw ::std::runtime_error("Appending a string to an invalid path"); + if( ::std::strchr(o, SEP) != nullptr ) + throw ::std::runtime_error("Appending a string containing the path separator (with operator+)"); + auto rv = *this; + rv.m_str.append(o); + return rv; + } + + path parent() const + { + if(!this->is_valid()) + throw ::std::runtime_error("Calling parent() on an invalid path"); + auto pos = m_str.find_last_of(SEP); + if(pos == ::std::string::npos) + { + return *this; + } + else + { + path rv; + rv.m_str = m_str.substr(0, pos); + return rv; + } + } + + operator ::std::string() const + { + return m_str; + } + + class ComponentsIter + { + const path& p; + size_t pos; + size_t end; + + friend class path; + ComponentsIter(const path& p, size_t i): p(p), pos(i) { + end = p.m_str.find(SEP, pos); + if(end == ::std::string::npos) + end = p.m_str.size(); + } + public: + string_view operator*() const { + return string_view(p.m_str.c_str() + pos, end - pos); + } + void operator++(); + bool operator!=(const ComponentsIter& x) const { + return pos != x.pos; + } + }; + ComponentsIter begin() const { + return ComponentsIter(*this, 0); + } + ComponentsIter end() const { + return ComponentsIter(*this, m_str.size()); + } + + path normalise() const; + //void normalise_in_place(); + + friend ::std::ostream& operator<<(::std::ostream& os, const path& p) + { + return os << p.m_str; + } +}; + +}
\ No newline at end of file |