~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to tools/porting/src/portingrules.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-08-24 04:09:09 UTC
  • Revision ID: james.westby@ubuntu.com-20050824040909-xmxe9jfr4a0w5671
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
 
4
**
 
5
** This file is part of the porting application of the Qt Toolkit.
 
6
**
 
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.
 
10
**
 
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.
 
15
**
 
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.
 
20
**
 
21
** Contact info@trolltech.com if any conditions of this licensing are
 
22
** not clear to you.
 
23
**
 
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.
 
26
**
 
27
****************************************************************************/
 
28
 
 
29
#include "portingrules.h"
 
30
#include <QFile>
 
31
#include <QFileInfo>
 
32
#include <QDir>
 
33
#include <iostream>
 
34
#include "logger.h"
 
35
#include "qtsimplexml.h"
 
36
using std::cout;
 
37
using std::endl;
 
38
 
 
39
PortingRules *PortingRules::theInstance  = 0;
 
40
 
 
41
void PortingRules::createInstance(QString xmlFilePath)
 
42
{
 
43
    deleteInstance();
 
44
    theInstance  = new PortingRules(xmlFilePath);
 
45
}
 
46
 
 
47
PortingRules *PortingRules::instance()
 
48
{
 
49
    if(theInstance) {
 
50
        return theInstance;
 
51
    } else {
 
52
        cout << "Error: must create a PortingRules instance with"
 
53
             << "createInstance() before calling instance()" << endl;
 
54
        return 0;
 
55
    }
 
56
}
 
57
 
 
58
void PortingRules::deleteInstance()
 
59
{
 
60
    if(theInstance) {
 
61
        delete theInstance;
 
62
        theInstance = 0;
 
63
    }
 
64
}
 
65
 
 
66
PortingRules::PortingRules(QString xmlFilePath)
 
67
{
 
68
    parseXml(xmlFilePath);
 
69
}
 
70
 
 
71
QList<TokenReplacement*> PortingRules::getTokenReplacementRules()
 
72
{
 
73
    if(tokenRules.isEmpty())
 
74
         addLogWarning("Warning: token rules list is empty");
 
75
    return tokenRules;
 
76
}
 
77
 
 
78
QStringList PortingRules::getHeaderList(QtVersion qtVersion)
 
79
{
 
80
    if(qt3Headers.isEmpty() || qt4Headers.isEmpty())
 
81
         addLogWarning("Warning: headers list is empty");
 
82
 
 
83
    if (qtVersion==Qt3)
 
84
        return qt3Headers;
 
85
    else //Qt4
 
86
        return qt4Headers;
 
87
}
 
88
 
 
89
QHash<QByteArray, QByteArray> PortingRules::getNeededHeaders()
 
90
{
 
91
    if(neededHeaders.isEmpty())
 
92
         addLogWarning("Warning: needed headers list is empty");
 
93
    return neededHeaders;
 
94
}
 
95
 
 
96
QStringList PortingRules::getInheritsQt()
 
97
{
 
98
    if(tokenRules.isEmpty())
 
99
        addLogWarning("Warning: inheritsQtClass list is empty");
 
100
    return inheritsQtClass;
 
101
}
 
102
 
 
103
QHash<QByteArray, QByteArray> PortingRules::getClassLibraryList()
 
104
{
 
105
    if(classLibraryList.isEmpty())
 
106
        addLogWarning("Warning: classLibraryList list is empty");
 
107
    return classLibraryList;
 
108
}
 
109
/*
 
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
 
112
    info rules.
 
113
 
 
114
    Replacement rules has the form Qt3Symobl -> Qt4Symbol
 
115
    Info rules includes the NeedHeader, Qt3Header, Qt4Header, InhertitsQt
 
116
    rule types.
 
117
*/
 
118
void PortingRules::parseXml(QString fileName)
 
119
{
 
120
    QtSimpleXml *xmlPointer = loadXml(fileName);
 
121
    QtSimpleXml &xml = *xmlPointer;
 
122
 
 
123
    int ruleCount = xml["Rules"].numChildren();
 
124
    ++ruleCount;
 
125
 
 
126
    for(int rule=0; rule<ruleCount; ++rule) {
 
127
        QtSimpleXml &currentRule = xml["Rules"][rule];
 
128
        QString ruleType = currentRule.attribute("Type");
 
129
 
 
130
        if(isReplacementRule(ruleType)) {
 
131
            QString qt3Symbol = currentRule["Qt3"].text();
 
132
            QString qt4Symbol = currentRule["Qt4"].text();
 
133
 
 
134
            QString disable = currentRule.attribute("Disable");
 
135
            if(disable == "True" || disable == "true") {
 
136
                disableRule(currentRule);
 
137
                continue;
 
138
            }
 
139
 
 
140
            if (isRuleDisabled(currentRule))
 
141
                continue;
 
142
 
 
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);
 
152
            }
 
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);
 
