Selaa lähdekoodia

ENH: Move relative path to kwsys

Andy Cedilnik 20 vuotta sitten
vanhempi
sitoutus
e5a8e115bc
4 muutettua tiedostoa jossa 123 lisäystä ja 98 poistoa
  1. 2 90
      Source/cmSystemTools.cxx
  2. 1 8
      Source/cmSystemTools.h
  3. 102 0
      Source/kwsys/SystemTools.cxx
  4. 18 0
      Source/kwsys/SystemTools.hxx.in

+ 2 - 90
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:

+ 1 - 8
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);

+ 102 - 0
Source/kwsys/SystemTools.cxx

@@ -1130,6 +1130,29 @@ kwsys_stl::string SystemTools::CropString(const kwsys_stl::string& s,
   return n;
 }
 
+//----------------------------------------------------------------------------
+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)
 {
@@ -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,

+ 18 - 0
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
    */