summaryrefslogtreecommitdiffstats
path: root/src/qtwaylandscanner
diff options
context:
space:
mode:
authorJohan Klokkhammer Helsing <johan.helsing@qt.io>2018-08-06 17:30:26 +0200
committerJohan Helsing <johan.helsing@qt.io>2018-08-09 07:15:28 +0000
commit0101b89db7d4b1214f78a45f553510a6982f77c0 (patch)
tree7f754b7e2b3cf6a9beb178e73eef3c4f3714a6e1 /src/qtwaylandscanner
parent985cf4667e68a32e9a32d295c5cb9f74f6a24bf1 (diff)
Convert qtwaylandscanner into a class
Encapsulate what the scanner needs of functions and state into a class, Scanner, instead of keeping everything in the global namespace. Change-Id: Idd4b412bb7f709f24c86abe82b135c09b7985878 Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
Diffstat (limited to 'src/qtwaylandscanner')
-rw-r--r--src/qtwaylandscanner/qtwaylandscanner.cpp319
1 files changed, 191 insertions, 128 deletions
diff --git a/src/qtwaylandscanner/qtwaylandscanner.cpp b/src/qtwaylandscanner/qtwaylandscanner.cpp
index 1b884a424..bdcbffa0d 100644
--- a/src/qtwaylandscanner/qtwaylandscanner.cpp
+++ b/src/qtwaylandscanner/qtwaylandscanner.cpp
@@ -41,92 +41,152 @@
#include <QFile>
#include <QXmlStreamReader>
-enum Option {
- ClientHeader,
- ServerHeader,
- ClientCode,
- ServerCode
-} option;
-
-bool isServerSide()
+class Scanner
{
- return option == ServerHeader || option == ServerCode;
+public:
+ explicit Scanner() {}
+ ~Scanner() { delete m_xml; }
+
+ bool parseArguments(int argc, char **argv);
+ void printUsage();
+ bool process();
+ void printErrors();
+
+private:
+ struct WaylandEnumEntry {
+ QByteArray name;
+ QByteArray value;
+ QByteArray summary;
+ };
+
+ struct WaylandEnum {
+ QByteArray name;
+
+ QList<WaylandEnumEntry> entries;
+ };
+
+ struct WaylandArgument {
+ QByteArray name;
+ QByteArray type;
+ QByteArray interface;
+ QByteArray summary;
+ bool allowNull;
+ };
+
+ struct WaylandEvent {
+ bool request;
+ QByteArray name;
+ QByteArray type;
+ QList<WaylandArgument> arguments;
+ };
+
+ struct WaylandInterface {
+ QByteArray name;
+ int version;
+
+ QList<WaylandEnum> enums;
+ QList<WaylandEvent> events;
+ QList<WaylandEvent> requests;
+ };
+
+ bool isServerSide();
+ bool parseOption(const char *str);
+
+ QByteArray byteArrayValue(const QXmlStreamReader &xml, const char *name);
+ int intValue(const QXmlStreamReader &xml, const char *name, int defaultValue = 0);
+ bool boolValue(const QXmlStreamReader &xml, const char *name);
+ WaylandEvent readEvent(QXmlStreamReader &xml, bool request);
+ Scanner::WaylandEnum readEnum(QXmlStreamReader &xml);
+ Scanner::WaylandInterface readInterface(QXmlStreamReader &xml);
+ QByteArray waylandToCType(const QByteArray &waylandType, const QByteArray &interface);
+ QByteArray waylandToQtType(const QByteArray &waylandType, const QByteArray &interface, bool cStyleArray);
+ const Scanner::WaylandArgument *newIdArgument(const QList<WaylandArgument> &arguments);
+
+ void printEvent(const WaylandEvent &e, bool omitNames = false, bool withResource = false);
+ void printEventHandlerSignature(const WaylandEvent &e, const char *interfaceName, bool deepIndent = true);
+ void printEnums(const QList<WaylandEnum> &enums);
+
+ QByteArray stripInterfaceName(const QByteArray &name);
+ bool ignoreInterface(const QByteArray &name);
+
+ enum Option {
+ ClientHeader,
+ ServerHeader,
+ ClientCode,
+ ServerCode
+ } m_option;
+
+ QByteArray m_protocolName;
+ QByteArray m_protocolFilePath;
+ QByteArray m_scannerName;
+ QByteArray m_headerPath;
+ QByteArray m_prefix;
+ QXmlStreamReader *m_xml = nullptr;
+};
+
+bool Scanner::parseArguments(int argc, char **argv)
+{
+ QByteArray m_scannerName = argv[0];
+
+ if (argc <= 2 || !parseOption(argv[1]))
+ return false;
+
+ m_protocolFilePath = QByteArray(argv[2]);
+
+ if (argc >= 4)
+ m_headerPath = QByteArray(argv[3]);
+ if (argc == 5)
+ m_prefix = QByteArray(argv[4]);
+
+ return true;
}
-QByteArray protocolName;
+void Scanner::printUsage()
+{
+ fprintf(stderr, "Usage: %s [client-header|server-header|client-code|server-code] specfile [header-path] [prefix]\n", m_scannerName.constData());
+}
-bool parseOption(const char *str, Option *option)
+bool Scanner::isServerSide()
+{
+ return m_option == ServerHeader || m_option == ServerCode;
+}
+
+bool Scanner::parseOption(const char *str)
{
if (str == QLatin1String("client-header"))
- *option = ClientHeader;
+ m_option = ClientHeader;
else if (str == QLatin1String("server-header"))
- *option = ServerHeader;
+ m_option = ServerHeader;
else if (str == QLatin1String("client-code"))
- *option = ClientCode;
+ m_option = ClientCode;
else if (str == QLatin1String("server-code"))
- *option = ServerCode;
+ m_option = ServerCode;
else
return false;
return true;
}
-struct WaylandEnumEntry {
- QByteArray name;
- QByteArray value;
- QByteArray summary;
-};
-
-struct WaylandEnum {
- QByteArray name;
-
- QList<WaylandEnumEntry> entries;
-};
-
-struct WaylandArgument {
- QByteArray name;
- QByteArray type;
- QByteArray interface;
- QByteArray summary;
- bool allowNull;
-};
-
-struct WaylandEvent {
- bool request;
- QByteArray name;
- QByteArray type;
- QList<WaylandArgument> arguments;
-};
-
-struct WaylandInterface {
- QByteArray name;
- int version;
-
- QList<WaylandEnum> enums;
- QList<WaylandEvent> events;
- QList<WaylandEvent> requests;
-};
-
-QByteArray byteArrayValue(const QXmlStreamReader &xml, const char *name)
+QByteArray Scanner::byteArrayValue(const QXmlStreamReader &xml, const char *name)
{
if (xml.attributes().hasAttribute(name))
return xml.attributes().value(name).toUtf8();
return QByteArray();
}
-int intValue(const QXmlStreamReader &xml, const char *name, int defaultValue = 0)
+int Scanner::intValue(const QXmlStreamReader &xml, const char *name, int defaultValue)
{
bool ok;
int result = byteArrayValue(xml, name).toInt(&ok);
return ok ? result : defaultValue;
}
-bool boolValue(const QXmlStreamReader &xml, const char *name)
+bool Scanner::boolValue(const QXmlStreamReader &xml, const char *name)
{
return byteArrayValue(xml, name) == "true";
}
-WaylandEvent readEvent(QXmlStreamReader &xml, bool request)
+Scanner::WaylandEvent Scanner::readEvent(QXmlStreamReader &xml, bool request)
{
WaylandEvent event;
event.request = request;
@@ -148,7 +208,7 @@ WaylandEvent readEvent(QXmlStreamReader &xml, bool request)
return event;
}
-WaylandEnum readEnum(QXmlStreamReader &xml)
+Scanner::WaylandEnum Scanner::readEnum(QXmlStreamReader &xml)
{
WaylandEnum result;
result.name = byteArrayValue(xml, "name");
@@ -168,7 +228,7 @@ WaylandEnum readEnum(QXmlStreamReader &xml)
return result;
}
-WaylandInterface readInterface(QXmlStreamReader &xml)
+Scanner::WaylandInterface Scanner::readInterface(QXmlStreamReader &xml)
{
WaylandInterface interface;
interface.name = byteArrayValue(xml, "name");
@@ -188,7 +248,7 @@ WaylandInterface readInterface(QXmlStreamReader &xml)
return interface;
}
-QByteArray waylandToCType(const QByteArray &waylandType, const QByteArray &interface)
+QByteArray Scanner::waylandToCType(const QByteArray &waylandType, const QByteArray &interface)
{
if (waylandType == "string")
return "const char *";
@@ -212,7 +272,7 @@ QByteArray waylandToCType(const QByteArray &waylandType, const QByteArray &inter
return waylandType;
}
-QByteArray waylandToQtType(const QByteArray &waylandType, const QByteArray &interface, bool cStyleArray)
+QByteArray Scanner::waylandToQtType(const QByteArray &waylandType, const QByteArray &interface, bool cStyleArray)
{
if (waylandType == "string")
return "const QString &";
@@ -222,7 +282,7 @@ QByteArray waylandToQtType(const QByteArray &waylandType, const QByteArray &inte
return waylandToCType(waylandType, interface);
}
-const WaylandArgument *newIdArgument(const QList<WaylandArgument> &arguments)
+const Scanner::WaylandArgument *Scanner::newIdArgument(const QList<WaylandArgument> &arguments)
{
for (int i = 0; i < arguments.size(); ++i) {
if (arguments.at(i).type == "new_id")
@@ -231,7 +291,7 @@ const WaylandArgument *newIdArgument(const QList<WaylandArgument> &arguments)
return nullptr;
}
-void printEvent(const WaylandEvent &e, bool omitNames = false, bool withResource = false)
+void Scanner::printEvent(const WaylandEvent &e, bool omitNames, bool withResource)
{
printf("%s(", e.name.constData());
bool needsComma = false;
@@ -274,7 +334,7 @@ void printEvent(const WaylandEvent &e, bool omitNames = false, bool withResource
printf(")");
}
-void printEventHandlerSignature(const WaylandEvent &e, const char *interfaceName, bool deepIndent = true)
+void Scanner::printEventHandlerSignature(const WaylandEvent &e, const char *interfaceName, bool deepIndent)
{
const char *indent = deepIndent ? " " : "";
printf("handle_%s(\n", e.name.constData());
@@ -299,7 +359,7 @@ void printEventHandlerSignature(const WaylandEvent &e, const char *interfaceName
printf(")");
}
-void printEnums(const QList<WaylandEnum> &enums)
+void Scanner::printEnums(const QList<WaylandEnum> &enums)
{
for (int i = 0; i < enums.size(); ++i) {
printf("\n");
@@ -318,66 +378,73 @@ void printEnums(const QList<WaylandEnum> &enums)
}
}
-QByteArray stripInterfaceName(const QByteArray &name, const QByteArray &prefix)
+QByteArray Scanner::stripInterfaceName(const QByteArray &name)
{
- if (!prefix.isEmpty() && name.startsWith(prefix))
- return name.mid(prefix.size());
+ if (!m_prefix.isEmpty() && name.startsWith(m_prefix))
+ return name.mid(m_prefix.size());
if (name.startsWith("qt_") || name.startsWith("wl_"))
return name.mid(3);
return name;
}
-bool ignoreInterface(const QByteArray &name)
+bool Scanner::ignoreInterface(const QByteArray &name)
{
return name == "wl_display"
|| (isServerSide() && name == "wl_registry");
}
-void process(QXmlStreamReader &xml, const QByteArray &headerPath, const QByteArray &prefix)
+bool Scanner::process()
{
- if (!xml.readNextStartElement())
- return;
+ QFile file(m_protocolFilePath);
+ if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ fprintf(stderr, "Unable to open file %s\n", m_protocolFilePath.constData());
+ return false;
+ }
- if (xml.name() != "protocol") {
- xml.raiseError(QStringLiteral("The file is not a wayland protocol file."));
- return;
+ m_xml = new QXmlStreamReader(&file);
+ if (!m_xml->readNextStartElement())
+ return false;
+
+ if (m_xml->name() != "protocol") {
+ m_xml->raiseError(QStringLiteral("The file is not a wayland protocol file."));
+ return false;
}
- protocolName = byteArrayValue(xml, "name");
+ m_protocolName = byteArrayValue(*m_xml, "name");
- if (protocolName.isEmpty()) {
- xml.raiseError(QStringLiteral("Missing protocol name."));
- return;
+ if (m_protocolName.isEmpty()) {
+ m_xml->raiseError(QStringLiteral("Missing protocol name."));
+ return false;
}
//We should convert - to _ so that the preprocessor wont generate code which will lead to unexpected behavior
//However, the wayland-scanner doesn't do so we will do the same for now
- //QByteArray preProcessorProtocolName = QByteArray(protocolName).replace('-', '_').toUpper();
- QByteArray preProcessorProtocolName = QByteArray(protocolName).toUpper();
+ //QByteArray preProcessorProtocolName = QByteArray(m_protocolName).replace('-', '_').toUpper();
+ QByteArray preProcessorProtocolName = QByteArray(m_protocolName).toUpper();
QList<WaylandInterface> interfaces;
- while (xml.readNextStartElement()) {
- if (xml.name() == "interface")
- interfaces << readInterface(xml);
+ while (m_xml->readNextStartElement()) {
+ if (m_xml->name() == "interface")
+ interfaces << readInterface(*m_xml);
else
- xml.skipCurrentElement();
+ m_xml->skipCurrentElement();
}
- if (xml.hasError())
- return;
+ if (m_xml->hasError())
+ return false;
- if (option == ServerHeader) {
+ if (m_option == ServerHeader) {
QByteArray inclusionGuard = QByteArray("QT_WAYLAND_SERVER_") + preProcessorProtocolName.constData();
printf("#ifndef %s\n", inclusionGuard.constData());
printf("#define %s\n", inclusionGuard.constData());
printf("\n");
printf("#include \"wayland-server.h\"\n");
- if (headerPath.isEmpty())
- printf("#include \"wayland-%s-server-protocol.h\"\n", QByteArray(protocolName).replace('_', '-').constData());
+ if (m_headerPath.isEmpty())
+ printf("#include \"wayland-%s-server-protocol.h\"\n", QByteArray(m_protocolName).replace('_', '-').constData());
else
- printf("#include <%s/wayland-%s-server-protocol.h>\n", headerPath.constData(), QByteArray(protocolName).replace('_', '-').constData());
+ printf("#include <%s/wayland-%s-server-protocol.h>\n", m_headerPath.constData(), QByteArray(m_protocolName).replace('_', '-').constData());
printf("#include <QByteArray>\n");
printf("#include <QMultiMap>\n");
printf("#include <QString>\n");
@@ -396,7 +463,7 @@ void process(QXmlStreamReader &xml, const QByteArray &headerPath, const QByteArr
printf("QT_WARNING_DISABLE_GCC(\"-Wmissing-field-initializers\")\n");
printf("QT_WARNING_DISABLE_CLANG(\"-Wmissing-field-initializers\")\n");
QByteArray serverExport;
- if (headerPath.size()) {
+ if (m_headerPath.size()) {
serverExport = QByteArray("Q_WAYLAND_SERVER_") + preProcessorProtocolName + "_EXPORT";
printf("\n");
printf("#if !defined(%s)\n", serverExport.constData());
@@ -418,7 +485,7 @@ void process(QXmlStreamReader &xml, const QByteArray &headerPath, const QByteArr
const char *interfaceName = interface.name.constData();
- QByteArray stripped = stripInterfaceName(interface.name, prefix);
+ QByteArray stripped = stripInterfaceName(interface.name);
const char *interfaceNameStripped = stripped.constData();
printf(" class %s %s\n {\n", serverExport.constData(), interfaceName);
@@ -547,11 +614,11 @@ void process(QXmlStreamReader &xml, const QByteArray &headerPath, const QByteArr
printf("#endif\n");
}
- if (option == ServerCode) {
- if (headerPath.isEmpty())
- printf("#include \"qwayland-server-%s.h\"\n", QByteArray(protocolName).replace('_', '-').constData());
+ if (m_option == ServerCode) {
+ if (m_headerPath.isEmpty())
+ printf("#include \"qwayland-server-%s.h\"\n", QByteArray(m_protocolName).replace('_', '-').constData());
else
- printf("#include <%s/qwayland-server-%s.h>\n", headerPath.constData(), QByteArray(protocolName).replace('_', '-').constData());
+ printf("#include <%s/qwayland-server-%s.h>\n", m_headerPath.constData(), QByteArray(m_protocolName).replace('_', '-').constData());
printf("\n");
printf("QT_BEGIN_NAMESPACE\n");
printf("QT_WARNING_PUSH\n");
@@ -573,7 +640,7 @@ void process(QXmlStreamReader &xml, const QByteArray &headerPath, const QByteArr
const char *interfaceName = interface.name.constData();
- QByteArray stripped = stripInterfaceName(interface.name, prefix);
+ QByteArray stripped = stripInterfaceName(interface.name);
const char *interfaceNameStripped = stripped.constData();
printf(" %s::%s(struct ::wl_client *client, int id, int version)\n", interfaceName, interfaceName);
@@ -860,15 +927,15 @@ void process(QXmlStreamReader &xml, const QByteArray &headerPath, const QByteArr
printf("QT_END_NAMESPACE\n");
}
- if (option == ClientHeader) {
+ if (m_option == ClientHeader) {
QByteArray inclusionGuard = QByteArray("QT_WAYLAND_") + preProcessorProtocolName.constData();
printf("#ifndef %s\n", inclusionGuard.constData());
printf("#define %s\n", inclusionGuard.constData());
printf("\n");
- if (headerPath.isEmpty())
- printf("#include \"wayland-%s-client-protocol.h\"\n", QByteArray(protocolName).replace('_', '-').constData());
+ if (m_headerPath.isEmpty())
+ printf("#include \"wayland-%s-client-protocol.h\"\n", QByteArray(m_protocolName).replace('_', '-').constData());
else
- printf("#include <%s/wayland-%s-client-protocol.h>\n", headerPath.constData(), QByteArray(protocolName).replace('_', '-').constData());
+ printf("#include <%s/wayland-%s-client-protocol.h>\n", m_headerPath.constData(), QByteArray(m_protocolName).replace('_', '-').constData());
printf("#include <QByteArray>\n");
printf("#include <QString>\n");
printf("\n");
@@ -878,7 +945,7 @@ void process(QXmlStreamReader &xml, const QByteArray &headerPath, const QByteArr
QByteArray clientExport;
- if (headerPath.size()) {
+ if (m_headerPath.size()) {
clientExport = QByteArray("Q_WAYLAND_CLIENT_") + preProcessorProtocolName + "_EXPORT";
printf("\n");
printf("#if !defined(%s)\n", clientExport.constData());
@@ -899,7 +966,7 @@ void process(QXmlStreamReader &xml, const QByteArray &headerPath, const QByteArr
const char *interfaceName = interface.name.constData();
- QByteArray stripped = stripInterfaceName(interface.name, prefix);
+ QByteArray stripped = stripInterfaceName(interface.name);
const char *interfaceNameStripped = stripped.constData();
printf(" class %s %s\n {\n", clientExport.constData(), interfaceName);
@@ -978,11 +1045,11 @@ void process(QXmlStreamReader &xml, const QByteArray &headerPath, const QByteArr
printf("#endif\n");
}
- if (option == ClientCode) {
- if (headerPath.isEmpty())
- printf("#include \"qwayland-%s.h\"\n", QByteArray(protocolName).replace('_', '-').constData());
+ if (m_option == ClientCode) {
+ if (m_headerPath.isEmpty())
+ printf("#include \"qwayland-%s.h\"\n", QByteArray(m_protocolName).replace('_', '-').constData());
else
- printf("#include <%s/qwayland-%s.h>\n", headerPath.constData(), QByteArray(protocolName).replace('_', '-').constData());
+ printf("#include <%s/qwayland-%s.h>\n", m_headerPath.constData(), QByteArray(m_protocolName).replace('_', '-').constData());
printf("\n");
printf("QT_BEGIN_NAMESPACE\n");
printf("QT_WARNING_PUSH\n");
@@ -997,7 +1064,7 @@ void process(QXmlStreamReader &xml, const QByteArray &headerPath, const QByteArr
const char *interfaceName = interface.name.constData();
- QByteArray stripped = stripInterfaceName(interface.name, prefix);
+ QByteArray stripped = stripInterfaceName(interface.name);
const char *interfaceNameStripped = stripped.constData();
bool hasEvents = !interface.events.isEmpty();
@@ -1172,34 +1239,30 @@ void process(QXmlStreamReader &xml, const QByteArray &headerPath, const QByteArr
printf("QT_WARNING_POP\n");
printf("QT_END_NAMESPACE\n");
}
+
+ return true;
}
-int main(int argc, char **argv)
+void Scanner::printErrors()
{
- if (argc <= 2 || !parseOption(argv[1], &option)) {
- fprintf(stderr, "Usage: %s [client-header|server-header|client-code|server-code] specfile [header-path] [prefix]\n", argv[0]);
- return 1;
- }
+ if (m_xml->hasError())
+ fprintf(stderr, "XML error: %s\nLine %lld, column %lld\n", m_xml->errorString().toLocal8Bit().constData(), m_xml->lineNumber(), m_xml->columnNumber());
+}
+int main(int argc, char **argv)
+{
QCoreApplication app(argc, argv);
+ Scanner scanner;
- QByteArray headerPath;
- if (argc >= 4)
- headerPath = QByteArray(argv[3]);
- QByteArray prefix;
- if (argc == 5)
- prefix = QByteArray(argv[4]);
- QFile file(argv[2]);
- if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
- fprintf(stderr, "Unable to open file %s\n", argv[2]);
- return 1;
+ if (!scanner.parseArguments(argc, argv)) {
+ scanner.printUsage();
+ return EXIT_FAILURE;
}
- QXmlStreamReader xml(&file);
- process(xml, headerPath, prefix);
-
- if (xml.hasError()) {
- fprintf(stderr, "XML error: %s\nLine %lld, column %lld\n", xml.errorString().toLocal8Bit().constData(), xml.lineNumber(), xml.columnNumber());
- return 1;
+ if (!scanner.process()) {
+ scanner.printErrors();
+ return EXIT_FAILURE;
}
+
+ return EXIT_SUCCESS;
}