16 #include "Teuchos_VerboseObject.hpp"
18 #include "Teuchos_Assert.hpp"
28 inline int my_max(
int a,
int b ) {
return a > b ? a : b; }
31 std::string remove_quotes(
const std::string& str )
33 if (str[0] ==
'\"' && str[str.size()-1] ==
'\"')
34 return str.substr(1,str.size()-2);
35 else if (str[0] ==
'\"')
36 return str.substr(1,str.size()-1);
37 else if (str[str.size()-1] ==
'\"')
38 return str.substr(0,str.size()-1);
43 std::string add_quotes(
const std::string& str )
47 return "\"" + str +
"\"";
57 const bool CommandLineProcessor::output_all_front_matter_default_(
false);
58 const bool CommandLineProcessor::output_show_line_prefix_default_(
false);
59 const bool CommandLineProcessor::output_show_tab_count_default_(
false);
60 const bool CommandLineProcessor::output_show_proc_rank_default_(
false);
61 const int CommandLineProcessor::output_to_root_rank_only_default_(0);
62 const bool CommandLineProcessor::print_rcpnode_statistics_on_exit_default_(
false);
63 const bool CommandLineProcessor::show_timer_summary_on_exit_default_(
false);
67 bool throwExceptions_in
68 ,
bool recogniseAllOptions_in
69 ,
bool addOutputSetupOptions_in
71 :throwExceptions_(throwExceptions_in)
72 ,recogniseAllOptions_(recogniseAllOptions_in)
73 ,addOutputSetupOptions_(addOutputSetupOptions_in)
74 ,output_all_front_matter_(output_all_front_matter_default_)
75 ,output_show_line_prefix_(output_show_line_prefix_default_)
76 ,output_show_tab_count_(output_show_tab_count_default_)
77 ,output_show_proc_rank_(output_show_proc_rank_default_)
78 ,output_to_root_rank_only_(output_to_root_rank_only_default_)
79 ,print_rcpnode_statistics_on_exit_(print_rcpnode_statistics_on_exit_default_)
80 ,show_timer_summary_on_exit_(show_timer_summary_on_exit_default_)
81 ,printed_timer_summary_(false)
82 ,added_extra_output_setup_options_(false)
83 ,in_add_extra_output_setup_options_(false)
98 doc_string_ = doc_string;
103 const char option_true[]
104 ,
const char option_false[]
106 ,
const char documentation[]
109 add_extra_output_setup_options();
111 options_list_[std::string(option_true)]
112 = opt_val_val_t(OPT_BOOL_TRUE,
any(option_val),
false);
113 options_list_[std::string(option_false)]
114 = opt_val_val_t(OPT_BOOL_FALSE,
any(option_val),
false);
115 options_documentation_list_.push_back(
116 opt_doc_t(OPT_BOOL_TRUE, option_true, option_false,
117 std::string(documentation?documentation:
""),
any(option_val))
123 const char option_name[]
125 ,
const char documentation[]
129 add_extra_output_setup_options();
131 options_list_[std::string(option_name)]
132 = opt_val_val_t(OPT_INT,
any(option_val),required);
133 options_documentation_list_.push_back(
134 opt_doc_t(OPT_INT, option_name,
"", std::string(documentation?documentation:
""),
141 const char option_name[]
142 ,
long int *option_val
143 ,
const char documentation[]
147 add_extra_output_setup_options();
149 options_list_[std::string(option_name)]
150 = opt_val_val_t(OPT_LONG_INT,
any(option_val),required);
151 options_documentation_list_.push_back(
152 opt_doc_t(OPT_LONG_INT, option_name,
"", std::string(documentation?documentation:
""),
159 const char option_name[]
161 ,
const char documentation[]
165 add_extra_output_setup_options();
167 options_list_[std::string(option_name)]
168 = opt_val_val_t(OPT_SIZE_T,
any(option_val),required);
169 options_documentation_list_.push_back(
170 opt_doc_t(OPT_SIZE_T, option_name,
"", std::string(documentation?documentation:
""),
176 const char option_name[]
177 ,
long long int *option_val
178 ,
const char documentation[]
182 add_extra_output_setup_options();
184 options_list_[std::string(option_name)]
185 = opt_val_val_t(OPT_LONG_LONG_INT,
any(option_val),required);
186 options_documentation_list_.push_back(
187 opt_doc_t(OPT_LONG_LONG_INT, option_name,
"", std::string(documentation?documentation:
""),
193 const char option_name[]
195 ,
const char documentation[]
199 add_extra_output_setup_options();
201 options_list_[std::string(option_name)]
202 = opt_val_val_t(OPT_DOUBLE,
any(option_val),required);
203 options_documentation_list_.push_back(
204 opt_doc_t(OPT_DOUBLE, option_name,
"", std::string(documentation?documentation:
""),
210 const char option_name[]
212 ,
const char documentation[]
216 add_extra_output_setup_options();
218 options_list_[std::string(option_name)]
219 = opt_val_val_t(OPT_FLOAT,
any(option_val),required);
220 options_documentation_list_.push_back(
221 opt_doc_t(OPT_FLOAT, option_name,
"", std::string(documentation?documentation:
""),
227 const char option_name[]
228 ,std::string *option_val
229 ,
const char documentation[]
233 add_extra_output_setup_options();
235 options_list_[std::string(option_name)]
236 = opt_val_val_t(OPT_STRING,
any(option_val),required);
237 options_documentation_list_.push_back(
238 opt_doc_t(OPT_STRING, option_name,
"", std::string(documentation?documentation:
""),
251 ,std::ostream *errout
254 add_extra_output_setup_options();
255 std::string opt_name;
256 std::string opt_val_str;
257 const std::string echo_cl_opt =
"echo-command-line";
258 const std::string help_opt =
"help";
259 const std::string pause_opt =
"pause-for-debugging";
264 for(
int i = 1; i < argc; ++i ) {
265 bool gov_return = get_opt_val( argv[i], &opt_name, &opt_val_str );
266 if( gov_return && opt_name == help_opt ) {
272 for(
int i = 1; i < argc; ++i ) {
273 bool gov_return = get_opt_val( argv[i], &opt_name, &opt_val_str );
276 print_bad_opt(i,argv,errout);
283 if( opt_name == echo_cl_opt ) {
284 if(errout && procRank == 0) {
285 *errout <<
"\nEchoing the command-line:\n\n";
286 for(
int j = 0; j < argc; ++j )
287 *errout << argv[j] <<
" ";
292 if( opt_name == pause_opt ) {
296 int rank_pid = getpid();
300 std::cerr <<
"Rank " << k <<
" has PID " << pids[k] << std::endl;
303 std::cerr <<
"\nType 0 and press enter to continue : ";
305 std::cin >> dummy_int;
311 options_list_t::iterator itr = options_list_.find(opt_name);
312 if( itr == options_list_.end() ) {
314 print_bad_opt(i,argv,errout);
322 opt_val_val_t &opt_val_val = (*itr).second;
323 opt_val_val.was_read =
true;
324 switch( opt_val_val.opt_type ) {
326 *(any_cast<
bool*>(opt_val_val.opt_val)) =
true;
329 *(any_cast<
bool*>(opt_val_val.opt_val)) =
false;
332 *(any_cast<
int*>(opt_val_val.opt_val)) = asSafe<int> (opt_val_str);
335 *(any_cast<
long int*>(opt_val_val.opt_val)) = asSafe<long int> (opt_val_str);
338 *(any_cast<
size_t *>(opt_val_val.opt_val)) = asSafe<size_t> (opt_val_str);
340 case OPT_LONG_LONG_INT:
341 *(any_cast<
long long int*>(opt_val_val.opt_val)) = asSafe<long long int> (opt_val_str);
344 *(any_cast<
double*>(opt_val_val.opt_val)) = asSafe<double> (opt_val_str);
347 *(any_cast<
float*>(opt_val_val.opt_val)) = asSafe<float> (opt_val_str);
350 *(any_cast<std::string*>(opt_val_val.opt_val)) = remove_quotes(opt_val_str);
353 if( !set_enum_value( i, argv, opt_name, any_cast<int>(opt_val_val.opt_val),
354 remove_quotes(opt_val_str), errout ) )
365 options_list_t::const_iterator itr = options_list_.begin();
366 itr != options_list_.end();
370 const opt_val_val_t &opt_val_val = (*itr).second;
371 if( opt_val_val.required && !opt_val_val.was_read ) {
372 const std::string &opt_val_name = (*itr).first;
373 #define CLP_ERR_MSG \
374 "Error, the option --"<<opt_val_name<<" was required but was not set!"
376 *errout << std::endl << argv[0] <<
" : " << CLP_ERR_MSG << std::endl;
387 if (defaultOut.
get() && addOutputSetupOptions_) {
388 if (output_all_front_matter_ != output_all_front_matter_default_)
389 defaultOut->setShowAllFrontMatter(output_all_front_matter_);
390 if (output_show_line_prefix_ != output_show_line_prefix_default_)
391 defaultOut->setShowLinePrefix(output_show_line_prefix_);
392 if (output_show_tab_count_ != output_show_tab_count_default_)
393 defaultOut->setShowTabCount(output_show_tab_count_);
394 if (output_show_proc_rank_ != output_show_proc_rank_default_)
395 defaultOut->setShowProcRank(output_show_proc_rank_);
396 if (output_to_root_rank_only_ != output_to_root_rank_only_default_)
397 defaultOut->setOutputToRootOnly(output_to_root_rank_only_);
405 std::ostream &out )
const
407 add_extra_output_setup_options();
413 const int opt_type_w = 14;
414 const char spc_chars[] =
" ";
418 options_documentation_list_t::const_iterator itr;
420 itr = options_documentation_list_.begin();
421 itr != options_documentation_list_.end();
425 opt_name_w = my_max(opt_name_w,static_cast<int>(itr->opt_name.length()));
427 opt_name_w = my_max(opt_name_w,static_cast<int>(itr->opt_name_false.length()));
433 <<
"Usage: " << program_name <<
" [options]\n"
434 << spc_chars <<
"options:\n"
437 #ifdef HAVE_STD_IOS_BASE_FMTFLAGS
438 << std::left << setw(opt_name_w) <<
"help"
439 << std::left << setw(opt_type_w) <<
" "
441 << std::setiosflags(std::ios::left) << setw(opt_name_w) <<
"help"
442 << std::setiosflags(std::ios::left) << setw(opt_type_w) <<
" "
444 <<
"Prints this help message"
448 #ifdef HAVE_STD_IOS_BASE_FMTFLAGS
449 << std::left << setw(opt_name_w) <<
"pause-for-debugging"
450 << std::left << setw(opt_type_w) <<
" "
452 << std::setiosflags(std::ios::left) << setw(opt_name_w) <<
"pause-for-debugging"
453 << std::setiosflags(std::ios::left) << setw(opt_type_w) <<
" "
455 <<
"Pauses for user input to allow attaching a debugger"
459 #ifdef HAVE_STD_IOS_BASE_FMTFLAGS
460 << std::left << setw(opt_name_w) <<
"echo-command-line"
461 << std::left << setw(opt_type_w) <<
" "
463 << std::setiosflags(std::ios::left) << setw(opt_name_w) <<
"echo-command-line"
464 << std::setiosflags(std::ios::left) << setw(opt_type_w) <<
" "
466 <<
"Echo the command-line but continue as normal"
469 itr = options_documentation_list_.begin();
470 itr != options_documentation_list_.end();
477 #ifdef HAVE_STD_IOS_BASE_FMTFLAGS
478 << std::left << setw(opt_name_w) << itr->opt_name
479 << std::left << setw(opt_type_w) << opt_type_str(itr->opt_type)
481 << std::setiosflags(std::ios::left) << setw(opt_name_w) << itr->opt_name
482 << std::setiosflags(std::ios::left) << setw(opt_type_w) << opt_type_str(itr->opt_type)
484 << ( itr->documentation.length() ? itr->documentation.c_str() :
"No documentation" )
487 if( itr->opt_type == OPT_ENUM_INT ) {
491 << setw(opt_name_w) <<
""
492 << setw(opt_type_w) <<
"";
493 print_enum_opt_names( any_cast<int>(itr->default_val), out );
498 if( itr->opt_type == OPT_BOOL_TRUE ) {
502 << setw(opt_name_w) << itr->opt_name_false;
508 << setw(opt_name_w) <<
" ";
511 << setw(opt_type_w) <<
" "
513 switch( itr->opt_type ) {
515 out <<
"--" << ( (*(any_cast<
bool*>(itr->default_val))) ?
516 itr->opt_name : itr->opt_name_false );
521 case OPT_LONG_LONG_INT:
526 out <<
"--" << itr->opt_name;
531 switch( itr->opt_type ) {
535 out <<
"=" << (*(any_cast<
int*>(itr->default_val)));
538 out <<
"=" << (*(any_cast<
long int*>(itr->default_val)));
541 out <<
"=" << (*(any_cast<
size_t*>(itr->default_val)));
543 case OPT_LONG_LONG_INT:
544 out <<
"=" << (*(any_cast<
long long int*>(itr->default_val)));
547 out <<
"=" << (*(any_cast<
double*>(itr->default_val)));
550 out <<
"=" << (*(any_cast<
float*>(itr->default_val)));
553 out <<
"=" << add_quotes(*(any_cast<std::string*>(itr->default_val)));
556 out <<
"=" << add_quotes(
557 enum_opt_default_val_name(itr->opt_name,any_cast<int>(itr->default_val),&out));
564 if(doc_string_.length()) {
565 out <<
"\nDETAILED DOCUMENTATION:\n\n" << doc_string_ << std::endl << std::endl;
577 if (!printed_timer_summary_ && show_timer_summary_on_exit_) {
580 out = rcpFromPtr(out_inout);
585 getTimeMonitorSurrogate()->summarize(*out <<
"\n");
586 printed_timer_summary_ =
true;
594 void CommandLineProcessor::add_extra_output_setup_options()
const
598 in_add_extra_output_setup_options_
601 added_extra_output_setup_options_
604 !addOutputSetupOptions_
612 clp->in_add_extra_output_setup_options_ =
true;
614 "output-all-front-matter",
"output-no-front-matter",&clp->output_all_front_matter_
615 ,
"Set if all front matter is printed to the default FancyOStream or not"
618 "output-show-line-prefix",
"output-no-show-line-prefix",&clp->output_show_line_prefix_
619 ,
"Set if the line prefix matter is printed to the default FancyOStream or not"
622 "output-show-tab-count",
"output-no-show-tab-count",&clp->output_show_tab_count_
623 ,
"Set if the tab count is printed to the default FancyOStream or not"
626 "output-show-proc-rank",
"output-no-show-proc-rank",&clp->output_show_proc_rank_
627 ,
"Set if the processor rank is printed to the default FancyOStream or not"
630 "output-to-root-rank-only",&clp->output_to_root_rank_only_
631 ,
"Set which processor (the root) gets the output. If < 0, then all processors get output."
634 "print-rcpnode-statistics-on-exit",
"no-print-rcpnode-statistics-on-exit",
635 &clp->print_rcpnode_statistics_on_exit_,
636 "Set if the RCPNode usage statistics will be printed on exit or not. Warning,"
637 " this prints to std::cerr or every process so do not turn this on for very large"
640 if (
nonnull(getTimeMonitorSurrogate())) {
642 "show-timer-summary",
"no-show-timer-sumary", &clp->show_timer_summary_on_exit_,
643 "If true, then Teuchos::TimeMonitor::summarize() is called in"
644 " CommandLineProcessor's destructor (usually at the end of main)."
648 clp->added_extra_output_setup_options_ =
true;
649 clp->in_add_extra_output_setup_options_ =
false;
653 void CommandLineProcessor::setEnumOption(
654 const char enum_option_name[],
655 int* enum_option_val,
656 const int num_enum_opt_values,
657 const int enum_opt_values[],
658 const char *
const enum_opt_names[],
659 const char documentation[],
663 add_extra_output_setup_options();
670 enum_opt_data_list_.push_back(
671 enum_opt_data_t(enum_option_val,num_enum_opt_values,enum_opt_values,enum_opt_names)
673 const int opt_id =
static_cast<int>(enum_opt_data_list_.size())-1;
674 options_list_[std::string(enum_option_name)]
675 = opt_val_val_t(OPT_ENUM_INT,any(opt_id),required);
676 options_documentation_list_.push_back(
677 opt_doc_t(OPT_ENUM_INT,enum_option_name,
"",
678 std::string(documentation?documentation:
""), any(opt_id))
683 bool CommandLineProcessor::set_enum_value(
686 ,
const std::string &enum_opt_name
688 ,
const std::string &enum_str_val
689 ,std::ostream *errout
692 const enum_opt_data_t
693 &enum_opt_data = enum_opt_data_list_.at(enum_id);
694 std::vector<std::string>::const_iterator
695 itr_begin = enum_opt_data.enum_opt_names.begin(),
696 itr_end = enum_opt_data.enum_opt_names.end(),
697 itr = std::find( itr_begin, itr_end, enum_str_val );
698 if( itr == itr_end ) {
699 const int j = argv_i;
700 #define CLP_ERR_MSG \
701 "Error, the value \"" << enum_str_val << "\" for the " \
702 << j<<(j==1?"st":(j==2?"nd":(j==3?"rd":"th"))) << " option --" \
703 << enum_opt_name << " was not recognized (use --help)!"
705 *errout << std::endl << argv[0] <<
" : " << CLP_ERR_MSG << std::endl;
714 const int enum_opt_val_index =
static_cast<int>(itr - itr_begin);
715 *enum_opt_data.enum_option_val = enum_opt_data.enum_opt_values.at(enum_opt_val_index);
720 void CommandLineProcessor::print_enum_opt_names(
725 const enum_opt_data_t
726 &enum_opt_data = enum_opt_data_list_.at(enum_id);
727 typedef std::vector<std::string>::const_iterator itr_t;
728 out <<
"Valid options:";
730 itr_t itr = enum_opt_data.enum_opt_names.begin();
731 itr != enum_opt_data.enum_opt_names.end();
735 if( itr != enum_opt_data.enum_opt_names.begin() ) out <<
",";
736 out <<
" " << add_quotes(*itr);
742 CommandLineProcessor::enum_opt_default_val_name(
743 const std::string &enum_name
745 ,std::ostream *errout
748 const enum_opt_data_t
749 &enum_opt_data = enum_opt_data_list_.at(enum_id);
750 return enum_opt_data.enum_opt_names.at(
752 enum_name,*enum_opt_data.enum_option_val,enum_opt_data,errout
758 int CommandLineProcessor::find_enum_opt_index(
759 const std::string &enum_opt_name
761 ,
const enum_opt_data_t &enum_data
762 ,std::ostream *errout
765 std::vector<int>::const_iterator
766 itr_begin = enum_data.enum_opt_values.begin(),
767 itr_end = enum_data.enum_opt_values.end(),
768 itr = std::find( itr_begin, itr_end, opt_value );
769 if( itr == itr_end ) {
770 #define CLP_ERR_MSG \
771 ( recogniseAllOptions() ? "Error" : "Warning" ) \
772 << ", option --" << enum_opt_name << " was given an invalid " \
773 "initial option value of " << opt_value << "!"
775 *errout << CLP_ERR_MSG << std::endl;
780 return static_cast<int>(itr - itr_begin);
784 bool CommandLineProcessor::get_opt_val(
786 ,std::string *opt_name
787 ,std::string *opt_val_str
790 const int len =
static_cast<int>(std::strlen(str));
793 if( str[0] !=
'-' || str[1] !=
'-' )
797 for( equ_i = 2; equ_i < len && str[equ_i] !=
'='; ++equ_i );
799 opt_name->assign( str + 2, equ_i-2 );
805 opt_val_str->assign( str + equ_i + 1, len - equ_i - 1 );
810 void CommandLineProcessor::print_bad_opt(
813 ,std::ostream *errout
816 const int j = argv_i;
817 #define CLP_ERR_MSG \
818 ( recogniseAllOptions() ? "Error" : "Warning" ) \
819 << ", the " << j<<(j==1?"st":(j==2?"nd":(j==3?"rd":"th"))) \
820 << " option \'" << argv[argv_i] << "\' was not recognized (use --help)!"
822 *errout << std::endl << argv[0] <<
" : " << CLP_ERR_MSG << std::endl;
832 void CommandLineProcessor::setTimeMonitorSurrogate(
833 const RCP<CommandLineProcessor::TimeMonitorSurrogate> &timeMonitorSurrogate)
835 getRawTimeMonitorSurrogate() = timeMonitorSurrogate;
839 RCP<CommandLineProcessor::TimeMonitorSurrogate>
840 CommandLineProcessor::getTimeMonitorSurrogate()
842 return getRawTimeMonitorSurrogate();
846 RCP<CommandLineProcessor::TimeMonitorSurrogate>&
847 CommandLineProcessor::getRawTimeMonitorSurrogate()
849 static RCP<TimeMonitorSurrogate> timeMonitorSurrogate;
850 return timeMonitorSurrogate;
static int getRank()
The rank of the calling process in MPI_COMM_WORLD.
Thrown if –help was specified and throwExceptions==true.
static int getNProc()
The number of processes in MPI_COMM_WORLD.
void printHelpMessage(const char program_name[], std::ostream &out) const
Print the help message.
bool nonnull(const std::shared_ptr< T > &p)
Returns true if p.get()!=NULL.
bool throwExceptions() const
Returns true if an std::exception is thrown, there is a parse error, or help is printed.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
static void setPrintRCPNodeStatisticsOnExit(bool printRCPNodeStatisticsOnExit)
Set if RCPNode usage statistics will be printed when the program ends or not.
T * get() const
Get the raw C++ pointer to the underlying object.
CommandLineProcessor(bool throwExceptions=true, bool recogniseAllOptions=true, bool addOutputSetupOptions=false)
Default Constructor.
Modified boost::any class, which is a container for a templated value.
~CommandLineProcessor()
Destructor.
void setOption(const char option_true[], const char option_false[], bool *option_val, const char documentation[]=NULL)
Set a boolean option.
static RCP< FancyOStream > getDefaultOStream()
Get the default output stream object.
EParseCommandLineReturn parse(int argc, char *argv[], std::ostream *errout=&std::cerr) const
Parse a command line.
void resize(size_type new_size, const value_type &x=value_type())
EParseCommandLineReturn
Return value for CommandLineProcessor::parse(). Note: These enums are all given non-negative values s...
Templated array class derived from the STL std::vector.
A MPI utilities class, providing methods for initializing, finalizing, and querying the global MPI se...
Basic command line parser for input from (argc,argv[])
void setDocString(const char doc_string[])
Set a documentation sting for the entire program printed when –help is specified. ...
static void barrier()
Call MPI_Barrier() on MPI_COMM_WORLD.
bool recogniseAllOptions() const
Returns true if all options must be recognized by the parser.
static void allGather(int localVal, const ArrayView< int > &allVals)
Global all-to-all of a set of integers across processes.
Smart reference counting pointer class for automatic garbage collection.
void printFinalTimerSummary(const Ptr< std::ostream > &out=null)
Call to print timers so that they don't get printed in the destructor.
Definition of Teuchos::as, for conversions between types.
Thrown if a parse std::exception occurs and throwExceptions==true.
#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...
Simple wrapper class for raw pointers to single objects where no persisting relationship exists...