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 26 #include "schema_cursor.h" 27 28 29 SchemaCursor::SchemaCursor(char *ptr): ptr(ptr) { 30 } 31 SchemaCursor::~SchemaCursor() { 32 } 33 void SchemaCursor::in(const char * location){ 34 where.push(location); 35 } 36 void SchemaCursor::out(){ 37 where.pop(); 38 } 39 SchemaCursor *SchemaCursor::skipWhiteSpace() { 40 while (*ptr == ' ' || *ptr == '\n' || *ptr == '\t') { 41 step(1); 42 } 43 return this; 44 } 45 46 47 SchemaCursor *SchemaCursor::skipIdentifier() { 48 while (peekAlpha() || peekDigit()) { 49 step(1); 50 } 51 return this; 52 } 53 54 void SchemaCursor::step(int count) { 55 while (count--) { 56 ptr++; 57 } 58 } 59 60 bool SchemaCursor::peekAlpha() { 61 skipWhiteSpace(); 62 return (::isalpha(*ptr)); 63 } 64 65 bool SchemaCursor::peekDigit() { 66 skipWhiteSpace(); 67 return (::isdigit(*ptr)); 68 } 69 70 bool SchemaCursor::is(char ch) { 71 skipWhiteSpace(); 72 if (*ptr == ch) { 73 step(1); 74 return true; 75 } 76 return false; 77 } 78 bool SchemaCursor::isColon() { 79 return is(':'); 80 } 81 82 bool SchemaCursor::expect(char ch, const char *context, int line ) { 83 if (is(ch)){ 84 return true; 85 } 86 if (!where.empty()){ 87 std::cerr << where.top() << " "; 88 } 89 std::cerr << "@" << line << ": parse error expecting '" << ch << "' "<< context <<" looking at " << ptr << std::endl; 90 exit(1); 91 return false; 92 } 93 bool SchemaCursor::expect(char ch, int line ) { 94 return expect(ch, "", line); 95 } 96 bool SchemaCursor::expectDigit(const char *context, int line ) { 97 if (::isdigit(*ptr)){ 98 return true; 99 } 100 if (!where.empty()){ 101 std::cerr << where.top() << " "; 102 } 103 std::cerr << "@" << line << ": parse error expecting digit "<< context <<" looking at " << ptr << std::endl; 104 exit(1); 105 return false; 106 } 107 bool SchemaCursor::expectAlpha(const char *context, int line ) { 108 if (::isalpha(*ptr)){ 109 return true; 110 } 111 if (!where.empty()){ 112 std::cerr << where.top() << " "; 113 } 114 std::cerr << "@" << line << ": parse error expecting alpha "<< context <<" looking at " << ptr << std::endl; 115 exit(1); 116 return false; 117 } 118 bool SchemaCursor::isEither(char ch1, char ch2, char*actual) { 119 skipWhiteSpace(); 120 if (*ptr == ch1 || *ptr == ch2) { 121 step(1); 122 *actual = *ptr; 123 return true; 124 } 125 return false; 126 } 127 void SchemaCursor::expectEither(char ch1, char ch2, char*actual, int line) { 128 skipWhiteSpace(); 129 if (*ptr == ch1 || *ptr == ch2) { 130 step(1); 131 *actual = *ptr; 132 return; 133 } 134 if (!where.empty()){ 135 std::cerr << where.top() << " "; 136 } 137 std::cerr << "@" << line << ": parse error expecting '" << ch1 << "' or '"<<ch2<< "' looking at " << ptr << std::endl; 138 exit(1); 139 140 } 141 142 int SchemaCursor::getInt() { 143 int value = *ptr - '0'; 144 step(1); 145 if (peekDigit()) { 146 return value * 10 + getInt(); 147 } 148 return value; 149 } 150 151 long SchemaCursor::getLong() { 152 long value = *ptr - '0'; 153 step(1); 154 if (peekDigit()) { 155 return value * 10 + getLong(); 156 } 157 return value; 158 } 159 160 char *SchemaCursor::getIdentifier() { 161 char *identifierStart = ptr; 162 skipIdentifier(); 163 size_t len = ptr - identifierStart; 164 char *identifier = new char[len + 1]; 165 std::memcpy(identifier, identifierStart, len); 166 identifier[len] = '\0'; 167 return identifier; 168 } 169 170 void SchemaCursor::error(std::ostream &ostream, const char *file, int line, const char *str) { 171 ostream << file << ":" << "@" << line << ": parse error " << str << " looking at " << ptr << std::endl; 172 exit(1); 173 } 174