2 Copyright (C) 2010 George Kiagiadakis <kiagiadakis.george@gmail.com>
4 This library is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published
6 by the Free Software Foundation; either version 2.1 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #include "generator.h"
20 #include <QtCore/QCoreApplication>
21 #include <QtCore/QFile>
24 int yyparse(CodeGen *codegen);
25 void yyrestart(FILE *file);
27 int main(int argc, char *argv[])
29 QCoreApplication a(argc, argv);
30 QTextStream outStream(stdout);
31 outStream << "// Autogenerated by the QtGstreamer helper code generator" << endl
32 << "#include <boost/static_assert.hpp>" << endl;
34 for (int i=1; i<argc; ++i) {
35 QString fileName(QFile::decodeName(argv[i]));
36 if (fileName.startsWith("-I")) {
37 outStream << "#include <" << fileName.remove(0, 2) << ">" << endl;
38 } else if (fileName.endsWith(".h") && QFile::exists(fileName)) {
39 CodeGen::parse(fileName);
41 QTextStream(stderr) << "Skipping " << fileName << ": Not an existing header" << endl;
48 void CodeGen::parse(const QString & fileName)
50 CodeGen codegen(fileName);
52 FILE *fp = std::fopen(QFile::encodeName(fileName), "r");
55 QTextStream(stderr) << "Could not open " << fileName << endl;
64 codegen.generateOutput();
67 void CodeGen::generateOutput()
69 QTextStream outStream(stdout);
70 outStream << "#include \"" << m_fileName << "\"" << endl << endl;
72 foreach(const TypeRegistration & typeReg, m_typeRegistrations) {
73 printTypeRegistration(outStream, typeReg);
77 foreach(const Enum & enumDef, m_enums) {
78 if (!enumDef.options.contains("skip")) {
79 printEnumAssertions(outStream, enumDef);
85 void CodeGen::printTypeRegistration(QTextStream & outStream, const TypeRegistration & typeReg)
87 outStream << "QGLIB_REGISTER_TYPE_IMPLEMENTATION(";
89 outStream << typeReg["namespace"] << "::" << typeReg["class"];
90 if (!typeReg["enum"].isEmpty()) {
91 outStream << "::" << typeReg["enum"];
96 if (typeReg.contains("GType")) {
97 outStream << typeReg["GType"];
99 outStream << (typeReg["namespace"] == "QGst" ? "GST_TYPE_" : "G_TYPE_");
100 outStream << toGstStyle(typeReg["enum"].isEmpty() ? typeReg["class"] : typeReg["enum"]);
102 outStream << ")" << endl;
105 void CodeGen::printEnumAssertions(QTextStream& outStream, const Enum & enumDef)
107 outStream << "namespace " << enumDef.options["namespace"] << " {" << endl;
109 foreach(const QByteArray & value, enumDef.values) {
110 outStream << " BOOST_STATIC_ASSERT(static_cast<int>(";
111 if (enumDef.options.contains("class") && !enumDef.options["class"].isEmpty()) {
112 outStream << enumDef.options["class"] << "::";
115 outStream << ") == static_cast<int>(";
117 if (enumDef.options.contains("prefix")) {
118 outStream << enumDef.options["prefix"];
120 outStream << (enumDef.options["namespace"] == "QGst" ? "GST_" : "G_");
121 if (enumDef.options.contains("class") && !enumDef.options["class"].isEmpty()) {
122 outStream << toGstStyle(enumDef.options["class"]) << "_";
126 if (enumDef.options.contains(value)) {
127 outStream << enumDef.options[value];
129 outStream << toGstStyle(value);
131 outStream << "));" << endl;
133 outStream << "}" << endl;
136 QByteArray CodeGen::toGstStyle(const QByteArray & str)
139 foreach(const char currentChar, str) {
140 if (isupper(currentChar)) {
141 if (!output.isEmpty()) { //if this is not the first char
144 output.append(currentChar);
146 output.append(toupper(currentChar));
153 void CodeGen::addEnum(const QList<QByteArray> & values, const QHash<QByteArray, QByteArray> & options)
158 e.options["namespace"] = m_currentNamespace;
159 e.options["class"] = m_currentClass;
163 void CodeGen::addTypeRegistration(const QByteArray& namespaceId, const QByteArray& classId,
164 const QByteArray& enumId, const QHash<QByteArray, QByteArray>& options)
166 TypeRegistration typeReg(options);
167 typeReg["namespace"] = namespaceId;
168 typeReg["class"] = classId;
169 typeReg["enum"] = enumId;
170 m_typeRegistrations.append(typeReg);
173 //called by yyerror()
174 void CodeGen::fatalError(const char* msg)
176 QTextStream(stderr) << "codegen: " << m_fileName << ":" << yylineno << ": error: " << msg << endl;