Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Chuck Atkins
KWSys
Commits
b913e6d6
Commit
b913e6d6
authored
Feb 07, 2006
by
Andy Cedilnik
Browse files
ENH: Move relative path to kwsys
parent
f5164880
Changes
2
Hide whitespace changes
Inline
Side-by-side
SystemTools.cxx
View file @
b913e6d6
...
...
@@ -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,
...
...
SystemTools.hxx.in
View file @
b913e6d6
...
...
@@ -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
*/
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment