boost::filesystem::path naive_uncomplete(boost::filesystem::path const path, boost::filesystem::path const base) { if (path.has_root_path()){ if (path.root_path() != base.root_path()) { return path; } else { return naive_uncomplete(path.relative_path(), base.relative_path()); } } else { if (base.has_root_path()) { throw "cannot uncomplete a path relative path from a rooted base"; } else { typedef boost::filesystem::path::const_iterator path_iterator; path_iterator path_it = path.begin(); path_iterator base_it = base.begin(); while ( path_it != path.end() && base_it != base.end() ) { if (*path_it != *base_it) break; ++path_it; ++base_it; } boost::filesystem::path result; for (; base_it != base.end(); ++base_it) { result /= ".."; } for (; path_it != path.end(); ++path_it) { result /= *path_it; } return result; } } }
boost::filesystem::path MultiresImagePlugin::MakePathRelative(boost::filesystem::path path, boost::filesystem::path base) { // Borrowed from: https://svn.boost.org/trac/boost/ticket/1976#comment:2 if (path.has_root_path()) { if (path.root_path() != base.root_path()) { return path; } else { return MakePathRelative(path.relative_path(), base.relative_path()); } } else { if (base.has_root_path()) { ROS_WARN("Cannot uncomplete a path relative path from a rooted base."); return path; } else { typedef boost::filesystem::path::const_iterator path_iterator; path_iterator path_it = path.begin(); path_iterator base_it = base.begin(); while (path_it != path.end() && base_it != base.end()) { if (*path_it != *base_it) break; ++path_it; ++base_it; } boost::filesystem::path result; for (; base_it != base.end(); ++base_it) { result /= ".."; } for (; path_it != path.end(); ++path_it) { result /= *path_it; } return result; } } }
// Resolve symlinks fs::path fs_base::canonicalize(fs::path in) { fs::path accum; if (!in.has_root_path()) { // dir is relative! accum = fs::system_complete("."); if (*--accum.end() == ".") accum = accum.parent_path(); } #ifdef WIN32 // No C:/ in the path else if (!in.has_root_name()) { accum = fs::system_complete(".").root_name() / accum; } #endif BOOST_FOREACH(fs::path seg, in) { if (seg == ".") continue; // We've already canon'd the path's parent, so just remove the last dir if (seg == "..") { accum = accum.parent_path(); continue; } accum /= seg; #ifndef WIN32 if (fs::is_symlink(accum)) { char buff[PATH_MAX]; ssize_t len = readlink(accum.string().c_str(), buff, PATH_MAX); if (len == -1) { format fmt = format(error_fmt) % "canonical" % std::strerror(errno) % accum; throw exception(fmt.str()); } fs::path link_path = std::string(buff, len); // An absolute link if (link_path.has_root_path()) accum = canonicalize(link_path); else { accum.remove_filename(); accum = canonicalize(accum / link_path); } } #endif } // This trickery forces a trailing / onto the dir if (fs::is_directory(accum)) { accum /= "."; accum.remove_filename(); } return accum; }
bool is_absolute( const boost::filesystem::path& p) { return p.has_root_path(); }