2004-08-28 16:13:42 +00:00
|
|
|
/** @file
|
|
|
|
|
|
|
|
$Id$
|
|
|
|
|
|
|
|
$Date$
|
|
|
|
$Author$
|
|
|
|
|
|
|
|
@copy © Marc Wäckerlin
|
|
|
|
@license LGPL, see file <a href="license.html">COPYING</a>
|
|
|
|
|
|
|
|
$Log$
|
2005-02-08 12:31:36 +00:00
|
|
|
Revision 1.3 2005/02/08 12:31:36 marc
|
|
|
|
new static methods to simplify access to options
|
|
|
|
|
2004-11-25 18:26:04 +00:00
|
|
|
Revision 1.2 2004/11/25 18:26:04 marc
|
|
|
|
Constness corrected
|
|
|
|
|
2004-08-28 16:13:42 +00:00
|
|
|
Revision 1.1 2004/08/28 16:13:42 marc
|
|
|
|
mrw-c++-0.92 (mrw)
|
2011-12-10 11:39:09 +00:00
|
|
|
- new file: version.cxx
|
2004-08-28 16:13:42 +00:00
|
|
|
- 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
|
|
|
|
|
|
|
|
*/
|
2011-12-10 11:39:09 +00:00
|
|
|
#include <mrw/arg.hxx>
|
|
|
|
#include <mrw/exception.hxx>
|
2004-08-28 16:13:42 +00:00
|
|
|
|
|
|
|
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());
|
|
|
|
}
|
|
|
|
|
2005-02-08 12:31:36 +00:00
|
|
|
Args& Args::operator<<(const mrw::Opt& opt) throw(std::exception) {
|
2004-08-28 16:13:42 +00:00
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
|
2004-11-25 18:26:04 +00:00
|
|
|
Args& Args::operator<<(char const*const*const argv) throw(std::exception) {
|
2004-08-28 16:13:42 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2004-11-25 18:26:04 +00:00
|
|
|
Args& Args::parse(int argc, char const*const*const argv)
|
2004-08-28 16:13:42 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|