[ fromfile: argumentlist.xml id: argumentlist ]
In this section, we present the ArgumentList class, an example from libutils (Section 7.3).
It reuses QString and QStringList to simplify the processing of command-line arguments.
Operationally, ArgumentList is a class that we initialize with the main() function's int, and char** parameters that capture the command line arguments.
Conceptually, ArgumentList is a list of QStrings.
Structurally, it is derived from QStringList, with some added functionality.
We could also say that ArgumentList is extended from QStringList (as they do in Java-land).
Example 6.24 contains the class definition for ArgumentList.
Example 6.24. src/libs/utils/argumentlist.h
#ifndef ARGUMENTLIST_H #define ARGUMENTLIST_H #include "utils_export.h" #include <QStringList> class UTILS_EXPORT ArgumentList : public QStringList { public: ArgumentList(); ArgumentList(int argc, char* argv[]) { argsToStringlist(argc, argv); } ArgumentList(const QStringList& argumentList): QStringList(argumentList) {} bool getSwitch(QString option); QString getSwitchArg(QString option, QString defaultRetVal=QString()); private: void argsToStringlist(int argc, char* argv[]); }; #endif
Because it is publicly derived from QStringList, ArgumentList supports the full interface of QStringList and can be used wherever a QStringList is expected. In addition to its constructors, ArgumentList defines a few additional functions:
argsToStringList() extracts the command-line arguments from the given array of char arrays and loads them into a QStringList. This function is private because it is part of the implementation of this class, not part of the public interface. It is needed by the constructors but not by client code.
getSwitch() finds and removes a switch from the string list, if that switch exists. It returns true if the switch was found.
getSwitchArg() finds and removes a switch and its accompanying argument from the string list and returns the argument if the switch is found. It does nothing and returns a defaultValue if the switch is not found.
Example 6.25 shows the implementation code for these functions.
Example 6.25. src/libs/utils/argumentlist.cpp
#include <QCoreApplication> #include <QApplication> #include "argumentlist.h" #include <QDebug> ArgumentList::ArgumentList() { if (qApp != NULL)*this = qApp->arguments(); } void ArgumentList::argsToStringlist(int argc, char * argv []) { for (int i=0; i < argc; ++i) { *this += argv[i]; } } bool ArgumentList::getSwitch (QString option) { QMutableStringListIterator itr(*this); while (itr.hasNext()) { if (option == itr.next()) { itr.remove(); return true; } } return false; } QString ArgumentList::getSwitchArg(QString option, QString defaultValue) { if (isEmpty()) return defaultValue; QMutableStringListIterator itr(*this); while (itr.hasNext()) { if (option == itr.next()) { itr.remove(); if (itr.hasNext()) { QString retval = itr.next(); itr.remove(); return retval; } else { qDebug() << "Missing Argument for " << option; return QString(); } } } return defaultValue; }
In the client code shown in Example 6.26
all argument processing code has been removed from main().
No loops, char*, or strcmp are to be found.
Example 6.26. src/reuse/main.cpp
#include <QString> #include <QDebug> #include <argumentlist.h> // in our utils lib void processFile(QString filename, bool verbose) { if (verbose) qDebug() << QString("Do something chatty with %1.").arg(filename); else qDebug() << filename; } void runTestOnly(QStringList & listOfFiles, bool verbose) { foreach (QString current, listOfFiles) {processFile(current, verbose); } } int main( int argc, char * argv[] ) { ArgumentList al(argc, argv);
QString appname = al.takeFirst();
qDebug() << "Running " << appname; bool verbose = al.getSwitch("-v"); bool testing = al.getSwitch("-t");
if (testing) { runTestOnly(al, verbose);
return 0; } else { qDebug() << "This Is Not A Test"; } }
| Qt improved foreach loop | |
| Instantiate the ArgumentList with command line args. | |
| The first item in the list is the name of the executable | |
| Now all switches have been removed from the list. Only filenames remain. | |
| ArgumentList can be used in place of QStringList. |
Here are some sample outputs from running the program in Example 6.26:
src/reuse> ./reuse item1 "item2 item3" item4 item5 "Running ./reuse" This Is Not A Test src/reuse> ./reuse -t item1 item2 item3 item4 item5 "Running ./reuse" "item1" "item2 item3" "item4" "item5" src/reuse> ./reuse -v -t "foo bar" 123 space1 "1 1" "Running ./reuse" "Do something chatty with foo bar." "Do something chatty with 123." "Do something chatty with space1." "Do something chatty with 1 1." src/reuse>
We include the project file in Example 6.27 to show how to reuse the classes in our utils library.
Example 6.27. src/reuse/reuse.pro
CONFIG += console TEMPLATE = app INCLUDEPATH += $$(CPPLIBS)/utils LIBS += -L$$(CPPLIBS) -lutils # Input SOURCES += main.cpp
| Generated: $Date: 2009-09-08 12:15:32 -0400 (Tue, 08 Sep 2009) $ | © 2009 Alan Ezust and Paul Ezust. |