93 bool contains_relative =
false;
96 contains_relative = strstr(path,
"..") !=
NULL;
98 return contains_relative;
135 std::vector<std::string> pathVec;
138 std::set<std::string> seenPaths;
139 std::vector<std::string> recursionStack;
140 while (!
m_isFull && !pathVec.empty()) {
141 if (pathVec.back() !=
".") {
142 scan(pathVec.back(), seenPaths, &recursionStack);
144 recursionStack.clear();
153 std::string name_real = name;
159 std::set<std::string> seenPaths;
160 const char* temp =
pathfind_slow(pathList, name, mode, seenPaths);
189 std::set<std::string>& seenPaths)
195 const char* result =
NULL;
197 int len = strlen(pathList) + 1;
198 char* myPathList =
new char[len];
199 char* pathList_nr =
new char[len];
200 char* pathList_r =
new char[len];
201 char* saveptr =
NULL;
202 strcpy(myPathList, pathList);
203 pathList_nr[0] =
'\0';
204 pathList_r[0] =
'\0';
206 char* aPath = strtok_r(myPathList,
":", &saveptr);
208 while (aPath !=
NULL) {
211 int l = strlen(aPath);
213 strcat(pathList_r,
":");
217 if (first_nr == 0) { strcat(pathList_nr,
":"); }
218 strcat(pathList_nr, aPath);
222 aPath = strtok_r((
char*)
NULL,
":", &saveptr);
240 sep = strchr(aPath,
':');
241 while (sep !=
NULL) {
252 std::string myPath = aPath;
253 std::string dirPathList =
scan(myPath, seenPaths);
255 if (!dirPathList.empty()) {
256 result =
pathfind_slow(dirPathList.c_str(), name, mode, seenPaths);
264 sep = strchr(aPath,
':');
268 delete[] pathList_nr;
278 PathMap::iterator it =
m_cache.find(fileName);
281 int levelsDeep =
resolve(pathNm);
282 const std::vector<std::string>& pathVec = it->second;
287 if ((pathNm.find_first_of(
'/') == pathNm.npos)
288 || (pathVec.size() == 1)) {
296 std::string toReturn;
297 int comparisonDepth = 0;
298 std::vector<std::string>::const_iterator it1;
300 for (it1 = pathVec.begin(); it1 != pathVec.end(); it1++) {
301 const std::string& currentPath = *it1;
303 if (currentPath == toReturn) {
307 size_t cTrailing = currentPath.length();
309 size_t cIn = currentPath.find_last_of(
"/") + 1;
312 size_t fpTrailing = pathNm.length();
313 size_t fpIn = pathNm.find_last_of(
"/") + 1;
317 bool loopedOnce =
false;
318 while (cIn < cTrailing && cTrailing != currentPath.npos) {
322 std::string comp1 = currentPath.substr(cIn, cTrailing - cIn);
323 std::string comp2 = pathNm.substr(fpIn, fpTrailing - fpIn);
325 if (comp1 == comp2) {
329 fpTrailing = fpIn - 1;
330 fpIn = pathNm.find_last_of(
"/", fpTrailing - 1) + 1;
332 if (fpIn >= fpTrailing || fpTrailing == pathNm.npos) {
340 cIn = currentPath.find_last_of(
"/", cTrailing - 1) + 1;
348 if (level > comparisonDepth && totalLevels >= levelsDeep) {
349 comparisonDepth = level;
350 toReturn = currentPath;
356 if (pathNm.empty()) {
376 PathMap::iterator it =
m_cache.find(fnm);
379 std::vector<std::string> pathVec;
380 pathVec.push_back(path);
381 m_cache.insert(std::make_pair(fnm, pathVec));
383 m_size +=
sizeof(pathVec);
384 m_size += fnm.size() + 1 + path.size() + 1;
388 std::vector<std::string>& pathVec = it->second;
390 for (std::vector<std::string>::const_iterator it1 = pathVec.begin();
391 it1 != pathVec.end(); ++it1) {
392 const std::string& x = *it1;
397 pathVec.push_back(path);
399 m_size += path.size() + 1;
407 "PathFindMgr::insert(): cache size limit reached");
415 std::vector<std::string>* recursionStack)
417 bool doCacheFiles = (recursionStack !=
NULL);
420 if (doRecursiveScan) {
424 std::string localPaths;
436 if ((recursionStack && recursionStack->empty())
437 || !recursionStack) {
442 std::set<std::string>::iterator it = seenPaths.find(path);
443 if (it != seenPaths.end()) {
447 seenPaths.insert(path);
453 DIR* dir = opendir(path.c_str());
458 bool isFirstDir =
true;
460 while ( (x = readdir(dir)) ) {
462 if (strcmp(x->d_name,
".") == 0 || strcmp(x->d_name,
"..") == 0) {
466 std::string x_fnm = path +
"/" + x->d_name;
471 unsigned char x_type = DT_UNKNOWN;
472 #if defined(_DIRENT_HAVE_D_TYPE) 477 if (x_type == DT_UNKNOWN) {
479 int ret = lstat(x_fnm.c_str(), &statbuf);
484 if (S_ISLNK(statbuf.st_mode)) {
487 else if (S_ISREG(statbuf.st_mode)) {
490 else if (S_ISDIR(statbuf.st_mode)) {
498 if (x_type == DT_LNK) {
500 int ret = stat(x_fnm.c_str(), &statbuf);
505 if (S_ISREG(statbuf.st_mode)) {
508 else if (S_ISDIR(statbuf.st_mode)) {
511 if (seenPaths.find(x_fnm) != seenPaths.end()) {
520 if (x_type == DT_REG) {
529 else if (x_type == DT_DIR) {
530 if (recursionStack) {
531 if (doRecursiveScan) {
533 recursionStack->push_back(x_fnm);
548 if (recursionStack && !recursionStack->empty()) {
549 std::string nextPath = recursionStack->back();
550 recursionStack->pop_back();
551 scan(nextPath, seenPaths, recursionStack);
561 if (path[0] ==
'/') {
566 int trailing = path.length();
567 int in = path.find_last_of(
"/") + 1;
570 while (trailing != -1) {
571 std::string section = path.substr(in, trailing - in + 1 );
573 if (section ==
"../") {
576 else if (section !=
"./") {
577 if (levelsBack == 0) {
578 result = section + result;
586 in = path.find_last_of(
"/", trailing - 1) + 1;
589 if (!result.empty()) {
613 int l = strlen(path);
615 (path[l - 1] ==
'*' || path[l - 1] ==
'+') &&
616 path[l - 2] ==
'/') {
628 std::ostringstream os;
636 const char* pfx)
const 640 os << pfx <<
"[ PathFindMgr: " << endl
642 << pfx <<
" isFull: " <<
m_isFull << endl
643 << pfx <<
" size: " <<
m_size <<
" (max: " <<
s_sizeMax <<
")" << endl;
644 for (PathMap::const_iterator it =
m_cache.begin();
646 const string& x = it->first;
647 const std::vector<string>& y = it->second;
649 os << pfx <<
" " << x <<
" => {";
650 for (
size_t i = 0; i < y.size(); ++i) {
658 os << pfx <<
"]" << endl;
666 dump(std::cerr, flags);
bool find(std::string &filePath)
static int isRecursivePath(const char *path)
static PathFindMgr & singleton()
std::string toString(uint flags=0) const
const char * pathfind(const char *pathList, const char *name, const char *mode)
std::string scan(std::string &path, std::set< std::string > &seenPaths, std::vector< std::string > *recursionStack=NULL)
std::string m_pathfind_ans
static PathFindMgr s_singleton
void tokenize_str(const std::string &tokenstr, const char *delim, std::vector< std::string > &tokenvec)
int resolve(std::string &path)
void ddump(uint flags=0) const
static const int RecursivePathSfxLn
static const uint64_t s_sizeMax
const char * RealPath(const char *nm)
bool try_slow_lookup_for_relative_paths(const char *path)
const char * pathfind_slow(const char *pathList, const char *name, const char *mode, std::set< std::string > &seenPaths)
string basename(const char *fName)
std::ostream & dump(std::ostream &os, uint flags=0, const char *pfx="") const
void insert(const std::string &path)