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 &amp; ph );</code></p>
+
+<p><b>Precondition:</b> <code>!ph.leaf().empy()</code>
+<p><b>Returns:</b> if <code>ph.leaf()</code> contains a dot (&apos;.&apos;),
+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> &mdash;
+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 &amp; ph );</code></p>
+
+<p><b>Precondition:</b> <code>!ph.leaf().empy()</code>
+<p><b>Returns:</b> if <code>ph.leaf()</code> contains a dot (&apos;.&apos;),
+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 &amp; ph, const std::string &amp; new_extension );</code></p>
+
+<p><b>Precondition:</b> <code>!ph.leaf().empy()</code>
+<p><b>Postcondition:</b> <code>basename(return_value) == basename(ph)
+&amp;&amp; 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;
 }