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

« back to all changes in this revision

Viewing changes to qmake/generators/xmloutput.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 qmake 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 "xmloutput.h"
 
30
 
 
31
XmlOutput::XmlOutput(QTextStream &file, ConverstionType type)
 
32
    : xmlFile(file), indent("\t"), currentLevel(0), currentState(Bare), format(NewLine),
 
33
      conversion(type)
 
34
{
 
35
    tagStack.clear();
 
36
}
 
37
 
 
38
XmlOutput::~XmlOutput()
 
39
{
 
40
    closeAll();
 
41
}
 
42
 
 
43
// Settings ------------------------------------------------------------------
 
44
void XmlOutput::setIndentString(const QString &indentString)
 
45
{
 
46
    indent = indentString;
 
47
}
 
48
 
 
49
QString XmlOutput::indentString()
 
50
{
 
51
    return indent;
 
52
}
 
53
 
 
54
void XmlOutput::setIndentLevel(int level)
 
55
{
 
56
    currentLevel = level;
 
57
}
 
58
 
 
59
int XmlOutput::indentLevel()
 
60
{
 
61
    return currentLevel;
 
62
}
 
63
 
 
64
void XmlOutput::setState(XMLState state)
 
65
{
 
66
    currentState = state;
 
67
}
 
68
 
 
69
XmlOutput::XMLState XmlOutput::state()
 
70
{
 
71
    return currentState;
 
72
}
 
73
 
 
74
void XmlOutput::updateIndent()
 
75
{
 
76
    currentIndent.clear();
 
77
    for (int i = 0; i < currentLevel; ++i)
 
78
        currentIndent.append(indent);
 
79
}
 
80
 
 
81
void XmlOutput::increaseIndent()
 
82
{
 
83
    ++currentLevel;
 
84
    updateIndent();
 
85
}
 
86
 
 
87
void XmlOutput::decreaseIndent()
 
88
{
 
89
    if (currentLevel)
 
90
        --currentLevel;
 
91
    updateIndent();
 
92
    if (!currentLevel)
 
93
        currentState = Bare;
 
94
}
 
95
 
 
96
QString XmlOutput::doConversion(const QString &text)
 
97
{
 
98
    if (!text.count())
 
99
        return QString();
 
100
    else if (conversion == NoConversion)
 
101
        return text;
 
102
 
 
103
    QString output(text);
 
104
    if (conversion == XMLConversion) {
 
105
        output.replace('&', "&amp;");
 
106
        output.replace('\"', "&quot;");
 
107
        output.replace('\'', "&apos;");
 
108
    } else if (conversion == EscapeConversion) {
 
109
        output.replace('\"', "\\\"");
 
110
        output.replace('\'', "\\\'");
 
111
    }
 
112
    return output;
 
113
}
 
114
 
 
115
// Stream functions ----------------------------------------------------------
 
116
XmlOutput& XmlOutput::operator<<(const QString& o)
 
117
{
 
118
    return operator<<(data(o));
 
119
}
 
120
 
 
121
XmlOutput& XmlOutput::operator<<(const xml_output& o)
 
122
{
 
123
    switch(o.xo_type) {
 
124
    case tNothing:
 
125
        break;
 
126
    case tRaw:
 
127
        addRaw(o.xo_text);
 
128
        break;
 
129
    case tDeclaration:
 
130
        addDeclaration(o.xo_text, o.xo_value);
 
131
        break;
 
132
    case tTag:
 
133
        newTagOpen(o.xo_text);
 
134
        break;
 
135
    case tCloseTag:
 
136
        if (o.xo_value.count())
 
137
            closeAll();
 
138
        else if (o.xo_text.count())
 
139
            closeTo(o.xo_text);
 
140
        else
 
141
            closeTag();
 
142
        break;
 
143
    case tAttribute:
 
144
        addAttribute(o.xo_text, o.xo_value);
 
145
        break;
 
146
    case tData:
 
147
        {
 
148
            // Special case to be able to close tag in normal
 
149
            // way ("</tag>", not "/>") without using addRaw()..
 
150
            if (!o.xo_text.count()) {
 
151
                closeOpen();
 
152
                break;
 
153
            }
 
154
            QString output = doConversion(o.xo_text);
 
155
            output.replace('\n', "\n" + currentIndent);
 
156
            addRaw(QString("\n%1%2").arg(currentIndent).arg(output));
 
157
        }
 
158
        break;
 
159
    case tComment:
 
160
        {
 
161
            QString output("<!--%1-->");
 
162
            addRaw(output.arg(o.xo_text));
 
163
        }
 
164
        break;
 
165
    case tCDATA:
 
166
        {
 
167
            QString output("<![CDATA[\n%1\n]]>");
 
168
            addRaw(output.arg(o.xo_text));
 
169
        }
 
170
        break;
 
171
    }
 
172
    return *this;
 
173
}
 
174
 
 
175
 
 
176
// Output functions ----------------------------------------------------------
 
177
void XmlOutput::newTag(const QString &tag)
 
