• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
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 
my_mkdir(const std::string & path)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 
my_remove(const std::string & path)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   {
make_error_code(error e)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:
lib3_error_category_imp()111       lib3_error_category_imp() : boost::system::error_category() { }
112 
name() const113       const char * name() const BOOST_SYSTEM_NOEXCEPT
114       {
115         return "lib3";
116       }
117 
default_error_condition(int ev) const118       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 
message(int ev) const127       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 
get_lib3_error_category()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:
lib4_error_category_imp()173     lib4_error_category_imp() : boost::system::error_category() { }
174 
name() const175     const char * name() const BOOST_SYSTEM_NOEXCEPT
176     {
177       return "lib4";
178     }
179 
default_error_condition(int ev) const180     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 
message(int ev) const188     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 
get_lib4_error_category()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 
main(int,char * [])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 }
403