// -*- C++ -*-
// regex utils for the C++ library testsuite.
//
// Copyright (C) 2012-2021 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
