source: trunk/tools/porting/src/projectporter.cpp@ 1028

Last change on this file since 1028 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 16.7 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the qt3to4 porting application of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "projectporter.h"
43#include "proparser.h"
44#include "textreplacement.h"
45#include "fileporter.h"
46#include "logger.h"
47#include "translationunit.h"
48#include "codemodelattributes.h"
49#include <QtDebug>
50#include <QFile>
51#include <QDir>
52#include <QStringList>
53#include <QFileInfo>
54#include <QBuffer>
55
56QT_BEGIN_NAMESPACE
57
58using namespace TokenEngine;
59
60ProjectPorter::ProjectPorter(QString basePath, QStringList includeDirectories, QStringList qt3HeadersFilenames)
61:basePath(basePath)
62,includeDirectories(includeDirectories)
63,defaultDefinitions(defaultMacros(preprocessorCache))
64,filePorter(preprocessorCache)
65,qt3HeadersFilenames(qt3HeadersFilenames)
66,analyze(true)
67,warnings(false)
68{}
69
70void ProjectPorter::enableCppParsing(bool enable)
71{
72 analyze = enable;
73}
74
75void ProjectPorter::enableMissingFilesWarnings(bool enable)
76{
77 warnings = enable;
78}
79
80void ProjectPorter::portProject(QString fileName)
81{
82 QFileInfo fileInfo(fileName);
83 portProject(fileInfo.path(), fileInfo.fileName());
84}
85
86/*
87 Port a single file
88*/
89void ProjectPorter::portFile(QString fileName)
90{
91 if (analyze) {
92 IncludeFiles includeFiles(basePath, includeDirectories);
93
94 PreprocessorController preprocessor(includeFiles, preprocessorCache, qt3HeadersFilenames);
95 connect(&preprocessor, SIGNAL(error(QString,QString)), SLOT(error(QString,QString)));
96
97 Rpp::DefineMap definitionsCopy = *defaultDefinitions;
98 // Preprocess
99 TokenSectionSequence translationUnit = preprocessor.evaluate(fileName, &definitionsCopy);
100 // Parse
101 TranslationUnit translationUnitData = TranslationUnitAnalyzer().analyze(translationUnit);
102
103 // Enable attribute generation for this file.
104 enableAttributes(includeFiles, fileName);
105 // Generate attributes.
106 CodeModelAttributes().createAttributes(translationUnitData);
107 }
108
109 portFiles(QString(), QStringList() << fileName);
110}
111
112void ProjectPorter::error(QString type, QString text)
113{
114 if (warnings && type == QLatin1String("Error"))
115 printf("Warning: %s\n", text.toLocal8Bit().constData());
116}
117
118void ProjectPorter::portProject(QString basePath, QString proFileName)
119{
120 QString fullInFileName = basePath + QLatin1String("/") + proFileName;
121 QFileInfo infileInfo(fullInFileName);
122 if (!infileInfo.exists()) {
123 printf("Could not open file: %s\n", QDir::toNativeSeparators(fullInFileName).toLocal8Bit().constData());
124 return;
125 }
126
127 QString proFileContents = loadFile(fullInFileName);
128 QMap<QString, QString> proFileMap = proFileTagMap(proFileContents, QDir(basePath).absolutePath());
129
130
131 // Check if this is a TEMPLATE = subdirs .pro file, in that case we
132 // process each subdir (recursively).
133
134 QString templateTag = proFileMap[QLatin1String("TEMPLATE")];
135 if (templateTag == QLatin1String("subdirs")) {
136 QStringList subdirs = proFileMap[QLatin1String("SUBDIRS")].split(QLatin1String(" "), QString::SkipEmptyParts);
137 foreach(QString subdir, subdirs) {
138 QString newBasePath = basePath + QLatin1String("/") + subdir;
139 QStringList dirsInSubdir = subdir.split(QRegExp(QLatin1String("/|\\\\")), QString::SkipEmptyParts);
140 QString newProFileName = dirsInSubdir.last() + QLatin1String(".pro");
141 portProject(newBasePath, newProFileName);
142 }
143 return;
144 }
145
146 // Get headers and sources file names from .pro file.
147 QStringList sources = proFileMap[QLatin1String("SOURCES")].split(QLatin1String(" "), QString::SkipEmptyParts);
148 QStringList headers = proFileMap[QLatin1String("HEADERS")].split(QLatin1String(" "), QString::SkipEmptyParts);
149 QStringList forms = proFileMap[QLatin1String("FORMS")].split(QLatin1String(" "), QString::SkipEmptyParts);
150 QStringList uidoth;
151 for (int i = 0; i < forms.size(); ++i) {
152 QString ui_h = forms.at(i) + QLatin1String(".h");
153 if (QFile::exists(basePath + QLatin1String("/") + ui_h))
154 uidoth += ui_h;
155 }
156
157 if (analyze) {
158 printf("Parsing");
159 // Get include paths from the pro file.
160 QStringList includeProPaths = proFileMap[QLatin1String("INCLUDEPATH")].split(QLatin1String(" "), QString::SkipEmptyParts);
161 QStringList dependProPaths = proFileMap[QLatin1String("DEPENDPATH")].split(QLatin1String(" "), QString::SkipEmptyParts);
162 IncludeFiles includeFiles(basePath, includeDirectories + includeProPaths + dependProPaths);
163
164 PreprocessorController preprocessorController(includeFiles, preprocessorCache, qt3HeadersFilenames);
165 connect(&preprocessorController, SIGNAL(error(QString,QString)), SLOT(error(QString,QString)));
166
167 TranslationUnitAnalyzer translationUnitAnalyzer;
168 CodeModelAttributes codeModelAttributes;
169
170 // Enable attribute generation for header files.
171 foreach(QString headerFile, headers)
172 enableAttributes(includeFiles, headerFile);
173
174 // Enable attribute generation for ui.h files.
175 foreach(QString headerFile, uidoth)
176 enableAttributes(includeFiles, headerFile);
177
178 // Analyze each translation unit. (one per cpp file)
179 foreach(QString sourceFile, sources) {
180 printf(".");
181 fflush(stdout);
182 Rpp::DefineMap definitionsCopy = *defaultDefinitions;
183 TokenSectionSequence translationUnit =
184 preprocessorController.evaluate(sourceFile, &definitionsCopy);
185 TranslationUnit translationUnitData =
186 translationUnitAnalyzer.analyze(translationUnit);
187
188 // Enable attribute generation for this file.
189 enableAttributes(includeFiles, sourceFile);
190
191 codeModelAttributes.createAttributes(translationUnitData);
192 }
193 puts("");
194 }
195
196
197 // Port files.
198 portFiles(basePath, sources);
199 portFiles(basePath, headers);
200 if (!uidoth.isEmpty())
201 portFiles(basePath, uidoth);
202
203 Logger::instance()->globalState[QLatin1String("currentFileName")] = proFileName;
204 Logger::instance()->beginSection();
205 portProFile(fullInFileName, proFileMap);
206}
207
208/*
209 Port each file given in the fileNames list. If a file name is relative
210 it is assumed to be relative to basePath.
211*/
212void ProjectPorter::portFiles(QString basePath, QStringList fileNames)
213{
214 foreach(QString fileName, fileNames) {
215 QString fullFilePath;
216 QFileInfo fileInfo(fileName);
217 if (fileInfo.isAbsolute()) {
218 fullFilePath = QDir::cleanPath(fileName);
219 } else {
220 fullFilePath = QDir::cleanPath(basePath + QLatin1String("/") + fileName);
221 }
222
223 QFileInfo fullFilePathInfo(fullFilePath);
224 if (!fullFilePathInfo.exists()) {
225 printf("Could not find file: %s\n", QDir::toNativeSeparators(fullFilePath).toLocal8Bit().constData());
226 continue;
227 }
228