|
Boost : |
From: John Torjo (john.lists_at_[hidden])
Date: 2004-03-13 02:23:55
Dear boosters,
I noticed that currently there's no way to get the relative path of path
A related to path B.
What I mean is, given two **complete** paths, to get the relative path
of one related to the other.
To give a real example, I have an application that starts in directory
initial_path().
I have several dialogs that allow the user to browse for files. My
requirement is, after the user browses for a file, to internally ALWAYS
store the path relative to initial_path().
Since there's no way to do this currently, I created my own function.
Do you think it could be a useful addition to filesystem library?
// converts the given path, making it relative to the src path
//
// precondition: dest & src are both complete
path relative_to( const path & dest, const path & src) {
// both paths should be complete
assert( dest.is_complete() && src.is_complete() );
path::iterator dest_begin = dest.begin(), dest_end = dest.end();
path::iterator src_begin = src.begin(), src_end = src.end();
path result;
#if defined(BOOST_WINDOWS)
//#if defined(WIN32)
if ( dest.root_name() != src.root_name() ) {
// paths are on different drives (like, "c:/test/t.txt" and
"d:/home")
return dest;
}
if ( src_begin != src_end) ++src_begin;
if ( dest_begin != dest_end) ++dest_begin;
#endif
// ignore directories that are same
while ( (src_begin != src_end) && (dest_begin != dest_end)) {
if ( *src_begin != *dest_begin)
break;
++src_begin, ++dest_begin;
}
// now, we begin to relativize
while ( src_begin != src_end) {
result /= "..";
++src_begin;
}
while ( dest_begin != dest_end) {
result /= *dest_begin;
++dest_begin;
}
return result;
}
void test_relative_to( const std::string & dest, const std::string & src) {
std::string result = relative_to( dest, src).string();
std::cout << "Testing path '" << dest << "',\n"
" relative to '" << src << "'\n"
" result : '" << result << "'\n" << std::endl;
}
int main(int argc, char* argv[])
{
path::default_name_check( &native);
test_relative_to( "c:/temp/test/inner/i2/file.txt", "c:/temp/test");
test_relative_to( "c:/temp/test/inner/i2/file.txt",
"c:/temp/test/other");
test_relative_to( "c:/temp/test/inner/i2/file.txt", "c:/temp");
test_relative_to( "c:/temp/test/inner/i2/file.txt", "c:/temp/test");
test_relative_to( "c:/temp/test", "c:/temp/test");
test_relative_to( "c:/temp/test/inner/i2/file.txt", "d:/temp/test");
test_relative_to( "c:/temp/test", "d:/temp/test");
test_relative_to( "c:/other/test/inner/i2/file.txt", "c:/temp/test");
test_relative_to( "c:/other/test/inner/i2/file.txt",
"c:/oth/test/other");
test_relative_to( "c:/other/test/inner/i2/file.txt", "c:/temp");
test_relative_to( "c:/other/test/inner/i2/file.txt", "c:/other/test");
return 0;
}
Best,
John
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk