Commit 9c536590 by Jonathan Wakely Committed by Jonathan Wakely

PR libstdc++/89117 fix path::replace_extension("") case

Previously the operator+=(extension) call would have re-parsed the path
and recreated the components with the right extension. Since optimising
it to not re-parse the whole string, we need to actually remove the
extension from the final filename before appending anything to it, and
append the dot to that final component too.

	PR libstdc++/89117
	* src/c++17/fs_path.cc (path::replace_extension): Erase extension from
	final component as well as from _M_pathname. Append the dot using
	operator+= instead of only to _M_pathname.
	(path::_M_find_extension): Reformat slightly.
	* testsuite/27_io/filesystem/path/modifiers/replace_extension.cc:
	Add more test cases.

From-SVN: r268406
parent d1ac2471
2019-01-30 Jonathan Wakely <jwakely@redhat.com>
PR libstdc++/89117
* src/c++17/fs_path.cc (path::replace_extension): Erase extension from
final component as well as from _M_pathname. Append the dot using
operator+= instead of only to _M_pathname.
(path::_M_find_extension): Reformat slightly.
* testsuite/27_io/filesystem/path/modifiers/replace_extension.cc:
Add more test cases.
2019-01-30 Ulrich Drepper <drepper@redhat.com>
* doc/xml/manual/status_cxx2020.xml: Update P0600 entry.
......
......@@ -1258,17 +1258,16 @@ path::replace_extension(const path& replacement)
_M_pathname.erase(ext.second);
else
{
const auto& back = _M_cmpts.back();
if (ext.first != &back._M_pathname)
_GLIBCXX_THROW_OR_ABORT(
std::logic_error("path::replace_extension failed"));
auto& back = _M_cmpts.back();
__glibcxx_assert( ext.first == &back._M_pathname );
back._M_pathname.erase(ext.second);
_M_pathname.erase(back._M_pos + ext.second);
}
}
// If replacement is not empty and does not begin with a dot character,
// a dot character is appended
if (!replacement.empty() && replacement.native()[0] != dot)
_M_pathname += dot;
operator+=(".");
operator+=(replacement);
return *this;
}
......@@ -1803,8 +1802,9 @@ path::_M_find_extension() const
{
if (sz <= 2 && (*s)[0] == dot)
return { s, string_type::npos };
const auto pos = s->rfind(dot);
return { s, pos ? pos : string_type::npos };
if (const auto pos = s->rfind(dot))
return { s , pos };
return { s, string_type::npos };
}
}
return {};
......
......@@ -33,6 +33,15 @@ test01()
compare_paths( path("/foo.txt").replace_extension("cpp"), "/foo.cpp" );
compare_paths( path("/foo.txt").replace_extension(".cpp"), "/foo.cpp" );
compare_paths( path("/").replace_extension("bar"), "/.bar" );
compare_paths( path("/").replace_extension(".bar"), "/.bar" );
compare_paths( path("/dir/").replace_extension("bar"), "/dir/.bar" );
compare_paths( path("dir/foo").replace_extension("bar"), "dir/foo.bar" );
// PR 89117:
compare_paths( path("/foo.txt").replace_extension(), "/foo" );
compare_paths( path("foo.txt").replace_extension(), "foo" );
compare_paths( path("/foo").replace_extension(), "/foo" );
compare_paths( path("foo").replace_extension(), "foo" );
}
void
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment