1 // -*- C++ -*-
2 // regex utils for the C++ library testsuite.
3 //
4 // Copyright (C) 2012-2013 Free Software Foundation, Inc.
5 //
6 // This file is part of the GNU ISO C++ Library.  This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 3, or (at your option)
10 // any later version.
11 //
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License along
18 // with this library; see the file COPYING3.  If not see
19 // <http://www.gnu.org/licenses/>.
20 //
21 
22 #include <regex>
23 #include <stdexcept>
24 #include <iostream>
25 
26 #ifndef _TESTSUITE_REGEX_H
27 #define _TESTSUITE_REGEX_H 1
28 
29 namespace __gnu_test
30 {
31   // Test on a compilation of simple expressions, throw regex_error on error.
32   typedef std::regex				regex_type;
33   typedef regex_type::flag_type			flag_type;
34   typedef std::regex_constants::error_type	error_type;
35   typedef std::size_t				size_type;
36   typedef std::string				string_type;
37 
38   // Utilities
39   struct regex_expected_fail { };
40 
41   const error_type regex_error_internal(static_cast<error_type>(-1));
42 
43   // Stringify error codes for text logging.
44   const char* regex_error_codes[] =
45     {
46     "error_collate",
47     "error_ctype",
48     "error_escape",
49     "error_backref",
50     "error_brack",
51     "error_paren",
52     "error_brace",
53     "error_badbrace",
54     "error_range",
55     "error_space",
56     "error_badrepeat",
57     "error_complexity",
58     "error_stack"
59   };
60 
61   void
show_regex_error_codes()62   show_regex_error_codes()
63   {
64     using namespace std;
65     using namespace std::regex_constants;
66     const char tab('\t');
67     cout << "error_collate =   " << tab << error_collate << endl;
68     cout << "error_ctype =     " << tab << error_ctype << endl;
69     cout << "error_escape =    " << tab << error_escape << endl;
70     cout << "error_backref =   " << tab << error_backref << endl;
71     cout << "error_brack =     " << tab << error_brack << endl;
72     cout << "error_paren =     " << tab << error_paren << endl;
73     cout << "error_brace =     " << tab << error_brace << endl;
74     cout << "error_badbrace =  " << tab << error_badbrace << endl;
75     cout << "error_range =     " << tab << error_range << endl;
76     cout << "error_space =     " << tab << error_space << endl;
77     cout << "error_badrepeat = " << tab << error_badrepeat << endl;
78     cout << "error_complexity =" << tab << error_complexity << endl;
79     cout << "error_stack =     " << tab << error_stack << endl;
80   }
81 
82   // Arguments
83   // string __res: the regular expression string
84   // flag_type __f: flag
85   // __error: expected error, if any
86   void
87   regex_sanity_check(const string_type& __res,
88 		     flag_type __f = regex_type::basic,
89 		     error_type __error =  regex_error_internal)
90   {
91     using namespace std;
92 
93     try
94       {
95 	regex_type reo(__res, __f);
96 	auto n = reo.mark_count();
97 	cout << "regex_type::mark_count " << n << endl;
98       }
catch(const regex_error & e)99     catch (const regex_error& e)
100       {
101 	cout << "regex_sanity_check: "  << __res << endl;
102 	cout << "regex_error::what " << e.what() << endl;
103 
104 	show_regex_error_codes();
105 	cout << "regex_error::code " << regex_error_codes[e.code()] << endl;
106 
107 	if (__error != regex_error_internal)
108 	  {
109 	    // Then expected error_type is __error. Check.
110 	    if (__error != e.code())
111 	      {
112 		throw regex_expected_fail();
113 	      }
114 	  }
115 	throw;
116       }
catch(const logic_error & e)117     catch (const logic_error& e)
118       {
119 	cout << "logic_error::what " << e.what() << endl;
120 	throw;
121       }
catch(const std::exception & e)122     catch (const std::exception& e)
123       {
124 	cout << "exception: " << endl;
125 	throw;
126       }
127   }
128 
129 } // namespace __gnu_test
130 #endif
131