~ubuntu-branches/ubuntu/precise/geany/precise-201203210702

« back to all changes in this revision

Viewing changes to scintilla/PerLine.cxx

  • Committer: Package Import Robot
  • Author(s): Chow Loong Jin
  • Date: 2011-12-10 07:43:26 UTC
  • mfrom: (3.3.7 sid)
  • Revision ID: package-import@ubuntu.com-20111210074326-s8yqbew5i20h33tf
Tags: 0.21-1ubuntu1
* Merge from Debian Unstable, remaining changes:
  - debian/patches/20_use_evince_viewer.patch:
     + use evince as viewer for pdf and dvi files
  - debian/patches/20_use_x_terminal_emulator.patch:
     + use x-terminal-emulator as terminal
  - debian/control
     + Add breaks on geany-plugins-common << 0.20
* Also fixes bugs:
  - Filter for MATLAB/Octave files filters everythign (LP: 885505)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// Scintilla source code edit control
2
 
/** @file PerLine.cxx
3
 
 ** Manages data associated with each line of the document
4
 
 **/
5
 
// Copyright 1998-2009 by Neil Hodgson <neilh@scintilla.org>
6
 
// The License.txt file describes the conditions under which this software may be distributed.
7
 
 
8
 
#include <string.h>
9
 
 
10
 
#include "Platform.h"
11
 
 
12
 
#include "Scintilla.h"
13
 
#include "SplitVector.h"
14
 
#include "Partitioning.h"
15
 
#include "CellBuffer.h"
16
 
#include "PerLine.h"
17
 
 
18
 
#ifdef SCI_NAMESPACE
19
 
using namespace Scintilla;
20
 
#endif
21
 
 
22
 
MarkerHandleSet::MarkerHandleSet() {
23
 
        root = 0;
24
 
}
25
 
 
26
 
MarkerHandleSet::~MarkerHandleSet() {
27
 
        MarkerHandleNumber *mhn = root;
28
 
        while (mhn) {
29
 
                MarkerHandleNumber *mhnToFree = mhn;
30
 
                mhn = mhn->next;
31
 
                delete mhnToFree;
32
 
        }
33
 
        root = 0;
34
 
}
35
 
 
36
 
int MarkerHandleSet::Length() const {
37
 
        int c = 0;
38
 
        MarkerHandleNumber *mhn = root;
39
 
        while (mhn) {
40
 
                c++;
41
 
                mhn = mhn->next;
42
 
        }
43
 
        return c;
44
 
}
45
 
 
46
 
int MarkerHandleSet::NumberFromHandle(int handle) const {
47
 
        MarkerHandleNumber *mhn = root;
48
 
        while (mhn) {
49
 
                if (mhn->handle == handle) {
50
 
                        return mhn->number;
51
 
                }
52
 
                mhn = mhn->next;
53
 
        }
54
 
        return - 1;
55
 
}
56
 
 
57
 
int MarkerHandleSet::MarkValue() const {
58
 
        unsigned int m = 0;
59
 
        MarkerHandleNumber *mhn = root;
60
 
        while (mhn) {
61
 
                m |= (1 << mhn->number);
62
 
                mhn = mhn->next;
63
 
        }
64
 
        return m;
65
 
}
66
 
 
67
 
bool MarkerHandleSet::Contains(int handle) const {
68
 
        MarkerHandleNumber *mhn = root;
69
 
        while (mhn) {
70
 
                if (mhn->handle == handle) {
71
 
                        return true;
72
 
                }
73
 
                mhn = mhn->next;
74
 
        }
75
 
        return false;
76
 
}
77
 
 
78
 
bool MarkerHandleSet::InsertHandle(int handle, int markerNum) {
79
 
        MarkerHandleNumber *mhn = new MarkerHandleNumber;
80
 
        if (!mhn)
81
 
                return false;
82
 
        mhn->handle = handle;
83
 
        mhn->number = markerNum;
84
 
        mhn->next = root;
85
 
        root = mhn;
86
 
        return true;
87
 
}
88
 
 
89
 
