1 /*=========================================================================
2 *
3 * Copyright Insight Software Consortium
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0.txt
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *=========================================================================*/
18 /*=========================================================================
19 *
20 * Portions of this file are subject to the VTK Toolkit Version 3 copyright.
21 *
22 * Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
23 *
24 * For complete copyright, license and disclaimer of warranty information
25 * please refer to the NOTICE file at the top of the ITK source tree.
26 *
27 *=========================================================================*/
28
29 #include "itkTestDriverIncludeRequiredIOFactories.h"
30
31
32 /* Select the environment variable holding the shared library runtime
33 search path for this platform. */
34
35 /* Linux */
36 #if defined(__linux) || (defined(__FreeBSD__)||defined(__DragonFly__)) || defined(__OpenBSD__)
37 # define ITK_TEST_DRIVER_LDPATH "LD_LIBRARY_PATH"
38 # define ITK_TEST_DRIVER_LDPATH64 ITK_TEST_DRIVER_LDPATH
39
40 /* OSX */
41 #elif defined(__APPLE__)
42 # define ITK_TEST_DRIVER_LDPATH "DYLD_LIBRARY_PATH"
43 # define ITK_TEST_DRIVER_LDPATH64 ITK_TEST_DRIVER_LDPATH
44
45 /* AIX */
46 #elif defined(_AIX)
47 # define ITK_TEST_DRIVER_LDPATH "LIBPATH"
48 # define ITK_TEST_DRIVER_LDPATH64 ITK_TEST_DRIVER_LDPATH
49
50 /* SUN */
51 #elif defined(__sun)
52 # define ITK_TEST_DRIVER_LDPATH "LD_LIBRARY_PATH"
53 # define ITK_TEST_DRIVER_LDPATH64 "LD_LIBRARY_PATH_64"
54
55 /* HP-UX */
56 #elif defined(__hpux)
57 # define ITK_TEST_DRIVER_LDPATH "SHLIB_PATH"
58 # define ITK_TEST_DRIVER_LDPATH64 "LD_LIBRARY_PATH"
59
60 /* SGI MIPS */
61 #elif defined(__sgi) && defined(_MIPS_SIM)
62 # if _MIPS_SIM == _ABIO32
63 # define ITK_TEST_DRIVER_LDPATH "LD_LIBRARY_PATH"
64 # elif _MIPS_SIM == _ABIN32
65 # define ITK_TEST_DRIVER_LDPATH "LD_LIBRARYN32_PATH"
66 # endif
67 # define ITK_TEST_DRIVER_LDPATH64 "LD_LIBRARY64_PATH"
68
69 /* Cygwin */
70 #elif defined(__CYGWIN__)
71 # define ITK_TEST_DRIVER_LDPATH "PATH"
72 # define ITK_TEST_DRIVER_LDPATH64 ITK_TEST_DRIVER_LDPATH
73
74 /* Windows */
75 #elif defined(_WIN32)
76 # define ITK_TEST_DRIVER_LDPATH "PATH"
77 # define ITK_TEST_DRIVER_LDPATH64 ITK_TEST_DRIVER_LDPATH
78
79 /* Guess on this unknown system. */
80 #else
81 # define ITK_TEST_DRIVER_LDPATH "LD_LIBRARY_PATH"
82 # define ITK_TEST_DRIVER_LDPATH64 ITK_TEST_DRIVER_LDPATH
83 #endif
84
85 #if defined(_WIN32) && !defined(__CYGWIN__)
86 # define ITK_TEST_DRIVER_PATH_SEP ';'
87 # define ITK_TEST_DRIVER_PATH_SLASH '\\'
88 #else
89 # define ITK_TEST_DRIVER_PATH_SEP ':'
90 # define ITK_TEST_DRIVER_PATH_SLASH '/'
91 #endif
92
93
AddEntriesBeforeLibraryPath(const ArgumentsList & args)94 void AddEntriesBeforeLibraryPath( const ArgumentsList & args )
95 {
96 unsigned int i = 0;
97
98 while( i < args.size() )
99 {
100 std::string libpath = ITK_TEST_DRIVER_LDPATH;
101 libpath += "=";
102 libpath += args[i];
103 char *oldenv = getenv(ITK_TEST_DRIVER_LDPATH);
104 if ( oldenv )
105 {
106 libpath += ITK_TEST_DRIVER_PATH_SEP;
107 libpath += oldenv;
108 }
109 itksys::SystemTools::PutEnv( libpath.c_str() );
110 // on some 64 bit systems, LD_LIBRARY_PATH_64 is used before
111 // LD_LIBRARY_PATH if it is set. It can lead the test to load
112 // the system library instead of the expected one, so this
113 // var must also be set
114 if ( std::string(ITK_TEST_DRIVER_LDPATH) != ITK_TEST_DRIVER_LDPATH64 )
115 {
116 std::string libpath64 = ITK_TEST_DRIVER_LDPATH64;
117 libpath64 += "=";
118 libpath64 += args[i];
119 char *oldenv64 = getenv(ITK_TEST_DRIVER_LDPATH64);
120 if ( oldenv64 )
121 {
122 libpath64 += ITK_TEST_DRIVER_PATH_SEP;
123 libpath64 += oldenv64;
124 }
125 itksys::SystemTools::PutEnv( libpath64.c_str() );
126 }
127
128 i++;
129 }
130 }
131
132
AddEntriesBeforeEnvironment(const ArgumentsList & args)133 void AddEntriesBeforeEnvironment( const ArgumentsList & args )
134 {
135 unsigned int i = 0;
136
137 while( i < args.size() )
138 {
139 std::string env = args[i];
140 env += "=";
141 env += args[i+1];
142 char *oldenv = getenv( args[i] );
143 if ( oldenv )
144 {
145 env += ITK_TEST_DRIVER_PATH_SEP;
146 env += oldenv;
147 }
148 itksys::SystemTools::PutEnv( env.c_str() );
149
150 i += 2;
151 }
152 }
153
154
AddEntriesBeforeEnvironmentWithSeparator(const ArgumentsList & args)155 void AddEntriesBeforeEnvironmentWithSeparator( const ArgumentsList & args )
156 {
157 unsigned int i = 0;
158
159 while( i < args.size() )
160 {
161 std::string env = args[i];
162 env += "=";
163 env += args[i+1];
164 char *oldenv = getenv( args[i] );
165 if ( oldenv )
166 {
167 env += args[i+2];
168 env += oldenv;
169 }
170 itksys::SystemTools::PutEnv( env.c_str() );
171
172 i += 3;
173 }
174 }
175
176
TestDriverInvokeProcess(const ArgumentsList & args)177 int TestDriverInvokeProcess( const ArgumentsList & args )
178 {
179 // a nullptr is required at the end of the table
180 auto ** argv = new char *[args.size() + 1];
181 for ( unsigned int i = 0; i < args.size(); i++ )
182 {
183 argv[i] = args[i];
184 }
185 argv[args.size()] = nullptr;
186
187 itksysProcess *process = itksysProcess_New();
188 itksysProcess_SetCommand(process, argv);
189 itksysProcess_SetPipeShared(process, itksysProcess_Pipe_STDOUT, true);
190 itksysProcess_SetPipeShared(process, itksysProcess_Pipe_STDERR, true);
191 itksysProcess_Execute(process);
192 itksysProcess_WaitForExit(process, nullptr);
193
194 delete[] argv;
195
196 int state = itksysProcess_GetState(process);
197 switch( state )
198 {
199 case itksysProcess_State_Error:
200 {
201 std::cerr << "itkTestDriver: Process error: " << itksysProcess_GetErrorString(process) << std::endl;
202 itksysProcess_Delete(process);
203 return 1;
204 }
205 case itksysProcess_State_Exception:
206 {
207 std::cerr << "itkTestDriver: Process exception: " << itksysProcess_GetExceptionString(process) << std::endl;
208 itksysProcess_Delete(process);
209 return 1;
210 }
211 case itksysProcess_State_Executing:
212 {
213 // this is not a possible state after itksysProcess_WaitForExit
214 std::cerr << "itkTestDriver: Internal error: process can't be in Executing State." << std::endl;
215 itksysProcess_Delete(process);
216 return 1;
217 }
218 case itksysProcess_State_Exited:
219 {
220 // this is the normal case - it is treated later
221 break;
222 }
223 case itksysProcess_State_Expired:
224 {
225 // this is not a possible state after itksysProcess_WaitForExit
226 std::cerr << "itkTestDriver: Internal error: process can't be in Expired State." << std::endl;
227 itksysProcess_Delete(process);
228 return 1;
229 }
230 case itksysProcess_State_Killed:
231 {
232 std::cerr << "itkTestDriver: The process has been killed." << std::endl;
233 itksysProcess_Delete(process);
234 return 1;
235 }
236 case itksysProcess_State_Disowned:
237 {
238 std::cerr << "itkTestDriver: Process disowned." << std::endl;
239 itksysProcess_Delete(process);
240 return 1;
241 }
242 default:
243 {
244 // this is not a possible state after itksysProcess_WaitForExit
245 std::cerr << "itkTestDriver: Internal error: unknown State." << std::endl;
246 itksysProcess_Delete(process);
247 return 1;
248 }
249 }
250
251 int retCode = itksysProcess_GetExitValue(process);
252 if ( retCode != 0 )
253 {
254 std::cerr << "itkTestDriver: Process exited with return value: " << retCode << std::endl;
255 }
256 itksysProcess_Delete(process);
257 return retCode;
258 }
259
260
main(int ac,char * av[])261 int main(int ac, char *av[])
262 {
263 try
264 {
265 RegisterRequiredFactories();
266 }
267 catch( itk::ExceptionObject & err )
268 {
269 err.Print(std::cerr);
270 return EXIT_FAILURE;
271 }
272
273
274 ProcessedOutputType po;
275
276 int result = ProcessArguments(&ac, &av, &po);
277
278 if( result )
279 {
280 // There was a problem parsing the arguments, so usage has already
281 // been printed, just return
282 return 1;
283 }
284
285 if ( po.externalProcessMustBeCalled && po.args.empty() )
286 {
287 usage();
288 return 1;
289 }
290
291 if ( !po.externalProcessMustBeCalled && !po.args.empty() )
292 {
293 usage();
294 return 1;
295 }
296
297
298 if ( !result && po.externalProcessMustBeCalled )
299 {
300 AddEntriesBeforeLibraryPath( po.add_before_libpath );
301
302 AddEntriesBeforeEnvironment( po.add_before_env );
303
304 AddEntriesBeforeEnvironmentWithSeparator( po.add_before_env_with_sep );
305
306 result = TestDriverInvokeProcess( po.args );
307 }
308
309 if (result == 0)
310 {
311 #include "itkTestDriverBeforeTest.inc"
312 #include "itkTestDriverAfterTest.inc"
313 }
314
315 return result;
316 }
317