& description) :
81 returnopt_name.length() == 1 ?
'-'+ opt_name :
"--"+ opt_name;
125 const string& synopsis,
const string&
usage) :
163 const string& program_name,
164 const string& program_summary,
165 const string& program_description,
166 const string& version_info);
169 const string&
text,
intcont_indent = -1)
const;
171 boolusing_help_command)
const;
173 const string& name_for_synopsis,
const string& name_for_usage)
const;
213 const string& program_name,
214 const string& program_summary,
215 const string& program_description,
216 const string& version_info) :
218m_ProgramName(program_name),
219m_VersionInfo(version_info),
236 int indent,
const string&
text,
intcont_indent)
const 238 if(
text.empty()) {
243 const char* line =
text.data();
244 const char* text_end = line +
text.length();
247 if(topic_len > 0 && (
offset-= topic_len) < 1) {
256 const char* next_line =
NULL;
258 const char* next_line;
261 const char* line_end;
264 const char* pos = line;
270 while(pos < text_end && pos[1] ==
' ')
273}
else if(*pos ==
'\n') {
274next_line = (line_end = pos) + 1;
277 if(++pos > max_pos && line_end !=
NULL)
279 if(pos == text_end) {
280next_line = line_end = pos;
286line_end = strchr(line,
'\n');
287next_line = (line_end ==
NULL? line_end = text_end : line_end + 1);
289 intline_len =
int(line_end - line);
291printf(
"%*.*s\n",
offset+ line_len, line_len, line);
295}
while((line = next_line) < text_end);
299 boolusing_help_command)
const 303 stringopt_name(option_value->first->GetNameVariants());
304 if(using_help_command)
305 Throw(
"command 'help' doesn't accept option '"+
306opt_name +
"'",
s_Help);
308 Throw(
"'--help' cannot be combined with option '"+
309opt_name +
"'",
"--help");
314 else if(commands.empty()) {
315printf(
"Usage: %s <command> [options] [args]\n",
m_ProgramName.c_str());
317printf(
"Type '%s help <command>' for help on a specific command.\n" 318 "Type '%s --version' to see the program version.\n",
325 if(!category->second->m_Commands.empty()) {
326printf(
"\n%s:\n\n", category->second->m_Title.c_str());
329(*cmd)->GetNameVariants().c_str()),
337 "Describe the usage of this program or its commands.",
kEmptyStr);
347command_info =
cmd->second;
348 else if(*cmd_name ==
s_Help)
349command_info = &help_command;
351printf(
"'%s': unknown command.\n\n", *cmd_name);
362 const string& name_for_synopsis,
const string& name_for_usage)
const 364 inttext_len = printf(
"%s:", name_for_synopsis.c_str());
371args.push_back(
' ');
372 switch((*arg)->m_Type) {
374args.append((*arg)->GetPrimaryName());
377args.push_back(
'[');
378args.append((*arg)->GetPrimaryName());
379args.push_back(
']');
382args.push_back(
'[');
383args.append((*arg)->GetPrimaryName());
384args.append(
"...]");
387args.append((*arg)->GetPrimaryName());
388args.append(
"...");
391text_len = printf(
"Usage: %s", name_for_usage.c_str());
394 if(!common_parts->
m_Usage.empty()) {
400printf(
"\nValid options:\n");
403(*opt)->GetNameVariants().c_str()),
416message.append(
": ");
417message.append(
error);
419message.append(
"\nType '");
423message.append(
" --help' for usage.\n");
424 else if(
cmd.empty())
425message.append(
" help' for usage.\n");
427message.append(
" help ");
428message.append(
cmd);
429message.append(
"' for usage.\n");
431 throwruntime_error(message);
438string::size_type basename_pos =
m_ProgramName.find_last_of(
"/\\:");
439 if(basename_pos != string::npos)
447 const char* arg = *++argv;
450 if(*arg !=
'-'|| arg[1] ==
'\0')
451positional_arguments.push_back(arg);
456 const char* opt_param;
457 if(*++arg ==
'-') {
461 if(*++arg ==
'\0') {
463positional_arguments.push_back(*++argv);
467opt_param = strchr(arg,
'=');
469 if(opt_param !=
NULL)
470opt_name.assign(arg, opt_param++);
472opt_name.assign(arg);
476 Throw(
"unknown option '--"+ opt_name +
"'");
477option_info = opt_info->second;
481 if(opt_param !=
NULL)
482 Throw(
"option '--"+ opt_name +
483 "' does not expect a parameter");
487 if(opt_param ==
NULL) {
492 Throw(
"option '--"+ opt_name +
493 "' requires a parameter");
499 charopt_letter = *arg++;
501(
unsignedchar) opt_letter];
502 if(option_info ==
NULL)
503 Throw(
string(
"unknown option '-") + opt_letter +
"'");
517 Throw(
string(
"option '-") + opt_letter +
518 "' requires a parameter");
526option_info, opt_param));
537 switch(option_value->first->m_Id) {
544 Help(positional_arguments,
false);
559 if(positional_arguments.empty())
562command_name = positional_arguments.front();
563positional_arguments.pop_front();
569 if(command_name ==
s_Help) {
570 Help(positional_arguments,
true);
573 Throw(
"unknown command '"+ command_name +
"'");
582 Throw(
"command '"+ command_name +
"' doesn't accept option '"+
583it->first->GetNameVariants() +
"'",
587ret_val = command_info->
m_Id;
590TPositionalArgumentList::const_iterator arg_value =
591positional_arguments.begin();
592TOptionInfoList::const_iterator expected_arg =
593expected_positional_arguments->begin();
596 if(expected_arg != expected_positional_arguments->end())
597 if(arg_value == positional_arguments.end())
598 switch((*expected_arg)->m_Type) {
601 Throw(
"missing argument '"+
602(*expected_arg)->GetPrimaryName() +
"'", command_name);
605 switch((*expected_arg)->m_Type) {
609*expected_arg, *arg_value));
616*expected_arg, *arg_value));
617 while(++arg_value != positional_arguments.end());
620 if(arg_value != positional_arguments.end())
621 Throw(
"too many positional arguments", command_name);
631 const string& program_name,
632 const string& version_info,
633 const string& program_summary,
634 const string& program_description) :
636program_name, program_summary, program_description, version_info))
641 intcmd_descr_indent,
intopt_descr_indent)
643 m_Impl->m_MaxHelpTextWidth = help_text_width;
644 m_Impl->m_CmdDescrIndent = cmd_descr_indent;
645 m_Impl->m_OptDescrIndent = opt_descr_indent;
649 intopt_id,
const string& name_variants,
const string& description)
651 _ASSERT(opt_id >= 0 &&
m_Impl->m_OptIdToOptionInfoMap.find(opt_id) ==
652 m_Impl->m_OptIdToOptionInfoMap.end() &&
"Option IDs must be unique");
660 "Positional arguments do not allow name variants");
662 m_Impl->m_PositionalArguments.push_back(option_info);
668 if(name->length() == 1)
669 m_Impl->m_SingleLetterOptions[
670(
unsignedchar) name->at(0)] = option_info;
672 m_Impl->m_OptionToOptInfoMap[*name] = option_info;
674 m_Impl->m_AcceptedOptions.push_back(option_info);
680 _ASSERT(cat_id >= 0 &&
m_Impl->m_CatIdToCatInfoMap.find(cat_id) ==
681 m_Impl->m_CatIdToCatInfoMap.end() &&
"Category IDs must be unique");
687 const string& synopsis,
const string&
usage,
intcat_id)
689 _ASSERT(cmd_id >= 0 &&
m_Impl->m_CmdIdToCommandInfoMap.find(cmd_id) ==
690 m_Impl->m_CmdIdToCommandInfoMap.end() &&
"Command IDs must be unique");
693 m_Impl->m_CatIdToCatInfoMap.end() &&
"No such category ID");
698 m_Impl->m_CatIdToCatInfoMap[cat_id]->m_Commands.push_back(command_info);
701 m_Impl->m_CommandNameToCommandInfoMap[*name] = command_info;
707 m_Impl->m_CmdIdToCommandInfoMap.end() &&
"No such command ID");
710 m_Impl->m_OptIdToOptionInfoMap.end() &&
"No such option ID");
715 switch(opt_info->
m_Type) {
722 _ASSERT(
"Invalid sequence of optional positional arguments"&&
736 return m_Impl->ParseAndValidate(argc, argv);
741 return m_Impl->m_ProgramName;
746 if(
m_Impl->m_NextOptionValue ==
m_Impl->m_OptionValues.end())
749*opt_id =
m_Impl->m_NextOptionValue->first->m_Id;
750*opt_value =
m_Impl->m_NextOptionValue->second;
752++
m_Impl->m_NextOptionValue;
int Parse(int argc, const char *const *argv)
Parse the command line.
bool NextOption(int *opt_id, const char **opt_value)
void AddOption(EOptionType type, int opt_id, const string &name_variants, const string &description)
void AddCommandCategory(int cat_id, const string &title)
void AddCommand(int cmd_id, const string &name_variants, const string &synopsis, const string &usage, int cat_id=-1)
CNetRef< SCommandLineParserImpl > m_Impl
void AddAssociation(int cmd_id, int opt_id)
const string & GetProgramName() const
void SetHelpTextMargins(int help_text_width, int cmd_descr_indent, int opt_descr_indent)
container_type::const_iterator const_iterator
const_iterator end() const
const_iterator find(const key_type &key) const
list< string > TNameVariantList
static const char s_Version[]
#define DEFAULT_CMD_DESCR_INDENT
list< const SCommandInfo * > TCommandInfoList
list< const char * > TPositionalArgumentList
#define UNSPECIFIED_CATEGORY_ID
static const char s_Help[]
#define DEFAULT_OPT_DESCR_INDENT
#define DEFAULT_HELP_TEXT_WIDTH
list< const SOptionInfo * > TOptionInfoList
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
#define END_NCBI_SCOPE
End previously defined NCBI scope.
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
static list< string > & Split(const CTempString str, const CTempString delim, list< string > &arr, TSplitFlags flags=0, vector< SIZE_TYPE > *token_pos=NULL)
Split a string using specified delimiters.
@ fSplit_MergeDelimiters
Merge adjacent delimiters.
unsigned int
A callback function used to compare two keys in a database.
static void text(MDB_val *v)
TCommandInfoList m_Commands
SCategoryInfo(const string &title)
string GetNameVariants() const
SCommandInfo(int cmd_id, const string &name_variants, const string &synopsis, const string &usage)
pair< const SOptionInfo *, const char * > TOptionValue
int ParseAndValidate(int argc, const char *const *argv)
void HelpOnCommand(const SCommonParts *common_parts, const string &name_for_synopsis, const string &name_for_usage) const
void PrintWordWrapped(int topic_len, int indent, const string &text, int cont_indent=-1) const
TCatIdToCategoryInfoMap m_CatIdToCatInfoMap
void Throw(const string &error, const string &cmd=kEmptyStr) const
void Help(const TPositionalArgumentList &commands, bool using_help_command) const
map< int, CRef< SCategoryInfo > > TCatIdToCategoryInfoMap
bool CommandsAreDefined() const
map< string, const SOptionInfo * > TOptionNameToOptionInfoMap
map< int, CRef< SCommandInfo > > m_CmdIdToCommandInfoMap
map< string, const SCommandInfo * > TCommandNameToCommandInfoMap
TCommandNameToCommandInfoMap m_CommandNameToCommandInfoMap
const SOptionInfo * m_SingleLetterOptions[256]
TOptionValues m_OptionValues
TOptionNameToOptionInfoMap m_OptionToOptInfoMap
SCommandLineParserImpl(const string &program_name, const string &program_summary, const string &program_description, const string &version_info)
list< TOptionValue > TOptionValues
SOptionInfo m_VersionOption
TOptionValues::const_iterator m_NextOptionValue
map< int, CRef< SOptionInfo > > m_OptIdToOptionInfoMap
SCommonParts(const string &synopsis, const string &usage)
TOptionInfoList m_AcceptedOptions
TOptionInfoList m_PositionalArguments
SOptionInfo(int opt_id, const string &name_variants, CCommandLineParser::EOptionType type, const string &description)
string GetNameVariants() const
static string AddDashes(const string &opt_name)
SOptionOrCommandInfo(int id, const string &name_variants)
TNameVariantList m_NameVariants
const string & GetPrimaryName() const
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4