Imported Upstream version 1.64.0
[platform/upstream/boost.git] / boost / test / impl / unit_test_parameters.ipp
1 //  (C) Copyright Gennadiy Rozental 2001.
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 //  File        : $RCSfile$
9 //
10 //  Version     : $Revision$
11 //
12 //  Description : simple implementation for Unit Test Framework parameter
13 //  handling routines. May be rewritten in future to use some kind of
14 //  command-line arguments parsing facility and environment variable handling
15 //  facility
16 // ***************************************************************************
17
18 #ifndef BOOST_TEST_UNIT_TEST_PARAMETERS_IPP_012205GER
19 #define BOOST_TEST_UNIT_TEST_PARAMETERS_IPP_012205GER
20
21 // Boost.Test
22 #include <boost/test/unit_test_parameters.hpp>
23
24 #include <boost/test/utils/basic_cstring/basic_cstring.hpp>
25 #include <boost/test/utils/basic_cstring/compare.hpp>
26 #include <boost/test/utils/basic_cstring/io.hpp>
27 #include <boost/test/utils/iterator/token_iterator.hpp>
28
29 #include <boost/test/debug.hpp>
30 #include <boost/test/framework.hpp>
31
32 #include <boost/test/detail/log_level.hpp>
33 #include <boost/test/detail/throw_exception.hpp>
34
35 // Boost.Runtime.Param
36 #include <boost/test/utils/runtime/parameter.hpp>
37 #include <boost/test/utils/runtime/argument.hpp>
38 #include <boost/test/utils/runtime/finalize.hpp>
39 #include <boost/test/utils/runtime/cla/parser.hpp>
40 #include <boost/test/utils/runtime/env/fetch.hpp>
41
42 // Boost
43 #include <boost/config.hpp>
44 #include <boost/test/detail/suppress_warnings.hpp>
45 #include <boost/test/detail/enable_warnings.hpp>
46 #include <boost/optional.hpp>
47 #include <boost/cstdlib.hpp>
48
49 // STL
50 #include <cstdlib>
51 #include <iostream>
52 #include <fstream>
53
54 #include <boost/test/detail/suppress_warnings.hpp>
55
56 //____________________________________________________________________________//
57
58 # ifdef BOOST_NO_STDC_NAMESPACE
59 namespace std { using ::getenv; using ::strncmp; using ::strcmp; }
60 # endif
61
62 namespace boost {
63 namespace unit_test {
64
65 namespace rt = boost::runtime;
66
67 // ************************************************************************** //
68 // **************                 runtime_config               ************** //
69 // ************************************************************************** //
70
71 namespace runtime_config {
72
73 // UTF parameters
74 std::string btrt_auto_start_dbg    = "auto_start_dbg";
75 std::string btrt_break_exec_path   = "break_exec_path";
76 std::string btrt_build_info        = "build_info";
77 std::string btrt_catch_sys_errors  = "catch_system_errors";
78 std::string btrt_color_output      = "color_output";
79 std::string btrt_detect_fp_except  = "detect_fp_exceptions";
80 std::string btrt_detect_mem_leaks  = "detect_memory_leaks";
81 std::string btrt_list_content      = "list_content";
82 std::string btrt_list_labels       = "list_labels";
83 std::string btrt_log_format        = "log_format";
84 std::string btrt_log_level         = "log_level";
85 std::string btrt_log_sink          = "log_sink";
86 std::string btrt_combined_logger   = "logger";
87 std::string btrt_output_format     = "output_format";
88 std::string btrt_random_seed       = "random";
89 std::string btrt_report_format     = "report_format";
90 std::string btrt_report_level      = "report_level";
91 std::string btrt_report_mem_leaks  = "report_memory_leaks_to";
92 std::string btrt_report_sink       = "report_sink";
93 std::string btrt_result_code       = "result_code";
94 std::string btrt_run_filters       = "run_test";
95 std::string btrt_save_test_pattern = "save_pattern";
96 std::string btrt_show_progress     = "show_progress";
97 std::string btrt_use_alt_stack     = "use_alt_stack";
98 std::string btrt_wait_for_debugger = "wait_for_debugger";
99
100 std::string btrt_help              = "help";
101 std::string btrt_usage             = "usage";
102 std::string btrt_version           = "version";
103
104 //____________________________________________________________________________//
105
106 namespace {
107
108 void
109 register_parameters( rt::parameters_store& store )
110 {
111     rt::option auto_start_dbg( btrt_auto_start_dbg, (
112         rt::description = "Automatically attaches debugger in case of system level failure (signal).",
113         rt::env_var = "BOOST_TEST_AUTO_START_DBG",
114
115         rt::help = "Option " + btrt_auto_start_dbg + " specifies whether Boost.Test should attempt "
116                    "to attach a debugger when fatal system error occurs. At the moment this feature "
117                    "is only available on a few selected platforms: Win32 and *nix. There is a "
118                    "default debugger configured for these platforms. You can manually configure "
119                    "different debugger. For more details on how to configure the debugger see the "
120                    "Boost.Test debug API, specifically the function boost::debug::set_debugger."
121     ));
122
123     auto_start_dbg.add_cla_id( "--", btrt_auto_start_dbg, "=" );
124     auto_start_dbg.add_cla_id( "-", "d", " " );
125     store.add( auto_start_dbg );
126
127     ///////////////////////////////////////////////
128
129     rt::parameter<std::string> break_exec_path( btrt_break_exec_path, (
130         rt::description = "For the exception safety testing allows to break at specific execution path.",
131         rt::env_var = "BOOST_TEST_BREAK_EXEC_PATH"
132 #ifndef BOOST_NO_CXX11_LAMBDAS
133         ,
134         rt::callback = [](rt::cstring) {
135             BOOST_TEST_SETUP_ASSERT( false, "parameter break_exec_path is disabled in this release" );
136         }
137 #endif
138     ));
139
140     break_exec_path.add_cla_id( "--", btrt_break_exec_path, "=" );
141     store.add( break_exec_path );
142
143     ///////////////////////////////////////////////
144
145     rt::option build_info( btrt_build_info, (
146         rt::description = "Displays library build information.",
147         rt::env_var = "BOOST_TEST_BUILD_INFO",
148         rt::help = "Option " + btrt_build_info + " displays library build information, including: platform, "
149                    "compiler, STL version and Boost version."
150     ));
151
152     build_info.add_cla_id( "--", btrt_build_info, "=" );
153     build_info.add_cla_id( "-", "i", " " );
154     store.add( build_info );
155
156     ///////////////////////////////////////////////
157
158     rt::option catch_sys_errors( btrt_catch_sys_errors, (
159         rt::description = "Allows to switch between catching and ignoring system errors (signals).",
160         rt::env_var = "BOOST_TEST_CATCH_SYSTEM_ERRORS",
161         rt::default_value =
162 #ifdef BOOST_TEST_DEFAULTS_TO_CORE_DUMP
163             false,
164 #else
165             true,
166 #endif
167         rt::help = "If option " + btrt_catch_sys_errors + " has value no the frameworks does not attempt to catch "
168                    "asynchronous system failure events (signals on *NIX platforms or structured exceptions on Windows). "
169                    " Default value is "
170 #ifdef BOOST_TEST_DEFAULTS_TO_CORE_DUMP
171                     "no."
172 #else
173                     "true."
174 #endif
175     ));
176
177     catch_sys_errors.add_cla_id( "--", btrt_catch_sys_errors, "=", true );
178     catch_sys_errors.add_cla_id( "-", "s", " " );
179     store.add( catch_sys_errors );
180
181     ///////////////////////////////////////////////
182
183     rt::option color_output( btrt_color_output, (
184         rt::description = "Enables color output of the framework log and report messages.",
185         rt::env_var = "BOOST_TEST_COLOR_OUTPUT",
186         rt::help = "The framework is able to produce color output on systems which supports it. "
187                    "To enable this behavior set this option to yes. By default the framework "
188                    "does not produces color output."
189     ));
190
191     color_output.add_cla_id( "--", btrt_color_output, "=", true );
192     color_output.add_cla_id( "-", "x", " " );
193     store.add( color_output );
194
195     ///////////////////////////////////////////////
196
197     rt::option detect_fp_except( btrt_detect_fp_except, (
198         rt::description = "Enables/disables floating point exceptions traps.",
199         rt::env_var = "BOOST_TEST_DETECT_FP_EXCEPTIONS",
200         rt::help = "Option " + btrt_detect_fp_except + " enables/disables hardware traps for the floating "
201                    "point exceptions (if supported on your platfrom)."
202     ));
203
204     detect_fp_except.add_cla_id( "--", btrt_detect_fp_except, "=", true );
205     store.add( detect_fp_except );
206
207     ///////////////////////////////////////////////
208
209     rt::parameter<unsigned long> detect_mem_leaks( btrt_detect_mem_leaks, (
210         rt::description = "Turns on/off memory leaks detection (optionally breaking on specified alloc order number).",
211         rt::env_var = "BOOST_TEST_DETECT_MEMORY_LEAK",
212         rt::default_value = 1L,
213         rt::optional_value = 1L,
214         rt::value_hint = "<alloc order number>",
215         rt::help = "Parameter " + btrt_detect_mem_leaks + " enables/disables memory leaks detection. "
216                    "This parameter has optional long integer value. The default value is 1, which "
217                    "enables the memory leak detection. The value 0 disables memory leak detection. "
218                    "Any value N greater than 1 is treated as leak allocation number and tells the "
219                    "framework to setup runtime breakpoint at Nth heap allocation. If value is "
220                    "omitted the default value is assumed."
221     ));
222
223     detect_mem_leaks.add_cla_id( "--", btrt_detect_mem_leaks, "=" );
224     store.add( detect_mem_leaks );
225
226     ///////////////////////////////////////////////
227
228     rt::enum_parameter<unit_test::output_format> list_content( btrt_list_content, (
229         rt::description = "Lists the content of test tree - names of all test suites and test cases.",
230         rt::env_var = "BOOST_TEST_LIST_CONTENT",
231         rt::default_value = OF_INVALID,
232         rt::optional_value = OF_CLF,
233         rt::enum_values<unit_test::output_format>::value =
234 #if defined(BOOST_TEST_CLA_NEW_API)
235         {
236             { "HRF", OF_CLF },
237             { "DOT", OF_DOT }
238         },
239 #else
240         rt::enum_values_list<unit_test::output_format>()
241             ( "HRF", OF_CLF )
242             ( "DOT", OF_DOT )
243         ,
244 #endif
245         rt::help = "Parameter " + btrt_list_content + " instructs the framework to list the content "
246                    "of the test module instead of executing the test cases. Parameter accepts "
247                    "optional string value indicating the format of the output. Currently the "
248                    "framework supports two formats: human readable format (HRF) and dot graph "
249                    "format (DOT). If value is omitted HRF value is assumed."
250     ));
251     list_content.add_cla_id( "--", btrt_list_content, "=" );
252     store.add( list_content );
253
254     ///////////////////////////////////////////////
255
256     rt::option list_labels( btrt_list_labels, (
257         rt::description = "Lists all available labels.",
258         rt::env_var = "BOOST_TEST_LIST_LABELS",
259         rt::help = "Option " + btrt_list_labels + " instructs the framework to list all the the labels "
260                    "defined in the test module instead of executing the test cases."
261     ));
262
263     list_labels.add_cla_id( "--", btrt_list_labels, "=" );
264     store.add( list_labels );
265
266     ///////////////////////////////////////////////
267
268     rt::enum_parameter<unit_test::output_format> log_format( btrt_log_format, (
269         rt::description = "Specifies log format.",
270         rt::env_var = "BOOST_TEST_LOG_FORMAT",
271         rt::default_value = OF_CLF,
272         rt::enum_values<unit_test::output_format>::value =
273 #if defined(BOOST_TEST_CLA_NEW_API)
274         {
275             { "HRF", OF_CLF },
276             { "CLF", OF_CLF },
277             { "XML", OF_XML },
278             { "JUNIT", OF_JUNIT },
279         },
280 #else
281         rt::enum_values_list<unit_test::output_format>()
282             ( "HRF", OF_CLF )
283             ( "CLF", OF_CLF )
284             ( "XML", OF_XML )
285             ( "JUNIT", OF_JUNIT )
286         ,
287 #endif
288         rt::help = "Parameter " + btrt_log_format + " allows to set the frameowrk's log format to one "
289                    "of the formats supplied by the framework. The only acceptable values for this "
290                    "parameter are the names of the output formats supplied by the framework. By "
291                    "default the framework uses human readable format (HRF) for testing log. This "
292                    "format is similar to compiler error format. Alternatively you can specify XML "
293                    "or JUNIT as log format, which are easier to process by testing automation tools."
294     ));
295
296     log_format.add_cla_id( "--", btrt_log_format, "=" );
297     log_format.add_cla_id( "-", "f", " " );
298     store.add( log_format );
299
300     ///////////////////////////////////////////////
301
302     rt::enum_parameter<unit_test::log_level> log_level( btrt_log_level, (
303         rt::description = "Specifies log level.",
304         rt::env_var = "BOOST_TEST_LOG_LEVEL",
305         rt::default_value = log_all_errors,
306         rt::enum_values<unit_test::log_level>::value =
307 #if defined(BOOST_TEST_CLA_NEW_API)
308         {
309             { "all"           , log_successful_tests },
310             { "success"       , log_successful_tests },
311             { "test_suite"    , log_test_units },
312             { "unit_scope"    , log_test_units },
313             { "message"       , log_messages },
314             { "warning"       , log_warnings },
315             { "error"         , log_all_errors },
316             { "cpp_exception" , log_cpp_exception_errors },
317             { "system_error"  , log_system_errors },
318             { "fatal_error"   , log_fatal_errors },
319             { "nothing"       , log_nothing }
320         },
321 #else
322         rt::enum_values_list<unit_test::log_level>()
323             ( "all"           , log_successful_tests )
324             ( "success"       , log_successful_tests )
325             ( "test_suite"    , log_test_units )
326             ( "unit_scope"    , log_test_units )
327             ( "message"       , log_messages )
328             ( "warning"       , log_warnings )
329             ( "error"         , log_all_errors )
330             ( "cpp_exception" , log_cpp_exception_errors )
331             ( "system_error"  , log_system_errors )
332             ( "fatal_error"   , log_fatal_errors )
333             ( "nothing"       , log_nothing )
334         ,
335 #endif
336         rt::help = "Parameter " + btrt_log_level + " allows to set the framework's log level. "
337                    "Log level defines the verbosity of testing log produced by a testing "
338                    "module. The verbosity ranges from a complete log, when all assertions "
339                    "(both successful and failing) are reported, all notifications about "
340                    "test units start and finish are included, to an empty log when nothing "
341                    "is reported to a testing log stream."
342     ));
343
344     log_level.add_cla_id( "--", btrt_log_level, "=" );
345     log_level.add_cla_id( "-", "l", " " );
346     store.add( log_level );
347
348     ///////////////////////////////////////////////
349
350     rt::parameter<std::string> log_sink( btrt_log_sink, (
351         rt::description = "Specifies log sink: stdout(default), stderr or file name.",
352         rt::env_var = "BOOST_TEST_LOG_SINK",
353         rt::value_hint = "<stderr|stdout|file name>",
354         rt::help = "Parameter " + btrt_log_sink + " allows to set the log sink - location "
355                    "where we report the log to, thus it allows to easily redirect the "
356                    "test logs to file or standard streams. By default testing log is "
357                    "directed to standard output."
358     ));
359
360     log_sink.add_cla_id( "--", btrt_log_sink, "=" );
361     log_sink.add_cla_id( "-", "k", " " );
362     store.add( log_sink );
363
364     ///////////////////////////////////////////////
365
366     rt::enum_parameter<unit_test::output_format> output_format( btrt_output_format, (
367         rt::description = "Specifies output format (both log and report).",
368         rt::env_var = "BOOST_TEST_OUTPUT_FORMAT",
369         rt::enum_values<unit_test::output_format>::value =
370 #if defined(BOOST_TEST_CLA_NEW_API)
371         {
372             { "HRF", OF_CLF },
373             { "CLF", OF_CLF },
374             { "XML", OF_XML }
375         },
376 #else
377         rt::enum_values_list<unit_test::output_format>()
378             ( "HRF", OF_CLF )
379             ( "CLF", OF_CLF )
380             ( "XML", OF_XML )
381         ,
382 #endif
383         rt::help = "Parameter " + btrt_output_format + " combines an effect of " + btrt_report_format +
384                    " and " + btrt_log_format + " parameters. This parameter has higher priority "
385                    "than either one of them. In other words if this parameter is specified "
386                    "it overrides the value of other two parameters. This parameter does not "
387                    "have a default value. The only acceptable values are string names of "
388                    "output formats: HRF - human readable format and XML - XML formats for "
389                    "automation tools processing."
390     ));
391
392     output_format.add_cla_id( "--", btrt_output_format, "=" );
393     output_format.add_cla_id( "-", "o", " " );
394     store.add( output_format );
395
396     /////////////////////////////////////////////// combined logger option
397
398     rt::parameter<std::string,rt::REPEATABLE_PARAM> combined_logger( btrt_combined_logger, (
399         rt::description = "Specifies log level and sink for one or several log format",
400         rt::env_var = "BOOST_TEST_LOGGER",
401         rt::value_hint = "log_format:log_level:log_sink",
402         rt::help = "Parameter " + btrt_combined_logger + " allows to specify the logger type, level and sink\n"
403                    "in one command."
404     ));
405
406     combined_logger.add_cla_id( "--", btrt_combined_logger, "=" );
407     store.add( combined_logger );
408
409     ///////////////////////////////////////////////
410
411     rt::parameter<unsigned> random_seed( btrt_random_seed, (
412         rt::description = "Allows to switch between sequential and random order of test units execution."
413                           " Optionally allows to specify concrete seed for random number generator.",
414         rt::env_var = "BOOST_TEST_RANDOM",
415         rt::default_value = 0U,
416         rt::optional_value = 1U,
417         rt::value_hint = "<seed>",
418         rt::help = "Parameter " + btrt_random_seed + " instructs the framework to execute the "
419                    "test cases in random order. This parameter accepts optional unsigned "
420                    "integer argument. By default test cases are executed in some specific "
421                    "order defined by order of test units in test files and dependency between "
422                    "test units. If parameter is specified without the argument value testing "
423                    "order is randomized based on current time. Alternatively you can specify "
424                    "any positive value greater than 1 and it will be used as random seed for "
425                    "the run."
426     ));
427
428     random_seed.add_cla_id( "--", btrt_random_seed, "=" );
429     store.add( random_seed );
430
431     ///////////////////////////////////////////////
432
433     rt::enum_parameter<unit_test::output_format> report_format( btrt_report_format, (
434         rt::description = "Specifies report format.",
435         rt::env_var = "BOOST_TEST_REPORT_FORMAT",
436         rt::default_value = OF_CLF,
437         rt::enum_values<unit_test::output_format>::value =
438 #if defined(BOOST_TEST_CLA_NEW_API)
439         {
440             { "HRF", OF_CLF },
441             { "CLF", OF_CLF },
442             { "XML", OF_XML }
443         },
444 #else
445         rt::enum_values_list<unit_test::output_format>()
446             ( "HRF", OF_CLF )
447             ( "CLF", OF_CLF )
448             ( "XML", OF_XML )
449         ,
450 #endif
451         rt::help = "Parameter " + btrt_report_format + " allows to set the framework's report format "
452                    "to one of the formats supplied by the framework. The only acceptable values "
453                    "for this parameter are the names of the output formats. By default the framework "
454                    "uses human readable format (HRF) for results reporting. Alternatively you can "
455                    "specify XML as report format. This format is easier to process by testing "
456                    "automation tools."
457     ));
458
459     report_format.add_cla_id( "--", btrt_report_format, "=" );
460     report_format.add_cla_id( "-", "m", " " );
461     store.add( report_format );
462
463     ///////////////////////////////////////////////
464
465     rt::enum_parameter<unit_test::report_level> report_level( btrt_report_level, (
466         rt::description = "Specifies report level.",
467         rt::env_var = "BOOST_TEST_REPORT_LEVEL",
468         rt::default_value = CONFIRMATION_REPORT,
469         rt::enum_values<unit_test::report_level>::value =
470 #if defined(BOOST_TEST_CLA_NEW_API)
471         {
472             { "confirm",  CONFIRMATION_REPORT },
473             { "short",    SHORT_REPORT },
474             { "detailed", DETAILED_REPORT },
475             { "no",       NO_REPORT }
476         },
477 #else
478         rt::enum_values_list<unit_test::report_level>()
479             ( "confirm",  CONFIRMATION_REPORT )
480             ( "short",    SHORT_REPORT )
481             ( "detailed", DETAILED_REPORT )
482             ( "no",       NO_REPORT )
483         ,
484 #endif
485         rt::help = "Parameter " + btrt_report_level + " allows to set the verbosity level of the "
486                    "testing result report generated by the framework. Use value 'no' to "
487                    "eliminate the results report completely."
488     ));
489
490     report_level.add_cla_id( "--", btrt_report_level, "=" );
491     report_level.add_cla_id( "-", "r", " " );
492     store.add( report_level );
493
494     ///////////////////////////////////////////////
495
496     rt::parameter<std::string> report_mem_leaks( btrt_report_mem_leaks, (
497         rt::description = "File where to report memory leaks to.",
498         rt::env_var = "BOOST_TEST_REPORT_MEMORY_LEAKS_TO",
499         rt::default_value = std::string(),
500         rt::value_hint = "<file name>",
501         rt::help = "Parameter " + btrt_report_mem_leaks + " allows to specify a file where to report "
502                    "memory leaks to. The parameter does not have default value. If it is not specified, "
503                    "memory leaks (if any) are reported to the standard error stream."
504     ));
505
506     report_mem_leaks.add_cla_id( "--", btrt_report_mem_leaks, "=" );
507     store.add( report_mem_leaks );
508
509     ///////////////////////////////////////////////
510
511     rt::parameter<std::string> report_sink( btrt_report_sink, (
512         rt::description = "Specifies report sink: stderr(default), stdout or file name.",
513         rt::env_var = "BOOST_TEST_REPORT_SINK",
514         rt::value_hint = "<stderr|stdout|file name>",
515         rt::help = "Parameter " + btrt_report_sink + " allows to set the result report sink - "
516                    "the location where the framework writes the result report to, thus it "
517                    "allows to easily redirect the result report to a file or a standard "
518                    "stream. By default the testing result report is directed to the "
519                    "standard error stream."
520     ));
521
522     report_sink.add_cla_id( "--", btrt_report_sink, "=" );
523     report_sink.add_cla_id( "-", "e", " " );
524     store.add( report_sink );
525
526     ///////////////////////////////////////////////
527
528     rt::option result_code( btrt_result_code, (
529         rt::description = "Disables test modules's result code generation.",
530         rt::env_var = "BOOST_TEST_RESULT_CODE",
531         rt::default_value = true,
532         rt::help = "The 'no' argument value for the parameter " + btrt_result_code + " instructs the "
533                    "framework to always return zero result code. This can be used for test programs "
534                    "executed within IDE. By default this parameter has value 'yes'."
535     ));
536
537     result_code.add_cla_id( "--", btrt_result_code, "=", true );
538     result_code.add_cla_id( "-", "c", " " );
539     store.add( result_code );
540
541     ///////////////////////////////////////////////
542
543     rt::parameter<std::string,rt::REPEATABLE_PARAM> tests_to_run( btrt_run_filters, (
544         rt::description = "Filters, which test units to include or exclude from test module execution.",
545         rt::env_var = "BOOST_TEST_RUN_FILTERS",
546         rt::value_hint = "<test unit filter>",
547         rt::help = "Parameter " + btrt_run_filters + " allows to filter which test units to execute during "
548                    "testing. The framework supports both 'selection filters', which allow to select "
549                    "which test units to enable from the set of available test units, and 'disabler "
550                    "filters', which allow to disable some test units. The __UTF__ also supports "
551                    "enabling/disabling test units at compile time. These settings identify the default "
552                    "set of test units to run. Parameter " + btrt_run_filters + " is used to change this default. "
553                    "This parameter is repeatable, so you can specify more than one filter if necessary."
554     ));
555
556     tests_to_run.add_cla_id( "--", btrt_run_filters, "=" );
557     tests_to_run.add_cla_id( "-", "t", " " );
558     store.add( tests_to_run );
559
560     ///////////////////////////////////////////////
561
562     rt::option save_test_pattern( btrt_save_test_pattern, (
563         rt::description = "Allows to switch between saving or matching test pattern file.",
564         rt::env_var = "BOOST_TEST_SAVE_PATTERN",
565         rt::help = "Parameter " + btrt_save_test_pattern + " facilitates switching mode of operation for "
566                    "testing output streams.\n\nThis parameter serves no particular purpose within the "
567                    "framework itself. It can be used by test modules relying on output_test_stream to "
568                    "implement testing logic. Default mode is 'match' (false)."
569     ));
570
571     save_test_pattern.add_cla_id( "--", btrt_save_test_pattern, "=" );
572     store.add( save_test_pattern );
573
574     ///////////////////////////////////////////////
575
576     rt::option show_progress( btrt_show_progress, (
577         rt::description = "Turns on progress display.",
578         rt::env_var = "BOOST_TEST_SHOW_PROGRESS",
579         rt::help = "Parameter " + btrt_show_progress + " instructs the framework to display test progress "
580                    "information. By default the test progress is not shown."
581     ));
582
583     show_progress.add_cla_id( "--", btrt_show_progress, "=" );
584     show_progress.add_cla_id( "-", "p", " " );
585     store.add( show_progress );
586
587     ///////////////////////////////////////////////
588
589     rt::option use_alt_stack( btrt_use_alt_stack, (
590         rt::description = "Turns on/off usage of an alternative stack for signal handling.",
591         rt::env_var = "BOOST_TEST_USE_ALT_STACK",
592         rt::default_value = true,
593         rt::help = "Parameter " + btrt_use_alt_stack + " instructs the framework to use alternative "
594                    "stack for signals processing, on platforms where they are supported. The feature "
595                    "is enabled by default, but can be disabled using this parameter."
596     ));
597
598     use_alt_stack.add_cla_id( "--", btrt_use_alt_stack, "=", true );
599     store.add( use_alt_stack );
600
601     ///////////////////////////////////////////////
602
603     rt::option wait_for_debugger( btrt_wait_for_debugger, (
604         rt::description = "Forces test module to wait for button to be pressed before starting test run.",
605         rt::env_var = "BOOST_TEST_WAIT_FOR_DEBUGGER",
606         rt::help = "Parameter " + btrt_wait_for_debugger + " instructs the framework to pause before starting "
607                    "test units execution, so that you can attach a debugger to running test module. By "
608                    "default this parameters turned off."
609     ));
610
611     wait_for_debugger.add_cla_id( "--", btrt_wait_for_debugger, "=" );
612     wait_for_debugger.add_cla_id( "-", "w", " " );
613     store.add( wait_for_debugger );
614
615     ///////////////////////////////////////////////
616
617     rt::parameter<std::string> help( btrt_help, (
618         rt::description = "Help for framework parameters.",
619         rt::optional_value = std::string(),
620         rt::value_hint = "<parameter name>",
621         rt::help = "Parameter " + btrt_help + " displays help on the framework's parameters. "
622                    "The parameter accepts an optional argument value. If present, an argument value is "
623                    "interpreted as a parameter name (name guessing works as well, so for example "
624                    "--help=rand displays help on the parameter random). If the parameter name is unknown "
625                    "or ambiguous error is reported. If argument value is absent, a summary of all "
626                    "framework's parameter is displayed."
627     ));
628     help.add_cla_id( "--", btrt_help, "=" );
629     store.add( help );
630
631     ///////////////////////////////////////////////
632
633     rt::option usage( btrt_usage, (
634         rt::description = "Short message explaining usage of Boost.Test parameters."
635     ));
636     usage.add_cla_id( "-", "?", " " );
637     store.add( usage );
638
639     ///////////////////////////////////////////////
640
641     rt::option version( btrt_version, (
642         rt::description = "Prints Boost.Test version and exits."
643     ));
644     version.add_cla_id( "--", btrt_version, " " );
645     store.add( version );
646 }
647
648 static rt::arguments_store  s_arguments_store;
649 static rt::parameters_store s_parameters_store;
650
651 //____________________________________________________________________________//
652
653 } // local namespace
654
655 void
656 init( int& argc, char** argv )
657 {
658     shared_ptr<rt::cla::parser> parser;
659
660     BOOST_TEST_I_TRY {
661         // Initialize parameters list
662         if( s_parameters_store.is_empty() )
663             register_parameters( s_parameters_store );
664
665         // Clear up arguments store just in case (of multiple init invocations)
666         s_arguments_store.clear();
667
668         // Parse CLA they take precedence over  environment
669         parser.reset( new rt::cla::parser( s_parameters_store, (rt::end_of_params = "--", rt::negation_prefix = "no_") ) );
670         argc = parser->parse( argc, argv, s_arguments_store );
671
672         // Try to fetch missing arguments from environment
673         rt::env::fetch_absent( s_parameters_store, s_arguments_store );
674
675         // Set arguments to default values if defined and perform all the validations
676         rt::finalize_arguments( s_parameters_store, s_arguments_store );
677
678         // Report help if requested
679         if( runtime_config::get<bool>( btrt_version ) ) {
680             parser->version( std::cerr );
681             BOOST_TEST_I_THROW( framework::nothing_to_test( boost::exit_success ) );
682         }
683         else if( runtime_config::get<bool>( btrt_usage ) ) {
684             parser->usage( std::cerr );
685             BOOST_TEST_I_THROW( framework::nothing_to_test( boost::exit_success ) );
686         }
687         else if( s_arguments_store.has( btrt_help ) ) {
688             parser->help( std::cerr, s_parameters_store, runtime_config::get<std::string>( btrt_help ) );
689             BOOST_TEST_I_THROW( framework::nothing_to_test( boost::exit_success ) );
690         }
691
692         // A bit of business logic: output_format takes precedence over log/report formats
693         if( s_arguments_store.has( btrt_output_format ) ) {
694             unit_test::output_format of = s_arguments_store.get<unit_test::output_format>( btrt_output_format );
695             s_arguments_store.set( btrt_report_format, of );
696             s_arguments_store.set( btrt_log_format, of );
697         }
698
699     }
700     BOOST_TEST_I_CATCH( rt::init_error, ex ) {
701         BOOST_TEST_SETUP_ASSERT( false, ex.msg );
702     }
703     BOOST_TEST_I_CATCH( rt::ambiguous_param, ex ) {
704         std::cerr << ex.msg << "\n Did you mean one of these?\n";
705
706         BOOST_TEST_FOREACH( rt::cstring, name, ex.m_amb_candidates )
707             std::cerr << "   " << name << "\n";
708
709         BOOST_TEST_I_THROW( framework::nothing_to_test( boost::exit_exception_failure ) );
710     }
711     BOOST_TEST_I_CATCH( rt::unrecognized_param, ex ) {
712         std::cerr << ex.msg << "\n";
713
714         if( !ex.m_typo_candidates.empty() ) {
715             std::cerr << " Did you mean one of these?\n";
716
717             BOOST_TEST_FOREACH( rt::cstring, name, ex.m_typo_candidates )
718                 std::cerr << "   " << name << "\n";
719         }
720         else if( parser ) {
721             std::cerr << "\n";
722             parser->usage( std::cerr );
723         }
724
725         BOOST_TEST_I_THROW( framework::nothing_to_test( boost::exit_exception_failure ) );
726     }
727     BOOST_TEST_I_CATCH( rt::input_error, ex ) {
728         std::cerr << ex.msg << "\n\n";
729
730         if( parser )
731             parser->usage( std::cerr, ex.param_name );
732
733         BOOST_TEST_I_THROW( framework::nothing_to_test( boost::exit_exception_failure ) );
734     }
735 }
736
737 //____________________________________________________________________________//
738
739 rt::arguments_store const&
740 argument_store()
741 {
742     return s_arguments_store;
743 }
744
745 //____________________________________________________________________________//
746
747 bool
748 save_pattern()
749 {
750     return runtime_config::get<bool>( btrt_save_test_pattern );
751 }
752
753 //____________________________________________________________________________//
754
755 } // namespace runtime_config
756 } // namespace unit_test
757 } // namespace boost
758
759 #include <boost/test/detail/enable_warnings.hpp>
760
761 #endif // BOOST_TEST_UNIT_TEST_PARAMETERS_IPP_012205GER