| 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 | 
|---|