[cmake-commits] king committed SystemTools.cxx 1.217 1.218
SystemTools.hxx.in 1.70 1.71
cmake-commits at cmake.org
cmake-commits at cmake.org
Fri Jan 11 08:33:50 EST 2008
Update of /cvsroot/CMake/CMake/Source/kwsys
In directory public:/mounts/ram/cvs-serv16541/Source/kwsys
Modified Files:
SystemTools.cxx SystemTools.hxx.in
Log Message:
ENH: Add SystemTools::SplitPathRootComponent and re-implement SplitPath to use it. Add better treatment of user home directory paths.
Index: SystemTools.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/kwsys/SystemTools.cxx,v
retrieving revision 1.217
retrieving revision 1.218
diff -u -d -r1.217 -r1.218
--- SystemTools.cxx 15 Dec 2007 01:31:27 -0000 1.217
+++ SystemTools.cxx 11 Jan 2008 13:33:48 -0000 1.218
@@ -2975,81 +2975,144 @@
}
//----------------------------------------------------------------------------
-void SystemTools::SplitPath(const char* p,
- kwsys_stl::vector<kwsys_stl::string>& components)
+const char* SystemTools::SplitPathRootComponent(const char* p,
+ kwsys_stl::string* root)
{
- components.clear();
// Identify the root component.
const char* c = p;
if((c[0] == '/' && c[1] == '/') || (c[0] == '\\' && c[1] == '\\'))
{
// Network path.
- components.push_back("//");
+ if(root)
+ {
+ *root = "//";
+ }
c += 2;
}
else if(c[0] == '/')
{
// Unix path.
- components.push_back("/");
+ if(root)
+ {
+ *root = "/";
+ }
c += 1;
}
else if(c[0] && c[1] == ':' && (c[2] == '/' || c[2] == '\\'))
{
// Windows path.
- kwsys_stl::string root = "_:/";
- root[0] = c[0];
- components.push_back(root);
+ if(root)
+ {
+ (*root) = "_:/";
+ (*root)[0] = c[0];
+ }
c += 3;
}
else if(c[0] && c[1] == ':')
{
// Path relative to a windows drive working directory.
- kwsys_stl::string root = "_:";
- root[0] = c[0];
- components.push_back(root);
+ if(root)
+ {
+ (*root) = "_:";
+ (*root)[0] = c[0];
+ }
c += 2;
}
-#ifdef HAVE_GETPWNAM
else if(c[0] == '~')
{
- int numChars = 1;
- while(c[numChars] && c[numChars] != '/')
+ // Home directory. The returned root should always have a
+ // trailing slash so that appending components as
+ // c[0]c[1]/c[2]/... works. The remaining path returned should
+ // skip the first slash if it exists:
+ //
+ // "~" : root = "~/" , return ""
+ // "~/ : root = "~/" , return ""
+ // "~/x : root = "~/" , return "x"
+ // "~u" : root = "~u/", return ""
+ // "~u/" : root = "~u/", return ""
+ // "~u/x" : root = "~u/", return "x"
+ int n = 1;
+ while(c[n] && c[n] != '/')
{
- numChars++;
+ ++n;
}
- const char* homedir;
- if(numChars == 1)
+ if(root)
{
- homedir = getenv("HOME");
+ root->assign(c, n);
+ *root += '/';
}
- else
+ if(c[n] == '/')
{
- char user[PATH_MAX];
- strncpy(user, c+1, numChars-1);
- user[numChars] = '\0';
- passwd* pw = getpwnam(user);
- if(p)
+ ++n;
+ }
+ c += n;
+ }
+ else
+ {
+ // Relative path.
+ if(root)
+ {
+ *root = "";
+ }
+ }
+
+ // Return the remaining path.
+ return c;
+}
+
+//----------------------------------------------------------------------------
+void SystemTools::SplitPath(const char* p,
+ kwsys_stl::vector<kwsys_stl::string>& components,
+ bool expand_home_dir)
+{
+ const char* c = p;
+ components.clear();
+
+ // Identify the root component.
+ {
+ kwsys_stl::string root;
+ c = SystemTools::SplitPathRootComponent(c, &root);
+
+ // Expand home directory references if requested.
+ if(expand_home_dir && !root.empty() && root[0] == '~')
+ {
+ kwsys_stl::string homedir;
+ root = root.substr(0, root.size()-1);
+ if(root.size() == 1)
+ {
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ if(const char* h = getenv("USERPROFILE"))
{
- homedir = pw->pw_dir;
+ homedir = h;
}
else
+#endif
+ if(const char* h = getenv("HOME"))
{
- homedir = "";
+ homedir = h;
+ }
+ }
+#ifdef HAVE_GETPWNAM
+ else if(passwd* pw = getpwnam(root.c_str()+1))
+ {
+ if(pw->pw_dir)
+ {
+ homedir = pw->pw_dir;
}
}
- kwsys_stl::vector<kwsys_stl::string> home_components;
- SystemTools::SplitPath(homedir, home_components);
- components.insert(components.end(),
- home_components.begin(),
- home_components.end());
- c += numChars;
- }
#endif
+ if(!homedir.empty() && (homedir[homedir.size()-1] == '/' ||
+ homedir[homedir.size()-1] == '\\'))
+ {
+ homedir = homedir.substr(0, homedir.size()-1);
+ }
+ SystemTools::SplitPath(homedir.c_str(), components);
+ }
else
{
- // Relative path.
- components.push_back("");
+ components.push_back(root);
}
+ }
// Parse the remaining components.
const char* first = c;
Index: SystemTools.hxx.in
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/kwsys/SystemTools.hxx.in,v
retrieving revision 1.70
retrieving revision 1.71
diff -u -d -r1.70 -r1.71
--- SystemTools.hxx.in 15 Dec 2007 01:31:27 -0000 1.70
+++ SystemTools.hxx.in 11 Jan 2008 13:33:48 -0000 1.71
@@ -351,20 +351,36 @@
const char* in_base);
/**
- * Split a path name into its basic components. The first component
- * is one of the following roots:
- * "/" = UNIX
+ * Split a path name into its root component and the rest of the
+ * path. The root component is one of the following:
+ * "/" = UNIX full path
* "c:/" = Windows full path (can be any drive letter)
* "c:" = Windows drive-letter relative path (can be any drive letter)
* "//" = Network path
+ * "~" = Home path for current user
+ * "~u" = Home path for user 'u'
* "" = Relative path
+ *
+ * A pointer to the rest of the path after the root component is
+ * returned. The root component is stored in the "root" string if
+ * given.
+ */
+ static const char* SplitPathRootComponent(const char* p,
+ kwsys_stl::string* root=0);
+
+ /**
+ * Split a path name into its basic components. The first component
+ * is one of the roots returned by SplitPathRootComponent.
* 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.
+ * produce the original path. Home directory references are
+ * automatically expanded if expand_home_dir is true and this
+ * platform supports them.
*/
static void SplitPath(const char* p,
- kwsys_stl::vector<kwsys_stl::string>& components);
+ kwsys_stl::vector<kwsys_stl::string>& components,
+ bool expand_home_dir = true);
/**
* Join components of a path name into a single string. See
More information about the Cmake-commits
mailing list