Index: boost/filesystem/convenience.hpp =================================================================== RCS file: /cvsroot/boost/boost/boost/filesystem/convenience.hpp,v retrieving revision 1.1 diff -u -r1.1 convenience.hpp --- boost/filesystem/convenience.hpp 18 Dec 2002 17:05:19 -0000 1.1 +++ boost/filesystem/convenience.hpp 25 Apr 2003 07:18:10 -0000 @@ -31,6 +31,12 @@ */ void create_directories(const path& ph); + std::string extension(const path& ph); + + std::string basename(const path& ph); + + path change_extension(const path& ph, const std::string& new_extension); + } // namespace filesystem } // namespace boost #endif // BOOST_FILESYSTEM_CONVENIENCE_HPP Index: libs/filesystem/doc/convenience.htm =================================================================== RCS file: /cvsroot/boost/boost/libs/filesystem/doc/convenience.htm,v retrieving revision 1.3 diff -u -r1.3 convenience.htm --- libs/filesystem/doc/convenience.htm 23 Dec 2002 20:09:06 -0000 1.3 +++ libs/filesystem/doc/convenience.htm 25 Apr 2003 07:18:10 -0000 @@ -24,6 +24,9 @@ <dl class="index"> <dt><a href="#create_directories">create_directories</a> +<dt><a href="#extension">extension</a> +<dt><a href="#basename">basename</a> +<dt><a href="#change_extension">change_extension</a> </ol> <h2 id="create_directoies">create_directories</h2> @@ -40,6 +43,61 @@ <p>Contributed by Vladimir Prus.</p> </blockquote> + +<h2 id="extension">extension</h2> + +<blockquote> + +<p><code>std::string extension( const path & ph );</code></p> + +<p><b>Precondition:</b> <code>!ph.leaf().empy()</code> +<p><b>Returns:</b> if <code>ph.leaf()</code> contains a dot ('.'), +returns the substring of <code>ph.leaf()</code> starting from the last dot and +ending at the string's end. Otherwise, returns empty string. +<p><b>Rationale:</b> <ul> +<li>The dot is included in the return value so that it's +possible to tell if extension is empty or absent. +<li>It was noted that this defintion of extension is probably not sufficient +when using <a href="http://tinyurl.com/9tih">Alternate Data Streams</a> — +a filesystem feature specific to NTFS. However, semantic in this case was not +clear, and the current one is quite usefull still. +</ul> +<p><b>Acknowlegements:</b> Carl Daniel and Pavel Vozenilek noticed and +discussed the ADS issue. + +</blockquote> + +<h2 id="basename">basename</h2> + +<blockquote> + +<p><code>std::string basename( const path & ph );</code></p> + +<p><b>Precondition:</b> <code>!ph.leaf().empy()</code> +<p><b>Returns:</b> if <code>ph.leaf()</code> contains a dot ('.'), +returns the substring of <code>ph.leaf()</code> starting from beginning and +ending at the last dot (the dot is not included). Otherwise, returns +<code>ph.leaf()</code> + +</p> +</blockquote> + +<h2 id="change_extension">change_extension</h2> + +<blockquote> + +<p><code>path basename( const path & ph, const std::string & new_extension );</code></p> + +<p><b>Precondition:</b> <code>!ph.leaf().empy()</code> +<p><b>Postcondition:</b> <code>basename(return_value) == basename(ph) +&& extension(return_value) == new_extension</code> +<p><b>Note:</b> It follows from the semantic of <code>extension</code> that +<code>new_extension</code> should include dot. + +</p> +</blockquote> + + <hr> <p>� Copyright Beman Dawes, 2002</p> Index: libs/filesystem/src/convenience.cpp =================================================================== RCS file: /cvsroot/boost/boost/libs/filesystem/src/convenience.cpp,v retrieving revision 1.1 diff -u -r1.1 convenience.cpp --- libs/filesystem/src/convenience.cpp 18 Dec 2002 17:05:58 -0000 1.1 +++ libs/filesystem/src/convenience.cpp 25 Apr 2003 07:18:10 -0000 @@ -10,6 +10,7 @@ // See http://www.boost.org/libs/filesystem for documentation. #include <boost/filesystem/convenience.hpp> +#include <cassert> namespace boost { @@ -27,6 +28,33 @@ // Now that parent's path exists, create the directory create_directory(ph); } + + std::string extension(const path& ph) + { + std::string leaf = ph.leaf(); + assert(!leaf.empty()); + + std::string::size_type n = leaf.rfind('.'); + if (n != std::string::npos) + return leaf.substr(n); + else + return std::string(); + } + + std::string basename(const path& ph) + { + std::string leaf = ph.leaf(); + assert(!leaf.empty()); + + std::string::size_type n = leaf.rfind('.'); + return leaf.substr(0, n); + } + + path change_extension(const path& ph, const std::string& new_extension) + { + return ph.branch_path() / (basename(ph) + new_extension); + } + } // namespace filesystem } // namespace boost Index: libs/filesystem/test/convenience_test.cpp =================================================================== RCS file: /cvsroot/boost/boost/libs/filesystem/test/convenience_test.cpp,v retrieving revision 1.1 diff -u -r1.1 convenience_test.cpp --- libs/filesystem/test/convenience_test.cpp 18 Dec 2002 17:09:08 -0000 1.1 +++ libs/filesystem/test/convenience_test.cpp 25 Apr 2003 07:18:10 -0000 @@ -35,6 +35,29 @@ BOOST_TEST( fs::is_directory( "xx" ) ); BOOST_TEST( fs::is_directory( "xx/ww" ) ); BOOST_TEST( fs::is_directory( "xx/ww/zz" ) ); + +// extension() tests ----------------------------------------------------------// + + BOOST_TEST( fs::extension("a/b") == "" ); + BOOST_TEST( fs::extension("a/b.txt") == ".txt"); + BOOST_TEST( fs::extension("a/b.") == "."); + BOOST_TEST( fs::extension("a.b.c") == ".c"); + BOOST_TEST( fs::extension("a.b.c.") == "."); + +// basename() tests ----------------------------------------------------------// + + BOOST_TEST( fs::basename("b") == "b" ); + BOOST_TEST( fs::basename("a/b.txt") == "b" ); + BOOST_TEST( fs::basename("a/b.") == "b" ); + BOOST_TEST( fs::basename("a.b.c") == "a.b" ); + BOOST_TEST( fs::basename("a.b.c.") == "a.b.c" ); + +// change_extension tests ---------------------------------------------------// + + BOOST_TEST( fs::change_extension("a.txt", ".tex").string() == "a.tex" ); + BOOST_TEST( fs::change_extension("a.", ".tex").string() == "a.tex" ); + BOOST_TEST( fs::change_extension("a", ".txt").string() == "a.txt" ); + BOOST_TEST( fs::change_extension("a.b.txt", ".tex").string() == "a.b.tex" ); return 0; }