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);
390 for (
size_t c = arg.length(); c > 1; c--) {
391 subStr = arg.substr(1, c-1);
394 size_t count = (arg.length()-1)-optName.length();
395 optValue = arg.substr(optName.length()+1, count);
398 std::cerr <<
"Unknown arg: " << subStr << std::endl;
408 if (optValue.empty()) {
409 auto nextIter = iter;
411 if (nextIter != args.end()) {
412 std::string nextArg = *(nextIter++);
413 if (!hasOptionPrefix(nextArg)) {
421 if (!optValue.empty()) {
422 setOptionValue(optName, optValue);
424 setOption(optName,
true);
426 std::cerr <<
"Unknown arg: " << optName << std::endl;
434 {std::cout <<
HelpText();
return false;}
438 {std::cout <<
UsageText();
return false;}
445 if (argc == 0 || argv ==
NULL) {
449 for (
int i = 0; i < argc; i++) {
450 argList.push_back(std::string(argv[i]));
452 return Parse(argList);
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 (!_commandName.empty()) {
472 return sp->
IsSet(name);
491 if (!values.empty()) {
504 if (!_commandName.empty()) {
512 val = opt.
Value(index);
524 if (!_commandName.empty()) {
546 if (*wantIter == *nameIter) {
558 _options.push_back(option);
566 for (
size_t i = 0; i < options.size(); i++) {
575 return options.size() ? (okCount == options.size() ?
true :
false) :
false;
586 helpOpt.
SetDesc(
"Print the help text");
597 usageOpt.
SetDesc(
"Print the usage text");
603 if (!_commandName.empty()) {
615 if (!_commandName.empty()) {
621 _usageText = usageText;
627 if (!_commandName.empty()) {
634 std::string usageText;
635 if (!_usageText.empty()) {
636 usageText = _usageText;
638 usageText = generateUsageText();
645 if (!_commandName.empty()) {
651 _helpText = helpText;
657 if (!_commandName.empty()) {
664 std::string helpText;
665 if (_helpText.empty()) {
666 helpText = generateHelpText();
668 helpText = _helpText;
673 std::string AJACommandLineParser::generateHelpText()
const
675 std::ostringstream oss;
678 oss <<
"Usage: " << exePath;
679 if (!_name.empty()) {
682 oss <<
" [OPTION...]" << std::endl;
685 size_t longestSize = 0;
687 it != _options.end(); ++it) {
689 size_t namesLength = 0;
691 const std::string &name = *sIter;
692 namesLength += name.length();
694 if (name.length() == 1) {
701 namesLength += ((names.size()*2)-2);
702 if (namesLength > longestSize) {
703 longestSize = namesLength;
709 it != _options.end(); ++it) {
710 oss << std::setw(2) << std::right;
712 size_t nameCount = 0;
713 size_t namesLength = 0;
715 const std::string &name = *sIter;
716 namesLength += name.length();
717 if (name.length() == 1) {
724 if (++nameCount < names.size()) {
728 namesLength += ((names.size()*2)-2);
729 oss << std::setw((longestSize-namesLength) + it->Desc().length() + 8);
730 oss << it->Desc() << std::endl;
736 std::string AJACommandLineParser::generateUsageText()
const
738 std::ostringstream oss;
741 oss <<
"Usage: " << exePath;
742 if (!_name.empty()) {
747 std::ostringstream usages;
748 bool haveHelp =
false;
749 bool haveUsage =
false;
750 for (
const auto &opt : _options) {
751 if (opt.HaveName(
"?")) {
753 }
else if (opt.HaveName(
"usage")) {
756 auto names = opt.Names();
758 for (
size_t ndx = 0; ndx < names.size(); ndx++) {
759 auto name = names.at(ndx);
760 bool isShortName = name.length() == 1;
763 usages <<
'-' << name;
765 usages <<
"--" << name;
767 if (ndx < names.size()-1) {
771 usages <<
']' << std::endl;
777 usages <<
"\t[" <<
"-?|--help]" << std::endl;
780 usages <<
"\t[" <<
"--usage]" << std::endl;
783 if (!abbrev.empty()) {
787 oss <<
" [-" << abbrev <<
"]" << std::endl;
789 oss << usages.str() << std::endl;
791 if (!_subParsers.empty()) {
792 oss <<
'\n' <<
"commands: " << std::endl;
793 for (
const auto &sp : _subParsers) {
795 oss <<
"\t " << sp.second->Name() << std::endl;
807 bool AJACommandLineParser::hasOptionPrefix(
const std::string &name)
812 bool AJACommandLineParser::hasAssignmentOperator(
const std::string &arg)
815 return assignPos != std::string::npos;
818 bool AJACommandLineParser::setOptionValue(
const std::string &name,
const std::string &value)
820 if (!
value.empty()) {
821 for (
size_t i = 0; i < _options.size(); i++) {
826 _options[i].AddValue(value);
835 bool AJACommandLineParser::setOption(
const std::string &name,
bool isSet)
837 for (
size_t i = 0; i < _options.size(); i++) {
842 _options[i].MarkSet(isSet);