1 /*
2 * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 #include <string.h>
26 #include <iostream>
27 #include "buffer_cursor.h"
28
29
30 Mark::Mark(BufferCursor *cursor)
31 : cursor(cursor), ptr(nullptr), end(nullptr) {
32 }
33
34 std::string Mark::str(char *end) const {
35 cursor->isValid(end);
36 return std::string(ptr, end - ptr);
37 }
38
39 size_t Mark::getSize() {
40 cursor->isValid(reinterpret_cast<char *>(cursor->get() - ptr));
41 return cursor->get() - ptr;
42 }
43
44 std::string Mark::str() {
45 return std::string(ptr, getSize());
46 }
47
48 std::string Mark::str(int delta) {
49 return std::string(ptr, getSize() + delta);
50 }
51
52
53 char *Mark::getStart() {
54 return ptr;
55 }
56
57 char *Mark::getEnd() {
58 return setEnd();
59 }
60
61 char *Mark::setEnd() {
62 if (end == nullptr) {
63 end = cursor->get();
64 }
65 return end;
66 }
67
68 char *BufferCursor::get() {
69 isValid(ptr);
70 return ptr;
71 }
72
73 bool BufferCursor::isValid(char *p) {
74 // if (p> endPtr){
75 // std::cerr << "p beyond end " << endPtr-p << std::endl;
76 // }
77 // if (p< startPtr){
78 // std::cerr << "p before start " << p-startPtr << std::endl;
79 // }
80 return p >= startPtr && p <= endPtr;
81 }
82
83 bool BufferCursor::end() const {
84 // isValid(ptr);
85 return ptr >= endPtr;
86 }
87
88 BufferCursor *BufferCursor::advance(int i) {
89 if (isValid(ptr)) {
90 ptr += i;
91 // if (isValid(ptr)) {
92 return this;
93 //} else {
94 // std::cerr << "ptr after advance is invalid";
95 // return this;
96 // std::exit(1);
97 } else {
98 std::cerr << "ptr before advance is invalid";
99 std::exit(1);
100 }
101 }
102
103 BufferCursor *BufferCursor::backup(const int i) {
104 if (isValid(ptr)) {
105 ptr -= i;
106 if (isValid(ptr)) {
107 return this;
108 } else {
109 std::cerr << "ptr after backup is invalid";
110 std::exit(1);
111 }
112 } else {
113 std::cerr << "ptr before backup is invalid";
114 std::exit(1);
115 }
116 }
117
118 BufferCursor *BufferCursor::advance() {
119 return advance(1);
120 }
121
122 BufferCursor *BufferCursor::backup() {
123 return backup(1);
124 }
125
126 char BufferCursor::ch() {
127 if (!isValid(ptr)) {
128 std::cerr << "read past end!" << std::endl;
129 std::exit(1);
130 }
131 return *ptr;
132 }
133
134 int BufferCursor::chAsDigit() {
135 isValid(ptr);
136 if (!isLookingAtDigit()) {
137 std::cerr << "not a digit" << std::endl;
138 std::exit(1);
139 }
140 return ch() - '0';
141 }
142
143 int BufferCursor::chAsHexDigit() {
144 isValid(ptr);
145 if (!isLookingAtHexDigit()) {
146 std::cerr << "not a digit" << std::endl;
147 std::exit(1);
148 }
149 if (isLookingAtDigit()) {
150 return chAsDigit();
151 } else {
152 return tolower(ch()) - 'a' + 10;
153 }
154 }
155
156 char BufferCursor::chAndAdvance() {
157 char c = ch();
158 advance();
159 return c;
160 }
161
162 bool BufferCursor::isLookingAt(const char c) {
163 return (ch() == c);
164 }
165
166 bool BufferCursor::isLookingAtAlpha() {
167 return (::isalpha(ch()));
168 }
169
170 bool BufferCursor::isLookingAtDigit() {
171 return (isLookingAtOneOf("0123456789"));
172 }
173
174 bool BufferCursor::isLookingAtOctalDigit() {
175 return (isLookingAtOneOf("01234567"));
176 }
177
178 bool BufferCursor::isLookingAtHexDigit() {
179 return (isLookingAtOneOf("0123456789abcdefABCDEF"));
180 }
181
182 bool BufferCursor::isLookingAtAlphaNum() {
183 return (isLookingAtAlpha() || isLookingAtDigit());
184 }
185
186 bool BufferCursor::isLookingAtAlphaNumOr(const char *s) {
187 return (isLookingAtAlphaNum() || isLookingAtOneOf(s));
188 }
189
190 BufferCursor *BufferCursor::skipWhiteSpace() {
191 return skipWhileLookingAt(" ");
192 }
193
194 BufferCursor *BufferCursor::skipWhiteSpaceOrNewLine() {
195 return skipWhileLookingAtOneOf(" \n\t\r");
196 }
197
198
199 bool BufferCursor::isLookingAt(const char *str) {
200 char *p = ptr;
201 isValid(p + strlen(str));
202 while ((*p == *str) && (*str != '\0')) {
203 p++;
204 str++;
205 }
206 return (!*str);
207 }
208
209 bool BufferCursor::isLookingAtAndStepOver(const char *str) {
210 if (isLookingAt(str)) {
211 stepOver(str);
212 return true;
213 }
214 return false;
215 }
216
217 BufferCursor *BufferCursor::skipUntilLookingAt(const char *str) {
218 while (!isLookingAt(str)) {
219 advance();
220 }
221 return this;
222 }
223
224 BufferCursor *BufferCursor::backupUntilLookingAt(const char *str) {
225 while (!isLookingAt(str)) {
226 backup();
227 }
228 return this;
229 }
230
231 BufferCursor *BufferCursor::skipWhileLookingAt(const char *str) {
232 while (isLookingAt(str)) {
233 advance();
234 }
235 return this;
236 }
237
238 BufferCursor *BufferCursor::skipWhileLookingAtOneOf(const char *str) {
239 while (isLookingAtOneOf(str)) {
240 advance();
241 }
242 return this;
243 }
244
245 BufferCursor *BufferCursor::skipUntilLookingAtOneOf(const char *str) {
246 while (!isLookingAtOneOf(str)) {
247 advance();
248 }
249 return this;
250 }
251
252 bool BufferCursor::isLookingAtOneOf(const char *str) {
253 while (*str) {
254 if (isLookingAt(*str++)) {
255 return true;
256 }
257 }
258
259 return false;
260 }
261
262
263 BufferCursor *BufferCursor::moveTo(Mark *mark) {
264 ptr = mark->ptr;
265 isValid(ptr);
266 return this;
267 }
268
269 bool BufferCursor::isLookingAtCRNL() {
270 return isLookingAt("\r\n");
271 }
272
273 BufferCursor *BufferCursor::stepOverCRNL() {
274 return stepOver("\r\n");
275 }
276
277 bool BufferCursor::isLookingAtNL() {
278 return isLookingAt("\n");
279 }
280
281 BufferCursor *BufferCursor::stepOverNL() {
282 return stepOver("\n");
283 }
284
285 Mark *BufferCursor::mark() {
286 Mark *mark = new Mark(this);
287 mark->cursor = this;
288 mark->ptr = ptr;
289 marks.push_back(mark);
290 return mark;
291 }
292
293 Mark *BufferCursor::markUntil(const char *s) {
294 Mark *newMark = mark();
295 skipTill(s);
296 newMark->setEnd();
297 return newMark;
298 }
299
300 BufferCursor *BufferCursor::stepOver(const char c) {
301 if (isLookingAt(c)) {
302 advance(1);
303 } else {
304 std::cerr << " expecting '" << c << "'" << std::endl;
305 std::exit(0);
306 }
307 return this;
308 }
309
310 BufferCursor *BufferCursor::stepOver(const char *s) {
311 int len = strlen(s);
312 if (isLookingAt(s)) {
313 advance(len);
314 } else {
315 std::cerr << " expecting to step over '" << s << "'" << std::endl;
316 std::exit(0);
317 }
318 return this;
319 }
320
321
322 BufferCursor *BufferCursor::skipTill(const char *str) {
323 while (!end() && *ptr) {
324 if (isLookingAt(str)) {
325 return this;
326 }
327 advance();
328 }
329 return this;
330 }
331
332 BufferCursor *BufferCursor::reset() {
333 ptr = startPtr;
334 return this;
335 }
336
337 BufferCursor::BufferCursor(PureRange *pureRange)
338 : startPtr(pureRange->getStart()), ptr(pureRange->getStart()), endPtr(pureRange->getEnd()) {
339 }
340
341 BufferCursor::BufferCursor(char *ptr, size_t
342 len)
343 : startPtr(ptr), ptr(ptr), endPtr(ptr + len) {
344 }
345
346 BufferCursor::BufferCursor(char *ptr)
347 : startPtr(ptr), ptr(ptr), endPtr(ptr + ::strlen(ptr)) {
348 }
349
350 BufferCursor::~BufferCursor() {
351 for (auto mark: marks) {
352 delete mark;
353 }
354 marks.clear();
355 }
356
357 void BufferCursor::show(std::ostream &o) {
358 char *safe = ptr;
359 while (!end()) {
360 o << *ptr;
361 advance();
362 }
363 ptr = safe;
364 }
365
366 std::ostream &operator<<(std::ostream &o, BufferCursor &c) {
367 c.show(o);
368 return o;
369 }
370
371 std::ostream &operator<<(std::ostream &o, BufferCursor *c) {
372 c->show(o);
373 return o;
374 }
375
376
377 char *BufferCursor::getStart() {
378 return startPtr;
379 }
380
381 char *BufferCursor::getEnd() {
382 return endPtr;
383 }
384
385 size_t BufferCursor::getSize() {
386 return endPtr - startPtr;
387 }
388
389 BufferCursor *BufferCursor::moveToOffset(int offset) {
390 if (offset < 0) {
391 ptr = endPtr + offset;
392 } else {
393 ptr = startPtr + offset;
394 }
395 if (!isValid(ptr)) {
396 std::cerr << "ptr after moveOffset is invalid";
397 std::exit(1);
398 }
399 return this;
400 }