summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/regex/test/regress/info.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/regex/test/regress/info.hpp')
-rw-r--r--src/boost/libs/regex/test/regress/info.hpp268
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 000000000..5c08961e2
--- /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
+