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(stdout) << "// Autogenerated by the QtGstreamer helper code generator" << endl
31 << "#include <gst/gst.h>" << endl
32 << "#include <boost/static_assert.hpp>" << endl << endl;
34 for (int i=1; i<argc; ++i) {
35 QString fileName(QFile::decodeName(argv[i]));
36 if (fileName.endsWith(".h") && QFile::exists(fileName)) {
37 CodeGen::parse(fileName);
39 QTextStream(stderr) << "Skipping " << fileName << ": Not an existing header" << endl;
46 void CodeGen::parse(const QString & fileName)
48 CodeGen codegen(fileName);
50 FILE *fp = std::fopen(QFile::encodeName(fileName), "r");
53 QTextStream(stderr) << "Could not open " << fileName << endl;
62 codegen.generateOutput();
65 void CodeGen::generateOutput()
67 QTextStream outStream(stdout);
68 outStream << "#include \"" << m_fileName << "\"" << endl << endl;
70 foreach(const TypeRegistration & typeReg, m_typeRegistrations) {
71 printTypeRegistration(outStream, typeReg);
75 foreach(const Enum & enumDef, m_enums) {
76 if (!enumDef.options.contains("skip")) {
77 printEnumAssertions(outStream, enumDef);
83 void CodeGen::printTypeRegistration(QTextStream & outStream, const TypeRegistration & typeReg)
85 outStream << "QGLIB_REGISTER_TYPE_IMPLEMENTATION(";
87 outStream << typeReg["namespace"] << "::" << typeReg["class"];
88 if (!typeReg["enum"].isEmpty()) {
89 outStream << "::" << typeReg["enum"];
94 if (typeReg.contains("GType")) {
95 outStream << typeReg["GType"];
97 outStream << (typeReg["namespace"] == "QGst" ? "GST_TYPE_" : "G_TYPE_");
98 outStream << toGstStyle(typeReg["enum"].isEmpty() ? typeReg["class"] : typeReg["enum"]);
100 outStream << ")" << endl;
103 void CodeGen::printEnumAssertions(QTextStream& outStream, const Enum & enumDef)
105 outStream << "namespace " << enumDef.options["namespace"] << " {" << endl;
107 foreach(const QByteArray & value, enumDef.values) {
108 outStream << " BOOST_STATIC_ASSERT(static_cast<int>(";
109 outStream << enumDef.options["class"] << "::" << value;
110 outStream << ") == static_cast<int>(";
112 if (enumDef.options.contains("prefix")) {
113 outStream << enumDef.options["prefix"];
115 outStream << (enumDef.options["namespace"] == "QGst" ? "GST_TYPE_" : "G_TYPE_");
118 if (enumDef.options.contains(value)) {
119 outStream << enumDef.options[value];
121 outStream << toGstStyle(value);
123 outStream << "));" << endl;
125 outStream << "}" << endl;
128 QByteArray CodeGen::toGstStyle(const QByteArray & str)
131 foreach(const char currentChar, str) {
132 if (isupper(currentChar)) {
133 if (!output.isEmpty()) { //if this is not the first char
136 output.append(currentChar);
138 output.append(toupper(currentChar));
145 void CodeGen::addEnum(const QList<QByteArray> & values, const QHash<QByteArray, QByteArray> & options)
150 e.options["namespace"] = m_currentNamespace;
151 e.options["class"] = m_currentClass;
155 void CodeGen::addTypeRegistration(const QByteArray& namespaceId, const QByteArray& classId,
156 const QByteArray& enumId, const QHash<QByteArray, QByteArray>& options)
158 TypeRegistration typeReg(options);
159 typeReg["namespace"] = namespaceId;
160 typeReg["class"] = classId;
161 typeReg["enum"] = enumId;
162 m_typeRegistrations.append(typeReg);
165 //called by yyerror()
166 void CodeGen::fatalError(const char* msg)
168 QTextStream(stderr) << "codegen: " << m_fileName << ":" << yylineno << ": error: " << msg << endl;