1///////////////////////////////////////////////////////////////////////////////
2// test_cycles.hpp
3//
4// Copyright 2008 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// defining this causes regex_impl objects to be counted, allowing us to detect
9// leaks portably.
10#define BOOST_XPRESSIVE_DEBUG_CYCLE_TEST
11
12#include <iostream>
13#include <boost/test/unit_test.hpp>
14#include <boost/xpressive/xpressive.hpp>
15
16#if defined(_MSC_VER) && defined(_DEBUG)
17# define _CRTDBG_MAP_ALLOC
18# include <crtdbg.h>
19#endif
20
21using namespace boost::unit_test;
22using namespace boost::xpressive;
23
24///////////////////////////////////////////////////////////////////////////////
25// test_main
26// regexes referred to by other regexes are kept alive via reference counting.
27// but cycles are handled naturally. the following works as expected and doesn't leak.
28void test_main()
29{
30 {
31 sregex v;
32 {
33 sregex a,b,c;
34 a = 'a' >> !by_ref(rex: b);
35 //std::cout << a << std::endl;
36 //std::cout << b << std::endl;
37 //std::cout << c << std::endl;
38
39 // just for giggles
40 c = a;
41 c = epsilon >> 'a';
42
43 b = epsilon >> by_ref(rex: c);
44 //std::cout << a << std::endl;
45 //std::cout << b << std::endl;
46 //std::cout << c << std::endl;
47
48 c = epsilon >> by_ref(rex: a);
49 //std::cout << a << std::endl;
50 //std::cout << b << std::endl;
51 //std::cout << c << std::endl;
52
53 v = a;
54 }
55 std::string const s("aaa");
56 smatch m;
57 if(!regex_match(rng: s, what&: m, re: v))
58 {
59 BOOST_ERROR("cycle test 1 failed");
60 }
61 }
62
63 if(0 != detail::regex_impl<std::string::const_iterator>::instances)
64 {
65 BOOST_ERROR("leaks detected (cycle test 1)");
66 detail::regex_impl<std::string::const_iterator>::instances = 0;
67 }
68
69 {
70 sregex v;
71 {
72 sregex a,b,c;
73 b = epsilon >> by_ref(rex: c);
74 a = 'a' >> !by_ref(rex: b);
75 c = epsilon >> by_ref(rex: a);
76
77 //std::cout << a << std::endl;
78 //std::cout << b << std::endl;
79 //std::cout << c << std::endl;
80
81 v = a;
82 }
83 std::string const s("aaa");
84 smatch m;
85 if(!regex_match(rng: s, what&: m, re: v))
86 {
87 BOOST_ERROR("cycle test 2 failed");
88 }
89 }
90
91 if(0 != detail::regex_impl<std::string::const_iterator>::instances)
92 {
93 BOOST_ERROR("leaks detected (cycle test 2)");
94 detail::regex_impl<std::string::const_iterator>::instances = 0;
95 }
96
97 {
98 sregex v;
99 {
100 sregex a,b,c;
101
102 b = epsilon >> by_ref(rex: c);
103 c = epsilon >> by_ref(rex: a);
104 a = 'a' >> !by_ref(rex: b);
105
106 //std::cout << a << std::endl;
107 //std::cout << b << std::endl;
108 //std::cout << c << std::endl;
109
110 v = a;
111 }
112 std::string const s("aaa");
113 smatch m;
114 if(!regex_match(rng: s, what&: m, re: v))
115 {
116 BOOST_ERROR("cycle test 3 failed");
117 }
118 }
119
120 if(0 != detail::regex_impl<std::string::const_iterator>::instances)
121 {
122 BOOST_ERROR("leaks detected (cycle test 3)");
123 detail::regex_impl<std::string::const_iterator>::instances = 0;
124 }
125
126 {
127 sregex v;
128 {
129 sregex a,b,c;
130 c = epsilon >> by_ref(rex: a);
131 b = epsilon >> by_ref(rex: c);
132 a = 'a' >> !by_ref(rex: b);
133
134 //std::cout << a << std::endl;
135 //std::cout << b << std::endl;
136 //std::cout << c << std::endl;
137
138 v = a;
139 }
140 std::string const s("aaa");
141 smatch m;
142 if(!regex_match(rng: s, what&: m, re: v))
143 {
144 BOOST_ERROR("cycle test 4 failed");
145 }
146 }
147
148 if(0 != detail::regex_impl<std::string::const_iterator>::instances)
149 {
150 BOOST_ERROR("leaks detected (cycle test 4)");
151 detail::regex_impl<std::string::const_iterator>::instances = 0;
152 }
153
154 {
155 sregex v;
156 {
157 sregex a,b,c;
158 a = 'a' >> !by_ref(rex: b);
159 b = epsilon >> by_ref(rex: c);
160 c = epsilon >> by_ref(rex: a);
161
162 sregex d,e;
163 d = epsilon >> by_ref(rex: e);
164 e = epsilon >> "aa";
165
166 c = d;
167
168 //std::cout << a << std::endl;
169 //std::cout << b << std::endl;
170 //std::cout << c << std::endl;
171 //std::cout << e << std::endl;
172
173 e = 'a' >> by_ref(rex: c);
174
175 //std::cout << "-new loop!\n";
176 //std::cout << a << std::endl;
177 //std::cout << b << std::endl;
178 //std::cout << c << std::endl;
179 //std::cout << e << std::endl;
180
181 v = a;
182
183 //std::cout << v << std::endl;
184
185 }
186 std::string const s("aaa");
187 smatch m;
188 if(regex_match(rng: s, what&: m, re: v)) // OK, this shouldn't match
189 {
190 BOOST_ERROR("cycle test 5 failed");
191 }
192 }
193
194 if(0 != detail::regex_impl<std::string::const_iterator>::instances)
195 {
196 BOOST_ERROR("leaks detected (cycle test 5)");
197 detail::regex_impl<std::string::const_iterator>::instances = 0;
198 }
199}
200
201///////////////////////////////////////////////////////////////////////////////
202// init_unit_test_suite
203//
204test_suite* init_unit_test_suite( int argc, char* argv[] )
205{
206 test_suite *test = BOOST_TEST_SUITE("test_cycles");
207 test->add(BOOST_TEST_CASE(&test_main));
208 return test;
209}
210
211///////////////////////////////////////////////////////////////////////////////
212// Debug stuff
213//
214namespace
215{
216 const struct debug_init
217 {
218 debug_init()
219 {
220 #ifdef _MSC_VER
221 // Send warnings, errors and asserts to STDERR
222 _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
223 _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
224 _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
225 _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
226 _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
227 _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
228
229 // Check for leaks at program termination
230 _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG));
231
232 //_CrtSetBreakAlloc(221);
233 #endif
234 }
235 } dbg;
236}
237

source code of boost/libs/xpressive/test/test_cycles.cpp