~haaaad/geany/master

« back to all changes in this revision

Viewing changes to scintilla/src/CellBuffer.cxx

  • Committer: elextr
  • Author(s): Colomban Wendling
  • Date: 2017-07-24 23:24:05 UTC
  • Revision ID: git-v1:18360460abb4f4bec23dff127031ecf4e9120f7f
Update Scintilla to version 3.7.5 (#1503)

* Update Scintilla to version 3.7.5

This now requires a C++11-capable compiler.

Closes #1308.

* Test using newer dist on Travis

Since Scintilla needs C++11

* Add debugging code for when configure fails

* Workaround a pkg-config-corsswrapper bug on Ubuntu 14.04

See https://bugs.launchpad.net/ubuntu/+source/mingw-w64/+bug/1327242

Show diffs side-by-side

added added

removed removed

Lines of Context:
5
5
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
6
6
// The License.txt file describes the conditions under which this software may be distributed.
7
7
 
8
 
#include <stdlib.h>
9
 
#include <string.h>
10
 
#include <stdio.h>
11
 
#include <stdarg.h>
 
8
#include <cstddef>
 
9
#include <cstdlib>
 
10
#include <cstring>
 
11
#include <cstdio>
 
12
#include <cstdarg>
12
13
 
13
14
#include <stdexcept>
 
15
#include <vector>
14
16
#include <algorithm>
 
17
#include <memory>
15
18
 
16
19
#include "Platform.h"
17
20
 
45
48
        perLine = pl;
46
49
}
47
50
 
48
 