void MarkerHandleSet::RemoveHandle(int handle) {
90
 
        MarkerHandleNumber **pmhn = &root;
91
 
        while (*pmhn) {
92
 
                MarkerHandleNumber *mhn = *pmhn;
93
 
                if (mhn->handle == handle) {
94
 
                        *pmhn = mhn->next;
95
 
                        delete mhn;
96
 
                        return;
97
 
                }
98
 
                pmhn = &((*pmhn)->next);
99
 
        }
100
 
}
101
 
 
102
 
bool MarkerHandleSet::RemoveNumber(int markerNum) {
103
 
        bool performedDeletion = false;
104
 
        MarkerHandleNumber **pmhn = &root;
105
 
        while (*pmhn) {
106
 
                MarkerHandleNumber *mhn = *pmhn;
107
 
                if (mhn->number == markerNum) {
108
 
                        *pmhn = mhn->next;
109
 
                        delete mhn;
110
 
                        performedDeletion = true;
111
 
                } else {
112
 
                        pmhn = &((*pmhn)->next);
113
 
                }
114
 
        }
115
 
        return performedDeletion;
116
 
}
117
 
 
118
 
void MarkerHandleSet::CombineWith(MarkerHandleSet *other) {
119
 
        MarkerHandleNumber **pmhn = &root;
120
 
        while (*pmhn) {
121
 
                pmhn = &((*pmhn)->next);
122
 
        }
123
 
        *pmhn = other->root;
124
 
        other->root = 0;
125
 
}
126
 
 
127
 
LineMarkers::~LineMarkers() {
128
 
        Init();
129
 
}
130
 
 
131
 
void LineMarkers::Init() {
132
 
        for (int line = 0; line < markers.Length(); line++) {
133
 
                delete markers[line];
134
 
                markers[line] = 0;
135
 
        }
136
 
        markers.DeleteAll();
137
 
}
138
 
 
139
 
void LineMarkers::InsertLine(int line) {
140
 
        if (markers.Length()) {
141
 
                markers.Insert(line, 0);
142
 
        }
143
 
}
144
 
 
145
 
void LineMarkers::RemoveLine(int line) {
146
 
        // Retain the markers from the deleted line by oring them into the previous line
147
 
        if (markers.Length()) {
148
 
                if (line > 0) {
149
 
                        MergeMarkers(line - 1);
150
 
                }
151
 
                markers.Delete(line);
152
 
        }
153
 
}
154
 
 
155
 
int LineMarkers::LineFromHandle(int markerHandle) {
156
 
        if (markers.Length()) {
157
 
                for (int line = 0; line < markers.Length(); line++) {
158
 
                        if (markers[line]) {
159
 
                                if (markers[line]->Contains(markerHandle)) {
160
 
                                        return line;
161
 
                                }
162
 
                        }
163
 
                }
164
 
        }
165
 
        return -1;
166
 
}
167
 
 
168
 
void LineMarkers::MergeMarkers(int pos) {
169
 
        if (markers[pos + 1] != NULL) {
170
 
                if (markers[pos] == NULL)
171
 
                        markers[pos] = new MarkerHandleSet;
172
 
                markers[pos]->CombineWith(markers[pos + 1]);
173
 
                delete markers[pos + 1];
174
 
                markers[pos + 1] = NULL;
175
 
        }
176
 
}
177
 
 
178
 
int LineMarkers::MarkValue(int line) {
179
 
        if (markers.Length() && (line >= 0) && (line < markers.Length()) && markers[line])
180
 
                return markers[line]->MarkValue();
181
 
        else
182
 
                return 0;
183
 
}
184
 
 
185
 
int LineMarkers::AddMark(int line, int markerNum, int lines) {
186
 
        handleCurrent++;
187
 
        if (!markers.Length()) {
188
 
                // No existing markers so allocate one element per line
189
 
                markers.InsertValue(0, lines, 0);
190
 
        }
191
 
        if (line >= markers.Length()) {
192
 
                return -1;
193
 
        }
194
 
        if (!markers[line]) {
195
 
                // Need new structure to hold marker handle
196
 
                markers[line] = new MarkerHandleSet();
197
 
                if (!markers[line])
198
 
                        return -1;
199
 
        }
200
 
        markers[line]->InsertHandle(handleCurrent, markerNum);
201
 
 
202
 
        return handleCurrent;
203
 
}
204
 
 
205
 
