-
Notifications
You must be signed in to change notification settings - Fork 0
/
textrom.cpp
92 lines (75 loc) · 1.85 KB
/
textrom.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#include <array>
#include <cerrno>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <optional>
#include <string>
#include <vector>
int main(int argc, char **argv) {
constexpr size_t BUFFER_SIZE = 1024;
constexpr size_t WIDTH = 40;
constexpr size_t HEIGHT = 22;
std::freopen(nullptr, "rb", stdin);
if (std::ferror(stdin))
throw std::runtime_error(std::strerror(errno));
std::size_t len;
std::array<char, BUFFER_SIZE> buf;
std::vector<char> input;
while (0 < (len = std::fread(buf.data(), sizeof(buf[0]), buf.size(), stdin))) {
if (std::ferror(stdin) && !std::feof(stdin))
throw std::runtime_error(std::strerror(errno));
input.insert(input.end(), buf.data(), buf.data() + len);
}
std::array<char, WIDTH> arr;
std::vector<decltype(arr)> lines;
arr.fill(' ');
size_t pos = 0;
std::array<char, WIDTH> empty = arr;
auto pad = [&] {
const size_t to_add = (HEIGHT - (lines.size() % HEIGHT)) % HEIGHT;
for (size_t i = 0; i < to_add; ++i)
lines.push_back(empty);
};
auto push = [&] {
lines.push_back(arr);
arr.fill(' ');
pos = 0;
};
size_t timeout = 0;
for (size_t i = 0; i < input.size(); ++i) {
const char ch = input[i];
std::optional<char> to_add;
if (ch == '\\') {
if (i != input.size() - 1) {
const char next = input[i + 1];
if (next == 's') {
push();
pad();
timeout = 2;
} else if (next == '\\') {
to_add = '\\';
} else
throw std::runtime_error("Invalid escape: " + std::string{ch, next});
} else
to_add = '\\';
} else if (0 < timeout) {
--timeout;
} else if (ch == '\n') {
push();
} else {
to_add = ch;
}
if (to_add) {
if (pos == WIDTH)
throw std::runtime_error("Line too long");
arr[pos++] = *to_add;
}
}
if (pos != 0)
lines.push_back(arr);
pad();
for (const auto &line: lines)
for (const char ch: line)
std::cout << ch;
}