38         Value() : str(), valid(false) {}
    40         explicit Value(
const std::string &v) : str(v), valid(true) {}
    42         operator const char *()
    50             return (valid && (std::istringstream(str) >> t)) ? t : 
false;
    56             return (valid && (std::istringstream(str) >> t)) ? t : 0;
    59         operator unsigned short()
    62             return (valid && (std::istringstream(str) >> t)) ? t : 0;
    68             return (valid && (std::istringstream(str) >> t)) ? t : 0;
    71         operator unsigned int()
    74             return (valid && (std::istringstream(str) >> t)) ? t : 0;
    80             return (valid && (std::istringstream(str) >> t)) ? t : 0;
    83         operator unsigned long()
    86             return (valid && (std::istringstream(str) >> t)) ? t : 0;
    92         return (valid && (std::istringstream(str) >> t)) ? t : 0;
    98             return (valid && (std::istringstream(str) >> t)) ? t : 0;
   101         operator long double()
   104             return (valid && (std::istringstream(str) >> t)) ? t : 0;
   107       operator std::string()
   114         const std::string str;
   125         const std::string &operator[](
const std::string &d)
 const   127             std::map<std::string, std::string>::const_iterator it = _map.find(d);
   128             static const std::string empty = 
"";
   129             return (it != _map.end()) ? it->second : empty;
   132         std::string &operator[](
const std::string &d)
   137         bool is_set(
const std::string &d)
 const   139             return _map.find(d) != _map.end();
   142         bool is_set_by_user(
const std::string &d)
 const   144             return _user_set.find(d) != _user_set.end();
   147         void is_set_by_user(
const std::string &d, 
bool yes)
   159         Value 
get(
const std::string &d) 
const   161             return (is_set(d)) ? Value((*
this)[d]) : Value();
   164         typedef std::vector<std::string>::iterator iterator;
   165         typedef std::vector<std::string>::const_iterator const_iterator;
   167         std::vector<std::string> &all(
const std::string &d)
   169             return _append_map[d];
   172         const std::vector<std::string> all(
const std::string &d)
 const   174             static const std::vector<std::string> empty;
   175             return (_append_map.find(d) == _append_map.end()) ?
   182         std::map<std::string, std::string> _map;
   183         std::map<std::string, std::vector<std::string> > _append_map;
   184         std::set<std::string> _user_set;
   194                 str_wrap(
const std::string &l, 
const std::string &r) : lwrap(l), rwrap(r) {}
   195                 explicit str_wrap(
const std::string &w) : lwrap(w), rwrap(w) {}
   196                 std::string operator()(
const std::string &s)
   198                     return lwrap + s + rwrap;
   201                 const std::string lwrap, rwrap;
   205         template<
typename InputIterator, 
typename UnaryOperator>
   206         static std::string str_join_trans(
const std::string &sep, InputIterator begin, InputIterator end, UnaryOperator op)
   209             for (InputIterator it = begin; it != end; ++it)
   222         template<
