summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/network/dnslookup/dnslookup.cpp171
-rw-r--r--examples/network/dnslookup/dnslookup.h20
-rw-r--r--src/corelib/doc/qtcore.qdocconf3
-rw-r--r--src/corelib/tools/qcommandlineparser.cpp72
4 files changed, 210 insertions, 56 deletions
diff --git a/examples/network/dnslookup/dnslookup.cpp b/examples/network/dnslookup/dnslookup.cpp
index 202a5f9580..003a3e3028 100644
--- a/examples/network/dnslookup/dnslookup.cpp
+++ b/examples/network/dnslookup/dnslookup.cpp
@@ -45,71 +45,114 @@
#include <QHostAddress>
#include <QStringList>
#include <QTimer>
+#include <QCommandLineParser>
+#include <QCommandLineOption>
#include <stdio.h>
-static void usage() {
- printf("Qt DNS example - performs DNS lookups\n"
- "Usage: dnslookup [-t <type>] [-s nameserver] name\n\n");
+static int typeFromParameter(const QString &type)
+{
+ if (type == "a")
+ return QDnsLookup::A;
+ if (type == "aaaa")
+ return QDnsLookup::AAAA;
+ if (type == "any")
+ return QDnsLookup::ANY;
+ if (type == "cname")
+ return QDnsLookup::CNAME;
+ if (type == "mx")
+ return QDnsLookup::MX;
+ if (type == "ns")
+ return QDnsLookup::NS;
+ if (type == "ptr")
+ return QDnsLookup::PTR;
+ if (type == "srv")
+ return QDnsLookup::SRV;
+ if (type == "txt")
+ return QDnsLookup::TXT;
+ return -1;
}
-DnsManager::DnsManager()
+//! [0]
+
+enum CommandLineParseResult
{
- dns = new QDnsLookup(this);
- connect(dns, SIGNAL(finished()), this, SLOT(showResults()));
-}
+ CommandLineOk,
+ CommandLineError,
+ CommandLineVersionRequested,
+ CommandLineHelpRequested
+};
-void DnsManager::execute()
+CommandLineParseResult parseCommandLine(QCommandLineParser &parser, DnsQuery *query, QString *errorMessage)
{
- QStringList args = QCoreApplication::instance()->arguments();
- args.takeFirst();
+ parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions);
+ const QCommandLineOption nameServerOption("n", "The name server to use.", "nameserver");
+ parser.addOption(nameServerOption);
+ const QCommandLineOption typeOption("t", "The lookup type.", "type");
+ parser.addOption(typeOption);
+ parser.addPositionalArgument("name", "The name to look up.");
+ const QCommandLineOption helpOption = parser.addHelpOption();
+ const QCommandLineOption versionOption = parser.addVersionOption();
+
+ if (!parser.parse(QCoreApplication::arguments())) {
+ *errorMessage = parser.errorText();
+ return CommandLineError;
+ }
- // lookup type
- dns->setType(QDnsLookup::A);
- if (args.size() > 1 && args.first() == "-t") {
- args.takeFirst();
- const QString type = args.takeFirst().toLower();
- if (type == "a")
- dns->setType(QDnsLookup::A);
- else if (type == "aaaa")
- dns->setType(QDnsLookup::AAAA);
- else if (type == "any")
- dns->setType(QDnsLookup::ANY);
- else if (type == "cname")
- dns->setType(QDnsLookup::CNAME);
- else if (type == "mx")
- dns->setType(QDnsLookup::MX);
- else if (type == "ns")
- dns->setType(QDnsLookup::NS);
- else if (type == "ptr")
- dns->setType(QDnsLookup::PTR);
- else if (type == "srv")
- dns->setType(QDnsLookup::SRV);
- else if (type == "txt")
- dns->setType(QDnsLookup::TXT);
- else {
- printf("Bad record type: %s\n", qPrintable(type));
- QCoreApplication::instance()->quit();
- return;
+ if (parser.isSet(versionOption))
+ return CommandLineVersionRequested;
+
+ if (parser.isSet(helpOption))
+ return CommandLineHelpRequested;
+
+ if (parser.isSet(nameServerOption)) {
+ const QString nameserver = parser.value(nameServerOption);
+ query->nameServer = QHostAddress(nameserver);
+ if (query->nameServer.isNull() || query->nameServer.protocol() == QAbstractSocket::UnknownNetworkLayerProtocol) {
+ *errorMessage = "Bad nameserver address: " + nameserver;
+ return CommandLineError;
}
}
- if (args.size() > 1 && args.first() == "-s") {
- args.takeFirst();
- const QString ns = args.takeFirst();
- QHostAddress nameserver(ns);
- if (nameserver.isNull() || nameserver.protocol() == QAbstractSocket::UnknownNetworkLayerProtocol) {
- printf("Bad nameserver address: %s\n", qPrintable(ns));
- QCoreApplication::instance()->quit();
- return;
+
+ if (parser.isSet(typeOption)) {
+ const QString typeParameter = parser.value(typeOption);
+ const int type = typeFromParameter(typeParameter.toLower());
+ if (type < 0) {
+ *errorMessage = "Bad record type: " + typeParameter;
+ return CommandLineError;
}
- dns->setNameserver(nameserver);
+ query->type = static_cast<QDnsLookup::Type>(type);
}
- if (args.isEmpty()) {
- usage();
- QCoreApplication::instance()->quit();
- return;
+
+ const QStringList positionalArguments = parser.positionalArguments();
+ if (positionalArguments.isEmpty()) {
+ *errorMessage = "Argument 'name' missing.";
+ return CommandLineError;
+ }
+ if (positionalArguments.size() > 1) {
+ *errorMessage = "Several 'name' arguments specified.";
+ return CommandLineError;
}
- dns->setName(args.takeFirst());
+ query->name = positionalArguments.first();
+
+ return CommandLineOk;
+}
+
+//! [0]
+
+DnsManager::DnsManager()
+{
+ dns = new QDnsLookup(this);
+ connect(dns, SIGNAL(finished()), this, SLOT(showResults()));
+}
+
+void DnsManager::execute()
+{
+ // lookup type
+ dns->setType(query.type);
+ if (!query.nameServer.isNull())
+ dns->setNameserver(query.nameServer);
+ dns->setName(query.name);
dns->lookup();
}
@@ -159,7 +202,33 @@ int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
+//! [1]
+ QCoreApplication::setApplicationVersion(QT_VERSION_STR);
+ QCoreApplication::setApplicationName(QCoreApplication::translate("QDnsLookupExample", "DNS Lookup Example"));
+ QCommandLineParser parser;
+ parser.setApplicationDescription(QCoreApplication::translate("QDnsLookupExample", "An example demonstrating the class QDnsLookup."));
+ DnsQuery query;
+ QString errorMessage;
+ switch (parseCommandLine(parser, &query, &errorMessage)) {
+ case CommandLineOk:
+ break;
+ case CommandLineError:
+ fputs(qPrintable(errorMessage), stderr);
+ fputs("\n\n", stderr);
+ fputs(qPrintable(parser.helpText()), stderr);
+ return 1;
+ case CommandLineVersionRequested:
+ printf("%s %s\n", qPrintable(QCoreApplication::applicationName()),
+ qPrintable(QCoreApplication::applicationVersion()));
+ return 0;
+ case CommandLineHelpRequested:
+ parser.showHelp();
+ Q_UNREACHABLE();
+ }
+//! [1]
+
DnsManager manager;
+ manager.setQuery(query);
QTimer::singleShot(0, &manager, SLOT(execute()));
return app.exec();
diff --git a/examples/network/dnslookup/dnslookup.h b/examples/network/dnslookup/dnslookup.h
index d76756bad0..4d0232be8a 100644
--- a/examples/network/dnslookup/dnslookup.h
+++ b/examples/network/dnslookup/dnslookup.h
@@ -38,11 +38,21 @@
**
****************************************************************************/
-#include <QObject>
+#include <QDnsLookup>
+#include <QHostAddress>
-QT_BEGIN_NAMESPACE
-class QDnsLookup;
-QT_END_NAMESPACE
+//! [0]
+
+struct DnsQuery
+{
+ DnsQuery() : type(QDnsLookup::A) {}
+
+ QDnsLookup::Type type;
+ QHostAddress nameServer;
+ QString name;
+};
+
+//! [0]
class DnsManager : public QObject
{
@@ -50,6 +60,7 @@ class DnsManager : public QObject
public:
DnsManager();
+ void setQuery(const DnsQuery &q) { query = q; }
public slots:
void execute();
@@ -57,5 +68,6 @@ public slots:
private:
QDnsLookup *dns;
+ DnsQuery query;
};
diff --git a/src/corelib/doc/qtcore.qdocconf b/src/corelib/doc/qtcore.qdocconf
index 18fdfb18f3..2ad24d33b1 100644
--- a/src/corelib/doc/qtcore.qdocconf
+++ b/src/corelib/doc/qtcore.qdocconf
@@ -37,7 +37,8 @@ exampledirs += \
snippets \
../../../examples/threads/ \
../../../examples/tools/ \
- ../../../examples/json/
+ ../../../examples/json/ \
+ ../../../examples/network/dnslookup
imagedirs += images
diff --git a/src/corelib/tools/qcommandlineparser.cpp b/src/corelib/tools/qcommandlineparser.cpp
index c860b4d155..505ab5f46d 100644
--- a/src/corelib/tools/qcommandlineparser.cpp
+++ b/src/corelib/tools/qcommandlineparser.cpp
@@ -187,6 +187,78 @@ QStringList QCommandLineParserPrivate::aliases(const QString &optionName) const
QCoreApplication::arguments() before QCommandLineParser defines the \c{profile}
option and parses the command line.
+ \section2 How to Use QCommandLineParser in Complex Applications
+
+ In practice, additional error checking needs to be performed on the positional
+ arguments and option values. For example, ranges of numbers should be checked.
+
+ It is then advisable to introduce a function to do the command line parsing
+ which takes a struct or class receiving the option values returning an
+ enumeration representing the result. The dnslookup example of the QtNetwork
+ module illustrates this:
+
+ \snippet dnslookup.h 0
+
+ \snippet dnslookup.cpp 0
+
+ In the main function, help should be printed to the standard output if the help option
+ was passed and the application should return the exit code 0.
+
+ If an error was detected, the error message should be printed to the standard
+ error output and the application should return an exit code other than 0.
+
+ \snippet dnslookup.cpp 1
+
+ A special case to consider here are GUI applications on Windows and mobile
+ platforms. These applications may not use the standard output or error channels
+ since the output is either discarded or not accessible.
+
+ For such GUI applications, it is recommended to display help texts and error messages
+ using a QMessageBox. To preserve the formatting of the help text, rich text
+ with \c <pre> elements should be used:
+
+ \code
+
+ switch (parseCommandLine(parser, &query, &errorMessage)) {
+ case CommandLineOk:
+ break;
+ case CommandLineError:
+#ifdef Q_OS_WIN
+ QMessageBox::warning(0, QGuiApplication::applicationDisplayName(),
+ "<html><head/><body><h2>" + errorMessage + "</h2><pre>"
+ + parser.helpText() + "</pre></body></html>");
+#else
+ fputs(qPrintable(errorMessage), stderr);
+ fputs("\n\n", stderr);
+ fputs(qPrintable(parser.helpText()), stderr);
+#endif
+ return 1;
+ case CommandLineVersionRequested:
+#ifdef Q_OS_WIN
+ QMessageBox::information(0, QGuiApplication::applicationDisplayName(),
+ QGuiApplication::applicationDisplayName() + ' '
+ + QCoreApplication::applicationVersion());
+#else
+ printf("%s %s\n", QGuiApplication::applicationDisplayName(),
+ qPrintable(QCoreApplication::applicationVersion()));
+#endif
+ return 0;
+ case CommandLineHelpRequested:
+#ifdef Q_OS_WIN
+ QMessageBox::warning(0, QGuiApplication::applicationDisplayName(),
+ "<html><head/><body><pre>"
+ + parser.helpText() + "</pre></body></html>");
+ return 0;
+#else
+ parser.showHelp();
+ Q_UNREACHABLE();
+#endif
+ }
+ \endcode
+
+ However, this does not apply to the dnslookup example, because it is a
+ console application.
+
\sa QCommandLineOption, QCoreApplication
*/