Teuchos - Trilinos Tools Package Version of the Day
Loading...
Searching...
No Matches
Teuchos_CommandLineProcessor.cpp
1// @HEADER
2// *****************************************************************************
3// Teuchos: Common Tools Package
4//
5// Copyright 2004 NTESS and the Teuchos contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10// //////////////////////////////////////////////////
11// Teuchos_CommandLineProcessor.cpp
12
13
16#include "Teuchos_VerboseObject.hpp"
17//#include "Teuchos_TimeMonitor.hpp"
18#include "Teuchos_Assert.hpp"
20#include "Teuchos_as.hpp"
21#ifndef _WIN32
22#include "Teuchos_Array.hpp"
23#include "unistd.h"
24#endif
25
26namespace {
27
28
29inline int my_max( int a, int b ) { return a > b ? a : b; }
30
31
32std::string remove_quotes( const std::string& str )
33{
34 if (str[0] == '\"' && str[str.size()-1] == '\"')
35 return str.substr(1,str.size()-2);
36 else if (str[0] == '\"')
37 return str.substr(1,str.size()-1);
38 else if (str[str.size()-1] == '\"')
39 return str.substr(0,str.size()-1);
40 return str;
41}
42
43
44std::string add_quotes( const std::string& str )
45{
46 if(str[0] == '\"')
47 return str;
48 return "\"" + str + "\"";
49}
50
51
52} // end namespace
53
54
55namespace Teuchos {
56
57
58const bool CommandLineProcessor::output_all_front_matter_default_(false);
59const bool CommandLineProcessor::output_show_line_prefix_default_(false);
60const bool CommandLineProcessor::output_show_tab_count_default_(false);
61const bool CommandLineProcessor::output_show_proc_rank_default_(false);
62const int CommandLineProcessor::output_to_root_rank_only_default_(0);
63const bool CommandLineProcessor::print_rcpnode_statistics_on_exit_default_(false);
64const bool CommandLineProcessor::show_timer_summary_on_exit_default_(false);
65const bool CommandLineProcessor::print_system_info_default_(false);
66
67
72 )
73 :throwExceptions_(throwExceptions_in)
74 ,recogniseAllOptions_(recogniseAllOptions_in)
75 ,addOutputSetupOptions_(addOutputSetupOptions_in)
76 ,output_all_front_matter_(output_all_front_matter_default_)
77 ,output_show_line_prefix_(output_show_line_prefix_default_)
78 ,output_show_tab_count_(output_show_tab_count_default_)
79 ,output_show_proc_rank_(output_show_proc_rank_default_)
80 ,output_to_root_rank_only_(output_to_root_rank_only_default_)
81 ,print_rcpnode_statistics_on_exit_(print_rcpnode_statistics_on_exit_default_)
82 ,show_timer_summary_on_exit_(show_timer_summary_on_exit_default_)
83 ,print_system_info_(print_system_info_default_)
84 ,printed_timer_summary_(false)
85 ,added_extra_output_setup_options_(false)
86 ,in_add_extra_output_setup_options_(false)
87{
88 SystemInformation::initializeCollection();
89}
90
91
96
97
98// Set up options
99
100
102{
103 doc_string_ = doc_string;
104}
105
106
108 const char option_true[]
109 ,const char option_false[]
110 ,bool *option_val
111 ,const char documentation[]
112 )
113{
114 add_extra_output_setup_options();
116 options_list_[std::string(option_true)]
117 = opt_val_val_t(OPT_BOOL_TRUE,any(option_val),false);
118 options_list_[std::string(option_false)]
119 = opt_val_val_t(OPT_BOOL_FALSE,any(option_val),false);
120 options_documentation_list_.push_back(
121 opt_doc_t(OPT_BOOL_TRUE, option_true, option_false,
122 std::string(documentation?documentation:""), any(option_val))
123 );
124}
125
126
128 const char option_name[]
129 ,int *option_val
130 ,const char documentation[]
131 ,const bool required
132 )
133{
134 add_extra_output_setup_options();
136 options_list_[std::string(option_name)]
137 = opt_val_val_t(OPT_INT,any(option_val),required);
138 options_documentation_list_.push_back(
139 opt_doc_t(OPT_INT, option_name, "", std::string(documentation?documentation:""),
141 );
142}
143
144
146 const char option_name[]
147 ,long int *option_val
148 ,const char documentation[]
149 ,const bool required
150 )
151{
152 add_extra_output_setup_options();
154 options_list_[std::string(option_name)]
155 = opt_val_val_t(OPT_LONG_INT,any(option_val),required);
156 options_documentation_list_.push_back(
157 opt_doc_t(OPT_LONG_INT, option_name, "", std::string(documentation?documentation:""),
159 );
160}
161
162
164 const char option_name[]
165 ,size_t *option_val
166 ,const char documentation[]
167 ,const bool required
168 )
169{
170 add_extra_output_setup_options();
172 options_list_[std::string(option_name)]
173 = opt_val_val_t(OPT_SIZE_T,any(option_val),required);
174 options_documentation_list_.push_back(
175 opt_doc_t(OPT_SIZE_T, option_name, "", std::string(documentation?documentation:""),
177 );
178}
179
181 const char option_name[]
182 ,long long int *option_val
183 ,const char documentation[]
184 ,const bool required
185 )
186{
187 add_extra_output_setup_options();
189 options_list_[std::string(option_name)]
190 = opt_val_val_t(OPT_LONG_LONG_INT,any(option_val),required);
191 options_documentation_list_.push_back(
192 opt_doc_t(OPT_LONG_LONG_INT, option_name, "", std::string(documentation?documentation:""),
194 );
195}
196
198 const char option_name[]
199 ,double *option_val
200 ,const char documentation[]
201 ,const bool required
202 )
203{
204 add_extra_output_setup_options();
206 options_list_[std::string(option_name)]
207 = opt_val_val_t(OPT_DOUBLE,any(option_val),required);
208 options_documentation_list_.push_back(
209 opt_doc_t(OPT_DOUBLE, option_name, "", std::string(documentation?documentation:""),
211 );
212}
213
215 const char option_name[]
216 ,float *option_val
217 ,const char documentation[]
218 ,const bool required
219 )
220{
221 add_extra_output_setup_options();
223 options_list_[std::string(option_name)]
224 = opt_val_val_t(OPT_FLOAT,any(option_val),required);
225 options_documentation_list_.push_back(
226 opt_doc_t(OPT_FLOAT, option_name, "", std::string(documentation?documentation:""),
228 );
229}
230
232 const char option_name[]
233 ,std::string *option_val
234 ,const char documentation[]
235 ,const bool required
236 )
237{
238 add_extra_output_setup_options();
240 options_list_[std::string(option_name)]
241 = opt_val_val_t(OPT_STRING,any(option_val),required);
242 options_documentation_list_.push_back(
243 opt_doc_t(OPT_STRING, option_name, "", std::string(documentation?documentation:""),
245 );
246}
247
248
249// Parse command line
250
251
254 int argc
255 ,char* argv[]
256 ,std::ostream *errout
257 ) const
258{
259 add_extra_output_setup_options();
260
261 if (options_list_.find("print-system-info") == options_list_.end()) {
262 CommandLineProcessor *clp = const_cast<CommandLineProcessor *>(this);
263 clp->setOption("print-system-info", "no-print-system-info",
264 &clp->print_system_info_,
265 "If true, then collect and print information about the system "
266 "we are running on.");
267
268 }
269
270 std::string opt_name;
271 std::string opt_val_str;
272 const std::string echo_cl_opt = "echo-command-line";
273 const std::string help_opt = "help";
274 const std::string pause_opt = "pause-for-debugging";
276
277 // check for help options before any others as we modify
278 // the values afterwards
279 for( int i = 1; i < argc; ++i ) {
280 bool gov_return = get_opt_val( argv[i], &opt_name, &opt_val_str );
281 if( gov_return && opt_name == help_opt ) {
283 return PARSE_HELP_PRINTED;
284 }
285 }
286 // check all other options
287 for( int i = 1; i < argc; ++i ) {
288 bool gov_return = get_opt_val( argv[i], &opt_name, &opt_val_str );
289 if( !gov_return ) {
290 if(procRank == 0)
291 print_bad_opt(i,argv,errout);
292 if( recogniseAllOptions() )
294 else {
295 continue;
296 }
297 }
298 if( opt_name == echo_cl_opt ) {
299 if(errout && procRank == 0) {
300 *errout << "\nEchoing the command-line:\n\n";
301 for( int j = 0; j < argc; ++j )
302 *errout << argv[j] << " ";
303 *errout << "\n\n";
304 }
305 continue;
306 }
307 if( opt_name == pause_opt ) {
308#ifndef _WIN32
311 int rank_pid = getpid();
313 if(procRank == 0)
314 for (int k=0; k<GlobalMPISession::getNProc(); k++)
315 std::cerr << "Rank " << k << " has PID " << pids[k] << std::endl;
316#endif
317 if(procRank == 0) {
318 std::cerr << "\nType 0 and press enter to continue : ";
319 int dummy_int = 0;
320 std::cin >> dummy_int;
321 }
323 continue;
324 }
325 // Lookup the option (we had better find it!)
326 options_list_t::iterator itr = options_list_.find(opt_name);
327 if( itr == options_list_.end() ) {
328 if(procRank == 0)
329 print_bad_opt(i,argv,errout);
330 if( recogniseAllOptions() )
332 else
333 continue;
334 }
335 // Changed access to second value of std::map to not use overloaded arrow operator,
336 // otherwise this code will not compile on Janus (HKT, 12/01/2003)
337 opt_val_val_t &opt_val_val = (*itr).second;
338 opt_val_val.was_read = true;
339 switch( opt_val_val.opt_type ) {
340 case OPT_BOOL_TRUE:
341 *(any_cast<bool*>(opt_val_val.opt_val)) = true;
342 break;
343 case OPT_BOOL_FALSE:
344 *(any_cast<bool*>(opt_val_val.opt_val)) = false;
345 break;
346 case OPT_INT:
348 break;
349 case OPT_LONG_INT:
351 break;
352 case OPT_SIZE_T:
354 break;
355 case OPT_LONG_LONG_INT:
357 break;
358 case OPT_DOUBLE:
360 break;
361 case OPT_FLOAT:
363 break;
364 case OPT_STRING:
366 break;
367 case OPT_ENUM_INT:
368 if( !set_enum_value( i, argv, opt_name, any_cast<int>(opt_val_val.opt_val),
370 {
372 }
373 break;
374 default:
375 TEUCHOS_TEST_FOR_EXCEPT(true); // Local programming error only
376 }
377 }
378 // Look for options that were required but were not set
379 for(
380 options_list_t::const_iterator itr = options_list_.begin();
381 itr != options_list_.end();
382 ++itr
383 )
384 {
385 const opt_val_val_t &opt_val_val = (*itr).second;
386 if( opt_val_val.required && !opt_val_val.was_read ) {
387 const std::string &opt_val_name = (*itr).first;
388#define CLP_ERR_MSG \
389 "Error, the option --"<<opt_val_name<<" was required but was not set!"
390 if(errout)
391 *errout << std::endl << argv[0] << " : " << CLP_ERR_MSG << std::endl;
392 if( throwExceptions() ) {
393 TEUCHOS_TEST_FOR_EXCEPTION( true, ParseError, CLP_ERR_MSG );
394 }
395 return PARSE_ERROR;
396#undef CLP_ERR_MSG
397 }
398 }
399 // Set the options of a default stream exists and if we are asked to
402 if (defaultOut.get() && addOutputSetupOptions_) {
403 if (output_all_front_matter_ != output_all_front_matter_default_)
404 defaultOut->setShowAllFrontMatter(output_all_front_matter_);
405 if (output_show_line_prefix_ != output_show_line_prefix_default_)
406 defaultOut->setShowLinePrefix(output_show_line_prefix_);
407 if (output_show_tab_count_ != output_show_tab_count_default_)
408 defaultOut->setShowTabCount(output_show_tab_count_);
409 if (output_show_proc_rank_ != output_show_proc_rank_default_)
410 defaultOut->setShowProcRank(output_show_proc_rank_);
411 if (output_to_root_rank_only_ != output_to_root_rank_only_default_)
412 defaultOut->setOutputToRootOnly(output_to_root_rank_only_);
413 RCPNodeTracer::setPrintRCPNodeStatisticsOnExit(print_rcpnode_statistics_on_exit_);
414 }
415
416 static bool alreadyPrintedSystemInfo = false;
417 if (print_system_info_ && !alreadyPrintedSystemInfo) {
418 if (procRank == 0) {
419 auto systemInfo = SystemInformation::collectSystemInformation();
420 for (const auto &e : systemInfo) {
421 std::cout << e.first << ": " << e.second << std::endl;
422 }
423 }
426 }
427
428 return PARSE_SUCCESSFUL;
429}
430
431
433 std::ostream &out ) const
434{
435 add_extra_output_setup_options();
437 if (procRank == 0) {
438 using std::setw;
439 using std::endl;
440
441 const int opt_type_w = 14;
442 const char spc_chars[] = " ";
443
444 // Get the maximum length of an option name
445 int opt_name_w = 19; // For the 'pause-for-debugging' option
446 options_documentation_list_t::const_iterator itr;
447 for (
448 itr = options_documentation_list_.begin();
449 itr != options_documentation_list_.end();
450 ++itr
451 )
452 {
453 opt_name_w = my_max(opt_name_w,static_cast<int>(itr->opt_name.length()));
454 if( itr->opt_type )
455 opt_name_w = my_max(opt_name_w,static_cast<int>(itr->opt_name_false.length()));
456 }
457 opt_name_w += 2;
458
459 // Some built-in options
460 out
461 << "Usage: " << program_name << " [options]\n"
462 << spc_chars << "options:\n"
463 << spc_chars
464 << "--"
465#ifdef HAVE_STD_IOS_BASE_FMTFLAGS
466 << std::left << setw(opt_name_w) << "help"
467 << std::left << setw(opt_type_w) << " "
468#else
469 << std::setiosflags(std::ios::left) << setw(opt_name_w) << "help"
470 << std::setiosflags(std::ios::left) << setw(opt_type_w) << " "
471#endif
472 << "Prints this help message"
473 << std::endl
474 << spc_chars
475 << "--"
476#ifdef HAVE_STD_IOS_BASE_FMTFLAGS
477 << std::left << setw(opt_name_w) << "pause-for-debugging"
478 << std::left << setw(opt_type_w) << " "
479#else
480 << std::setiosflags(std::ios::left) << setw(opt_name_w) << "pause-for-debugging"
481 << std::setiosflags(std::ios::left) << setw(opt_type_w) << " "
482#endif
483 << "Pauses for user input to allow attaching a debugger"
484 << std::endl
485 << spc_chars
486 << "--"
487#ifdef HAVE_STD_IOS_BASE_FMTFLAGS
488 << std::left << setw(opt_name_w) << "echo-command-line"
489 << std::left << setw(opt_type_w) << " "
490#else
491 << std::setiosflags(std::ios::left) << setw(opt_name_w) << "echo-command-line"
492 << std::setiosflags(std::ios::left) << setw(opt_type_w) << " "
493#endif
494 << "Echo the command-line but continue as normal"
495 << std::endl;
496 for(
497 itr = options_documentation_list_.begin();
498 itr != options_documentation_list_.end();
499 ++itr )
500 {
501 // print top line with option name, type and short documentation string
502 out
503 << spc_chars
504 << "--"
505#ifdef HAVE_STD_IOS_BASE_FMTFLAGS
506 << std::left << setw(opt_name_w) << itr->opt_name
507 << std::left << setw(opt_type_w) << opt_type_str(itr->opt_type)
508#else
509 << std::setiosflags(std::ios::left) << setw(opt_name_w) << itr->opt_name
510 << std::setiosflags(std::ios::left) << setw(opt_type_w) << opt_type_str(itr->opt_type)
511#endif
512 << ( itr->documentation.length() ? itr->documentation.c_str() : "No documentation" )
513 << std::endl;
514 // If an enumeration option then the next line is the value options
515 if( itr->opt_type == OPT_ENUM_INT ) {
516 out
517 << spc_chars
518 << " "
519 << setw(opt_name_w) << ""
520 << setw(opt_type_w) << "";
521 print_enum_opt_names( any_cast<int>(itr->default_val), out );
522 out
523 << std::endl;
524 }
525 // Now print the line that contains the default values
526 if( itr->opt_type == OPT_BOOL_TRUE ) {
527 out
528 << spc_chars
529 << "--"
530 << setw(opt_name_w) << itr->opt_name_false;
531 }
532 else {
533 out
534 << spc_chars
535 << " "
536 << setw(opt_name_w) << " ";
537 }
538 out
539 << setw(opt_type_w) << " "
540 << "(default: ";
541 switch( itr->opt_type ) {
542 case OPT_BOOL_TRUE:
543 out << "--" << ( (*(any_cast<bool*>(itr->default_val))) ?
544 itr->opt_name : itr->opt_name_false );
545 break;
546 case OPT_INT:
547 case OPT_LONG_INT:
548 case OPT_SIZE_T:
549 case OPT_LONG_LONG_INT:
550 case OPT_DOUBLE:
551 case OPT_FLOAT:
552 case OPT_STRING:
553 case OPT_ENUM_INT:
554 out << "--" << itr->opt_name;
555 break;
556 default:
557 TEUCHOS_TEST_FOR_EXCEPT(true); // Local programming error only
558 }
559 switch( itr->opt_type ) {
560 case OPT_BOOL_TRUE:
561 break;
562 case OPT_INT:
563 out << "=" << (*(any_cast<int*>(itr->default_val)));
564 break;
565 case OPT_LONG_INT:
566 out << "=" << (*(any_cast<long int*>(itr->default_val)));
567 break;
568 case OPT_SIZE_T:
569 out << "=" << (*(any_cast<size_t*>(itr->default_val)));
570 break;
571 case OPT_LONG_LONG_INT:
572 out << "=" << (*(any_cast<long long int*>(itr->default_val)));
573 break;
574 case OPT_DOUBLE:
575 out << "=" << (*(any_cast<double*>(itr->default_val)));
576 break;
577 case OPT_FLOAT:
578 out << "=" << (*(any_cast<float*>(itr->default_val)));
579 break;
580 case OPT_STRING:
581 out << "=" << add_quotes(*(any_cast<std::string*>(itr->default_val)));
582 break;
583 case OPT_ENUM_INT:
584 out << "=" << add_quotes(
585 enum_opt_default_val_name(itr->opt_name,any_cast<int>(itr->default_val),&out));
586 break;
587 default:
588 TEUCHOS_TEST_FOR_EXCEPT(true); // Local programming error only
589 }
590 out << ")\n";
591 }
592 if(doc_string_.length()) {
593 out << "\nDETAILED DOCUMENTATION:\n\n" << doc_string_ << std::endl << std::endl;
594 }
595 if(throwExceptions_)
596 TEUCHOS_TEST_FOR_EXCEPTION( true, HelpPrinted, "Help message was printed" );
597 }
598}
599
600
603 )
604{
605 if (!printed_timer_summary_ && show_timer_summary_on_exit_) {
607 if (nonnull(out_inout)) {
608 out = rcpFromPtr(out_inout);
609 }
610 else {
612 }
613 getTimeMonitorSurrogate()->summarize(*out << "\n");
614 printed_timer_summary_ = true;
615 }
616}
617
618
619// private
620
621
622void CommandLineProcessor::add_extra_output_setup_options() const
623{
624 if(
625 // Are we in this function already and calling it recursively?
626 in_add_extra_output_setup_options_
627 ||
628 // Have we already setup these options?
629 added_extra_output_setup_options_
630 ||
631 // Are we not supposed to setup these options?
632 !addOutputSetupOptions_
633 )
634 {
635 return; // If any of the above is true, we need to return right away!
636 }
637 // Set the commandline options for this ...
638 CommandLineProcessor
639 *clp = const_cast<CommandLineProcessor*>(this);
640 clp->in_add_extra_output_setup_options_ = true;
641 clp->setOption(
642 "output-all-front-matter","output-no-front-matter",&clp->output_all_front_matter_
643 ,"Set if all front matter is printed to the default FancyOStream or not"
644 );
645 clp->setOption(
646 "output-show-line-prefix","output-no-show-line-prefix",&clp->output_show_line_prefix_
647 ,"Set if the line prefix matter is printed to the default FancyOStream or not"
648 );
649 clp->setOption(
650 "output-show-tab-count","output-no-show-tab-count",&clp->output_show_tab_count_
651 ,"Set if the tab count is printed to the default FancyOStream or not"
652 );
653 clp->setOption(
654 "output-show-proc-rank","output-no-show-proc-rank",&clp->output_show_proc_rank_
655 ,"Set if the processor rank is printed to the default FancyOStream or not"
656 );
657 clp->setOption(
658 "output-to-root-rank-only",&clp->output_to_root_rank_only_
659 ,"Set which processor (the root) gets the output. If < 0, then all processors get output."
660 );
661 clp->setOption(
662 "print-rcpnode-statistics-on-exit", "no-print-rcpnode-statistics-on-exit",
663 &clp->print_rcpnode_statistics_on_exit_,
664 "Set if the RCPNode usage statistics will be printed on exit or not. Warning,"
665 " this prints to std::cerr or every process so do not turn this on for very large"
666 " parallel runs."
667 );
668 if (nonnull(getTimeMonitorSurrogate())) {
669 clp->setOption(
670 "show-timer-summary", "no-show-timer-sumary", &clp->show_timer_summary_on_exit_,
671 "If true, then Teuchos::TimeMonitor::summarize() is called in"
672 " CommandLineProcessor's destructor (usually at the end of main)."
673 );
674 }
675
676 clp->added_extra_output_setup_options_ = true;
677 clp->in_add_extra_output_setup_options_ = false;
678}
679
680
681void CommandLineProcessor::setEnumOption(
682 const char enum_option_name[],
683 int* enum_option_val,
684 const int num_enum_opt_values,
685 const int enum_opt_values[],
686 const char * const enum_opt_names[],
687 const char documentation[],
688 const bool required
689 )
690{
691 add_extra_output_setup_options();
692
693 TEUCHOS_TEST_FOR_EXCEPT(enum_option_val==NULL);
694 TEUCHOS_TEST_FOR_EXCEPT(num_enum_opt_values<=0);
695 TEUCHOS_TEST_FOR_EXCEPT(enum_opt_values==NULL);
696 TEUCHOS_TEST_FOR_EXCEPT(enum_opt_names==NULL);
697
698 enum_opt_data_list_.push_back(
699 enum_opt_data_t(enum_option_val,num_enum_opt_values,enum_opt_values,enum_opt_names)
700 );
701 const int opt_id = static_cast<int>(enum_opt_data_list_.size())-1;
702 options_list_[std::string(enum_option_name)]
703 = opt_val_val_t(OPT_ENUM_INT,any(opt_id),required);
704 options_documentation_list_.push_back(
705 opt_doc_t(OPT_ENUM_INT,enum_option_name, "",
706 std::string(documentation?documentation:""), any(opt_id))
707 );
708}
709
710
711bool CommandLineProcessor::set_enum_value(
712 int argv_i
713 ,char* argv[]
714 ,const std::string &enum_opt_name
715 ,const int enum_id
716 ,const std::string &enum_str_val
717 ,std::ostream *errout
718 ) const
719{
720 const enum_opt_data_t
721 &enum_opt_data = enum_opt_data_list_.at(enum_id);
722 std::vector<std::string>::const_iterator
723 itr_begin = enum_opt_data.enum_opt_names.begin(),
724 itr_end = enum_opt_data.enum_opt_names.end(),
725 itr = std::find( itr_begin, itr_end, enum_str_val );
726 if( itr == itr_end ) {
727 const int j = argv_i;
728#define CLP_ERR_MSG \
729 "Error, the value \"" << enum_str_val << "\" for the " \
730 << j<<(j==1?"st":(j==2?"nd":(j==3?"rd":"th"))) << " option --" \
731 << enum_opt_name << " was not recognized (use --help)!"
732 if(errout)
733 *errout << std::endl << argv[0] << " : " << CLP_ERR_MSG << std::endl;
734 if( throwExceptions() ) {
735 TEUCHOS_TEST_FOR_EXCEPTION( true, UnrecognizedOption, CLP_ERR_MSG );
736 }
737 else {
738 return false;
739 }
740#undef CLP_ERR_MSG
741 }
742 const int enum_opt_val_index = static_cast<int>(itr - itr_begin);
743 *enum_opt_data.enum_option_val = enum_opt_data.enum_opt_values.at(enum_opt_val_index);
744 return true;
745}
746
747
748void CommandLineProcessor::print_enum_opt_names(
749 const int enum_id
750 ,std::ostream &out
751 ) const
752{
753 const enum_opt_data_t
754 &enum_opt_data = enum_opt_data_list_.at(enum_id);
755 typedef std::vector<std::string>::const_iterator itr_t;
756 out << "Valid options:";
757 for(
758 itr_t itr = enum_opt_data.enum_opt_names.begin();
759 itr != enum_opt_data.enum_opt_names.end();
760 ++itr
761 )
762 {
763 if( itr != enum_opt_data.enum_opt_names.begin() ) out << ",";
764 out << " " << add_quotes(*itr);
765 }
766}
767
768
769std::string
770CommandLineProcessor::enum_opt_default_val_name(
771 const std::string &enum_name
772 ,const int enum_id
773 ,std::ostream *errout
774 ) const
775{
776 const enum_opt_data_t
777 &enum_opt_data = enum_opt_data_list_.at(enum_id);
778 return enum_opt_data.enum_opt_names.at(
779 find_enum_opt_index(
780 enum_name,*enum_opt_data.enum_option_val,enum_opt_data,errout
781 )
782 );
783}
784
785
786int CommandLineProcessor::find_enum_opt_index(
787 const std::string &enum_opt_name
788 ,const int opt_value
789 ,const enum_opt_data_t &enum_data
790 ,std::ostream *errout
791 ) const
792{
793 std::vector<int>::const_iterator
794 itr_begin = enum_data.enum_opt_values.begin(),
795 itr_end = enum_data.enum_opt_values.end(),
796 itr = std::find( itr_begin, itr_end, opt_value );
797 if( itr == itr_end ) {
798#define CLP_ERR_MSG \
799 ( recogniseAllOptions() ? "Error" : "Warning" ) \
800 << ", option --" << enum_opt_name << " was given an invalid " \
801 "initial option value of " << opt_value << "!"
802 if(errout)
803 *errout << CLP_ERR_MSG << std::endl;
804 if( throwExceptions() )
805 TEUCHOS_TEST_FOR_EXCEPTION( true, std::invalid_argument, CLP_ERR_MSG );
806#undef CLP_ERR_MSG
807 }
808 return static_cast<int>(itr - itr_begin);
809}
810
811
812bool CommandLineProcessor::get_opt_val(
813 const char str[]
814 ,std::string *opt_name
815 ,std::string *opt_val_str
816 ) const
817{
818 const int len = static_cast<int>(std::strlen(str));
819 if( len < 3 )
820 return false; // Can't be an option with '--' followed by at least one char
821 if( str[0] != '-' || str[1] != '-' )
822 return false; // Not a recognised option
823 // Find the '='
824 int equ_i;
825 for( equ_i = 2; equ_i < len && str[equ_i] != '='; ++equ_i );
826 // Set opt_name
827 opt_name->assign( str + 2, equ_i-2 );
828 // Set opt_val_str
829 if( equ_i == len ) {
830 *opt_val_str = "";
831 }
832 else {
833 opt_val_str->assign( str + equ_i + 1, len - equ_i - 1 );
834 }
835 return true;
836}
837
838void CommandLineProcessor::print_bad_opt(
839 int argv_i
840 ,char* argv[]
841 ,std::ostream *errout
842 ) const
843{
844 const int j = argv_i;
845#define CLP_ERR_MSG \
846 ( recogniseAllOptions() ? "Error" : "Warning" ) \
847 << ", the " << j<<(j==1?"st":(j==2?"nd":(j==3?"rd":"th"))) \
848 << " option \'" << argv[argv_i] << "\' was not recognized (use --help)!"
849 if(errout)
850 *errout << std::endl << argv[0] << " : " << CLP_ERR_MSG << std::endl;
852 TEUCHOS_TEST_FOR_EXCEPTION( true, UnrecognizedOption, CLP_ERR_MSG );
853#undef CLP_ERR_MSG
854}
855
856
857// Hidden stuff
858
859
860void CommandLineProcessor::setTimeMonitorSurrogate(
861 const RCP<CommandLineProcessor::TimeMonitorSurrogate> &timeMonitorSurrogate)
862{
863 getRawTimeMonitorSurrogate() = timeMonitorSurrogate;
864}
865
866
867RCP<CommandLineProcessor::TimeMonitorSurrogate>
868CommandLineProcessor::getTimeMonitorSurrogate()
869{
870 return getRawTimeMonitorSurrogate();
871}
872
873
874RCP<CommandLineProcessor::TimeMonitorSurrogate>&
875CommandLineProcessor::getRawTimeMonitorSurrogate()
876{
877 static RCP<TimeMonitorSurrogate> timeMonitorSurrogate;
878 return timeMonitorSurrogate;
879}
880
881
882} // end namespace Teuchos
Templated array class derived from the STL std::vector.
Basic command line parser for input from (argc,argv[])
A MPI utilities class, providing methods for initializing, finalizing, and querying the global MPI se...
Collect information about the runtime environment.
Definition of Teuchos::as, for conversions between types.
Thrown if –help was specified and throwExceptions==true.
Thrown if a parse std::exception occurs and throwExceptions==true.
Class that helps parse command line input arguments from (argc,argv[]) and set options.
bool throwExceptions() const
Returns true if an std::exception is thrown, there is a parse error, or help is printed.
void setOption(const char option_true[], const char option_false[], bool *option_val, const char documentation[]=NULL)
Set a boolean option.
EParseCommandLineReturn
Return value for CommandLineProcessor::parse(). Note: These enums are all given non-negative values s...
EParseCommandLineReturn parse(int argc, char *argv[], std::ostream *errout=&std::cerr) const
Parse a command line.
void printHelpMessage(const char program_name[], std::ostream &out) const
Print the help message.
void printFinalTimerSummary(const Ptr< std::ostream > &out=null)
Call to print timers so that they don't get printed in the destructor.
void setDocString(const char doc_string[])
Set a documentation sting for the entire program printed when –help is specified.
CommandLineProcessor(bool throwExceptions=true, bool recogniseAllOptions=true, bool addOutputSetupOptions=false)
Default Constructor.
bool recogniseAllOptions() const
Returns true if all options must be recognized by the parser.
static void barrier()
Call MPI_Barrier() on MPI_COMM_WORLD.
static int getRank()
The rank of the calling process in MPI_COMM_WORLD.
static int getNProc()
The number of processes in MPI_COMM_WORLD.
static void allGather(int localVal, const ArrayView< int > &allVals)
Global all-to-all of a set of integers across processes.
static void setPrintRCPNodeStatisticsOnExit(bool printRCPNodeStatisticsOnExit)
Set if RCPNode usage statistics will be printed when the program ends or not.
Smart reference counting pointer class for automatic garbage collection.
T * get() const
Get the raw C++ pointer to the underlying object.
static RCP< FancyOStream > getDefaultOStream()
Get the default output stream object.
Modified boost::any class, which is a container for a templated value.
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
This macro is designed to be a short version of TEUCHOS_TEST_FOR_EXCEPTION() that is easier to call.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
bool nonnull(const std::shared_ptr< T > &p)
Returns true if p.get()!=NULL.
The Teuchos namespace contains all of the classes, structs and enums used by Teuchos,...