1/****************************************************************************
2**
3** Copyright (C) 2016 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Volker Krause <volker.krause@kdab.com>
4** Copyright (C) 2016 Intel Corporation.
5** Contact: https://www.qt.io/licensing/
6**
7** This file is part of the tools applications of the Qt Toolkit
8**
9** $QT_BEGIN_LICENSE:GPL-EXCEPT$
10** Commercial License Usage
11** Licensees holding valid commercial Qt licenses may use this file in
12** accordance with the commercial license agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and The Qt Company. For licensing terms
15** and conditions see https://www.qt.io/terms-conditions. For further
16** information use the contact form at https://www.qt.io/contact-us.
17**
18** GNU General Public License Usage
19** Alternatively, this file may be used under the terms of the GNU
20** General Public License version 3 as published by the Free Software
21** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
22** included in the packaging of this file. Please review the following
23** information to ensure the GNU General Public License requirements will
24** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25**
26** $QT_END_LICENSE$
27**
28****************************************************************************/
29
30#include <QCommandLineParser>
31#include <QCoreApplication>
32#include <QDir>
33#include <QFile>
34#include <QJsonDocument>
35#include <QJsonObject>
36#include <QLibrary>
37#include <QPluginLoader>
38#include <QStringList>
39
40#include <iostream>
41
42enum PrintOption {
43 PrintIID = 0x01,
44 PrintClassName = 0x02,
45 PrintQtInfo = 0x04,
46 PrintUserData = 0x08
47};
48Q_DECLARE_FLAGS(PrintOptions, PrintOption)
49Q_DECLARE_OPERATORS_FOR_FLAGS(PrintOptions)
50
51int main(int argc, char** argv)
52{
53 QCoreApplication app(argc, argv);
54 QCoreApplication::setApplicationName(QStringLiteral("qplugininfo"));
55 QCoreApplication::setApplicationVersion(QStringLiteral(QT_VERSION_STR));
56
57 QCommandLineParser parser;
58 parser.setApplicationDescription(QStringLiteral("Qt5 plugin meta-data dumper"));
59 QCommandLineOption jsonFormatOption(QStringList() << "f" << "json-format",
60 QStringLiteral("Print JSON data as: indented, compact"), QStringLiteral("format"));
61 QCommandLineOption fullJsonOption("full-json",
62 QStringLiteral("Print the plugin metadata in JSON format"));
63 QCommandLineOption printOption(QStringList() << "p" << QStringLiteral("print"),
64 QStringLiteral("Print detail (iid, classname, qtinfo, userdata)"), QStringLiteral("detail"));
65 jsonFormatOption.setDefaultValue(QStringLiteral("indented"));
66 printOption.setDefaultValues(QStringList() << QStringLiteral("iid") << QStringLiteral("qtinfo") << QStringLiteral("userdata"));
67
68 parser.addOption(commandLineOption: fullJsonOption);
69 parser.addOption(commandLineOption: jsonFormatOption);
70 parser.addOption(commandLineOption: printOption);
71 parser.addHelpOption();
72 parser.addVersionOption();
73 parser.addPositionalArgument(QStringLiteral("plugin"), QStringLiteral("Plug-in of which to read the meta data."), QStringLiteral("<plugin>"));
74 parser.process(app);
75
76 if (parser.positionalArguments().isEmpty())
77 parser.showHelp(exitCode: 1);
78
79 bool fullJson = parser.isSet(option: fullJsonOption);
80 QJsonDocument::JsonFormat jsonFormat = parser.value(option: jsonFormatOption) == "indented" ? QJsonDocument::Indented : QJsonDocument::Compact;
81 QStringList printOptionList = parser.values(option: printOption);
82 PrintOptions print;
83 if (printOptionList.contains(str: "iid"))
84 print |= PrintIID;
85 if (printOptionList.contains(str: "classname"))
86 print |= PrintClassName;
87 if (printOptionList.contains(str: "qtinfo"))
88 print |= PrintQtInfo;
89 if (printOptionList.contains(str: "userdata"))
90 print |= PrintUserData;
91
92 int retval = 0;
93 const QStringList positionalArguments = parser.positionalArguments();
94 for (const QString &plugin : positionalArguments) {
95 QByteArray pluginNativeName = QFile::encodeName(fileName: QDir::toNativeSeparators(pathName: plugin));
96 if (!QFile::exists(fileName: plugin)) {
97 std::cerr << "qtplugininfo: " << pluginNativeName.constData() << ": No such file or directory." << std::endl;
98 retval = 1;
99 continue;
100 }
101 if (!QLibrary::isLibrary(fileName: plugin)) {
102 std::cerr << "qtplugininfo: " << pluginNativeName.constData() << ": Not a plug-in." << std::endl;
103 retval = 1;
104 continue;
105 }
106
107 QPluginLoader loader(plugin);
108 QJsonObject metaData = loader.metaData();
109 if (metaData.isEmpty()) {
110 std::cerr << "qtplugininfo: " << pluginNativeName.constData() << ": No plug-in meta-data found: "
111 << qPrintable(loader.errorString()) << std::endl;
112 retval = 1;
113 continue;
114 }
115
116 QString iid = metaData.value(key: "IID").toString();
117 QString className = metaData.value(key: "className").toString();
118 QJsonValue debug = metaData.value(key: "debug");
119 int version = metaData.value(key: "version").toInt();
120 QJsonValue userData = metaData.value(key: "MetaData");
121
122 if ((version >> 16) != (QT_VERSION >> 16)) {
123 std::cerr << "qtplugininfo: " << pluginNativeName.constData()
124 << ": Qt version mismatch - got major version " << (version >> 16)
125 << ", expected " << (QT_VERSION >> 16) << std::endl;
126 retval = 1;
127 continue;
128 }
129 if (iid.isEmpty() || className.isEmpty() || debug.isNull()) {
130 std::cerr << "qtplugininfo: " << pluginNativeName.constData() << ": invalid metadata, missing required fields:";
131 if (iid.isEmpty())
132 std::cerr << " iid";
133 if (className.isEmpty())
134 std::cerr << " className";
135 if (debug.isNull())
136 std::cerr << " debug";
137 std::cerr << std::endl;
138 retval = 1;
139 continue;
140 }
141
142 if (parser.positionalArguments().size() != 1)
143 std::cout << pluginNativeName.constData() << ": ";
144 if (fullJson) {
145 std::cout << QJsonDocument(metaData).toJson(format: jsonFormat).constData();
146 if (jsonFormat == QJsonDocument::Compact)
147 std::cout << std::endl;
148 } else {
149 if (print & PrintIID)
150 std::cout << "IID \"" << qPrintable(iid) << "\" ";
151 if (print & PrintClassName)
152 std::cout << "class " << qPrintable(className) << ' ';
153 if (print & PrintQtInfo)
154 std::cout << "Qt " << (version >> 16) << '.' << ((version >> 8) & 0xFF) << '.' << (version & 0xFF)
155 << (debug.toBool() ? " (debug)" : " (release)");
156 std::cout << std::endl;
157 if (print & PrintUserData) {
158 if (userData.isObject())
159 std::cout << "User Data: " << QJsonDocument(userData.toObject()).toJson().constData();
160 else if (!userData.isNull()) {
161 std::cerr << "qtplugininfo: " << pluginNativeName.constData() << ": invalid metadata, user data is not a JSON object" << std::endl;
162 retval = 1;
163 }
164 }
165 }
166 }
167
168 return retval;
169}
170

source code of qttools/src/qtplugininfo/qtplugininfo.cpp