13 #ifndef __STOUT_PATH_HPP__ 14 #define __STOUT_PATH_HPP__ 20 #include <glog/logging.h> 69 const std::string&
path,
76 std::vector<std::string> components;
77 const bool isAbs = (path[0] == _separator);
78 const std::string separator(1, _separator);
84 if (component ==
"." || component.empty()) {
88 if (component ==
"..") {
89 if (components.empty()) {
91 return Error(
"Absolute path '" + path +
"' tries to escape root");
93 components.push_back(component);
94 }
else if (components.back() ==
"..") {
95 components.push_back(component);
97 components.pop_back();
100 components.push_back(component);
104 if (components.empty()) {
105 return isAbs ? separator :
".";
108 components.insert(components.begin(),
"");
117 const std::string& path1,
118 const std::string& path2,
121 const std::string separator =
stringify(_separator);
128 template <
typename... Paths>
130 const std::string& path1,
131 const std::string& path2,
134 return join(path1,
join(path2, std::forward<Paths>(
paths)...));
139 const std::vector<std::string>&
paths,
146 std::string result = paths[0];
147 for (
size_t i = 1; i < paths.size(); ++i) {
148 result =
join(result, paths[i], separator);
183 if (path.length() < 3) {
187 const char letter = path[0];
188 if (!((letter >=
'A' && letter <=
'Z') ||
189 (letter >=
'a' && letter <=
'z'))) {
193 std::string colon = path.substr(1, 2);
194 return colon ==
":\\" || colon ==
":/";
195 #endif // __WINDOWS__ 220 separator(path_separator)
252 return std::string(
".");
255 size_t end = value.size() - 1;
258 if (value[end] == separator) {
259 end = value.find_last_not_of(separator, end);
262 if (end == std::string::npos) {
269 size_t start = value.find_last_of(separator, end);
271 if (start == std::string::npos) {
277 return value.substr(start, end + 1 - start);
311 return std::string(
".");
314 size_t end = value.size() - 1;
317 if (value[end] == separator) {
318 end = value.find_last_not_of(separator, end);
322 end = value.find_last_of(separator, end);
325 if (end == std::string::npos) {
326 return std::string(
".");
336 end = value.find_last_not_of(separator, end);
339 if (end == std::string::npos) {
343 return value.substr(0, end + 1);
365 std::string _basename = basename();
366 size_t index = _basename.rfind(
'.');
368 if (_basename ==
"." || _basename ==
".." || index == std::string::npos) {
372 return _basename.substr(index);
382 operator std::string()
const 403 using pointer = std::string::const_iterator::pointer;
416 std::string::const_iterator offset_)
417 :
path(path_), offset(offset_) {}
427 if (offset ==
path->string().end()) {
446 CHECK_EQ(
path, other.path)
447 <<
"Iterators into different paths cannot be compared";
449 return (!
path && !other.path) || offset == other.offset;
454 return !(*
this == other);
465 std::string::const_iterator offset;
489 return !(left == right);
507 return !(left > right);
513 return !(left < right);
518 std::ostream& stream,
521 return stream << path.
string();
529 const std::string& path_,
530 const std::string& base_,
535 "Relative paths can only be computed between paths which are either " 536 "both absolute or both relative");
543 if (normalized_path.
isError()) {
544 return normalized_path;
547 if (normalized_base.
isError()) {
548 return normalized_base;
552 if (*normalized_path == *normalized_base) {
559 auto path_it = path.
begin();
560 auto base_it = base.
begin();
562 const auto path_end = path.
end();
563 const auto base_end = base.
end();
566 for (; path_it != path_end && base_it != base_end && *path_it == *base_it;
567 ++path_it, ++base_it) {
570 std::vector<std::string> result;
572 std::distance(base_it, base_end) + std::distance(path_it, path_end));
576 if (base_it != base_end) {
577 for (; base_it != base_end; ++base_it) {
578 result.emplace_back(
"..");
583 for (; path_it != path_end; ++path_it) {
584 result.emplace_back(*path_it);
587 return join(result, path_separator);
592 #endif // __STOUT_PATH_HPP__
bool is_absolute(const std::string &path)
Returns whether the given path is an absolute path.
Definition: path.hpp:158
Definition: errorbase.hpp:36
std::stringstream & join(std::stringstream &stream, const std::string &separator, T &&...args)
Definition: strings.hpp:307
std::string reference
Definition: path.hpp:412
std::string value_type
Definition: path.hpp:401
Definition: format.hpp:45
const_iterator & operator++()
Definition: path.hpp:422
std::string paths()
Definition: os.hpp:138
Definition: posix_signalhandler.hpp:23
std::string join(const std::string &path1, const std::string &path2, const char _separator=os::PATH_SEPARATOR)
Definition: path.hpp:116
Try< Nothing > start(const std::string &name)
Starts the slice with the given name (via 'systemctl start <name>').
std::string remove(const std::string &from, const std::string &substring, Mode mode=ANY)
Definition: strings.hpp:41
bool operator>=(const Path &left, const Path &right)
Definition: path.hpp:511
const_iterator end() const
Definition: path.hpp:473
std::vector< std::string > tokenize(const std::string &s, const std::string &delims, const Option< size_t > &maxTokens=None())
Definition: strings.hpp:139
Result< int > index(const std::string &link)
bool operator>(const Path &left, const Path &right)
Definition: path.hpp:499
Definition: strings.hpp:36
Represents a POSIX or Windows file system path and offers common path manipulations.
Definition: path.hpp:212
bool operator==(const const_iterator &other) const
Definition: path.hpp:444
reference operator*() const
Definition: path.hpp:457
std::string from_uri(const std::string &uri)
Definition: path.hpp:44
STOUT_DEPRECATED bool absolute(const std::string &path)
Definition: path.hpp:198
std::string::const_iterator::difference_type difference_type
Definition: path.hpp:402
std::string replace(const std::string &s, const std::string &from, const std::string &to)
Definition: strings.hpp:113
Path(const std::string &path, const char path_separator=os::PATH_SEPARATOR)
Definition: path.hpp:217
std::string dirname() const
Extracts the component up to, but not including, the final '/'.
Definition: path.hpp:308
Try< std::string > normalize(const std::string &path, const char _separator=os::PATH_SEPARATOR)
Definition: path.hpp:68
Try< bool > remove(const std::string &link, const Handle &parent, uint16_t protocol)
std::ostream & operator<<(std::ostream &stream, const Path &path)
Definition: path.hpp:517
bool operator!=(const const_iterator &other) const
Definition: path.hpp:452
bool isError() const
Definition: try.hpp:78
Option< std::string > extension() const
Returns the file extension of the path, including the dot.
Definition: path.hpp:363
#define STOUT_DEPRECATED
Definition: attributes.hpp:59
bool operator==(const Path &left, const Path &right)
Definition: path.hpp:481
const_iterator begin() const
Definition: path.hpp:468
bool operator<=(const Path &left, const Path &right)
Definition: path.hpp:505
const_iterator operator++(int)
Definition: path.hpp:437
Try< std::string > relative(const std::string &path_, const std::string &base_, char path_separator=os::PATH_SEPARATOR)
Definition: path.hpp:528
std::string::const_iterator::pointer pointer
Definition: path.hpp:403
bool operator<(const Path &left, const Path &right)
Definition: path.hpp:493
const_iterator(const Path *path_, std::string::const_iterator offset_)
Definition: path.hpp:414
std::string basename() const
Extracts the component following the final '/'.
Definition: path.hpp:249
std::string stringify(int flags)
bool startsWith(const std::string &s, const std::string &prefix)
Definition: strings.hpp:381
const std::string & string() const
Definition: path.hpp:387
Path()
Definition: path.hpp:215
bool operator!=(const Path &left, const Path &right)
Definition: path.hpp:487
bool is_absolute() const
Definition: path.hpp:376
constexpr char PATH_SEPARATOR
Definition: constants.hpp:24
std::forward_iterator_tag iterator_category
Definition: path.hpp:400
Try< std::list< std::string > > find(const std::string &directory, const std::string &pattern)
Definition: find.hpp:37
Definition: strings.hpp:35