]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /* |
2 | * | |
3 | * Copyright (c) 2004 | |
4 | * John Maddock | |
5 | * | |
6 | * Use, modification and distribution are subject to the | |
7 | * Boost Software License, Version 1.0. (See accompanying file | |
8 | * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
9 | * | |
10 | */ | |
11 | ||
12 | /* | |
13 | * LOCATION: see http://www.boost.org for most recent version. | |
14 | * FILE info.hpp | |
15 | * VERSION see <boost/version.hpp> | |
16 | * DESCRIPTION: Error handling for test cases. | |
17 | */ | |
18 | ||
19 | #ifndef BOOST_REGEX_REGRESS_INFO_HPP | |
20 | #define BOOST_REGEX_REGRESS_INFO_HPP | |
21 | #include <iostream> | |
22 | #include <string> | |
23 | #include <boost/regex.hpp> | |
24 | ||
25 | #ifdef TEST_THREADS | |
26 | #include <boost/thread/once.hpp> | |
27 | #include <boost/thread.hpp> | |
28 | #endif | |
29 | // | |
30 | // class test info, | |
31 | // store information about the test we are about to conduct: | |
32 | // | |
33 | template <class charT> | |
34 | class test_info_base | |
35 | { | |
36 | public: | |
37 | typedef std::basic_string<charT> string_type; | |
38 | private: | |
39 | struct data_type | |
40 | { | |
41 | std::string file; | |
42 | int line; | |
43 | string_type expression; | |
44 | boost::regex_constants::syntax_option_type options; | |
45 | string_type search_text; | |
46 | boost::regex_constants::match_flag_type match_options; | |
47 | const int* answer_table; | |
48 | string_type format_string; | |
49 | string_type result_string; | |
50 | bool need_to_print; | |
51 | std::string expression_type_name; | |
52 | }; | |
53 | #ifdef TEST_THREADS | |
54 | static data_type& do_get_data() | |
55 | { | |
56 | static boost::thread_specific_ptr<data_type> pd; | |
57 | if(pd.get() == 0) | |
58 | pd.reset(new data_type()); | |
59 | return *(pd.get()); | |
60 | } | |
61 | static void init_data() | |
62 | { | |
63 | do_get_data(); | |
64 | } | |
65 | #endif | |
66 | static data_type& data() | |
67 | { | |
68 | #ifdef TEST_THREADS | |
69 | static boost::once_flag f = BOOST_ONCE_INIT; | |
70 | boost::call_once(f,&init_data); | |
71 | return do_get_data(); | |
72 | #else | |
73 | static data_type d; | |
74 | return d; | |
75 | #endif | |
76 | } | |
77 | public: | |
78 | test_info_base(){}; | |
79 | static void set_info( | |
80 | const char* file, | |
81 | int line, | |
82 | const string_type& ex, | |
83 | boost::regex_constants::syntax_option_type opt, | |
84 | const string_type& search_text = string_type(), | |
85 | boost::regex_constants::match_flag_type match_options = boost::match_default, | |
86 | const int* answer_table = 0, | |
87 | const string_type& format_string = string_type(), | |
88 | const string_type& result_string = string_type()) | |
89 | { | |
90 | data_type& dat = data(); | |
91 | dat.file = file; | |
92 | dat.line = line; | |
93 | dat.expression = ex; | |
94 | dat.options = opt; | |
95 | dat.search_text = search_text; | |
96 | dat.match_options = match_options; | |
97 | dat.answer_table = answer_table; | |
98 | dat.format_string = format_string; | |
99 | dat.result_string = result_string; | |
100 | dat.need_to_print = true; | |
101 | } | |
102 | static void set_typename(const std::string& n) | |
103 | { | |
104 | data().expression_type_name = n; | |
105 | } | |
106 | ||
107 | static const string_type& expression() | |
108 | { | |
109 | return data().expression; | |
110 | } | |
111 | static boost::regex_constants::syntax_option_type syntax_options() | |
112 | { | |
113 | return data().options; | |
114 | } | |
115 | static const string_type& search_text() | |
116 | { | |
117 | return data().search_text; | |
118 | } | |
119 | static boost::regex_constants::match_flag_type match_options() | |
120 | { | |
121 | return data().match_options; | |
122 | } | |
123 | static const int* answer_table() | |
124 | { | |
125 | return data().answer_table; | |
126 | } | |
127 | static const string_type& format_string() | |
128 | { | |
129 | return data().format_string; | |
130 | } | |
131 | static const string_type& result_string() | |
132 | { | |
133 | return data().result_string; | |
134 | } | |
135 | static bool need_to_print() | |
136 | { | |
137 | return data().need_to_print; | |
138 | } | |
139 | static const std::string& file() | |
140 | { | |
141 | return data().file; | |
142 | } | |
143 | static int line() | |
144 | { | |
145 | return data().line; | |
146 | } | |
147 | static void clear() | |
148 | { | |
149 | data().need_to_print = false; | |
150 | } | |
151 | static std::string& expression_typename() | |
152 | { | |
153 | return data().expression_type_name; | |
154 | } | |
155 | }; | |
156 | ||
157 | template <class T> | |
158 | struct test_info | |
159 | : public test_info_base<wchar_t> | |
160 | {}; | |
161 | ||
162 | template<> | |
163 | struct test_info<char> | |
164 | : public test_info_base<char> | |
165 | {}; | |
166 | ||
167 | #if BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042)) | |
168 | ||
169 | // Some template instantiation modes (namely local, implicit local, and weak) of | |
170 | // this compiler need an explicit instantiation because otherwise we end up with | |
171 | // multiple copies of the static variable defined in this method. This explicit | |
172 | // instantiation generates the static variable with common linkage, which makes | |
173 | // the linker choose only one of the available definitions. For more details, | |
174 | // see "man ld". | |
175 | ||
176 | template test_info_base<wchar_t>::data_type & test_info_base<wchar_t>::data(); | |
177 | template test_info_base<char>::data_type & test_info_base<char>::data(); | |
178 | ||
179 | #endif | |
180 | ||
181 | template <class charT> | |
182 | std::ostream& operator<<(std::ostream& os, const test_info<charT>&) | |
183 | { | |
184 | if(test_info<charT>::need_to_print()) | |
185 | { | |
186 | os << test_info<charT>::file() << ":" << test_info<charT>::line() << ": Error in test here:" << std::endl; | |
187 | test_info<charT>::clear(); | |
188 | } | |
189 | return os; | |
190 | } | |
191 | // | |
192 | // define some test macros: | |
193 | // | |
194 | extern int error_count; | |
195 | ||
196 | #define BOOST_REGEX_TEST_ERROR(msg, charT)\ | |
197 | ++error_count;\ | |
198 | std::cerr << test_info<charT>();\ | |
199 | std::cerr << " " << __FILE__ << ":" << __LINE__ << ":" << msg \ | |
200 | << " (While testing " << test_info<charT>::expression_typename() << ")" << std::endl | |
201 | ||
202 | class errors_as_warnings | |
203 | { | |
204 | public: | |
205 | errors_as_warnings() | |
206 | { | |
207 | m_saved_error_count = error_count; | |
208 | } | |
209 | ~errors_as_warnings() | |
210 | { | |
211 | if(m_saved_error_count != error_count) | |
212 | { | |
213 | std::cerr << "<note>The above " << (error_count - m_saved_error_count) << " errors are treated as warnings only.</note>" << std::endl; | |
214 | error_count = m_saved_error_count; | |
215 | } | |
216 | } | |
217 | private: | |
218 | int m_saved_error_count; | |
219 | }; | |
220 | ||
221 | #endif | |
222 |