178
{
 
179
    Q_ASSERT_X(tag.count(), "XmlOutput", "Cannot open an empty tag");
 
180
    newTagOpen(tag);
 
181
    closeOpen();
 
182
}
 
183
 
 
184
void XmlOutput::newTagOpen(const QString &tag)
 
185
{
 
186
    Q_ASSERT_X(tag.count(), "XmlOutput", "Cannot open an empty tag");
 
187
    closeOpen();
 
188
 
 
189
    if (format == NewLine)
 
190
        xmlFile << endl << currentIndent;
 
191
    xmlFile << '<' << doConversion(tag);
 
192
    currentState = Attribute;
 
193
    tagStack.append(tag);
 
194
    increaseIndent(); // ---> indent
 
195
}
 
196
 
 
197
void XmlOutput::closeOpen()
 
198
{
 
199
    switch(currentState) {
 
200
        case Bare:
 
201
        case Tag:
 
202
            return;
 
203
        case Attribute:
 
204
            break;
 
205
    }
 
206
    xmlFile << '>';
 
207
    currentState = Tag;
 
208
}
 
209
 
 
210
void XmlOutput::closeTag()
 
211
{
 
212
    switch(currentState) {
 
213
        case Bare:
 
214
            if (tagStack.count())
 
215
                //warn_msg(WarnLogic, "<Root>: Cannot close tag in Bare state, %d tags on stack", tagStack.count());
 
216
                qDebug("<Root>: Cannot close tag in Bare state, %d tags on stack", tagStack.count());
 
217
            else
 
218
                //warn_msg(WarnLogic, "<Root>: Cannot close tag, no tags on stack");
 
219
                qDebug("<Root>: Cannot close tag, no tags on stack");
 
220
            return;
 
221
        case Tag:
 
222
            decreaseIndent(); // <--- Pre-decrease indent
 
223
            if (format == NewLine)
 
224
                xmlFile << endl << currentIndent;
 
225
            xmlFile << "</" << doConversion(tagStack.last()) << '>';
 
226
            tagStack.pop_back();
 
227
            break;
 
228
        case Attribute:
 
229
            xmlFile << "/>";
 
230
            tagStack.pop_back();
 
231
            currentState = Tag;
 
232
            decreaseIndent(); // <--- Post-decrease indent
 
233
            break;
 
234
    }
 
235
}
 
236
 
 
237
void XmlOutput::closeTo(const QString &tag)
 
238
{
 
239
    bool cont = true;
 
240
    if (!tagStack.contains(tag) && tag != QString()) {
 
241
        //warn_msg(WarnLogic, "<%s>: Cannot close to tag <%s>, not on stack", tagStack.last().latin1(), tag.latin1());
 
242
        qDebug("<%s>: Cannot close to tag <%s>, not on stack", tagStack.last().toLatin1().constData(), tag.toLatin1().constData());
 
243
        return;
 
244
    }
 
245
    int left = tagStack.count();
 
246
    while (left-- && cont) {
 
247
        cont = tagStack.last().compare(tag) != 0;
 
248
        closeTag();
 
249
    }
 
250
}
 
251
 
 
252
void XmlOutput::closeAll()
 
253
{
 
254
    if (!tagStack.count())
 
255
        return;
 
256
    closeTo(QString());
 
257
}
 
258
 
 
259
void XmlOutput::addDeclaration(const QString &version, const QString &encoding)
 
260
{
 
261
    switch(currentState) {
 
262
        case Bare:
 
263
            break;
 
264
        case Tag:
 
265
        case Attribute:
 
266
            //warn_msg(WarnLogic, "<%s>: Cannot add declaration when not in bare state", tagStack.last().toLatin1().constData());
 
267
            qDebug("<%s>: Cannot add declaration when not in bare state", tagStack.last().toLatin1().constData());
 
268
            return;
 
269
    }
 
270
    QString outData = QString("<?xml version=\"%1\" encoding = \"%2\"?>")
 
271
                              .arg(doConversion(version))
 
272
                              .arg(doConversion(encoding));
 
273
    addRaw(outData);
 
274
}
 
275
 
 
276
void XmlOutput::addRaw(const QString &rawText)
 
277
{
 
278
    closeOpen();
 
279
    xmlFile << rawText;
 
280
}
 
281
 
 
282
void XmlOutput::addAttribute(const QString &attribute, const QString &value)
 
283
{
 
284
     switch(currentState) {
 
285
        case Bare:
 
286
        case Tag:
 
287
            //warn_msg(WarnLogic, "<%s>: Cannot add attribute since tags not open", tagStack.last().toLatin1().constData());
 
288
            qDebug("<%s>: Cannot add attribute (%s) since tag's not open",
 
289
                   (tagStack.count() ? tagStack.last().toLatin1().constData() : "Root"),
 
290
                   attribute.toLatin1().constData());
 
291
            return;
 
292
        case Attribute:
 
293
            break;
 
294
    }
 
295
    if (format == NewLine)
 
296
        xmlFile << endl;
 
297
    xmlFile << currentIndent << doConversion(attribute) << "=\"" << doConversion(value) << "\"";
 
298
}
 
299