• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  //  (C) Copyright Gennadiy Rozental 2005-2014.
2  //  Distributed under the Boost Software License, Version 1.0.
3  //  (See accompanying file LICENSE_1_0.txt or copy at
4  //  http://www.boost.org/LICENSE_1_0.txt)
5  
6  //  See http://www.boost.org/libs/test for the library home page.
7  
8  // Boost.Test
9  #ifndef BOOST_TEST_DYN_LINK
10  #define BOOST_TEST_DYN_LINK
11  #endif
12  #include <boost/test/unit_test.hpp>
13  
14  // Boost.Runtime.Param
15  //#include <boost/test/utils/runtime/cla/named_parameter.hpp>
16  #include <boost/test/utils/named_params.hpp>
17  #include <boost/test/utils/runtime/cla/parser.hpp>
18  
19  namespace rt  = boost::runtime;
20  namespace cla = boost::runtime::cla;
21  
22  // STL
23  #include <iostream>
24  
25  //_________________________________________________________________//
26  
27  // System API
28  
29  namespace dyn_lib {
30  
31  #if defined(BOOST_WINDOWS) && !defined(BOOST_DISABLE_WIN32) // WIN32 API
32  
33  #include <windows.h>
34  
35  typedef HINSTANCE handle;
36  
37  inline handle
open(std::string const & file_name)38  open( std::string const& file_name )
39  {
40      return LoadLibrary( file_name.c_str() );
41  }
42  
43  //_________________________________________________________________//
44  
45  template<typename TargType>
46  inline TargType
locate_symbol(handle h,std::string const & symbol)47  locate_symbol( handle h, std::string const& symbol )
48  {
49      return reinterpret_cast<TargType>( GetProcAddress( h, symbol.c_str() ) );
50  }
51  
52  //_________________________________________________________________//
53  
54  inline void
close(handle h)55  close( handle h )
56  {
57      if( h )
58          FreeLibrary( h );
59  }
60  
61  //_________________________________________________________________//
62  
63  inline std::string
error()64  error()
65  {
66      LPTSTR msg = NULL;
67  
68      FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
69                     NULL,
70                     GetLastError(),
71                     MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
72                     (LPTSTR)&msg,
73                     0, NULL );
74  
75      std::string res( msg );
76  
77      if( msg )
78          LocalFree( msg );
79  
80      return res;
81  }
82  
83  //_________________________________________________________________//
84  
85  #elif defined(BOOST_HAS_UNISTD_H) // POSIX API
86  
87  #include <dlfcn.h>
88  
89  #include <sys/types.h>
90  #include <sys/stat.h>
91  #include <fcntl.h>
92  
93  
94  typedef void* handle;
95  
96  inline handle
97  open( std::string const& file_name )
98  {
99      return dlopen( file_name.c_str(), RTLD_LOCAL | RTLD_LAZY );
100  }
101  
102  //_________________________________________________________________//
103  
104  template<typename TargType>
105  inline TargType
106  locate_symbol( handle h, std::string const& symbol )
107  {
108      return reinterpret_cast<TargType>( dlsym( h, symbol.c_str() ) );
109  }
110  
111  //_________________________________________________________________//
112  
113  inline void
114  close( handle h )
115  {
116      if( h )
117          dlclose( h );
118  }
119  
120  //_________________________________________________________________//
121  
122  inline std::string
123  error()
124  {
125      return dlerror();
126  }
127  
128  //_________________________________________________________________//
129  
130  #else
131  
132  #error "Dynamic library API is unknown"
133  
134  #endif
135  
136  } // namespace dyn_lib
137  
138  //____________________________________________________________________________//
139  
140  static std::string test_lib_name;
141  static std::string init_func_name( "init_unit_test" );
142  
143  dyn_lib::handle test_lib_handle;
144  
load_test_lib()145  bool load_test_lib()
146  {
147      typedef bool (*init_func_ptr)();
148      init_func_ptr init_func;
149  
150      test_lib_handle = dyn_lib::open( test_lib_name );
151      if( !test_lib_handle )
152          throw std::logic_error( std::string("Fail to load test library: ")
153                                      .append( dyn_lib::error() ) );
154  
155      init_func =  dyn_lib::locate_symbol<init_func_ptr>( test_lib_handle, init_func_name );
156  
157      if( !init_func )
158          throw std::logic_error( std::string("Can't locate test initilization function ")
159                                      .append( init_func_name )
160                                      .append( ": " )
161                                      .append( dyn_lib::error() ) );
162  
163      return (*init_func)();
164  }
165  
166  //____________________________________________________________________________//
167  
main(int argc,char * argv[])168  int main( int argc, char* argv[] )
169  {
170      try {
171  
172          rt::parameters_store store;
173  
174          rt::parameter<rt::cstring, rt::REQUIRED_PARAM> p_test( "test" );
175          p_test.add_cla_id( "--", "test", " " );
176          store.add( p_test );
177  
178          rt::parameter<rt::cstring> p_init( "init" );
179          p_init.add_cla_id( "--", "init", " " );
180          store.add( p_init );
181  
182          rt::cla::parser P( store );
183  
184          rt::arguments_store args_store;
185  
186          P.parse( argc, argv, args_store );
187  
188          test_lib_name = args_store.get<std::string>( "test" );
189          if( args_store.has("init") )
190              init_func_name = args_store.get<std::string>( "init" );
191  
192          int res = ::boost::unit_test::unit_test_main( &load_test_lib, argc, argv );
193  
194          ::boost::unit_test::framework::clear();
195          dyn_lib::close( test_lib_handle );
196  
197          return res;
198      }
199      catch( rt::param_error const& ex ) {
200          std::cout << "Fail to parse command line arguments: " << ex.msg << std::endl;
201          return -1;
202      }
203  }
204  
205  //____________________________________________________________________________//
206  
207  // EOF
208