]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // (C) Copyright Gennadiy Rozental 2005-2014. |
2 | // Distributed under the Boost Software License, Version 1.0. | |
92f5a8d4 | 3 | // (See accompanying file LICENSE_1_0.txt or copy at |
7c673cae FG |
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 | |
92f5a8d4 TL |
15 | //#include <boost/test/utils/runtime/cla/named_parameter.hpp> |
16 | #include <boost/test/utils/named_params.hpp> | |
7c673cae FG |
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 | |
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 | |
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 | |
55 | close( handle h ) | |
56 | { | |
57 | if( h ) | |
58 | FreeLibrary( h ); | |
59 | } | |
60 | ||
61 | //_________________________________________________________________// | |
62 | ||
63 | inline std::string | |
64 | error() | |
65 | { | |
66 | LPTSTR msg = NULL; | |
67 | ||
68 | FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, | |
92f5a8d4 TL |
69 | NULL, |
70 | GetLastError(), | |
7c673cae | 71 | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), |
92f5a8d4 | 72 | (LPTSTR)&msg, |
7c673cae FG |
73 | 0, NULL ); |
74 | ||
75 | std::string res( msg ); | |
76 | ||
77 | if( msg ) | |
78 | LocalFree( msg ); | |
79 | ||
92f5a8d4 | 80 | return res; |
7c673cae FG |
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 | ||
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 ); | |
92f5a8d4 | 156 | |
7c673cae FG |
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() ) ); | |
92f5a8d4 | 162 | |
7c673cae FG |
163 | return (*init_func)(); |
164 | } | |
165 | ||
166 | //____________________________________________________________________________// | |
167 | ||
168 | int main( int argc, char* argv[] ) | |
169 | { | |
170 | try { | |
7c673cae | 171 | |
92f5a8d4 TL |
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; | |
7c673cae | 185 | |
92f5a8d4 | 186 | P.parse( argc, argv, args_store ); |
7c673cae | 187 | |
92f5a8d4 TL |
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" ); | |
7c673cae FG |
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 | } | |
92f5a8d4 TL |
199 | catch( rt::param_error const& ex ) { |
200 | std::cout << "Fail to parse command line arguments: " << ex.msg << std::endl; | |
7c673cae FG |
201 | return -1; |
202 | } | |
203 | } | |
204 | ||
205 | //____________________________________________________________________________// | |
206 | ||
207 | // EOF |