summaryrefslogtreecommitdiff
path: root/src/lexer-source.cc
diff options
context:
space:
mode:
authorBen Smith <binjimin@gmail.com>2017-06-02 13:35:24 -0700
committerGitHub <noreply@github.com>2017-06-02 13:35:24 -0700
commit3c6c7a83c5bcf4f6654d4646652ace2c1468f0fb (patch)
treee595fdac4cfb86796b50db01f0a807a451b1cfcb /src/lexer-source.cc
parentc37a2d912e83f9298c64c61e1e92aff8042566e1 (diff)
downloadwabt-3c6c7a83c5bcf4f6654d4646652ace2c1468f0fb.tar.gz
wabt-3c6c7a83c5bcf4f6654d4646652ace2c1468f0fb.tar.bz2
wabt-3c6c7a83c5bcf4f6654d4646652ace2c1468f0fb.zip
Cleanup Lexer (#466)
* Add class LexerSource: it encapsulates reading data from a source, either buffer or file. * Add class LexerSourceLineFinder: it uses a LexerSource to read a line from the source for displaying in errors. It lazily caches line numbers -> file offsets, so no work is done unless an error occurs. * Make WastLexer a class instead of a struct.
Diffstat (limited to 'src/lexer-source.cc')
-rw-r--r--src/lexer-source.cc131
1 files changed, 131 insertions, 0 deletions
diff --git a/src/lexer-source.cc b/src/lexer-source.cc
new file mode 100644
index 00000000..13ca713e
--- /dev/null
+++ b/src/lexer-source.cc
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2017 WebAssembly Community Group participants
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "lexer-source.h"
+
+#include <algorithm>
+
+#define CHECK_RESULT(expr) \
+ do { \
+ if (WABT_FAILED(expr)) \
+ return Result::Error; \
+ } while (0)
+
+namespace wabt {
+
+LexerSourceFile::LexerSourceFile(const std::string& filename)
+ : filename_(filename) {
+ file_ = fopen(filename.c_str(), "rb");
+}
+
+LexerSourceFile::~LexerSourceFile() {
+ if (file_)
+ fclose(file_);
+}
+
+std::unique_ptr<LexerSource> LexerSourceFile::Clone() {
+ std::unique_ptr<LexerSourceFile> result(new LexerSourceFile(filename_));
+
+ Offset offset = 0;
+ if (WABT_FAILED(Tell(&offset)) || WABT_FAILED(result->Seek(offset)))
+ result.reset();
+
+ return std::move(result);
+}
+
+Result LexerSourceFile::Tell(Offset* out_offset) {
+ if (!file_)
+ return Result::Error;
+
+ long offset = ftell(file_);
+ if (offset < 0)
+ return Result::Error;
+
+ *out_offset = offset;
+ return Result::Ok;
+}
+
+size_t LexerSourceFile::Fill(void* dest, size_t size) {
+ if (!file_)
+ return 0;
+ return fread(dest, 1, size, file_);
+}
+
+Result LexerSourceFile::ReadRange(OffsetRange range,
+ std::vector<char>* out_data) {
+ Offset old_offset = 0;
+ CHECK_RESULT(Tell(&old_offset));
+ CHECK_RESULT(Seek(range.start));
+
+ std::vector<char> result(range.size());
+ if (range.size() > 0) {
+ size_t read_size = Fill(result.data(), range.size());
+ if (read_size < range.size())
+ result.resize(read_size);
+ }
+
+ CHECK_RESULT(Seek(old_offset));
+
+ *out_data = std::move(result);
+ return Result::Ok;
+}
+
+Result LexerSourceFile::Seek(Offset offset) {
+ if (!file_)
+ return Result::Error;
+
+ int result = fseek(file_, offset, SEEK_SET);
+ return result < 0 ? Result::Error : Result::Ok;
+}
+
+LexerSourceBuffer::LexerSourceBuffer(const void* data, Offset size)
+ : data_(data), size_(size), read_offset_(0) {}
+
+std::unique_ptr<LexerSource> LexerSourceBuffer::Clone() {
+ LexerSourceBuffer* result = new LexerSourceBuffer(data_, size_);
+ result->read_offset_ = read_offset_;
+ return std::unique_ptr<LexerSource>(result);
+}
+
+Result LexerSourceBuffer::Tell(Offset* out_offset) {
+ *out_offset = read_offset_;
+ return Result::Ok;
+}
+
+size_t LexerSourceBuffer::Fill(void* dest, Offset size) {
+ Offset read_size = std::min(size, size_ - read_offset_);
+ if (read_size > 0) {
+ const void* src = static_cast<const char*>(data_) + read_offset_;
+ memcpy(dest, src, read_size);
+ read_offset_ += read_size;
+ }
+ return read_size;
+}
+
+Result LexerSourceBuffer::ReadRange(OffsetRange range,
+ std::vector<char>* out_data) {
+ OffsetRange clamped = range;
+ clamped.start = std::min(clamped.start, size_);
+ clamped.end = std::min(clamped.end, size_);
+ if (clamped.size()) {
+ std::vector<char> result(clamped.size());
+ const void* src = static_cast<const char*>(data_) + clamped.start;
+ memcpy(result.data(), src, clamped.size());
+ }
+ return Result::Ok;
+}
+
+} // namespace wabt