// StormLib needs paths with windows style \'s std::string getStormLibPath(const bfs::path& path) { std::string retval = ""; for(bfs::path::iterator it = path.begin(); it != path.end(); ++it) { retval += it->string() + "\\"; } retval = retval.substr(0, retval.size()-1); return retval; }
boost::filesystem::path normalized_path(const boost::filesystem::path& path) { if (path.empty()) return path; fs::path temp; fs::path::iterator start( path.begin() ); fs::path::iterator last( path.end() ); fs::path::iterator stop( last-- ); for ( fs::path::iterator itr( start ); itr != stop; ++itr ) { if (*itr == "." && itr != start && itr != last) continue; // ignore a name and following ".." if (!temp.empty() && *itr == "..") { string lf( temp.filename() ); if (!lf.empty() && lf != "." && lf != "/" # ifdef BOOST_WINDOWS_PATH && !(lf.size() == 2 && lf[1] == ':') # endif && lf != "..") { temp.remove_filename(); continue; } } temp /= *itr; if (itr != last && temp.has_root_path() && fs::is_symlink(temp)) { temp = normalized_path(readlink(temp)); if (temp.filename() == ".") temp = temp.parent_path(); } } if (temp.empty()) temp /= "."; return temp; }
// expands "./my/path.sfc" to "[relativeTo]/my/path.sfc" // if allowHome is true, also expands "~/my/path.sfc" to "/home/pi/my/path.sfc" fs::path resolvePath(const fs::path& path, const fs::path& relativeTo, bool allowHome) { // nothing here if(path.begin() == path.end()) return path; if(*path.begin() == ".") { fs::path ret = relativeTo; for(auto it = ++path.begin(); it != path.end(); ++it) ret /= *it; return ret; } if(allowHome && *path.begin() == "~") { fs::path ret = getHomePath(); for(auto it = ++path.begin(); it != path.end(); ++it) ret /= *it; return ret; } return path; }
/** * https://svn.boost.org/trac/boost/ticket/1976#comment:2 * * "The idea: uncomplete(/foo/new, /foo/bar) => ../new * The use case for this is any time you get a full path (from an open dialog, perhaps) * and want to store a relative path so that the group of files can be moved to a different * directory without breaking the paths. An IDE would be a simple example, so that the * project file could be safely checked out of subversion." * * ALGORITHM: * iterate path and base * compare all elements so far of path and base * whilst they are the same, no write to output * when they change, or one runs out: * write to output, ../ times the number of remaining elements in base * write to output, the remaining elements in path */ boost::filesystem::path naive_uncomplete(boost::filesystem::path const p, boost::filesystem::path const base) { using boost::filesystem::path; using boost::filesystem::dot; using boost::filesystem::slash; if (p == base) return "./"; /*!! this breaks stuff if path is a filename rather than a directory, which it most likely is... but then base shouldn't be a filename so... */ boost::filesystem::path from_path, from_base, output; boost::filesystem::path::iterator path_it = p.begin(), path_end = p.end(); boost::filesystem::path::iterator base_it = base.begin(), base_end = base.end(); // check for emptiness if ((path_it == path_end) || (base_it == base_end)) throw std::runtime_error("path or base was empty; couldn't generate relative path"); #ifdef WIN32 // drive letters are different; don't generate a relative path if (*path_it != *base_it) return p; // now advance past drive letters; relative paths should only go up // to the root of the drive and not past it ++path_it, ++base_it; #endif // Cache system-dependent dot, double-dot and slash strings const String _dot = String(1, dot<path>::value); const String _dots = String(2, dot<path>::value); const String _sep = String(1, slash<path>::value); // iterate over path and base while (true) { // compare all elements so far of path and base to find greatest common root; // when elements of path and base differ, or run out: if ((path_it == path_end) || (base_it == base_end) || (*path_it != *base_it)) { // write to output, ../ times the number of remaining elements in base; // this is how far we've had to come down the tree from base to get to the common root for (; base_it != base_end; ++base_it) { if (*base_it == _dot) continue; else if (*base_it == _sep) continue; output /= "../"; } // write to output, the remaining elements in path; // this is the path relative from the common root boost::filesystem::path::iterator path_it_start = path_it; for (; path_it != path_end; ++path_it) { if (path_it != path_it_start) output /= "/"; if (*path_it == _dot) continue; if (*path_it == _sep) continue; output /= *path_it; } break; } // add directory level to both paths and continue iteration from_path /= path(*path_it); from_base /= path(*base_it); ++path_it, ++base_it; } return output;
/* * Save list<list<CarImg> > objects to carsDir */ void FileIO::saveCars(list<list<CarImg> > cars, fs::path carsDir) { carsDir = fs::absolute(carsDir); if (!fs::exists(carsDir) || !fs::is_directory(carsDir)) { //if not exists, create it fs::create_directory(carsDir); } fs::path::iterator iterate; fs::path temp; list<CarImg> *line; //this gets the "car" prefix from the name of carsDir, "cars" iterate = carsDir.end(); iterate--; string cDirName = (*iterate).generic_string(); string linePrefix = Tools::shorten(cDirName, cDirName.size()-1); string number; int carsSize = cars.size(); for (int i = 0; i < carsSize; i++) { line = Tools::atList(&cars, i); if (i < 10) { number = "000"+boost::lexical_cast<string>(i); } else if (i < 100) { number = "00"+boost::lexical_cast<string>(i); } else if (i < 1000) { number = "0"+boost::lexical_cast<string>(i); } else { number = boost::lexical_cast<string>(i); } temp = fs::path(cDirName+"/"+linePrefix+number); temp = fs::absolute(temp); if (!fs::exists(temp) || !fs::is_directory(temp)) { //if not exists, create it fs::create_directory(temp); } if (line->size()<=1) { //this catches onesize lists, and replaces them the right way string thisFilename = line->front().getPath()->filename().generic_string(); fs::path thisPath = temp/thisFilename; CarImg backupImg = line->front(); CarImg c = backupImg; c.setPath(thisPath); replace(line->begin(), line->end(), backupImg, c); } else { int j = 0; for (list<CarImg>::iterator lineIt=line->begin(); lineIt != line->end(); lineIt++) { string thisFilename = lineIt->getPath()->filename().generic_string(); fs::path thisPath = temp/thisFilename; CarImg backupImg = *lineIt; CarImg c = backupImg; c.setPath(thisPath); *line = Tools::replaceObj(*line, backupImg, c, j); //replaces line with replaced line j++; } } FileIO::saveCarImgList(*line); ostringstream oss; oss << "SaveCarImgList " << "Line: " << i << ";Size=" << line->size(); Tools::debugMessage(oss.str()); Tools::debugMessage("Car at 0: " + line->front().toString()); } }