summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/cmSystemTools.cxx92
-rw-r--r--Source/cmSystemTools.h9
-rw-r--r--Source/kwsys/SystemTools.cxx102
-rw-r--r--Source/kwsys/SystemTools.hxx.in18
4 files changed, 123 insertions, 98 deletions
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 425d2f5..52032f0 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -1225,29 +1225,6 @@ bool cmSystemTools::CreateSymlink(const char* origName, const char* newName)
#endif
-std::vector<cmStdString> cmSystemTools::SplitString(const char* p, char sep, bool isPath)
-{
- std::string path = p;
- std::vector<cmStdString> paths;
- if(isPath && 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)
- {
- paths.push_back(path.substr(pos1, pos2-pos1));
- pos1 = pos2+1;
- pos2 = path.find(sep, pos1+1);
- }
- paths.push_back(path.substr(pos1, pos2-pos1));
-
- return paths;
-}
-
-
// compute the relative path from here to there
std::string cmSystemTools::RelativePath(const char* local, const char* remote)
{
@@ -1259,74 +1236,9 @@ std::string cmSystemTools::RelativePath(const char* local, const char* remote)
{
cmSystemTools::Error("RelativePath must be passed a full path to remote: ", remote);
}
-
- // split up both paths into arrays of strings using / as a separator
- std::vector<cmStdString> localSplit = cmSystemTools::SplitString(local, '/', true);
- std::vector<cmStdString> remoteSplit = cmSystemTools::SplitString(remote, '/', true);
- std::vector<cmStdString> commonPath; // store shared parts of path in this array
- std::vector<cmStdString> finalPath; // store the final relative path here
- // count up how many matching directory names there are from the start
- unsigned int sameCount = 0;
- while(
- ((sameCount <= (localSplit.size()-1)) && (sameCount <= (remoteSplit.size()-1)))
- &&
-// for windows and apple do a case insensitive string compare
-#if defined(_WIN32) || defined(__APPLE__)
- cmSystemTools::Strucmp(localSplit[sameCount].c_str(),
- remoteSplit[sameCount].c_str()) == 0
-#else
- localSplit[sameCount] == remoteSplit[sameCount]
-#endif
- )
- {
- // put the common parts of the path into the commonPath array
- commonPath.push_back(localSplit[sameCount]);
- // erase the common parts of the path from the original path arrays
- localSplit[sameCount] = "";
- remoteSplit[sameCount] = "";
- sameCount++;
- }
- // If there is nothing in common but the root directory, then just
- // return the full path.
- if(sameCount <= 1)
- {
- return remote;
- }
-
- // for each entry that is not common in the local path
- // add a ../ to the finalpath array, this gets us out of the local
- // path into the remote dir
- for(unsigned int i = 0; i < localSplit.size(); ++i)
- {
- if(localSplit[i].size())
- {
- finalPath.push_back("../");
- }
- }
- // for each entry that is not common in the remote path add it
- // to the final path.
- for(std::vector<cmStdString>::iterator i = remoteSplit.begin();
- i != remoteSplit.end(); ++i)
- {
- if(i->size())
- {
- finalPath.push_back(*i);
- }
- }
- std::string relativePath; // result string
- // 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)
- {
- if(relativePath.size() && relativePath[relativePath.size()-1] != '/')
- {
- relativePath += "/";
- }
- relativePath += *i;
- }
- return relativePath;
+ return cmsys::SystemTools::RelativePath(local, remote);
}
+
class cmDeletingCharVector : public std::vector<char*>
{
public:
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h
index 2895fff..6c5be99 100644
--- a/Source/cmSystemTools.h
+++ b/Source/cmSystemTools.h
@@ -285,14 +285,7 @@ public:
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 /.
- If isPath is true then the string is treated like a path and if
- s starts with a / then the first element of the returned array will
- be /, so /foo/bar will be [/, foo, bar]
- */
- static std::vector<cmStdString> SplitString(const char* s, char separator = '/',
- bool isPath = false);
+
/** put a string into the environment
of the form var=value */
static bool PutEnv(const char* value);
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx
index ee59852..5da7606 100644
--- a/Source/kwsys/SystemTools.cxx
+++ b/Source/kwsys/SystemTools.cxx
@@ -1131,6 +1131,29 @@ kwsys_stl::string SystemTools::CropString(const kwsys_stl::string& s,
}
//----------------------------------------------------------------------------
+std::vector<kwsys::String> SystemTools::SplitString(const char* p, char sep, bool isPath)
+{
+ std::string path = p;
+ std::vector<kwsys::String> paths;
+ if(isPath && 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)
+ {
+ paths.push_back(path.substr(pos1, pos2-pos1));
+ pos1 = pos2+1;
+ pos2 = path.find(sep, pos1+1);
+ }
+ paths.push_back(path.substr(pos1, pos2-pos1));
+
+ return paths;
+}
+
+//----------------------------------------------------------------------------
int SystemTools::EstimateFormatLength(const char *format, va_list ap)
{
if (!format)
@@ -2395,6 +2418,85 @@ kwsys_stl::string SystemTools::CollapseFullPath(const char* in_path,
return newPath;
}
+// compute the relative path from here to there
+std::string SystemTools::RelativePath(const char* local, const char* remote)
+{
+ if(!SystemTools::FileIsFullPath(local))
+ {
+ return "";
+ }
+ if(!SystemTools::FileIsFullPath(remote))
+ {
+ return "";
+ }
+
+ // split up both paths into arrays of strings using / as a separator
+ std::vector<kwsys::String> localSplit = SystemTools::SplitString(local, '/', true);
+ std::vector<kwsys::String> remoteSplit = SystemTools::SplitString(remote, '/', true);
+ std::vector<kwsys::String> commonPath; // store shared parts of path in this array
+ std::vector<kwsys::String> finalPath; // store the final relative path here
+ // count up how many matching directory names there are from the start
+ unsigned int sameCount = 0;
+ while(
+ ((sameCount <= (localSplit.size()-1)) && (sameCount <= (remoteSplit.size()-1)))
+ &&
+// for windows and apple do a case insensitive string compare
+#if defined(_WIN32) || defined(__APPLE__)
+ cmSystemTools::Strucmp(localSplit[sameCount].c_str(),
+ remoteSplit[sameCount].c_str()) == 0
+#else
+ localSplit[sameCount] == remoteSplit[sameCount]
+#endif
+ )
+ {
+ // put the common parts of the path into the commonPath array
+ commonPath.push_back(localSplit[sameCount]);
+ // erase the common parts of the path from the original path arrays
+ localSplit[sameCount] = "";
+ remoteSplit[sameCount] = "";
+ sameCount++;
+ }
+ // If there is nothing in common but the root directory, then just
+ // return the full path.
+ if(sameCount <= 1)
+ {
+ return remote;
+ }
+
+ // for each entry that is not common in the local path
+ // add a ../ to the finalpath array, this gets us out of the local
+ // path into the remote dir
+ for(unsigned int i = 0; i < localSplit.size(); ++i)
+ {
+ if(localSplit[i].size())
+ {
+ finalPath.push_back("../");
+ }
+ }
+ // for each entry that is not common in the remote path add it
+ // to the final path.
+ for(std::vector<kwsys_stl::string>::iterator i = remoteSplit.begin();
+ i != remoteSplit.end(); ++i)
+ {
+ if(i->size())
+ {
+ finalPath.push_back(*i);
+ }
+ }
+ std::string relativePath; // result string
+ // now turn the array of directories into a unix path by puttint /
+ // between each entry that does not already have one
+ for(std::vector<kwsys_stl::string>::iterator i = finalPath.begin();
+ i != finalPath.end(); ++i)
+ {
+ if(relativePath.size() && relativePath[relativePath.size()-1] != '/')
+ {
+ relativePath += "/";
+ }
+ relativePath += *i;
+ }
+ return relativePath;
+}
// OK, some fun stuff to get the actual case of a given path.
// Basically, you just need to call ShortPath, then GetLongPathName,
diff --git a/Source/kwsys/SystemTools.hxx.in b/Source/kwsys/SystemTools.hxx.in
index 703f739..31bfa9a 100644
--- a/Source/kwsys/SystemTools.hxx.in
+++ b/Source/kwsys/SystemTools.hxx.in
@@ -20,6 +20,7 @@
#include <@KWSYS_NAMESPACE@/stl/map>
#include <@KWSYS_NAMESPACE@/Configure.h>
+#include <@KWSYS_NAMESPACE@/String.hxx>
#include <sys/types.h>
@@ -176,6 +177,13 @@ public:
*/
static kwsys_stl::string CropString(const kwsys_stl::string&,size_t max_len);
+ /** split a path by separator into an array of strings, default is /.
+ If isPath is true then the string is treated like a path and if
+ s starts with a / then the first element of the returned array will
+ be /, so /foo/bar will be [/, foo, bar]
+ */
+ static std::vector<String> SplitString(const char* s, char separator = '/',
+ bool isPath = false);
/**
* Perform a case-independent string comparison
*/
@@ -574,6 +582,16 @@ public:
static kwsys_stl::string FileExistsInParentDirectories(const char* fname,
const char* directory, const char* toplevel);
+ /** 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);
+
/**
* Return file's modified time
*/