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 }