/* (C) 2011 Viktor Lofgren * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifdef GETOPTPP_H /* This file contains template voodoo, and due to the unique way GCC handles * templates, it needs to be included as a header (and it -is-). Do not attempt to * compile this file directly! */ template T &ParameterSet::add(char shortName, const char* longName, const char* description) { T* p = new T(shortName, longName, description); parameters.push_back(p); return *p; } template T Parameter::get() const{ const PODParameter *ppt = dynamic_cast*>(this); if(ppt) { return ppt->getValue(); } throw new std::runtime_error("Type conversion not possible"); } /* * * Class CommonParameter implementation * * */ template CommonParameter::~CommonParameter() {} template CommonParameter::CommonParameter(char shortOption, const char *longOption, const char* description) : Parameter(shortOption, longOption, description) {} template bool CommonParameter::isSet() const{ return SwitchingBehavior::isSet(); } template std::string CommonParameter::usageLine() const { std::stringstream strstr; strstr.width(10); strstr << std::left<< std::string("-") + shortOption(); strstr.width(20); strstr << std::left << "--" + longOption(); return strstr.str(); } template bool CommonParameter::receive(ParserState& state) throw(Parameter::ParameterRejected) { const std::string arg = state.get(); try { if(arg.at(0) != '-') return false; if(arg.at(1) == '-') { /* Long form parameter */ try { unsigned int eq = arg.find_first_of("="); if(eq == std::string::npos) { if(arg.substr(2) != longOption()) return false; this->receiveSwitch(); } else { if(arg.substr(2, eq-2) != longOption()) return false; this->receiveArgument(arg.substr(eq+1)); } return true; } catch(Parameter::ExpectedArgument &ea) { throw ExpectedArgument("--" + longOption() + ": expected an argument"); } catch(Parameter::UnexpectedArgument &ua) { throw UnexpectedArgument("--" + longOption() + ": did not expect an argument"); } catch(Switchable::SwitchingError &e) { throw ParameterRejected("--" + longOption() + ": parameter already set"); } catch(Parameter::ParameterRejected &pr) { std::string what = pr.what(); if(what.length()) throw Parameter::ParameterRejected("--" + longOption() + ": " + what); throw Parameter::ParameterRejected("--" + longOption() + " (unspecified error)"); } } try { if(arg.at(1) == shortOption()) { /* Matched argument on the form -f or -fsomething */ if(arg.length() == 2) { /* -f */ this->receiveSwitch(); return true; } else { /* -fsomething */ this->receiveArgument(arg.substr(2)); return true; } } } catch(Parameter::ExpectedArgument &ea) { throw ExpectedArgument(std::string("-") + shortOption() + ": expected an argument"); } catch(Parameter::UnexpectedArgument &ua) { throw UnexpectedArgument(std::string("-") + shortOption() + ": did not expect an argument"); } catch(Switchable::SwitchingError &e) { throw ParameterRejected(std::string("-") + shortOption() + ": parameter already set"); } } catch(std::out_of_range& o) { return false; } return false; } /* * PODParameter stuff * */ template PODParameter::PODParameter(char shortOption, const char *longOption, const char* description) : CommonParameter(shortOption, longOption, description) {} template PODParameter::~PODParameter() {} template PODParameter::operator T() const { return getValue(); } template void PODParameter::setDefault(T value) { PresettableUniquelySwitchable::preset(); this->value = value; } template T PODParameter::getValue() const { if(!isSet()) { throw runtime_error( std::string("Attempting to retreive the argument of parameter") + longOption() + " but it hasn't been set!"); } return value; } template std::string PODParameter::usageLine() const { std::stringstream strstr; strstr.width(10); strstr << std::left<< std::string("-") + shortOption() +"arg"; strstr.width(20); strstr << std::left << "--" + longOption() + "=arg"; return strstr.str(); } template void PODParameter::receiveSwitch() throw (Parameter::ParameterRejected) { throw Parameter::ExpectedArgument(); } template void PODParameter::receiveArgument(const std::string &argument) throw(Parameter::ParameterRejected) { set(); value = this->validate(argument); } #endif