summaryrefslogtreecommitdiffstats
path: root/Source/kwsys/SystemTools.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/kwsys/SystemTools.cxx')
-rw-r--r--Source/kwsys/SystemTools.cxx133
1 files changed, 98 insertions, 35 deletions
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx
index 977133f..dbcf230 100644
--- a/Source/kwsys/SystemTools.cxx
+++ b/Source/kwsys/SystemTools.cxx
@@ -2975,81 +2975,144 @@ kwsys_stl::string SystemTools::GetActualCaseForPath(const char* p)
}
//----------------------------------------------------------------------------
-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] == '/')
+ {
+ ++n;
+ }
+ c += n;
+ }
+ else
+ {
+ // Relative path.
+ if(root)
{
- char user[PATH_MAX];
- strncpy(user, c+1, numChars-1);
- user[numChars] = '\0';
- passwd* pw = getpwnam(user);
- if(p)
+ *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;