diff options
Diffstat (limited to 'src/boost/libs/regex/test/regress/info.hpp')
-rw-r--r-- | src/boost/libs/regex/test/regress/info.hpp | 268 |
1 files changed, 268 insertions, 0 deletions
diff --git a/src/boost/libs/regex/test/regress/info.hpp b/src/boost/libs/regex/test/regress/info.hpp new file mode 100644 index 00000000..5c08961e --- /dev/null +++ b/src/boost/libs/regex/test/regress/info.hpp @@ -0,0 +1,268 @@ +/* + * + * Copyright (c) 2004 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE info.hpp + * VERSION see <boost/version.hpp> + * DESCRIPTION: Error handling for test cases. + */ + +#ifndef BOOST_REGEX_REGRESS_INFO_HPP +#define BOOST_REGEX_REGRESS_INFO_HPP +#include <iostream> +#include <string> +#include <boost/regex.hpp> + +#ifdef TEST_THREADS +#include <boost/thread/once.hpp> +#include <boost/thread.hpp> +#endif + +#ifdef GENERATE_CORPUS +#include <boost/lexical_cast.hpp> +#include <fstream> +// +// class de_fuzz_output +// Generates de-fuzzing corpus files +// +template <class charT> +class de_fuzz_output +{ +public: + de_fuzz_output() {} + template <class U> + void add(const U&, const U&) {} +}; +template<> +class de_fuzz_output<char> +{ + std::set<std::pair<std::string, std::string> > data; +public: + de_fuzz_output() {} + void add(const std::string& re, const std::string& text) + { + data.insert(std::make_pair(re, text)); + } + ~de_fuzz_output() + { + unsigned j = 0; + for(typename std::set<std::pair<std::string, std::string> >::const_iterator i = data.begin(); i != data.end(); ++i) + { + std::string filename = "corpus_" + boost::lexical_cast<std::string>(j); + std::fstream ofs(filename.c_str(), std::ios_base::out | std::ios_base::binary); + ofs.put(static_cast<char>(i->first.size() >> 8)); + ofs.put(static_cast<char>(i->first.size() & 0xff)); + ofs.write(i->first.c_str(), i->first.size()); + ofs.write(i->second.c_str(), i->second.size()); + ++j; + } + } +}; +#endif +// +// class test info, +// store information about the test we are about to conduct: +// +template <class charT> +class test_info_base +{ +public: + typedef std::basic_string<charT> string_type; +private: + struct data_type + { + std::string file; + int line; + string_type expression; + boost::regex_constants::syntax_option_type options; + string_type search_text; + boost::regex_constants::match_flag_type match_options; + const int* answer_table; + string_type format_string; + string_type result_string; + bool need_to_print; + std::string expression_type_name; + }; +#ifdef TEST_THREADS + static data_type& do_get_data() + { + static boost::thread_specific_ptr<data_type> pd; + if(pd.get() == 0) + pd.reset(new data_type()); + return *(pd.get()); + } + static void init_data() + { + do_get_data(); + } +#endif + static data_type& data() + { +#ifdef TEST_THREADS + static boost::once_flag f = BOOST_ONCE_INIT; + boost::call_once(f,&init_data); + return do_get_data(); +#else + static data_type d; + return d; +#endif + } +public: + test_info_base(){}; + static void set_info( + const char* file, + int line, + const string_type& ex, + boost::regex_constants::syntax_option_type opt, + const string_type& search_text = string_type(), + boost::regex_constants::match_flag_type match_options = boost::match_default, + const int* answer_table = 0, + const string_type& format_string = string_type(), + const string_type& result_string = string_type()) + { + data_type& dat = data(); + dat.file = file; + dat.line = line; + dat.expression = ex; + dat.options = opt; + dat.search_text = search_text; + dat.match_options = match_options; + dat.answer_table = answer_table; + dat.format_string = format_string; + dat.result_string = result_string; + dat.need_to_print = true; +#ifdef GENERATE_CORPUS + static de_fuzz_output<charT> corpus; + corpus.add(ex, search_text); +#endif + } + static void set_typename(const std::string& n) + { + data().expression_type_name = n; + } + + static const string_type& expression() + { + return data().expression; + } + static boost::regex_constants::syntax_option_type syntax_options() + { + return data().options; + } + static const string_type& search_text() + { + return data().search_text; + } + static boost::regex_constants::match_flag_type match_options() + { + return data().match_options; + } + static const int* answer_table() + { + return data().answer_table; + } + static const string_type& format_string() + { + return data().format_string; + } + static const string_type& result_string() + { + return data().result_string; + } + static bool need_to_print() + { + return data().need_to_print; + } + static const std::string& file() + { + return data().file; + } + static int line() + { + return data().line; + } + static void clear() + { + data().need_to_print = false; + } + static std::string& expression_typename() + { + return data().expression_type_name; + } +}; + +template <class T> +struct test_info + : public test_info_base<wchar_t> +{}; + +template<> +struct test_info<char> + : public test_info_base<char> +{}; + +#if BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042)) + +// Some template instantiation modes (namely local, implicit local, and weak) of +// this compiler need an explicit instantiation because otherwise we end up with +// multiple copies of the static variable defined in this method. This explicit +// instantiation generates the static variable with common linkage, which makes +// the linker choose only one of the available definitions. For more details, +// see "man ld". + +template test_info_base<wchar_t>::data_type & test_info_base<wchar_t>::data(); +template test_info_base<char>::data_type & test_info_base<char>::data(); + +#endif + +template <class charT> +std::ostream& operator<<(std::ostream& os, const test_info<charT>&) +{ + if(test_info<charT>::need_to_print()) + { + os << test_info<charT>::file() << ":" << test_info<charT>::line() << ": Error in test here:" << std::endl; + test_info<charT>::clear(); + } + return os; +} +// +// define some test macros: +// +extern int error_count; + +#define BOOST_REGEX_TEST_ERROR(msg, charT)\ + ++error_count;\ + std::cerr << test_info<charT>();\ + std::cerr << " " << __FILE__ << ":" << __LINE__ << ":" << msg \ + << " (While testing " << test_info<charT>::expression_typename() << ")" << std::endl + +class errors_as_warnings +{ +public: + errors_as_warnings() + { + m_saved_error_count = error_count; + } + ~errors_as_warnings() + { + if(m_saved_error_count != error_count) + { + std::cerr << "<note>The above " << (error_count - m_saved_error_count) << " errors are treated as warnings only.</note>" << std::endl; + error_count = m_saved_error_count; + } + } +private: + int m_saved_error_count; +}; + +#endif + |