Qcommandlineparser (#199)

* Replaced getoptplusplus with QCommandLineParser. Fixes #39

* enabling C++11 if possible

* enabling C++11 if possible

* fixed gcc compilation issues

* fixed linux builds and improved os x build

* trying to fix dispmanx

* trying to fix dispmanx

* simplified travis build script

* fixed argumentparser default values

* rewrote validator system and made sure default arguments are processed correctly

* rewrote validator system and made sure default arguments are processed correctly

* fixed bool vs. regular options

* oops... removing debug code

* reverted screenshot api change
This commit is contained in:
Rick van Hattem
2016-08-28 15:10:43 +02:00
committed by redPanther
parent c13f2e20ec
commit 61db9f43b8
74 changed files with 1490 additions and 3911 deletions

View File

@@ -4,6 +4,7 @@ SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include)
SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc)
add_subdirectory(hyperion)
add_subdirectory(commandline)
add_subdirectory(blackborder)
add_subdirectory(jsonserver)
add_subdirectory(protoserver)

View File

@@ -0,0 +1,3 @@
#include "commandline/BooleanOption.h"
using namespace commandline;

View File

@@ -0,0 +1,42 @@
# Define the current source locations
set(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/commandline)
set(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/commandline)
set(Parser_HEADERS
${CURRENT_HEADER_DIR}/ColorOption.h
${CURRENT_HEADER_DIR}/ColorsOption.h
${CURRENT_HEADER_DIR}/DoubleOption.h
${CURRENT_HEADER_DIR}/ImageOption.h
${CURRENT_HEADER_DIR}/IntOption.h
${CURRENT_HEADER_DIR}/Option.h
${CURRENT_HEADER_DIR}/Parser.h
${CURRENT_HEADER_DIR}/RegularExpressionOption.h
${CURRENT_HEADER_DIR}/SwitchOption.h
${CURRENT_HEADER_DIR}/ValidatorOption.h
${CURRENT_HEADER_DIR}/BooleanOption.h
)
set(Parser_SOURCES
${CURRENT_SOURCE_DIR}/ColorOption.cpp
${CURRENT_SOURCE_DIR}/ColorsOption.cpp
${CURRENT_SOURCE_DIR}/DoubleOption.cpp
${CURRENT_SOURCE_DIR}/ImageOption.cpp
${CURRENT_SOURCE_DIR}/IntOption.cpp
${CURRENT_SOURCE_DIR}/Option.cpp
${CURRENT_SOURCE_DIR}/Parser.cpp
${CURRENT_SOURCE_DIR}/RegularExpressionOption.cpp
${CURRENT_SOURCE_DIR}/SwitchOption.cpp
${CURRENT_SOURCE_DIR}/ValidatorOption.cpp
${CURRENT_SOURCE_DIR}/BooleanOption.cpp
)
add_library(commandline
${Parser_HEADERS}
${Parser_SOURCES}
)
qt5_use_modules(commandline Gui)
target_link_libraries(commandline
hyperion
)

View File

@@ -0,0 +1,30 @@
#include <QRegularExpression>
#include "commandline/ColorOption.h"
#include "commandline/Parser.h"
using namespace commandline;
bool ColorOption::validate(Parser & parser, QString & value)
{
// Check if we can create the color by name
_color = QColor(value);
if (_color.isValid()) {
return true;
}
// check if we can create the color by hex RRGGBB getColors
_color = QColor(QString("#%1").arg(value));
if (_color.isValid()) {
return true;
}
if(!parser.isSet(*this)){
// Return true if no value is available
return true;
}
QStringList error;
_error = QString("Invalid color. A color is specified by a six lettered RRGGBB hex getColors or one of the following names:\n\t- %1").arg(QColor::colorNames().join("\n\t- "));
return false;
}

View File

@@ -0,0 +1,37 @@
#include <QRegularExpression>
#include "commandline/ColorsOption.h"
#include "commandline/Parser.h"
using namespace commandline;
bool ColorsOption::validate(Parser & parser, QString & value)
{
// Clear any old results
_colors.clear();
// Check if we can create the color by name
QColor color(value);
if (color.isValid()) {
_colors.push_back(color);
return true;
}
// check if we can create the color by hex RRGGBB getColors
QRegularExpression hexRe("^([0-9A-F]{6})+$", QRegularExpression::CaseInsensitiveOption);
QRegularExpressionMatch match = hexRe.match(value);
if(match.hasMatch()) {
Q_FOREACH(const QString m, match.capturedTexts()){
_colors.push_back(QColor(QString("#%1").arg(m)));
}
return true;
}
if(!parser.isSet(*this)){
// Return true if no value is available
return true;
}
_error = QString("Invalid color. A color is specified by a six lettered RRGGBB hex getColors or one of the following names:\n\t- %1").arg(QColor::colorNames().join("\n\t- "));
return false;
}

View File

@@ -0,0 +1,20 @@
#include "commandline/DoubleOption.h"
#include "commandline/Parser.h"
using namespace commandline;
double DoubleOption::getDouble(Parser &parser, bool *ok)
{
_double = value(parser).toDouble(ok);
return _double;
}
double *DoubleOption::getDoublePtr(Parser &parser, bool *ok)
{
if (parser.isSet(this)) {
getDouble(parser, ok);
return &_double;
} else {
return nullptr;
}
}

