1 | /////////////////////////////////////////////////////////////////////////////// |
---|
2 | // test.hpp |
---|
3 | // |
---|
4 | // Copyright 2004 Eric Niebler. Distributed under the Boost |
---|
5 | // Software License, Version 1.0. (See accompanying file |
---|
6 | // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
---|
7 | |
---|
8 | #ifndef BOOST_XPRESSIVE_TEST_TEST_HPP_EAN_10_04_2005 |
---|
9 | #define BOOST_XPRESSIVE_TEST_TEST_HPP_EAN_10_04_2005 |
---|
10 | |
---|
11 | // MS compatible compilers support #pragma once |
---|
12 | #if defined(_MSC_VER) && (_MSC_VER >= 1020) |
---|
13 | # pragma once |
---|
14 | #endif |
---|
15 | |
---|
16 | #include <string> |
---|
17 | #include <vector> |
---|
18 | #include <cstdio> |
---|
19 | #include <cstdarg> |
---|
20 | #include <functional> |
---|
21 | #include <boost/range/iterator_range.hpp> |
---|
22 | #include <boost/xpressive/xpressive_static.hpp> |
---|
23 | #include "./test_minimal.hpp" |
---|
24 | using namespace boost::xpressive; |
---|
25 | |
---|
26 | #define L(x) BOOST_XPR_CSTR_(char_type, x) |
---|
27 | |
---|
28 | #define BOOST_XPR_CHECK(pred) \ |
---|
29 | if( pred ) {} else { BOOST_ERROR( this->format_msg(#pred).c_str() ); } |
---|
30 | |
---|
31 | using namespace boost::xpressive; |
---|
32 | |
---|
33 | /////////////////////////////////////////////////////////////////////////////// |
---|
34 | // backrefs |
---|
35 | // |
---|
36 | template<typename Char> |
---|
37 | inline std::vector<std::basic_string<Char> > backrefs(Char const *br0, ...) |
---|
38 | { |
---|
39 | using namespace std; |
---|
40 | std::vector<std::basic_string<Char> > backrefs; |
---|
41 | if(0 != br0) |
---|
42 | { |
---|
43 | backrefs.push_back(br0); |
---|
44 | va_list va; |
---|
45 | va_start(va, br0); |
---|
46 | Char const *brN; |
---|
47 | while(0 != (brN = va_arg(va, Char const *))) |
---|
48 | { |
---|
49 | backrefs.push_back(brN); |
---|
50 | } |
---|
51 | va_end(va); |
---|
52 | } |
---|
53 | return backrefs; |
---|
54 | } |
---|
55 | |
---|
56 | /////////////////////////////////////////////////////////////////////////////// |
---|
57 | // |
---|
58 | struct no_match_t {}; |
---|
59 | no_match_t const no_match = {}; |
---|
60 | |
---|
61 | template<typename BidiIter> |
---|
62 | struct test_case; |
---|
63 | |
---|
64 | template<typename BidiIter> |
---|
65 | std::string format_msg(test_case<BidiIter> const &test, char const *msg); |
---|
66 | |
---|
67 | /////////////////////////////////////////////////////////////////////////////// |
---|
68 | // test_case |
---|
69 | // |
---|
70 | template<typename BidiIter> |
---|
71 | struct test_case |
---|
72 | { |
---|
73 | typedef BidiIter iterator_type; |
---|
74 | typedef typename boost::iterator_value<iterator_type>::type char_type; |
---|
75 | typedef basic_regex<iterator_type> regex_type; |
---|
76 | typedef std::basic_string<char_type> string_type; |
---|
77 | typedef std::vector<string_type> backrefs_type; |
---|
78 | |
---|
79 | test_case(std::string section, string_type str, regex_type rex, backrefs_type brs) |
---|
80 | : section_(section) |
---|
81 | , str_(str) |
---|
82 | , rex_(rex) |
---|
83 | , brs_(brs) |
---|
84 | { |
---|
85 | } |
---|
86 | |
---|
87 | test_case(std::string section, string_type str, regex_type rex, no_match_t) |
---|
88 | : section_(section) |
---|
89 | , str_(str) |
---|
90 | , rex_(rex) |
---|
91 | , brs_() |
---|
92 | { |
---|
93 | } |
---|
94 | |
---|
95 | void run() const |
---|
96 | { |
---|
97 | char_type const empty[] = {0}; |
---|
98 | match_results<BidiIter> what; |
---|
99 | if(regex_search(this->str_, what, this->rex_)) |
---|
100 | { |
---|
101 | // match succeeded: was it expected to succeed? |
---|
102 | BOOST_XPR_CHECK(what.size() == this->brs_.size()); |
---|
103 | |
---|
104 | for(std::size_t i = 0; i < what.size() && i < this->brs_.size(); ++i) |
---|
105 | { |
---|
106 | BOOST_XPR_CHECK(!what[i].matched && this->brs_[i] == empty || this->brs_[i] == what[i].str()); |
---|
107 | } |
---|
108 | } |
---|
109 | else |
---|
110 | { |
---|
111 | // match failed: was it expected to fail? |
---|
112 | BOOST_XPR_CHECK(0 == this->brs_.size()); |
---|
113 | } |
---|
114 | } |
---|
115 | |
---|
116 | private: |
---|
117 | |
---|
118 | std::string format_msg(char const *msg) const |
---|
119 | { |
---|
120 | return this->section_ + " : " + msg; |
---|
121 | } |
---|
122 | |
---|
123 | std::string section_; |
---|
124 | string_type str_; |
---|
125 | regex_type rex_; |
---|
126 | std::vector<string_type> brs_; |
---|
127 | }; |
---|
128 | |
---|
129 | /////////////////////////////////////////////////////////////////////////////// |
---|
130 | // test_runner |
---|
131 | template<typename BidiIter> |
---|
132 | struct test_runner |
---|
133 | : std::unary_function<test_case<BidiIter>, void> |
---|
134 | { |
---|
135 | void operator ()(test_case<BidiIter> const &test) const |
---|
136 | { |
---|
137 | test.run(); |
---|
138 | } |
---|
139 | }; |
---|
140 | |
---|
141 | /////////////////////////////////////////////////////////////////////////////// |
---|
142 | // helpful debug routines |
---|
143 | /////////////////////////////////////////////////////////////////////////////// |
---|
144 | |
---|
145 | /////////////////////////////////////////////////////////////////////////////// |
---|
146 | // remove all occurances of sz from str |
---|
147 | inline void string_remove(std::string &str, char const *sz) |
---|
148 | { |
---|
149 | std::string::size_type i = 0, n = std::strlen(sz); |
---|
150 | while(std::string::npos != (i=str.find(sz,i))) |
---|
151 | { |
---|
152 | str.erase(i,n); |
---|
153 | } |
---|
154 | } |
---|
155 | |
---|
156 | /////////////////////////////////////////////////////////////////////////////// |
---|
157 | // display_type2 |
---|
158 | // for type T, write typeid::name after performing some substitutions |
---|
159 | template<typename T> |
---|
160 | inline void display_type2() |
---|
161 | { |
---|
162 | std::string str = typeid(T).name(); |
---|
163 | |
---|
164 | string_remove(str, "struct "); |
---|
165 | string_remove(str, "boost::"); |
---|
166 | string_remove(str, "xpressive::"); |
---|
167 | string_remove(str, "detail::"); |
---|
168 | string_remove(str, "fusion::"); |
---|
169 | |
---|
170 | //std::printf("%s\n\n", str.c_str()); |
---|
171 | std::printf("%s\nwdith=%d\nis_pure=%s\n\n", str.c_str() |
---|
172 | , detail::width_of<T>::value |
---|
173 | , detail::is_pure<T>::value ? "true" : "false"); |
---|
174 | } |
---|
175 | |
---|
176 | /////////////////////////////////////////////////////////////////////////////// |
---|
177 | // display_type |
---|
178 | // display the type of the deduced template argument |
---|
179 | template<typename T> |
---|
180 | inline void display_type(T const &) |
---|
181 | { |
---|
182 | display_type2<T>(); |
---|
183 | } |
---|
184 | |
---|
185 | /////////////////////////////////////////////////////////////////////////////// |
---|
186 | // test_compile |
---|
187 | // try to compile a given static regular expression |
---|
188 | template<typename BidiIter, typename Xpr> |
---|
189 | inline void test_compile(Xpr const &xpr) |
---|
190 | { |
---|
191 | typedef typename boost::iterator_value<BidiIter>::type char_type; |
---|
192 | typedef boost::xpressive::regex_traits<char_type> traits_type; |
---|
193 | boost::xpressive::detail::xpression_visitor<BidiIter, boost::mpl::false_, traits_type> visitor; |
---|
194 | |
---|
195 | display_type(boost::proto::compile( |
---|
196 | xpr |
---|
197 | , boost::xpressive::detail::end_xpression() |
---|
198 | , visitor |
---|
199 | , boost::xpressive::detail::seq_tag() |
---|
200 | )); |
---|
201 | } |
---|
202 | |
---|
203 | #endif |
---|