| 174 | } |
| 175 | |
| 176 | NativePathString NativeParent(const NativePathString& s) { |
| 177 | auto last_sep = s.find_last_of(kAllSeps); |
| 178 | if (last_sep == s.length() - 1) { |
| 179 | // Last separator is a trailing separator, skip all trailing separators |
| 180 | // and try again |
| 181 | auto before_last_seps = s.find_last_not_of(kAllSeps); |
| 182 | if (before_last_seps == NativePathString::npos) { |
| 183 | // Only separators in path |
| 184 | return s; |
| 185 | } |
| 186 | last_sep = s.find_last_of(kAllSeps, before_last_seps); |
| 187 | } |
| 188 | if (last_sep == NativePathString::npos) { |
| 189 | // No (other) separator in path |
| 190 | return s; |
| 191 | } |
| 192 | // There may be multiple contiguous separators, skip all of them |
| 193 | auto before_last_seps = s.find_last_not_of(kAllSeps, last_sep); |
| 194 | if (before_last_seps == NativePathString::npos) { |
| 195 | // All separators are at start of string, keep them all |
| 196 | return s.substr(0, last_sep + 1); |
| 197 | } else { |
| 198 | return s.substr(0, before_last_seps + 1); |
| 199 | } |
| 200 | } |
| 201 | |
| 202 | Status ValidatePath(std::string_view s) { |
| 203 | if (s.find_first_of('\0') != std::string::npos) { |