void LineMarkers::DeleteMark(int line, int markerNum, bool all) {
206
 
        if (markers.Length() && (line >= 0) && (line < markers.Length()) && markers[line]) {
207
 
                if (markerNum == -1) {
208
 
                        delete markers[line];
209
 
                        markers[line] = NULL;
210
 
                } else {
211
 
                        bool performedDeletion = markers[line]->RemoveNumber(markerNum);
212
 
                        while (all && performedDeletion) {
213
 
                                performedDeletion = markers[line]->RemoveNumber(markerNum);
214
 
                        }
215
 
                        if (markers[line]->Length() == 0) {
216
 
                                delete markers[line];
217
 
                                markers[line] = NULL;
218
 
                        }
219
 
                }
220
 
        }
221
 
}
222
 
 
223
 
void LineMarkers::DeleteMarkFromHandle(int markerHandle) {
224
 
        int line = LineFromHandle(markerHandle);
225
 
        if (line >= 0) {
226
 
                markers[line]->RemoveHandle(markerHandle);
227
 
                if (markers[line]->Length() == 0) {
228
 
                        delete markers[line];
229
 
                        markers[line] = NULL;
230
 
                }
231
 
        }
232
 
}
233
 
 
234
 
LineLevels::~LineLevels() {
235
 
}
236
 
 
237
 
void LineLevels::Init() {
238
 
        levels.DeleteAll();
239
 
}
240
 
 
241
 
void LineLevels::InsertLine(int line) {
242
 
        if (levels.Length()) {
243
 
                int level = SC_FOLDLEVELBASE;
244
 
                if ((line > 0) && (line < levels.Length())) {
245
 
                        level = levels[line-1] & ~SC_FOLDLEVELWHITEFLAG;
246
 
                }
247
 
                levels.InsertValue(line, 1, level);
248
 
        }
249
 
}
250
 
 
251
 
void LineLevels::RemoveLine(int line) {
252
 
        if (levels.Length()) {
253
 
                // Move up following lines but merge header flag from this line
254
 
                // to line before to avoid a temporary disappearence causing expansion.
255
 
                int firstHeader = levels[line] & SC_FOLDLEVELHEADERFLAG;
256
 
                levels.Delete(line);
257
 
                if (line == levels.Length()-1) // Last line loses the header flag
258
 
                        levels[line-1] &= ~SC_FOLDLEVELHEADERFLAG;
259
 
                else if (line > 0)
260
 
                        levels[line-1] |= firstHeader;
261
 
        }
262
 
}
263
 
 
264
 
void LineLevels::ExpandLevels(int sizeNew) {
265
 
        levels.InsertValue(levels.Length(), sizeNew - levels.Length(), SC_FOLDLEVELBASE);
266
 
}
267
 
 
268
 
void LineLevels::ClearLevels() {
269
 
        levels.DeleteAll();
270
 
}
271
 
 
272
 
int LineLevels::SetLevel(int line, int level, int lines) {
273
 
        int prev = 0;
274
 
        if ((line >= 0) && (line < lines)) {
275
 
                if (!levels.Length()) {
276
 
                        ExpandLevels(lines + 1);
277
 
                }
278
 
                prev = levels[line];
279
 
                if (prev != level) {
280
 
                        levels[line] = level;
281
 
                }
282
 
        }
283
 
        return prev;
284
 
}
285
 
 
286
 
int LineLevels::GetLevel(int line) {
287
 
        if (levels.Length() && (line >= 0) && (line < levels.Length())) {
288
 
                return levels[line];
289
 
        } else {
290
 
                return SC_FOLDLEVELBASE;
291
 
        }
292
 
}
293
 
 
294
 
