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_
616 *clp = const_cast<CommandLineProcessor*>(
this);
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;