/* (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