28 const std::string &desc,
29 const std::string &defaultValue)
34 _defaultValue(defaultValue),
41 const std::string &desc,
42 const std::string &defaultValue)
47 _defaultValue(defaultValue),
50 for (
const auto &name : names) {
61 bool haveName =
false;
62 for (
size_t i = 0; i < _names.size(); i++) {
63 if (_names.at(i) == name) {
69 _names.push_back(name);
82 for (
const auto &
n : _names) {
114 _defaultValue = value;
119 return _defaultValue;
124 _values.push_back(value);
129 if (index > _values.size() || _values.empty()) {
132 return _values.at(index);
156 : _flags(flags), _name(), _commandName(), _desc(), _descExtra(), _usageText(), _helpText(),
157 _options(), _subParsers()
163 : _flags(flags), _name(name), _commandName(), _desc(), _descExtra(), _usageText(), _helpText(),
164 _options(), _subParsers()
180 _flags = other._flags;
182 _commandName = other._commandName;
184 _descExtra = other._descExtra;
185 _usageText = other._usageText;
186 _helpText = other._helpText;
187 _options = other._options;
189 for (
SubParserMapConstIter iter = other._subParsers.begin(); iter != other._subParsers.end(); ++iter) {
194 void AJACommandLineParser::init()
220 for (
auto &sp : _subParsers) {
225 for (
auto &opt : _options) {
233 if (!_commandName.empty()) {
240 iter != _options.end(); ++iter) {
243 std::ostringstream oss;
250 if (++count < names.size()) {
254 oss <<
"] " <<
"set? " << (
IsSet(name) ?
"true" :
"false") <<
" value = " << o.
Value();
255 std::cout << oss.str() << std::endl;
262 for (
const auto &opt : _options) {
263 for (
const auto &
n : opt.Names()) {
274 for (
const auto &arg : _positionalArgs) {
284 return _positionalArgs;
289 for (
const auto &o : _options) {
290 for (
const auto &
n : o.Names()) {
302 const std::string &name = p->
Name();
303 if (_subParsers.find(name) == _subParsers.end()) {
313 AJAStringList::const_iterator iter = args.begin();
316 for (SubParserMap::iterator spIter = _subParsers.begin(); spIter != _subParsers.end(); ++spIter) {
318 if (*iter == spIter->first) {
319 _commandName = *iter;
322 if (spIter->second !=
NULL) {
323 if (!spIter->second->Parse(args)) {
324 std::cerr <<
"Error parsing args with sub-parser: " << spIter->second->Name() << std::endl;
335 if (!_name.empty() && *iter != _name) {
340 bool havePositionalArgs =
false;
341 for (; iter != args.end(); iter++) {
342 const std::string &arg = *iter;
345 havePositionalArgs =
true;
349 if (havePositionalArgs) {
350 _positionalArgs.push_back(arg);
354 if (hasOptionPrefix(arg)) {
357 std::string optValue;
362 argStr = arg.substr(2, arg.length());
363 }
else if (singleDash) {
364 argStr = arg.substr(1, arg.length());
366 if (hasAssignmentOperator(argStr)) {
367 size_t assignPos = argStr.find_first_of(
kAssignChar);
368 optName = argStr.substr(0, assignPos);
369 optValue = argStr.substr(assignPos+1, argStr.length());
383 for (
size_t c = 1; c < arg.length(); c++) {
384 subStr = arg.substr(c, 1);
386 setOption(subStr,
true);
400 for (
size_t c = arg.length(); c > 1; c--) {
401 subStr = arg.substr(1, c-1);
404 size_t count = (arg.length()-1)-optName.length();
405 optValue = arg.substr(optName.length()+1, count);
409 if (optName.empty()) {
420 if (optValue.empty()) {
421 auto nextIter = iter;
423 if (nextIter != args.end()) {
424 std::string nextArg = *(nextIter++);
425 if (!hasOptionPrefix(nextArg)) {
433 if (!optValue.empty()) {
434 setOptionValue(optName, optValue);
436 setOption(optName,
true);
438 std::cerr <<
"Unknown arg: " << optName << std::endl;
446 {std::cout <<
HelpText();
return false;}
450 {std::cout <<
UsageText();
return false;}
457 if (argc == 0 || argv ==
NULL) {
461 for (
int i = 0; i < argc; i++) {
462 argList.push_back(std::string(argv[i]));
464 return Parse(argList);
469 if (argc == 0 || argv ==
NULL) {
473 for (
int i = 0; i < argc; i++) {
474 argList.push_back(std::string(argv[i]));
476 return Parse(argList);
481 if (!_commandName.empty()) {
484 return sp->
IsSet(name);
503 if (!values.empty()) {
516 if (!_commandName.empty()) {
524 val = opt.
Value(index);
536 if (!_commandName.empty()) {
558 if (*wantIter == *nameIter) {
570 _options.push_back(option);
578 for (
size_t i = 0; i < options.size(); i++) {
587 return options.size() ? (okCount == options.size() ?
true :
false) :
false;
598 helpOpt.
SetDesc(
"Print the help text");
609 usageOpt.
SetDesc(
"Print the usage text");
615 if (!_commandName.empty()) {
627 if (!_commandName.empty()) {
633 _usageText = usageText;
639 if (!_commandName.empty()) {
646 std::string usageText;
647 if (!_usageText.empty()) {
648 usageText = _usageText;
650 usageText = generateUsageText();
657 if (!_commandName.empty()) {
663 _helpText = helpText;
669 if (!_commandName.empty()) {
676 std::string helpText;
677 if (_helpText.empty()) {
678 helpText = generateHelpText();
680 helpText = _helpText;
685 std::string AJACommandLineParser::generateHelpText()
const 687 std::ostringstream oss;
690 oss <<
"Usage: " << exePath;
691 if (!_name.empty()) {
694 oss <<
" [OPTION...]" << std::endl;
697 size_t longestSize = 0;
699 it != _options.end(); ++it) {
701 size_t namesLength = 0;
703 const std::string &name = *sIter;
704 namesLength += name.length();
706 if (name.length() == 1) {
713 namesLength += ((names.size()*2)-2);
714 if (namesLength > longestSize) {
715 longestSize = namesLength;
721 it != _options.end(); ++it) {
722 oss << std::setw(2) << std::right;
724 size_t nameCount = 0;
725 size_t namesLength = 0;
727 const std::string &name = *sIter;
728 namesLength += name.length();
729 if (name.length() == 1) {
736 if (++nameCount < names.size()) {
740 namesLength += ((names.size()*2)-2);
741 oss << std::setw((longestSize-namesLength) + it->Desc().length() + 8);
742 oss << it->Desc() << std::endl;
748 std::string AJACommandLineParser::generateUsageText()
const 750 std::ostringstream oss;
753 oss <<
"Usage: " << exePath;
754 if (!_name.empty()) {
759 std::ostringstream usages;
760 bool haveHelp =
false;
761 bool haveUsage =
false;
762 for (
const auto &opt : _options) {
763 if (opt.HaveName(
"?")) {
765 }
else if (opt.HaveName(
"usage")) {
768 auto names = opt.Names();
770 for (
size_t ndx = 0; ndx < names.size(); ndx++) {
771 auto name = names.at(ndx);
772 bool isShortName = name.length() == 1;
775 usages <<
'-' << name;
777 usages <<
"--" << name;
779 if (ndx < names.size()-1) {
783 usages <<
']' << std::endl;
789 usages <<
"\t[" <<
"-?|--help]" << std::endl;
792 usages <<
"\t[" <<
"--usage]" << std::endl;
795 if (!abbrev.empty()) {
799 oss <<
" [-" << abbrev <<
"]" << std::endl;
801 oss << usages.str() << std::endl;
803 if (!_subParsers.empty()) {
804 oss <<
'\n' <<
"commands: " << std::endl;
805 for (
const auto &sp : _subParsers) {
807 oss <<
"\t " << sp.second->Name() << std::endl;
819 bool AJACommandLineParser::hasOptionPrefix(
const std::string &name)
824 bool AJACommandLineParser::hasAssignmentOperator(
const std::string &arg)
827 return assignPos != std::string::npos;
830 bool AJACommandLineParser::setOptionValue(
const std::string &name,
const std::string &value)
832 if (!
value.empty()) {
833 for (
size_t i = 0; i < _options.size(); i++) {
838 _options[i].AddValue(value);
847 bool AJACommandLineParser::setOption(
const std::string &name,
bool isSet)
849 for (
size_t i = 0; i < _options.size(); i++) {
854 _options[i].MarkSet(isSet);
std::vector< AJACommandLineOption > AJACommandLineOptionList
void SetHelpText(const std::string &helpText)
void MarkSet(bool isSet=true)
bool HaveOption(const std::string &name) const
SubParserMap::const_iterator SubParserMapConstIter
AJAStringList PositionalArgs() const
bool starts_with(const std::string &str, const std::string &needle)
std::vector< AJAVariant > AJAVariantList
AJACommandLineParser(int flags=0)
bool IsSet(const std::string &name) const
std::vector< std::string > AJAStringList
void AddValue(const std::string &value)
void SetDesc(const std::string &desc)
bool AddSubParser(AJACommandLineParser *sp)
bool AddOption(const AJACommandLineOption &option)
void Reset(bool clearAll=false)
bool HavePositionalArg(const std::string &name) const
Declares the AJAFileIO class.
bool Parse(const AJAStringList &args)
virtual ~AJACommandLineOption()
std::string DefaultValue() const
static const char * kDoubleDash
AJAVariantList Values(const std::string &name) const
the parser finished reading a JSON value
std::string CommandName()
AJAStringList Names() const
std::pair< std::string, AJACommandLineParser * > AJASubParserPair
Declaration of Command Line classes.
bool AddOptions(const std::vector< AJACommandLineOption > &options)
AJAVariant Value(const std::string &name, size_t index=0) const
bool HaveName(const std::string &name) const
AJAStringList::const_iterator AJAStringListConstIter
static const char kSingleDash
void SetDefaultValue(const std::string &value)
AJAStringList Values() const
bool AddUsageOption(bool useShortName=false)
std::string ValueString(const std::string &name, size_t index=0) const
AJACommandLineOptionList::const_iterator AJACommandLineOptionListIter
Private include file for all ajabase sources.
AJAStringList ValueStrings(const std::string &name) const
bool OptionByName(const std::string &name, AJACommandLineOption &opt) const
static const char kAssignChar
std::string ExtraDesc() const
void operator=(const AJACommandLineParser &other)
void SetExtraDesc(const std::string &desc)
static AJAStatus GetExecutablePath(std::string &path)
bool AddHelpOption(bool useShortName=false)
void SetUsageText(const std::string &usageText)
bool AddName(const std::string &name)
std::string Value(size_t index=0) const