mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2023-10-10 13:36:59 +02:00
Improve readability of usage message
Former-commit-id: 7919b8e95e57518ee5dd60c6de8b6524a1749998
This commit is contained in:
parent
b74036b61d
commit
6248489aed
268
dependencies/build/getoptPlusPlus/getoptpp.cc
vendored
268
dependencies/build/getoptPlusPlus/getoptpp.cc
vendored
@ -17,6 +17,9 @@
|
|||||||
#include "getoptpp.h"
|
#include "getoptpp.h"
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <string>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@ -34,107 +37,124 @@ 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++)
|
||||||
{
|
{
|
||||||
int n = 0;
|
int n = 0;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
n = (*i)->receive(state);
|
n = (*i)->receive(state);
|
||||||
}
|
}
|
||||||
catch(Parameter::ExpectedArgument &)
|
catch(Parameter::ExpectedArgument &)
|
||||||
{
|
{
|
||||||
throw Parameter::ExpectedArgument(state.get() + ": expected an argument");
|
throw Parameter::ExpectedArgument(state.get() + ": expected an argument");
|
||||||
}
|
}
|
||||||
catch(Parameter::UnexpectedArgument &)
|
catch(Parameter::UnexpectedArgument &)
|
||||||
{
|
{
|
||||||
throw Parameter::UnexpectedArgument(state.get() + ": did not expect an argument");
|
throw Parameter::UnexpectedArgument(state.get() + ": did not expect an argument");
|
||||||
}
|
}
|
||||||
catch(Switchable::SwitchingError &)
|
catch(Switchable::SwitchingError &)
|
||||||
{
|
{
|
||||||
throw Parameter::ParameterRejected(state.get() + ": parameter already set");
|
throw Parameter::ParameterRejected(state.get() + ": parameter already set");
|
||||||
}
|
}
|
||||||
catch(Parameter::ParameterRejected & pr) {
|
catch(Parameter::ParameterRejected & pr) {
|
||||||
std::string what = pr.what();
|
std::string what = pr.what();
|
||||||
if(what.length())
|
if(what.length())
|
||||||
{
|
{
|
||||||
throw Parameter::ParameterRejected(state.get() + ": " + what);
|
throw Parameter::ParameterRejected(state.get() + ": " + what);
|
||||||
}
|
}
|
||||||
throw Parameter::ParameterRejected(state.get() + " (unspecified error)");
|
throw Parameter::ParameterRejected(state.get() + " (unspecified error)");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 1; j < n; ++j)
|
for (int j = 1; j < n; ++j)
|
||||||
{
|
{
|
||||||
state.advance();
|
state.advance();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(n != 0)
|
if(n != 0)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(i == parameters.parameters.end()) {
|
if(i == parameters.parameters.end()) {
|
||||||
std::string file = state.get();
|
std::string file = state.get();
|
||||||
if(file == "--") {
|
if(file == "--") {
|
||||||
state.advance();
|
state.advance();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if(file.at(0) == '-')
|
else if(file.at(0) == '-')
|
||||||
throw Parameter::ParameterRejected(string("Bad parameter: ") + file);
|
throw Parameter::ParameterRejected(string("Bad parameter: ") + file);
|
||||||
else files.push_back(state.get());
|
else files.push_back(state.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!state.end()) for(; !state.end(); state.advance()) {
|
if(!state.end()) for(; !state.end(); state.advance()) {
|
||||||
files.push_back(state.get());
|
files.push_back(state.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptionsParser::usage() const {
|
void OptionsParser::usage() const {
|
||||||
cerr << fprogramDesc << endl;
|
cerr << fprogramDesc << endl;
|
||||||
cerr << "Build time: " << __DATE__ << " " << __TIME__ << endl << endl;
|
cerr << "Build time: " << __DATE__ << " " << __TIME__ << endl << endl;
|
||||||
cerr << "Usage: " << programName() << " [OPTIONS]" << endl << endl;
|
cerr << "Usage: " << programName() << " [OPTIONS]" << endl << endl;
|
||||||
|
|
||||||
cerr << "Parameters: " << endl;
|
cerr << "Parameters: " << endl;
|
||||||
|
|
||||||
std::list<Parameter*>::const_iterator i;
|
int totalWidth = 80;
|
||||||
for(i = parameters.parameters.begin();
|
int usageWidth = 33;
|
||||||
i != parameters.parameters.end(); i++)
|
|
||||||
{
|
|
||||||
cerr.width(33);
|
|
||||||
cerr << std::left << " " + (*i)->usageLine();
|
|
||||||
|
|
||||||
cerr.width(40);
|
// read total width from the terminal
|
||||||
cerr << std::left << (*i)->description() << endl;
|
struct winsize w;
|
||||||
|
if (ioctl(0, TIOCGWINSZ, &w) == 0)
|
||||||
|
{
|
||||||
|
if (w.ws_col > totalWidth)
|
||||||
|
totalWidth = w.ws_col;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
std::list<Parameter*>::const_iterator i;
|
||||||
|
for(i = parameters.parameters.begin();
|
||||||
|
i != parameters.parameters.end(); i++)
|
||||||
|
{
|
||||||
|
cerr.width(usageWidth);
|
||||||
|
cerr << std::left << " " + (*i)->usageLine();
|
||||||
|
|
||||||
|
std::string description = (*i)->description();
|
||||||
|
while (int(description.length()) > (totalWidth - usageWidth))
|
||||||
|
{
|
||||||
|
size_t pos = description.find_last_of(' ', totalWidth - usageWidth);
|
||||||
|
cerr << description.substr(0, pos) << std::endl << std::string(usageWidth - 1, ' ');
|
||||||
|
description = description.substr(pos);
|
||||||
|
}
|
||||||
|
cerr << 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -144,15 +164,15 @@ const string& OptionsParser::programName() const {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,18 +181,18 @@ ParameterSet::~ParameterSet() {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
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["+string(&c)+string("]"));
|
throw out_of_range("ParameterSet["+string(&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+"]");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -186,29 +206,29 @@ Parameter& ParameterSet::operator[](const string& param) const {
|
|||||||
|
|
||||||
|
|
||||||
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -222,7 +242,7 @@ bool ParserState::end() const {
|
|||||||
|
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -250,22 +270,22 @@ 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();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -279,58 +299,58 @@ void PresettableUniquelySwitchable::preset() {
|
|||||||
|
|
||||||
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) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user