4040****************************************************************************/
4141
4242#include < cstdio>
43+ #include < iostream>
4344
44- #include " main.h"
4545#include " asttoxml.h"
4646#include " reporthandler.h"
4747#include " typesystem.h"
4848#include " generatorset.h"
4949#include " fileout.h"
5050#include " control.h"
51+ #include " pp.h"
5152
5253#include < QDir>
5354#include < QFileInfo>
5758
5859void displayHelp (GeneratorSet *generatorSet);
5960
60- static unsigned int getQtVersion ( const QString& commandLineIncludes)
61+ namespace
6162{
62- QRegularExpression re (" #define\\ s+QTCORE_VERSION\\ s+0x([0-9a-f]+)" , QRegularExpression::CaseInsensitiveOption);
63- for (const QString& includeDir : Preprocess::getIncludeDirectories (commandLineIncludes)) {
64- QFileInfo fi (QDir (includeDir), " qtcoreversion.h" );
65- if (fi.exists ()) {
66- QString filePath = fi.absoluteFilePath ();
67- QFile f (filePath);
68- if (f.open (QIODevice::ReadOnly)) {
69- QTextStream ts (&f);
70- QString content = ts.readAll ();
71- f.close ();
72- auto match = re.match (content);
73- if (match.isValid ()) {
74- unsigned int result;
75- bool ok;
76- result = match.captured (1 ).toUInt (&ok, 16 );
77- if (!ok) {
78- printf (" Could not parse Qt version in file [%s] (looked for #define QTCORE_VERSION)\n " ,
79- qPrintable (filePath));
63+
64+ QStringList getIncludeDirectories (const QString &commandLineIncludes)
65+ {
66+ QStringList includes;
67+ includes << QString (" ." );
68+
69+ #if defined(Q_OS_WIN32)
70+ const char *path_splitter = " ;" ;
71+ #else
72+ const char *path_splitter = " :" ;
73+ #endif
74+
75+ // Environment INCLUDE
76+ QString includePath = getenv (" INCLUDE" );
77+ if (!includePath.isEmpty ())
78+ includes += includePath.split (path_splitter);
79+
80+ // Includes from the command line
81+ if (!commandLineIncludes.isEmpty ())
82+ includes += commandLineIncludes.split (path_splitter);
83+
84+ // Include Qt
85+ QString qtdir = getenv (" QTDIR" );
86+ if (qtdir.isEmpty ()) {
87+ #if defined(Q_OS_MAC)
88+ qWarning (" QTDIR environment variable not set. Assuming standard binary install using frameworks." );
89+ QString frameworkDir = " /Library/Frameworks" ;
90+ includes << (frameworkDir + " /QtXml.framework/Headers" );
91+ includes << (frameworkDir + " /QtNetwork.framework/Headers" );
92+ includes << (frameworkDir + " /QtCore.framework/Headers" );
93+ includes << (frameworkDir + " /QtGui.framework/Headers" );
94+ includes << (frameworkDir + " /QtOpenGL.framework/Headers" );
95+ includes << frameworkDir;
96+ #else
97+ qWarning (" QTDIR environment variable not set. This may cause problems with finding the necessary include files." );
98+ #endif
99+ } else {
100+ std::cout << " -------------------------------------------------------------" << std::endl;
101+ std::cout << " Using QT at: " << qtdir.toLocal8Bit ().constData () << std::endl;
102+ std::cout << " -------------------------------------------------------------" << std::endl;
103+ qtdir += " /include" ;
104+ includes << (qtdir + " /QtXml" );
105+ includes << (qtdir + " /QtNetwork" );
106+ includes << (qtdir + " /QtCore" );
107+ includes << (qtdir + " /QtGui" );
108+ includes << (qtdir + " /QtOpenGL" );
109+ includes << qtdir;
110+ }
111+ return includes;
112+ }
113+
114+ bool
115+ preprocess (const QString &sourceFile, const QString &targetFile, const QString &commandLineIncludes = QString())
116+ {
117+ rpp::pp_environment env;
118+ rpp::pp preprocess (env);
119+
120+ rpp::pp_null_output_iterator null_out;
121+
122+ const char *ppconfig = " :/trolltech/generator/parser/rpp/pp-qt-configuration" ;
123+
124+ QFile file (ppconfig);
125+ if (!file.open (QFile::ReadOnly))
126+ {
127+ fprintf (stderr, " Preprocessor configuration file not found '%s'\n " , ppconfig);
128+ return false ;
129+ }
130+
131+ QByteArray ba = file.readAll ();
132+ file.close ();
133+ preprocess.operator ()(ba.constData (), ba.constData () + ba.size (), null_out);
134+
135+ foreach (QString
136+ include, getIncludeDirectories (commandLineIncludes)) {
137+ preprocess.push_include_path (QDir::toNativeSeparators (include).toStdString ());
138+ }
139+
140+ QString currentDir = QDir::current ().absolutePath ();
141+ QFileInfo sourceInfo (sourceFile);
142+ QDir::setCurrent (sourceInfo.absolutePath ());
143+
144+ std::string result;
145+ result.reserve (20 * 1024 ); // 20K
146+
147+ result += " # 1 \" builtins\"\n " ;
148+ result += " # 1 \" " ;
149+ result += sourceFile.toStdString ();
150+ result += " \"\n " ;
151+
152+ preprocess.file (sourceInfo.fileName ().toStdString (),
153+ rpp::pp_output_iterator<std::string>(result));
154+
155+ QDir::setCurrent (currentDir);
156+
157+ QFile f (targetFile);
158+ if (!f.open (QIODevice::WriteOnly | QIODevice::Text))
159+ {
160+ fprintf (stderr, " Failed to write preprocessed file: %s\n " , qPrintable (targetFile));
161+ }
162+ f.write (result.c_str (), result.length ());
163+
164+ return true ;
165+ }
166+
167+ unsigned int getQtVersion (const QString &commandLineIncludes)
168+ {
169+ QRegularExpression re (" #define\\ s+QTCORE_VERSION\\ s+0x([0-9a-f]+)" , QRegularExpression::CaseInsensitiveOption);
170+ for (const QString &includeDir: getIncludeDirectories (commandLineIncludes))
171+ {
172+ QFileInfo fi (QDir (includeDir), " qtcoreversion.h" );
173+ if (fi.exists ())
174+ {
175+ QString filePath = fi.absoluteFilePath ();
176+ QFile f (filePath);
177+ if (f.open (QIODevice::ReadOnly))
178+ {
179+ QTextStream ts (&f);
180+ QString content = ts.readAll ();
181+ f.close ();
182+ auto match = re.match (content);
183+ if (match.isValid ())
184+ {
185+ unsigned int result;
186+ bool ok;
187+ result = match.captured (1 ).toUInt (&ok, 16 );
188+ if (!ok)
189+ {
190+ printf (" Could not parse Qt version in file [%s] (looked for #define QTCORE_VERSION)\n " ,
191+ qPrintable (filePath));
192+ }
193+ return result;
194+ }
80195 }
81- return result;
82196 }
83197 }
198+ printf (" Error: Could not find Qt version (looked for qtcoreversion.h in %s)\n " ,
199+ qPrintable (commandLineIncludes));
200+ return 0 ;
84201 }
85- }
86- printf (" Error: Could not find Qt version (looked for qtcoreversion.h in %s)\n " ,
87- qPrintable (commandLineIncludes));
88- return 0 ;
89- }
202+ };
90203
91204
92- #include < QDebug>
93205int main (int argc, char *argv[])
94206{
95207 ReportHandler::setContext (" Arguments" );
@@ -102,7 +214,6 @@ int main(int argc, char *argv[])
102214 QString fileName;
103215 QString typesystemFileName;
104216 QString pp_file = " .preprocessed.tmp" ;
105- QStringList rebuild_classes;
106217
107218 QMap<QString, QString> args;
108219 unsigned int qtVersion{};
@@ -213,7 +324,7 @@ int main(int argc, char *argv[])
213324 printf (" PreProcessing - Generate [%s] using [%s] and include-paths [%s]\n " ,
214325 qPrintable (pp_file), qPrintable (fileName), qPrintable (args.value (" include-paths" )));
215326 ReportHandler::setContext (" Preprocess" );
216- if (!Preprocess:: preprocess (fileName, pp_file, args.value (" include-paths" ))) {
327+ if (!preprocess (fileName, pp_file, args.value (" include-paths" ))) {
217328 fprintf (stderr, " Preprocessor failed on file: '%s'\n " , qPrintable (fileName));
218329 return 1 ;
219330 }
@@ -243,9 +354,9 @@ int main(int argc, char *argv[])
243354
244355void displayHelp (GeneratorSet* generatorSet) {
245356#if defined(Q_OS_WIN32)
246- char path_splitter = ' ;' ;
357+ char path_splitter = ' ;' ;
247358#else
248- char path_splitter = ' :' ;
359+ char path_splitter = ' :' ;
249360#endif
250361 printf (" Usage:\n generator [options] header-file typesystem-file\n\n " );
251362 printf (" Available options:\n\n " );
0 commit comments