23 using namespace DD4hep;
27 const char separator =
'/';
28 const char*
const separators =
"/";
29 const char colon =
':';
32 inline bool is_separator(
char c) {
return c == separator; }
34 bool is_root_separator(
const string& str,
size_t pos)
37 if ( str.empty() || is_separator(str[pos]) ) {
38 throw runtime_error(
"precondition violation");
41 while (pos > 0 && is_separator(str[pos-1]))
48 if (pos < 3 || !is_separator(str[0]) || !is_separator(str[1]))
51 return str.find_first_of(separators, 2) == pos;
54 size_t filename_pos(
const string& str,
size_t end_pos)
59 && is_separator(str[0])
60 && is_separator(str[1]))
return 0;
63 if (end_pos && is_separator(str[end_pos-1]))
67 size_t pos(str.find_last_of(separators, end_pos-1));
69 return (pos == string::npos
70 || (pos == 1 && is_separator(str[0])))
76 size_t root_directory_start(
const string& path,
size_t size) {
79 && is_separator(path[0])
80 && is_separator(path[1]))
return string::npos;
83 && is_separator(path[0])
84 && is_separator(path[1])
85 && !is_separator(path[2]))
87 string::size_type pos(path.find_first_of(separators, 2));
88 return pos < size ? pos : string::npos;
92 if (size > 0 && is_separator(path[0]))
return 0;
97 const Path& Path::detail::dot_path() {
101 const Path& Path::detail::dot_dot_path() {
106 Path& Path::append(
const std::string& c) {
107 insert(end(),separator);
108 insert(end(),c.begin(),c.end());
116 vector<string> pathes;
118 ::strncpy(tmp, string_data(),
sizeof(tmp));
119 tmp[
sizeof(tmp)-1] = 0;
120 char *token, *save=0;
121 token = ::strtok_r(tmp,separators,&save);
123 pathes.push_back(token);
124 token = ::strtok_r(0,separators,&save);
127 vector<string>::const_iterator start(pathes.begin());
128 vector<string>::const_iterator last(pathes.end());
129 vector<string>::const_iterator stop(last--);
130 for (vector<string>::const_iterator itr(start); itr != stop; ++itr) {
133 if (itr_path.
native().size() == 1
134 && (itr_path.
native())[0] == dot
136 && itr != last)
continue;
139 if ( temp.empty() && itr_path.find(colon) != string::npos ) {
143 else if (!temp.empty()
144 && itr_path.
native().size() == 2
145 && (itr_path.
native())[0] == dot
146 && (itr_path.
native())[1] == dot)
150 && (lf.size() != 1 || (lf[0] != dot && lf[0] != separator))
151 && (lf.size() != 2 || (lf[0] != dot && lf[1] != dot)) )
168 vector<string>::const_iterator next(itr);
169 if (temp.empty() && ++next != stop && next == last && *last == detail::dot_path()) {
170 temp /= detail::dot_path();
179 temp /= detail::dot_path();
183 size_t Path::parent_path_end()
const {
184 size_t end_pos(filename_pos(native(),this->size()));
185 bool filename_was_separator(this->size() && is_separator(at(end_pos)));
188 size_t root_dir_pos(root_directory_start(native(), end_pos));
190 && (end_pos-1) != root_dir_pos
191 && is_separator(this->at(end_pos-1))
195 return (end_pos == 1 && root_dir_pos == 0 && filename_was_separator) ? string::npos : end_pos;
199 Path& Path::remove_filename() {
200 this->erase(this->parent_path_end());
204 Path Path::parent_path()
const {
205 size_t end_pos(parent_path_end());
206 return end_pos == string::npos ?
Path() : Path(string_data(), string_data() + end_pos);
211 size_t pos(filename_pos(native(), native().size()));
212 return (native().size()
214 && is_separator(at(pos))
215 && !is_root_separator(native(), pos))
217 :
Path(string_data() + pos);
221 size_t pos(filename_pos(native(), native().size()));
222 return (native().size()
224 && is_separator(at(pos))
225 && !is_root_separator(native(), pos))
227 :
Path(string_data() + pos);
Path filename() const
The file name of the path.
Path & remove_filename()
Manipulator: remove the file name part. Leaves the parent path.
const std::string & native() const
String representation of thre Path object.