ENH: Added SystemTools::SplitPath method to split any file path into its basic components.

This commit is contained in:
Brad King 2005-02-10 10:32:53 -05:00
parent 52a6bb1bca
commit 4bf8aa6293
4 changed files with 82 additions and 66 deletions

View File

@ -2306,7 +2306,7 @@ cmLocalUnixMakefileGenerator2::ConvertToRelativePath(const char* p)
// Identify the longest shared path component between the given path // Identify the longest shared path component between the given path
// and the current output directory. // and the current output directory.
std::vector<std::string> path; std::vector<std::string> path;
this->SplitFullPath(p, path); cmSystemTools::SplitPath(p, path);
unsigned int common=0; unsigned int common=0;
while(common < path.size() && while(common < path.size() &&
common < m_CurrentOutputDirectoryComponents.size() && common < m_CurrentOutputDirectoryComponents.size() &&
@ -2397,8 +2397,8 @@ cmLocalUnixMakefileGenerator2::ConfigureOutputPaths()
// directory and the build directory. // directory and the build directory.
std::vector<std::string> source; std::vector<std::string> source;
std::vector<std::string> binary; std::vector<std::string> binary;
this->SplitFullPath(m_HomeDirectory.c_str(), source); cmSystemTools::SplitPath(m_HomeDirectory.c_str(), source);
this->SplitFullPath(m_HomeOutputDirectory.c_str(), binary); cmSystemTools::SplitPath(m_HomeOutputDirectory.c_str(), binary);
unsigned int common=0; unsigned int common=0;
while(common < source.size() && common < binary.size() && while(common < source.size() && common < binary.size() &&
this->ComparePath(source[common].c_str(), binary[common].c_str())) this->ComparePath(source[common].c_str(), binary[common].c_str()))
@ -2427,68 +2427,8 @@ cmLocalUnixMakefileGenerator2::ConfigureOutputPaths()
// Split the current output directory now to save time when // Split the current output directory now to save time when
// converting paths. // converting paths.
this->SplitFullPath(m_CurrentOutputDirectory.c_str(), cmSystemTools::SplitPath(m_CurrentOutputDirectory.c_str(),
m_CurrentOutputDirectoryComponents); m_CurrentOutputDirectoryComponents);
}
}
//----------------------------------------------------------------------------
void
cmLocalUnixMakefileGenerator2
::SplitFullPath(const char* p, std::vector<std::string>& components)
{
// The path is split into its basic components. This starts with a
// root ("/" for UNIX, "c:/" for Windows, "//" for Network) and is
// followed by the directory names. If there is a trailing slash
// then the last component is the empty string. The components can
// be recombined as "c[0]c[1]/c[2]/.../c[n]".
assert(cmSystemTools::FileIsFullPath(p));
// Identify the root component.
const char* c = p;
if(c[0] == '/' && c[1] == '/')
{
// Network path.
components.push_back("//");
c += 2;
}
else if(c[0] == '/')
{
// Unix path.
components.push_back("/");
c += 1;
}
else if(c[0] && c[1] == ':' && c[2] == '/')
{
// Windows path.
std::string root = "_:/";
root[0] = c[0];
components.push_back(root);
c += 3;
}
else
{
// Already a relative path.
cmSystemTools::Error("SplitFullPath called with path ", p);
return;
}
// Parse the remaining components.
const char* first = c;
const char* last = first;
for(;*last; ++last)
{
if(*last == '/')
{
// End of a component. Save it.
components.push_back(std::string(first, last-first));
first = last+1;
}
}
// Save the last component unless there were no components.
if(last != c)
{
components.push_back(std::string(first, last-first));
} }
} }

View File

@ -166,7 +166,6 @@ protected:
std::string ConvertToRelativePath(const char* p); std::string ConvertToRelativePath(const char* p);
std::string ConvertToRelativeOutputPath(const char* p); std::string ConvertToRelativeOutputPath(const char* p);
virtual void ConfigureOutputPaths(); virtual void ConfigureOutputPaths();
void SplitFullPath(const char* p, std::vector<std::string>& components);
bool ComparePath(const char* c1, const char* c2); bool ComparePath(const char* c1, const char* c2);
void AppendTargetDepends(std::vector<std::string>& depends, void AppendTargetDepends(std::vector<std::string>& depends,

View File

@ -1614,6 +1614,66 @@ kwsys_stl::string SystemTools::CollapseFullPath(const char* in_relative,
return newPath; return newPath;
} }
//----------------------------------------------------------------------------
void SystemTools::SplitPath(const char* p,
kwsys_stl::vector<kwsys_stl::string>& components)
{
// Identify the root component.
const char* c = p;
if(c[0] == '/' && c[1] == '/')
{
// Network path.
components.push_back("//");
c += 2;
}
else if(c[0] == '/')
{
// Unix path.
components.push_back("/");
c += 1;
}
else if(c[0] && c[1] == ':' && c[2] == '/')
{
// Windows path.
std::string root = "_:/";
root[0] = c[0];
components.push_back(root);
c += 3;
}
else if(c[0] && c[1] == ':')
{
// Path relative to a windows drive working directory.
std::string root = "_:";
root[0] = c[0];
components.push_back(root);
c += 2;
}
else
{
// Relative path.
components.push_back("");
}
// Parse the remaining components.
const char* first = c;
const char* last = first;
for(;*last; ++last)
{
if(*last == '/')
{
// End of a component. Save it.
components.push_back(std::string(first, last-first));
first = last+1;
}
}
// Save the last component unless there were no components.
if(last != c)
{
components.push_back(std::string(first, last-first));
}
}
bool SystemTools::Split(const char* str, kwsys_stl::vector<kwsys_stl::string>& lines) bool SystemTools::Split(const char* str, kwsys_stl::vector<kwsys_stl::string>& lines)
{ {
kwsys_stl::string data(str); kwsys_stl::string data(str);

View File

@ -238,6 +238,23 @@ public:
static kwsys_stl::string CollapseFullPath(const char* in_relative, static kwsys_stl::string CollapseFullPath(const char* in_relative,
const char* in_base); const char* in_base);
/**
* Split a path name into its basic components. The first component
* is one of the following roots:
* "/" = UNIX
* "c:/" = Windows full path (can be any drive letter)
* "c:" = Windows drive-letter relative path (can be any drive letter)
* "//" = Network path
* "" = Relative path
* The remaining components form the path. If there is a trailing
* slash then the last component is the empty string. The
* components can be recombined as "c[0]c[1]/c[2]/.../c[n]" to
* produce the original path. The input is assumed to be formatted
* with forward slashes.
*/
static void SplitPath(const char* p,
kwsys_stl::vector<kwsys_stl::string>& components);
///! return path of a full filename (no trailing slashes). ///! return path of a full filename (no trailing slashes).
static kwsys_stl::string GetFilenamePath(const kwsys_stl::string&); static kwsys_stl::string GetFilenamePath(const kwsys_stl::string&);