int findSubDirectory(const filesystem::path& directory, const filesystem::path& path, filesystem::path& out_subdirectory) { int numMatchedDepth = 0; if(directory.is_absolute() && path.is_absolute()){ filesystem::path compactPath; makePathCompact(path, compactPath); filesystem::path::const_iterator p = directory.begin(); filesystem::path::const_iterator q = compactPath.begin(); while(p != directory.end() && q != compactPath.end()){ if(!comparePathIterator(p, q)){ break; } ++numMatchedDepth; ++p; ++q; } if(p == directory.end()){ out_subdirectory.clear(); while(q != compactPath.end()){ out_subdirectory /= *q++; } return numMatchedDepth; } } return 0; }
bool findRelativePath(const filesystem::path& from_, const filesystem::path& to, filesystem::path& out_relativePath) { if(from_.is_complete() && to.is_complete()){ filesystem::path from; makePathCompact(from_, from); filesystem::path::const_iterator p = from.begin(); filesystem::path::const_iterator q = to.begin(); while(p != from.end() && q != to.end()){ if(!comparePathIterator(p, q)){ break; } ++p; ++q; } out_relativePath.clear(); while(p != from.end()){ out_relativePath /= ".."; ++p; } while(q != to.end()){ out_relativePath /= *q++; } return true; } return false; }
void makePathCompact(const filesystem::path& path, filesystem::path& out_compact) { out_compact.clear(); for(filesystem::path::const_iterator p = path.begin(); p != path.end(); ++p){ if(*p == ".."){ out_compact = out_compact.parent_path(); } else if(*p != "."){ out_compact /= *p; } } }
/** \todo Introduce a tree structure to improve the efficiency of searching matched directories */ bool ParametricPathProcessorImpl::findSubDirectoryOfDirectoryVariable (const filesystem::path& path, std::string& out_varName, filesystem::path& out_relativePath) { out_relativePath.clear(); int maxMatchSize = 0; filesystem::path relativePath; Mapping::const_iterator p; for(p = variables->begin(); p != variables->end(); ++p) { Listing* paths = p->second->toListing(); if(paths) { for(int i=0; i < paths->size(); ++i) { filesystem::path dirPath(paths->at(i)->toString()); int n = findSubDirectory(dirPath, path, relativePath); if(n > maxMatchSize) { maxMatchSize = n; out_relativePath = relativePath; out_varName = fromUTF8(p->first); } } } } return (maxMatchSize > 0); }