157
        }
 
158
        else if(ruleType == "qt3Header") {
 
159
            qt3Headers += currentRule.text();
 
160
        }
 
161
        else if(ruleType == "qt4Header") {
 
162
            qt4Headers += currentRule.text();
 
163
        }
 
164
        else if(ruleType == "InheritsQt") {
 
165
            inheritsQtClass += currentRule.text();
 
166
        }
 
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);
 
171
        }
 
172
    }
 
173
 
 
174
    QString includeFile = xml["Rules"]["Include"].text();
 
175
 
 
176
    if(includeFile != QString()) {
 
177
        QString resolvedIncludeFile = resolveFileName(fileName, includeFile);
 
178
        if (!resolvedIncludeFile.isEmpty())
 
179
            parseXml(resolvedIncludeFile);
 
180
    }
 
181
 
 
182
    delete xmlPointer;
 
183
}
 
184
 
 
185
/*
 
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
 
189
*/
 
190
void PortingRules::checkScopeAddRule(/*const */QtSimpleXml &currentRule)
 
191
{
 
192
    QByteArray oldToken = currentRule["Qt3"].text().toLatin1();
 
193
    QByteArray newToken = currentRule["Qt4"].text().toLatin1();
 
194
 
 
195
    if (oldToken.contains("::"))
 
196
        tokenRules.append(new ScopedTokenReplacement(oldToken, newToken));
 
197
    else
 
198
        tokenRules.append(new GenericTokenReplacement(oldToken, newToken));
 
199
}
 
200
 
 
201
/*
 
202
    Loads the xml-file given by fileName into a new'ed QtSimpleXml, which is
 
203
    returned by pointer.
 
204
*/
 
205
QtSimpleXml *PortingRules::loadXml(const QString fileName) const
 
206
{
 
207
    QFile f(fileName);
 
208
    if(!f.open(QIODevice::ReadOnly)) {
 
209
        qFatal("Could not find rule file %s", fileName.toLatin1().constData());
 
210
    }
 
211
    QtSimpleXml *xml = new QtSimpleXml();
 
212
    if(!xml->setContent(&f))
 
213
        addLogError(QByteArray("Xml parsing failed: ") + xml->errorString().toLatin1());
 
214
 
 
215
    return xml;
 
216
}
 
217
 
 
218
/*
 
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
 
222
    unmodified.
 
223
*/
 
224
QString PortingRules::resolveFileName(const QString currentFilePath,
 
225
                                      const QString includeFilePath) const
 
226
{
 
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))
 
232
        return testFileName;
 
233
 
 
234
    return QString();
 
235
}
 
236
/*
 
237
    Checks if a rule is a replacement rule.
 
238
*/
 
239
bool PortingRules::isReplacementRule(const QString ruleType) const
 
240
{
 
241
    return (ruleType == "RenamedHeader" || ruleType == "RenamedClass" ||
 
242
            ruleType == "RenamedToken" || ruleType == "RenamedEnumvalue" ||
 
243
            ruleType == "RenamedType" || ruleType == "RenamedQtSymbol" );
 
244
}
 
245
 
 
246
/*
 
247
    Disables a replacement rule given by the replacementRule parameter
 
248
*/
 
249
void PortingRules::disableRule(QtSimpleXml &replacementRule)
 
250
{
 
251
    RuleDescription ruleDescription(replacementRule);
 
252
    disabledRules.append(ruleDescription);
 
253
}
 
254
 
 
255
/*
 
256
    Checks if a replacement rule is disabled or not
 
257
*/
 
258
bool PortingRules::isRuleDisabled(QtSimpleXml &replacementRule) const
 
259
{
 
260
    RuleDescription ruleDescription(replacementRule);
 
261
    return disabledRules.contains(ruleDescription);
 
262
}
 
263
 
 
264
/*
 
265
    Adds a warning to the global logger.
 
266
*/
 
267
void PortingRules::addLogWarning(const QString text) const
 
268
{
 
269
    Logger::instance()->addEntry(new PlainLogEntry("Warning", "Porting", text));
 
270
}
 
271
 
 
272
/*
 
273
    Adds an error to the global logger.
 
274
*/
 
275
void PortingRules::addLogError(const QString text) const
 
276
{
 
277
    Logger::instance()->addEntry(new PlainLogEntry("Error", "Porting", text));
 
278
}