added GPL incipit

This commit is contained in:
granzuglia 2009-05-18 14:19:30 +00:00
parent 143f9461dd
commit 9a900a640f
1 changed files with 289 additions and 289 deletions

View File

@ -19,292 +19,292 @@
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * * GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
* for more details. * * for more details. *
* * * *
****************************************************************************/ ****************************************************************************/
#include <assert.h> #include <assert.h>
#include <QtCore/QVariant> #include <QtCore/QVariant>
#include "qgetopt.h" #include "qgetopt.h"
#include <stdlib.h> #include <stdlib.h>
#include <iostream> #include <iostream>
using namespace std; using namespace std;
GetOpt::GetOpt(int argc, char *argv[] ) { GetOpt::GetOpt(int argc, char *argv[] ) {
appname = argv[0]; appname = argv[0];
for(int i = 1; i < argc; i++) for(int i = 1; i < argc; i++)
args.push_back(argv[i]); args.push_back(argv[i]);
} }
GetOpt::GetOpt(const QStringList &a): args(a) { GetOpt::GetOpt(const QStringList &a): args(a) {
appname = a[0]; appname = a[0];
args = a; args = a;
args.pop_front(); args.pop_front();
} }
//add an option without a value //add an option without a value
void GetOpt::addSwitch(char s, const QString &name, const QString &description, bool *b ) { void GetOpt::addSwitch(char s, const QString &name, const QString &description, bool *b ) {
Option option; Option option;
assert(!findOption(s, option)); assert(!findOption(s, option));
assert(!findArg(name, option)); assert(!findArg(name, option));
option.type = Option::SWITCH; option.type = Option::SWITCH;
option.o = s; option.o = s;
option.name = name; option.name = name;
option.description = description; option.description = description;
option.b = b; option.b = b;
options.push_back(option); options.push_back(option);
} }
//add a valued option (v will be left untouched if the option is not given) //add a valued option (v will be left untouched if the option is not given)
void GetOpt::addOption(char s, const QString &name, const QString &description, QVariant *v ) { void GetOpt::addOption(char s, const QString &name, const QString &description, QVariant *v ) {
Option option; Option option;
assert(!findOption(s, option)); assert(!findOption(s, option));
assert(!findArg(name, option)); assert(!findArg(name, option));
option.type = Option::OPTION; option.type = Option::OPTION;
option.o = s; option.o = s;
option.name = name; option.name = name;
option.description = description; option.description = description;
option.value = v; option.value = v;
options.push_back(option); options.push_back(option);
} }
//add an argument //add an argument
void GetOpt::addArgument(const QString &name, const QString &description, QVariant *v) { void GetOpt::addArgument(const QString &name, const QString &description, QVariant *v) {
Option option; Option option;
assert(!findArg(name, option)); assert(!findArg(name, option));
option.type = Option::ARGUMENT; option.type = Option::ARGUMENT;
option.name = name; option.name = name;
option.description = description; option.description = description;
option.value = v; option.value = v;
options.push_back(option); options.push_back(option);
} }
//add an optional agrument //add an optional agrument
void GetOpt::addOptionalArgument(const QString &name, const QString &description, QVariant *v) { void GetOpt::addOptionalArgument(const QString &name, const QString &description, QVariant *v) {
Option option; Option option;
assert(!findArg(name, option)); assert(!findArg(name, option));
option.type = Option::OPTIONAL; option.type = Option::OPTIONAL;
option.name = name; option.name = name;
option.description = description; option.description = description;
option.value = v; option.value = v;
options.push_back(option); options.push_back(option);
} }
//return application name //return application name
QString &GetOpt::applicationName() { QString &GetOpt::applicationName() {
return appname; return appname;
} }
//return usage string //return usage string
QString GetOpt::usage() { QString GetOpt::usage() {
QString u = "Usage: " + appname; QString u = "Usage: " + appname;
//arguments //arguments
bool has_optionals = false; bool has_optionals = false;
bool has_options = false; bool has_options = false;
for(int i = 0; i < options.size(); i++) { for(int i = 0; i < options.size(); i++) {
if(options[i].type == Option::OPTION) has_options = true; if(options[i].type == Option::OPTION) has_options = true;
if(options[i].type == Option::OPTIONAL) has_optionals = true; if(options[i].type == Option::OPTIONAL) has_optionals = true;
if(options[i].type != Option::ARGUMENT) continue; if(options[i].type != Option::ARGUMENT) continue;
u += " <" + options[i].name + ">"; u += " <" + options[i].name + ">";
} }
//optional arguments //optional arguments
if(has_optionals) { if(has_optionals) {
u += " ["; u += " [";
for(int i = 0; i < options.size(); i++) { for(int i = 0; i < options.size(); i++) {
if(options[i].type != Option::OPTIONAL) continue; if(options[i].type != Option::OPTIONAL) continue;
u += " <" + options[i].name + ">"; u += " <" + options[i].name + ">";
} }
u += "]"; u += "]";
} }
if(has_options) { if(has_options) {
u += " [-"; u += " [-";
for(int i = 0; i < options.size(); i++) { for(int i = 0; i < options.size(); i++) {
if(options[i].type != Option::OPTION) continue; if(options[i].type != Option::OPTION) continue;
u += options[i].o; u += options[i].o;
} }
u += "]"; u += "]";
} }
u += "\n\n"; u += "\n\n";
//compute maxlen: //compute maxlen:
int maxlen = 0; int maxlen = 0;
for(int i = 0; i < options.size(); i++) { for(int i = 0; i < options.size(); i++) {
Option &o = options[i]; Option &o = options[i];
int len = o.name.size() + 2; int len = o.name.size() + 2;
switch(o.type) { switch(o.type) {
case Option::ARGUMENT: case Option::ARGUMENT:
case Option::OPTIONAL: break; case Option::OPTIONAL: break;
case Option::SWITCH: len += 5; break; case Option::SWITCH: len += 5; break;
case Option::OPTION: len += 16; break; case Option::OPTION: len += 16; break;
default: break; default: break;
} }
if(len > maxlen) maxlen = len; if(len > maxlen) maxlen = len;
} }
//print options and arguments in the given order //print options and arguments in the given order
for(int i = 0; i < options.size(); i++) { for(int i = 0; i < options.size(); i++) {
Option &o = options[i]; Option &o = options[i];
QString line = ""; QString line = "";
switch(o.type) { switch(o.type) {
case Option::ARGUMENT: case Option::ARGUMENT:
case Option::OPTIONAL: line += o.name; break; case Option::OPTIONAL: line += o.name; break;
case Option::SWITCH: line += "-" + QString(o.o) + " --" + o.name; break; case Option::SWITCH: line += "-" + QString(o.o) + " --" + o.name; break;
case Option::OPTION: line += "-" + QString(o.o) + " <val> --" + o.name + " <val>"; break; case Option::OPTION: line += "-" + QString(o.o) + " <val> --" + o.name + " <val>"; break;
default: break; default: break;
} }
QString blank = ""; QString blank = "";
blank.resize(maxlen - line.size()); blank.resize(maxlen - line.size());
blank.fill(' '); blank.fill(' ');
line += blank + formatDesc(o.description, maxlen) + "\n"; line += blank + formatDesc(o.description, maxlen) + "\n";
u += line; u += line;
} }
return u; return u;
} }
void GetOpt::parse() { void GetOpt::parse() {
QString error; QString error;
if(!parse(error)) { if(!parse(error)) {
cerr << qPrintable(error) << endl << endl << qPrintable(usage()) << endl << endl; cerr << qPrintable(error) << endl << endl << qPrintable(usage()) << endl << endl;
exit(0); exit(0);
} }
} }
bool GetOpt::parse(QString &error) { bool GetOpt::parse(QString &error) {
for(int i = 0; i < args.size(); i++) { for(int i = 0; i < args.size(); i++) {
QString arg = args[i]; QString arg = args[i];
if(args[i] == "-h" || args[i] == "--help") { if(args[i] == "-h" || args[i] == "--help") {
cout << qPrintable(usage()) << endl << qPrintable(help) << endl; cout << qPrintable(usage()) << endl << qPrintable(help) << endl;
exit(0); exit(0);
} }
//long option //long option
if(arg.startsWith( QString::fromLatin1( "--" ) ) ) { if(arg.startsWith( QString::fromLatin1( "--" ) ) ) {
arg = arg.mid( 2 ); arg = arg.mid( 2 );
if(arg.isEmpty()) { if(arg.isEmpty()) {
error = "'--' feature not supported, yet"; error = "'--' feature not supported, yet";
return false; return false;
} }
Option o; Option o;
if(!findArg(arg, o)) { if(!findArg(arg, o)) {
error = "Unknown option: '" + arg + "'"; error = "Unknown option: '" + arg + "'";
return false; return false;
} }
if(o.type == Option::SWITCH) { if(o.type == Option::SWITCH) {
*(o.b) = true; *(o.b) = true;
} else { //OPTION } else { //OPTION
i++; i++;
if(args.size() <= i) { if(args.size() <= i) {
error = "Missing value for option: " + arg; error = "Missing value for option: " + arg;
return false; return false;
} }
arg = args[i]; arg = args[i];
if(i == args.size() || arg[0] == '-') { if(i == args.size() || arg[0] == '-') {
error = "Missing argument after option '" + arg + "'"; error = "Missing argument after option '" + arg + "'";
return false; return false;
} }
QVariant v(arg); QVariant v(arg);
if(!v.canConvert(o.value->type()) || !v.convert(o.value->type())) { if(!v.canConvert(o.value->type()) || !v.convert(o.value->type())) {
error = "Error while parsing option " + o.name + ": cannot convert " + error = "Error while parsing option " + o.name + ": cannot convert " +
arg + " to: " + o.value->typeName(); arg + " to: " + o.value->typeName();
return false; return false;
} }
*(o.value) = v; *(o.value) = v;
} }
//option //option
} else if( arg[0] == '-' ) { } else if( arg[0] == '-' ) {
if(arg.size() != 2) { if(arg.size() != 2) {
error = "Invalid option: " + arg; error = "Invalid option: " + arg;
return false; return false;
} }
Option o; Option o;
if(!findOption(arg[1].toAscii(), o)) { if(!findOption(arg[1].toAscii(), o)) {
error = "Unknown option: '" + arg + "'"; error = "Unknown option: '" + arg + "'";
return false; return false;
} }
if(o.type == Option::SWITCH) { if(o.type == Option::SWITCH) {
*(o.b) = true; *(o.b) = true;
} else { //OPTION } else { //OPTION
i++; i++;
if(args.size() <= i) { if(args.size() <= i) {
error = "Missing value for option: " + arg; error = "Missing value for option: " + arg;
return false; return false;
} }
arg = args[i]; arg = args[i];
if(i == args.size() || arg[0] == '-') { if(i == args.size() || arg[0] == '-') {
error = "Missing argument after option '" + arg + "'"; error = "Missing argument after option '" + arg + "'";
return false; return false;
} }
QVariant v(arg); QVariant v(arg);
if(!v.canConvert(o.value->type()) || !v.convert(o.value->type())) { if(!v.canConvert(o.value->type()) || !v.convert(o.value->type())) {
error = "Error while parsing option " + o.name + ": cannot convert " + error = "Error while parsing option " + o.name + ": cannot convert " +
arg + " to: " + o.value->typeName(); arg + " to: " + o.value->typeName();
return false; return false;
} }
*(o.value) = v; *(o.value) = v;
} }
//argument //argument
} else { } else {
arguments.push_back(arg); arguments.push_back(arg);
} }
} }
//test arguments //test arguments
for(int i = 0; i < options.size(); i++) { for(int i = 0; i < options.size(); i++) {
Option &o = options[i]; Option &o = options[i];
if(o.type != Option::ARGUMENT) continue; if(o.type != Option::ARGUMENT) continue;
if(arguments.isEmpty()) { if(arguments.isEmpty()) {
error = "Too few arguments, could not parse argument '" + o.name + "'"; error = "Too few arguments, could not parse argument '" + o.name + "'";
return false; return false;
} }
*(o.value) = arguments.front(); *(o.value) = arguments.front();
arguments.pop_front(); arguments.pop_front();
} }
//test arguments //test arguments
for(int i = 0; i < options.size(); i++) { for(int i = 0; i < options.size(); i++) {
Option &o = options[i]; Option &o = options[i];
if(o.type != Option::ARGUMENT) continue; if(o.type != Option::ARGUMENT) continue;
if(arguments.isEmpty()) break; if(arguments.isEmpty()) break;
*(o.value) = arguments.front(); *(o.value) = arguments.front();
arguments.pop_front(); arguments.pop_front();
} }
if(!arguments.isEmpty() && !unlimitedArgs) { if(!arguments.isEmpty() && !unlimitedArgs) {
error = "Too many arguments"; error = "Too many arguments";
return false; return false;
} }
return true; return true;
} }
bool GetOpt::findOption(char c, Option &option) { bool GetOpt::findOption(char c, Option &option) {
for(int i = 0; i < options.size(); i++) { for(int i = 0; i < options.size(); i++) {
Option &o = options[i]; Option &o = options[i];
if(o.type != Option::OPTION && o.type != Option::SWITCH) continue; if(o.type != Option::OPTION && o.type != Option::SWITCH) continue;
if(o.o == c) { if(o.o == c) {
option = o; option = o;
return true; return true;
} }
} }
return false; return false;
} }
bool GetOpt::findArg(const QString &name, Option &option) { bool GetOpt::findArg(const QString &name, Option &option) {
for(int i = 0; i < options.size(); i++) { for(int i = 0; i < options.size(); i++) {
Option &o = options[i]; Option &o = options[i];
if(o.name == name) { if(o.name == name) {
option = o; option = o;
return true; return true;
} }
} }
return false; return false;
} }
QString GetOpt::formatDesc(QString desc, int len) { QString GetOpt::formatDesc(QString desc, int len) {
QString output; QString output;
//search for last space before 79 - len characters //search for last space before 79 - len characters
while(!desc.isEmpty()) { while(!desc.isEmpty()) {
int pos = desc.lastIndexOf(" ", 79 - len); int pos = desc.lastIndexOf(" ", 79 - len);
if(pos == -1) { if(pos == -1) {
output += desc; output += desc;
break; break;
} }
output += desc.left(pos) + "\n"; output += desc.left(pos) + "\n";
QString blank; QString blank;
blank.resize(len); blank.resize(len);
blank.fill(' '); blank.fill(' ');
output += blank; output += blank;
desc = desc.mid(pos+1); desc = desc.mid(pos+1);
} }
return output; return output;
} }