re PR libstdc++/83601 (std::regex_replace C++14 conformance issue: escaping in SED mode)

PR libstdc++/83601
	* include/bits/regex.tcc (regex_replace): Fix escaping in sed.
	* testsuite/28_regex/algorithms/regex_replace/char/pr83601.cc: Tests.
	* testsuite/28_regex/algorithms/regex_replace/wchar_t/pr83601.cc: Tests.

From-SVN: r256654
This commit is contained in:
Tim Shen 2018-01-14 00:48:30 +00:00 committed by Tim Shen
parent 8bc5a5c57c
commit 8532713fc4
4 changed files with 103 additions and 16 deletions

View File

@ -1,3 +1,10 @@
2018-01-13 Tim Shen <timshen@google.com>
PR libstdc++/83601
* include/bits/regex.tcc (regex_replace): Fix escaping in sed.
* testsuite/28_regex/algorithms/regex_replace/char/pr83601.cc: Tests.
* testsuite/28_regex/algorithms/regex_replace/wchar_t/pr83601.cc: Tests.
2018-01-12 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
PR libstdc++/64054

View File

@ -373,22 +373,32 @@ namespace __detail
if (__flags & regex_constants::format_sed)
{
for (; __fmt_first != __fmt_last;)
if (*__fmt_first == '&')
{
__output(0);
++__fmt_first;
}
else if (*__fmt_first == '\\')
{
if (++__fmt_first != __fmt_last
&& __fctyp.is(__ctype_type::digit, *__fmt_first))
__output(__traits.value(*__fmt_first++, 10));
else
*__out++ = '\\';
}
else
*__out++ = *__fmt_first++;
bool __escaping = false;
for (; __fmt_first != __fmt_last; __fmt_first++)
{
if (__escaping)
{
__escaping = false;
if (__fctyp.is(__ctype_type::digit, *__fmt_first))
__output(__traits.value(*__fmt_first, 10));
else
*__out++ = *__fmt_first;
continue;
}
if (*__fmt_first == '\\')
{
__escaping = true;
continue;
}
if (*__fmt_first == '&')
{
__output(0);
continue;
}
*__out++ = *__fmt_first;
}
if (__escaping)
*__out++ = '\\';
}
else
{

View File

@ -0,0 +1,31 @@
// { dg-do run { target c++11 } }
// Copyright (C) 2018 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
//
#include <regex>
#include <testsuite_hooks.h>
// libstdc++/83601
int main() {
auto format = std::regex_constants::format_sed;
auto out = regex_replace("ab", std::regex("(a)(b)"), R"(\\1\&\\2)", format);
VERIFY(out == R"(\1&\2)");
return 0;
}

View File

@ -0,0 +1,39 @@
// { dg-do run { target c++11 } }
// Copyright (C) 2018 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
//
#include <regex>
#include <testsuite_hooks.h>
// libstdc++/83601
void frep(const wchar_t *istr, const wchar_t *rstr, const wchar_t *ostr) {
std::basic_regex<wchar_t> wrgx(L"(a*)(b+)");
std::basic_string<wchar_t> wstr = istr, wret = ostr, test;
std::regex_replace(std::back_inserter(test), wstr.begin(), wstr.end(),
wrgx, std::basic_string<wchar_t>(rstr),
std::regex_constants::format_sed);
VERIFY(test == wret);
}
int main() {
frep(L"xbbyabz", L"!\\\\2!", L"x!\\2!y!\\2!z");
frep(L"xbbyabz", L"!\\\\0!", L"x!\\0!y!\\0!z");
frep(L"xbbyabz", L"!\\&!", L"x!&!y!&!z");
return 0;
}