ROSE  0.9.9.109
CommandLine.h
1 // WARNING: Changes to this file must be contributed back to Sawyer or else they will
2 // be clobbered by the next update from Sawyer. The Sawyer repository is at
3 // https://github.com/matzke1/sawyer.
4 
5 
6 
7 
8 /* Command-line switch parsing. */
9 #ifndef Sawyer_CommandLine_H
10 #define Sawyer_CommandLine_H
11 
12 #include <Sawyer/Assert.h>
13 #include <Sawyer/DocumentMarkup.h>
14 #include <Sawyer/Map.h>
15 #include <Sawyer/Message.h>
16 #include <Sawyer/Optional.h>
17 #include <Sawyer/Sawyer.h>
18 #include <Sawyer/Set.h>
19 #include <Sawyer/SharedPointer.h>
20 
21 #include <boost/algorithm/string/case_conv.hpp>
22 #include <boost/any.hpp>
23 #include <boost/cstdint.hpp>
24 #include <boost/foreach.hpp>
25 #include <boost/lexical_cast.hpp>
26 #include <boost/numeric/conversion/cast.hpp>
27 #include <cerrno>
28 #include <ctype.h>
29 #include <list>
30 #include <set>
31 #include <stdexcept>
32 #include <string>
33 #include <vector>
34 
35 namespace Sawyer { // documented in Sawyer.h
36 
161 namespace CommandLine {
162 
163 SAWYER_EXPORT extern const std::string STR_NONE;
164 class Switch;
165 class SwitchGroup;
166 class Parser;
167 class ParserResult;
168 
170 enum SortOrder {
180 };
181 
183 enum Canonical {
188 };
189 
196 };
197 
203 };
204 
206 // Program argument cursor
208 
213 struct SAWYER_EXPORT Location {
214  size_t idx;
215  size_t offset;
219  Location(): idx(0), offset(0) {}
220 
222  Location(size_t idx, size_t offset): idx(idx), offset(offset) {}
223 
226  bool operator==(const Location &other) const { return idx==other.idx && offset==other.offset; }
227 
230  bool operator!=(const Location &other) const { return !(*this==other); }
231 
234  bool operator<(const Location &other) const { return idx<other.idx || (idx==other.idx && offset<other.offset); }
235 
238  bool operator<=(const Location &other) const { return *this<other || *this==other; }
239 };
240 
242 SAWYER_EXPORT std::ostream& operator<<(std::ostream&, const Location&);
243 
247 SAWYER_EXPORT extern const Location NOWHERE;
248 
252 class SAWYER_EXPORT Cursor {
253 #include <Sawyer/WarningsOff.h>
254  std::vector<std::string> strings_;
255  Location loc_;
256 #include <Sawyer/WarningsRestore.h>
257 public:
260  Cursor(const std::vector<std::string> &strings): strings_(strings) { location(Location()); }
261 
264  Cursor(const std::string &string): strings_(1, string) { location(Location()); }
265 
267  Cursor() {}
268 
270  const std::vector<std::string>& strings() const { return strings_; }
271 
289  const Location& location() const { return loc_; }
290  Cursor& location(const Location &loc);
295  bool atArgBegin() const { return loc_.idx<strings_.size() && 0==loc_.offset; }
296 
299  bool atArgEnd() const { return loc_.idx<strings_.size() && loc_.offset>=strings_[loc_.idx].size(); }
300 
305  bool atEnd() const { return atEnd(loc_); }
306  bool atEnd(const Location &location) const { return location.idx >= strings_.size(); }
313  const std::string& arg() const { return arg(loc_); }
314  const std::string& arg(const Location &location) const;
321  std::string rest() const { return rest(loc_); }
322  std::string rest(const Location &location) const;
330  std::string substr(const Location &limit, const std::string &separator=" ") const { return substr(loc_, limit, separator); }
331  std::string substr(const Location &limit1, const Location &limit2, const std::string &separator=" ") const;
336  void replace(const std::vector<std::string>&);
337 
341  void consumeChars(size_t nchars);
342 
347  void consumeArgs(size_t nargs) {
348  loc_.idx = std::min(strings_.size(), loc_.idx+nargs);
349  loc_.offset = 0;
350  }
351  void consumeArg() { consumeArgs(1); }
359  size_t linearDistance() const;
360 };
361 
365  Cursor &cursor_;
366  Location loc_;
367  bool canceled_;
368 public:
371  ExcursionGuard(Cursor &cursor): cursor_(cursor), loc_(cursor.location()), canceled_(false) {} // implicit
372  ~ExcursionGuard() { if (!canceled_) cursor_.location(loc_); }
373 
376  void cancel() { canceled_ = true; }
377 
380  const Location &startingLocation() const { return loc_; }
381 };
382 
383 
385 // Switch value savers
387 
388 // used internally
389 class SAWYER_EXPORT ValueSaver: public SharedObject {
390 protected:
391  ValueSaver() {}
392 public:
394  virtual ~ValueSaver() {}
395  virtual void save(const boost::any&, const std::string &switchKey) const = 0;
396 };
397 
398 // used internally
399 template<typename T>
400 class TypedSaver: public ValueSaver {
401  T &storage_;
402 protected:
403  TypedSaver(T &storage): storage_(storage) {}
404 public:
406  static Ptr instance(T &storage) { return Ptr(new TypedSaver(storage)); }
407  virtual void save(const boost::any &value, const std::string &/*switchKey*/) const /*override*/ {
408  storage_ = boost::any_cast<T>(value);
409  }
410 };
411 
412 // Partial specialization of TypedSaver, saving a value of any type T into a container of type CONTAINER_TEMPLATE calling the
413 // containers INSERT_METHOD with one argument: the value. The CONTAINER_TEMPLATE is the name of a class template that
414 // takes one argument: type type of value stored by the container.
415 #define SAWYER_COMMANDLINE_SEQUENCE_SAVER(CONTAINER_TEMPLATE, INSERT_METHOD) \
416  template<typename T> \
417  class TypedSaver<CONTAINER_TEMPLATE<T> >: public ValueSaver { \
418  CONTAINER_TEMPLATE<T> &storage_; \
419  protected: \
420  TypedSaver(CONTAINER_TEMPLATE<T> &storage): storage_(storage) {} \
421  public: \
422  static Ptr instance(CONTAINER_TEMPLATE<T> &storage) { return Ptr(new TypedSaver(storage)); } \
423  virtual void save(const boost::any &value, const std::string &/*switchKey*/) const /*override*/ { \
424  T typed = boost::any_cast<T>(value); \
425  storage_.INSERT_METHOD(typed); \
426  } \
427  }
428 
429 // Partial specialization of TypedSaver for saving values into map-like containers. The CONTAINER_TEMPLATE should take two
430 // parameters: the key type (always std::string) and the value type (not part of this specialization). The value is stored by
431 // invoking the INSERT_METHOD with two arguments: the key string for the switch whose value is being saved, and the value to
432 // save.
433 #define SAWYER_COMMANDLINE_MAP_SAVER(CONTAINER_TEMPLATE, INSERT_METHOD) \
434  template<typename T> \
435  class TypedSaver<CONTAINER_TEMPLATE<std::string, T> >: public ValueSaver { \
436  CONTAINER_TEMPLATE<std::string, T> &storage_; \
437  protected: \
438  TypedSaver(CONTAINER_TEMPLATE<std::string, T> &storage): storage_(storage) {} \
439  public: \
440  static Ptr instance(CONTAINER_TEMPLATE<std::string, T> &storage) { return Ptr(new TypedSaver(storage)); } \
441  virtual void save(const boost::any &value, const std::string &switchKey) const /*override*/ { \
442  T typed = boost::any_cast<T>(value); \
443  storage_.INSERT_METHOD(switchKey, typed); \
444  } \
445  }
446 
447 // Partial specialization of TypedSaver for saving values into map-like containers using the STL approach where the insert
448 // operator takes an std::pair(key,value) rather than two arguments. The CONTAINER_TEMPLATE should take two parameters: the key
449 // type (always std::string) and the value type (not part of this specialization). The value is stored by invoking the
450 // INSERT_METHOD with two arguments: the key string for the switch whose value is being saved, and the value to save.
451 #define SAWYER_COMMANDLINE_MAP_PAIR_SAVER(CONTAINER_TEMPLATE, INSERT_METHOD) \
452  template<typename T> \
453  class TypedSaver<CONTAINER_TEMPLATE<std::string, T> >: public ValueSaver { \
454  CONTAINER_TEMPLATE<std::string, T> &storage_; \
455  protected: \
456  TypedSaver(CONTAINER_TEMPLATE<std::string, T> &storage): storage_(storage) {} \
457  public: \
458  static Ptr instance(CONTAINER_TEMPLATE<std::string, T> &storage) { return Ptr(new TypedSaver(storage)); } \
459  virtual void save(const boost::any &value, const std::string &switchKey) const /*override*/ { \
460  T typed = boost::any_cast<T>(value); \
461  storage_.INSERT_METHOD(std::make_pair(switchKey, typed)); \
462  } \
463  }
464 
465 SAWYER_COMMANDLINE_SEQUENCE_SAVER(std::vector, push_back);
466 SAWYER_COMMANDLINE_SEQUENCE_SAVER(std::list, push_back);
467 SAWYER_COMMANDLINE_SEQUENCE_SAVER(std::set, insert);
468 SAWYER_COMMANDLINE_SEQUENCE_SAVER(Sawyer::Container::Set, insert);
469 SAWYER_COMMANDLINE_SEQUENCE_SAVER(Optional, operator=);
470 SAWYER_COMMANDLINE_MAP_PAIR_SAVER(std::map, insert);
471 SAWYER_COMMANDLINE_MAP_SAVER(Sawyer::Container::Map, insert);
472 
474 // Parsed value
476 
483 class SAWYER_EXPORT ParsedValue {
484 #include <Sawyer/WarningsOff.h>
485  boost::any value_;
486  Location valueLocation_;
487  std::string valueString_;
488  std::string switchKey_;
489  Location switchLocation_;
490  std::string switchString_;
491  size_t keySequence_;
492  size_t switchSequence_;
493  ValueSaver::Ptr valueSaver_;
494 #include <Sawyer/WarningsRestore.h>
495 
496 public:
498  ParsedValue(): keySequence_(0), switchSequence_(0) {}
499 
509  ParsedValue(const boost::any value, const Location &loc, const std::string &str, const ValueSaver::Ptr &saver)
510  : value_(value), valueLocation_(loc), valueString_(str), keySequence_(0), switchSequence_(0), valueSaver_(saver) {}
511 
514  ParsedValue& switchInfo(const std::string &key, const Location &loc, const std::string &str) {
515  switchKey_ = key;
516  switchLocation_ = loc;
517  switchString_ = str;
518  return *this;
519  }
520 
521 private:
522  friend class ParserResult;
523  void sequenceInfo(size_t keySequence, size_t switchSequence) {
524  keySequence_ = keySequence;
525  switchSequence_ = switchSequence;
526  }
527 
528 public:
534  const boost::any& value() const { return value_; }
535  void value(const boost::any &v) { value_ = v; }
541  Location valueLocation() const { return valueLocation_; }
542  ParsedValue& valueLocation(const Location &loc) { valueLocation_ = loc; return *this; }
546  const std::string &string() const { return valueString_; }
547 
553  int asInt() const;
554  unsigned asUnsigned() const;
555  long asLong() const;
556  unsigned long asUnsignedLong() const;
557  boost::int64_t asInt64() const;
558  boost::uint64_t asUnsigned64() const;
559  double asDouble() const;
560  float asFloat() const;
561  bool asBool() const;
562  std::string asString() const;
567  template<typename T> T as() const { return boost::any_cast<T>(value_); }
568 
571  ParsedValue& switchKey(const std::string &s) { switchKey_ = s; return *this; }
572  const std::string& switchKey() const { return switchKey_; }
582  const std::string& switchString() const { return switchString_; }
583 
587  Location switchLocation() const { return switchLocation_; }
588 
591  size_t keySequence() const { return keySequence_; }
592 
595  size_t switchSequence() const { return switchSequence_; }
596 
599  const ValueSaver::Ptr valueSaver() const { return valueSaver_; }
600 
603  void save() const;
604 
606  bool isEmpty() const { return value_.empty(); }
607 
609  void print(std::ostream&) const;
610 };
611 
613 SAWYER_EXPORT std::ostream& operator<<(std::ostream&, const ParsedValue&);
614 
616 typedef std::vector<ParsedValue> ParsedValues;
617 
618 
619 
620 
622 // Switch argument parsers
624 
677 class SAWYER_EXPORT ValueParser: public SharedObject, public SharedFromThis<ValueParser> {
678 #include <Sawyer/WarningsOff.h>
679  ValueSaver::Ptr valueSaver_;
680 #include <Sawyer/WarningsRestore.h>
681 protected:
684 
686  explicit ValueParser(const ValueSaver::Ptr &valueSaver): valueSaver_(valueSaver) {}
687 public:
690 
691  virtual ~ValueParser() {}
692 
696  ParsedValue matchString(const std::string&) /*final*/;
697 
702  ParsedValue match(Cursor&) /*final*/;
703 
718  Ptr valueSaver(const ValueSaver::Ptr &f) { valueSaver_ = f; return sharedFromThis(); }
719  const ValueSaver::Ptr valueSaver() const { return valueSaver_; }
722 private:
725  virtual ParsedValue operator()(Cursor&);
726  virtual ParsedValue operator()(const char *input, const char **endptr, const Location&);
728 };
729 
730 // used internally to convert from one type to another via boost::lexical_cast or throw a runtime_error with a decent message.
731 template<typename T>
732 struct LexicalCast {
733  static T convert(const std::string &src) {
734  try {
735  return boost::lexical_cast<T>(src);
736  } catch (const boost::bad_lexical_cast &e) {
737  throw std::runtime_error(e.what());
738  }
739  }
740 };
741 
742 template<>
743 struct LexicalCast<boost::any> {
744  static boost::any convert(const std::string &src) {
745  return src;
746  }
747 };
748 
749 template<typename T>
750 struct LexicalCast<Optional<T> > {
751  static T convert(const std::string &src) {
752  return LexicalCast<T>::convert(src);
753  }
754 };
755 
756 template<typename T>
758  static T convert(const std::string &src) {
759  return LexicalCast<T>::convert(src);
760  }
761 };
762 
763 template<typename T>
764 struct LexicalCast<Sawyer::Container::Map<std::string, T> > {
765  static T convert(const std::string &src) {
766  return LexicalCast<T>::convert(src);
767  }
768 };
769 
770 template<typename T>
771 struct LexicalCast<std::vector<T> > {
772  static T convert(const std::string &src) {
773  return LexicalCast<T>::convert(src);
774  }
775 };
776 
777 template<typename T>
778 struct LexicalCast<std::set<T> > {
779  static T convert(const std::string &src) {
780  return LexicalCast<T>::convert(src);
781  }
782 };
783 
784 template<typename T>
785 struct LexicalCast<std::list<T> > {
786  static T convert(const std::string &src) {
787  return LexicalCast<T>::convert(src);
788  }
789 };
790 
791 template<typename T>
792 struct LexicalCast<std::map<std::string, T> > {
793  static T convert(const std::string &src) {
794  return LexicalCast<T>::convert(src);
795  }
796 };
797 
821 template<typename T>
822 class AnyParser: public ValueParser {
823 protected:
826 
829 public:
832 
836  static Ptr instance() { return Ptr(new AnyParser); }
837 
841  static Ptr instance(const ValueSaver::Ptr &valueSaver) { return Ptr(new AnyParser(valueSaver)); }
842 private:
843  virtual ParsedValue operator()(Cursor &cursor) /*override*/ {
844  if (cursor.atEnd())
845  throw std::runtime_error("string expected");
846  Location startLoc = cursor.location();
847  std::string s = cursor.rest();
848  cursor.consumeChars(s.size());
849  return ParsedValue(LexicalCast<T>::convert(s), startLoc, s, valueSaver());
850  }
851 };
852 
853 // used internally to cast one numeric type to another and throw a range_error with a decent message.
854 template<typename Target, typename Source>
855 struct NumericCast {
856  static Target convert(Source from, const std::string &parsed) {
857  try {
858  return boost::numeric_cast<Target>(from);
859  } catch (const boost::numeric::positive_overflow&) {
860  std::string bound = boost::lexical_cast<std::string>(boost::numeric::bounds<Target>::highest());
861  throw std::range_error("parsed string \""+parsed+"\" is greater than "+bound);
862  } catch (const boost::numeric::negative_overflow&) {
863  std::string bound = boost::lexical_cast<std::string>(boost::numeric::bounds<Target>::lowest());
864  throw std::range_error("parsed string \""+parsed+"\" is less than "+bound);
865  } catch (const boost::numeric::bad_numeric_cast&) {
866  throw std::range_error("cannot cast \""+parsed+"\" to destination type");
867  }
868  }
869 };
870 
871 // partial specialization for Sawyer::Optional<Target>
872 template<typename Target, typename Source>
873 struct NumericCast<Optional<Target>, Source> {
874  static Target convert(Source from, const std::string &parsed) {
875  return NumericCast<Target, Source>::convert(from, parsed);
876  }
877 };
878 
879 // partial specialization for std::vector<Target>
880 template<typename Target, typename Source>
881 struct NumericCast<std::vector<Target>, Source> {
882  static Target convert(Source from, const std::string &parsed) {
883  return NumericCast<Target, Source>::convert(from, parsed);
884  }
885 };
886 
887 // partial specialization for std::list<Target>
888 template<typename Target, typename Source>
889 struct NumericCast<std::list<Target>, Source> {
890  static Target convert(Source from, const std::string &parsed) {
891  return NumericCast<Target, Source>::convert(from, parsed);
892  }
893 };
894 
895 // partial specialization for std::set<Target>
896 template<typename Target, typename Source>
897 struct NumericCast<std::set<Target>, Source> {
898  static Target convert(Source from, const std::string &parsed) {
899  return NumericCast<Target, Source>::convert(from, parsed);
900  }
901 };
902 
903 // partial specialization for Sawyer::Container::Set<Target>
904 template<typename Target, typename Source>
905 struct NumericCast<Sawyer::Container::Set<Target>, Source> {
906  static Target convert(Source from, const std::string &parsed) {
907  return NumericCast<Target, Source>::convert(from, parsed);
908  }
909 };
910 
911 // partial specialization for std::map<std::string, Target>
912 template<typename Target, typename Source>
913 struct NumericCast<std::map<std::string, Target>, Source> {
914  static Target convert(Source from, const std::string &parsed) {
915  return NumericCast<Target, Source>::convert(from, parsed);
916  }
917 };
918 
919 // partial specialization for Sawyer::Container::Map<std::string, Target>
920 template<typename Target, typename Source>
921 struct NumericCast<Sawyer::Container::Map<std::string, Target>, Source> {
922  static Target convert(Source from, const std::string &parsed) {
923  return NumericCast<Target, Source>::convert(from, parsed);
924  }
925 };
926 
936 template<typename T>
937 class IntegerParser: public ValueParser {
938 protected:
941 
943  explicit IntegerParser(const ValueSaver::Ptr &valueSaver): ValueParser(valueSaver) {}
944 public:
947 
954  static Ptr instance() { return Ptr(new IntegerParser); }
955 
962  static Ptr instance(const ValueSaver::Ptr &valueSaver) { return Ptr(new IntegerParser(valueSaver)); }
963 private:
964  virtual ParsedValue operator()(const char *input, const char **rest, const Location &loc) /*override*/ {
965  errno = 0;
966  boost::int64_t big = strtoll(input, (char**)rest, 0);
967  if (*rest==input)
968  throw std::runtime_error("integer expected");
969  while (isspace(**rest)) ++*rest;
970  std::string parsed(input, *rest-input);
971  if (ERANGE==errno)
972  throw std::range_error("integer overflow when parsing \""+parsed+"\"");
973  return ParsedValue(NumericCast<T, boost::int64_t>::convert(big, parsed), loc, parsed, valueSaver());
974  }
975 };
976 
987 template<typename T>
989 protected:
992 
995 public:
998 
1002  static Ptr instance() { return Ptr(new NonNegativeIntegerParser); }
1003 
1007  static Ptr instance(const ValueSaver::Ptr &valueSaver) { return Ptr(new NonNegativeIntegerParser(valueSaver)); }
1008 private:
1009  virtual ParsedValue operator()(const char *input, const char **rest, const Location &loc) /*override*/ {
1010  errno = 0;
1011  while (isspace(*input)) ++input;
1012  if ('+'!=*input && !isdigit(*input))
1013  throw std::runtime_error("unsigned integer expected");
1014  boost::uint64_t big = strtoull(input, (char**)rest, 0);
1015  if (*rest==input)
1016  throw std::runtime_error("unsigned integer expected");
1017  while (isspace(**rest)) ++*rest;
1018  std::string parsed(input, *rest-input);
1019  if (ERANGE==errno)
1020  throw std::range_error("integer overflow when parsing \""+parsed+"\"");
1021  return ParsedValue(NumericCast<T, boost::uint64_t>::convert(big, parsed), loc, parsed, valueSaver());
1022  }
1023 };
1024 
1035 template<typename T>
1037 protected:
1040 
1043 public:
1046 
1050  static Ptr instance() { return Ptr(new PositiveIntegerParser); }
1051 
1055  static Ptr instance(const ValueSaver::Ptr &valueSaver) { return Ptr(new PositiveIntegerParser(valueSaver)); }
1056 private:
1057  virtual ParsedValue operator()(const char *input, const char **rest, const Location &loc) /*override*/ {
1058  errno = 0;
1059  while (isspace(*input)) ++input;
1060  if ('+'!=*input && !isdigit(*input))
1061  throw std::runtime_error("positive integer expected");
1062  boost::uint64_t big = strtoull(input, (char**)rest, 0);
1063  if (*rest==input || big==0)
1064  throw std::runtime_error("positive integer expected");
1065  while (isspace(**rest)) ++*rest;
1066  std::string parsed(input, *rest-input);
1067  if (ERANGE==errno)
1068  throw std::range_error("integer overflow when parsing \""+parsed+"\"");
1069  return ParsedValue(NumericCast<T, boost::uint64_t>::convert(big, parsed), loc, parsed, valueSaver());
1070  }
1071 };
1072 
1082 template<typename T>
1084 protected:
1087 
1090 public:
1093 
1097  static Ptr instance() { return Ptr(new RealNumberParser); }
1098 
1102  static Ptr instance(const ValueSaver::Ptr &valueSaver) { return Ptr(new RealNumberParser(valueSaver)); }
1103 private:
1104  virtual ParsedValue operator()(const char *input, const char **rest, const Location &loc) /*override*/ {
1105  double big = strtod(input, (char**)rest);
1106  if (*rest==input)
1107  throw std::runtime_error("real number expected");
1108  while (isspace(**rest)) ++*rest;
1109  std::string parsed(input, *rest-input);
1110  return ParsedValue(NumericCast<T, double>::convert(big, parsed), loc, parsed, valueSaver());
1111  }
1112 };
1113 
1120 template<typename T>
1122 protected:
1125 
1128 public:
1131 
1135  static Ptr instance() { return Ptr(new BooleanParser); }
1136 
1140  static Ptr instance(const ValueSaver::Ptr &valueSaver) { return Ptr(new BooleanParser(valueSaver)); }
1141 private:
1142  virtual ParsedValue operator()(const char *input, const char **rest, const Location &loc) /*override*/ {
1143  static const char *neg[] = {"false", "off", "no", "0", "f", "n"}; // longest to shortest
1144  static const char *pos[] = {"true", "yes", "on", "1", "t", "y"};
1145  const char *start = input;
1146  while (isspace(*input)) ++input;
1147  for (int negpos=0; negpos<2; ++negpos) {
1148  const char **list = 0==negpos ? neg : pos;
1149  size_t listsz = 0==negpos ? sizeof(neg)/sizeof(*neg) : sizeof(pos)/sizeof(*pos);
1150  for (size_t i=0; i<listsz; ++i) {
1151  if (0==my_strncasecmp(list[i], input, strlen(list[i]))) {
1152  *rest = input + strlen(list[i]);
1153  while (isspace(**rest)) ++*rest;
1154  std::string parsed(start, *rest-start);
1155  return ParsedValue(NumericCast<T, bool>::convert(0!=negpos, parsed), loc, parsed, valueSaver());
1156  }
1157  }
1158  }
1159  throw std::runtime_error("Boolean expected");
1160  }
1161 
1162  // Microsoft doesn't have the POSIX.1-2001 strncasecmp function
1163  int my_strncasecmp(const char *a, const char *b, size_t nchars) {
1164  ASSERT_not_null(a);
1165  ASSERT_not_null(b);
1166  for (size_t i=0; i<nchars; ++i) {
1167  if (!a[i] || !b[i])
1168  return a[i] ? 1 : (b[i] ? -1 : 0);
1169  char achar = (char)tolower(a[i]);
1170  char bchar = (char)tolower(b[i]);
1171  if (achar != bchar)
1172  return achar < bchar ? -1 : 1;
1173  }
1174  return 0;
1175  }
1176 };
1177 
1186 class SAWYER_EXPORT StringSetParser: public ValueParser {
1187 #include <Sawyer/WarningsOff.h>
1188  std::vector<std::string> strings_;
1189 #include <Sawyer/WarningsRestore.h>
1190 protected:
1193 
1195  StringSetParser(const ValueSaver::Ptr &valueSaver): ValueParser(valueSaver) {}
1196 public:
1199 
1203  static Ptr instance() { return Ptr(new StringSetParser); }
1204 
1208  static Ptr instance(const ValueSaver::Ptr &valueSaver) { return Ptr(new StringSetParser(valueSaver)); }
1209 
1212  Ptr with(const std::string &s) { return with(&s, &s+1); }
1213  Ptr with(const std::vector<std::string> sv) { return with(sv.begin(), sv.end()); }
1214  template<class InputIterator>
1215  Ptr with(InputIterator begin, InputIterator end) {
1216  strings_.insert(strings_.end(), begin, end);
1217  return sharedFromThis().dynamicCast<StringSetParser>();
1218  }
1221 private:
1222  virtual ParsedValue operator()(Cursor&) /*override*/;
1223 };
1224 
1232 template<typename T>
1233 class EnumParser: public ValueParser {
1234  StringSetParser::Ptr strParser_;
1236 protected:
1238  EnumParser(): strParser_(StringSetParser::instance()) {}
1239 
1242 public:
1245 
1249  static Ptr instance() { return Ptr(new EnumParser); }
1250 
1254  static Ptr instance(const ValueSaver::Ptr &valueSaver) { return Ptr(new EnumParser(valueSaver)); }
1255 
1257  Ptr with(const std::string &name, T value) {
1258  strParser_->with(name);
1259  members_.insert(name, value);
1260  return sharedFromThis().template dynamicCast<EnumParser>();
1261  }
1262 private:
1263  virtual ParsedValue operator()(Cursor &cursor) /*override*/ {
1264  ParsedValue strVal = strParser_->match(cursor);
1265  return ParsedValue(members_[strVal.string()], strVal.valueLocation(), strVal.string(), valueSaver());
1266  }
1267 };
1268 
1276 class SAWYER_EXPORT ListParser: public ValueParser {
1277  typedef std::pair<ValueParser::Ptr, std::string> ParserSep;
1278 #include <Sawyer/WarningsOff.h>
1279  std::vector<ParserSep> elements_;
1280  size_t minLength_, maxLength_; // limits on the number of values permitted
1281 #include <Sawyer/WarningsRestore.h>
1282 protected:
1284  ListParser(const ValueParser::Ptr &firstElmtType, const std::string &separatorRe)
1285  : minLength_(1), maxLength_((size_t)-1) {
1286  elements_.push_back(ParserSep(firstElmtType, separatorRe));
1287  }
1288 public:
1291 
1293  typedef std::list<ParsedValue> ValueList;
1294 
1302  static Ptr instance(const ValueParser::Ptr &firstElmtType, const std::string &separatorRe="[,;:]\\s*") {
1303  return Ptr(new ListParser(firstElmtType, separatorRe));
1304  }
1305 
1312  Ptr nextMember(const ValueParser::Ptr &elmtType, const std::string &separatorRe="[,;:]\\s*") {
1313  elements_.push_back(ParserSep(elmtType, separatorRe));
1314  return sharedFromThis().dynamicCast<ListParser>();
1315  }
1316 
1323  Ptr limit(size_t minLength, size_t maxLength);
1324  Ptr limit(size_t maxLength) { return limit(std::min(minLength_, maxLength), maxLength); }
1325  Ptr exactly(size_t length) { return limit(length, length); }
1327 private:
1328  virtual ParsedValue operator()(Cursor&) /*override*/;
1329 };
1330 
1386 template<typename T>
1387 typename AnyParser<T>::Ptr anyParser(T &storage) {
1389 }
1390 template<typename T>
1392  return AnyParser<T>::instance();
1393 }
1394 SAWYER_EXPORT AnyParser<std::string>::Ptr anyParser();
1395 
1396 template<typename T>
1397 typename IntegerParser<T>::Ptr integerParser(T &storage) {
1399 }
1400 template<typename T>
1402  return IntegerParser<T>::instance();
1403 }
1404 SAWYER_EXPORT IntegerParser<int>::Ptr integerParser();
1405 
1406 template<typename T>
1409 }
1410 template<typename T>
1413 }
1414 SAWYER_EXPORT NonNegativeIntegerParser<unsigned>::Ptr nonNegativeIntegerParser();
1415 
1416 template<typename T>
1419 }
1420 template<typename T>
1423 }
1424 SAWYER_EXPORT PositiveIntegerParser<unsigned>::Ptr positiveIntegerParser();
1425 
1426 template<typename T>
1429 }
1430 template<typename T>
1433 }
1434 SAWYER_EXPORT RealNumberParser<double>::Ptr realNumberParser();
1435 
1436 template<typename T>
1437 typename BooleanParser<T>::Ptr booleanParser(T &storage) {
1439 }
1440 template<typename T>
1442  return BooleanParser<T>::instance();
1443 }
1444 SAWYER_EXPORT BooleanParser<bool>::Ptr booleanParser();
1445 
1446 template<typename T>
1447 typename EnumParser<T>::Ptr enumParser(T &storage) {
1449 }
1450 template<typename T>
1451 typename EnumParser<T>::Ptr enumParser(std::vector<T> &storage) {
1452  return EnumParser<T>::instance(TypedSaver<std::vector<T> >::instance(storage));
1453 }
1454 template<typename T>
1456  return EnumParser<T>::instance(TypedSaver<Optional<T> >::instance(storage));
1457 }
1458 template<typename T>
1460  return EnumParser<T>::instance();
1461 }
1462 
1463 SAWYER_EXPORT StringSetParser::Ptr stringSetParser(std::string &storage);
1464 SAWYER_EXPORT StringSetParser::Ptr stringSetParser();
1465 
1466 SAWYER_EXPORT ListParser::Ptr listParser(const ValueParser::Ptr&, const std::string &sepRe="[,;:]\\s*");
1470 // Switch argument descriptors
1473 
1488 class SAWYER_EXPORT SwitchArgument {
1489 #include <Sawyer/WarningsOff.h>
1490  std::string name_; // argument name for synopsis
1491  ValueParser::Ptr parser_; // how to match and parse this argument
1492  ParsedValue defaultValue_; // default value if the argument is optional
1493 #include <Sawyer/WarningsRestore.h>
1494 public:
1497  explicit SwitchArgument(const std::string &name, const ValueParser::Ptr &parser = anyParser())
1498  : name_(name), parser_(parser) {}
1499 
1503  SwitchArgument(const std::string &name, const ValueParser::Ptr &parser, const std::string &defaultValueString)
1504  : name_(name), parser_(parser), defaultValue_(parser->matchString(defaultValueString)) {
1505  defaultValue_.valueLocation(NOWHERE);
1506  }
1507 
1509  bool isRequired() const {
1510  return defaultValue_.isEmpty();
1511  }
1512 
1515  bool isOptional() const {
1516  return !isRequired();
1517  }
1518 
1524  const std::string &name() const { return name_; }
1525 
1527  std::string nameAsText() const;
1528 
1530  const ParsedValue& defaultValue() const {
1531  return defaultValue_;
1532  }
1533 
1537  const std::string& defaultValueString() const {
1538  return defaultValue_.string();
1539  }
1540 
1542  const ValueParser::Ptr& parser() const { return parser_; }
1543 };
1544 
1545 
1547 // Switch actions
1549 
1565 class SAWYER_EXPORT SwitchAction: public SharedObject {
1566 public:
1569  virtual ~SwitchAction() {}
1570 
1572  void run(const ParserResult &parserResult) /*final*/ { (*this)(parserResult); }
1573 protected:
1574  virtual void operator()(const ParserResult&) = 0;
1575 };
1576 
1580 class SAWYER_EXPORT ShowVersion: public SwitchAction {
1581 #include <Sawyer/WarningsOff.h>
1582  std::string versionString_;
1583 #include <Sawyer/WarningsRestore.h>
1584 protected:
1586  explicit ShowVersion(const std::string &versionString): versionString_(versionString) {}
1587 public:
1590 
1595  static Ptr instance(const std::string &versionString) { return Ptr(new ShowVersion(versionString)); }
1596 protected:
1597  virtual void operator()(const ParserResult&) /*overload*/;
1598 };
1599 
1602 class SAWYER_EXPORT ShowVersionAndExit: public ShowVersion {
1603  int exitStatus_;
1604 protected:
1606  explicit ShowVersionAndExit(const std::string &versionString, int exitStatus)
1607  : ShowVersion(versionString), exitStatus_(exitStatus) {}
1608 public:
1611 
1616  static Ptr instance(const std::string &versionString, int exitStatus) {
1617  return Ptr(new ShowVersionAndExit(versionString, exitStatus));
1618  }
1619 protected:
1620  virtual void operator()(const ParserResult&) /*overload*/;
1621 };
1622 
1627 class SAWYER_EXPORT ShowHelp: public SwitchAction {
1628 protected:
1631 public:
1634 
1639  static Ptr instance() { return Ptr(new ShowHelp); }
1640 protected:
1641  virtual void operator()(const ParserResult&) /*override*/;
1642 };
1643 
1646 class SAWYER_EXPORT ShowHelpAndExit: public ShowHelp {
1647  int exitStatus_;
1648 protected:
1650  ShowHelpAndExit(int exitStatus): exitStatus_(exitStatus) {}
1651 public:
1654 
1659  static Ptr instance(int exitStatus) { return Ptr(new ShowHelpAndExit(exitStatus)); }
1660 protected:
1661  virtual void operator()(const ParserResult&) /*override*/;
1662 };
1663 
1679 class SAWYER_EXPORT ConfigureDiagnostics: public SwitchAction {
1680 #include <Sawyer/WarningsOff.h>
1681  std::string switchKey_;
1682  Message::Facilities &facilities_;
1683  bool exitOnHelp_;
1684 #include <Sawyer/WarningsRestore.h>
1685 protected:
1687  ConfigureDiagnostics(const std::string &switchKey, Message::Facilities &facilities, bool exitOnHelp)
1688  : switchKey_(switchKey), facilities_(facilities), exitOnHelp_(exitOnHelp) {}
1689 public:
1692 
1697  static Ptr instance(const std::string &switchKey, Message::Facilities &facilities, bool exitOnHelp=true) {
1698  return Ptr(new ConfigureDiagnostics(switchKey, facilities, exitOnHelp));
1699  }
1700 
1706  bool exitOnHelp() const { return exitOnHelp_; }
1707  void exitOnHelp(bool b) { exitOnHelp_=b; }
1709 protected:
1710  virtual void operator()(const ParserResult&) /*override*/;
1711 };
1712 
1732 template<class Functor>
1733 class UserAction: public SwitchAction {
1734  Functor &functor_;
1735 protected:
1737  UserAction(Functor &f): functor_(f) {}
1738 public:
1741 
1746  static Ptr instance(Functor &f) { return Ptr(new UserAction(f)); }
1747 protected:
1748  virtual void operator()(const ParserResult &parserResult) /*override*/ { (functor_)(parserResult); }
1749 };
1750 
1780 SAWYER_EXPORT ShowVersion::Ptr showVersion(const std::string &versionString);
1781 SAWYER_EXPORT ShowVersionAndExit::Ptr showVersionAndExit(const std::string &versionString, int exitStatus);
1782 
1783 SAWYER_EXPORT ShowHelp::Ptr showHelp();
1784 
1785 SAWYER_EXPORT ShowHelpAndExit::Ptr showHelpAndExit(int exitStatus);
1786 
1787 SAWYER_EXPORT ConfigureDiagnostics::Ptr configureDiagnostics(const std::string&, Message::Facilities&, bool exitOnHelp=true);
1788 
1789 template<class Functor>
1790 typename UserAction<Functor>::Ptr userAction(const Functor &functor) {
1791  return UserAction<Functor>::instance(functor);
1792 }
1797 // Switch value agumenters
1800 
1815 class SAWYER_EXPORT ValueAugmenter: public SharedObject {
1816 public:
1819  virtual ~ValueAugmenter() {}
1820 
1825  virtual ParsedValues operator()(const ParsedValues &savedValues, const ParsedValues &newValues) = 0;
1826 };
1827 
1840 template<typename T>
1841 class Sum: public ValueAugmenter {
1842 protected:
1844  Sum() {}
1845 public:
1848 
1853  static Ptr instance() { return Ptr(new Sum<T>); }
1854 
1855  virtual ParsedValues operator()(const ParsedValues &savedValues, const ParsedValues &newValues) /*override*/ {
1856  ASSERT_forbid(newValues.empty());
1857  T sum = 0;
1858  BOOST_FOREACH (const ParsedValue &pv, savedValues)
1859  sum = sum + boost::any_cast<T>(pv.value());
1860  BOOST_FOREACH (const ParsedValue &pv, newValues)
1861  sum = sum + boost::any_cast<T>(pv.value());
1862  ParsedValue pval = newValues.front(); // so we keep the same location information
1863  pval.value(sum);
1864  ParsedValues pvals;
1865  pvals.push_back(pval);
1866  return pvals;
1867  }
1868 };
1869 
1899 template<typename T>
1900 typename Sum<T>::Ptr sum() {
1901  return Sum<T>::instance();
1902 }
1907 // Switch descriptors
1910 
1911 // Used internally to pass around switch properties that are common among parsers, switch groups, and switches.
1912 struct SAWYER_EXPORT ParsingProperties {
1913 #include <Sawyer/WarningsOff.h>
1914  std::vector<std::string> longPrefixes; // Prefixes for long command-line switches
1915  bool inheritLongPrefixes; // True if this also inherits longPrefixes from a higher layer
1916  std::vector<std::string> shortPrefixes;
1917  bool inheritShortPrefixes;
1918  std::vector<std::string> valueSeparators; // What separates a long switch from its value.
1919  bool inheritValueSeparators;
1920  ShowGroupName showGroupName; // How to show group name in switch synopsis
1921 #include <Sawyer/WarningsRestore.h>
1923  : inheritLongPrefixes(true), inheritShortPrefixes(true), inheritValueSeparators(true),
1924  showGroupName(SHOW_GROUP_INHERIT) {}
1925  ParsingProperties inherit(const ParsingProperties &base) const;
1926 };
1927 
1936 };
1937 
1960 class SAWYER_EXPORT Switch {
1961 private:
1962 #include <Sawyer/WarningsOff.h>
1963  std::vector<std::string> longNames_; // Long name of switch, or empty string.
1964  std::string shortNames_; // Optional short names for this switch.
1965  std::string key_; // Unique key, usually the long name or the first short name.
1966  ParsingProperties properties_; // Properties valid at multiple levels of the hierarchy.
1967  std::string synopsis_; // User-defined synopsis or empty string.
1968  std::string documentation_; // Main documentation for the switch.
1969  std::string documentationKey_; // For sorting documentation.
1970  bool hidden_; // Whether to hide documentation.
1971  std::vector<SwitchArgument> arguments_; // Arguments with optional default values.
1972  SwitchAction::Ptr action_; // Optional action to perform during ParserResult::apply.
1973  WhichValue whichValue_; // Which switch values should be saved.
1974  ValueAugmenter::Ptr valueAugmenter_; // Used if <code>whichValue_==SAVE_AUGMENTED</code>.
1975  ParsedValue intrinsicValue_; // Value for switches that have no declared arguments.
1976  bool explosiveLists_; // Whether to expand ListParser::ValueList into separate values.
1977  SwitchSkipping skipping_; // Whether to skip over this switch without saving or acting.
1978 #include <Sawyer/WarningsRestore.h>
1979 
1980 public:
1993  explicit Switch(const std::string &longName, char shortName='\0')
1994  : hidden_(false), whichValue_(SAVE_LAST), intrinsicValue_(ParsedValue(true, NOWHERE, "true", ValueSaver::Ptr())),
1995  explosiveLists_(false), skipping_(SKIP_NEVER) {
1996  init(longName, shortName);
1997  }
1998 
1999  // FIXME[Robb Matzke 2014-03-03]: test that "--prefix=5" works when names are "pre" and "prefix" in that order
2004  Switch& longName(const std::string &name);
2005  const std::string& longName() const { return longNames_.front(); }
2006  const std::vector<std::string>& longNames() const { return longNames_; }
2014  Switch& shortName(char c) { if (c) shortNames_ += std::string(1, c); return *this; }
2015  const std::string& shortNames() const { return shortNames_; }
2020  std::string preferredName() const { return longNames_.empty() ? std::string(1, shortNames_[0]) : longNames_[0]; }
2021 
2030  Switch& key(const std::string &s) { key_ = s; return *this; }
2031  const std::string &key() const { return key_; }
2065  Switch& synopsis(const std::string &s) { synopsis_ = s; return *this; }
2066  std::string synopsis() const;
2104  Switch& doc(const std::string &s) { documentation_ = s; return *this; }
2105  const std::string& doc() const { return documentation_; }
2112  Switch& docKey(const std::string &s) { documentationKey_ = s; return *this; }
2113  const std::string &docKey() const { return documentationKey_; }
2120  Switch& hidden(bool b) { hidden_ = b; return *this; }
2121  bool hidden() const { return hidden_; }
2135  Switch& skipping(SwitchSkipping how) { skipping_ = how; return *this; }
2136  SwitchSkipping skipping() const { return skipping_; }
2150  Switch& resetLongPrefixes(const std::string &s1=STR_NONE, const std::string &s2=STR_NONE,
2151  const std::string &s3=STR_NONE, const std::string &s4=STR_NONE);
2152  Switch& longPrefix(const std::string &s1) { properties_.longPrefixes.push_back(s1); return *this; }
2153  const std::vector<std::string>& longPrefixes() const { return properties_.longPrefixes; }
2167  Switch& resetShortPrefixes(const std::string &s1=STR_NONE, const std::string &s2=STR_NONE,
2168  const std::string &s3=STR_NONE, const std::string &s4=STR_NONE);
2169  Switch& shortPrefix(const std::string &s1) { properties_.shortPrefixes.push_back(s1); return *this; }
2170  const std::vector<std::string>& shortPrefixes() const { return properties_.shortPrefixes; }
2189  Switch& resetValueSeparators(const std::string &s1=STR_NONE, const std::string &s2=STR_NONE,
2190  const std::string &s3=STR_NONE, const std::string &s4=STR_NONE);
2191  Switch& valueSeparator(const std::string &s1) { properties_.valueSeparators.push_back(s1); return *this; }
2192  const std::vector<std::string>& valueSeparators() const { return properties_.valueSeparators; }
2217  Switch& argument(const std::string &name, const ValueParser::Ptr &parser = anyParser());
2218  Switch& argument(const std::string &name, const ValueParser::Ptr &parser, const std::string &defaultValue);
2219  Switch& argument(const SwitchArgument &arg) { arguments_.push_back(arg); return *this; }
2220  const SwitchArgument& argument(size_t idx) const { return arguments_[idx]; }
2221  const std::vector<SwitchArgument>& arguments() const { return arguments_; }
2225  size_t nArguments() const { return arguments_.size(); }
2226 
2229  size_t nRequiredArguments() const;
2230 
2260  template<typename T>
2261  Switch& intrinsicValue(const T &value, T &storage) {
2262  intrinsicValue_ = ParsedValue(value, NOWHERE, boost::lexical_cast<std::string>(value), TypedSaver<T>::instance(storage));
2263  return *this;
2264  }
2265  Switch& intrinsicValue(const char *value, std::string &storage) {
2266  intrinsicValue_ = ParsedValue(std::string(value), NOWHERE, value, TypedSaver<std::string>::instance(storage));
2267  return *this;
2268  }
2269  Switch& intrinsicValue(const std::string &text, const ValueParser::Ptr &p) {
2270  intrinsicValue_ = p->matchString(text);
2271  intrinsicValue_.valueLocation(NOWHERE);
2272  return *this;
2273  }
2274  Switch& intrinsicValue(const std::string &text) {
2275  intrinsicValue_ = anyParser()->matchString(text);
2276  intrinsicValue_.valueLocation(NOWHERE);
2277  return *this;
2278  }
2279  Switch& intrinsicValue(const ParsedValue &value) { intrinsicValue_ = value; return *this; }
2280  ParsedValue intrinsicValue() const { return intrinsicValue_; }
2305  Switch& explosiveLists(bool b) { explosiveLists_ = b; return *this; }
2306  bool explosiveLists() const { return explosiveLists_; }
2330  Switch& action(const SwitchAction::Ptr &f) { action_ = f; return *this; }
2331  const SwitchAction::Ptr& action() const { return action_; }
2359  Switch& whichValue(WhichValue s) { whichValue_ = s; return *this; }
2360  WhichValue whichValue() const { return whichValue_; }
2371  Switch& valueAugmenter(const ValueAugmenter::Ptr &f) { valueAugmenter_ = f; return *this; }
2372  ValueAugmenter::Ptr valueAugmenter() const { return valueAugmenter_; }
2375 public:
2376  // Used internally
2377  const ParsingProperties& properties() const { return properties_; }
2378 
2379 private:
2380  friend class Parser;
2381  friend class ParserResult;
2382 
2383  void init(const std::string &longName, char shortName);
2384 
2386  std::runtime_error noSeparator(const std::string &switchString, const Cursor&, const ParsingProperties&) const;
2387 
2389  std::runtime_error extraTextAfterSwitch(const std::string &switchString, const Location &endOfSwitch, const Cursor&,
2390  const ParsingProperties&, const ParsedValues&) const;
2391 
2393  std::runtime_error extraTextAfterArgument(const Cursor&, const ParsedValue &va) const;
2394 
2396  std::runtime_error notEnoughArguments(const std::string &switchString, const Cursor&, size_t nargs) const;
2397 
2399  std::runtime_error missingArgument(const std::string &switchString, const Cursor &cursor,
2400  const SwitchArgument &sa, const std::string &reason) const;
2401 
2403  std::runtime_error malformedArgument(const std::string &switchString, const Cursor &cursor,
2404  const SwitchArgument &sa, const std::string &reason) const;
2405 
2412  size_t matchLongName(Cursor&/*in,out*/, const ParsingProperties &props,
2413  const std::string &optionalPart, const std::string &requiredPart) const;
2414 
2421  size_t matchShortName(Cursor&/*in,out*/, const ParsingProperties &props, std::string &name) const;
2422 
2424  bool explode(ParsedValues &pvals /*in,out*/) const;
2425 
2430  void matchLongArguments(const std::string &switchString, Cursor &cursor /*in,out*/, const ParsingProperties &props,
2431  ParsedValues &result /*out*/) const;
2432 
2436  void matchShortArguments(const std::string &switchString, Cursor &cursor /*in,out*/, const ParsingProperties &props,
2437  ParsedValues &result /*out*/, bool mayNestle) const;
2438 
2446  size_t matchArguments(const std::string &switchString, const Location &endOfSwitch, Cursor &cursor /*in,out*/,
2447  const ParsingProperties &props, ParsedValues &result /*out*/, bool isLongSwitch) const;
2448 
2450  std::string synopsisForArgument(const SwitchArgument&) const;
2451 
2452  // If the synopsis is empty, create one from an optional switch group and name space separator
2453  std::string synopsis(const ParsingProperties &swProps, const SwitchGroup *sg, const std::string &nameSpaceSeparator) const;
2454 };
2455 
2457 // Switch groups
2459 
2460 
2488 class SAWYER_EXPORT SwitchGroup {
2489 #include <Sawyer/WarningsOff.h>
2490  std::vector<Switch> switches_;
2491  ParsingProperties properties_;
2492  std::string name_; // name optionally prepended to all switches
2493  std::string title_; // title showing in documentation
2494  std::string docKey_; // for sorting
2495  std::string documentation_;
2496  SortOrder switchOrder_;
2497 #include <Sawyer/WarningsRestore.h>
2498 public:
2501 
2508  explicit SwitchGroup(const std::string &title, const std::string &docKey="")
2509  : title_(title), docKey_(docKey), switchOrder_(DOCKEY_ORDER) {}
2510 
2516  const std::string& title() const { return title_; }
2517  SwitchGroup& title(const std::string &title) { title_ = title; return *this; }
2530  const std::string& name() const { return name_; }
2531  SwitchGroup& name(const std::string &name) { name_ = name; return *this; }
2546  const std::string& docKey() const { return docKey_; }
2547  SwitchGroup& docKey(const std::string &key) { docKey_ = key; return *this; }
2562  SwitchGroup& doc(const std::string &s) { documentation_ = s; return *this; }
2563  const std::string& doc() const { return documentation_; }
2572  ShowGroupName showingGroupNames() const { return properties_.showGroupName; }
2573  void showingGroupNames(ShowGroupName x) { properties_.showGroupName = x; }
2578  SwitchGroup& resetLongPrefixes(const std::string &s1=STR_NONE, const std::string &s2=STR_NONE,
2579  const std::string &s3=STR_NONE, const std::string &s4=STR_NONE);
2580  SwitchGroup& longPrefix(const std::string &s1) { properties_.longPrefixes.push_back(s1); return *this; }
2581  const std::vector<std::string>& longPrefixes() const { return properties_.longPrefixes; }
2586  SwitchGroup& resetShortPrefixes(const std::string &s1=STR_NONE, const std::string &s2=STR_NONE,
2587  const std::string &s3=STR_NONE, const std::string &s4=STR_NONE);
2588  SwitchGroup& shortPrefix(const std::string &s1) { properties_.shortPrefixes.push_back(s1); return *this; }
2589  const std::vector<std::string>& shortPrefixes() const { return properties_.shortPrefixes; }
2594  SwitchGroup& resetValueSeparators(const std::string &s1=STR_NONE, const std::string &s2=STR_NONE,
2595  const std::string &s3=STR_NONE, const std::string &s4=STR_NONE);
2596  SwitchGroup& valueSeparator(const std::string &s1) { properties_.valueSeparators.push_back(s1); return *this; }
2597  const std::vector<std::string>& valueSeparators() const { return properties_.valueSeparators; }
2601  size_t nSwitches() const { return switches_.size(); }
2602 
2605  const std::vector<Switch>& switches() const { return switches_; }
2606 
2608  bool nameExists(const std::string &switchName);
2609 
2612  const Switch& getByName(const std::string &switchName);
2613 
2615  bool keyExists(const std::string &switchKey);
2616 
2618  const Switch& getByKey(const std::string &switchKey);
2619 
2621  SwitchGroup& insert(const Switch&);
2622 
2624  SwitchGroup& insert(const SwitchGroup&);
2625 
2627  SwitchGroup& removeByIndex(size_t n);
2628 
2631  SwitchGroup& removeByName(const std::string &switchName);
2632 
2634  SwitchGroup& removeByKey(const std::string &switchKey);
2635 
2647  const SortOrder& switchOrder() const { return switchOrder_; }
2648  SwitchGroup& switchOrder(SortOrder order) { switchOrder_ = order; return *this; }
2651 public:
2652  // Used internally
2653  const ParsingProperties& properties() const { return properties_; }
2654 
2655 private:
2656  friend class Parser;
2657 };
2658 
2661 
2664 
2666 // Parser
2668 
2674 class SAWYER_EXPORT Parser {
2675 #include <Sawyer/WarningsOff.h>
2676  std::vector<SwitchGroup> switchGroups_;
2677  ParsingProperties properties_;
2678  std::string groupNameSeparator_;
2679  std::vector<std::string> terminationSwitches_;
2680  bool shortMayNestle_;
2681  std::vector<std::string> inclusionPrefixes_;
2682  bool skipNonSwitches_;
2683  bool skipUnknownSwitches_;
2684  mutable std::string programName_;
2685  std::string purpose_;
2686  std::string versionString_;
2687  mutable std::string dateString_;
2688  int chapterNumber_;
2689  std::string chapterName_;
2691  StringStringMap sectionDoc_;
2692  StringStringMap sectionOrder_;
2693  Message::SProxy errorStream_;
2694  Optional<std::string> exitMessage_;
2695  SortOrder switchGroupOrder_;
2696  bool reportingAmbiguities_;
2697 #include <Sawyer/WarningsRestore.h>
2698 
2699 public:
2703  : groupNameSeparator_("-"), shortMayNestle_(true), skipNonSwitches_(false), skipUnknownSwitches_(false),
2704  versionString_("alpha"), chapterNumber_(1), chapterName_("User Commands"), switchGroupOrder_(INSERTION_ORDER),
2705  reportingAmbiguities_(true) {
2706  init();
2707  }
2708 
2712  Parser& with(const SwitchGroup &sg) { switchGroups_.push_back(sg); return *this; }
2713  Parser& with(const SwitchGroup &sg, const std::string &docKey) {
2714  switchGroups_.push_back(sg);
2715  switchGroups_.back().docKey(docKey);
2716  return *this;
2717  }
2718  Parser& with(const Switch &sw) { switchGroups_.push_back(SwitchGroup().insert(sw)); return *this; }
2719  Parser& with(Switch sw, const std::string &docKey) {
2720  sw.docKey(docKey);
2721  switchGroups_.push_back(SwitchGroup().insert(sw));
2722  return *this;
2723  }
2727  const std::vector<SwitchGroup>& switchGroups() const {
2728  return switchGroups_;
2729  }
2730 
2742  bool reportingAmbiguities() const { return reportingAmbiguities_; }
2743  Parser& reportingAmbiguities(bool b) { reportingAmbiguities_ = b; return *this; }
2753  const std::string& groupNameSeparator() const { return groupNameSeparator_; }
2754  Parser& groupNameSeparator(const std::string &s) { groupNameSeparator_ = s; return *this; }
2766  ShowGroupName showingGroupNames() const { return properties_.showGroupName; }
2767  Parser& showingGroupNames(ShowGroupName x) { properties_.showGroupName = x; return *this; }
2774  Parser& resetLongPrefixes(const std::string &s1=STR_NONE, const std::string &s2=STR_NONE,
2775  const std::string &s3=STR_NONE, const std::string &s4=STR_NONE);
2776  Parser& longPrefix(const std::string &s1) { properties_.longPrefixes.push_back(s1); return *this; }
2777  const std::vector<std::string>& longPrefixes() const { return properties_.longPrefixes; }
2784  Parser& resetShortPrefixes(const std::string &s1=STR_NONE, const std::string &s2=STR_NONE,
2785  const std::string &s3=STR_NONE, const std::string &s4=STR_NONE);
2786  Parser& shortPrefix(const std::string &s1) { properties_.shortPrefixes.push_back(s1); return *this; }
2787  const std::vector<std::string>& shortPrefixes() const { return properties_.shortPrefixes; }
2796  Parser& resetValueSeparators(const std::string &s1=STR_NONE, const std::string &s2=STR_NONE,
2797  const std::string &s3=STR_NONE, const std::string &s4=STR_NONE);
2798  Parser& valueSeparator(const std::string &s1) { properties_.valueSeparators.push_back(s1); return *this; }
2799  const std::vector<std::string>& valueSeparators() const { return properties_.valueSeparators; }
2806  Parser& resetTerminationSwitches(const std::string &s1=STR_NONE, const std::string &s2=STR_NONE,
2807  const std::string &s3=STR_NONE, const std::string &s4=STR_NONE);
2808  Parser& terminationSwitch(const std::string &s1) { terminationSwitches_.push_back(s1); return *this; }
2809  const std::vector<std::string>& terminationSwitches() const { return terminationSwitches_; }
2819  Parser& shortMayNestle(bool b) { shortMayNestle_ = b; return *this; }
2820  bool shortMayNestle() const { return shortMayNestle_; }
2834  Parser& resetInclusionPrefixes(const std::string &s1=STR_NONE, const std::string &s2=STR_NONE,
2835  const std::string &s3=STR_NONE, const std::string &s4=STR_NONE);
2836  Parser& inclusionPrefix(const std::string &s1) { inclusionPrefixes_.push_back(s1); return *this; }
2837  const std::vector<std::string>& inclusionPrefixes() const { return inclusionPrefixes_; }
2847  Parser& skippingNonSwitches(bool b) { skipNonSwitches_ = b; return *this; }
2848  bool skippingNonSwitches() const { return skipNonSwitches_; }
2857  Parser& skippingUnknownSwitches(bool b) { skipUnknownSwitches_ = b; return *this; }
2858  bool skippingUnknownSwitches() const { return skipUnknownSwitches_; }
2878  Parser& errorStream(const Message::SProxy &stream) { errorStream_ = stream; return *this; }
2879  const Message::SProxy& errorStream() const { return errorStream_; }
2888  Parser& exitMessage(const std::string &s) { exitMessage_ = s; return *this; }
2889  std::string exitMessage() const { return exitMessage_ ? *exitMessage_ : std::string(); }
2895  ParserResult parse(int argc, char *argv[]);
2896 
2898  ParserResult parse(const std::vector<std::string>&);
2899 
2900 #if 0 /* [Robb Matzke 2014-03-04] */
2901 
2903  template<typename Iterator>
2904  ParserResult parse(Iterator begin, Iterator end) {
2905  std::vector<std::string> args(begin, end);
2906  return parse(args);
2907  }
2908 #endif
2909 
2915  static std::vector<std::string> readArgsFromFile(const std::string &filename);
2916 
2921  std::vector<std::string> expandIncludedFiles(const std::vector<std::string> &args);
2922 
2925  DEFAULT_GROUPING = 0,
2926  PROHIBIT_EMPTY_GROUPS = 0x0001,
2927  SPLIT_SINGLE_GROUP = 0x0002
2928  };
2929 
2937  std::vector<std::vector<std::string> >
2938  regroupArgs(const std::vector<std::string> &args,
2940  unsigned flags = 0 /*GroupingFlags*/);
2941 
2945  Parser& programName(const std::string& programName) { programName_ = programName; return *this; }
2946  const std::string& programName() const;
2953  Parser& purpose(const std::string &purpose) { purpose_ = purpose; return *this; }
2954  const std::string& purpose() const { return purpose_; }
2960  Parser& version(const std::string &versionString, const std::string &dateString="");
2961  Parser& version(const std::pair<std::string, std::string> &p) { return version(p.first, p.second); }
2962  std::pair<std::string, std::string> version() const;
2980  Parser& chapter(int chapterNumber, const std::string &chapterName="");
2981  Parser& chapter(const std::pair<int, std::string> &p) { return chapter(p.first, p.second); }
2982  std::pair<int, std::string> chapter() const;
3023  Parser& doc(const std::string &sectionName, const std::string &docKey, const std::string &text);
3024  Parser& doc(const std::string &sectionName, const std::string &text) { return doc(sectionName, sectionName, text); }
3025  std::vector<std::string> docSections() const;
3026  std::string docForSwitches() const;
3027  std::string docForSection(const std::string &sectionName) const;
3034  std::string documentationMarkup() const;
3035 
3039  std::string podDocumentation() const;
3040 
3042  std::string textDocumentation() const;
3043 
3045  void emitDocumentationToPager() const;
3046 
3047  template<class Grammar>
3048  void emitDocumentationToPager() const {
3049  Grammar grammar;
3050  initDocGrammar(grammar);
3051  grammar.title(programName(), boost::lexical_cast<std::string>(chapter().first), chapter().second);
3052  grammar.version(version().first, version().second);
3053  grammar.emit(documentationMarkup());
3054  }
3055 
3061  SortOrder switchGroupOrder() const { return switchGroupOrder_; }
3062  Parser& switchGroupOrder(SortOrder order) { switchGroupOrder_ = order; return *this; }
3068  void insertLongSwitchStrings(Canonical, NamedSwitches &index /*in,out*/) const;
3069 
3073  void insertShortSwitchStrings(NamedSwitches &index /*in,out*/) const;
3074 
3079  void insertSwitchStrings(Canonical, NamedSwitches &index /*in,out*/) const;
3080 
3084  static void printIndex(std::ostream&, const NamedSwitches&, const std::string &linePrefix = "");
3085 
3089  NamedSwitches findAmbiguities() const;
3090 
3094  NamedSwitches findUnresolvableAmbiguities() const;
3095 
3096 public:
3097  // Used internally
3098  const ParsingProperties& properties() const { return properties_; }
3099 
3100 private:
3101  void init();
3102 
3103  // Implementation for the public parse methods.
3104  ParserResult parseInternal(const std::vector<std::string> &programArguments);
3105 
3106  // Parse one switch from the current position in the command line and return the switch descriptor. If the cursor is at
3107  // the end of the command line then return false without updating the cursor or parsed values. If the cursor is at a
3108  // termination switch (e.g., "--") then consume the terminator and return false. If the switch name is valid but the
3109  // arguments cannot be parsed, then throw an error. If the cursor is at what appears to be a switch but no matching switch
3110  // declaration can be found, then throw an error. The cursor will not be modified when an error is thrown.
3111  bool parseOneSwitch(Cursor&, const NamedSwitches &ambiguities, ParserResult&/*out*/);
3112 
3119  const Switch* parseLongSwitch(Cursor&, ParsedValues&, const NamedSwitches &ambiguities, Optional<std::runtime_error>&);
3120 
3129  const Switch* parseShortSwitch(Cursor&, ParsedValues&, const NamedSwitches &ambiguities,
3130  Optional<std::runtime_error>&, bool mayNestle);
3131 
3132  // Returns true if the program argument at the cursor looks like it might be a switch. Apparent switches are any program
3133  // argument that starts with a long or short prefix.
3134  bool apparentSwitch(const Cursor&) const;
3135 
3136  // Returns the best prefix for each switch--the one used for documentation
3137  void preferredSwitchPrefixes(Container::Map<std::string, std::string> &prefixMap /*out*/) const;
3138 
3139  // Construct an error message for an ambiguous switch, switchString, having an optional group name part (including the
3140  // separator), and the required switch name. The switchString must be present in the ambiguities table.
3141  std::string ambiguityErrorMesg(const std::string &longSwitchString, const std::string &optionalPart,
3142  const std::string &longSwitchName, const NamedSwitches &ambiguities);
3143  std::string ambiguityErrorMesg(const std::string &shortSwitchString, const NamedSwitches &ambiguities);
3144 
3145  // Initialize a documentation parser by registering things like @s, @man, etc. The argument is a subclass such as
3146  // Document::PodMarkup.
3147  void initDocGrammar(Document::Markup::Grammar& /*in,out*/) const;
3148 
3149  // FIXME[Robb Matzke 2014-02-21]: Some way to parse command-lines from a config file, or to merge parsed command-lines with
3150  // a yaml config file, etc.
3151 };
3152 
3177 class SAWYER_EXPORT ParserResult {
3178 #include <Sawyer/WarningsOff.h>
3179  Parser parser_;
3180  Cursor cursor_;
3181  ParsedValues values_;
3182 
3183  // Maps a name to indexes into the values_ vector.
3185  NameIndex keyIndex_; // Values per switch key
3186  NameIndex switchIndex_; // Values per switch preferred name
3187 
3188  // List of parsed values organized by their location on the command line. The location is for the switch itself even if
3189  // the values are spread out across subsequent argv members. We do it this way because many of the values are defaults that
3190  // don't actually have an argv location. The integers are indexes into the values_ vector. In other words, this is a
3191  // mapping from switch location to values_ elements for the switch's values.
3193  ArgvIndex argvIndex_;
3194 
3195  // Information about program arguments that the parser skipped over. Indexes into argv_.
3196  typedef std::vector<size_t> SkippedIndex;
3197  SkippedIndex skippedIndex_;
3198 
3199  // Information about terminator switches like "--". Indexes into argv_.
3200  SkippedIndex terminators_;
3201 
3204 #include <Sawyer/WarningsRestore.h>
3205 
3206 private:
3207  friend class Parser;
3208  ParserResult(const Parser &parser, const std::vector<std::string> &argv): parser_(parser), cursor_(argv) {}
3209 
3210 public:
3211  ParserResult() {}
3212 
3215  const ParserResult& apply() const;
3216 
3219  size_t have(const std::string &switchKey) const {
3220  return keyIndex_.getOrDefault(switchKey).size();
3221  }
3222 
3241  const ParsedValue& parsed(const std::string &switchKey, size_t idx) const;
3242  ParsedValues parsed(const std::string &switchKey) const;
3255  std::vector<std::string> skippedArgs() const;
3256 
3263  std::vector<std::string> unreachedArgs() const;
3264 
3279  std::vector<std::string> unparsedArgs(bool includeTerminators=false) const;
3280 
3285  std::vector<std::string> parsedArgs() const;
3286 
3291  const std::vector<std::string>& allArgs() const { return cursor_.strings(); }
3292 
3294  const Parser& parser() const { return parser_; }
3295 
3296 private:
3297  // Insert more parsed values. Values should be inserted one switch's worth at a time (or fewer)
3298  void insertValuesForSwitch(const ParsedValues&, const Parser*, const Switch*);
3299  void insertOneValue(const ParsedValue&, const Switch*, bool save=true);
3300 
3301  // Indicate that we're skipping over a program argument
3302  void skip(const Location&);
3303 
3304  // Add a terminator
3305  void terminator(const Location&);
3306 
3307  Cursor& cursor() { return cursor_; }
3308 };
3309 
3310 } // namespace
3311 } // namespace
3312 
3313 #endif
SharedPointer< RealNumberParser > Ptr
Reference counting pointer for this class.
Definition: CommandLine.h:1092
Switch strings that are not CANONICAL.
Definition: CommandLine.h:186
Switch & intrinsicValue(const ParsedValue &value)
Property: value for a switch that has no declared arguments.
Definition: CommandLine.h:2279
SharedPointer< ValueParser > Ptr
Reference counting pointer for this class.
Definition: CommandLine.h:689
SortOrder switchGroupOrder() const
Property: How to order switch groups in documentation.
Definition: CommandLine.h:3061
Container::Map< const SwitchGroup *, std::set< const Switch * > > GroupedSwitches
Subset of switches grouped by their switch groups.
Definition: CommandLine.h:2660
std::vector< ParsedValue > ParsedValues
A vector of parsed values.
Definition: CommandLine.h:616
Ordered set of values.
Definition: Set.h:46
static Ptr instance(int exitStatus)
Allocating constructor.
Definition: CommandLine.h:1659
Parser & switchGroupOrder(SortOrder order)
Property: How to order switch groups in documentation.
Definition: CommandLine.h:3062
Switch & skipping(SwitchSkipping how)
Property: whether to skip over this switch.
Definition: CommandLine.h:2135
SharedPointer< ShowHelp > Ptr
Reference counting pointer for this class.
Definition: CommandLine.h:1633
Switch & shortName(char c)
Property: switch short name.
Definition: CommandLine.h:2014
ListParser(const ValueParser::Ptr &firstElmtType, const std::string &separatorRe)
Constructor for derived classes.
Definition: CommandLine.h:1284
SwitchGroup & name(const std::string &name)
Property: Group name.
Definition: CommandLine.h:2531
Sum< T >::Ptr sum()
Factory for value agumenter.
Definition: CommandLine.h:1900
const std::vector< std::string > & terminationSwitches() const
Strings that indicate the end of the argument list.
Definition: CommandLine.h:2809
Sum()
Constructor for derived classes.
Definition: CommandLine.h:1844
void cancel()
Cancel the excursion guard.
Definition: CommandLine.h:376
Sums all previous and current values.
Definition: CommandLine.h:1841
Cursor(const std::string &string)
Constructs a cursor for a single string.
Definition: CommandLine.h:264
std::ostream & operator<<(std::ostream &, const Location &)
Print a location.
bool isRequired() const
Returns true if this argument is required.
Definition: CommandLine.h:1509
IntegerParser()
Constructor for derived classes.
Definition: CommandLine.h:940
bool exitOnHelp() const
Property: program exit after help is displayed.
Definition: CommandLine.h:1706
static Ptr instance()
Allocating constructor.
Definition: CommandLine.h:1639
static Ptr instance()
Allocating constructor.
Definition: CommandLine.h:1853
const Message::SProxy & errorStream() const
Specifies a message stream to which errors are sent.
Definition: CommandLine.h:2879
ListParser::Ptr listParser(const ValueParser::Ptr &, const std::string &sepRe="[,;:]\\s*")
Factory for value parsers.
static Ptr instance(const ValueParser::Ptr &firstElmtType, const std::string &separatorRe="[,;:]\\s*")
Allocating constructor.
Definition: CommandLine.h:1302
ShowGroupName
How to show group names in switch synopsis.
Definition: CommandLine.h:191
Cursor()
Constructs a not-very-useful cursor to nothing.
Definition: CommandLine.h:267
SharedPointer< EnumParser > Ptr
Reference counting pointer for this class.
Definition: CommandLine.h:1244
const ValueSaver::Ptr valueSaver() const
Property: functor responsible for saving a parsed value in user storage.
Definition: CommandLine.h:719
bool skippingNonSwitches() const
Whether to skip over non-switch arguments when parsing.
Definition: CommandLine.h:2848
SharedPointer< AnyParser > Ptr
Reference counting pointer for this class.
Definition: CommandLine.h:831
const ValueSaver::Ptr valueSaver() const
How to save a value at a user-supplied location.
Definition: CommandLine.h:599
WhichValue
Describes how to handle switches that occur multiple times.
Definition: CommandLine.h:1929
const std::string & arg() const
Return the entire current program argument regardless of where the cursor is in that argument...
Definition: CommandLine.h:313
static Ptr instance(const ValueSaver::Ptr &valueSaver)
Allocating constructor.
Definition: CommandLine.h:1007
void consumeChars(size_t nchars)
Advance over characters.
SwitchGroup & valueSeparator(const std::string &s1)
Property: strings that separate a long switch from its value.
Definition: CommandLine.h:2596
Functor to configure diagnostics.
Definition: CommandLine.h:1679
bool operator<(const Location &other) const
Less than.
Definition: CommandLine.h:234
Entities appear in the documentation in the same order they are inserted into the container...
Definition: CommandLine.h:171
static Ptr instance(const std::string &versionString, int exitStatus)
Allocating constructor.
Definition: CommandLine.h:1616
const SwitchArgument & argument(size_t idx) const
Property: switch argument.
Definition: CommandLine.h:2220
void run(const ParserResult &parserResult)
Runs the action.
Definition: CommandLine.h:1572
SharedPointer< Sum > Ptr
Reference counting pointer for this class.
Definition: CommandLine.h:1847
T as() const
Convenient any_cast.
Definition: CommandLine.h:567
const std::string & docKey() const
Property: Documentation sort key.
Definition: CommandLine.h:2546
bool explosiveLists() const
Property: whether to convert a list value to individual values.
Definition: CommandLine.h:2306
Switch & shortPrefix(const std::string &s1)
Property: prefixes for short names.
Definition: CommandLine.h:2169
Location switchLocation() const
The command-line location of the switch to which this value belongs.
Definition: CommandLine.h:587
Parser & inclusionPrefix(const std::string &s1)
Strings that indicate that arguments are to be read from a file.
Definition: CommandLine.h:2836
BooleanParser()
Constructor for derived classes.
Definition: CommandLine.h:1124
SwitchGroup(const std::string &title, const std::string &docKey="")
Construct a titled group.
Definition: CommandLine.h:2508
const std::string & doc() const
Property: Detailed description.
Definition: CommandLine.h:2563
bool reportingAmbiguities() const
Property: Whether to report ambiguities.
Definition: CommandLine.h:2742
std::string exitMessage() const
Extra text to print before exit.
Definition: CommandLine.h:2889
static Ptr instance()
Allocating constructor.
Definition: CommandLine.h:1097
RealNumberParser< T >::Ptr realNumberParser(T &storage)
Factory for value parsers.
Definition: CommandLine.h:1427
size_t offset
Character offset within a program argument string.
Definition: CommandLine.h:215
Parser & terminationSwitch(const std::string &s1)
Strings that indicate the end of the argument list.
Definition: CommandLine.h:2808
The result from parsing a command line.
Definition: CommandLine.h:3177
Describes one command-line switch.
Definition: CommandLine.h:1960
Switch & docKey(const std::string &s)
Property: key to control order of documentation.
Definition: CommandLine.h:2112
const std::string & doc() const
Property: detailed description.
Definition: CommandLine.h:2105
Parser & groupNameSeparator(const std::string &s)
Property: String separating group name from switch name.
Definition: CommandLine.h:2754
Collection of facilities.
Definition: Message.h:1688
Location()
Constructs the location of the first character of the first string.
Definition: CommandLine.h:219
Parses any one of a set of strings.
Definition: CommandLine.h:1186
Never show the group name.
Definition: CommandLine.h:194
StringSetParser::Ptr stringSetParser(std::string &storage)
Factory for value parsers.
const std::vector< std::string > & valueSeparators() const
Strings that separate a long switch from its value.
Definition: CommandLine.h:2799
Parser & with(const Switch &sw)
Add switch declarations.
Definition: CommandLine.h:2718
STL namespace.
Holds a value or nothing.
Definition: Optional.h:49
static Ptr instance()
Allocating constructor.
Definition: CommandLine.h:836
const Parser & parser() const
That parser that created this result.
Definition: CommandLine.h:3294
A collection of related switch declarations.
Definition: CommandLine.h:2488
ShowHelp()
Constructor for derived classes.
Definition: CommandLine.h:1630
bool atEnd() const
Returns true when the cursor is after all arguments.
Definition: CommandLine.h:305
Ptr with(const std::vector< std::string > sv)
Adds string members.
Definition: CommandLine.h:1213
const std::vector< std::string > & strings() const
All strings for the cursor.
Definition: CommandLine.h:270
size_t nArguments() const
Total number of arguments.
Definition: CommandLine.h:2225
static Ptr instance(const ValueSaver::Ptr &valueSaver)
Allocating constructor.
Definition: CommandLine.h:1208
Switch & action(const SwitchAction::Ptr &f)
Property: action to occur.
Definition: CommandLine.h:2330
SharedPointer< PositiveIntegerParser > Ptr
Reference counting pointer for this class.
Definition: CommandLine.h:1045
const std::string & defaultValueString() const
The default value string.
Definition: CommandLine.h:1537
Base class for value agumentors.
Definition: CommandLine.h:1815
Parser & valueSeparator(const std::string &s1)
Strings that separate a long switch from its value.
Definition: CommandLine.h:2798
Input stream for command line arguments.
Definition: CommandLine.h:252
ValueParser(const ValueSaver::Ptr &valueSaver)
Constructor for derived classes.
Definition: CommandLine.h:686
PositiveIntegerParser(const ValueSaver::Ptr &valueSaver)
Constructor for derived classes.
Definition: CommandLine.h:1042
SwitchGroup()
Construct an unnamed, untitled group.
Definition: CommandLine.h:2500
Parses a list of values.
Definition: CommandLine.h:1276
std::string preferredName() const
Name by which switch prefers to be known.
Definition: CommandLine.h:2020
const std::string & groupNameSeparator() const
Property: String separating group name from switch name.
Definition: CommandLine.h:2753
SharedPointer< BooleanParser > Ptr
Reference counting pointer for this class.
Definition: CommandLine.h:1130
bool operator!=(const Location &other) const
Inequality.
Definition: CommandLine.h:230
Show name as being optional, like "--[group-]switch".
Definition: CommandLine.h:192
SwitchGroup & longPrefix(const std::string &s1)
Property: prefixes for long names.
Definition: CommandLine.h:2580
Save the first value, or modify previously saved value.
Definition: CommandLine.h:1935
Describes one argument of a command-line switch.
Definition: CommandLine.h:1488
Group inherits value from the parser.
Definition: CommandLine.h:195
ShowHelp::Ptr showHelp()
Factory for switch action.
AnyParser< T >::Ptr anyParser(T &storage)
Factory for value parsers.
Definition: CommandLine.h:1387
Parser & version(const std::pair< std::string, std::string > &p)
Program version.
Definition: CommandLine.h:2961
AnyParser(const ValueSaver::Ptr &valueSaver)
Constructor for derived classes.
Definition: CommandLine.h:828
static Ptr instance(const ValueSaver::Ptr &valueSaver)
Allocating constructor.
Definition: CommandLine.h:962
Ptr limit(size_t maxLength)
Specify limits for the number of values parsed.
Definition: CommandLine.h:1324
Ptr with(const std::string &name, T value)
Adds enum members.
Definition: CommandLine.h:1257
Functor to print the Unix man page.
Definition: CommandLine.h:1627
const std::vector< std::string > & allArgs() const
The original command line.
Definition: CommandLine.h:3291
Canonical
Format of a switch string.
Definition: CommandLine.h:183
Location(size_t idx, size_t offset)
Constructs a location that points to a particular character of a particular string.
Definition: CommandLine.h:222
Switch & doc(const std::string &s)
Property: detailed description.
Definition: CommandLine.h:2104
Name space for the entire library.
Definition: Access.h:11
size_t switchSequence() const
How this value relates to others created by the same switch.
Definition: CommandLine.h:595
ShowVersion::Ptr showVersion(const std::string &versionString)
Factory for switch action.
static Ptr instance()
Allocating constructor.
Definition: CommandLine.h:1050
SwitchGroup & docKey(const std::string &key)
Property: Documentation sort key.
Definition: CommandLine.h:2547
Use only the first occurrence and ignore all previous.
Definition: CommandLine.h:1933
IntegerParser(const ValueSaver::Ptr &valueSaver)
Constructor for derived classes.
Definition: CommandLine.h:943
Parses a positive integer and converts it to numeric type T.
Definition: CommandLine.h:1036
size_t keySequence() const
How this value relates to others with the same key.
Definition: CommandLine.h:591
Process switch normally, but also add to skipped list.
Definition: CommandLine.h:201
const std::string & string() const
String representation.
Definition: CommandLine.h:546
Parser & with(const SwitchGroup &sg)
Add switch declarations.
Definition: CommandLine.h:2712
static Ptr instance(const ValueSaver::Ptr &valueSaver)
Allocating constructor.
Definition: CommandLine.h:1055
EnumParser< T >::Ptr enumParser(T &storage)
Factory for value parsers.
Definition: CommandLine.h:1447
const std::string & shortNames() const
Property: switch short name.
Definition: CommandLine.h:2015
SharedPointer< ValueParser > sharedFromThis()
Create a shared pointer from this.
const ParsedValue & defaultValue() const
The parsed default value.
Definition: CommandLine.h:1530
Ptr nextMember(const ValueParser::Ptr &elmtType, const std::string &separatorRe="[,;:]\\s*")
Specifies element type and separator.
Definition: CommandLine.h:1312
Ptr exactly(size_t length)
Specify limits for the number of values parsed.
Definition: CommandLine.h:1325
Location valueLocation() const
Property: command-line location from whence this value came.
Definition: CommandLine.h:541
std::string rest() const
Return the part of an argument at and beyond the cursor location.
Definition: CommandLine.h:321
SharedPointer< StringSetParser > Ptr
Reference counting pointer for this class.
Definition: CommandLine.h:1198
const std::vector< std::string > & valueSeparators() const
Property: strings that separate a long switch from its value.
Definition: CommandLine.h:2597
void consumeArg()
Advance the cursor to the beginning of the next string.
Definition: CommandLine.h:351
static Ptr instance(const std::string &versionString)
Allocating constructor.
Definition: CommandLine.h:1595
The switch is disabled.
Definition: CommandLine.h:1930
Switch & intrinsicValue(const std::string &text)
Property: value for a switch that has no declared arguments.
Definition: CommandLine.h:2274
const std::vector< Switch > & switches() const
List of all declared switches.
Definition: CommandLine.h:2605
static Ptr instance(const ValueSaver::Ptr &valueSaver)
Allocating constructor.
Definition: CommandLine.h:841
bool atArgEnd() const
True when the cursor is at the end of an argument.
Definition: CommandLine.h:299
Parses an enumerated constant.
Definition: CommandLine.h:1233
Switch(const std::string &longName, char shortName='\0')
Constructs a switch declaration.
Definition: CommandLine.h:1993
const std::string & docKey() const
Property: key to control order of documentation.
Definition: CommandLine.h:2113
Functor to print a version string and exit.
Definition: CommandLine.h:1602
Information about a parsed switch value.
Definition: CommandLine.h:483
Parser & chapter(const std::pair< int, std::string > &p)
Manual chapter.
Definition: CommandLine.h:2981
The parser for a program command line.
Definition: CommandLine.h:2674
SharedPointer< IntegerParser > Ptr
Reference counting pointer for this class.
Definition: CommandLine.h:946
Parses a non-negative integer and converts it to numeric type T.
Definition: CommandLine.h:988
bool operator<=(const Location &other) const
Less than or equal.
Definition: CommandLine.h:238
EnumParser()
Constructor for derived classes.
Definition: CommandLine.h:1238
SharedPointer< NonNegativeIntegerParser > Ptr
Reference counting pointer for this class.
Definition: CommandLine.h:997
SwitchSkipping skipping() const
Property: whether to skip over this switch.
Definition: CommandLine.h:2136
SharedPointer< ShowHelpAndExit > Ptr
Reference counting pointer for this class.
Definition: CommandLine.h:1653
const std::vector< std::string > & longPrefixes() const
Property: prefixes for long names.
Definition: CommandLine.h:2581
Switch & intrinsicValue(const char *value, std::string &storage)
Property: value for a switch that has no declared arguments.
Definition: CommandLine.h:2265
bool isEmpty() const
True if the value is void.
Definition: CommandLine.h:606
ParsedValue & switchInfo(const std::string &key, const Location &loc, const std::string &str)
Update switch information.
Definition: CommandLine.h:514
const std::string & switchString() const
The string for the switch that caused this value to be parsed.
Definition: CommandLine.h:582
Switch & argument(const SwitchArgument &arg)
Property: switch argument.
Definition: CommandLine.h:2219
Switch & intrinsicValue(const std::string &text, const ValueParser::Ptr &p)
Property: value for a switch that has no declared arguments.
Definition: CommandLine.h:2269
const std::vector< std::string > & longPrefixes() const
Property: prefixes for long names.
Definition: CommandLine.h:2153
Parser & shortMayNestle(bool b)
Indicates whether short switches can nestle together.
Definition: CommandLine.h:2819
ParsedValue & switchKey(const std::string &s)
Property: switch key.
Definition: CommandLine.h:571
static Ptr instance(Functor &f)
Allocating constructor.
Definition: CommandLine.h:1746
static Ptr instance(const ValueSaver::Ptr &valueSaver)
Allocating constructor.
Definition: CommandLine.h:1140
BooleanParser(const ValueSaver::Ptr &valueSaver)
Constructor for derived classes.
Definition: CommandLine.h:1127
static Ptr instance(const ValueSaver::Ptr &valueSaver)
Allocating constructor.
Definition: CommandLine.h:1102
Parser & longPrefix(const std::string &s1)
Prefixes to use for long command-line switches.
Definition: CommandLine.h:2776
const SortOrder & switchOrder() const
Property: Order of switches in documentation.
Definition: CommandLine.h:2647
Creates SharedPointer from this.
Ptr with(InputIterator begin, InputIterator end)
Adds string members.
Definition: CommandLine.h:1215
EnumParser(const ValueSaver::Ptr &valueSaver)
Constructor for derived classes.
Definition: CommandLine.h:1241
GroupingFlags
Bit flags for argument grouping.
Definition: CommandLine.h:2924
SharedPointer< ConfigureDiagnostics > Ptr
Reference counting pointer for this class.
Definition: CommandLine.h:1691
Functor to print a version string.
Definition: CommandLine.h:1580
Parses any argument as plain text.
Definition: CommandLine.h:822
const Location & location() const
Property: current position of the cursor.
Definition: CommandLine.h:289
SharedPointer< class UserAction > Ptr
Reference counting pointer for this class.
Definition: CommandLine.h:1740
const std::vector< SwitchArgument > & arguments() const
Property: switch argument.
Definition: CommandLine.h:2221
Switch & whichValue(WhichValue s)
Property: how to handle multiple occurrences.
Definition: CommandLine.h:2359
Parser & purpose(const std::string &purpose)
Program purpose.
Definition: CommandLine.h:2953
Parser & with(const SwitchGroup &sg, const std::string &docKey)
Add switch declarations.
Definition: CommandLine.h:2713
SwitchArgument(const std::string &name, const ValueParser::Ptr &parser=anyParser())
Construct a new required argument.
Definition: CommandLine.h:1497
Treat the switch normally.
Definition: CommandLine.h:200
Switch & hidden(bool b)
Property: whether this switch appears in documentation.
Definition: CommandLine.h:2120
Switch & explosiveLists(bool b)
Property: whether to convert a list value to individual values.
Definition: CommandLine.h:2305
WhichValue whichValue() const
Property: how to handle multiple occurrences.
Definition: CommandLine.h:2360
bool hidden() const
Property: whether this switch appears in documentation.
Definition: CommandLine.h:2121
static Ptr instance()
Allocating constructor.
Definition: CommandLine.h:1135
const std::string & name() const
Argument name.
Definition: CommandLine.h:1524
StringSetParser(const ValueSaver::Ptr &valueSaver)
Constructor for derived classes.
Definition: CommandLine.h:1195
const std::vector< std::string > & shortPrefixes() const
Prefixes to use for short command-line switches.
Definition: CommandLine.h:2787
ShowVersionAndExit(const std::string &versionString, int exitStatus)
Constructor for derived classes.
Definition: CommandLine.h:1606
void value(const boost::any &v)
Property: the parsed value.
Definition: CommandLine.h:535
ExcursionGuard(Cursor &cursor)
Construct a guard for a cursor.
Definition: CommandLine.h:371
SortOrder
The order in which things are sorted in the documentation.
Definition: CommandLine.h:170
ShowVersionAndExit::Ptr showVersionAndExit(const std::string &versionString, int exitStatus)
Factory for switch action.
SharedPointer< U > dynamicCast() const
Dynamic cast.
SwitchGroup & title(const std::string &title)
Property: Title of the switch group.
Definition: CommandLine.h:2517
virtual ParsedValues operator()(const ParsedValues &savedValues, const ParsedValues &newValues)
Called when a switch's value is about to be stored into the ParserResult.
Definition: CommandLine.h:1855
Parses a boolean value and converts it to numeric type T.
Definition: CommandLine.h:1121
const Value & getOrDefault(const Key &key) const
Lookup and return a value or a default.
Definition: Sawyer/Map.h:513
const std::string & key() const
Property: value storage key.
Definition: CommandLine.h:2031
ParsedValue & valueLocation(const Location &loc)
Property: command-line location from whence this value came.
Definition: CommandLine.h:542
Switch & intrinsicValue(const T &value, T &storage)
Property: value for a switch that has no declared arguments.
Definition: CommandLine.h:2261
Parser & shortPrefix(const std::string &s1)
Prefixes to use for short command-line switches.
Definition: CommandLine.h:2786
SharedPointer< SwitchAction > Ptr
Reference counting pointer for this class.
Definition: CommandLine.h:1568
const std::string & longName() const
Property: switch long name.
Definition: CommandLine.h:2005
bool isOptional() const
Returns true if this argument is not required.
Definition: CommandLine.h:1515
AnyParser()
Constructor for derived classes.
Definition: CommandLine.h:825
Parses an integer and converts it to numeric type T.
Definition: CommandLine.h:937
ShowHelpAndExit::Ptr showHelpAndExit(int exitStatus)
Factory for switch action.
Parser & doc(const std::string &sectionName, const std::string &text)
Documentation for a section of the manual.
Definition: CommandLine.h:3024
Parser()
Default constructor.
Definition: CommandLine.h:2702
const std::vector< std::string > & valueSeparators() const
Property: strings that separate a long switch from its value.
Definition: CommandLine.h:2192
Switch & longPrefix(const std::string &s1)
Property: prefixes for long names.
Definition: CommandLine.h:2152
size_t nSwitches() const
Number of switches declared.
Definition: CommandLine.h:2601
Parser & reportingAmbiguities(bool b)
Property: Whether to report ambiguities.
Definition: CommandLine.h:2743
const std::vector< std::string > & inclusionPrefixes() const
Strings that indicate that arguments are to be read from a file.
Definition: CommandLine.h:2837
bool atEnd(const Location &location) const
Returns true when the cursor is after all arguments.
Definition: CommandLine.h:306
Parser & skippingNonSwitches(bool b)
Whether to skip over non-switch arguments when parsing.
Definition: CommandLine.h:2847
const Location NOWHERE
Indicates an invalid location.
ShowVersion(const std::string &versionString)
Constructor for derived classes.
Definition: CommandLine.h:1586
SwitchGroup & shortPrefix(const std::string &s1)
Property: prefixes for short names.
Definition: CommandLine.h:2588
const boost::any & value() const
Property: the parsed value.
Definition: CommandLine.h:534
Wrapper around a user functor.
Definition: CommandLine.h:1733
ShowGroupName showingGroupNames() const
Property: How to show group names in switch documentation.
Definition: CommandLine.h:2766
ShowGroupName showingGroupNames() const
Property: How to show group name in switch synopsis.
Definition: CommandLine.h:2572
Switch & valueSeparator(const std::string &s1)
Property: strings that separate a long switch from its value.
Definition: CommandLine.h:2191
RealNumberParser()
Constructor for derived classes.
Definition: CommandLine.h:1086
Show name as being required, like "--group-switch".
Definition: CommandLine.h:193
Base class for reference counted objects.
Definition: SharedObject.h:22
size_t idx
Index into some vector of program argument strings.
Definition: CommandLine.h:214
Skip switch and its argument(s) without saving any value.
Definition: CommandLine.h:202
const std::vector< std::string > & shortPrefixes() const
Property: prefixes for short names.
Definition: CommandLine.h:2170
void consumeArgs(size_t nargs)
Advance the cursor to the beginning of the next string.
Definition: CommandLine.h:347
const std::vector< std::string > & longPrefixes() const
Prefixes to use for long command-line switches.
Definition: CommandLine.h:2777
Container::Map< std::string, GroupedSwitches > NamedSwitches
Subset of switches indexed by their command-line representation.
Definition: CommandLine.h:2663
The switch cannot occur more than once.
Definition: CommandLine.h:1931
const std::string & name() const
Property: Group name.
Definition: CommandLine.h:2530
Parser & skippingUnknownSwitches(bool b)
Whether to skip over unrecognized switches.
Definition: CommandLine.h:2857
Map & insert(const Key &key, const Value &value)
Insert or update a key/value pair.
Definition: Sawyer/Map.h:530
const std::string & title() const
Property: Title of the switch group.
Definition: CommandLine.h:2516
size_t have(const std::string &switchKey) const
Returns the number of values for the specified key.
Definition: CommandLine.h:3219
SharedPointer< ShowVersion > Ptr
Reference counting pointer for this class.
Definition: CommandLine.h:1589
SwitchArgument(const std::string &name, const ValueParser::Ptr &parser, const std::string &defaultValueString)
Construct a new switch optional argument.
Definition: CommandLine.h:1503
Entities are sorted according to their documentation keys.
Definition: CommandLine.h:176
StringSetParser()
Constructor for derived classes.
Definition: CommandLine.h:1192
const Location & startingLocation() const
Starting location.
Definition: CommandLine.h:380
std::list< ParsedValue > ValueList
Value type for list ParsedValue.
Definition: CommandLine.h:1293
static Ptr instance(const std::string &switchKey, Message::Facilities &facilities, bool exitOnHelp=true)
Allocating constructor.
Definition: CommandLine.h:1697
const std::vector< std::string > & shortPrefixes() const
Property: prefixes for short names.
Definition: CommandLine.h:2589
Use only the last occurrence and ignore all previous.
Definition: CommandLine.h:1932
Save all values as a vector.
Definition: CommandLine.h:1934
Switch & key(const std::string &s)
Property: value storage key.
Definition: CommandLine.h:2030
ParsedValue intrinsicValue() const
Property: value for a switch that has no declared arguments.
Definition: CommandLine.h:2280
Ptr valueSaver(const ValueSaver::Ptr &f)
Property: functor responsible for saving a parsed value in user storage.
Definition: CommandLine.h:718
Cursor(const std::vector< std::string > &strings)
Construct a cursor from an ordered set of strings.
Definition: CommandLine.h:260
Position within a command-line.
Definition: CommandLine.h:213
Ptr with(const std::string &s)
Adds string members.
Definition: CommandLine.h:1212
UserAction< Functor >::Ptr userAction(const Functor &functor)
Factory for switch action.
Definition: CommandLine.h:1790
const std::string & purpose() const
Program purpose.
Definition: CommandLine.h:2954
void exitOnHelp(bool b)
Property: program exit after help is displayed.
Definition: CommandLine.h:1707
static Ptr instance()
Allocating constructor.
Definition: CommandLine.h:1203
Base class parsing a value from input.
Definition: CommandLine.h:677
Switch strings that are qualified with the switch group name or which belong to a group that has no n...
Definition: CommandLine.h:184
const std::vector< std::string > & longNames() const
Property: switch long name.
Definition: CommandLine.h:2006
NonNegativeIntegerParser< T >::Ptr nonNegativeIntegerParser(T &storage)
Factory for value parsers.
Definition: CommandLine.h:1407
Parser & with(Switch sw, const std::string &docKey)
Add switch declarations.
Definition: CommandLine.h:2719
IntegerParser< T >::Ptr integerParser(T &storage)
Factory for value parsers.
Definition: CommandLine.h:1397
boost::uint64_t strtoull(const char *, char **, int)
Portable replacement for strtoull.
SharedPointer< ShowVersionAndExit > Ptr
Reference counting pointer for this class.
Definition: CommandLine.h:1610
UserAction(Functor &f)
Constructor for derived classes.
Definition: CommandLine.h:1737
static Ptr instance()
Allocating constructor.
Definition: CommandLine.h:954
ParsedValue(const boost::any value, const Location &loc, const std::string &str, const ValueSaver::Ptr &saver)
Construct a new value.
Definition: CommandLine.h:509
ValueParser()
Constructor for derived classes.
Definition: CommandLine.h:683
Parser & programName(const std::string &programName)
Program name for documentation.
Definition: CommandLine.h:2945
void showingGroupNames(ShowGroupName x)
Property: How to show group name in switch synopsis.
Definition: CommandLine.h:2573
NonNegativeIntegerParser(const ValueSaver::Ptr &valueSaver)
Constructor for derived classes.
Definition: CommandLine.h:994
bool shortMayNestle() const
Indicates whether short switches can nestle together.
Definition: CommandLine.h:2820
const std::vector< SwitchGroup > & switchGroups() const
List of all switch groups.
Definition: CommandLine.h:2727
boost::int64_t strtoll(const char *, char **, int)
Portable replacement for strtoll.
Parser & errorStream(const Message::SProxy &stream)
Specifies a message stream to which errors are sent.
Definition: CommandLine.h:2878
The union of CANONICAL and NONCANONICAL.
Definition: CommandLine.h:187
SwitchGroup & switchOrder(SortOrder order)
Property: Order of switches in documentation.
Definition: CommandLine.h:2648
bool atArgBegin() const
True when the cursor is at the beginning of an argument.
Definition: CommandLine.h:295
bool operator==(const Location &other) const
Equality.
Definition: CommandLine.h:226
BooleanParser< T >::Ptr booleanParser(T &storage)
Factory for value parsers.
Definition: CommandLine.h:1437
Parses a real number and converts it to numeric type T.
Definition: CommandLine.h:1083
const std::string & switchKey() const
Property: switch key.
Definition: CommandLine.h:572
ShowHelpAndExit(int exitStatus)
Constructor for derived classes.
Definition: CommandLine.h:1650
ConfigureDiagnostics(const std::string &switchKey, Message::Facilities &facilities, bool exitOnHelp)
Constructor for derived classes.
Definition: CommandLine.h:1687
SwitchSkipping
Whether to skip a switch.
Definition: CommandLine.h:199
SharedPointer< ListParser > Ptr
Reference counting pointer for this class.
Definition: CommandLine.h:1290
Switch & synopsis(const std::string &s)
Property: abstract summary of the switch syntax.
Definition: CommandLine.h:2065
Parser & showingGroupNames(ShowGroupName x)
Property: How to show group names in switch documentation.
Definition: CommandLine.h:2767
SharedPointer< ValueAugmenter > Ptr
Reference counting pointer for this class.
Definition: CommandLine.h:1818
static Ptr instance()
Allocating constructor.
Definition: CommandLine.h:1249
static Ptr instance(const ValueSaver::Ptr &valueSaver)
Allocating constructor.
Definition: CommandLine.h:1254
Functor to print the Unix man page and exit.
Definition: CommandLine.h:1646
Container associating values with keys.
Definition: Sawyer/Map.h:64
bool initializeLibrary(size_t vmajor=0, size_t vminor=1, size_t vpatch=0, bool withThreads=0)
Explicitly initialize the library.
ValueAugmenter::Ptr valueAugmenter() const
Property: functor to agument values.
Definition: CommandLine.h:2372
NonNegativeIntegerParser()
Constructor for derived classes.
Definition: CommandLine.h:991
ParsedValue()
Construct a new empty value.
Definition: CommandLine.h:498
RealNumberParser(const ValueSaver::Ptr &valueSaver)
Constructor for derived classes.
Definition: CommandLine.h:1089
Switch & valueAugmenter(const ValueAugmenter::Ptr &f)
Property: functor to agument values.
Definition: CommandLine.h:2371
const ValueParser::Ptr & parser() const
Returns a pointer to the parser.
Definition: CommandLine.h:1542
ConfigureDiagnostics::Ptr configureDiagnostics(const std::string &, Message::Facilities &, bool exitOnHelp=true)
Factory for switch action.
const SwitchAction::Ptr & action() const
Property: action to occur.
Definition: CommandLine.h:2331
Guards a cursor and restores it when the guard is destroyed.
Definition: CommandLine.h:364
static Ptr instance()
Allocating constructor.
Definition: CommandLine.h:1002
PositiveIntegerParser< T >::Ptr positiveIntegerParser(T &storage)
Factory for value parsers.
Definition: CommandLine.h:1417
Base class for switch actions.
Definition: CommandLine.h:1565
PositiveIntegerParser()
Constructor for derived classes.
Definition: CommandLine.h:1039
Parser & exitMessage(const std::string &s)
Extra text to print before exit.
Definition: CommandLine.h:2888
SwitchGroup & doc(const std::string &s)
Property: Detailed description.
Definition: CommandLine.h:2562
std::string substr(const Location &limit, const std::string &separator=" ") const
Returns all characters within limits.
Definition: CommandLine.h:330
bool skippingUnknownSwitches() const
Whether to skip over unrecognized switches.
Definition: CommandLine.h:2858