LineState::~LineState() {
295
 
}
296
 
 
297
 
void LineState::Init() {
298
 
        lineStates.DeleteAll();
299
 
}
300
 
 
301
 
void LineState::InsertLine(int line) {
302
 
        if (lineStates.Length()) {
303
 
                lineStates.EnsureLength(line);
304
 
                lineStates.Insert(line, 0);
305
 
        }
306
 
}
307
 
 
308
 
void LineState::RemoveLine(int line) {
309
 
        if (lineStates.Length() > line) {
310
 
                lineStates.Delete(line);
311
 
        }
312
 
}
313
 
 
314
 
int LineState::SetLineState(int line, int state) {
315
 
        lineStates.EnsureLength(line + 1);
316
 
        int stateOld = lineStates[line];
317
 
        lineStates[line] = state;
318
 
        return stateOld;
319
 
}
320
 
 
321
 
int LineState::GetLineState(int line) {
322
 
        lineStates.EnsureLength(line + 1);
323
 
        return lineStates[line];
324
 
}
325
 
 
326
 
int LineState::GetMaxLineState() {
327
 
        return lineStates.Length();
328
 
}
329
 
 
330
 
static int NumberLines(const char *text) {
331
 
        if (text) {
332
 
                int newLines = 0;
333
 
                while (*text) {
334
 
                        if (*text == '\n')
335
 
                                newLines++;
336
 
                        text++;
337
 
                }
338
 
                return newLines+1;
339
 
        } else {
340
 
                return 0;
341
 
        }
342
 
}
343
 
 
344
 
// Each allocated LineAnnotation is a char array which starts with an AnnotationHeader
345
 
// and then has text and optional styles.
346
 
 
347
 
static const int IndividualStyles = 0x100;
348
 
 
349
 
struct AnnotationHeader {
350
 
        short style;    // Style IndividualStyles implies array of styles
351
 
        short lines;
352
 
        int length;
353
 
};
354
 
 
355
 
LineAnnotation::~LineAnnotation() {
356
 
        ClearAll();
357
 
}
358
 
 
359
 
void LineAnnotation::Init() {
360
 
        ClearAll();
361
 
}
362
 
 
363
 
void LineAnnotation::InsertLine(int line) {
364
 
        if (annotations.Length()) {
365
 
                annotations.EnsureLength(line);
366
 
                annotations.Insert(line, 0);
367
 
        }
368
 
}
369
 
 
370
 
void LineAnnotation::RemoveLine(int line) {
371
 
        if (annotations.Length() && (line < annotations.Length())) {
372
 
                delete []annotations[line];
373
 
                annotations.Delete(line);
374
 
        }
375
 
}
376
 
 
377
 
bool LineAnnotation::AnySet() const {
378
 
        return annotations.Length() > 0;
379
 
}
380
 
 
381
 
bool LineAnnotation::MultipleStyles(int line) const {
382
 
        if (annotations.Length() && (line < annotations.Length()) && annotations[line])
383
 
                return reinterpret_cast<AnnotationHeader *>(annotations[line])->style == IndividualStyles;
384
 
        else
385
 
                return 0;
386
 
}
387
 
 
388
 
int LineAnnotation::Style(int line) {
389
 
        if (annotations.Length() && (line < annotations.Length()) && annotations[line])
390
 
                return reinterpret_cast<AnnotationHeader *>(annotations[line])->style;
391
 
        else
392
 
                return 0;
393
 
}
394
 
 
395
 
const char *LineAnnotation::Text(int line) const {
396
 
        if (annotations.Length() && (line < annotations.Length()) && annotations[line])
397
 
                return annotations[line]+sizeof(AnnotationHeader);
398
 
        else
399
 
                return 0;
400
 
}
401
 
 
402
 
const unsigned char *LineAnnotation::Styles(int line) const {
403
 
        if (annotations.Length() && (line < annotations.Length()) && annotations[line] && MultipleStyles(line))
404
 
                return reinterpret_cast<unsigned char *>(annotations[line] + sizeof(AnnotationHeader) + Length(line));
405
 
        else
406
 
                return 0;
407
 
}
408
 
 
409
 
