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 std::string Mark::str(char *end) { 34 cursor->isValid(end); 35 return std::string(ptr, end - ptr); 36 } 37 38 size_t Mark::getSize() { 39 cursor->isValid((char *) (cursor->get() - ptr)); 40 return cursor->get() - ptr; 41 } 42 43 std::string Mark::str() { 44 return std::string(ptr, getSize()); 45 } 46 47 std::string Mark::str(int delta) { 48 return std::string(ptr, getSize()+delta); 49 } 50 51 52 char *Mark::getStart(){ 53 return ptr; 54 } 55 char *Mark::getEnd(){ 56 return setEnd(); 57 } 58 59 char *Mark::setEnd(){ 60 if (end == nullptr){ 61 end = cursor->get(); 62 } 63 return end; 64 } 65 66 char *BufferCursor::get() { 67 isValid(ptr); 68 return ptr; 69 } 70 71 bool BufferCursor::isValid(char *p) { 72 // if (p> endPtr){ 73 // std::cerr << "p beyond end " << endPtr-p << std::endl; 74 // } 75 // if (p< startPtr){ 76 // std::cerr << "p before start " << p-startPtr << std::endl; 77 // } 78 return p >= startPtr && p <= endPtr; 79 } 80 81 bool BufferCursor::end() { 82 // isValid(ptr); 83 return ptr >= endPtr; 84 } 85 86 BufferCursor *BufferCursor::advance(int i) { 87 if (isValid(ptr)) { 88 ptr += i; 89 // if (isValid(ptr)) { 90 return this; 91 //} else { 92 // std::cerr << "ptr after advance is invalid"; 93 // return this; 94 // std::exit(1); 95 96 } else { 97 std::cerr << "ptr before advance is invalid"; 98 std::exit(1); 99 } 100 101 } 102 103 BufferCursor *BufferCursor::backup(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 119 BufferCursor *BufferCursor::advance() { 120 return advance(1); 121 } 122 123 BufferCursor *BufferCursor::backup() { 124 return backup(1); 125 } 126 127 char BufferCursor::ch() { 128 if (!isValid(ptr)){ 129 std::cerr << "read past end!" << std::endl; 130 std::exit(1); 131 } 132 return *ptr; 133 } 134 135 int BufferCursor::chAsDigit() { 136 isValid(ptr); 137 if (!isLookingAtDigit()) { 138 std::cerr << "not a digit" << std::endl; 139 std::exit(1); 140 } 141 return ch() - '0'; 142 } 143 144 int BufferCursor::chAsHexDigit() { 145 isValid(ptr); 146 if (!isLookingAtHexDigit()) { 147 std::cerr << "not a digit" << std::endl; 148 std::exit(1); 149 } 150 if (isLookingAtDigit()) { 151 return chAsDigit(); 152 } else { 153 return tolower(ch()) - 'a' + 10; 154 } 155 } 156 157 char BufferCursor::chAndAdvance() { 158 char c = ch(); 159 advance(); 160 return c; 161 } 162 163 bool BufferCursor::isLookingAt(const char c) { 164 return (ch() == c); 165 } 166 167 bool BufferCursor::isLookingAtAlpha() { 168 return (::isalpha(ch())); 169 } 170 171 bool BufferCursor::isLookingAtDigit() { 172 return (isLookingAtOneOf("0123456789")); 173 } 174 bool BufferCursor::isLookingAtOctalDigit() { 175 return (isLookingAtOneOf("01234567")); 176 } 177 bool BufferCursor::isLookingAtHexDigit() { 178 return (isLookingAtOneOf("0123456789abcdefABCDEF")); 179 } 180 181 bool BufferCursor::isLookingAtAlphaNum() { 182 return (isLookingAtAlpha() || isLookingAtDigit()); 183 } 184 185 bool BufferCursor::isLookingAtAlphaNumOr(const char *s) { 186 return (isLookingAtAlphaNum() || isLookingAtOneOf(s)); 187 } 188 189 BufferCursor *BufferCursor::skipWhiteSpace() { 190 return skipWhileLookingAt(" "); 191 } 192 193 BufferCursor *BufferCursor::skipWhiteSpaceOrNewLine() { 194 return skipWhileLookingAtOneOf(" \n\t\r"); 195 } 196 197 198 bool BufferCursor::isLookingAt(const char *str) { 199 char *p = ptr; 200 isValid(p + strlen(str)); 201 while ((*p == *str) && (*str != '\0')) { 202 p++; 203 str++; 204 } 205 return (!*str); 206 } 207 208 bool BufferCursor::isLookingAtAndStepOver(const char *str) { 209 if (isLookingAt(str)) { 210 stepOver(str); 211 return true; 212 } 213 return false; 214 } 215 216 BufferCursor *BufferCursor::skipUntilLookingAt(const char *str) { 217 while (!isLookingAt(str)) { 218 advance(); 219 } 220 return this; 221 } 222 223 BufferCursor *BufferCursor::backupUntilLookingAt(const char *str) { 224 while (!isLookingAt(str)) { 225 backup(); 226 } 227 return this; 228 } 229 230 BufferCursor *BufferCursor::skipWhileLookingAt(const char *str) { 231 while (isLookingAt(str)) { 232 advance(); 233 } 234 return this; 235 } 236 237 BufferCursor *BufferCursor::skipWhileLookingAtOneOf(const char *str) { 238 while (isLookingAtOneOf(str)) { 239 advance(); 240 } 241 return this; 242 } 243 244 BufferCursor *BufferCursor::skipUntilLookingAtOneOf(const char *str) { 245 while (!isLookingAtOneOf(str)) { 246 advance(); 247 } 248 return this; 249 } 250 251 bool BufferCursor::isLookingAtOneOf(const char *str) { 252 while (*str) { 253 if (isLookingAt(*str++)) { 254 return true; 255 } 256 } 257 258 return false; 259 } 260 261 262 BufferCursor *BufferCursor::moveTo(Mark *mark) { 263 ptr = mark->ptr; 264 isValid(ptr); 265 return this; 266 } 267 268 bool BufferCursor::isLookingAtCRNL() { 269 return isLookingAt("\r\n"); 270 } 271 272 BufferCursor *BufferCursor::stepOverCRNL() { 273 return stepOver("\r\n"); 274 } 275 276 bool BufferCursor::isLookingAtNL() { 277 return isLookingAt("\n"); 278 } 279 280 BufferCursor *BufferCursor::stepOverNL() { 281 return stepOver("\n"); 282 } 283 284 Mark *BufferCursor::mark() { 285 Mark *mark = new Mark(this); 286 mark->cursor = this; 287 mark->ptr = ptr; 288 marks.push_back(mark); 289 return mark; 290 } 291 292 Mark *BufferCursor::markUntil(const char *s) { 293 Mark *newMark = mark(); 294 skipTill(s); 295 newMark->setEnd(); 296 return newMark; 297 } 298 299 BufferCursor *BufferCursor::stepOver(const char c) { 300 if (isLookingAt(c)) { 301 advance(1); 302 } else { 303 std::cerr << " expecting '" << c << "'" << std::endl; 304 std::exit(0); 305 } 306 return this; 307 } 308 309 BufferCursor *BufferCursor::stepOver(const char *s) { 310 int len = strlen(s); 311 if (isLookingAt(s)) { 312 advance(len); 313 } else { 314 std::cerr << " expecting to step over '" << s << "'" << std::endl; 315 std::exit(0); 316 } 317 return this; 318 } 319 320 321 BufferCursor *BufferCursor::skipTill(const char *str) { 322 while (!end() && *ptr) { 323 if (isLookingAt(str)) { 324 return this; 325 } 326 advance(); 327 } 328 return this; 329 } 330 331 BufferCursor *BufferCursor::reset() { 332 ptr = startPtr; 333 return this; 334 } 335 336 BufferCursor::BufferCursor(PureRange *pureRange) 337 : startPtr(pureRange->getStart()), ptr(pureRange->getStart()), endPtr(pureRange->getEnd()) { 338 339 } 340 341 BufferCursor::BufferCursor(char *ptr, size_t 342 len) 343 : startPtr(ptr), ptr(ptr), endPtr(ptr + len) { 344 345 } 346 347 BufferCursor::BufferCursor(char *ptr) 348 : startPtr(ptr), ptr(ptr), endPtr(ptr + ::strlen(ptr)) { 349 350 } 351 BufferCursor::~BufferCursor(){ 352 for (auto mark:marks){ 353 delete mark; 354 } 355 marks.clear(); 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 }