29#include "xvasprintf.h"
34 return (pathComponent.size() == 2 &&
35 std::isalpha(
static_cast<unsigned char>(pathComponent[0])) &&
36 pathComponent[1] ==
':');
46 return components.size() >= 1 && components[0] ==
"/";
48 return components.size() >= 2 &&
is_drive_component(components[0]) && components[1] ==
"\\";
55 return components.size() >= 1 && components[0] ==
"/";
57 return ((components.size() >= 2 &&
is_drive_component(components[0]) && components[1] ==
"\\") ||
58 (components.size() >= 1 && components[0] ==
"\\"));
66 std::string front = components.front();
70 front[0] =
static_cast<char>(std::toupper(
static_cast<unsigned char>(front[0])));
84 size_t end = path.find_last_of(
"\\");
85 if (end == std::string::npos) {
86 return std::string(path);
88 return path.substr(end+1);
92 char *f1 = xstrdup(path);
93 char *p = f1 + strlen(f1);
101 while ((p > f1) && (*p !=
'/') && (*p !=
'\\')) {
120 if (!strcmp(path,
"..")) {
123 if ((path[0] !=
'/') && (path[0] !=
'\\') && (path[1] !=
':')) {
125 f1 = xasprintf(
"%s%s", relativeToPath, path);
133 for (
char *p = f1; *p; p++) {
144 std::vector<std::string> result;
145 size_t pathStartIndex = 0;
149 if (format == PathFormat::kWindows && path.length() >= 2 &&
is_drive_component(path.substr(0, 2))) {
150 result.push_back(path.substr(0, 2));
156 size_t previousIndex = pathStartIndex;
157 size_t index = pathStartIndex;
158 bool foundNonRootSeparator =
false;
159 while ((index = path.find(separator, previousIndex)) != std::string::npos) {
162 if (index == pathStartIndex) {
163 result.push_back(path.substr(index, 1));
165 foundNonRootSeparator =
true;
167 size_t length = index - previousIndex;
169 result.push_back(path.substr(previousIndex, length));
171 previousIndex = index + 1;
173 if (previousIndex < path.length() || foundNonRootSeparator) {
174 result.push_back(path.substr(previousIndex));
181 auto begin = components.begin();
184 if (format == PathFormat::kWindows && components.size() >= 1 &&
is_drive_component(components[0])) {
185 drive += components[0];
192 for (
auto iterator = begin; iterator != components.end(); iterator++) {
193 if (iterator != begin && path.back() != separator) {
204 if ((*iterator).empty() && path.empty()) {
216 const std::vector<std::string> &components,
218 auto pathComponents =
split(path, format);
219 pathComponents.insert(pathComponents.end(), components.begin(), components.end());
220 return join(pathComponents, format);
224 auto components =
split(path, format);
225 return ::is_absolute(components, format);
237 std::vector<std::string>::const_iterator iterator = components.begin();
240 if (iterator == components.end()) {
249 if (iterator == components.end()) {
263 const std::string &basePath,
265 std::vector<std::string> pathComponents =
split(path, format);
266 std::vector<std::string> basePathComponents =
split(basePath, format);
276 std::string basePathDrive =
drive_component(basePathComponents, format);
277 if (!pathDrive.empty() && pathDrive != basePathDrive && !
is_rooted(pathComponents, format)) {
283 std::vector<std::string> resolvedPathRootComponents(basePathComponents.cbegin(), basePathComponentsPathBegin);
284 std::vector<std::string> resolvedPathRootlessComponents(basePathComponentsPathBegin, basePathComponents.cend());
289 std::string pathSeparator;
291 if (resolvedPathRootComponents.empty() || resolvedPathRootComponents.back() != pathSeparator) {
292 resolvedPathRootComponents.push_back(pathSeparator);
294 resolvedPathRootlessComponents = std::vector<std::string>(++pathComponents.begin(), pathComponents.end());
299 for (
const auto &pathComponent : pathComponents) {
302 while (!resolvedPathRootlessComponents.empty() && resolvedPathRootlessComponents.back().empty()) {
303 resolvedPathRootlessComponents.pop_back();
306 if (pathComponent ==
"..") {
307 if (resolvedPathRootlessComponents.empty() || resolvedPathRootlessComponents.back() ==
"..") {
308 resolvedPathRootlessComponents.push_back(
"..");
310 resolvedPathRootlessComponents.pop_back();
313 resolvedPathRootlessComponents.push_back(pathComponent);
320 std::vector<std::string> resolvedPathComponents = resolvedPathRootComponents;
321 resolvedPathComponents.insert(resolvedPathComponents.end(), resolvedPathRootlessComponents.begin(), resolvedPathRootlessComponents.end());
322 std::string resolvedPath =
join(resolvedPathComponents, format);
325 if (resolvedPath.empty()) {
char path_separator(const PathFormat format)
char * epoc_dirname(const char *path)
Compute parent directory of an EPOC directory.
bool is_absolute(const std::string &path, const PathFormat format)
Check if a path is absolute.
std::vector< std::string > split(const std::string &path, const PathFormat format)
Split a path, path, into its components, using the path separator, separator.
char * resolve_epoc_path(const char *path, const char *initialPath)
Returns a new absolute EPOC path, determined by resolving path relative to initialPath.
std::string appending_components(const std::string &path, const std::vector< std::string > &components, const PathFormat format)
Convenience wrapper for join that returns a new path resulting from appending path components,...
std::string resolve_path(const std::string &path, const std::string &startingPath, const PathFormat format)
Returns a path by resolving a relative or absolute path against a starting path.
std::string epoc_basename(std::string path)
Returns the last path component of an EPOC path.
std::string join(const std::vector< std::string > &components, const PathFormat format)
Return a new path by joining the path components, components, with path separator,...
static bool is_drive_component(const std::string &pathComponent)
static bool is_separator(const std::string &pathComponent, const pathutils::PathFormat format)
static std::vector< std::string >::const_iterator path_find_rootless_components_begin(const std::vector< std::string > &components, const pathutils::PathFormat format)
Return the iterator corresponding with the beginning of the path components.
static bool is_rooted(const std::vector< std::string > &components, const pathutils::PathFormat format)
static bool is_absolute(const std::vector< std::string > &components, const pathutils::PathFormat format)
static std::string drive_component(const std::vector< std::string > components, const pathutils::PathFormat format)