]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // error_code_user_test.cpp ------------------------------------------------// |
2 | ||
3 | // Copyright Beman Dawes 2006 | |
4 | ||
5 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | |
6 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
7 | ||
8 | // See library home page at http://www.boost.org/libs/system | |
9 | ||
10 | // ------------------------------------------------------------------------ // | |
11 | ||
12 | // This program demonstrates creation and use of new categories of error | |
13 | // codes. Several scenarios are demonstrated and tested. | |
14 | ||
15 | // Motivation was a Boost posting by Christopher Kohlhoff on June 28, 2006. | |
16 | ||
7c673cae FG |
17 | #include <boost/system/error_code.hpp> |
18 | #include <boost/cerrno.hpp> | |
19 | #include <string> | |
20 | #include <cstdio> | |
21 | #include <boost/detail/lightweight_test.hpp> | |
22 | ||
23 | #ifdef BOOST_POSIX_API | |
24 | # include <sys/stat.h> | |
25 | #else | |
26 | # include <windows.h> | |
27 | #endif | |
28 | ||
29 | // ------------------------------------------------------------------------ // | |
30 | ||
31 | // Library 1: User function passes through an error code from the | |
32 | // operating system. | |
33 | ||
34 | ||
35 | boost::system::error_code my_mkdir( const std::string & path ) | |
36 | { | |
37 | return boost::system::error_code( | |
38 | # ifdef BOOST_POSIX_API | |
39 | ::mkdir( path.c_str(), S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH ) == 0 ? 0 : errno, | |
40 | # else | |
41 | ::CreateDirectoryA( path.c_str(), 0 ) != 0 ? 0 : ::GetLastError(), | |
42 | # endif | |
43 | boost::system::system_category() ); | |
44 | } | |
45 | ||
46 | // ------------------------------------------------------------------------ // | |
47 | ||
48 | // Library 2: User function passes through errno from the C-runtime. | |
49 | ||
50 | #include <cstdio> | |
51 | ||
52 | boost::system::error_code my_remove( const std::string & path ) | |
53 | { | |
54 | return boost::system::error_code( | |
55 | std::remove( path.c_str() ) == 0 ? 0 : errno, | |
56 | boost::system::generic_category() ); // OK for both Windows and POSIX | |
57 | // Alternatively, could use generic_category() | |
58 | // on Windows and system_category() on | |
59 | // POSIX-based systems. | |
60 | } | |
61 | ||
62 | // ------------------------------------------------------------------------ // | |
63 | ||
64 | // Library 3: Library uses enum to identify library specific errors. | |
65 | ||
66 | // This particular example is for a library within the parent namespace. For | |
67 | // an example of a library not within the parent namespace, see library 4. | |
68 | ||
69 | // header lib3.hpp: | |
70 | ||
71 | namespace boost | |
72 | { | |
73 | namespace lib3 | |
74 | { | |
75 | // lib3 has its own error_category: | |
76 | const boost::system::error_category & get_lib3_error_category() BOOST_SYSTEM_NOEXCEPT; | |
77 | const boost::system::error_category & lib3_error_category = get_lib3_error_category(); | |
78 | ||
79 | enum error | |
80 | { | |
81 | boo_boo=123, | |
82 | big_boo_boo | |
83 | }; | |
84 | } | |
85 | ||
86 | namespace system | |
87 | { | |
88 | template<> struct is_error_code_enum<boost::lib3::error> | |
89 | { static const bool value = true; }; | |
90 | } | |
91 | ||
92 | namespace lib3 | |
93 | { | |
94 | inline boost::system::error_code make_error_code(error e) | |
95 | { return boost::system::error_code(e,lib3_error_category); } | |
96 | } | |
97 | ||
98 | } | |
99 | ||
100 | // implementation file lib3.cpp: | |
101 | ||
102 | // #include <lib3.hpp> | |
103 | ||
104 | namespace boost | |
105 | { | |
106 | namespace lib3 | |
107 | { | |
108 | class lib3_error_category_imp : public boost::system::error_category | |
109 | { | |
110 | public: | |
111 | lib3_error_category_imp() : boost::system::error_category() { } | |
112 | ||
113 | const char * name() const BOOST_SYSTEM_NOEXCEPT | |
114 | { | |
115 | return "lib3"; | |
116 | } | |
117 | ||
118 | boost::system::error_condition default_error_condition( int ev ) const BOOST_SYSTEM_NOEXCEPT | |
119 | { | |
120 | return ev == boo_boo | |
121 | ? boost::system::error_condition( boost::system::errc::io_error, | |
122 | boost::system::generic_category() ) | |
123 | : boost::system::error_condition( ev, | |
124 | boost::lib3::lib3_error_category ); | |
125 | } | |
126 | ||
127 | std::string message( int ev ) const | |
128 | { | |
129 | if ( ev == boo_boo ) return std::string("boo boo"); | |
130 | if ( ev == big_boo_boo ) return std::string("big boo boo"); | |
131 | return std::string("unknown error"); | |
132 | } | |
133 | ||
134 | }; | |
135 | ||
136 | const boost::system::error_category & get_lib3_error_category() BOOST_SYSTEM_NOEXCEPT | |
137 | { | |
138 | static const lib3_error_category_imp l3ecat; | |
139 | return l3ecat; | |
140 | } | |
141 | } | |
142 | } | |
143 | ||
144 | // ------------------------------------------------------------------------ // | |
145 | ||
146 | // Library 4: Library uses const error_code's to identify library specific | |
147 | // errors. | |
148 | ||
149 | // This particular example is for a library not within the parent namespace. | |
150 | // For an example of a library within the parent namespace, see library 3. | |
151 | ||
152 | // header lib4.hpp: | |
153 | ||
154 | namespace lib4 | |
155 | { | |
156 | // lib4 has its own error_category: | |
157 | const boost::system::error_category & get_lib4_error_category() BOOST_SYSTEM_NOEXCEPT; | |
158 | const boost::system::error_category & lib4_error_category = get_lib4_error_category(); | |
159 | ||
160 | extern const boost::system::error_code boo_boo; | |
161 | extern const boost::system::error_code big_boo_boo; | |
162 | } | |
163 | ||
164 | // implementation file lib4.cpp: | |
165 | ||
166 | // #include <lib4.hpp> | |
167 | ||
168 | namespace lib4 | |
169 | { | |
170 | class lib4_error_category_imp : public boost::system::error_category | |
171 | { | |
172 | public: | |
173 | lib4_error_category_imp() : boost::system::error_category() { } | |
174 | ||
175 | const char * name() const BOOST_SYSTEM_NOEXCEPT | |
176 | { | |
177 | return "lib4"; | |
178 | } | |
179 | ||
180 | boost::system::error_condition default_error_condition( int ev ) const BOOST_SYSTEM_NOEXCEPT | |
181 | { | |
182 | return ev == boo_boo.value() | |
183 | ? boost::system::error_condition( boost::system::errc::io_error, | |
184 | boost::system::generic_category() ) | |
185 | : boost::system::error_condition( ev, lib4::lib4_error_category ); | |
186 | } | |
187 | ||
188 | std::string message( int ev ) const | |
189 | { | |
190 | if ( ev == boo_boo.value() ) return std::string("boo boo"); | |
191 | if ( ev == big_boo_boo.value() ) return std::string("big boo boo"); | |
192 | return std::string("unknown error"); | |
193 | } | |
194 | }; | |
195 | ||
196 | const boost::system::error_category & get_lib4_error_category() BOOST_SYSTEM_NOEXCEPT | |
197 | { | |
198 | static const lib4_error_category_imp l4ecat; | |
199 | return l4ecat; | |
200 | } | |
201 | ||
202 | const boost::system::error_code boo_boo( 456, lib4_error_category ); | |
203 | const boost::system::error_code big_boo_boo( 789, lib4_error_category ); | |
204 | ||
205 | } | |
206 | ||
207 | // ------------------------------------------------------------------------ // | |
208 | ||
209 | // Chris Kolhoff's Test3, modified to work with error_code.hpp | |
210 | ||
211 | // Test3 | |
212 | // ===== | |
213 | // Define error classes to check for success, permission_denied and | |
214 | // out_of_memory, but add additional mappings for a user-defined error category. | |
215 | // | |
216 | ||
217 | //namespace test3 { | |
218 | ||
219 | // enum user_err | |
220 | // { | |
221 | // user_success = 0, | |
222 | // user_permission_denied, | |
223 | // user_out_of_memory | |
224 | // }; | |
225 | // | |
226 | // class user_error_category_imp : public boost::system::error_category | |
227 | // { | |
228 | // public: | |
229 | // const std::string & name() const | |
230 | // { | |
231 | // static std::string s( "test3" ); | |
232 | // return s; | |
233 | // } | |
234 | // | |
235 | // boost::system::error_code portable_error_code( int ev ) const | |
236 | // { | |
237 | // switch (ev) | |
238 | // { | |
239 | // case user_success: | |
240 | // return boost::system::error_code(boost::system::errc::success, boost::system::generic_category()); | |
241 | // case user_permission_denied: | |
242 | // return boost::system::error_code(boost::system::errc::permission_denied, boost::system::generic_category()); | |
243 | // case user_out_of_memory: | |
244 | // return boost::system::error_code(boost::system::errc::not_enough_memory, boost::system::generic_category()); | |
245 | // default: | |
246 | // break; | |
247 | // } | |
248 | // return boost::system::error_code(boost::system::errc::no_posix_equivalent, boost::system::generic_category()); | |
249 | // } | |
250 | // | |
251 | // }; | |
252 | // | |
253 | // const user_error_category_imp user_error_category_const; | |
254 | // | |
255 | // const boost::system::error_category & user_error_category | |
256 | // = user_error_category_const; | |
257 | // | |
258 | // template<> inline boost::system::error_code make_error_code(user_err e) | |
259 | // { | |
260 | // return boost::system::error_code(e, user_error_category); | |
261 | // } | |
262 | // | |
263 | // // test code | |
264 | // | |
265 | // void check_success(const boost::system::error_code& ec, bool expect) | |
266 | // { | |
267 | // BOOST_TEST( (ec == boost::system::errc::success) == expect ); | |
268 | // if (ec == boost::system::errc::success) | |
269 | // std::cout << "yes... " << (expect ? "ok" : "fail") << '\n'; | |
270 | // else | |
271 | // std::cout << "no... " << (expect ? "fail" : "ok") << '\n'; | |
272 | // } | |
273 | // | |
274 | // void check_permission_denied(const boost::system::error_code& ec, bool expect) | |
275 | // { | |
276 | // BOOST_TEST( (ec == boost::system::errc::permission_denied) == expect ); | |
277 | // if (ec == boost::system::errc::permission_denied) | |
278 | // std::cout << "yes... " << (expect ? "ok" : "fail") << '\n'; | |
279 | // else | |
280 | // std::cout << "no... " << (expect ? "fail" : "ok") << '\n'; | |
281 | // } | |
282 | // | |
283 | // void check_out_of_memory(const boost::system::error_code& ec, bool expect) | |
284 | // { | |
285 | // BOOST_TEST( (ec == boost::system::errc::not_enough_memory) == expect ); | |
286 | // if (ec == boost::system::errc::not_enough_memory) | |
287 | // std::cout << "yes... " << (expect ? "ok" : "fail") << '\n'; | |
288 | // else | |
289 | // std::cout << "no... " << (expect ? "fail" : "ok") << '\n'; | |
290 | // } | |
291 | // | |
292 | // void run() | |
293 | // { | |
294 | // printf("Test3\n"); | |
295 | // printf("=====\n"); | |
296 | // boost::system::error_code ec; | |
297 | // check_success(ec, true); | |
298 | // check_success(boost::system::errc::success, true); | |
299 | // check_success(boost::system::errc::permission_denied, false); | |
300 | // check_success(boost::system::errc::not_enough_memory, false); | |
301 | // check_success(user_success, true); | |
302 | // check_success(user_permission_denied, false); | |
303 | // check_success(user_out_of_memory, false); | |
304 | // check_permission_denied(ec, false); | |
305 | // check_permission_denied(boost::system::errc::success, false); | |
306 | // check_permission_denied(boost::system::errc::permission_denied, true); | |
307 | // check_permission_denied(boost::system::errc::not_enough_memory, false); | |
308 | // check_permission_denied(user_success, false); | |
309 | // check_permission_denied(user_permission_denied, true); | |
310 | // check_permission_denied(user_out_of_memory, false); | |
311 | // check_out_of_memory(ec, false); | |
312 | // check_out_of_memory(boost::system::errc::success, false); | |
313 | // check_out_of_memory(boost::system::errc::permission_denied, false); | |
314 | // check_out_of_memory(boost::system::errc::not_enough_memory, true); | |
315 | // check_out_of_memory(user_success, false); | |
316 | // check_out_of_memory(user_permission_denied, false); | |
317 | // check_out_of_memory(user_out_of_memory, true); | |
318 | // | |
319 | //# ifdef BOOST_WINDOWS_API | |
320 | // check_success(boost::system::windows::success, true); | |
321 | // check_success(boost::system::windows::access_denied, false); | |
322 | // check_success(boost::system::windows::not_enough_memory, false); | |
323 | // check_permission_denied(boost::system::windows::success, false); | |
324 | // check_permission_denied(boost::system::windows::access_denied, true); | |
325 | // check_permission_denied(boost::system::windows::not_enough_memory, false); | |
326 | // check_out_of_memory(boost::system::windows::success, false); | |
327 | // check_out_of_memory(boost::system::windows::access_denied, false); | |
328 | // check_out_of_memory(boost::system::windows::not_enough_memory, true); | |
329 | //# endif | |
330 | // | |
331 | // printf("\n"); | |
332 | // } | |
333 | // | |
334 | //} // namespace test3 | |
335 | ||
336 | ||
337 | ||
338 | // ------------------------------------------------------------------------ // | |
339 | ||
340 | int main( int, char *[] ) | |
341 | { | |
342 | boost::system::error_code ec; | |
343 | ||
344 | // Library 1 tests: | |
345 | ||
346 | ec = my_mkdir( "/no-such-file-or-directory/will-not-succeed" ); | |
347 | std::cout << "ec.value() is " << ec.value() << '\n'; | |
348 | ||
349 | BOOST_TEST( ec ); | |
350 | BOOST_TEST( ec == boost::system::errc::no_such_file_or_directory ); | |
351 | BOOST_TEST( ec.category() == boost::system::system_category() ); | |
352 | ||
353 | // Library 2 tests: | |
354 | ||
355 | ec = my_remove( "/no-such-file-or-directory" ); | |
356 | std::cout << "ec.value() is " << ec.value() << '\n'; | |
357 | ||
358 | BOOST_TEST( ec ); | |
359 | BOOST_TEST( ec == boost::system::errc::no_such_file_or_directory ); | |
360 | BOOST_TEST( ec.category() == boost::system::generic_category() ); | |
361 | ||
362 | // Library 3 tests: | |
363 | ||
364 | ec = boost::lib3::boo_boo; | |
365 | std::cout << "ec.value() is " << ec.value() << '\n'; | |
366 | ||
367 | BOOST_TEST( ec ); | |
368 | BOOST_TEST( ec == boost::lib3::boo_boo ); | |
369 | BOOST_TEST( ec.value() == boost::lib3::boo_boo ); | |
370 | BOOST_TEST( ec.category() == boost::lib3::lib3_error_category ); | |
371 | ||
372 | BOOST_TEST( ec == boost::system::errc::io_error ); | |
373 | ||
374 | boost::system::error_code ec3( boost::lib3::boo_boo+100, | |
375 | boost::lib3::lib3_error_category ); | |
376 | BOOST_TEST( ec3.category() == boost::lib3::lib3_error_category ); | |
377 | BOOST_TEST( ec3.default_error_condition().category() | |
378 | == boost::lib3::lib3_error_category ); | |
379 | ||
380 | // Library 4 tests: | |
381 | ||
382 | ec = lib4::boo_boo; | |
383 | std::cout << "ec.value() is " << ec.value() << '\n'; | |
384 | ||
385 | BOOST_TEST( ec ); | |
386 | BOOST_TEST( ec == lib4::boo_boo ); | |
387 | BOOST_TEST( ec.value() == lib4::boo_boo.value() ); | |
388 | BOOST_TEST( ec.category() == lib4::lib4_error_category ); | |
389 | ||
390 | BOOST_TEST( ec == boost::system::errc::io_error ); | |
391 | ||
392 | boost::system::error_code ec4( lib4::boo_boo.value()+100, | |
393 | lib4::lib4_error_category ); | |
394 | BOOST_TEST( ec4.default_error_condition().category() | |
395 | == lib4::lib4_error_category ); | |
396 | ||
397 | // Test 3 | |
398 | ||
399 | //test3::run(); | |
400 | ||
401 | return ::boost::report_errors(); | |
402 | } |