class InputIterator>
   223         static std::string str_join(
const std::string &sep, InputIterator begin, InputIterator end)
   225             return str_join_trans(sep, begin, end, str_wrap(
""));
   229         static std::string &str_replace_helper(std::string &s, 
const std::string &patt, 
const std::string &repl)
   232             const size_t n = patt.length();
   235                 pos = s.find(patt, pos);
   236                 if (pos == std::string::npos)
   240                 s.replace(pos, n, repl);
   248         static std::string str_replace(
const std::string &s, 
const std::string &patt, 
const std::string &repl)
   251             str_replace_helper(tmp, patt, repl);
   256         static std::string str_format(
const std::string &s, 
size_t pre, 
size_t len, 
bool indent_first = 
true)
   258             std::stringstream ss;
   262                 p = std::string(pre, 
' ');
   265             size_t pos = 0, linestart = 0;
   271                 size_t new_pos = s.find_first_of(
" \n\t", pos);
   272                 if (new_pos == std::string::npos)
   277                 if (s[new_pos] == 
'\n')
   285                     p = std::string(pre, 
' ');
   288                 if (wrap or new_pos + pre > linestart + len)
   290                     ss << p << s.substr(linestart, pos - linestart - 1) << std::endl;
   298             ss << p << s.substr(linestart) << std::endl;
   303         static std::string str_inc(
const std::string &s)
   305             std::stringstream ss;
   307             std::istringstream(s) >> i;
   313         static unsigned int cols()
   317             const char *s = getenv(
"COLUMNS");
   320                 std::istringstream(s) >> n;
   327         static std::string basename(
const std::string &s)
   330             size_t i = b.find_last_not_of(
'/');
   331             if (i == std::string::npos)
   341             b.erase(i + 1, b.length() - i - 1);
   342             i = b.find_last_of(
"/");
   343             if (i != std::string::npos)
   352         static OptionParser &add_option_group_helper(OptionParser &parser,
   353                                                      const OptionGroup &group);
   356         static Values &parse_args_helper(OptionParser &parser,
   357                                          const std::vector<std::string> &v);
   360         static std::string format_help_helper(
const OptionParser &parser);
   368         virtual void operator()(
const Option &option,
   369                                 const std::string &opt,
   370                                 const std::string &val,
   371                                 const OptionParser &parser) = 0;
   372         virtual ~Callback() {}
   380         Option() : _action(
"store"), _type(
"string"), _nargs(1), _suppress_help(false), _callback(0) {}
   382         Option &action(
const std::string &a)
   385             if (a == 
"store_const" or
   387                 a == 
"store_false" or
   388                 a == 
"append_const" or
   398         Option &type(
const std::string &t)
   404         Option &dest(
const std::string &d)
   410         Option &set_default(
const std::string &d)
   417         Option &set_default(T t)
   419             std::ostringstream ss;
   425         Option &nargs(
size_t n)
   430                 throw std::invalid_argument(
   431                     "nargs greater than 1 not supported");
   438         Option &set_const(
const std::string &c)
   444         template<
typename InputIterator>
   445         Option &choices(InputIterator begin, InputIterator end)
   447             _choices.assign(begin, end);
   452         Option &help(
const std::string &h)
   458         Option &suppress_help(
const bool suppress=
true)
   460             _suppress_help = suppress;
   464         Option &metavar(
const std::string &m)
   470         Option &callback(Callback &c)
   476         const std::string &action()
 const   481         const std::string &type()
 const   486         const std::string &dest()
 const   491         const std::string &get_default()
 const   501         const std::string &get_const()
 const   506         const std::list<std::string> &choices()
 const   511         const std::string &help()
 const   516         const std::string &metavar()
 const   521         Callback *callback()
 const   528         std::string check_type(
const std::string &opt, 
const std::string &val)
 const   530             std::istringstream ss(val);
   531             std::stringstream err;
   533             if (type() == 
"int" or type() == 
"long")
   538                     err << 
"option" << 
" " << opt << 
": " << 
"invalid integer value" << 
": '" << val << 
"'";
   541             else if (type() == 
"float" or type() == 
"double")
   546                     err << 
"option" << 
" " << opt << 
": " << 
"invalid floating-point value" << 
": '" << val << 
"'";
   549             else if (type() == 
"choice")
   551                 if (find(choices().begin(), choices().end(), val) == choices().end())
   553                     std::list<std::string> tmp = choices();
   554                     std::transform(tmp.begin(), tmp.end(), tmp.begin(), detail::str_wrap(
"'"));
   555                     err << 
"option" << 
" " << opt << 
": " << 
"invalid choice" << 
": '" << val << 
"'"   556                         << 
" (" << 
"choose from" << 
" " << detail::str_join(
", ", tmp.begin(), tmp.end()) << 
")";
   559             else if (type() == 
"complex")
   561                 std::complex<double> t;
   564                     err << 
"option" << 
" " << opt << 
": " << 
"invalid complex value" << 
": '" << val << 
"'";
   571         std::string format_option_help(
const unsigned int indent=2)
 const   573             std::string mvar_short;
   574             std::string mvar_long;
   578                 std::string mvar = metavar();
   582                     std::transform(mvar.begin(), mvar.end(), mvar.begin(), ::toupper);
   584                 mvar_short = 
" " + mvar;
   585                 mvar_long = 
"=" + mvar;
   588             std::stringstream ss;
   589             ss << std::string(indent, 
' ');
   591             if (not _short_opts.empty())
   593                 ss << detail::str_join_trans(
", ", _short_opts.begin(), _short_opts.end(), detail::str_wrap(
"-", mvar_short));
   594                 if (not _long_opts.empty())
   599             if (not _long_opts.empty())
   601                 ss << detail::str_join_trans(
", ", _long_opts.begin(), _long_opts.end(), detail::str_wrap(
"--", mvar_long));
   607         std::string format_help(
const unsigned int indent=2)
 const   609             std::stringstream ss;
   610             std::string h = format_option_help(indent);
   611             unsigned int width = detail::cols();
   612             unsigned int opt_width = std::min(width * 3 / 10, 36u);
   613             bool indent_first = 
false;
   617             if (h.length() >= (opt_width - 1))
   624                 ss << std::string(opt_width - h.length(), 
' ');
   631                 std::string help_str = (get_default() != 
"") ? detail::str_replace(help(), 
"%default", get_default()) : help();
   632                 ss << detail::str_format(help_str, opt_width, width, indent_first);
   638         std::set<std::string> _short_opts;
   639         std::set<std::string> _long_opts;
   644         std::string _default;
   647         std::list<std::string> _choices;
   650         std::string _metavar;
   653         friend class OptionParser;
   655         friend OptionParser &detail::add_option_group_helper(
   656             OptionParser &parser,
   657             const OptionGroup &group);
   666             _usage(
"%prog [options]"),
   667             _add_help_option(true),
   668             _add_version_option(true),
   669             _interspersed_args(true)
   674         OptionParser &usage(
const std::string &u)
   680         OptionParser &version(
const std::string &v)
   686         OptionParser &description(
const std::string &d)
   692         OptionParser &add_help_option(
bool h)
   694             _add_help_option = h;
   698         OptionParser &add_version_option(
bool v)
   700             _add_version_option = v;
   704         OptionParser &prog(
const std::string &p)
   710         OptionParser &epilog(
const std::string &e)
   716         OptionParser &set_defaults(
const std::string &dest, 
const std::string &val)
   718             _defaults[dest] = val;
   723         OptionParser &set_defaults(
const std::string &dest, T t)
   725             std::ostringstream ss;
   727             _defaults[dest] = ss.str();
   731         OptionParser &enable_interspersed_args()
   733             _interspersed_args = 
true;
   737         OptionParser &disable_interspersed_args()
   739             _interspersed_args = 
false;
   743         OptionParser &add_option_group(
const OptionGroup &group)
   745             return detail::add_option_group_helper(*
this, group);
   748         const std::string &usage()
 const   753         const std::string &version()
 const   758         const std::string &description()
 const   763         bool add_help_option()
 const   765             return _add_help_option;
   768         bool add_version_option()
 const   770             return _add_version_option;
   773         const std::string &prog()
 const   778         const std::string &epilog()
 const   783         bool interspersed_args()
 const   785             return _interspersed_args;
   788         Option &add_option(
const std::vector<std::string> &opt)
   790             _opts.resize(_opts.size() + 1);
   791             Option &option = _opts.back();
   792             std::string dest_fallback;
   793             for (std::vector<std::string>::const_iterator it = opt.begin(); it != opt.end(); ++it)
   795                 if (it->substr(0, 2) == 
"--")
   797                     const std::string s = it->substr(2);
   798                     if (option.dest() == 
"")
   799                         option.dest(detail::str_replace(s, 
"-", 
"_"));
   800                     option._long_opts.insert(s);
   801                     _optmap_l[s] = &option;
   805                     const std::string s = it->substr(1, 1);
   806                     if (dest_fallback == 
"")
   808                     option._short_opts.insert(s);
   809                     _optmap_s[s] = &option;
   812             if (option.dest() == 
"")
   814                 option.dest(dest_fallback);
   819         Option &add_option(
const std::string &opt)
   821             const std::string tmp[1] = {opt};
   822             return add_option(std::vector<std::string>(&tmp[0], &tmp[1]));
   825         Option &add_option(
const std::string &opt1, 
const std::string &opt2)
   827             const std::string tmp[2] = {opt1, opt2};
   828             return add_option(std::vector<std::string>(&tmp[0], &tmp[2]));
   831         Option &add_option(
const std::string &opt1, 
const std::string &opt2, 
const std::string &opt3)
   833             const std::string tmp[3] = {opt1, opt2, opt3};
   834             return add_option(std::vector<std::string>(&tmp[0], &tmp[3]));
   837         Values &parse_args(
int argc, 
char const *
const *argv)
   841                 prog(detail::basename(argv[0]));
   843             return parse_args(&argv[1], &argv[argc]);
   846         Values &parse_args(
const std::vector<std::string> &arguments)
   848             return detail::parse_args_helper(*
this, arguments);
   851         template<
typename InputIterator>
   852         Values &parse_args(InputIterator begin, InputIterator end)
   854             return parse_args(std::vector<std::string>(begin, end));
   857         const std::vector<std::string> &args()
 const   862         std::string format_help()
 const   864             return detail::format_help_helper(*
this);
   867         std::string format_option_help(
unsigned int indent=2)
 const   869             std::stringstream ss;
   876             for (std::list<Option>::const_iterator it = _opts.begin(); it != _opts.end(); ++it)
   878                 if (not it->_suppress_help)
   880                     ss << it->format_help(indent);
   887         void print_help()
 const   889             std::cout << format_help();
   892         void set_usage(
const std::string &u)
   894             std::string lower = u;
   895             std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
   896             if (lower.compare(0, 7, 
"usage: ") == 0)
   898                 _usage = u.substr(7);
   906         std::string get_usage()
 const   908             return format_usage(detail::str_replace(usage(), 
"%prog", prog()));
   911         void print_usage(std::ostream &out)
 const   913             std::string u = get_usage();
   916                 out << u << std::endl;
   920         void print_usage()
 const   922             print_usage(std::cout);
   925         std::string get_version()
 const   927             return detail::str_replace(_version, 
"%prog", prog());
   930         void print_version(std::ostream &out)
 const   932             out << get_version() << std::endl;
   935         void print_version()
 const   937             print_version(std::cout);
   940         void error(
const std::string &msg)
 const   942             std::cout << prog() << 
": " << 
"error" << 
": " << msg << std::endl;
   954         const Option &lookup_short_opt(
const std::string &opt)
 const   956             std::map<std::string, Option const *>::const_iterator it = _optmap_s.find(opt);
   957             if (it == _optmap_s.end())
   959                 error(
"no such option" + std::string(
": -") + opt);
   964         const Option &lookup_long_opt(
const std::string &opt)
 const   966             std::vector<std::string> matching;
   967             for (std::map<std::string, Option const *>::const_iterator it = _optmap_l.begin(); it != _optmap_l.end(); ++it)
   969                 if (it->first.compare(0, opt.length(), opt) == 0)
   971                     matching.push_back(it->first);
   974             if (matching.size() > 1)
   976                 std::string x = detail::str_join(
", ", matching.begin(), matching.end());
   977                 error(
"ambiguous option" + std::string(
": --") + opt + 
" (" + x + 
"?)");
   979             if (matching.size() == 0)
   981                 error(
"no such option" + std::string(
": --") + opt);
   984             return *_optmap_l.find(matching.front())->second;
   987         void handle_short_opt(
const std::string &opt, 
const std::string &arg)
   989             _remaining.pop_front();
   992             const Option &option = lookup_short_opt(opt);
   993             if (option._nargs == 1)
   995                 value = arg.substr(2);
   998                     if (_remaining.empty())
  1000                         error(
"-" + opt + 
" " + 
"option requires an argument");
  1002                     value = _remaining.front();
  1003                     _remaining.pop_front();
  1008                 if (arg.length() > 2)
  1010                     _remaining.push_front(std::string(
"-") + arg.substr(2));
  1014             process_opt(option, std::string(
"-") + opt, value);
  1017         void handle_long_opt(
const std::string &optstr)
  1019             _remaining.pop_front();
  1023             size_t delim = optstr.find(
"=");
  1024             if (delim != std::string::npos)
  1026                 opt = optstr.substr(0, delim);
  1027                 value = optstr.substr(delim + 1);
  1034             const Option &option = lookup_long_opt(opt);
  1035             if (option._nargs == 1 and delim == std::string::npos)
  1037                 if (not _remaining.empty())
  1039                     value = _remaining.front();
  1040                     _remaining.pop_front();
  1044             if (option._nargs == 1 and value == 
"")
  1046                 error(
"--" + opt + 
" " + 
"option requires an argument");
  1049             process_opt(option, std::string(
"--") + opt, value);
  1052         void process_opt(
const Option &o, 
const std::string &opt, 
const std::string &value)
  1054             if (o.action() == 
"store")
  1056                 std::string err = o.check_type(opt, value);
  1061                 _values[o.dest()] = value;
  1062                 _values.is_set_by_user(o.dest(), 
true);
  1064             else if (o.action() == 
"store_const")
  1066                 _values[o.dest()] = o.get_const();
  1067                 _values.is_set_by_user(o.dest(), 
true);
  1069             else if (o.action() == 
"store_true")
  1071                 _values[o.dest()] = 
"1";
  1072                 _values.is_set_by_user(o.dest(), 
true);
  1074             else if (o.action() == 
"store_false")
  1076                 _values[o.dest()] = 
"0";
  1077                 _values.is_set_by_user(o.dest(), 
true);
  1079             else if (o.action() == 
"append")
  1081                 std::string err = o.check_type(opt, value);
  1086                 _values[o.dest()] = value;
  1087                 _values.all(o.dest()).push_back(value);
  1088                 _values.is_set_by_user(o.dest(), 
true);
  1090             else if (o.action() == 
"append_const")
  1092                 _values[o.dest()] = o.get_const();
  1093                 _values.all(o.dest()).push_back(o.get_const());
  1094                 _values.is_set_by_user(o.dest(), 
true);
  1096             else if (o.action() == 
"count")
  1098                 _values[o.dest()] = detail::str_inc(_values[o.dest()]);
  1099                 _values.is_set_by_user(o.dest(), 
true);
  1101             else if (o.action() == 
"help")
  1106             else if (o.action() == 
"version")
  1111             else if (o.action() == 
"callback" and o.callback())
  1113                 (*o.callback())(o, opt, value, *
this);
  1117         std::string format_usage(
const std::string &u)
 const  1119             std::stringstream ss;
  1120             ss << 
"Usage" << 
": " << u << std::endl;
  1125         std::string _version;
  1126         std::string _description;
  1127         bool _add_help_option;
  1128         bool _add_version_option;
  1130         std::string _epilog;
  1131         bool _interspersed_args;
  1135         std::list<Option> _opts;
  1136         std::map<std::string, Option const *> _optmap_s;
  1137         std::map<std::string, Option const *> _optmap_l;
  1138         std::map<std::string, std::string> _defaults;
  1139         std::vector<OptionGroup const *> _groups;
  1141         std::list<std::string> _remaining;
  1142         std::vector<std::string> _leftover;
  1144         friend OptionParser &detail::add_option_group_helper(
  1145             OptionParser &parser,
  1146             const OptionGroup &group);
  1148         friend Values &detail::parse_args_helper(
  1149             OptionParser &parser,
  1150             const std::vector<std::string> &v);
  1152         friend std::string detail::format_help_helper(
const OptionParser &parser);
  1156     class OptionGroup : 
public OptionParser
  1160         OptionGroup(
const std::string &t, 
const std::string &d=
"") :
  1161             _title(t), _group_description(d) {}
  1163         OptionGroup &title(
const std::string &t)
  1169         OptionGroup &group_description(
const std::string &d)
  1171             _group_description = d;
  1175         const std::string &title()
 const  1180         const std::string &group_description()
 const  1182             return _group_description;
  1188         std::string _group_description;
  1194         static OptionParser &add_option_group_helper(OptionParser &parser,
  1195                                                      const OptionGroup &group)
  1197             for (std::list<Option>::const_iterator oit = group._opts.begin(); oit != group._opts.end(); ++oit)
  1199                 const Option &option = *oit;
  1200                 for (std::set<std::string>::const_iterator it = option._short_opts.begin();
  1201                      it != option._short_opts.end();
  1204                     parser._optmap_s[*it] = &option;
  1207                 for (std::set<std::string>::const_iterator it = option._long_opts.begin();
  1208                      it != option._long_opts.end();
  1211                     parser._optmap_l[*it] = &option;
  1214             parser._groups.push_back(&group);
  1219         static Values &parse_args_helper(OptionParser &parser,
  1220                                          const std::vector<std::string> &v)
  1222             parser._remaining.assign(v.begin(), v.end());
  1224             if (parser.add_version_option() and parser.version() != 
"")
  1226                 parser.add_option(
"--version").action(
"version").help(
"show program's version number and exit");
  1227                 parser._opts.splice(parser._opts.begin(), parser._opts, --(parser._opts.end()));
  1229             if (parser.add_help_option())
  1231                 parser.add_option(
"-h", 
"--help").action(
"help").help(
"show this help message and exit");
  1232                 parser._opts.splice(parser._opts.begin(), parser._opts, --(parser._opts.end()));
  1235             while (not parser._remaining.empty())
  1237                 const std::string arg = parser._remaining.front();
  1241                     parser._remaining.pop_front();
  1245                 if (arg.substr(0, 2) == 
"--")
  1247                     parser.handle_long_opt(arg.substr(2));
  1249                 else if (arg.substr(0, 1) == 
"-" and arg.length() > 1)
  1251                     parser.handle_short_opt(arg.substr(1, 1), arg);
  1255                     parser._remaining.pop_front();
  1256                     parser._leftover.push_back(arg);
  1257                     if (not parser.interspersed_args())
  1263             while (not parser._remaining.empty())
  1265                 const std::string arg = parser._remaining.front();
  1266                 parser._remaining.pop_front();
  1267                 parser._leftover.push_back(arg);
  1270             for (std::map<std::string, std::string>::const_iterator it = parser._defaults.begin(); it != parser._defaults.end(); ++it)
  1272                 if (not parser._values.is_set(it->first))
  1274                     parser._values[it->first] = it->second;
  1278             for (std::list<Option>::const_iterator it = parser._opts.begin(); it != parser._opts.end(); ++it)
  1280                 if (it->get_default() != 
"" and not parser._values.is_set(it->dest()))
  1282                     parser._values[it->dest()] = it->get_default();
  1286             for (std::vector<OptionGroup const *>::iterator group_it = parser._groups.begin(); group_it != parser._groups.end(); ++group_it)
  1288                 for (std::map<std::string, std::string>::const_iterator it = (*group_it)->_defaults.begin(); it != (*group_it)->_defaults.end(); ++it)
  1290                     if (not parser._values.is_set(it->first))
  1292                         parser._values[it->first] = it->second;;
  1296                 for (std::list<Option>::const_iterator it = (*group_it)->_opts.begin(); it != (*group_it)->_opts.end(); ++it)
  1298                     if (it->get_default() != 
"" and not parser._values.is_set(it->dest()))
  1300                         parser._values[it->dest()] = it->get_default();
  1305             return parser._values;
  1309         static std::string format_help_helper(
const OptionParser &parser)
  1311             std::stringstream ss;
  1313             ss << parser.get_usage() << std::endl;
  1315             if (parser.description() != 
"")
  1317                 ss << detail::str_format(parser.description(), 0, detail::cols()) << std::endl;
  1320             ss << 
"Options" << 
":" << std::endl;
  1321             ss << parser.format_option_help();
  1323             for (std::vector<OptionGroup const *>::const_iterator it = parser._groups.begin();
  1324                  it != parser._groups.end();
  1327                 const OptionGroup &group = **it;
  1328                 ss << std::endl << 
"  " << group.title() << 
":" << std::endl;
  1329                 if (group.group_description() != 
"")
  1330                     ss << detail::str_format(group.group_description(), 4, detail::cols()) << std::endl;
  1331                 ss << group.format_option_help(4);
  1334             if (parser.epilog() != 
"")
  1336                 ss << std::endl << detail::str_format(parser.epilog(), 0, detail::cols());
  1344 typedef optparse::Values Config;