diff options
author | Ben Smith <binjimin@gmail.com> | 2017-06-02 13:35:24 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-06-02 13:35:24 -0700 |
commit | 3c6c7a83c5bcf4f6654d4646652ace2c1468f0fb (patch) | |
tree | e595fdac4cfb86796b50db01f0a807a451b1cfcb /src/lexer-source.cc | |
parent | c37a2d912e83f9298c64c61e1e92aff8042566e1 (diff) | |
download | wabt-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.cc | 131 |
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 |