View File

@@ -0,0 +1,18 @@
#include "commandline/ImageOption.h"
using namespace commandline;
bool ImageOption::validate(Parser & parser, QString & value)
{
if(value.size()){
_image = QImage(value);
if (_image.isNull())
{
_error = QString("File %1 could not be opened as image").arg(value);
return false;
}
}
return true;
}

View File

@@ -0,0 +1,20 @@
#include "commandline/IntOption.h"
#include "commandline/Parser.h"
using namespace commandline;
int IntOption::getInt(Parser &parser, bool *ok, int base)
{
_int = value(parser).toInt(ok, base);
return _int;
}
int *IntOption::getIntPtr(Parser &parser, bool *ok, int base)
{
if (parser.isSet(this)) {
getInt(parser, ok, base);
return &_int;
} else {
return nullptr;
}
}

View File

@@ -0,0 +1,26 @@
#include "commandline/Option.h"
#include "commandline/Parser.h"
using namespace commandline;
bool Option::validate(Parser & parser, QString &value)
{
/* By default everything is accepted */
return true;
}
QString Option::value(Parser &parser)
{
return parser.value(*this);
}
std::string Option::getStdString(Parser &parser)
{
return value(parser).toStdString();
}
std::wstring Option::getStdWString(Parser &parser)
{
return value(parser).toStdWString();
}

View File

@@ -0,0 +1,90 @@
#include <QtDebug>
#include <QtGui>
#include "commandline/Parser.h"
using namespace commandline;
bool Parser::parse(const QStringList &arguments)
{
if (!_parser.parse(arguments)) {
return false;
}
Q_FOREACH(Option * option, _options) {
QString value = this->value(*option);
if (!option->validate(*this, value)) {
const QString error = option->getError();
if (error.size()) {
_errorText = tr("%1 is not a valid option for %2\n%3").arg(value, option->name(), error);
}
else {
_errorText = tr("%1 is not a valid option for %2").arg(value, option->name());
}
return false;
}
}
return true;
}
void Parser::process(const QStringList &arguments)
{
_parser.process(arguments);
if (!parse(arguments)) {
fprintf(stdout, "%s", qPrintable(tr("Error: %1").arg(_errorText)));
showHelp(EXIT_FAILURE);
}
}
void Parser::process(const QCoreApplication &app)
{
Q_UNUSED(app);
process(QCoreApplication::arguments());
}
QString Parser::errorText() const
{
if (_errorText.size()) {
return _errorText;
}
else {
return _parser.errorText();
}
}
bool Parser::addOption(Option &option)
{
return addOption(&option);
}
bool Parser::addOption(Option * const option)
{
_options[option->name()] = option;
return _parser.addOption(*option);
}
QStringList Parser::_getNames(const char shortOption, const QString longOption)
{
QStringList names;
if (shortOption != 0x0) {
names << QString(shortOption);
}
if (longOption.size()) {
names << longOption;
}
return names;
}
QString Parser::_getDescription(const QString description, const QString default_)
{
/* Add the translations if available */
QString formattedDescription(tr(qPrintable(description)));
/* Fill in the default if needed */
if (default_.size()) {
if(!formattedDescription.contains("%1")){
formattedDescription += " [default: %1]";
}
formattedDescription = formattedDescription.arg(default_);
}
return formattedDescription;
}

View File

@@ -0,0 +1,4 @@
#include "commandline/RegularExpressionOption.h"
using namespace commandline;

View File

@@ -0,0 +1,5 @@
#include "commandline/SwitchOption.h"
using namespace commandline;

View File

@@ -0,0 +1,25 @@
#include "commandline/ValidatorOption.h"
#include "commandline/Parser.h"
using namespace commandline;
bool ValidatorOption::validate(Parser & parser, QString & value)
{
if (parser.isSet(*this) || !defaultValues().empty()) {
int pos = 0;
validator->fixup(value);
return validator->validate(value, pos) == QValidator::Acceptable;
} else {
return true;
}
}
const QValidator *ValidatorOption::getValidator() const
{
return validator;
}
void ValidatorOption::setValidator(const QValidator *validator)
{
ValidatorOption::validator = validator;
}

View File

@@ -1,10 +1,13 @@
// protoserver includes
#include "protoserver/ProtoConnectionWrapper.h"
ProtoConnectionWrapper::ProtoConnectionWrapper(const std::string & address, int priority, int duration_ms, bool skipProtoReply)
ProtoConnectionWrapper::ProtoConnectionWrapper(const QString &address,
int priority,
int duration_ms,
bool skipProtoReply)
: _priority(priority)
, _duration_ms(duration_ms)
, _connection(address)
, _connection(address.toStdString())
{
_connection.setSkipReply(skipProtoReply);
connect(&_connection, SIGNAL(setGrabbingMode(GrabbingMode)), this, SIGNAL(setGrabbingMode(GrabbingMode)));