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)
13 * LOCATION: see http://www.boost.org for most recent version.
15 * VERSION see <boost/version.hpp>
16 * DESCRIPTION: Error handling for test cases.
19 #ifndef BOOST_REGEX_REGRESS_INFO_HPP
20 #define BOOST_REGEX_REGRESS_INFO_HPP
23 #include <boost/regex.hpp>
26 #include <boost/thread/once.hpp>
27 #include <boost/thread.hpp>
30 #ifdef GENERATE_CORPUS
31 #include <boost/lexical_cast.hpp>
34 // class de_fuzz_output
35 // Generates de-fuzzing corpus files
37 template <class charT>
43 void add(const U&, const U&) {}
46 class de_fuzz_output<char>
48 std::set<std::pair<std::string, std::string> > data;
51 void add(const std::string& re, const std::string& text)
53 data.insert(std::make_pair(re, text));
58 for(typename std::set<std::pair<std::string, std::string> >::const_iterator i = data.begin(); i != data.end(); ++i)
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());
73 // store information about the test we are about to conduct:
75 template <class charT>
79 typedef std::basic_string<charT> string_type;
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;
93 std::string expression_type_name;
96 static data_type& do_get_data()
98 static boost::thread_specific_ptr<data_type> pd;
100 pd.reset(new data_type());
103 static void init_data()
108 static data_type& data()
111 static boost::once_flag f = BOOST_ONCE_INIT;
112 boost::call_once(f,&init_data);
113 return do_get_data();
115 static data_type d = {};
121 static void set_info(
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())
132 data_type& dat = data();
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);
148 static void set_typename(const std::string& n)
150 data().expression_type_name = n;
153 static const string_type& expression()
155 return data().expression;
157 static boost::regex_constants::syntax_option_type syntax_options()
159 return data().options;
161 static const string_type& search_text()
163 return data().search_text;
165 static boost::regex_constants::match_flag_type match_options()
167 return data().match_options;
169 static const int* answer_table()
171 return data().answer_table;
173 static const string_type& format_string()
175 return data().format_string;
177 static const string_type& result_string()
179 return data().result_string;
181 static bool need_to_print()
183 return data().need_to_print;
185 static const std::string& file()
195 data().need_to_print = false;
197 static std::string& expression_typename()
199 return data().expression_type_name;
205 : public test_info_base<wchar_t>
209 struct test_info<char>
210 : public test_info_base<char>
213 #if BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042))
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,
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();
227 template <class charT>
228 std::ostream& operator<<(std::ostream& os, const test_info<charT>&)
230 if(test_info<charT>::need_to_print())
232 os << test_info<charT>::file() << ":" << test_info<charT>::line() << ": Error in test here:" << std::endl;
233 test_info<charT>::clear();
238 // define some test macros:
240 extern int error_count;
242 #define BOOST_REGEX_TEST_ERROR(msg, charT)\
244 std::cerr << test_info<charT>();\
245 std::cerr << " " << __FILE__ << ":" << __LINE__ << ":" << msg \
246 << " (While testing " << test_info<charT>::expression_typename() << ")" << std::endl
248 class errors_as_warnings
253 m_saved_error_count = error_count;
255 ~errors_as_warnings()
257 if(m_saved_error_count != error_count)
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;
264 int m_saved_error_count;