20 #define QT_NO_CAST_ASCII
21 #define QT_NO_ASCII_CAST
23 #include "optionparser.h"
25 #include <QCoreApplication>
34 QCoreApplication* qApp1 = QCoreApplication::instance();
36 qFatal(
"OptionParser: requires a QCoreApplication instance to be constructed first" );
38 init( qApp1->argc(), qApp1->argv(), 1 );
42 QCoreApplication* qApp1 = QCoreApplication::instance();
44 qFatal(
"OptionParser: requires a QApplication instance to be constructed first" );
46 init( qApp1->argc(), qApp1->argv(), offset );
58 void OptionParser::init(
int argc,
char *argv[],
int offset ) {
59 numReqArgs = numOptArgs = 0;
63 aname = QFileInfo( QString::fromUtf8( argv[0] ) ).fileName();
65 for (
int i = offset; i < argc; ++i ) {
66 args.append( QString::fromUtf8( argv[i] ) );
77 QStack<QString> stack;
79 QStringListIterator it(args);
81 while( it.hasPrevious() ) {
82 stack.push( it.previous() );
86 const OptionConstIterator obegin = options.begin();
87 const OptionConstIterator oend = options.end();
88 enum { StartState, ExpectingState, OptionalState } state = StartState;
90 enum TokenType { LongOpt, ShortOpt, Arg, End } t, currType = End;
91 bool extraLoop =
true;
92 while ( !stack.isEmpty() || extraLoop ) {
96 if ( !stack.isEmpty() ) {
101 if ( a.startsWith( QString::fromLatin1(
"--" ) ) ) {
105 qWarning(
"'--' feature not supported, yet" );
110 int equal = a.indexOf(
'=' );
112 stack.push( a.mid( equal + 1 ) );
116 }
else if ( a.length() == 1 ) {
118 }
else if ( a[0] ==
'-' ) {
119 #if 0 // compat mode for -long style options
120 if ( a.length() == 2 ) {
127 int equal = a.find(
'=' );
129 stack.push( a.mid( equal + 1 ) );
138 if ( a.length() > 2 ) {
139 stack.push( a.mid( 2 ) );
154 OptionConstIterator oit = obegin;
155 while ( oit != oend ) {
156 const Option &o = *oit;
157 if ( ( t == LongOpt && a == o.lname ) ||
158 ( t == ShortOpt && a[0].unicode() == o.sname ) ) {
164 if ( t == LongOpt && opt.type == OUnknown ) {
165 if ( currOpt.type != OVarLen ) {
166 qWarning(
"Unknown option --%s", a.toAscii().data() );
172 }
else if ( t == ShortOpt && opt.type == OUnknown ) {
173 if ( currOpt.type != OVarLen ) {
174 qWarning(
"Unknown option -%c", a[0].unicode() );
182 opt = Option( OEnd );
188 if ( opt.type == OSwitch ) {
190 setOptions.insert( opt.lname, 1 );
191 setOptions.insert( QString( QChar( opt.sname ) ), 1 );
192 }
else if ( opt.type == OArg1 || opt.type == ORepeat ) {
193 state = ExpectingState;
196 setOptions.insert( opt.lname, 1 );
197 setOptions.insert( QString( QChar( opt.sname ) ), 1 );
198 }
else if ( opt.type == OOpt || opt.type == OVarLen ) {
199 state = OptionalState;
202 setOptions.insert( opt.lname, 1 );
203 setOptions.insert( QString( QChar( opt.sname ) ), 1 );
204 }
else if ( opt.type == OEnd ) {
206 }
else if ( opt.type == OUnknown && t == Arg ) {
207 if ( numReqArgs > 0 ) {
208 if ( reqArg.stringValue->isNull() ) {
209 *reqArg.stringValue = a;
211 qWarning(
"Too many arguments" );
214 }
else if ( numOptArgs > 0 ) {
215 if ( optArg.stringValue->isNull() ) {
216 *optArg.stringValue = a;
218 qWarning(
"Too many arguments" );
223 qFatal(
"unhandled StartState case %d", opt.type );
228 if ( currOpt.type == OArg1 ) {
229 *currOpt.stringValue = a;
231 }
else if ( currOpt.type == ORepeat ) {
232 currOpt.listValue->append( a );
238 QString n = currType == LongOpt ?
239 currOpt.lname : QString( QChar( currOpt.sname ) );
240 qWarning(
"Expected an argument after '%s' option", n.toAscii().data() );
246 if ( currOpt.type == OOpt ) {
247 *currOpt.stringValue = a;
249 }
else if ( currOpt.type == OVarLen ) {
250 currOpt.listValue->append( origA );
257 if ( currOpt.type == OOpt )
258 *currOpt.stringValue = currOpt.def;
269 if ( untilFirstSwitchOnly && opt.type == OSwitch )
277 if ( numReqArgs > 0 && reqArg.stringValue->isNull() ) {
278 qWarning(
"Lacking required argument" );
291 Option opt( OSwitch, 0, lname );
298 void OptionParser::setSwitch(
const Option &o ) {
299 assert( o.type == OSwitch );
304 Option opt( OArg1, s, l );
311 Option opt( OVarLen, 0, l );
318 Option opt( ORepeat, s, QString::null );
325 Option opt( ORepeat, 0, l );
336 Option opt( OOpt, s, l );
344 Option opt( OUnknown, 0, name );
352 Option opt( OUnknown, 0, name );
361 return setOptions.find( name ) != setOptions.end();