From 244901a5721d5bf5597ac71117e50b190337da44 Mon Sep 17 00:00:00 2001 From: Tim Shen Date: Wed, 17 Feb 2016 03:33:02 +0000 Subject: [PATCH] re PR libstdc++/69794 (std::regex_search match failure with regex object with flags grep|icase) 2016-02-16 Tim Shen PR libstdc++/69794 * include/bits/regex_scanner.h: Add different special character sets for grep and egrep regex. * include/bits/regex_scanner.tcc: Use _M_spec_char more uniformly. * testsuite/28_regex/regression.cc: Add new testcase. From-SVN: r233482 --- libstdc++-v3/ChangeLog | 8 ++++++++ libstdc++-v3/include/bits/regex_scanner.h | 15 ++++++++++++--- libstdc++-v3/include/bits/regex_scanner.tcc | 10 ++-------- libstdc++-v3/testsuite/28_regex/regression.cc | 16 ++++++++++++++++ 4 files changed, 38 insertions(+), 11 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 04dfebf43ac..be4e95cbb43 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,11 @@ +2016-02-16 Tim Shen + + PR libstdc++/69794 + * include/bits/regex_scanner.h: Add different special character + sets for grep and egrep regex. + * include/bits/regex_scanner.tcc: Use _M_spec_char more uniformly. + * testsuite/28_regex/regression.cc: Add new testcase. + 2016-02-08 Jonathan Wakely * acinclude.m4 (GLIBCXX_CHECK_MATH11_PROTO): Remove accidentally diff --git a/libstdc++-v3/include/bits/regex_scanner.h b/libstdc++-v3/include/bits/regex_scanner.h index bff73669756..37dea840d5b 100644 --- a/libstdc++-v3/include/bits/regex_scanner.h +++ b/libstdc++-v3/include/bits/regex_scanner.h @@ -95,11 +95,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : _M_awk_escape_tbl), _M_spec_char(_M_is_ecma() ? _M_ecma_spec_char - : _M_is_basic() + : _M_flags & regex_constants::basic ? _M_basic_spec_char - : _M_extended_spec_char), + : _M_flags & regex_constants::extended + ? _M_extended_spec_char + : _M_flags & regex_constants::grep + ? ".[\\*^$\n" + : _M_flags & regex_constants::egrep + ? ".[\\()*+?{|^$\n" + : _M_flags & regex_constants::awk + ? _M_extended_spec_char + : nullptr), _M_at_bracket_start(false) - { } + { __glibcxx_assert(_M_spec_char); } protected: const char* @@ -137,6 +145,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return _M_flags & regex_constants::awk; } protected: + // TODO: Make them static in the next abi change. const std::pair _M_token_tbl[9] = { {'^', _S_token_line_begin}, diff --git a/libstdc++-v3/include/bits/regex_scanner.tcc b/libstdc++-v3/include/bits/regex_scanner.tcc index 920cb146407..fedba09a713 100644 --- a/libstdc++-v3/include/bits/regex_scanner.tcc +++ b/libstdc++-v3/include/bits/regex_scanner.tcc @@ -97,9 +97,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_scan_normal() { auto __c = *_M_current++; - const char* __pos; - if (std::strchr(_M_spec_char, _M_ctype.narrow(__c, '\0')) == nullptr) + if (std::strchr(_M_spec_char, _M_ctype.narrow(__c, ' ')) == nullptr) { _M_token = _S_token_ord_char; _M_value.assign(1, __c); @@ -177,12 +176,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_state = _S_state_in_brace; _M_token = _S_token_interval_begin; } - else if (((__pos = std::strchr(_M_spec_char, _M_ctype.narrow(__c, '\0'))) - != nullptr - && *__pos != '\0' - && __c != ']' - && __c != '}') - || (_M_is_grep() && __c == '\n')) + else if (__c != ']' && __c != '}') { auto __it = _M_token_tbl; auto __narrowc = _M_ctype.narrow(__c, '\0'); diff --git a/libstdc++-v3/testsuite/28_regex/regression.cc b/libstdc++-v3/testsuite/28_regex/regression.cc index f95bef91760..c9a3402011e 100644 --- a/libstdc++-v3/testsuite/28_regex/regression.cc +++ b/libstdc++-v3/testsuite/28_regex/regression.cc @@ -33,10 +33,26 @@ test01() regex re("((.)", regex_constants::basic); } +void +test02() +{ + bool test __attribute__((unused)) = true; + + std::string re_str + { + "/abcd" "\n" + "/aecf" "\n" + "/ghci" + }; + auto rx = std::regex(re_str, std::regex_constants::grep | std::regex_constants::icase); + VERIFY(std::regex_search("/abcd", rx)); +} + int main() { test01(); + test02(); return 0; }