mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			307 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			307 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
	
// -*- C++ -*-
 | 
						|
// regex utils for the C++ library testsuite.
 | 
						|
//
 | 
						|
// Copyright (C) 2012-2016 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/>.
 | 
						|
//
 | 
						|
 | 
						|
#ifndef _TESTSUITE_REGEX_H
 | 
						|
#define _TESTSUITE_REGEX_H 1
 | 
						|
 | 
						|
#include <regex>
 | 
						|
#include <stdexcept>
 | 
						|
#include <iostream>
 | 
						|
 | 
						|
namespace __gnu_test
 | 
						|
{
 | 
						|
  // Test on a compilation of simple expressions, throw regex_error on error.
 | 
						|
  typedef std::regex				regex_type;
 | 
						|
  typedef regex_type::flag_type			flag_type;
 | 
						|
  typedef std::regex_constants::match_flag_type	match_flag_type;
 | 
						|
  typedef std::regex_constants::error_type	error_type;
 | 
						|
  typedef std::size_t				size_type;
 | 
						|
  typedef std::string				string_type;
 | 
						|
  using std::basic_regex;
 | 
						|
  using std::match_results;
 | 
						|
 | 
						|
  // Utilities
 | 
						|
  struct regex_expected_fail { };
 | 
						|
 | 
						|
  const error_type regex_error_internal(static_cast<error_type>(-1));
 | 
						|
 | 
						|
  // Stringify error codes for text logging.
 | 
						|
  const char* regex_error_codes[] =
 | 
						|
    {
 | 
						|
    "error_collate",
 | 
						|
    "error_ctype",
 | 
						|
    "error_escape",
 | 
						|
    "error_backref",
 | 
						|
    "error_brack",
 | 
						|
    "error_paren",
 | 
						|
    "error_brace",
 | 
						|
    "error_badbrace",
 | 
						|
    "error_range",
 | 
						|
    "error_space",
 | 
						|
    "error_badrepeat",
 | 
						|
    "error_complexity",
 | 
						|
    "error_stack"
 | 
						|
  };
 | 
						|
 | 
						|
  void
 | 
						|
  show_regex_error_codes()
 | 
						|
  {
 | 
						|
    using namespace std;
 | 
						|
    using namespace std::regex_constants;
 | 
						|
    const char tab('\t');
 | 
						|
    cout << "error_collate =   " << tab << error_collate << endl;
 | 
						|
    cout << "error_ctype =     " << tab << error_ctype << endl;
 | 
						|
    cout << "error_escape =    " << tab << error_escape << endl;
 | 
						|
    cout << "error_backref =   " << tab << error_backref << endl;
 | 
						|
    cout << "error_brack =     " << tab << error_brack << endl;
 | 
						|
    cout << "error_paren =     " << tab << error_paren << endl;
 | 
						|
    cout << "error_brace =     " << tab << error_brace << endl;
 | 
						|
    cout << "error_badbrace =  " << tab << error_badbrace << endl;
 | 
						|
    cout << "error_range =     " << tab << error_range << endl;
 | 
						|
    cout << "error_space =     " << tab << error_space << endl;
 | 
						|
    cout << "error_badrepeat = " << tab << error_badrepeat << endl;
 | 
						|
    cout << "error_complexity =" << tab << error_complexity << endl;
 | 
						|
    cout << "error_stack =     " << tab << error_stack << endl;
 | 
						|
  }
 | 
						|
 | 
						|
  // Arguments
 | 
						|
  // string __res: the regular expression string
 | 
						|
  // flag_type __f: flag
 | 
						|
  // __error: expected error, if any
 | 
						|
  void
 | 
						|
  regex_sanity_check(const string_type& __res,
 | 
						|
		     flag_type __f = regex_type::basic,
 | 
						|
		     error_type __error =  regex_error_internal)
 | 
						|
  {
 | 
						|
    using namespace std;
 | 
						|
 | 
						|
    try
 | 
						|
      {
 | 
						|
	regex_type reo(__res, __f);
 | 
						|
	auto n = reo.mark_count();
 | 
						|
	cout << "regex_type::mark_count " << n << endl;
 | 
						|
      }
 | 
						|
    catch (const regex_error& e)
 | 
						|
      {
 | 
						|
	cout << "regex_sanity_check: "  << __res << endl;
 | 
						|
	cout << "regex_error::what " << e.what() << endl;
 | 
						|
 | 
						|
	show_regex_error_codes();
 | 
						|
	cout << "regex_error::code " << regex_error_codes[e.code()] << endl;
 | 
						|
 | 
						|
	if (__error != regex_error_internal)
 | 
						|
	  {
 | 
						|
	    // Then expected error_type is __error. Check.
 | 
						|
	    if (__error != e.code())
 | 
						|
	      {
 | 
						|
		throw regex_expected_fail();
 | 
						|
	      }
 | 
						|
	  }
 | 
						|
	throw;
 | 
						|
      }
 | 
						|
    catch (const logic_error& e)
 | 
						|
      {
 | 
						|
	cout << "logic_error::what " << e.what() << endl;
 | 
						|
	throw;
 | 
						|
      }
 | 
						|
    catch (const std::exception& e)
 | 
						|
      {
 | 
						|
	cout << "exception: " << endl;
 | 
						|
	throw;
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  // regex_match_debug behaves like regex_match, but will run *two* executors
 | 
						|
  // (if there's no back-reference) and check if their results agree. If not,
 | 
						|
  // an exception is thrown. The arguments are the same as for regex_match.
 | 
						|
  template<typename _Bi_iter, typename _Alloc,
 | 
						|
	   typename _Ch_type, typename _Rx_traits>
 | 
						|
    bool
 | 
						|
    regex_match_debug(_Bi_iter                                 __s,
 | 
						|
		      _Bi_iter                                 __e,
 | 
						|
		      match_results<_Bi_iter, _Alloc>&         __m,
 | 
						|
		      const basic_regex<_Ch_type, _Rx_traits>& __re,
 | 
						|
		      match_flag_type                          __flags
 | 
						|
		      = std::regex_constants::match_default)
 | 
						|
    {
 | 
						|
      using namespace std::__detail;
 | 
						|
      auto __res1 = __regex_algo_impl<_Bi_iter, _Alloc, _Ch_type, _Rx_traits,
 | 
						|
	   _RegexExecutorPolicy::_S_auto, true>
 | 
						|
	(__s, __e, __m, __re, __flags);
 | 
						|
      match_results<_Bi_iter, _Alloc> __mm;
 | 
						|
      auto __res2 = __regex_algo_impl<_Bi_iter, _Alloc, _Ch_type, _Rx_traits,
 | 
						|
	   _RegexExecutorPolicy::_S_alternate, true>
 | 
						|
	(__s, __e, __mm, __re, __flags);
 | 
						|
      // __m is unspecified if return value is false.
 | 
						|
      if (__res1 == __res2 && (!__res1 || __m == __mm))
 | 
						|
	return __res1;
 | 
						|
      throw std::exception();
 | 
						|
    }
 | 
						|
 | 
						|
  // No match_results version
 | 
						|
  template<typename _Bi_iter, typename _Ch_type, typename _Rx_traits>
 | 
						|
    inline bool
 | 
						|
    regex_match_debug(_Bi_iter                                 __first,
 | 
						|
		      _Bi_iter                                 __last,
 | 
						|
		      const basic_regex<_Ch_type, _Rx_traits>& __re,
 | 
						|
		      match_flag_type                          __flags
 | 
						|
		      = std::regex_constants::match_default)
 | 
						|
    {
 | 
						|
      match_results<_Bi_iter> __what;
 | 
						|
      return regex_match_debug(__first, __last, __what, __re, __flags);
 | 
						|
    }
 | 
						|
 | 
						|
  // C-string version
 | 
						|
  template<typename _Ch_type, typename _Alloc, typename _Rx_traits>
 | 
						|
    inline bool
 | 
						|
    regex_match_debug(const _Ch_type*                          __s,
 | 
						|
		      match_results<const _Ch_type*, _Alloc>&  __m,
 | 
						|
		      const basic_regex<_Ch_type, _Rx_traits>& __re,
 | 
						|
		      match_flag_type                          __f
 | 
						|
		      = std::regex_constants::match_default)
 | 
						|
      { return regex_match_debug(__s, __s + _Rx_traits::length(__s),
 | 
						|
				 __m, __re, __f); }
 | 
						|
 | 
						|
  // C-string version without match_results
 | 
						|
  template<typename _Ch_type, class _Rx_traits>
 | 
						|
    inline bool
 | 
						|
    regex_match_debug(const _Ch_type*                          __s,
 | 
						|
		      const basic_regex<_Ch_type, _Rx_traits>& __re,
 | 
						|
		      match_flag_type                          __f
 | 
						|
		      = std::regex_constants::match_default)
 | 
						|
      { return regex_match_debug(__s, __s + _Rx_traits::length(__s),
 | 
						|
				 __re, __f); }
 | 
						|
 | 
						|
  // std::basic_string version
 | 
						|
  template<typename _Ch_traits, typename _Ch_alloc,
 | 
						|
           typename _Alloc, typename _Ch_type, typename _Rx_traits>
 | 
						|
    inline bool
 | 
						|
    regex_match_debug(const std::basic_string<_Ch_type, _Ch_traits,
 | 
						|
			_Ch_alloc>& __s,
 | 
						|
		      match_results<typename std::basic_string<_Ch_type,
 | 
						|
			_Ch_traits, _Ch_alloc>::const_iterator,
 | 
						|
			_Alloc>& __m,
 | 
						|
		      const basic_regex<_Ch_type, _Rx_traits>& __re,
 | 
						|
		      match_flag_type                          __flags
 | 
						|
		      = std::regex_constants::match_default)
 | 
						|
      { return regex_match_debug(__s.begin(), __s.end(),
 | 
						|
				 __m, __re, __flags); }
 | 
						|
 | 
						|
  // std::basic_string version without match_results
 | 
						|
  template<typename _Ch_traits, typename _Str_allocator,
 | 
						|
           typename _Ch_type, typename _Rx_traits>
 | 
						|
    inline bool
 | 
						|
    regex_match_debug(const std::basic_string<_Ch_type, _Ch_traits,
 | 
						|
		      _Str_allocator>&                         __s,
 | 
						|
		      const basic_regex<_Ch_type, _Rx_traits>& __re,
 | 
						|
		      match_flag_type                          __flags
 | 
						|
		      = std::regex_constants::match_default)
 | 
						|
    { return regex_match_debug(__s.begin(), __s.end(), __re, __flags); }
 | 
						|
 | 
						|
  // regex_match_debug behaves like regex_match, but will run *two* executors
 | 
						|
  // (if there's no back-reference) and check if their results agree. If not,
 | 
						|
  // an exception throws. One can use them just in the way of using regex_match.
 | 
						|
  template<typename _Bi_iter, typename _Alloc,
 | 
						|
           typename _Ch_type, typename _Rx_traits>
 | 
						|
    bool
 | 
						|
    regex_search_debug(_Bi_iter                                 __s,
 | 
						|
		       _Bi_iter                                 __e,
 | 
						|
		       match_results<_Bi_iter, _Alloc>&         __m,
 | 
						|
		       const basic_regex<_Ch_type, _Rx_traits>& __re,
 | 
						|
		       match_flag_type   __flags
 | 
						|
		       = std::regex_constants::match_default)
 | 
						|
    {
 | 
						|
      using namespace std::__detail;
 | 
						|
      auto __res1 = __regex_algo_impl<_Bi_iter, _Alloc, _Ch_type, _Rx_traits,
 | 
						|
	   _RegexExecutorPolicy::_S_auto, false>
 | 
						|
        (__s, __e, __m, __re, __flags);
 | 
						|
      match_results<_Bi_iter, _Alloc> __mm;
 | 
						|
      auto __res2 = __regex_algo_impl<_Bi_iter, _Alloc, _Ch_type, _Rx_traits,
 | 
						|
	   _RegexExecutorPolicy::_S_alternate, false>
 | 
						|
        (__s, __e, __mm, __re, __flags);
 | 
						|
      if (__res1 == __res2 && __m == __mm)
 | 
						|
        return __res1;
 | 
						|
      throw(std::exception()); // Let test fail. Give it a name.
 | 
						|
    }
 | 
						|
 | 
						|
  // No match_results version
 | 
						|
  template<typename _Bi_iter, typename _Ch_type, typename _Rx_traits>
 | 
						|
    inline bool
 | 
						|
    regex_search_debug(_Bi_iter                                 __first,
 | 
						|
		       _Bi_iter                                 __last,
 | 
						|
		       const basic_regex<_Ch_type, _Rx_traits>& __re,
 | 
						|
		       match_flag_type                          __flags
 | 
						|
		       = std::regex_constants::match_default)
 | 
						|
    {
 | 
						|
      match_results<_Bi_iter> __what;
 | 
						|
      return regex_search_debug(__first, __last, __what, __re, __flags);
 | 
						|
    }
 | 
						|
 | 
						|
  // C-string version
 | 
						|
  template<typename _Ch_type, class _Alloc, class _Rx_traits>
 | 
						|
    inline bool
 | 
						|
    regex_search_debug(const _Ch_type*                          __s,
 | 
						|
		       match_results<const _Ch_type*, _Alloc>&  __m,
 | 
						|
		       const basic_regex<_Ch_type, _Rx_traits>& __e,
 | 
						|
		       match_flag_type                          __f
 | 
						|
		       = std::regex_constants::match_default)
 | 
						|
    { return regex_search_debug(__s, __s + _Rx_traits::length(__s),
 | 
						|
				__m, __e, __f); }
 | 
						|
 | 
						|
  // C-string version without match_results
 | 
						|
  template<typename _Ch_type, typename _Rx_traits>
 | 
						|
    inline bool
 | 
						|
    regex_search_debug(const _Ch_type*                          __s,
 | 
						|
		       const basic_regex<_Ch_type, _Rx_traits>& __e,
 | 
						|
		       match_flag_type                          __f
 | 
						|
		       = std::regex_constants::match_default)
 | 
						|
    { return regex_search_debug(__s, __s + _Rx_traits::length(__s),
 | 
						|
				__e, __f); }
 | 
						|
 | 
						|
  // std::basic_string version
 | 
						|
  template<typename _Ch_traits, typename _Ch_alloc,
 | 
						|
           typename _Alloc, typename _Ch_type,
 | 
						|
           typename _Rx_traits>
 | 
						|
    inline bool
 | 
						|
    regex_search_debug(const std::basic_string<_Ch_type, _Ch_traits,
 | 
						|
		       _Ch_alloc>& __s,
 | 
						|
		       match_results<typename std::basic_string<_Ch_type,
 | 
						|
		       _Ch_traits, _Ch_alloc>::const_iterator, _Alloc>&
 | 
						|
		       __m,
 | 
						|
		       const basic_regex<_Ch_type, _Rx_traits>& __e,
 | 
						|
		       match_flag_type                          __f
 | 
						|
		       = std::regex_constants::match_default)
 | 
						|
    { return regex_search_debug(__s.begin(), __s.end(), __m, __e, __f); }
 | 
						|
 | 
						|
  // std::basic_string version without match_results
 | 
						|
  template<typename _Ch_traits, typename _String_allocator,
 | 
						|
           typename _Ch_type, typename _Rx_traits>
 | 
						|
    inline bool
 | 
						|
    regex_search_debug(const std::basic_string<_Ch_type, _Ch_traits,
 | 
						|
		       _String_allocator>&                      __s,
 | 
						|
		       const basic_regex<_Ch_type, _Rx_traits>& __e,
 | 
						|
		       match_flag_type                          __f
 | 
						|
		       = std::regex_constants::match_default)
 | 
						|
    { return regex_search_debug(__s.begin(), __s.end(), __e, __f); }
 | 
						|
 | 
						|
} // namespace __gnu_test
 | 
						|
#endif
 |