1 /* e_line.cpp
2 *
3 * Copyright (c) 1994-1996, Marko Macek
4 *
5 * You may distribute under the terms of either the GNU General Public
6 * License or the Artistic License, as specified in the README file.
7 *
8 */
9
10 #include "o_buflist.h"
11 #include "sysdep.h"
12
ELine(size_t ACount,const char * AChars)13 ELine::ELine(size_t ACount, const char *AChars) :
14 Count(ACount),
15 Chars(NULL)
16 #ifdef CONFIG_SYNTAX_HILIT
17 , StateE(0)
18 #endif
19 {
20 Allocate(Count);
21 if (AChars)
22 memcpy(Chars, AChars, Count);
23 else
24 memset(Chars, ' ', Count);
25 }
26
ELine(char * AChars,size_t ACount)27 ELine::ELine(char *AChars, size_t ACount) :
28 Count(ACount),
29 Chars(AChars)
30 #ifdef CONFIG_SYNTAX_HILIT
31 , StateE(0)
32 #endif
33 {
34 }
35
~ELine()36 ELine::~ELine() {
37 free(Chars);
38 }
39
Allocate(size_t Bytes)40 int ELine::Allocate(size_t Bytes) {
41 Chars = (char*)realloc(Chars, Bytes | CHAR_TRESHOLD);
42 return (Chars != NULL);
43 }
44
ScreenPos(ELine * L,int Offset)45 int EBuffer::ScreenPos(ELine *L, int Offset) {
46 int ExpandTabs = BFI(this, BFI_ExpandTabs);
47 int TabSize = BFI(this, BFI_TabSize);
48
49 if (!ExpandTabs)
50 return Offset;
51
52 char *p = L->Chars;
53 int Len = L->Count;
54 int Pos = 0;
55 int Ofs = Offset;
56
57 if (Ofs > Len) {
58 while (Len > 0) {
59 if (*p++ != '\t')
60 Pos++;
61 else
62 Pos = NextTab(Pos, TabSize);
63 Len--;
64 }
65 Pos += Ofs - L->Count;
66 } else
67 while (Ofs > 0) {
68 if (*p++ != '\t')
69 Pos++;
70 else
71 Pos = NextTab(Pos, TabSize);
72 Ofs--;
73 }
74
75 return Pos;
76 }
77
CharOffset(ELine * L,int ScreenPos)78 int EBuffer::CharOffset(ELine *L, int ScreenPos) {
79 int ExpandTabs = BFI(this, BFI_ExpandTabs);
80 int TabSize = BFI(this, BFI_TabSize);
81
82 if (!ExpandTabs)
83 return ScreenPos;
84
85 int Pos = 0;
86 int Ofs = 0;
87 char *p = L->Chars;
88 int Len = L->Count;
89
90 while (Len > 0) {
91 if (*p++ != '\t')
92 Pos++;
93 else
94 Pos = NextTab(Pos, TabSize);
95 if (Pos > ScreenPos)
96 return Ofs;
97 Ofs++;
98 Len--;
99 }
100
101 return Ofs + ScreenPos - Pos;
102 }
103
Allocate(int ACount)104 int EBuffer::Allocate(int ACount) {
105 PELine *L;
106
107 if (ACount > 10 * 1024 * 1024) // FIXME: - let's crash, before OOOM kills us
108 return 0;
109
110 L = (PELine *) realloc(LL, sizeof(PELine) * (ACount + 1));
111 if (!L && ACount != 0)
112 return 0;
113 RAllocated = ACount;
114 LL = L;
115
116 return 1;
117 }
118
MoveRGap(int RPos)119 int EBuffer::MoveRGap(int RPos) {
120 int GapSize = RAllocated - RCount;
121
122 if (RGap == RPos)
123 return 1;
124 if (RPos < 0 || RPos > RCount)
125 return 0;
126
127 if (RGap < RPos) {
128 if (RPos - RGap == 1)
129 LL[RGap] = LL[RGap + GapSize];
130 else
131 memmove(LL + RGap,
132 LL + RGap + GapSize,
133 sizeof(PELine) * (RPos - RGap));
134 } else {
135 if (RGap - RPos == 1)
136 LL[RPos + GapSize] = LL[RPos];
137 else
138 memmove(LL + RPos + GapSize,
139 LL + RPos,
140 sizeof(PELine) * (RGap - RPos));
141 }
142 RGap = RPos;
143
144 return 1;
145 }
146
AllocVis(int ACount)147 int EBuffer::AllocVis(int ACount) {
148 int *V = (int *) realloc(VV, sizeof(int) * (ACount + 1));
149 if (!V && ACount != 0)
150 return 0;
151 VAllocated = ACount;
152 VV = V;
153
154 return 1;
155 }
156
MoveVGap(int VPos)157 int EBuffer::MoveVGap(int VPos) {
158 int GapSize = VAllocated - VCount;
159
160 if (VGap == VPos) return 1;
161 if (VPos < 0 || VPos > VCount) return 0;
162
163 if (VGap < VPos) {
164 if (VPos - VGap == 1)
165 VV[VGap] = VV[VGap + GapSize];
166 else
167 memmove(VV + VGap,
168 VV + VGap + GapSize,
169 sizeof(VV[0]) * (VPos - VGap));
170 } else {
171 if (VGap - VPos == 1) {
172 VV[VPos + GapSize] = VV[VPos];
173 } else {
174 memmove(VV + VPos + GapSize,
175 VV + VPos,
176 sizeof(VV[0]) * (VGap - VPos));
177 }
178 }
179 VGap = VPos;
180 return 1;
181 }
182
RToV(int No)183 int EBuffer::RToV(int No) {
184 int L = 0, R = VCount, M, V;
185
186 if (No > Vis(VCount - 1) + VCount - 1) // beyond end
187 return -1;
188 if (No < VCount) // no folds before (direct match)
189 if (Vis(No) == 0) return No;
190
191 while (L < R) {
192 M = (L + R) / 2;
193 V = Vis(M) + M;
194 if (V == No)
195 return M;
196 if (V > No)
197 R = M;
198 else
199 L = M + 1;
200 }
201 return -1;
202 }
203
RToVN(int No)204 int EBuffer::RToVN(int No) {
205 int L = 0, R = VCount, M, V;
206
207 if (No == RCount)
208 return VCount;
209 if (No > Vis(VCount - 1) + VCount - 1)
210 return VCount - 1;
211 if (No < VCount)
212 if (Vis(No) == 0) return No;
213
214 while (L < R) {
215 M = (L + R) / 2;
216 V = Vis(M) + M;
217 if (V == No)
218 return M;
219 else if (V > No)
220 R = M;
221 else {
222 if (M == VCount - 1)
223 return M;
224 else if (Vis(M + 1) + M + 1 > No)
225 return M;
226 L = M + 1;
227 }
228 }
229 return R;
230 }
231