mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2023-10-10 13:36:59 +02:00
Special command line option classes added
This commit is contained in:
parent
29f6e41923
commit
cc3baec022
334
dependencies/build/getoptPlusPlus/getoptpp.cc
vendored
334
dependencies/build/getoptPlusPlus/getoptpp.cc
vendored
@ -1,18 +1,18 @@
|
|||||||
/* (C) 2011 Viktor Lofgren
|
/* (C) 2011 Viktor Lofgren
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* any later version.
|
* any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "getoptpp.h"
|
#include "getoptpp.h"
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
@ -23,173 +23,205 @@ using namespace std;
|
|||||||
namespace vlofgren {
|
namespace vlofgren {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* Class OptionsParser
|
* Class OptionsParser
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
OptionsParser::OptionsParser(const char* programDesc) : fprogramDesc(programDesc) {}
|
OptionsParser::OptionsParser(const char* programDesc) : fprogramDesc(programDesc) {}
|
||||||
OptionsParser::~OptionsParser() {}
|
OptionsParser::~OptionsParser() {}
|
||||||
|
|
||||||
ParameterSet& OptionsParser::getParameters() {
|
ParameterSet& OptionsParser::getParameters() {
|
||||||
return parameters;
|
return parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptionsParser::parse(int argc, const char* argv[]) throw(runtime_error)
|
void OptionsParser::parse(int argc, const char* argv[]) throw(runtime_error)
|
||||||
{
|
{
|
||||||
argv0 = argv[0];
|
argv0 = argv[0];
|
||||||
|
|
||||||
if(argc == 1) return;
|
if(argc == 1) return;
|
||||||
|
|
||||||
vector<string> v(&argv[1], &argv[argc]);
|
vector<string> v(&argv[1], &argv[argc]);
|
||||||
|
|
||||||
ParserState state(*this, v);
|
ParserState state(*this, v);
|
||||||
|
|
||||||
for(; !state.end(); state.advance()) {
|
for(; !state.end(); state.advance()) {
|
||||||
|
|
||||||
std::list<Parameter*>::iterator i;
|
std::list<Parameter*>::iterator i;
|
||||||
|
|
||||||
for(i = parameters.parameters.begin();
|
for(i = parameters.parameters.begin();
|
||||||
i != parameters.parameters.end(); i++)
|
i != parameters.parameters.end(); i++)
|
||||||
{
|
{
|
||||||
if((*i)->receive(state)) break;
|
int n = 0;
|
||||||
}
|
try
|
||||||
|
{
|
||||||
|
n = (*i)->receive(state);
|
||||||
|
}
|
||||||
|
catch(Parameter::ExpectedArgument &)
|
||||||
|
{
|
||||||
|
throw Parameter::ExpectedArgument(state.get() + ": expected an argument");
|
||||||
|
}
|
||||||
|
catch(Parameter::UnexpectedArgument &)
|
||||||
|
{
|
||||||
|
throw Parameter::UnexpectedArgument(state.get() + ": did not expect an argument");
|
||||||
|
}
|
||||||
|
catch(Switchable::SwitchingError &)
|
||||||
|
{
|
||||||
|
throw Parameter::ParameterRejected(state.get() + ": parameter already set");
|
||||||
|
}
|
||||||
|
catch(Parameter::ParameterRejected & pr) {
|
||||||
|
std::string what = pr.what();
|
||||||
|
if(what.length())
|
||||||
|
{
|
||||||
|
throw Parameter::ParameterRejected(state.get() + ": " + what);
|
||||||
|
}
|
||||||
|
throw Parameter::ParameterRejected(state.get() + " (unspecified error)");
|
||||||
|
}
|
||||||
|
|
||||||
if(i == parameters.parameters.end()) {
|
for (int j = 1; j < n; ++j)
|
||||||
std::string file = state.get();
|
{
|
||||||
if(file == "--") {
|
state.advance();
|
||||||
state.advance();
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if(file.at(0) == '-')
|
|
||||||
throw Parameter::ParameterRejected(string("Bad parameter: ") + file);
|
|
||||||
else files.push_back(state.get());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!state.end()) for(; !state.end(); state.advance()) {
|
if(n != 0)
|
||||||
files.push_back(state.get());
|
{
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(i == parameters.parameters.end()) {
|
||||||
|
std::string file = state.get();
|
||||||
|
if(file == "--") {
|
||||||
|
state.advance();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if(file.at(0) == '-')
|
||||||
|
throw Parameter::ParameterRejected(string("Bad parameter: ") + file);
|
||||||
|
else files.push_back(state.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!state.end()) for(; !state.end(); state.advance()) {
|
||||||
|
files.push_back(state.get());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptionsParser::usage() const {
|
void OptionsParser::usage() const {
|
||||||
cerr << "Usage: " << programName() << " arguments" << endl;
|
cerr << fprogramDesc << endl;
|
||||||
|
cerr << "Usage: " << programName() << " [OPTIONS]" << endl << endl;
|
||||||
|
|
||||||
cerr << fprogramDesc << endl << endl;
|
cerr << "Parameters: " << endl;
|
||||||
|
|
||||||
cerr << "Parameters: " << endl;
|
std::list<Parameter*>::const_iterator i;
|
||||||
|
for(i = parameters.parameters.begin();
|
||||||
|
i != parameters.parameters.end(); i++)
|
||||||
|
{
|
||||||
|
cerr.width(30);
|
||||||
|
cerr << std::left << " " + (*i)->usageLine();
|
||||||
|
|
||||||
std::list<Parameter*>::const_iterator i;
|
cerr.width(40);
|
||||||
for(i = parameters.parameters.begin();
|
cerr << std::left << (*i)->description() << endl;
|
||||||
i != parameters.parameters.end(); i++)
|
|
||||||
{
|
|
||||||
cerr.width(30);
|
|
||||||
cerr << std::left << " " + (*i)->usageLine();
|
|
||||||
|
|
||||||
cerr.width(40);
|
|
||||||
cerr << std::left << (*i)->description() << endl;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const vector<string>& OptionsParser::getFiles() const {
|
const vector<string>& OptionsParser::getFiles() const {
|
||||||
return files;
|
return files;
|
||||||
}
|
}
|
||||||
|
|
||||||
const string& OptionsParser::programName() const {
|
const string& OptionsParser::programName() const {
|
||||||
return argv0;
|
return argv0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parameter set
|
* Parameter set
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ParameterSet::ParameterSet(const ParameterSet& ps) {
|
ParameterSet::ParameterSet(const ParameterSet& ps) {
|
||||||
throw new runtime_error("ParameterSet not copyable");
|
throw new runtime_error("ParameterSet not copyable");
|
||||||
}
|
}
|
||||||
|
|
||||||
ParameterSet::~ParameterSet() {
|
ParameterSet::~ParameterSet() {
|
||||||
for(std::list<Parameter*>::iterator i = parameters.begin();
|
for(std::list<Parameter*>::iterator i = parameters.begin();
|
||||||
i != parameters.end(); i++)
|
i != parameters.end(); i++)
|
||||||
{
|
{
|
||||||
delete *i;
|
delete *i;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The typical use case for command line arguments makes linear searching completely
|
/* The typical use case for command line arguments makes linear searching completely
|
||||||
* acceptable here.
|
* acceptable here.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Parameter& ParameterSet::operator[](char c) const {
|
Parameter& ParameterSet::operator[](char c) const {
|
||||||
for(std::list<Parameter*>::const_iterator i = parameters.begin(); i!= parameters.end(); i++) {
|
for(std::list<Parameter*>::const_iterator i = parameters.begin(); i!= parameters.end(); i++) {
|
||||||
if((*i)->shortOption() == c) return *(*i);
|
if((*i)->shortOption() == c) return *(*i);
|
||||||
}
|
}
|
||||||
throw out_of_range("ParameterSet["+c+string("]"));
|
throw out_of_range("ParameterSet["+c+string("]"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Parameter& ParameterSet::operator[](const string& param) const {
|
Parameter& ParameterSet::operator[](const string& param) const {
|
||||||
for(std::list<Parameter*>::const_iterator i = parameters.begin(); i!= parameters.end(); i++) {
|
for(std::list<Parameter*>::const_iterator i = parameters.begin(); i!= parameters.end(); i++) {
|
||||||
if((*i)->longOption() == param) return *(*i);
|
if((*i)->longOption() == param) return *(*i);
|
||||||
}
|
}
|
||||||
throw out_of_range("ParameterSet["+param+"]");
|
throw out_of_range("ParameterSet["+param+"]");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* Class ParserState
|
* Class ParserState
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
ParserState::ParserState(OptionsParser &opts, vector<string>& args) :
|
ParserState::ParserState(OptionsParser &opts, vector<string>& args) :
|
||||||
opts(opts), arguments(args), iterator(args.begin())
|
opts(opts), arguments(args), iterator(args.begin())
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const string ParserState::peek() const {
|
const string ParserState::peek() const {
|
||||||
vector<string>::const_iterator next = iterator+1;
|
vector<string>::const_iterator next = iterator+1;
|
||||||
if(next != arguments.end()) return *next;
|
if(next != arguments.end()) return *next;
|
||||||
else return "";
|
else return "";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const string ParserState::get() const {
|
const string ParserState::get() const {
|
||||||
if(!end()) return *iterator;
|
if(!end()) return *iterator;
|
||||||
else return "";
|
else return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParserState::advance() {
|
void ParserState::advance() {
|
||||||
iterator++;
|
iterator++;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ParserState::end() const {
|
bool ParserState::end() const {
|
||||||
return iterator == arguments.end();
|
return iterator == arguments.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* Class Parameter
|
* Class Parameter
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Parameter::Parameter(char shortOption, const std::string & longOption, const std::string & description) :
|
Parameter::Parameter(char shortOption, const std::string & longOption, const std::string & description) :
|
||||||
fshortOption(shortOption), flongOption(longOption), fdescription(description)
|
fshortOption(shortOption), flongOption(longOption), fdescription(description)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -202,11 +234,11 @@ bool Parameter::hasShortOption() const { return fshortOption != 0x0; }
|
|||||||
char Parameter::shortOption() const { assert(hasShortOption()); return fshortOption; }
|
char Parameter::shortOption() const { assert(hasShortOption()); return fshortOption; }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* Class Switchable
|
* Class Switchable
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool Switchable::isSet() const { return fset; }
|
bool Switchable::isSet() const { return fset; }
|
||||||
Switchable::~Switchable() {};
|
Switchable::~Switchable() {};
|
||||||
@ -217,108 +249,88 @@ MultiSwitchable::~MultiSwitchable() {}
|
|||||||
|
|
||||||
|
|
||||||
void UniquelySwitchable::set() throw (Switchable::SwitchingError) {
|
void UniquelySwitchable::set() throw (Switchable::SwitchingError) {
|
||||||
if(UniquelySwitchable::isSet()) throw Switchable::SwitchingError();
|
if(UniquelySwitchable::isSet()) throw Switchable::SwitchingError();
|
||||||
fset = true;
|
fset = true;
|
||||||
}
|
}
|
||||||
UniquelySwitchable::~UniquelySwitchable() {}
|
UniquelySwitchable::~UniquelySwitchable() {}
|
||||||
|
|
||||||
|
|
||||||
PresettableUniquelySwitchable::~PresettableUniquelySwitchable() {}
|
PresettableUniquelySwitchable::~PresettableUniquelySwitchable() {}
|
||||||
bool PresettableUniquelySwitchable::isSet() const {
|
bool PresettableUniquelySwitchable::isSet() const {
|
||||||
return UniquelySwitchable::isSet() || fpreset.isSet();
|
return UniquelySwitchable::isSet() || fpreset.isSet();
|
||||||
}
|
}
|
||||||
void PresettableUniquelySwitchable::set() throw (Switchable::SwitchingError)
|
void PresettableUniquelySwitchable::set() throw (Switchable::SwitchingError)
|
||||||
{
|
{
|
||||||
UniquelySwitchable::set();
|
UniquelySwitchable::set();
|
||||||
}
|
}
|
||||||
void PresettableUniquelySwitchable::preset() {
|
void PresettableUniquelySwitchable::preset() {
|
||||||
fpreset.set();
|
fpreset.set();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* Class SwitchParameter
|
* PODParameter specializations
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
SwitchParameter::SwitchParameter(char shortOption, const char *longOption,
|
|
||||||
const char* description) : CommonParameter<MultiSwitchable>(shortOption, longOption, description) {}
|
|
||||||
SwitchParameter::~SwitchParameter() {}
|
|
||||||
|
|
||||||
void SwitchParameter::receiveSwitch() throw(Parameter::ParameterRejected) {
|
|
||||||
set();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SwitchParameter::receiveArgument(const string &arg) throw(Parameter::ParameterRejected) {
|
|
||||||
throw UnexpectedArgument();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
* PODParameter specializations
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
PODParameter<string>::PODParameter(char shortOption, const char *longOption,
|
PODParameter<string>::PODParameter(char shortOption, const char *longOption,
|
||||||
const char* description) : CommonParameter<PresettableUniquelySwitchable>(shortOption, longOption, description) {
|
const char* description) : CommonParameter<PresettableUniquelySwitchable>(shortOption, longOption, description) {
|
||||||
preset();
|
preset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
int PODParameter<int>::validate(const string &s) throw(Parameter::ParameterRejected)
|
int PODParameter<int>::validate(const string &s) throw(Parameter::ParameterRejected)
|
||||||
{
|
{
|
||||||
// This is sadly necessary for strto*-functions to operate on
|
// This is sadly necessary for strto*-functions to operate on
|
||||||
// const char*. The function doesn't write to the memory, though,
|
// const char*. The function doesn't write to the memory, though,
|
||||||
// so it's quite safe.
|
// so it's quite safe.
|
||||||
|
|
||||||
char* cstr = const_cast<char*>(s.c_str());
|
char* cstr = const_cast<char*>(s.c_str());
|
||||||
if(*cstr == '\0') throw ParameterRejected("No argument given");
|
if(*cstr == '\0') throw ParameterRejected("No argument given");
|
||||||
|
|
||||||
long l = strtol(cstr, &cstr, 10);
|
long l = strtol(cstr, &cstr, 10);
|
||||||
if(*cstr != '\0') throw ParameterRejected("Expected int");
|
if(*cstr != '\0') throw ParameterRejected("Expected int");
|
||||||
|
|
||||||
if(l > INT_MAX || l < INT_MIN) {
|
if(l > INT_MAX || l < INT_MIN) {
|
||||||
throw ParameterRejected("Expected int");
|
throw ParameterRejected("Expected int");
|
||||||
}
|
}
|
||||||
|
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
long PODParameter<long>::validate(const string &s) throw(Parameter::ParameterRejected)
|
long PODParameter<long>::validate(const string &s) throw(Parameter::ParameterRejected)
|
||||||
{
|
{
|
||||||
char* cstr = const_cast<char*>(s.c_str());
|
char* cstr = const_cast<char*>(s.c_str());
|
||||||
if(*cstr == '\0') throw ParameterRejected("No argument given");
|
if(*cstr == '\0') throw ParameterRejected("No argument given");
|
||||||
|
|
||||||
long l = strtol(cstr, &cstr, 10);
|
long l = strtol(cstr, &cstr, 10);
|
||||||
if(*cstr != '\0') throw ParameterRejected("Expected long");
|
if(*cstr != '\0') throw ParameterRejected("Expected long");
|
||||||
|
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
double PODParameter<double>::validate(const string &s) throw(Parameter::ParameterRejected)
|
double PODParameter<double>::validate(const string &s) throw(Parameter::ParameterRejected)
|
||||||
{
|
{
|
||||||
char* cstr = const_cast<char*>(s.c_str());
|
char* cstr = const_cast<char*>(s.c_str());
|
||||||
if(*cstr == '\0') throw ParameterRejected("No argument given");
|
if(*cstr == '\0') throw ParameterRejected("No argument given");
|
||||||
|
|
||||||
double d = strtod(cstr, &cstr);
|
double d = strtod(cstr, &cstr);
|
||||||
if(*cstr != '\0') throw ParameterRejected("Expected double");
|
if(*cstr != '\0') throw ParameterRejected("Expected double");
|
||||||
|
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
string PODParameter<string>::validate(const string &s) throw(Parameter::ParameterRejected)
|
string PODParameter<string>::validate(const string &s) throw(Parameter::ParameterRejected)
|
||||||
{
|
{
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
33
dependencies/include/getoptPlusPlus/getoptpp.h
vendored
33
dependencies/include/getoptPlusPlus/getoptpp.h
vendored
@ -203,7 +203,7 @@ protected:
|
|||||||
* iterator that technically allows for more complex grammar than what is
|
* iterator that technically allows for more complex grammar than what is
|
||||||
* presently used.
|
* presently used.
|
||||||
*/
|
*/
|
||||||
virtual bool receive(ParserState& state) throw(ParameterRejected) = 0;
|
virtual int receive(ParserState& state) throw(ParameterRejected) = 0;
|
||||||
|
|
||||||
friend class OptionsParser;
|
friend class OptionsParser;
|
||||||
|
|
||||||
@ -250,20 +250,9 @@ protected:
|
|||||||
* receiveSwitch() or receiveArgument() accordingly.
|
* receiveSwitch() or receiveArgument() accordingly.
|
||||||
*
|
*
|
||||||
* @param state The current argument being parsed.
|
* @param state The current argument being parsed.
|
||||||
|
* @return The number of parameters taken from the input
|
||||||
*/
|
*/
|
||||||
virtual bool receive(ParserState& state) throw(ParameterRejected);
|
virtual int receive(ParserState& state) throw(ParameterRejected) = 0;
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when a parameter does not have an argument, e.g.
|
|
||||||
* either -f or --foo
|
|
||||||
*/
|
|
||||||
virtual void receiveSwitch() throw (ParameterRejected) = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when a parameter does have an argument, .e.g
|
|
||||||
* -fbar or --foo=bar
|
|
||||||
*/
|
|
||||||
virtual void receiveArgument(const std::string& argument) throw (ParameterRejected) = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** This class (used as a mixin) defines how a parameter
|
/** This class (used as a mixin) defines how a parameter
|
||||||
@ -344,15 +333,15 @@ private:
|
|||||||
/* Parameter that does not take an argument, and throws an exception
|
/* Parameter that does not take an argument, and throws an exception
|
||||||
* if an argument is given */
|
* if an argument is given */
|
||||||
|
|
||||||
class SwitchParameter : public CommonParameter<MultiSwitchable> {
|
template<typename SwitchingBehavior=MultiSwitchable>
|
||||||
|
class SwitchParameter : public CommonParameter<SwitchingBehavior> {
|
||||||
public:
|
public:
|
||||||
SwitchParameter(char shortOption, const char *longOption,
|
SwitchParameter(char shortOption, const char *longOption,
|
||||||
const char* description);
|
const char* description);
|
||||||
virtual ~SwitchParameter();
|
virtual ~SwitchParameter();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void receiveSwitch() throw (Parameter::ParameterRejected);
|
virtual int receive(ParserState& state) throw(Parameter::ParameterRejected);
|
||||||
virtual void receiveArgument(const std::string& argument) throw (Parameter::ParameterRejected);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Plain-Old-Data parameter. Performs input validation.
|
/** Plain-Old-Data parameter. Performs input validation.
|
||||||
@ -363,8 +352,8 @@ protected:
|
|||||||
* Specifically, you need to specialize validate().
|
* Specifically, you need to specialize validate().
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template<typename T>
|
template<typename T, typename SwitchingBehavior=PresettableUniquelySwitchable>
|
||||||
class PODParameter : public CommonParameter<PresettableUniquelySwitchable> {
|
class PODParameter : public CommonParameter<SwitchingBehavior> {
|
||||||
public:
|
public:
|
||||||
PODParameter(char shortOption, const char *longOption,
|
PODParameter(char shortOption, const char *longOption,
|
||||||
const char* description);
|
const char* description);
|
||||||
@ -383,14 +372,14 @@ public:
|
|||||||
|
|
||||||
std::string usageLine() const;
|
std::string usageLine() const;
|
||||||
protected:
|
protected:
|
||||||
|
virtual int receive(ParserState& state) throw(Parameter::ParameterRejected);
|
||||||
|
|
||||||
/** Validation function for the data type.
|
/** Validation function for the data type.
|
||||||
*
|
*
|
||||||
* @throw ParameterRejected if the argument does not conform to this data type.
|
* @throw ParameterRejected if the argument does not conform to this data type.
|
||||||
* @return the value corresponding to the argument.
|
* @return the value corresponding to the argument.
|
||||||
*/
|
*/
|
||||||
virtual T validate(const std::string& s) throw (ParameterRejected);
|
virtual T validate(const std::string& s) throw (Parameter::ParameterRejected);
|
||||||
virtual void receiveArgument(const std::string &argument) throw(ParameterRejected);
|
|
||||||
virtual void receiveSwitch() throw (Parameter::ParameterRejected);
|
|
||||||
|
|
||||||
T value;
|
T value;
|
||||||
};
|
};
|
||||||
|
@ -53,155 +53,125 @@ template<typename SwitchingBehavior>
|
|||||||
std::string CommonParameter<SwitchingBehavior>::usageLine() const {
|
std::string CommonParameter<SwitchingBehavior>::usageLine() const {
|
||||||
std::stringstream strstr;
|
std::stringstream strstr;
|
||||||
|
|
||||||
strstr.width(10);
|
|
||||||
if (hasShortOption())
|
if (hasShortOption())
|
||||||
{
|
{
|
||||||
strstr << std::left<< std::string("-") + shortOption();
|
strstr << "-" << shortOption() << ", ";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
strstr << " ";
|
strstr << " ";
|
||||||
}
|
}
|
||||||
strstr.width(20);
|
strstr.width(20);
|
||||||
strstr << std::left << "--" + longOption();
|
strstr << std::left << "--" + longOption();
|
||||||
|
|
||||||
return strstr.str();
|
return strstr.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Class SwitchParameter
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
template<typename SwitchingBehavior>
|
template<typename SwitchingBehavior>
|
||||||
bool CommonParameter<SwitchingBehavior>::receive(ParserState& state) throw(Parameter::ParameterRejected) {
|
SwitchParameter<SwitchingBehavior>::SwitchParameter(char shortOption, const char *longOption,
|
||||||
|
const char* description) : CommonParameter<SwitchingBehavior>(shortOption, longOption, description) {}
|
||||||
|
template<typename SwitchingBehavior>
|
||||||
|
SwitchParameter<SwitchingBehavior>::~SwitchParameter() {}
|
||||||
|
|
||||||
|
template<typename SwitchingBehavior>
|
||||||
|
int SwitchParameter<SwitchingBehavior>::receive(ParserState& state) throw(Parameter::ParameterRejected) {
|
||||||
|
|
||||||
const std::string arg = state.get();
|
const std::string arg = state.get();
|
||||||
|
|
||||||
try {
|
if(arg.at(0) != '-') return false;
|
||||||
if(arg.at(0) != '-') return false;
|
|
||||||
|
|
||||||
if(arg.at(1) == '-') { /* Long form parameter */
|
if ((arg.at(1) == '-' && arg.substr(2) == this->longOption()) ||
|
||||||
try {
|
(this->hasShortOption() && arg.at(1) == this->shortOption() && arg.length() == 2))
|
||||||
unsigned int eq = arg.find_first_of("=");
|
{
|
||||||
|
this->set();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if(eq == std::string::npos) {
|
return 0;
|
||||||
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)");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (hasShortOption())
|
|
||||||
{
|
|
||||||
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
|
* PODParameter stuff
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T, typename SwitchingBehavior>
|
||||||
PODParameter<T>::PODParameter(char shortOption, const char *longOption,
|
PODParameter<T, SwitchingBehavior>::PODParameter(char shortOption, const char *longOption,
|
||||||
const char* description) : CommonParameter<PresettableUniquelySwitchable>(shortOption, longOption, description) {}
|
const char* description) : CommonParameter<PresettableUniquelySwitchable>(shortOption, longOption, description) {}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T, typename SwitchingBehavior>
|
||||||
PODParameter<T>::~PODParameter() {}
|
PODParameter<T, SwitchingBehavior>::~PODParameter() {}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T, typename SwitchingBehavior>
|
||||||
PODParameter<T>::operator T() const { return getValue(); }
|
PODParameter<T, SwitchingBehavior>::operator T() const { return getValue(); }
|
||||||
|
|
||||||
template<typename T>
|
template<typename T, typename SwitchingBehavior>
|
||||||
void PODParameter<T>::setDefault(T value) {
|
void PODParameter<T, SwitchingBehavior>::setDefault(T value) {
|
||||||
PresettableUniquelySwitchable::preset();
|
PresettableUniquelySwitchable::preset();
|
||||||
this->value = value;
|
this->value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T, typename SwitchingBehavior>
|
||||||
T PODParameter<T>::getValue() const {
|
T PODParameter<T, SwitchingBehavior>::getValue() const {
|
||||||
if(!isSet()) {
|
if(!this->isSet()) {
|
||||||
throw runtime_error(
|
throw std::runtime_error(
|
||||||
std::string("Attempting to retreive the argument of parameter") + longOption() + " but it hasn't been set!");
|
std::string("Attempting to retreive the argument of parameter") + this->longOption() + " but it hasn't been set!");
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T, typename SwitchingBehavior>
|
||||||
template<typename T>
|
std::string PODParameter<T, SwitchingBehavior>::usageLine() const {
|
||||||
std::string PODParameter<T>::usageLine() const {
|
|
||||||
std::stringstream strstr;
|
std::stringstream strstr;
|
||||||
|
|
||||||
strstr.width(10);
|
if (this->hasShortOption())
|
||||||
if (hasShortOption())
|
|
||||||
{
|
{
|
||||||
strstr << std::left << std::string("-") + shortOption() +"arg";
|
strstr << "-" << this->shortOption() << ", ";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
strstr << "";
|
strstr << " ";
|
||||||
}
|
}
|
||||||
strstr.width(20);
|
strstr.width(20);
|
||||||
strstr << std::left << "--" + longOption() + "=arg";
|
strstr << std::left << "--" + this->longOption() + " <arg>";
|
||||||
|
|
||||||
return strstr.str();
|
return strstr.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T, typename SwitchingBehavior>
|
||||||
void PODParameter<T>::receiveSwitch() throw (Parameter::ParameterRejected) {
|
int PODParameter<T, SwitchingBehavior>::receive(ParserState& state) throw(Parameter::ParameterRejected) {
|
||||||
throw Parameter::ExpectedArgument();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
const std::string arg = state.get();
|
||||||
void PODParameter<T>::receiveArgument(const std::string &argument) throw(Parameter::ParameterRejected) {
|
|
||||||
set();
|
|
||||||
value = this->validate(argument);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if(arg.at(0) != '-') return false;
|
||||||
|
|
||||||
|
if((arg.at(1) == '-' && arg.substr(2) == this->longOption()) ||
|
||||||
|
(this->hasShortOption() && arg.at(1) == this->shortOption() && arg.length() == 2))
|
||||||
|
{
|
||||||
|
// retrieve the argument
|
||||||
|
std::string arg1 = state.peek();
|
||||||
|
if (arg1.length() == 0)
|
||||||
|
{
|
||||||
|
throw Parameter::ExpectedArgument(arg + ": expected an argument");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->set();
|
||||||
|
value = this->validate(arg1);
|
||||||
|
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,19 +1,22 @@
|
|||||||
cmake_minimum_required(VERSION 2.8)
|
cmake_minimum_required(VERSION 2.8)
|
||||||
project(hyperion-remote)
|
project(hyperion-remote)
|
||||||
|
|
||||||
find_package(Qt4 REQUIRED QtCore QtNetwork)
|
find_package(Qt4 REQUIRED QtCore QtGui QtNetwork)
|
||||||
|
|
||||||
# The following I do not undrstand completely...
|
# The following I do not undrstand completely...
|
||||||
# libQtCore.so uses some hardcoded library path inside which are incorrect after copying the file RPi file system
|
# libQtCore.so uses some hardcoded library path inside which are incorrect after copying the file RPi file system
|
||||||
# Therefor, an extra path is needed on which to find the required libraries
|
# Therefor, an extra path is needed on which to find the required libraries
|
||||||
LINK_DIRECTORIES(${LINK_DIRECTORIES} ${CMAKE_FIND_ROOT_PATH}/lib/arm-linux-gnueabihf)
|
LINK_DIRECTORIES(${LINK_DIRECTORIES} ${CMAKE_FIND_ROOT_PATH}/lib/arm-linux-gnueabihf)
|
||||||
|
|
||||||
include_directories(${QT_INCLUDE_DIR})
|
include_directories(${QT_INCLUDES})
|
||||||
|
|
||||||
set(hyperion-remote_HEADERS)
|
set(hyperion-remote_HEADERS
|
||||||
|
specialoptions.h
|
||||||
|
connection.h)
|
||||||
|
|
||||||
set(hyperion-remote_SOURCES
|
set(hyperion-remote_SOURCES
|
||||||
hyperion-remote.cpp)
|
hyperion-remote.cpp
|
||||||
|
connection.cpp)
|
||||||
|
|
||||||
qt4_wrap_cpp(HYPERION_REMOTE_MOC_SOURCES
|
qt4_wrap_cpp(HYPERION_REMOTE_MOC_SOURCES
|
||||||
${hyperion-remote_HEADERS})
|
${hyperion-remote_HEADERS})
|
||||||
@ -25,6 +28,7 @@ add_executable(hyperion-remote
|
|||||||
|
|
||||||
qt4_use_modules(hyperion-remote
|
qt4_use_modules(hyperion-remote
|
||||||
Core
|
Core
|
||||||
|
Gui
|
||||||
Network)
|
Network)
|
||||||
|
|
||||||
target_link_libraries(hyperion-remote
|
target_link_libraries(hyperion-remote
|
||||||
|
71
src/hyperion-remote/connection.cpp
Normal file
71
src/hyperion-remote/connection.cpp
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
#include "connection.h"
|
||||||
|
|
||||||
|
Connection::Connection(const std::string &address, bool printJson)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Connection::~Connection()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Connection::setColor(QColor color, int priority, int duration)
|
||||||
|
{
|
||||||
|
std::cout << "Set color to " << color.red() << " " << color.green() << " " << color.blue() << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Connection::setImage(QImage image, int priority, int duration)
|
||||||
|
{
|
||||||
|
std::cout << "Set image has size: " << image.width() << "x" << image.height() << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Connection::listPriorities()
|
||||||
|
{
|
||||||
|
std::cout << "List priority channels" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Connection::clear(int priority)
|
||||||
|
{
|
||||||
|
std::cout << "Clear priority channel " << priority << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Connection::clearAll()
|
||||||
|
{
|
||||||
|
std::cout << "Clear all priority channels" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Connection::setThreshold(double red, double green, double blue)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Connection::setGamma(double red, double green, double blue)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Connection::setBlacklevel(double red, double green, double blue)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Connection::setWhitelevel(double red, double green, double blue)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Connection::sendMessage(const Json::Value &message)
|
||||||
|
{
|
||||||
|
if (_printJson)
|
||||||
|
{
|
||||||
|
std::cout << "Command:" << std::endl;
|
||||||
|
std::cout << message << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
31
src/hyperion-remote/connection.h
Normal file
31
src/hyperion-remote/connection.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <QColor>
|
||||||
|
#include <QImage>
|
||||||
|
|
||||||
|
#include <json/json.h>
|
||||||
|
|
||||||
|
class Connection
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Connection(const std::string & address, bool printJson);
|
||||||
|
~Connection();
|
||||||
|
|
||||||
|
bool setColor(QColor color, int priority, int duration);
|
||||||
|
bool setImage(QImage image, int priority, int duration);
|
||||||
|
bool listPriorities();
|
||||||
|
bool clear(int priority);
|
||||||
|
bool clearAll();
|
||||||
|
bool setThreshold(double red, double green, double blue);
|
||||||
|
bool setGamma(double red, double green, double blue);
|
||||||
|
bool setBlacklevel(double red, double green, double blue);
|
||||||
|
bool setWhitelevel(double red, double green, double blue);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool sendMessage(const Json::Value & message);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool _printJson;
|
||||||
|
};
|
@ -1,10 +1,25 @@
|
|||||||
#include <QDebug>
|
#include <initializer_list>
|
||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
|
|
||||||
#include <getoptPlusPlus/getoptpp.h>
|
#include <getoptPlusPlus/getoptpp.h>
|
||||||
|
|
||||||
|
#include "specialoptions.h"
|
||||||
|
#include "connection.h"
|
||||||
|
|
||||||
|
|
||||||
using namespace vlofgren;
|
using namespace vlofgren;
|
||||||
|
|
||||||
|
int count(std::initializer_list<bool> values)
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
for (auto& value : values) {
|
||||||
|
if (value)
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, const char * argv[])
|
int main(int argc, const char * argv[])
|
||||||
{
|
{
|
||||||
// some settings
|
// some settings
|
||||||
@ -13,37 +28,96 @@ int main(int argc, const char * argv[])
|
|||||||
|
|
||||||
OptionsParser optionParser("Simple application to send a command to hyperion using the Json interface");
|
OptionsParser optionParser("Simple application to send a command to hyperion using the Json interface");
|
||||||
ParameterSet & parameters = optionParser.getParameters();
|
ParameterSet & parameters = optionParser.getParameters();
|
||||||
StringParameter & argAddress = parameters.add<StringParameter>('a', "address" , QString("Set the address of the hyperion server [default: %1]").arg(defaultServerAddress).toAscii().constData());
|
StringParameter & argAddress = parameters.add<StringParameter> ('a', "address" , QString("Set the address of the hyperion server [default: %1]").arg(defaultServerAddress).toAscii().constData());
|
||||||
IntParameter & argPriority = parameters.add<IntParameter> ('p', "priority" , QString("Use to the provided priority channel (the lower the number, the higher the priority) [default: %1]").arg(defaultPriority).toAscii().constData());
|
IntParameter & argPriority = parameters.add<IntParameter> ('p', "priority" , QString("Use to the provided priority channel (the lower the number, the higher the priority) [default: %1]").arg(defaultPriority).toAscii().constData());
|
||||||
IntParameter & argDuration = parameters.add<IntParameter> ('d', "duration" , "Specify how long the leds should be switched on in millseconds. Without this parameter, the leds will be switched on without end time.");
|
IntParameter & argDuration = parameters.add<IntParameter> ('d', "duration" , "Specify how long the leds should be switched on in millseconds [default: infinity]");
|
||||||
StringParameter & argColor = parameters.add<StringParameter>('c', "color" , "Set all leds to a constant color (either RRGGBB hex value or a color name)");
|
ColorParameter & argColor = parameters.add<ColorParameter> ('c', "color" , "Set all leds to a constant color (either RRGGBB hex value or a color name)");
|
||||||
StringParameter & argImage = parameters.add<StringParameter>('i', "image" , "Set the leds to the colors according to the given image file");
|
ImageParameter & argImage = parameters.add<ImageParameter> ('i', "image" , "Set the leds to the colors according to the given image file");
|
||||||
SwitchParameter & argList = parameters.add<SwitchParameter>('l', "list" , "List all priority channels which are in use");
|
SwitchParameter<> & argList = parameters.add<SwitchParameter<> >('l', "list" , "List all priority channels which are in use");
|
||||||
SwitchParameter & argClear = parameters.add<SwitchParameter>('x', "clear" , "Clear data for the priority channel provided by the -p option");
|
SwitchParameter<> & argClear = parameters.add<SwitchParameter<> >('x', "clear" , "Clear data for the priority channel provided by the -p option");
|
||||||
SwitchParameter & argClearAll = parameters.add<SwitchParameter>(0x0, "clear-all" , "Clear data for all priority channels");
|
SwitchParameter<> & argClearAll = parameters.add<SwitchParameter<> >(0x0, "clear-all" , "Clear data for all priority channels");
|
||||||
DoubleParameter & argGamma = parameters.add<DoubleParameter>('g', "gamma" , "Set the gamma of the leds (requires 3 values)");
|
TransformParameter & argGamma = parameters.add<TransformParameter>('g', "gamma" , "Set the gamma of the leds (requires 3 values)");
|
||||||
DoubleParameter & argThreshold = parameters.add<DoubleParameter>('t', "threshold" , "Set the threshold of the leds (requires 3 values between 0.0 and 1.0)");
|
TransformParameter & argThreshold = parameters.add<TransformParameter>('t', "threshold" , "Set the threshold of the leds (requires 3 space seperated values between 0.0 and 1.0)");
|
||||||
DoubleParameter & argBlacklevel = parameters.add<DoubleParameter>('b', "blacklevel", "Set the blacklevel of the leds (requires 3 values which are normally between 0.0 and 1.0)");
|
TransformParameter & argBlacklevel = parameters.add<TransformParameter>('b', "blacklevel", "Set the blacklevel of the leds (requires 3 space seperated values which are normally between 0.0 and 1.0)");
|
||||||
DoubleParameter & argWhitelevel = parameters.add<DoubleParameter>('w', "whitelevel", "Set the whitelevel of the leds (requires 3 values which are normally between 0.0 and 1.0)");
|
TransformParameter & argWhitelevel = parameters.add<TransformParameter>('w', "whitelevel", "Set the whitelevel of the leds (requires 3 space seperated values which are normally between 0.0 and 1.0)");
|
||||||
SwitchParameter & argPrint = parameters.add<SwitchParameter>(0x0, "print" , "Print the json input and output messages on stdout");
|
SwitchParameter<> & argPrint = parameters.add<SwitchParameter<> >(0x0, "print" , "Print the json input and output messages on stdout");
|
||||||
SwitchParameter & argHelp = parameters.add<SwitchParameter>('h', "help" , "Show this help message and exit");
|
SwitchParameter<> & argHelp = parameters.add<SwitchParameter<> >('h', "help" , "Show this help message and exit");
|
||||||
|
|
||||||
|
argAddress.setDefault(defaultServerAddress.toStdString());
|
||||||
|
argPriority.setDefault(defaultPriority);
|
||||||
|
argDuration.setDefault(-1);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
optionParser.parse(argc, argv);
|
optionParser.parse(argc, argv);
|
||||||
}
|
}
|
||||||
catch (const std::runtime_error & e)
|
catch (const std::runtime_error & e)
|
||||||
{
|
{
|
||||||
qWarning() << e.what();
|
std::cerr << e.what() << std::endl;
|
||||||
optionParser.usage();
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check if we need to display the usage
|
||||||
if (argHelp.isSet())
|
if (argHelp.isSet())
|
||||||
{
|
{
|
||||||
optionParser.usage();
|
optionParser.usage();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check if a color transform is set
|
||||||
|
bool colorTransform = argThreshold.isSet() || argGamma.isSet() || argBlacklevel.isSet() || argWhitelevel.isSet();
|
||||||
|
|
||||||
|
// check if exactly one command was given
|
||||||
|
int commandCount = count({argColor.isSet(), argImage.isSet(), argList.isSet(), argClear.isSet(), argClearAll.isSet(), colorTransform});
|
||||||
|
if (commandCount != 1)
|
||||||
|
{
|
||||||
|
if (commandCount == 0)
|
||||||
|
{
|
||||||
|
std::cerr << "No command found. Provide one of the following options:" << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cerr << "Multiple commands found. Provide one of the following options:" << std::endl;
|
||||||
|
}
|
||||||
|
std::cerr << " " << argColor.usageLine() << std::endl;
|
||||||
|
std::cerr << " " << argImage.usageLine() << std::endl;
|
||||||
|
std::cerr << " " << argList.usageLine() << std::endl;
|
||||||
|
std::cerr << " " << argClear.usageLine() << std::endl;
|
||||||
|
std::cerr << " " << argClearAll.usageLine() << std::endl;
|
||||||
|
std::cerr << "or one or more of the color transformations:" << std::endl;
|
||||||
|
std::cerr << " " << argThreshold.usageLine() << std::endl;
|
||||||
|
std::cerr << " " << argGamma.usageLine() << std::endl;
|
||||||
|
std::cerr << " " << argBlacklevel.usageLine() << std::endl;
|
||||||
|
std::cerr << " " << argWhitelevel.usageLine() << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Connection connection(argAddress.getValue(), argPrint.isSet());
|
||||||
|
|
||||||
|
// now execute the given command
|
||||||
|
if (argColor.isSet())
|
||||||
|
{
|
||||||
|
connection.setColor(argColor.getValue(), argPriority.getValue(), argDuration.getValue());
|
||||||
|
}
|
||||||
|
else if (argImage.isSet())
|
||||||
|
{
|
||||||
|
connection.setImage(argImage.getValue(), argPriority.getValue(), argDuration.getValue());
|
||||||
|
}
|
||||||
|
else if (argList.isSet())
|
||||||
|
{
|
||||||
|
connection.listPriorities();
|
||||||
|
}
|
||||||
|
else if (argClear.isSet())
|
||||||
|
{
|
||||||
|
connection.clear(argPriority.getValue());
|
||||||
|
}
|
||||||
|
else if (argClearAll.isSet())
|
||||||
|
{
|
||||||
|
connection.clearAll();
|
||||||
|
}
|
||||||
|
else if (colorTransform)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
102
src/hyperion-remote/specialoptions.h
Normal file
102
src/hyperion-remote/specialoptions.h
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QColor>
|
||||||
|
#include <QImage>
|
||||||
|
|
||||||
|
#include <getoptPlusPlus/getoptpp.h>
|
||||||
|
|
||||||
|
struct ColorTransform
|
||||||
|
{
|
||||||
|
double valueRed;
|
||||||
|
double valueGreen;
|
||||||
|
double valueBlue;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef vlofgren::PODParameter<QColor> ColorParameter;
|
||||||
|
typedef vlofgren::PODParameter<QImage> ImageParameter;
|
||||||
|
typedef vlofgren::PODParameter<ColorTransform> TransformParameter;
|
||||||
|
|
||||||
|
namespace vlofgren {
|
||||||
|
template<>
|
||||||
|
QColor ColorParameter::validate(const std::string& s) throw (Parameter::ParameterRejected)
|
||||||
|
{
|
||||||
|
// Check if we can create the color by name
|
||||||
|
QColor color(s.c_str());
|
||||||
|
if (color.isValid())
|
||||||
|
{
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if we can create the color by hex RRGGBB value
|
||||||
|
if (s.length() == 6 && isxdigit(s[0]) && isxdigit(s[1]) && isxdigit(s[2]) && isxdigit(s[3]) && isxdigit(s[4]) && isxdigit(s[5]))
|
||||||
|
{
|
||||||
|
bool ok = true;
|
||||||
|
int rgb[3];
|
||||||
|
for (int i = 0; i < 3 && ok; ++i)
|
||||||
|
{
|
||||||
|
QString colorComponent(s.substr(2*i, 2).c_str());
|
||||||
|
rgb[i] = colorComponent.toInt(&ok, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if all components parsed succesfully
|
||||||
|
if (ok)
|
||||||
|
{
|
||||||
|
color.setRgb(rgb[0], rgb[1], rgb[2]);
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::stringstream errorMessage;
|
||||||
|
errorMessage << "Invalid color. A color is specified by a six lettered RRGGBB hex value or one of the following names:";
|
||||||
|
foreach (const QString & colorname, QColor::colorNames()) {
|
||||||
|
errorMessage << "\n " << colorname.toStdString();
|
||||||
|
}
|
||||||
|
throw Parameter::ParameterRejected(errorMessage.str());
|
||||||
|
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
QImage ImageParameter::validate(const std::string& s) throw (Parameter::ParameterRejected)
|
||||||
|
{
|
||||||
|
QImage image(s.c_str());
|
||||||
|
|
||||||
|
if (image.isNull())
|
||||||
|
{
|
||||||
|
std::stringstream errorMessage;
|
||||||
|
errorMessage << "File " << s << " could not be opened as an image";
|
||||||
|
throw Parameter::ParameterRejected(errorMessage.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
ColorTransform TransformParameter::validate(const std::string& s) throw (Parameter::ParameterRejected)
|
||||||
|
{
|
||||||
|
ColorTransform transform;
|
||||||
|
|
||||||
|
// s should be split in 3 parts
|
||||||
|
// seperators are either a ',' or a space
|
||||||
|
QStringList components = QString(s.c_str()).split(" ", QString::SkipEmptyParts);
|
||||||
|
|
||||||
|
if (components.size() == 3)
|
||||||
|
{
|
||||||
|
bool ok1, ok2, ok3;
|
||||||
|
transform.valueRed = components[0].toDouble(&ok1);
|
||||||
|
transform.valueGreen = components[1].toDouble(&ok2);
|
||||||
|
transform.valueBlue = components[2].toDouble(&ok3);
|
||||||
|
|
||||||
|
if (ok1 && ok2 && ok3)
|
||||||
|
{
|
||||||
|
return transform;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::stringstream errorMessage;
|
||||||
|
errorMessage << "Argument " << s << " can not be parsed to 3 double values";
|
||||||
|
throw Parameter::ParameterRejected(errorMessage.str());
|
||||||
|
|
||||||
|
return transform;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user