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

« back to all changes in this revision

Viewing changes to tools/porting/src/tokenengine.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) 2004-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
#include "tokenengine.h"
 
29
 
 
30
namespace TokenEngine {
 
31
 
 
32
/*
 
33
    Add a container-global attribute.
 
34
*/
 
35
void TokenAttributes::addAttribute(const QByteArray &name,  const QByteArray &value)
 
36
{
 
37
    const QByteArray keyText = makeKeyText(-1, name);
 
38
    attributes.insert(keyText, value);
 
39
}
 
40
 
 
41
/*
 
42
     Retrieve container-global attribute.
 
43
*/
 
44
QByteArray TokenAttributes::attribute(const QByteArray &name) const
 
45
{
 
46
    const QByteArray keyText = makeKeyText(-1, name);
 
47
    return attributes.value(keyText);
 
48
}
 
49
 
 
50
/*
 
51
    Add an attribute. Note: Don't use names starting with a number, that will
 
52
    break the indexing.
 
53
*/
 
54
void TokenAttributes::addAttribute(const int index, const QByteArray &name, const QByteArray &value)
 
55
{
 
56
    const QByteArray keyText = makeKeyText(index, name);
 
57
    attributes.insert(keyText, value);
 
58
}
 
59
 
 
60
QByteArray TokenAttributes::attribute(const int index, const QByteArray &name) const
 
61
{
 
62
    const QByteArray keyText = makeKeyText(index, name);
 
63
    return attributes.value(keyText);
 
64
}
 
65
 
 
66
QByteArray TokenAttributes::makeKeyText(const int index, const QByteArray &name) const
 
67
{
 
68
    QByteArray indexText;
 
69
    return indexText.setNum(index) + name;
 
70
}
 
71
 
 
72
 
 
73
/*
 
74
     Construnct an empty TokenContainer.
 
75
*/
 
76
TokenContainer::TokenContainer()
 
77
{
 
78
    d = new TokenContainerData();
 
79
    d->typeInfo = 0;
 
80
}
 
81
 
 
82
/*
 
83
    Construnct a TokenContainer from data
 
84
*/
 
85
TokenContainer::TokenContainer(QByteArray text, QVector<Token> tokens, TypeInfo *typeInfo)
 
86
{
 
87
    d = new TokenContainerData();
 
88
    d->text = text;
 
89
    d->tokens = tokens;
 
90
    if(typeInfo == 0)
 
91
        d->typeInfo = new TypeInfo();
 
92
    else
 
93
        d->typeInfo = typeInfo;
 
94
}
 
95
 
 
96
int TokenContainer::count() const
 
97
{
 
98
    return d->tokens.count();
 
99
}
 
100
 
 
101
QByteArray TokenContainer::text(const int index) const
 
102
{
 
103
    Token token = d->tokens.at(index);
 
104
    return d->text.mid(token.start, token.length);
 
105
}
 
106
 
 
107
QByteArray TokenContainer::tempText(const int index) const
 
108
{
 
109
    Token token = d->tokens.at(index);
 
110
    return QByteArray::fromRawData(d->text.constData() + token.start, token.length);
 
111
}
 
112
 
 
113
QByteArray TokenContainer::fullText() const
 
114
{
 
115
    return d->text;
 
116
}
 
117
 
 
118
TokenContainer TokenContainer::tokenContainer(const int index) const
 
119
{
 
120
    Q_UNUSED(index);
 
121
    return *this;
 
122
}
 
123
 
 
124
Token TokenContainer::token(const int index) const
 
125
{
 
126
    return d->tokens.at(index);
 
127
}
 
128
 
 
129
TypeInfo *TokenContainer::typeInfo()
 
130
{
 
131
    return d->typeInfo;
 
132
}
 
133
 
 
134
TokenAttributes *TokenContainer::tokenAttributes()
 
135
{
 
136
    return d->tokenAttributes;
 
137
}
 
138
 
 
139
const TokenAttributes *TokenContainer::tokenAttributes() const
 
140
{
 
141
    return d->tokenAttributes;
 
142
}
 
143
 
 
144
/*
 
145
    Returns the line number for the given index.
 
146
*/
 
147
int TokenContainer::line(int index) const
 
148
{
 
149
    //This algorithm is a bit more complicated than it should be,
 
150
    //since we have to search for newlines inside comments.
 
151
    //(Comments are tokenized as one token)
 
152
    QByteArray contents = fullText();
 
153
    int pos=0;
 
154
    int lines=0;
 
155
    for(int t=0; t < index; ++t) {
 
156
        int tokenLength = d->tokens.at(t).length;
 
157
        if((tokenLength == 1) && (text(t) == "\n")) {
 
158
            ++lines;
 
159
        } else if(tokenLength > 2) {// 3 is the minimum size for a comment (// + newline)
 
160
            int newpos = d->tokens.at(t).length;
 
161
            for(int p = pos; p < newpos; ++p) {
 
162
                if(contents[p] == '\n')
 
163
                    ++lines;
 
164
            }
 
165
        }
 
166
        pos += d->tokens.at(t).length;
 
167
    }
 
168
    return lines;
 
169
}
 
170
 
 
171
/*
 
172
    Returns the column number for the given index.
 
173
*/
 
174
int TokenContainer::column(int index) const
 
175
{
 
176
    //Scan backwards, find \n.
 
177
    int chars = 0;
 
178
    int t = index;
 
179
    while (t>0) {
 
180
        if((d->tokens.at(t).length == 1) && (text(t) == "\n"))
 
181
            break;
 
182
        chars += d->tokens.at(t).length;
 
183
        --t;
 
184
    }
 
185
    return chars;
 
186
}
 
187
 
 
188
TokenTempRef TokenContainer::tokenTempRef(const int index) const
 
189
{
 
190
    Q_ASSERT(index < d->tokens.count());
 
191
    const Token token = d->tokens.at(index);
 
192
    return TokenTempRef(d->text.constData() + token.start, token.length);
 
193
}
 
194
 
 
195
QByteArray TokenSection::fullText() const
 
196
{
 
197
    QByteArray text;
 
198
    for (int t = m_start; t < m_start + m_count; ++t) {
 
199
        text += m_tokenContainer.text(t);
 
200
    }
 
201
    return text;
 
202
}
 
203
 
 
204
QByteArray TokenList::fullText() const
 
205
{
 
206
    QByteArray text;
 
207
    for (int t = 0; t < m_tokenList.count(); ++t) {
 
208
        text += m_tokenContainer.text(m_tokenList.at(t));
 
209
    }
 
210
    return text;
 
211
}
 
212
 
 
213
TokenSectionSequence::TokenSectionSequence(QVector<TokenSection> tokenSections)
 
214
:m_tokenSections(tokenSections), m_count(0)
 
215
{
 
216
    for(int s = 0; s < m_tokenSections.count(); ++s) {
 
217
        m_startIndexes.append(m_count);
 
218
        m_count += m_tokenSections.at(s).count();
 
219
    }
 
220
}
 
221
 
 
222
QByteArray TokenSectionSequence::fullText() const
 
223
{
 
224
    QByteArray text;
 
225
    foreach(TokenSection section, m_tokenSections) {
 
226
        text += section.fullText();
 
227
    }
 
228
    return text;
 
229
}
 
230
 
 
231
int TokenSectionSequence::count() const
 
232
{
 
233
    return m_count;
 
234
}
 
235
 
 
236
QVector<TokenSection> TokenSectionSequence::tokenSections() const
 
237
{
 
238
    return m_tokenSections;
 
239
}
 
240
 
 
241
QByteArray TokenSectionSequence::text(const int index) const
 
242
{
 
243
    const int sectionIndex = findSection(index);
 
244
    const int sectionInternalIndex = calculateInternalIndex(index, sectionIndex);
 
245
    return m_tokenSections.at(sectionIndex).text(sectionInternalIndex);
 
246
}
 
247
 
 
248
QByteArray TokenSectionSequence::tempText(const int index) const
 
249
{
 
250
    const int sectionIndex = findSection(index);
 
251
    const int sectionInternalIndex = calculateInternalIndex(index, sectionIndex);
 
252
    return m_tokenSections.at(sectionIndex).tempText(sectionInternalIndex);
 
253
}
 
254
 
 
255
 
 
256
TokenContainer TokenSectionSequence::tokenContainer(const int index) const
 
257
{
 
258
    const int sectionIndex = findSection(index);
 
259
    const int sectionInternalIndex = calculateInternalIndex(index, sectionIndex);
 
260
    return m_tokenSections.at(sectionIndex).tokenContainer(sectionInternalIndex);
 
261
}
 
262
 
 
263
int TokenSectionSequence::containerIndex(const int index) const
 
264
{
 
265
    const int sectionIndex = findSection(index);
 
266
    const int sectionInternalIndex = calculateInternalIndex(index, sectionIndex);
 
267
    return m_tokenSections.at(sectionIndex).containerIndex(sectionInternalIndex);
 
268
}
 
269
 
 
270
int TokenSectionSequence::findSection(const int index) const
 
271
{
 
272
    int c = 0;
 
273
    bool found = false;
 
274
    //Here we do a linear search through all collections in the list,
 
275
    //which could turn out to be to slow.
 
276
    while(!found && c < m_tokenSections.count()) {
 
277
        const int sectionEnd = m_startIndexes.at(c)
 
278
                                + m_tokenSections.at(c).count();
 
279
        if (index < sectionEnd)
 
280
            found = true;
 
281
        else
 
282
            ++c;
 
283
    }
 
284
    if(!found) {
 
285
        //error
 
286
        Q_ASSERT(0);
 
287
        return -1;
 
288
    }
 
289
    Q_ASSERT(c < m_tokenSections.count());
 
290
    return c;
 
291
}
 
292
 
 
293
int TokenSectionSequence::calculateInternalIndex(const int index, const int sectionIndex) const
 
294
{
 
295
    const int sectionInternalIndex =
 
296
        index - m_startIndexes.at(sectionIndex);
 
297
    Q_ASSERT(sectionInternalIndex < m_tokenSections.at(sectionIndex).count());
 
298
    return sectionInternalIndex;
 
299
}
 
300
 
 
301
 
 
302
TokenSectionSequenceIterator::TokenSectionSequenceIterator(const TokenSectionSequence &tokenSectionSequence)
 
303
:m_currentSection(0)
 
304
,m_currentToken(-1)
 
305
,m_numSections(tokenSectionSequence.m_tokenSections.count())
 
306
,m_tokenSectionSequence(tokenSectionSequence)
 
307
 
 
308
{ }
 
309
 
 
310
/*
 
311
    Resets the token iterator.
 
312
*/
 
313
void TokenSectionSequenceIterator::reset()
 
314
{
 
315
    m_currentSection = 0;
 
316
    m_currentToken = -1;
 
317
}
 
318
 
 
319
/*
 
320
    Advances the token iterator.
 
321
*/
 
322
bool TokenSectionSequenceIterator::nextToken()
 
323
{
 
324
    if(m_tokenSectionSequence.m_tokenSections.isEmpty())
 
325
        return false;
 
326
    ++m_currentToken;
 
327
    //check of we are past the end of the current section
 
328
    if(m_currentToken < m_tokenSectionSequence.m_tokenSections.at(m_currentSection).count())
 
329
        return true;
 
330
    //Advance to the next non-empty section.
 
331
    m_currentToken = 0;
 
332
    do {
 
333
        ++m_currentSection;
 
334
        //return false if no more sections
 
335
        if(m_currentSection >= m_numSections)
 
336
            return false;
 
337
    //skip empty sections
 
338
    } while(m_tokenSectionSequence.m_tokenSections.at(m_currentSection).count() == 0);
 
339
 
 
340
    return true;
 
341
}
 
342
 
 
343
/*
 
344
    Returns the text for the current token;
 
345
*/
 
346
QByteArray TokenSectionSequenceIterator::text() const
 
347
{
 
348
    return m_tokenSectionSequence.m_tokenSections.at(m_currentSection).text(m_currentToken);
 
349
}
 
350
 
 
351
/*
 
352
    Returns the text for the current token as a temporary QByteArray;
 
353
*/
 
354
QByteArray TokenSectionSequenceIterator::tempText() const
 
355
{
 
356
    return m_tokenSectionSequence.m_tokenSections.at(m_currentSection).tempText(m_currentToken);
 
357
}
 
358
 
 
359
/*
 
360
    Returns the container for the current token;
 
361
*/
 
362
TokenContainer TokenSectionSequenceIterator::tokenContainer() const
 
363
{
 
364
    return m_tokenSectionSequence.m_tokenSections.at(m_currentSection).tokenContainer(m_currentToken);
 
365
}
 
366
 
 
367
/*
 
368
    Returns the containerIndex for the current token;
 
369
*/
 
370
int TokenSectionSequenceIterator::containerIndex() const
 
371
{
 
372
    return m_tokenSectionSequence.m_tokenSections.at(m_currentSection).containerIndex(m_currentToken);
 
373
}
 
374
 
 
375
/*
 
376
    Returns a temporary token reference for the current token for the current token;
 
377
*/
 
378
TokenTempRef TokenSectionSequenceIterator::tokenTempRef() const
 
379
{
 
380
    return m_tokenSectionSequence.m_tokenSections.at(m_currentSection).tokenTempRef(m_currentToken);
 
381
}
 
382
 
 
383
 
 
384
} //namespace TokenEngine
 
385