Skip to content

Commit

Permalink
glgen: Added support for parsing the new xml spec.
Browse files Browse the repository at this point in the history
The .spec file is no longer updated thus support for gl 4.4 is impossible without an update to parse the new xml spec. The legacy parser can be used with the -l (--legacy) switch.

Task-number: QTBUG-33671
Task-number: QTBUG-40090
Change-Id: I83d9380842a16e925f6c07331ee35fe035f6baa9
Reviewed-by: Sean Harmer <[email protected]>
  • Loading branch information
DaveeFTW authored and seanharmer committed Aug 29, 2014
1 parent 036cc9c commit d444bbf
Show file tree
Hide file tree
Showing 7 changed files with 730 additions and 56 deletions.
5 changes: 4 additions & 1 deletion util/glgen/glgen.pro
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@ TEMPLATE = app
TARGET = glgen

SOURCES += main.cpp \
specparser.cpp \
xmlspecparser.cpp \
legacyspecparser.cpp \
codegenerator.cpp

HEADERS += \
specparser.h \
xmlspecparser.h \
legacyspecparser.h \
codegenerator.h

OTHER_FILES += \
Expand Down
57 changes: 29 additions & 28 deletions util/glgen/specparser.cpp → util/glgen/legacyspecparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
**
****************************************************************************/

#include "specparser.h"
#include "legacyspecparser.h"

#include <QDebug>
#include <QFile>
Expand All @@ -48,39 +48,36 @@
#include <QTextStream>

#ifdef SPECPARSER_DEBUG
#define qSpecParserDebug qDebug
#define qLegacySpecParserDebug qDebug
#else
#define qSpecParserDebug QT_NO_QDEBUG_MACRO
#define qLegacySpecParserDebug QT_NO_QDEBUG_MACRO
#endif

SpecParser::SpecParser()
{
}

void SpecParser::parse()
bool LegacySpecParser::parse()
{
// Get the mapping form generic types to specific types suitable for use in C-headers
if (!parseTypeMap())
return;
return false;

// Open up a stream on the actual OpenGL function spec file
QFile file(m_specFileName);
QFile file(specFileName());
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
qWarning() << "Failed to open spec file:" << m_specFileName << "Aborting";
return;
qWarning() << "Failed to open spec file:" << specFileName() << "Aborting";
return false;
}

QTextStream stream(&file);

// Extract the info that we need
parseFunctions(stream);
return true;
}

bool SpecParser::parseTypeMap()
bool LegacySpecParser::parseTypeMap()
{
QFile file(m_typeMapFileName);
QFile file(typeMapFileName());
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
qWarning() << "Failed to open spec file:" << m_specFileName << "Aborting";
qWarning() << "Failed to open type file:" << typeMapFileName() << "Aborting";
return false;
}

Expand All @@ -103,18 +100,18 @@ bool SpecParser::parseTypeMap()
value = QStringLiteral("void");

m_typeMap.insert(key, value);
qSpecParserDebug() << "Found type mapping from" << key << "=>" << value;
qLegacySpecParserDebug() << "Found type mapping from" << key << "=>" << value;
}
}

return true;
}

void SpecParser::parseEnums()
void LegacySpecParser::parseEnums()
{
}

void SpecParser::parseFunctions(QTextStream &stream)
void LegacySpecParser::parseFunctions(QTextStream &stream)
{
static QRegExp functionRegExp("^(\\w+)\\(.*\\)");
static QRegExp returnRegExp("^\\treturn\\s+(\\S+)");
Expand Down Expand Up @@ -168,8 +165,12 @@ void SpecParser::parseFunctions(QTextStream &stream)
versions.insert(currentVersionProfile.version);
}

if (acceptCurrentFunctionInExtension)
m_extensionFunctions.insert(currentCategory, currentFunction);
if (acceptCurrentFunctionInExtension) {
FunctionProfile fp;
fp.profile = currentVersionProfile.profile;
fp.function = currentFunction;
m_extensionFunctions.insert(currentCategory, fp);
}
}

// Start a new function
Expand All @@ -187,7 +188,7 @@ void SpecParser::parseFunctions(QTextStream &stream)
// Extract the function name
QString functionName = functionRegExp.cap(1);
currentFunction.name = functionName;
qSpecParserDebug() << "Found function:" << functionName;
qLegacySpecParserDebug() << "Found function:" << functionName;

} else if (argumentRegExp.indexIn(line) != -1) {
// Extract info about this function argument
Expand Down Expand Up @@ -219,7 +220,7 @@ void SpecParser::parseFunctions(QTextStream &stream)
acceptCurrentFunctionInCore = false;
}

