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 |