48 #include "Teuchos_VerboseObject.hpp" 50 #include "Teuchos_Assert.hpp" 60 inline int my_max(
int a,
int b ) {
return a > b ? a : b; }
63 std::string remove_quotes(
const std::string& str )
67 return str.substr(1,str.size()-2);
71 std::string add_quotes(
const std::string& str )
75 return "\"" + str +
"\"";
85 const bool CommandLineProcessor::output_all_front_matter_default_(
false);
86 const bool CommandLineProcessor::output_show_line_prefix_default_(
false);
87 const bool CommandLineProcessor::output_show_tab_count_default_(
false);
88 const bool CommandLineProcessor::output_show_proc_rank_default_(
false);
89 const int CommandLineProcessor::output_to_root_rank_only_default_(0);
90 const bool CommandLineProcessor::print_rcpnode_statistics_on_exit_default_(
false);
91 const bool CommandLineProcessor::show_timer_summary_on_exit_default_(
false);
95 bool throwExceptions_in
96 ,
bool recogniseAllOptions_in
97 ,
bool addOutputSetupOptions_in
99 :throwExceptions_(throwExceptions_in)
100 ,recogniseAllOptions_(recogniseAllOptions_in)
101 ,addOutputSetupOptions_(addOutputSetupOptions_in)
102 ,output_all_front_matter_(output_all_front_matter_default_)
103 ,output_show_line_prefix_(output_show_line_prefix_default_)
104 ,output_show_tab_count_(output_show_tab_count_default_)
105 ,output_show_proc_rank_(output_show_proc_rank_default_)
106 ,output_to_root_rank_only_(output_to_root_rank_only_default_)
107 ,print_rcpnode_statistics_on_exit_(print_rcpnode_statistics_on_exit_default_)
108 ,show_timer_summary_on_exit_(show_timer_summary_on_exit_default_)
109 ,printed_timer_summary_(false)
110 ,added_extra_output_setup_options_(false)
111 ,in_add_extra_output_setup_options_(false)
126 doc_string_ = doc_string;
131 const char option_true[]
132 ,
const char option_false[]
134 ,
const char documentation[]
137 add_extra_output_setup_options();
139 options_list_[std::string(option_true)]
140 = opt_val_val_t(OPT_BOOL_TRUE,
any(option_val),
false);
141 options_list_[std::string(option_false)]
142 = opt_val_val_t(OPT_BOOL_FALSE,
any(option_val),
false);
143 options_documentation_list_.push_back(
144 opt_doc_t(OPT_BOOL_TRUE, option_true, option_false,
145 std::string(documentation?documentation:
""),
any(option_val))
151 const char option_name[]
153 ,
const char documentation[]
157 add_extra_output_setup_options();
159 options_list_[std::string(option_name)]
160 = opt_val_val_t(OPT_INT,
any(option_val),required);
161 options_documentation_list_.push_back(
162 opt_doc_t(OPT_INT, option_name,
"", std::string(documentation?documentation:
""),
169 const char option_name[]
170 ,
long int *option_val
171 ,
const char documentation[]
175 add_extra_output_setup_options();
177 options_list_[std::string(option_name)]
178 = opt_val_val_t(OPT_LONG_INT,
any(option_val),required);
179 options_documentation_list_.push_back(
180 opt_doc_t(OPT_LONG_INT, option_name,
"", std::string(documentation?documentation:
""),
187 const char option_name[]
189 ,
const char documentation[]
193 add_extra_output_setup_options();
195 options_list_[std::string(option_name)]
196 = opt_val_val_t(OPT_SIZE_T,
any(option_val),required);
197 options_documentation_list_.push_back(
198 opt_doc_t(OPT_SIZE_T, option_name,
"", std::string(documentation?documentation:
""),
204 const char option_name[]
205 ,
long long int *option_val
206 ,
const char documentation[]
210 add_extra_output_setup_options();
212 options_list_[std::string(option_name)]
213 = opt_val_val_t(OPT_LONG_LONG_INT,
any(option_val),required);
214 options_documentation_list_.push_back(
215 opt_doc_t(OPT_LONG_LONG_INT, option_name,
"", std::string(documentation?documentation:
""),
221 const char option_name[]
223 ,
const char documentation[]
227 add_extra_output_setup_options();
229 options_list_[std::string(option_name)]
230 = opt_val_val_t(OPT_DOUBLE,
any(option_val),required);
231 options_documentation_list_.push_back(
232 opt_doc_t(OPT_DOUBLE, option_name,
"", std::string(documentation?documentation:
""),
239 const char option_name[]
240 ,std::string *option_val
241 ,
const char documentation[]
245 add_extra_output_setup_options();
247 options_list_[std::string(option_name)]
248 = opt_val_val_t(OPT_STRING,
any(option_val),required);
249 options_documentation_list_.push_back(
250 opt_doc_t(OPT_STRING, option_name,
"", std::string(documentation?documentation:
""),
263 ,std::ostream *errout
266 add_extra_output_setup_options();
267 std::string opt_name;
268 std::string opt_val_str;
269 const std::string echo_cl_opt =
"echo-command-line";
270 const std::string help_opt =
"help";
271 const std::string pause_opt =
"pause-for-debugging";
276 for(
int i = 1; i < argc; ++i ) {
277 bool gov_return = get_opt_val( argv[i], &opt_name, &opt_val_str );
278 if( gov_return && opt_name == help_opt ) {
284 for(
int i = 1; i < argc; ++i ) {
285 bool gov_return = get_opt_val( argv[i], &opt_name, &opt_val_str );
288 print_bad_opt(i,argv,errout);
295 if( opt_name == echo_cl_opt ) {
296 if(errout && procRank == 0) {
297 *errout <<
"\nEchoing the command-line:\n\n";
298 for(
int j = 0; j < argc; ++j )
299 *errout << argv[j] <<
" ";
304 if( opt_name == pause_opt ) {
308 int rank_pid = getpid();
312 std::cerr <<
"Rank " << k <<
" has PID " << pids[k] << std::endl;
315 std::cerr <<
"\nType 0 and press enter to continue : ";
317 std::cin >> dummy_int;
323 options_list_t::iterator itr = options_list_.find(opt_name);
324 if( itr == options_list_.end() ) {
326 print_bad_opt(i,argv,errout);
334 opt_val_val_t &opt_val_val = (*itr).second;
335 opt_val_val.was_read =
true;
336 switch( opt_val_val.opt_type ) {
338 *(any_cast<
bool*>(opt_val_val.opt_val)) =
true;
341 *(any_cast<
bool*>(opt_val_val.opt_val)) =
false;
344 *(any_cast<
int*>(opt_val_val.opt_val)) = asSafe<int> (opt_val_str);
347 *(any_cast<
long int*>(opt_val_val.opt_val)) = asSafe<long int> (opt_val_str);
350 *(any_cast<
size_t *>(opt_val_val.opt_val)) = asSafe<size_t> (opt_val_str);
352 case OPT_LONG_LONG_INT:
353 *(any_cast<
long long int*>(opt_val_val.opt_val)) = asSafe<long long int> (opt_val_str);
356 *(any_cast<
double*>(opt_val_val.opt_val)) = asSafe<double> (opt_val_str);
359 *(any_cast<std::string*>(opt_val_val.opt_val)) = remove_quotes(opt_val_str);
362 if( !set_enum_value( i, argv, opt_name, any_cast<int>(opt_val_val.opt_val),
363 remove_quotes(opt_val_str), errout ) )
374 options_list_t::const_iterator itr = options_list_.begin();
375 itr != options_list_.end();
379 const opt_val_val_t &opt_val_val = (*itr).second;
380 if( opt_val_val.required && !opt_val_val.was_read ) {
381 const std::string &opt_val_name = (*itr).first;
382 #define CLP_ERR_MSG \ 383 "Error, the option --"<<opt_val_name<<" was required but was not set!" 385 *errout << std::endl << argv[0] <<
" : " << CLP_ERR_MSG << std::endl;
396 if (defaultOut.
get() && addOutputSetupOptions_) {
397 if (output_all_front_matter_ != output_all_front_matter_default_)
398 defaultOut->setShowAllFrontMatter(output_all_front_matter_);
399 if (output_show_line_prefix_ != output_show_line_prefix_default_)
400 defaultOut->setShowLinePrefix(output_show_line_prefix_);
401 if (output_show_tab_count_ != output_show_tab_count_default_)
402 defaultOut->setShowTabCount(output_show_tab_count_);
403 if (output_show_proc_rank_ != output_show_proc_rank_default_)
404 defaultOut->setShowProcRank(output_show_proc_rank_);
405 if (output_to_root_rank_only_ != output_to_root_rank_only_default_)
406 defaultOut->setOutputToRootOnly(output_to_root_rank_only_);
414 std::ostream &out )
const 416 add_extra_output_setup_options();
422 const int opt_type_w = 14;
423 const char spc_chars[] =
" ";
427 options_documentation_list_t::const_iterator itr;
429 itr = options_documentation_list_.begin();
430 itr != options_documentation_list_.end();
434 opt_name_w = my_max(opt_name_w,static_cast<int>(itr->opt_name.length()));
436 opt_name_w = my_max(opt_name_w,static_cast<int>(itr->opt_name_false.length()));
442 <<
"Usage: " << program_name <<
" [options]\n" 443 << spc_chars <<
"options:\n" 446 #ifdef HAVE_STD_IOS_BASE_FMTFLAGS 447 << std::left << setw(opt_name_w) <<
"help" 448 << std::left << setw(opt_type_w) <<
" " 450 << std::setiosflags(std::ios::left) << setw(opt_name_w) <<
"help" 451 << std::setiosflags(std::ios::left) << setw(opt_type_w) <<
" " 453 <<
"Prints this help message" 457 #ifdef HAVE_STD_IOS_BASE_FMTFLAGS 458 << std::left << setw(opt_name_w) <<
"pause-for-debugging" 459 << std::left << setw(opt_type_w) <<
" " 461 << std::setiosflags(std::ios::left) << setw(opt_name_w) <<
"pause-for-debugging" 462 << std::setiosflags(std::ios::left) << setw(opt_type_w) <<
" " 464 <<
"Pauses for user input to allow attaching a debugger" 468 #ifdef HAVE_STD_IOS_BASE_FMTFLAGS 469 << std::left << setw(opt_name_w) <<
"echo-command-line" 470 << std::left << setw(opt_type_w) <<
" " 472 << std::setiosflags(std::ios::left) << setw(opt_name_w) <<
"echo-command-line" 473 << std::setiosflags(std::ios::left) << setw(opt_type_w) <<
" " 475 <<
"Echo the command-line but continue as normal" 478 itr = options_documentation_list_.begin();
479 itr != options_documentation_list_.end();
486 #ifdef HAVE_STD_IOS_BASE_FMTFLAGS 487 << std::left << setw(opt_name_w) << itr->opt_name
488 << std::left << setw(opt_type_w) << opt_type_str(itr->opt_type)
490 << std::setiosflags(std::ios::left) << setw(opt_name_w) << itr->opt_name
491 << std::setiosflags(std::ios::left) << setw(opt_type_w) << opt_type_str(itr->opt_type)
493 << ( itr->documentation.length() ? itr->documentation.c_str() :
"No documentation" )
496 if( itr->opt_type == OPT_ENUM_INT ) {
500 << setw(opt_name_w) <<
"" 501 << setw(opt_type_w) <<
"";
502 print_enum_opt_names( any_cast<int>(itr->default_val), out );
507 if( itr->opt_type == OPT_BOOL_TRUE ) {
511 << setw(opt_name_w) << itr->opt_name_false;
517 << setw(opt_name_w) <<
" ";
520 << setw(opt_type_w) <<
" " 522 switch( itr->opt_type ) {
524 out <<
"--" << ( (*(any_cast<
bool*>(itr->default_val))) ?
525 itr->opt_name : itr->opt_name_false );
530 case OPT_LONG_LONG_INT:
534 out <<
"--" << itr->opt_name;
539 switch( itr->opt_type ) {
543 out <<
"=" << (*(any_cast<
int*>(itr->default_val)));
546 out <<
"=" << (*(any_cast<
long int*>(itr->default_val)));
549 out <<
"=" << (*(any_cast<
size_t*>(itr->default_val)));
551 case OPT_LONG_LONG_INT:
552 out <<
"=" << (*(any_cast<
long long int*>(itr->default_val)));
555 out <<
"=" << (*(any_cast<
double*>(itr->default_val)));
558 out <<
"=" << add_quotes(*(any_cast<std::string*>(itr->default_val)));
561 out <<
"=" << add_quotes(
562 enum_opt_default_val_name(itr->opt_name,any_cast<int>(itr->default_val),&out));
569 if(doc_string_.length()) {
570 out <<
"\nDETAILED DOCUMENTATION:\n\n" << doc_string_ << std::endl << std::endl;
582 if (!printed_timer_summary_ && show_timer_summary_on_exit_) {
585 out = rcpFromPtr(out_inout);
590 getTimeMonitorSurrogate()->summarize(*out <<
"\n");
591 printed_timer_summary_ =
true;
599 void CommandLineProcessor::add_extra_output_setup_options()
const 603 in_add_extra_output_setup_options_
606 added_extra_output_setup_options_
609 !addOutputSetupOptions_
617 clp->in_add_extra_output_setup_options_ =
true;
619 "output-all-front-matter",
"output-no-front-matter",&clp->output_all_front_matter_
620 ,
"Set if all front matter is printed to the default FancyOStream or not" 623 "output-show-line-prefix",
"output-no-show-line-prefix",&clp->output_show_line_prefix_
624 ,
"Set if the line prefix matter is printed to the default FancyOStream or not" 627 "output-show-tab-count",
"output-no-show-tab-count",&clp->output_show_tab_count_
628 ,
"Set if the tab count is printed to the default FancyOStream or not" 631 "output-show-proc-rank",
"output-no-show-proc-rank",&clp->output_show_proc_rank_
632 ,
"Set if the processor rank is printed to the default FancyOStream or not" 635 "output-to-root-rank-only",&clp->output_to_root_rank_only_
636 ,
"Set which processor (the root) gets the output. If < 0, then all processors get output." 639 "print-rcpnode-statistics-on-exit",
"no-print-rcpnode-statistics-on-exit",
640 &clp->print_rcpnode_statistics_on_exit_,
641 "Set if the RCPNode usage statistics will be printed on exit or not. Warning," 642 " this prints to std::cerr or every process so do not turn this on for very large" 645 if (
nonnull(getTimeMonitorSurrogate())) {
647 "show-timer-summary",
"no-show-timer-sumary", &clp->show_timer_summary_on_exit_,
648 "If true, then Teuchos::TimeMonitor::summarize() is called in" 649 " CommandLineProcessor's destructor (usually at the end of main)." 653 clp->added_extra_output_setup_options_ =
true;
654 clp->in_add_extra_output_setup_options_ =
false;
658 void CommandLineProcessor::setEnumOption(
659 const char enum_option_name[]
660 ,
int *enum_option_val
661 ,
const int num_enum_opt_values
662 ,
const int enum_opt_values[]
663 ,
const char* enum_opt_names[]
664 ,
const char documentation[]
668 add_extra_output_setup_options();
675 enum_opt_data_list_.push_back(
676 enum_opt_data_t(enum_option_val,num_enum_opt_values,enum_opt_values,enum_opt_names)
678 const int opt_id =
static_cast<int>(enum_opt_data_list_.size())-1;
679 options_list_[std::string(enum_option_name)]
680 = opt_val_val_t(OPT_ENUM_INT,any(opt_id),required);
681 options_documentation_list_.push_back(
682 opt_doc_t(OPT_ENUM_INT,enum_option_name,
"",
683 std::string(documentation?documentation:
""), any(opt_id))
688 bool CommandLineProcessor::set_enum_value(
691 ,
const std::string &enum_opt_name
693 ,
const std::string &enum_str_val
694 ,std::ostream *errout
697 const enum_opt_data_t
698 &enum_opt_data = enum_opt_data_list_.at(enum_id);
699 std::vector<std::string>::const_iterator
700 itr_begin = enum_opt_data.enum_opt_names.begin(),
701 itr_end = enum_opt_data.enum_opt_names.end(),
702 itr = std::find( itr_begin, itr_end, enum_str_val );
703 if( itr == itr_end ) {
704 const int j = argv_i;
705 #define CLP_ERR_MSG \ 706 "Error, the value \"" << enum_str_val << "\" for the " \ 707 << j<<(j==1?"st":(j==2?"nd":(j==3?"rd":"th"))) << " option --" \ 708 << enum_opt_name << " was not recognized (use --help)!" 710 *errout << std::endl << argv[0] <<
" : " << CLP_ERR_MSG << std::endl;
719 const int enum_opt_val_index =
static_cast<int>(itr - itr_begin);
720 *enum_opt_data.enum_option_val = enum_opt_data.enum_opt_values.at(enum_opt_val_index);
725 void CommandLineProcessor::print_enum_opt_names(
730 const enum_opt_data_t
731 &enum_opt_data = enum_opt_data_list_.at(enum_id);
732 typedef std::vector<std::string>::const_iterator itr_t;
733 out <<
"Valid options:";
735 itr_t itr = enum_opt_data.enum_opt_names.begin();
736 itr != enum_opt_data.enum_opt_names.end();
740 if( itr != enum_opt_data.enum_opt_names.begin() ) out <<
",";
741 out <<
" " << add_quotes(*itr);
747 CommandLineProcessor::enum_opt_default_val_name(
748 const std::string &enum_name
750 ,std::ostream *errout
753 const enum_opt_data_t
754 &enum_opt_data = enum_opt_data_list_.at(enum_id);
755 return enum_opt_data.enum_opt_names.at(
757 enum_name,*enum_opt_data.enum_option_val,enum_opt_data,errout
763 int CommandLineProcessor::find_enum_opt_index(
764 const std::string &enum_opt_name
766 ,
const enum_opt_data_t &enum_data
767 ,std::ostream *errout
770 std::vector<int>::const_iterator
771 itr_begin = enum_data.enum_opt_values.begin(),
772 itr_end = enum_data.enum_opt_values.end(),
773 itr = std::find( itr_begin, itr_end, opt_value );
774 if( itr == itr_end ) {
775 #define CLP_ERR_MSG \ 776 ( recogniseAllOptions() ? "Error" : "Warning" ) \ 777 << ", option --" << enum_opt_name << " was given an invalid " \ 778 "initial option value of " << opt_value << "!" 780 *errout << CLP_ERR_MSG << std::endl;
785 return static_cast<int>(itr - itr_begin);
789 bool CommandLineProcessor::get_opt_val(
791 ,std::string *opt_name
792 ,std::string *opt_val_str
795 const int len =
static_cast<int>(std::strlen(str));
798 if( str[0] !=
'-' || str[1] !=
'-' )
802 for( equ_i = 2; equ_i < len && str[equ_i] !=
'='; ++equ_i );
804 opt_name->assign( str + 2, equ_i-2 );
810 opt_val_str->assign( str + equ_i + 1, len - equ_i - 1 );
815 void CommandLineProcessor::print_bad_opt(
818 ,std::ostream *errout
821 const int j = argv_i;
822 #define CLP_ERR_MSG \ 823 ( recogniseAllOptions() ? "Error" : "Warning" ) \ 824 << ", the " << j<<(j==1?"st":(j==2?"nd":(j==3?"rd":"th"))) \ 825 << " option \'" << argv[argv_i] << "\' was not recognized (use --help)!" 827 *errout << std::endl << argv[0] <<
" : " << CLP_ERR_MSG << std::endl;
837 void CommandLineProcessor::setTimeMonitorSurrogate(
838 const RCP<CommandLineProcessor::TimeMonitorSurrogate> &timeMonitorSurrogate)
840 getRawTimeMonitorSurrogate() = timeMonitorSurrogate;
844 RCP<CommandLineProcessor::TimeMonitorSurrogate>
845 CommandLineProcessor::getTimeMonitorSurrogate()
847 return getRawTimeMonitorSurrogate();
851 RCP<CommandLineProcessor::TimeMonitorSurrogate>&
852 CommandLineProcessor::getRawTimeMonitorSurrogate()
854 static RCP<TimeMonitorSurrogate> timeMonitorSurrogate;
855 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.
bool nonnull(const std::shared_ptr< T > &p)
Returns true if p.get()!=NULL.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
bool recogniseAllOptions() const
Returns true if all options must be recognized by the parser.
static void setPrintRCPNodeStatisticsOnExit(bool printRCPNodeStatisticsOnExit)
Set if RCPNode usage statistics will be printed when the program ends or not.
CommandLineProcessor(bool throwExceptions=true, bool recogniseAllOptions=true, bool addOutputSetupOptions=false)
Default Constructor.
Modified boost::any class, which is a container for a templated value.
T * get() const
Get the raw C++ pointer to the underlying object.
~CommandLineProcessor()
Destructor.
void setOption(const char option_true[], const char option_false[], bool *option_val, const char documentation[]=NULL)
Set a boolean option.
EParseCommandLineReturn parse(int argc, char *argv[], std::ostream *errout=&std::cerr) const
Parse a command line.
static RCP< FancyOStream > getDefaultOStream()
Get the default output stream object.
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.
The Teuchos namespace contains all of the classes, structs and enums used by Teuchos, as well as a number of utility routines.
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.
bool throwExceptions() const
Returns true if an std::exception is thrown, there is a parse error, or help is printed.
void printHelpMessage(const char program_name[], std::ostream &out) const
Print the help message.
static void barrier()
Call MPI_Barrier() on MPI_COMM_WORLD.
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...