summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2017-08-21 21:44:35 +0800
committerJohn Hodge <tpg@mutabah.net>2017-08-21 21:44:35 +0800
commitaf317dcd9059ee78e4c8f36d9c67eb38fdf07709 (patch)
tree4e4c3330d75cd5c1d6952f67b87d6b2385223fc9 /tools
parent84c0019c3e7cf8932bfd74db8d4f0d10cd86811e (diff)
downloadmrust-af317dcd9059ee78e4c8f36d9c67eb38fdf07709.tar.gz
minicargo - move path code to its own file
Diffstat (limited to 'tools')
-rw-r--r--tools/minicargo/build.cpp2
-rw-r--r--tools/minicargo/helpers.h245
-rw-r--r--tools/minicargo/manifest.cpp2
-rw-r--r--tools/minicargo/manifest.h2
-rw-r--r--tools/minicargo/path.cpp157
-rw-r--r--tools/minicargo/path.h126
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