]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/regex/test/regress/info.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / regex / test / regress / info.hpp
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 #ifdef GENERATE_CORPUS
31 #include <boost/lexical_cast.hpp>
32 #include <fstream>
33 //
34 // class de_fuzz_output
35 // Generates de-fuzzing corpus files
36 //
37 template <class charT>
38 class de_fuzz_output
39 {
40 public:
41 de_fuzz_output() {}
42 template <class U>
43 void add(const U&, const U&) {}
44 };
45 template<>
46 class de_fuzz_output<char>
47 {
48 std::set<std::pair<std::string, std::string> > data;
49 public:
50 de_fuzz_output() {}
51 void add(const std::string& re, const std::string& text)
52 {
53 data.insert(std::make_pair(re, text));
54 }
55 ~de_fuzz_output()
56 {
57 unsigned j = 0;
58 for(typename std::set<std::pair<std::string, std::string> >::const_iterator i = data.begin(); i != data.end(); ++i)
59 {
60 std::string filename = "corpus_" + boost::lexical_cast<std::string>(j);
61 std::fstream ofs(filename.c_str(), std::ios_base::out | std::ios_base::binary);
62 ofs.put(static_cast<char>(i->first.size() >> 8));
63 ofs.put(static_cast<char>(i->first.size() & 0xff));
64 ofs.write(i->first.c_str(), i->first.size());
65 ofs.write(i->second.c_str(), i->second.size());
66 ++j;
67 }
68 }
69 };
70 #endif
71 //
72 // class test info,
73 // store information about the test we are about to conduct:
74 //
75 template <class charT>
76 class test_info_base
77 {
78 public:
79 typedef std::basic_string<charT> string_type;
80 private:
81 struct data_type
82 {
83 std::string file;
84 int line;
85 string_type expression;
86 boost::regex_constants::syntax_option_type options;
87 string_type search_text;
88 boost::regex_constants::match_flag_type match_options;
89 const int* answer_table;
90 string_type format_string;
91 string_type result_string;
92 bool need_to_print;
93 std::string expression_type_name;
94 };
95 #ifdef TEST_THREADS
96 static data_type& do_get_data()
97 {
98 static boost::thread_specific_ptr<data_type> pd;
99 if(pd.get() == 0)
100 pd.reset(new data_type());
101 return *(pd.get());
102 }
103 static void init_data()
104 {
105 do_get_data();
106 }
107 #endif
108 static data_type& data()
109 {
110 #ifdef TEST_THREADS
111 static boost::once_flag f = BOOST_ONCE_INIT;
112 boost::call_once(f,&init_data);
113 return do_get_data();
114 #else
115 static data_type d;
116 return d;
117 #endif
118 }
119 public:
120 test_info_base(){};
121 static void set_info(
122 const char* file,
123 int line,
124 const string_type& ex,
125 boost::regex_constants::syntax_option_type opt,
126 const string_type& search_text = string_type(),
127 boost::regex_constants::match_flag_type match_options = boost::match_default,
128 const int* answer_table = 0,
129 const string_type& format_string = string_type(),
130 const string_type& result_string = string_type())
131 {
132 data_type& dat = data();
133 dat.file = file;
134 dat.line = line;
135 dat.expression = ex;
136 dat.options = opt;
137 dat.search_text = search_text;
138 dat.match_options = match_options;
139 dat.answer_table = answer_table;
140 dat.format_string = format_string;
141 dat.result_string = result_string;
142 dat.need_to_print = true;
143 #ifdef GENERATE_CORPUS
144 static de_fuzz_output<charT> corpus;
145 corpus.add(ex, search_text);
146 #endif
147 }
148 static void set_typename(const std::string& n)
149 {
150 data().expression_type_name = n;
151 }
152
153 static const string_type& expression()
154 {
155 return data().expression;
156 }
157 static boost::regex_constants::syntax_option_type syntax_options()
158 {
159 return data().options;
160 }
161 static const string_type& search_text()
162 {
163 return data().search_text;
164 }
165 static boost::regex_constants::match_flag_type match_options()
166 {
167 return data().match_options;
168 }
169 static const int* answer_table()
170 {
171 return data().answer_table;
172 }
173 static const string_type& format_string()
174 {
175 return data().format_string;
176 }
177 static const string_type& result_string()
178 {
179 return data().result_string;
180 }
181 static bool need_to_print()
182 {
183 return data().need_to_print;
184 }
185 static const std::string& file()
186 {
187 return data().file;
188 }
189 static int line()
190 {
191 return data().line;
192 }
193 static void clear()
194 {
195 data().need_to_print = false;
196 }
197 static std::string& expression_typename()
198 {
199 return data().expression_type_name;
200 }
201 };
202
203 template <class T>
204 struct test_info
205 : public test_info_base<wchar_t>
206 {};
207
208 template<>
209 struct test_info<char>
210 : public test_info_base<char>
211 {};
212
213 #if BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042))
214
215 // Some template instantiation modes (namely local, implicit local, and weak) of
216 // this compiler need an explicit instantiation because otherwise we end up with
217 // multiple copies of the static variable defined in this method. This explicit
218 // instantiation generates the static variable with common linkage, which makes
219 // the linker choose only one of the available definitions. For more details,
220 // see "man ld".
221
222 template test_info_base<wchar_t>::data_type & test_info_base<wchar_t>::data();
223 template test_info_base<char>::data_type & test_info_base<char>::data();
224
225 #endif
226
227 template <class charT>
228 std::ostream& operator<<(std::ostream& os, const test_info<charT>&)
229 {
230 if(test_info<charT>::need_to_print())
231 {
232 os << test_info<charT>::file() << ":" << test_info<charT>::line() << ": Error in test here:" << std::endl;
233 test_info<charT>::clear();
234 }
235 return os;
236 }
237 //
238 // define some test macros:
239 //
240 extern int error_count;
241
242 #define BOOST_REGEX_TEST_ERROR(msg, charT)\
243 ++error_count;\
244 std::cerr << test_info<charT>();\
245 std::cerr << " " << __FILE__ << ":" << __LINE__ << ":" << msg \
246 << " (While testing " << test_info<charT>::expression_typename() << ")" << std::endl
247
248 class errors_as_warnings
249 {
250 public:
251 errors_as_warnings()
252 {
253 m_saved_error_count = error_count;
254 }
255 ~errors_as_warnings()
256 {
257 if(m_saved_error_count != error_count)
258 {
259 std::cerr << "<note>The above " << (error_count - m_saved_error_count) << " errors are treated as warnings only.</note>" << std::endl;
260 error_count = m_saved_error_count;
261 }
262 }
263 private:
264 int m_saved_error_count;
265 };
266
267 #endif
268