void LineVector::InsertText(int line, int delta) {
 
51
void LineVector::InsertText(Sci::Line line, Sci::Position delta) {
49
52
        starts.InsertText(line, delta);
50
53
}
51
54
 
52
 
void LineVector::InsertLine(int line, int position, bool lineStart) {
 
55
void LineVector::InsertLine(Sci::Line line, Sci::Position position, bool lineStart) {
53
56
        starts.InsertPartition(line, position);
54
57
        if (perLine) {
55
58
                if ((line > 0) && lineStart)
58
61
        }
59
62
}
60
63
 
61
 
void LineVector::SetLineStart(int line, int position) {
 
64
void LineVector::SetLineStart(Sci::Line line, Sci::Position position) {
62
65
        starts.SetPartitionStartPosition(line, position);
63
66
}
64
67
 
65
 
void LineVector::RemoveLine(int line) {
 
68
void LineVector::RemoveLine(Sci::Line line) {
66
69
        starts.RemovePartition(line);
67
70
        if (perLine) {
68
71
                perLine->RemoveLine(line);
69
72
        }
70
73
}
71
74
 
72
 
int LineVector::LineFromPosition(int pos) const {
 
75
Sci::Line LineVector::LineFromPosition(Sci::Position pos) const {
73
76
        return starts.PartitionFromPosition(pos);
74
77
}
75
78
 
76
79
Action::Action() {
77
80
        at = startAction;
78
81
        position = 0;
79
 
        data = 0;
80
82
        lenData = 0;
81
83
        mayCoalesce = false;
82
84
}
83
85
 
 
86
Action::Action(Action &&other) {
 
87
        at = other.at;
 
88
        position = other.position;
 
89
        data = std::move(other.data);
 
90
        lenData = other.lenData;
 
91
        mayCoalesce = other.mayCoalesce;
 
92
}
 
93
 
84
94
Action::~Action() {
85
 
        Destroy();
86
95
}
87
96
 
88
 
void Action::Create(actionType at_, int position_, const char *data_, int lenData_, bool mayCoalesce_) {
89
 
        delete []data;
90
 
        data = NULL;
 
97
void Action::Create(actionType at_, Sci::Position position_, const char *data_, Sci::Position lenData_, bool mayCoalesce_) {
 
98
        data = nullptr;
91
99
        position = position_;
92
100
        at = at_;
93
101
        if (lenData_) {
94
 
                data = new char[lenData_];
95
 
                memcpy(data, data_, lenData_);
 
102
                data = std::unique_ptr<char []>(new char[lenData_]);
 
103
                memcpy(&data[0], data_, lenData_);
96
104
        }
97
105
        lenData = lenData_;
98
106
        mayCoalesce = mayCoalesce_;
99
107
}
100
108
 
101
 
void Action::Destroy() {
102
 
        delete []data;
103
 
        data = 0;
104
 
}
105
 
 
106
 
void Action::Grab(Action *source) {
107
 
        delete []data;
108
 
 
109
 
        position = source->position;
110
 
        at = source->at;
111
 
        data = source->data;
112
 
        lenData = source->lenData;
113
 
        mayCoalesce = source->mayCoalesce;
114
 
 
115
 
        // Ownership of source data transferred to this
116
 
        source->position = 0;
117
 
        source->at = startAction;
118
 
        source->data = 0;
119
 
        source->lenData = 0;
120
 
        source->mayCoalesce = true;
 
109
void Action::Clear() {
 
110
        data = nullptr;
 
111
        lenData = 0;
121
112
}
122
113
 
123
114
// The undo history stores a sequence of user operations that represent the user's view of the
140
131
 
141
132
UndoHistory::UndoHistory() {
142
133
 
143
 
        lenActions = 100;
144
 
        actions = new Action[lenActions];
 
134
        actions.resize(3);
145
135
        maxAction = 0;
146
136
        currentAction = 0;
147
137
        undoSequenceDepth = 0;
152
142
}
153
143
 
154
144
UndoHistory::~UndoHistory() {
155
 
        delete []actions;
156
 
        actions = 0;
157
145
}
158
146
 
159
147
void UndoHistory::EnsureUndoRoom() {
160
148
        // Have to test that there is room for 2 more actions in the array
161
149
        // as two actions may be created by the calling function
162
 
        if (currentAction >= (lenActions - 2)) {
 
150
        if (static_cast<size_t>(currentAction) >= (actions.size() - 2)) {
163
151
                // Run out of undo nodes so extend the array
164
 
                int lenActionsNew = lenActions * 2;
165
 
                Action *actionsNew = new Action[lenActionsNew];
166
 
                for (int act = 0; act <= currentAction; act++)
167
 
                        actionsNew[act].Grab(&actions[act]);
168
 
                delete []actions;
169
 
                lenActions = lenActionsNew;
170
 
                actions = actionsNew;
 
152
                actions.resize(actions.size() * 2);
171
153
        }
172
154
}
173
155
 
174
 
const char *UndoHistory::AppendAction(actionType at, int position, const char *data, int lengthData,
 
156
const char *UndoHistory::AppendAction(actionType at, Sci::Position position, const char *data, Sci::Position lengthData,
175
157
        bool &startSequence, bool mayCoalesce) {
176
158
        EnsureUndoRoom();
177
159
        //Platform::DebugPrintf("%% %d action %d %d %d\n", at, position, lengthData, currentAction);
193
175
                        }
194
176
                        // See if current action can be coalesced into previous action
195
177
                        // Will work if both are inserts or deletes and position is same
196
 
#if defined(_MSC_VER) && defined(_PREFAST_)
197
 
                        // Visual Studio 2013 Code Analysis wrongly believes actions can be NULL at its next reference
198
 
                        __analysis_assume(actions);
199
 
#endif
200
178
                        if ((currentAction == savePoint) || (currentAction == tentativePoint)) {
201
179
                                currentAction++;
202
180
                        } else if (!actions[currentAction].mayCoalesce) {
239
217
                currentAction++;
240
218
        }
241
219
        startSequence = oldCurrentAction != currentAction;
242
 
        int actionWithData = currentAction;
 
220
        const int actionWithData = currentAction;
243
221
        actions[currentAction].Create(at, position, data, lengthData, mayCoalesce);
244
222
        currentAction++;
245
223
        actions[currentAction].Create(startAction);
246
224
        maxAction = currentAction;
247
 
        return actions[actionWithData].data;
 
225
        return actions[actionWithData].data.get();
248
226
}
249
227
 
250
228
void UndoHistory::BeginUndoAction() {
280
258
 
281
259
void UndoHistory::DeleteUndoHistory() {
282
260
        for (int i = 1; i < maxAction; i++)
283
 
                actions[i].Destroy();
 
261
                actions[i].Clear();
284
262
        maxAction = 0;
285
263
        currentAction = 0;
286
264
        actions[currentAction].Create(startAction);
347
325
 
348
326
int UndoHistory::StartRedo() {
349
327
        // Drop any leading startAction
350
 
        if (actions[currentAction].at == startAction && currentAction < maxAction)
 
328
        if (currentAction < maxAction && actions[currentAction].at == startAction)
351
329
                currentAction++;
352
330
 
353
331
        // Count the steps in this action
354
332
        int act = currentAction;
355
 
        while (actions[act].at != startAction && act < maxAction) {
 
333
        while (act < maxAction && actions[act].at != startAction) {
356
334
                act++;
357
335
        }
358
336
        return act - currentAction;
375
353
CellBuffer::~CellBuffer() {
376
354
}
377
355
 
378
 
char CellBuffer::CharAt(int position) const {
 
356
char CellBuffer::CharAt(Sci::Position position) const {
379
357
        return substance.ValueAt(position);
380
358
}
381
359
 
382
 
void CellBuffer::GetCharRange(char *buffer, int position, int lengthRetrieve) const {
 
360
void CellBuffer::GetCharRange(char *buffer, Sci::Position position, Sci::Position lengthRetrieve) const {
383
361
        if (lengthRetrieve <= 0)
384
362
                return;
385
363
        if (position < 0)
392
370
        substance.GetRange(buffer, position, lengthRetrieve);
393
371
}
394
372
 
395
 
char CellBuffer::StyleAt(int position) const {
 
373
char CellBuffer::StyleAt(Sci::Position position) const {
396
374
        return style.ValueAt(position);
397
375
}
398
376
 
399
 
void CellBuffer::GetStyleRange(unsigned char *buffer, int position, int lengthRetrieve) const {
 
377
void CellBuffer::GetStyleRange(unsigned char *buffer, Sci::Position position, Sci::Position lengthRetrieve) const {
400
378
        if (lengthRetrieve < 0)
401
379
                return;
402
380
        if (position < 0)
413
391
        return substance.BufferPointer();
414
392
}
415
393
 
416
 
const char *CellBuffer::RangePointer(int position, int rangeLength) {
 
394
const char *CellBuffer::RangePointer(Sci::Position position, Sci::Position rangeLength) {
417
395
        return substance.RangePointer(position, rangeLength);
418
396
}
419
397
 
420
 
int CellBuffer::GapPosition() const {
 
398
Sci::Position CellBuffer::GapPosition() const {
421
399
        return substance.GapPosition();
422
400
}
423
401
 
424
402
// The char* returned is to an allocation owned by the undo history
425
 
const char *CellBuffer::InsertString(int position, const char *s, int insertLength, bool &startSequence) {
 
403
const char *CellBuffer::InsertString(Sci::Position position, const char *s, Sci::Position insertLength, bool &startSequence) {
426
404
        // InsertString and DeleteChars are the bottleneck though which all changes occur
427
405
        const char *data = s;
428
406
        if (!readOnly) {
437
415
        return data;
438
416
}
439
417
 
440
 
bool CellBuffer::SetStyleAt(int position, char styleValue) {
441
 
        char curVal = style.ValueAt(position);
 
418
bool CellBuffer::SetStyleAt(Sci::Position position, char styleValue) {
 
419
        const char curVal = style.ValueAt(position);
442
420
        if (curVal != styleValue) {
443
421
                style.SetValueAt(position, styleValue);
444
422
                return true;
447
425
        }
448
426
}
449
427
 
450
 
bool CellBuffer::SetStyleFor(int position, int lengthStyle, char styleValue) {
 
428
bool CellBuffer::SetStyleFor(Sci::Position position, Sci::Position lengthStyle, char styleValue) {
451
429
        bool changed = false;
452
430
        PLATFORM_ASSERT(lengthStyle == 0 ||
453
431
                (lengthStyle > 0 && lengthStyle + position <= style.Length()));
454
432
        while (lengthStyle--) {
455
 
                char curVal = style.ValueAt(position);
 
433
                const char curVal = style.ValueAt(position);
456
434
                if (curVal != styleValue) {
457
435
                        style.SetValueAt(position, styleValue);
458
436
                        changed = true;
463
441
}
464
442
 
465
443
// The char* returned is to an allocation owned by the undo history
466
 
const char *CellBuffer::DeleteChars(int position, int deleteLength, bool &startSequence) {
 
444
const char *CellBuffer::DeleteChars(Sci::Position position, Sci::Position deleteLength, bool &startSequence) {
467
445
        // InsertString and DeleteChars are the bottleneck though which all changes occur
468
446
        PLATFORM_ASSERT(deleteLength > 0);
469
447
        const char *data = 0;
480
458
        return data;
481
459
}
482
460
 
483
 
int CellBuffer::Length() const {
 
461
Sci::Position CellBuffer::Length() const {
484
462
        return substance.Length();
485
463
}
486
464
 
487
 
void CellBuffer::Allocate(int newSize) {
 
465
void CellBuffer::Allocate(Sci::Position newSize) {
488
466
        substance.ReAllocate(newSize);
489
467
        style.ReAllocate(newSize);
490
468
}
496
474
        }
497
475
}
498
476
 
499
 
bool CellBuffer::ContainsLineEnd(const char *s, int length) const {
 
477
bool CellBuffer::ContainsLineEnd(const char *s, Sci::Position length) const {
500
478
        unsigned char chBeforePrev = 0;
501
479
        unsigned char chPrev = 0;
502
 
        for (int i = 0; i < length; i++) {
 
480
        for (Sci::Position i = 0; i < length; i++) {
503
481
                const unsigned char ch = s[i];
504
482
                if ((ch == '\r') || (ch == '\n')) {
505
483
                        return true;
506
484
                } else if (utf8LineEnds) {
507
 
                        unsigned char back3[3] = { chBeforePrev, chPrev, ch };
 
485
                        const unsigned char back3[3] = { chBeforePrev, chPrev, ch };
508
486
                        if (UTF8IsSeparator(back3) || UTF8IsNEL(back3 + 1)) {
509
487
                                return true;
510
488
                        }
519
497
        lv.SetPerLine(pl);
520
498
}
521
499
 
522
 
int CellBuffer::Lines() const {
 
500
Sci::Line CellBuffer::Lines() const {
523
501
        return lv.Lines();
524
502
}
525
503
 
526
 
int CellBuffer::LineStart(int line) const {
 
504
Sci::Position CellBuffer::LineStart(Sci::Line line) const {
527
505
        if (line < 0)
528
506
                return 0;
529
507
        else if (line >= Lines())
566
544
 
567
545
// Without undo
568
546
 
569
 
void CellBuffer::InsertLine(int line, int position, bool lineStart) {
 
547
void CellBuffer::InsertLine(Sci::Line line, Sci::Position position, bool lineStart) {
570
548
        lv.InsertLine(line, position, lineStart);
571
549
}
572
550
 
573
 
void CellBuffer::RemoveLine(int line) {
 
551
void CellBuffer::RemoveLine(Sci::Line line) {
574
552
        lv.RemoveLine(line);
575
553
}
576
554
 
577
 
bool CellBuffer::UTF8LineEndOverlaps(int position) const {
578
 
        unsigned char bytes[] = {
 
555
bool CellBuffer::UTF8LineEndOverlaps(Sci::Position position) const {
 
556
        const unsigned char bytes[] = {
579
557
                static_cast<unsigned char>(substance.ValueAt(position-2)),
580
558
                static_cast<unsigned char>(substance.ValueAt(position-1)),
581
559
                static_cast<unsigned char>(substance.ValueAt(position)),
588
566
        // Reinitialize line data -- too much work to preserve
589
567
        lv.Init();
590
568
 
591
 
        int position = 0;
592
 
        int length = Length();
593
 
        int lineInsert = 1;
 
569
        Sci::Position position = 0;
 
570
        Sci::Position length = Length();
 
571
        Sci::Line lineInsert = 1;
594
572
        bool atLineStart = true;
595
573
        lv.InsertText(lineInsert-1, length);
596
574
        unsigned char chBeforePrev = 0;
597
575
        unsigned char chPrev = 0;
598
 
        for (int i = 0; i < length; i++) {
599
 
                unsigned char ch = substance.ValueAt(position + i);
 
576
        for (Sci::Position i = 0; i < length; i++) {
 
577
                const unsigned char ch = substance.ValueAt(position + i);
600
578
                if (ch == '\r') {
601
579
                        InsertLine(lineInsert, (position + i) + 1, atLineStart);
602
580
                        lineInsert++;
609
587
                                lineInsert++;
610
588
                        }
611
589
                } else if (utf8LineEnds) {
612
 
                        unsigned char back3[3] = {chBeforePrev, chPrev, ch};
 
590
                        const unsigned char back3[3] = {chBeforePrev, chPrev, ch};
613
591
                        if (UTF8IsSeparator(back3) || UTF8IsNEL(back3+1)) {
614
592
                                InsertLine(lineInsert, (position + i) + 1, atLineStart);
615
593
                                lineInsert++;
620
598
        }
621
599
}
622
600
 
623
 
void CellBuffer::BasicInsertString(int position, const char *s, int insertLength) {
 
601
void CellBuffer::BasicInsertString(Sci::Position position, const char *s, Sci::Position insertLength) {
624
602
        if (insertLength == 0)
625
603
                return;
626
604
        PLATFORM_ASSERT(insertLength > 0);
627
605
 
628
 
        unsigned char chAfter = substance.ValueAt(position);
 
606
        const unsigned char chAfter = substance.ValueAt(position);
629
607
        bool breakingUTF8LineEnd = false;
630
608
        if (utf8LineEnds && UTF8IsTrailByte(chAfter)) {
631
609
                breakingUTF8LineEnd = UTF8LineEndOverlaps(position);
634
612
        substance.InsertFromArray(position, s, 0, insertLength);
635
613
        style.InsertValue(position, insertLength, 0);
636
614
 
637
 
        int lineInsert = lv.LineFromPosition(position) + 1;
 
615
        Sci::Line lineInsert = lv.LineFromPosition(position) + 1;
638
616
        bool atLineStart = lv.LineStart(lineInsert-1) == position;
639
617
        // Point all the lines after the insertion point further along in the buffer
640
618
        lv.InsertText(lineInsert-1, insertLength);
649
627
                RemoveLine(lineInsert);
650
628
        }
651
629
        unsigned char ch = ' ';
652
 
        for (int i = 0; i < insertLength; i++) {
 
630
        for (Sci::Position i = 0; i < insertLength; i++) {
653
631
                ch = s[i];
654
632
                if (ch == '\r') {
655
633
                        InsertLine(lineInsert, (position + i) + 1, atLineStart);
663
641
                                lineInsert++;
664
642
                        }
665
643
                } else if (utf8LineEnds) {
666
 
                        unsigned char back3[3] = {chBeforePrev, chPrev, ch};
 
644
                        const unsigned char back3[3] = {chBeforePrev, chPrev, ch};
667
645
                        if (UTF8IsSeparator(back3) || UTF8IsNEL(back3+1)) {
668
646
                                InsertLine(lineInsert, (position + i) + 1, atLineStart);
669
647
                                lineInsert++;
681
659
        } else if (utf8LineEnds && !UTF8IsAscii(chAfter)) {
682
660
                // May have end of UTF-8 line end in buffer and start in insertion
683
661
                for (int j = 0; j < UTF8SeparatorLength-1; j++) {
684
 
                        unsigned char chAt = substance.ValueAt(position + insertLength + j);
685
 
                        unsigned char back3[3] = {chBeforePrev, chPrev, chAt};
 
662
                        const unsigned char chAt = substance.ValueAt(position + insertLength + j);
 
663
                        const unsigned char back3[3] = {chBeforePrev, chPrev, chAt};
686
664
                        if (UTF8IsSeparator(back3)) {
687
665
                                InsertLine(lineInsert, (position + insertLength + j) + 1, atLineStart);
688
666
                                lineInsert++;
697
675
        }
698
676
}
699
677
 
700
 
void CellBuffer::BasicDeleteChars(int position, int deleteLength) {
 
678
void CellBuffer::BasicDeleteChars(Sci::Position position, Sci::Position deleteLength) {
701
679
        if (deleteLength == 0)
702
680
                return;
703
681
 
709
687
                // Have to fix up line positions before doing deletion as looking at text in buffer
710
688
                // to work out which lines have been removed
711
689
 
712
 
                int lineRemove = lv.LineFromPosition(position) + 1;
 
690
                Sci::Line lineRemove = lv.LineFromPosition(position) + 1;
713
691
                lv.InsertText(lineRemove-1, - (deleteLength));
714
 
                unsigned char chPrev = substance.ValueAt(position - 1);
715
 
                unsigned char chBefore = chPrev;
 
692
                const unsigned char chPrev = substance.ValueAt(position - 1);
 
693
                const unsigned char chBefore = chPrev;
716
694
                unsigned char chNext = substance.ValueAt(position);
717
695
                bool ignoreNL = false;
718
696
                if (chPrev == '\r' && chNext == '\n') {
728
706
                }
729
707
 
730
708
                unsigned char ch = chNext;
731
 
                for (int i = 0; i < deleteLength; i++) {
 
709
                for (Sci::Position i = 0; i < deleteLength; i++) {
732
710
                        chNext = substance.ValueAt(position + i + 1);
733
711
                        if (ch == '\r') {
734
712
                                if (chNext != '\n') {
742
720
                                }
743
721
                        } else if (utf8LineEnds) {
744
722
                                if (!UTF8IsAscii(ch)) {
745
 
                                        unsigned char next3[3] = {ch, chNext,
 
723
                                        const unsigned char next3[3] = {ch, chNext,
746
724
                                                static_cast<unsigned char>(substance.ValueAt(position + i + 2))};
747
725
                                        if (UTF8IsSeparator(next3) || UTF8IsNEL(next3)) {
748
726
                                                RemoveLine(lineRemove);
754
732
                }
755
733
                // May have to fix up end if last deletion causes cr to be next to lf
756
734
                // or removes one of a crlf pair
757
 
                char chAfter = substance.ValueAt(position + deleteLength);
 
735
                const char chAfter = substance.ValueAt(position + deleteLength);
758
736
                if (chBefore == '\r' && chAfter == '\n') {
759
737
                        // Using lineRemove-1 as cr ended line before start of deletion
760
738
                        RemoveLine(lineRemove - 1);
783
761
        uh.EndUndoAction();
784
762
}
785
763
 
786
 
void CellBuffer::AddUndoAction(int token, bool mayCoalesce) {
 
764
void CellBuffer::AddUndoAction(Sci::Position token, bool mayCoalesce) {
787
765
        bool startSequence;
788
766
        uh.AppendAction(containerAction, token, 0, 0, startSequence, mayCoalesce);
789
767
}
813
791
                }
814
792
                BasicDeleteChars(actionStep.position, actionStep.lenData);
815
793
        } else if (actionStep.at == removeAction) {
816
 
                BasicInsertString(actionStep.position, actionStep.data, actionStep.lenData);
 
794
                BasicInsertString(actionStep.position, actionStep.data.get(), actionStep.lenData);
817
795
        }
818
796
        uh.CompletedUndoStep();
819
797
}
833
811
void CellBuffer::PerformRedoStep() {
834
812
        const Action &actionStep = uh.GetRedoStep();
835
813
        if (actionStep.at == insertAction) {
836
 
                BasicInsertString(actionStep.position, actionStep.data, actionStep.lenData);
 
814
                BasicInsertString(actionStep.position, actionStep.data.get(), actionStep.lenData);
837
815
        } else if (actionStep.at == removeAction) {
838
816
                BasicDeleteChars(actionStep.position, actionStep.lenData);
839
817
        }