/** @file $Id$ $Date$ $Author$ @copy © Marc Wäckerlin @license LGPL, see file <a href="license.html">COPYING</a> $Log$ Revision 1.3 2005/02/08 12:31:36 marc new static methods to simplify access to options Revision 1.2 2004/11/25 18:26:04 marc Constness corrected Revision 1.1 2004/08/28 16:13:42 marc mrw-c++-0.92 (mrw) - new file: version.cpp - new file header for all sources - work around warning in mrw::auto<T> - possibility to compile without log4cxx - work around bugs in demangle.h and libiberty.h - corrections in documentation - added simple tracing mechanism - more warnings - small corrections in Auto<>::Free and a new test for it - possibility to compile without stack trace */ #include <mrw/arg.hpp> #include <mrw/exception.hpp> namespace mrw { const std::string& Param::Value::toString() const throw(std::exception) { throw mrw::bad_cast(); } int Param::Value::toInt() const throw(std::exception) { throw mrw::bad_cast(); } bool Param::Value::toBool() const throw(std::exception) { throw mrw::bad_cast(); } void Param::IntValue::operator=(const std::string& s) throw(std::exception) { if (!(std::stringstream(s)>>_i)) throw mrw::bad_cast(); } const mrw::SmartPointer<Param::Value>& Param::operator[](unsigned int i) const throw(std::exception) { if (i<_params.size()) return _params[i]; throw mrw::out_of_range (((std::stringstream&) (std::stringstream()<<"check failed: " <<i<<'<'<<_params.size())).str()); } mrw::SmartPointer<Param::Value>& Param::setable(unsigned int i) throw(std::exception) { if (i<_params.size()) return _params[i]; throw mrw::out_of_range (((std::stringstream&) (std::stringstream()<<"check failed: " <<i<<'<'<<_params.size())).str()); } Args& Args::operator<<(const mrw::Opt& opt) throw(std::exception) { // twice the same, but other sort order Options::iterator it(_options.insert(_options.end(), opt)); if (!_shortopts.insert(ShortOpts::value_type(opt._shortname, it)).second) throw mrw::invalid_argument(std::string(1, opt._shortname)); if (!_longopts.insert(LongOpts::value_type(opt._longname, it)).second) throw mrw::invalid_argument(opt._longname); return *this; } Args& Args::operator<<(char const*const*const argv) throw(std::exception) { if (_argc<0) throw mrw::invalid_argument("argc was not set when shifting argv"); return parse(_argc, argv); } const Opt& Args::find(char c) const throw(std::exception) { ShortOpts::const_iterator it(_shortopts.find(c)); if (it==_shortopts.end()) throw mrw::out_of_range(std::string(1, c)); return *it->second; } const Opt& Args::find(const std::string& s) const throw(std::exception) { LongOpts::const_iterator it(_longopts.find(s)); if (it==_longopts.end()) throw mrw::out_of_range(s); return *it->second; } Args& Args::parse(int argc, char const*const*const argv) throw(std::exception) { if (argc>0) _filename = argv[0]; for (int i(1); i<argc; ++i) { std::string arg(argv[i]); if (arg.find("--")==0 && arg!="--") { // long arguments LongOpts::iterator it(_longopts.find(arg)); if (it!=_longopts.end() || i+it->second->args().size()>=argc) throw mrw::invalid_argument(arg); it->second->set(); for (int j(0), l(it->second->args().size()); j<l; ++j) { *(it->second->args().setable(j)) = argv[++i]; } } else if (arg.find("-")==0) { // short arguments // first check all, then set all for (int j(1), l(arg.size()); j<l; ++j) { ShortOpts::iterator it(_shortopts.find(arg[j])); if (it==_shortopts.end() || it->second->args().size()>0 && (j+1!=l || i+it->second->args().size()>=argc)) throw mrw::invalid_argument(arg); } for (int j(1), l(arg.size()); j<l; ++j) { ShortOpts::iterator it(_shortopts.find(arg[j])); it->second->set(); if (j+1==l && it->second->args().size()>0) { for (int k(0); k < it->second->args().size(); ++k) { *(it->second->args().setable(k)) = argv[++i]; } } } } else { if (arg!="--") _otherargs.push_back(arg); while (++i<argc) _otherargs.push_back(argv[i]); } } if (_help && find(_help)) help(); return *this; } }