diff options
author | Bill Hoffman <bill.hoffman@kitware.com> | 2004-10-13 15:37:55 (GMT) |
---|---|---|
committer | Bill Hoffman <bill.hoffman@kitware.com> | 2004-10-13 15:37:55 (GMT) |
commit | 78e8f12b86e7e4d21c8af1463a166341ba7398e7 (patch) | |
tree | b14ed6889636b1828e3aefe6012bc03883e969b9 /Source | |
parent | 68c3550faa5793a0445c457d65b2f491cee559df (diff) | |
download | CMake-78e8f12b86e7e4d21c8af1463a166341ba7398e7.zip CMake-78e8f12b86e7e4d21c8af1463a166341ba7398e7.tar.gz CMake-78e8f12b86e7e4d21c8af1463a166341ba7398e7.tar.bz2 |
BUG: fix and comment relative path funciton
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmSystemTools.cxx | 81 | ||||
-rw-r--r-- | Source/cmSystemTools.h | 10 |
2 files changed, 69 insertions, 22 deletions
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 5eef488..0fc6e34 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -1190,6 +1190,11 @@ std::vector<cmStdString> cmSystemTools::SplitString(const char* p, char sep) { std::string path = p; std::vector<cmStdString> paths; + if(path[0] == '/') + { + path.erase(path.begin()); + } + paths.push_back("/"); std::string::size_type pos1 = 0; std::string::size_type pos2 = path.find(sep, pos1+1); while(pos2 != std::string::npos) @@ -1207,14 +1212,17 @@ std::vector<cmStdString> cmSystemTools::SplitString(const char* p, char sep) // compute the relative path from here to there std::string cmSystemTools::RelativePath(const char* local, const char* remote) { -#ifdef _WIN32 - std::string lowerCaseLocal = cmSystemTools::LowerCase(std::string(local)); - std::string lowerCaseRemote = cmSystemTools::LowerCase(std::string(remote)); - remote = lowerCaseRemote.c_str(); - local = lowerCaseLocal.c_str(); -#endif + if(!cmSystemTools::FileIsFullPath(local)) + { + cmSystemTools::Error("RelativePath must be passed a full path to local: ", local); + } + if(!cmSystemTools::FileIsFullPath(remote)) + { + cmSystemTools::Error("RelativePath must be passed a full path to local: ", remote); + } + // check for driveletter: as the start of the path - // if not on the same drive then full path to remote must be used. + // if not on the same drive then full path to local must be used. if(local[0] && local[0] != '/') { if(remote[0] && local[0] != remote[0]) @@ -1224,31 +1232,62 @@ std::string cmSystemTools::RelativePath(const char* local, const char* remote) } std::string relativePath; // result string // split up both paths into arrays of strings using / as a separator - std::vector<cmStdString> fileSplit = cmSystemTools::SplitString(local); + std::vector<cmStdString> fileSplit = cmSystemTools::SplitString(local); std::vector<cmStdString> relativeSplit = cmSystemTools::SplitString(remote); - // count up how many mathing directory names there are from the start + std::vector<cmStdString> commonPath; + std::vector<cmStdString> finalPath; + // count up how many matching directory names there are from the start unsigned int sameCount = 0; - while(sameCount < fileSplit.size()-1 && sameCount < relativeSplit.size()-1 && - fileSplit[sameCount] == relativeSplit[sameCount]) + while( + ((sameCount <= (fileSplit.size()-1)) && (sameCount <= (relativeSplit.size()-1))) + && +// for windows and apple do a case insensitive string compare +#if defined(_WIN32) || defined(__APPLE__) + cmSystemTools::Strucmp(fileSplit[sameCount].c_str(), + relativeSplit[sameCount].c_str()) == 0 +#else + fileSplit[sameCount] == relativeSplit[sameCount] +#endif + ) { + // put the common parts of the path into the commonPath array + commonPath.push_back(fileSplit[sameCount]); + // erase the common parts of the path from the original path arrays + fileSplit[sameCount] = ""; + relativeSplit[sameCount] = ""; sameCount++; } - if(sameCount == 0) + + // for each entry that is not common in the local or file path + // add a ../ to the finalpath array + for(unsigned int i = 0; i < fileSplit.size(); ++i) { - return std::string(remote); + if(fileSplit[i].size()) + { + finalPath.push_back("../"); + } } - // put in sameCount number of ../ into the path - unsigned int i; - for(i = sameCount; i < fileSplit.size(); ++i) + // for each entry that is not common in the remote path add it + // to the final path + for(std::vector<cmStdString>::iterator i = relativeSplit.begin(); + i != relativeSplit.end(); ++i) { - relativePath += "../"; + if(i->size()) + { + finalPath.push_back(*i); + } } - // now put the rest of path that did not match back - for(i = sameCount; i < relativeSplit.size()-1; ++i) + // now turn the array of directories into a unix path by puttint / + // between each entry that does not already have one + for(std::vector<cmStdString>::iterator i = finalPath.begin(); + i != finalPath.end(); ++i) { - relativePath += relativeSplit[i] + "/"; + if(relativePath.size() && relativePath[relativePath.size()-1] != '/') + { + relativePath += "/"; + } + relativePath += *i; } - relativePath += relativeSplit[i]; return relativePath; } class cmDeletingCharVector : public std::vector<char*> diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index ad2fe43..a5046e4 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -269,8 +269,16 @@ public: static bool CreateSymlink(const char* origName, const char* newName); - ///! compute the relative path from local to remote + /** compute the relative path from local to remote. local must + be a directory. remote can be a file or a directory. + Both remote and local must be full paths. Basically, if + you are in directory local and you want to access the file in remote + what is the relative path to do that. For example: + /a/b/c/d to /a/b/c1/d1 -> ../../c1/d1 + from /usr/src to /usr/src/test/blah/foo.cpp -> test/blah/foo.cpp + */ static std::string RelativePath(const char* local, const char* remote); + ///! split a path by separator into an array of strings, default is / static std::vector<cmStdString> SplitString(const char* s, char separator = '/'); /** put a string into the environment |