qSpecParserDebug() << " argument:" << arg.type << arg.name;
qLegacySpecParserDebug() << " argument:" << arg.type << arg.name;
currentFunction.arguments.append(arg);

} else if (returnRegExp.indexIn(line) != -1) {
Expand All @@ -230,13 +231,13 @@ void SpecParser::parseFunctions(QTextStream &stream)
acceptCurrentFunctionInCore = false;
}
QString returnType = m_typeMap.value(returnTypeKey);
qSpecParserDebug() << " return type:" << returnType;
qLegacySpecParserDebug() << " return type:" << returnType;
currentFunction.returnType = returnType;

} else if (versionRegExp.indexIn(line) != -1 && !haveVersionInfo) { // Only use version line if no other source
// Extract the OpenGL version in which this function was introduced
QString version = versionRegExp.cap(1);
qSpecParserDebug() << " version:" << version;
qLegacySpecParserDebug() << " version:" << version;
QStringList parts = version.split(QLatin1Char('.'));
if (parts.size() != 2) {
qWarning() << "Found invalid version number";
Expand All @@ -259,7 +260,7 @@ void SpecParser::parseFunctions(QTextStream &stream)
} else if (categoryRegExp.indexIn(line) != -1) {
// Extract the category for this function
QString category = categoryRegExp.cap(1).simplified();
qSpecParserDebug() << " category:" << category;
qLegacySpecParserDebug() << " category:" << category;

if (categoryVersionRegExp.indexIn(category) != -1) {
// Use the version info in the category in preference to the version
Expand All @@ -275,7 +276,7 @@ void SpecParser::parseFunctions(QTextStream &stream)

} else {
// Make a note of the extension name and tag this function as being part of an extension
qSpecParserDebug() << "Found category =" << category;
qLegacySpecParserDebug() << "Found category =" << category;
currentCategory = category;
acceptCurrentFunctionInExtension = true;

Expand All @@ -290,7 +291,7 @@ void SpecParser::parseFunctions(QTextStream &stream)
}

} else if (extToCoreVersionRegExp.indexIn(line) != -1) {
qSpecParserDebug() << line;
qLegacySpecParserDebug() << line;
int majorVersion = extToCoreVersionRegExp.cap(1).toInt();
int minorVersion = extToCoreVersionRegExp.cap(2).toInt();
extToCoreCurrentVersion.major = majorVersion;
Expand All @@ -306,7 +307,7 @@ void SpecParser::parseFunctions(QTextStream &stream)
qSort(m_versions);
}

bool SpecParser::inDeprecationException(const QString &functionName) const
bool LegacySpecParser::inDeprecationException(const QString &functionName) const
{
return (functionName == QStringLiteral("TexImage3D"));
}
78 changes: 78 additions & 0 deletions util/glgen/legacyspecparser.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/***************************************************************************
**
** Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB)
** Contact: http://www.qt-project.org/legal
**
** This file is part of the utilities of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#ifndef LEGACYSPECPARSER_H
#define LEGACYSPECPARSER_H

#include "specparser.h"

#include <QStringList>
#include <QVariant>

class QTextStream;

class LegacySpecParser : public SpecParser
{
public:
virtual QList<Version> versions() const {return m_versions;}

virtual bool parse();

protected:
const QMultiHash<VersionProfile, Function> &versionFunctions() const { return m_functions; }
const QMultiMap<QString, FunctionProfile> &extensionFunctions() const { return m_extensionFunctions; }

private:
QMap<QString, QString> m_typeMap;
QMultiHash<VersionProfile, Function> m_functions;

QList<Version> m_versions;

// Extension support
QMultiMap<QString, FunctionProfile> m_extensionFunctions;

bool parseTypeMap();
void parseEnums();
void parseFunctions(QTextStream &stream);
bool inDeprecationException(const QString &functionName) const;
};

#endif // LEGACYSPECPARSER_H
33 changes: 25 additions & 8 deletions util/glgen/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,22 +40,39 @@
****************************************************************************/

#include "codegenerator.h"
#include "specparser.h"
#include "legacyspecparser.h"
#include "xmlspecparser.h"

#include <QCommandLineParser>

int main(int argc, char *argv[])
{
Q_UNUSED(argc);
Q_UNUSED(argv);
QCoreApplication app(argc, argv);
QCommandLineParser cmdParser;

// flag whether to use legacy or not
QCommandLineOption legacyOption(QStringList() << "l" << "legacy", "Use legacy parser.");
cmdParser.addOption(legacyOption);
cmdParser.process(app);

SpecParser *parser;

if (cmdParser.isSet(legacyOption)) {
parser = new LegacySpecParser();
parser->setTypeMapFileName(QStringLiteral("gl.tm"));
parser->setSpecFileName(QStringLiteral("gl.spec"));
} else {
parser = new XmlSpecParser();
parser->setSpecFileName(QStringLiteral("gl.xml"));
}

SpecParser parser;
parser.setTypeMapFileName(QStringLiteral("gl.tm"));
parser.setSpecFileName(QStringLiteral("gl.spec"));
parser.parse();
parser->parse();

CodeGenerator generator;
generator.setParser(&parser);
generator.setParser(parser);
generator.generateCoreClasses(QStringLiteral("qopenglversionfunctions"));
generator.generateExtensionClasses(QStringLiteral("qopenglextensions"));

delete parser;
return 0;
}
Loading

0 comments on commit d444bbf

Please sign in to comment.