static char *AllocateAnnotation(int length, int style) {
410
 
        size_t len = sizeof(AnnotationHeader) + length + ((style == IndividualStyles) ? length : 0);
411
 
        char *ret = new char[len];
412
 
        memset(ret, 0, len);
413
 
        return ret;
414
 
}
415
 
 
416
 
void LineAnnotation::SetText(int line, const char *text) {
417
 
        if (text) {
418
 
                annotations.EnsureLength(line+1);
419
 
                int style = Style(line);
420
 
                if (annotations[line]) {
421
 
                        delete []annotations[line];
422
 
                }
423
 
                annotations[line] = AllocateAnnotation(strlen(text), style);
424
 
                AnnotationHeader *pah = reinterpret_cast<AnnotationHeader *>(annotations[line]);
425
 
                pah->style = static_cast<short>(style);
426
 
                pah->length = strlen(text);
427
 
                pah->lines = static_cast<short>(NumberLines(text));
428
 
                memcpy(annotations[line]+sizeof(AnnotationHeader), text, pah->length);
429
 
        } else {
430
 
                if (annotations.Length() && (line < annotations.Length()) && annotations[line]) {
431
 
                        delete []annotations[line];
432
 
                        annotations[line] = 0;
433
 
                }
434
 
        }
435
 
}
436
 
 
437
 
void LineAnnotation::ClearAll() {
438
 
        for (int line = 0; line < annotations.Length(); line++) {
439
 
                delete []annotations[line];
440
 
                annotations[line] = 0;
441
 
        }
442
 
        annotations.DeleteAll();
443
 
}
444
 
 
445
 
void LineAnnotation::SetStyle(int line, int style) {
446
 
        annotations.EnsureLength(line+1);
447
 
        if (!annotations[line]) {
448
 
                annotations[line] = AllocateAnnotation(0, style);
449
 
        }
450
 
        reinterpret_cast<AnnotationHeader *>(annotations[line])->style = static_cast<short>(style);
451
 
}
452
 
 
453
 
void LineAnnotation::SetStyles(int line, const unsigned char *styles) {
454
 
        annotations.EnsureLength(line+1);
455
 
        if (!annotations[line]) {
456
 
                annotations[line] = AllocateAnnotation(0, IndividualStyles);
457
 
        } else {
458
 
                AnnotationHeader *pahSource = reinterpret_cast<AnnotationHeader *>(annotations[line]);
459
 
                if (pahSource->style != IndividualStyles) {
460
 
                        char *allocation = AllocateAnnotation(pahSource->length, IndividualStyles);
461
 
                        AnnotationHeader *pahAlloc = reinterpret_cast<AnnotationHeader *>(allocation);
462
 
                        pahAlloc->length = pahSource->length;
463
 
                        pahAlloc->lines = pahSource->lines;
464
 
                        memcpy(allocation + sizeof(AnnotationHeader), annotations[line] + sizeof(AnnotationHeader), pahSource->length);
465
 
                        delete []annotations[line];
466
 
                        annotations[line] = allocation;
467
 
                }
468
 
        }
469
 
        AnnotationHeader *pah = reinterpret_cast<AnnotationHeader *>(annotations[line]);
470
 
        pah->style = IndividualStyles;
471
 
        memcpy(annotations[line] + sizeof(AnnotationHeader) + pah->length, styles, pah->length);
472
 
}
473
 
 
474
 
int LineAnnotation::Length(int line) const {
475
 
        if (annotations.Length() && (line < annotations.Length()) && annotations[line])
476
 
                return reinterpret_cast<AnnotationHeader *>(annotations[line])->length;
477
 
        else
478
 
                return 0;
479
 
}
480
 
 
481
 
int LineAnnotation::Lines(int line) const {
482
 
        if (annotations.Length() && (line < annotations.Length()) && annotations[line])
483
 
                return reinterpret_cast<AnnotationHeader *>(annotations[line])->lines;
484
 
        else
485
 
                return 0;
486
 
}