| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include "lexer/buffer.h" | ||
| 2 | |||
| 3 | #if __linux__ | ||
| 4 | # define __STDC_WANT_LIB_EXT1__ 1 | ||
| 5 | # define __STDC_WANT_SECURE_LIB__ 1 | ||
| 6 | #endif | ||
| 7 | |||
| 8 | #include <cstdio> | ||
| 9 | |||
| 10 | namespace lython { | ||
| 11 | |||
| 12 | FILE* internal_fopen(String filename) { | ||
| 13 | FILE* file; | ||
| 14 | |||
| 15 | #if (defined __STDC_LIB_EXT1__) || BUILD_WINDOWS | ||
| 16 | auto err = fopen_s(&file, filename.c_str(), "r"); | ||
| 17 | if (err != 0) { | ||
| 18 | throw FileError("{}: File `{}` does not exist", filename); | ||
| 19 | } | ||
| 20 | #else | ||
| 21 | 5 | file = fopen(filename.c_str(), "r"); | |
| 22 | |||
| 23 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
|
5 | if (!file) { |
| 24 | ✗ | throw FileError("{}: File `{}` does not exist", filename); | |
| 25 | } | ||
| 26 | #endif | ||
| 27 | |||
| 28 | 5 | return file; | |
| 29 | } | ||
| 30 | |||
| 31 | AbstractBuffer::~AbstractBuffer() {} | ||
| 32 | |||
| 33 | FileBuffer::FileBuffer(String const& name): _file_name(name) { | ||
| 34 | |||
| 35 |
2/2✓ Branch 1 taken 5 times.
✓ Branch 4 taken 5 times.
|
5 | _file = internal_fopen(_file_name); |
| 36 | |||
| 37 |
1/1✓ Branch 1 taken 5 times.
|
5 | init(); |
| 38 | 5 | } | |
| 39 | |||
| 40 | FileBuffer::~FileBuffer() { fclose(_file); } | ||
| 41 | |||
| 42 | void FileBuffer::reset() { | ||
| 43 | ✗ | fseek(_file, 0, SEEK_SET); | |
| 44 | ✗ | AbstractBuffer::reset(); | |
| 45 | ✗ | } | |
| 46 | |||
| 47 | String FileBuffer::getline(int start_line, int end_line) { | ||
| 48 | fpos_t pos; | ||
| 49 | ✗ | fgetpos(_file, &pos); | |
| 50 | //-- | ||
| 51 | |||
| 52 | ✗ | String result; | |
| 53 | ✗ | result.reserve(128); | |
| 54 | ✗ | fseek(_file, start_line, SEEK_SET); | |
| 55 | |||
| 56 | ✗ | char c = fgetc(_file); | |
| 57 | |||
| 58 | ✗ | while (c != '\n') { | |
| 59 | ✗ | result.push_back(c); | |
| 60 | ✗ | c = fgetc(_file); | |
| 61 | } | ||
| 62 | |||
| 63 | // -- | ||
| 64 | ✗ | fsetpos(_file, &pos); | |
| 65 | ✗ | return result; | |
| 66 | ✗ | } | |
| 67 | |||
| 68 | StringBuffer::~StringBuffer() {} | ||
| 69 | |||
| 70 | ConsoleBuffer::~ConsoleBuffer() {} | ||
| 71 | |||
| 72 | String read_file(String const& name) { | ||
| 73 | ✗ | FILE* file = internal_fopen(name); | |
| 74 | |||
| 75 | ✗ | if (!file) | |
| 76 | ✗ | throw FileError("{}: File `{}` does not exist", name); | |
| 77 | |||
| 78 | ✗ | Array<String> data; | |
| 79 | |||
| 80 | ✗ | size_t const buffer_size = 8192; | |
| 81 | ✗ | size_t read = 0; | |
| 82 | ✗ | size_t total = 0; | |
| 83 | |||
| 84 | do { | ||
| 85 | ✗ | data.emplace_back(buffer_size, ' '); | |
| 86 | ✗ | auto& buffer = *(data.end() - 1); | |
| 87 | |||
| 88 | ✗ | read = fread(&buffer[0], 1, buffer_size, file); | |
| 89 | |||
| 90 | ✗ | total += read; | |
| 91 | ✗ | } while (read == buffer_size); | |
| 92 | |||
| 93 | ✗ | String aggregated(total, ' '); | |
| 94 | |||
| 95 | ✗ | ptrdiff_t start = 0; | |
| 96 | ✗ | for (auto& segment: data) { | |
| 97 | ✗ | std::copy(std::begin(segment), std::end(segment), std::begin(aggregated) + start); | |
| 98 | |||
| 99 | ✗ | start += segment.size(); | |
| 100 | } | ||
| 101 | |||
| 102 | kwdebug("read {}", aggregated); | ||
| 103 | ✗ | return aggregated; | |
| 104 | ✗ | } | |
| 105 | |||
| 106 | } // namespace lython | ||
| 107 |