1
/****************************************************************************
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
5
** This file is part of the porting application of the Qt Toolkit.
7
** This file may be distributed under the terms of the Q Public License
8
** as defined by Trolltech AS of Norway and appearing in the file
9
** LICENSE.QPL included in the packaging of this file.
11
** This file may be distributed and/or modified under the terms of the
12
** GNU General Public License version 2 as published by the Free Software
13
** Foundation and appearing in the file LICENSE.GPL included in the
14
** packaging of this file.
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
17
** information about Qt Commercial License Agreements.
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
21
** Contact info@trolltech.com if any conditions of this licensing are
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27
****************************************************************************/
29
#include "portingrules.h"
35
#include "qtsimplexml.h"
39
PortingRules *PortingRules::theInstance = 0;
41
void PortingRules::createInstance(QString xmlFilePath)
44
theInstance = new PortingRules(xmlFilePath);
47
PortingRules *PortingRules::instance()
52
cout << "Error: must create a PortingRules instance with"
53
<< "createInstance() before calling instance()" << endl;
58
void PortingRules::deleteInstance()
66
PortingRules::PortingRules(QString xmlFilePath)
68
parseXml(xmlFilePath);
71
QList<TokenReplacement*> PortingRules::getTokenReplacementRules()
73
if(tokenRules.isEmpty())
74
addLogWarning("Warning: token rules list is empty");
78
QStringList PortingRules::getHeaderList(QtVersion qtVersion)
80
if(qt3Headers.isEmpty() || qt4Headers.isEmpty())
81
addLogWarning("Warning: headers list is empty");
89
QHash<QByteArray, QByteArray> PortingRules::getNeededHeaders()
91
if(neededHeaders.isEmpty())
92
addLogWarning("Warning: needed headers list is empty");
96
QStringList PortingRules::getInheritsQt()
98
if(tokenRules.isEmpty())
99
addLogWarning("Warning: inheritsQtClass list is empty");
100
return inheritsQtClass;
103
QHash<QByteArray, QByteArray> PortingRules::getClassLibraryList()
105
if(classLibraryList.isEmpty())
106
addLogWarning("Warning: classLibraryList list is empty");
107
return classLibraryList;
110
Loads rule xml file given by fileName, and sets up data structures.
111
The rules can generally be divided into to types, replacement rules and
114
Replacement rules has the form Qt3Symobl -> Qt4Symbol
115
Info rules includes the NeedHeader, Qt3Header, Qt4Header, InhertitsQt
118
void PortingRules::parseXml(QString fileName)
120
QtSimpleXml *xmlPointer = loadXml(fileName);
121
QtSimpleXml &xml = *xmlPointer;
123
int ruleCount = xml["Rules"].numChildren();
126
for(int rule=0; rule<ruleCount; ++rule) {
127
QtSimpleXml ¤tRule = xml["Rules"][rule];
128
QString ruleType = currentRule.attribute("Type");
130
if(isReplacementRule(ruleType)) {
131
QString qt3Symbol = currentRule["Qt3"].text();
132
QString qt4Symbol = currentRule["Qt4"].text();
134
QString disable = currentRule.attribute("Disable");
135
if(disable == "True" || disable == "true") {
136
disableRule(currentRule);
140
if (isRuleDisabled(currentRule))
143
if(ruleType == "RenamedHeader") {
144
tokenRules.append(new IncludeTokenReplacement(
145
qt3Symbol.toLatin1(), qt4Symbol.toLatin1()));
146
} else if(ruleType == "RenamedClass" || ruleType == "RenamedToken" ) {
147
tokenRules.append(new ClassNameReplacement(
148
qt3Symbol.toLatin1(), qt4Symbol.toLatin1()));
149
} else if(ruleType == "RenamedEnumvalue" || ruleType == "RenamedType" ||
150
ruleType == "RenamedQtSymbol" ) {
151
checkScopeAddRule(currentRule);
153
} else if(ruleType == "NeedHeader") {
154
const QByteArray className = currentRule["Class"].text().toLatin1();
155
const QByteArray headerName = currentRule["Header"].text().toLatin1();
156
neededHeaders.insert(className, headerName);
158
else if(ruleType == "qt3Header") {
159
qt3Headers += currentRule.text();
161
else if(ruleType == "qt4Header") {
162
qt4Headers += currentRule.text();
164
else if(ruleType == "InheritsQt") {
165
inheritsQtClass += currentRule.text();
167
else if(ruleType == "Qt4Class") {
168
// Get library name, make it lowercase and chop of the "Qt" prefix.
169
const QByteArray libraryName = currentRule["Library"].text().toLatin1().toLower().mid(2);
170
classLibraryList.insert(currentRule["Name"].text().toLatin1(), libraryName);
174
QString includeFile = xml["Rules"]["Include"].text();
176
if(includeFile != QString()) {
177
QString resolvedIncludeFile = resolveFileName(fileName, includeFile);
178
if (!resolvedIncludeFile.isEmpty())
179
parseXml(resolvedIncludeFile);
186
Check if the rule in currentRule describes a qualified name
187
(like QButton::ToggleState). If so, create a scoped ScopedTokenReplacement,
188
else create a GenericTokenReplacement
190
void PortingRules::checkScopeAddRule(/*const */QtSimpleXml ¤tRule)
192
QByteArray oldToken = currentRule["Qt3"].text().toLatin1();
193
QByteArray newToken = currentRule["Qt4"].text().toLatin1();
195
if (oldToken.contains("::"))
196
tokenRules.append(new ScopedTokenReplacement(oldToken, newToken));
198
tokenRules.append(new GenericTokenReplacement(oldToken, newToken));
202
Loads the xml-file given by fileName into a new'ed QtSimpleXml, which is
205
QtSimpleXml *PortingRules::loadXml(const QString fileName) const
208
if(!f.open(QIODevice::ReadOnly)) {
209
qFatal("Could not find rule file %s", fileName.toLatin1().constData());
211
QtSimpleXml *xml = new QtSimpleXml();
212
if(!xml->setContent(&f))
213
addLogError(QByteArray("Xml parsing failed: ") + xml->errorString().toLatin1());
219
Resolves includeFilePath against currentFilePath. If currentFilePath
220
contains foo/bar.xml, and includeFilePath contains bar2.xml, the returned
221
result will be foo/bar2.xml. If includeFilePath is absolute, it is returned
224
QString PortingRules::resolveFileName(const QString currentFilePath,
225
const QString includeFilePath) const
227
if(QFileInfo(includeFilePath).isAbsolute())
228
return includeFilePath;
229
QString relativeDirectory = QFileInfo(currentFilePath).dir().dirName();
230
QString testFileName = relativeDirectory + "/" + includeFilePath;
231
if (QFile::exists(testFileName))
237
Checks if a rule is a replacement rule.
239
bool PortingRules::isReplacementRule(const QString ruleType) const
241
return (ruleType == "RenamedHeader" || ruleType == "RenamedClass" ||
242
ruleType == "RenamedToken" || ruleType == "RenamedEnumvalue" ||
243
ruleType == "RenamedType" || ruleType == "RenamedQtSymbol" );
247
Disables a replacement rule given by the replacementRule parameter
249
void PortingRules::disableRule(QtSimpleXml &replacementRule)
251
RuleDescription ruleDescription(replacementRule);
252
disabledRules.append(ruleDescription);
256
Checks if a replacement rule is disabled or not
258
bool PortingRules::isRuleDisabled(QtSimpleXml &replacementRule) const
260
RuleDescription ruleDescription(replacementRule);
261
return disabledRules.contains(ruleDescription);
265
Adds a warning to the global logger.
267
void PortingRules::addLogWarning(const QString text) const
269
Logger::instance()->addEntry(new PlainLogEntry("Warning", "Porting", text));
273
Adds an error to the global logger.
275
void PortingRules::addLogError(const QString text) const
277
Logger::instance()->addEntry(new PlainLogEntry("Error", "Porting", text));