////////////////////////////////////////////////////////////////////////////////// // Function name : util_RemoveLastPathElement // Description : // effectively pops off a path element from the end, except for the root dir, where it does nothing // it removes any slashes before and after the element // ///root//foo/ -> leaves "///root" ("foo" is strElem) // ///root -> leaves "" ("root" is strElem) // // -> leaves "" ("" is strElem) // // Return type : void // Argument : TSTRING& strPath // Argument : TSTRING& strElem ///////////////////////////////////////////////////////////////////////////////// void util_RemoveLastPathElement(TSTRING& strPath, TSTRING& strElem) { // remove all trailing separators util_RemoveTrailingSeps(strPath); // find the last separator TSTRING::size_type lastSep = strPath.rfind(TW_SLASH); // if separator was found, take all chars after it if (lastSep != TSTRING::npos) { strElem = strPath.substr(lastSep + 1); strPath.resize(lastSep + 1); } else // no seps in name, take whole string { // last element strElem = strPath; strPath.erase(); } // remove all trailing separators util_RemoveTrailingSeps(strPath); }
//////////////////////////////////////////////////////////////////////////////// // Function name : util_RemoveDuplicateSeps // Description : // takes all adjacent slashes and replaces them with a single slash // ///root//foo -> /root/foo // rel//foo/// -> rel/foo/ // // Return type : void // Argument : TSTRING& strPath /////////////////////////////////////////////////////////////////////////////// void util_RemoveDuplicateSeps(TSTRING& strPath) { bool fLastCharWasSep = false; TSTRING::iterator iter = strPath.begin(); while (iter != strPath.end()) { bool fErasedChar = false; // if we've found a char that's not '/', then it's not the root if (*iter == TW_SLASH) { // if this char is a duplicate sep, erase it if (fLastCharWasSep) { iter = strPath.erase(iter); fErasedChar = true; } fLastCharWasSep = true; } else { fLastCharWasSep = false; } // don't go past end of string (could happen with erase) if (!fErasedChar) iter++; } }
/////////////////////////////////////////////////////////////////////////////// // Function name : util_PathFind // Description : // takes single-element executible filename and looks in path env var for it // assumes path is colon-delimited string of directories. // // Return type : bool // Argument : TSTRING& strFullPath // Argument : const TSTRING& strFilename /////////////////////////////////////////////////////////////////////////////// bool util_PathFind(TSTRING& strFullPath, const TSTRING& strFilename) { bool fFoundFile = false; if (strFilename.empty()) return false; // // get the path environment variable // TCHAR* pszPathVar = getenv("PATH"); if (pszPathVar != NULL) { // // cycle over characters in path looking for the ':' // TSTRING strCurPath; TCHAR* pchTemp = pszPathVar; bool fMorePaths = true; do // while still more paths and haven't found file { // // are we at the ':'? // if (*pchTemp && *pchTemp != _T(':')) // if we're not at the end of the path { strCurPath += *pchTemp; } else // we have found the ':' { // // expand current path into a fully qualified path // if it's empty, use current directory // TSTRING strFP; if (strCurPath.empty()) strCurPath = _T("."); if (iFSServices::GetInstance()->FullPath(strFP, strCurPath)) strCurPath = strFP; // // put the file together with the path dir // TSTRING strFullName = strCurPath; util_TrailingSep(strFullName, true); strFullName += strFilename; // // the file must exist and be executable // if (util_FileIsExecutable(strFullName)) { strFullPath = strFullName; fFoundFile = true; } else strCurPath.erase(); // start over } // // keep searching if we're not at the end of the path string // if (*pchTemp) pchTemp++; else fMorePaths = false; } while (!fFoundFile && fMorePaths); } return (fFoundFile); }