/* (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 .
*/
#include "getoptpp.h"
#include
#include
#include
#include
using namespace std;
using namespace vlofgren;
#ifndef DOXYGEN_SHOULD_SKIP_THIS
/*
*
* This is one way of adding new parameter types,
* inheriting existing types and adding new validation.
*
* In this case, StringParameter (which is a typedef of PODParameter gets
* a new validator that only accepts strings with only letters.
*
*/
class AlphabeticParameter : public StringParameter {
public:
AlphabeticParameter(char shortName, const char* longName, const char* description) :
StringParameter(shortName, longName, description) {}
virtual ~AlphabeticParameter() {}
void receiveSwitch() throw(Parameter::ParameterRejected) {
throw Parameter::ParameterRejected();
}
/* isalpha may be a macro */
static bool isNotAlpha(char c) { return !isalpha(c); }
virtual string validate(const string& arg) throw(Parameter::ParameterRejected) {
int nonalpha = count_if(arg.begin(), arg.end(), isNotAlpha);
if(nonalpha) throw Parameter::ParameterRejected("I only want numbers");
else return arg;
}
};
/*
*
* The other way is to specialize the PODParameter class
*
*/
enum RockPaperScissor { ROCK, PAPER, SCISSOR } ;
namespace vlofgren {
// needs to live in the vlofgren namespace for whatever reason
template<> enum RockPaperScissor
PODParameter::validate(const string &s) throw(Parameter::ParameterRejected)
{
if(s == "rock")
return ROCK;
else if(s == "paper")
return PAPER;
else if(s == "scissor")
return SCISSOR;
else {
throw ParameterRejected("Invalid argument");
}
}
}
typedef PODParameter RockPaperScissorParameter;
/*
*
* Dummy program
*
*/
int main(int argc, const char* argv[]) {
// Create a parser
OptionsParser optp("An example program (that also runs some tests)");
ParameterSet& ps = optp.getParameters();
/* An alternative option is to simply extend the options parser and set all this up
* in the constructor.
*/
ps.add('f', "foo", "Enable the foo system (no argument)");
ps.add('b', "bar", "Enable the bar system (string argument)");
ps.add >('z', "baz", "Enable the baz system (floating point argument");
PODParameter& i = ps.add >('i', "foobar", "Enable the foobar system (integer argument");
i.setDefault(15);
ps.add('a', "alpha", "Custom parameter that requires a string of letters");
ps.add('r', "rps", "Takes the values rock, paper or scissor");
ps.add('h', "help", "Display help screen");
// Register the parameters with the parser
try {
// Parse argv
optp.parse(argc, argv);
// Test for the help flag
if(ps['h'].isSet()) {
optp.usage();
return EXIT_SUCCESS;
}
// Print out what values the parameters were given
cout << "The following parameters were set:" << endl;
cout << "foo: " << (ps['f'].isSet() ? "true" : "false") << endl;
cout << "bar: \"" << ps['b'].get() << "\""<< endl;
cout << "baz: ";
if(ps['z'].isSet()) {
cout << ps['z'].get() << endl;
} else {
cout << "not set" << endl;
}
/* You can also save the return value from ParserSet::add() if
* you feel the operator[].get() stuff is a bit much */
cout << "foobar: ";
if(i.isSet()) {
cout << i.get() << endl;
} else {
cout << "not set" << endl;
}
cout << "alpha: ";
if(ps["alpha"].isSet()) {
cout << ps["alpha"].get() << endl;
} else {
cout << "not set" << endl;
}
cout << "rps: ";
if(ps["rps"].isSet()) {
cout << ps["rps"].get() << endl;
} else {
cout << "not set" << endl;
}
} catch(Parameter::ParameterRejected &p){
// This will happen if the user has fed some malformed parameter to the program
cerr << p.what() << endl;
optp.usage();
return EXIT_FAILURE;
} catch(runtime_error &e) {
// This will happen if you try to access a parameter that hasn't been set
cerr << e.what() << endl;
return EXIT_FAILURE;
}
// List what non-parameter options were given (typically files)
cout << "The following file arguments were given:" << endl;
vector files = optp.getFiles();
for(vector::iterator i = files.begin(); i != files.end(); i++) {
cout << "\t" << *i << endl;
}
return EXIT_SUCCESS;
}
#endif