1 /*
2 Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License, version 2.0,
6 as published by the Free Software Foundation.
7
8 This program is also distributed with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have included with MySQL.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25 #include "mysql/harness/vt100.h"
26
27 #include <string>
28 #include <vector>
29
30 namespace Vt100 {
31 #define ESC "\x1b"
32 constexpr const char BEL{0x07};
33 constexpr const char CSI[]{ESC "["}; // Control Sequence Introducer
34 constexpr const char OSC[]{ESC "]"}; // Operating system command
35
reset()36 std::string reset() { return ESC "c"; }
37
38 template <Vt100::value_type N>
not_num_to_string(Vt100::value_type n)39 static std::string not_num_to_string(Vt100::value_type n) {
40 return (n == N) ? "" : std::to_string(n);
41 }
42
csi(Csi c,const std::string & s)43 static std::string csi(Csi c, const std::string &s) {
44 return CSI + s + static_cast<char>(c);
45 }
46
csi(Csi c)47 static std::string csi(Csi c) { return csi(c, ""); }
48
49 template <Vt100::value_type DEF>
csi_default(Csi c,Vt100::value_type n)50 static std::string csi_default(Csi c, Vt100::value_type n) {
51 return csi(c, not_num_to_string<DEF>(n));
52 }
53
54 template <Vt100::value_type DEF, size_t N>
csi_default(Csi c,const std::array<Vt100::value_type,N> & fields)55 static std::string csi_default(Csi c,
56 const std::array<Vt100::value_type, N> &fields) {
57 std::string s;
58 bool is_first = true;
59 for (const auto &field : fields) {
60 if (!is_first) {
61 s += ";";
62 }
63 s += not_num_to_string<DEF>(field);
64 is_first = false;
65 }
66 return csi(c, s);
67 }
68
cursor_up(Vt100::value_type n)69 std::string cursor_up(Vt100::value_type n) {
70 return csi_default<1>(Csi::CUU, n);
71 }
cursor_down(Vt100::value_type n)72 std::string cursor_down(Vt100::value_type n) {
73 return csi_default<1>(Csi::CUD, n);
74 }
cursor_forward(Vt100::value_type n)75 std::string cursor_forward(Vt100::value_type n) {
76 return csi_default<1>(Csi::CUF, n);
77 }
cursor_back(Vt100::value_type n)78 std::string cursor_back(Vt100::value_type n) {
79 return csi_default<1>(Csi::CUB, n);
80 }
cursor_next_line(Vt100::value_type n)81 std::string cursor_next_line(Vt100::value_type n) {
82 return csi_default<1>(Csi::CNL, n);
83 }
cursor_prev_line(Vt100::value_type n)84 std::string cursor_prev_line(Vt100::value_type n) {
85 return csi_default<1>(Csi::CPL, n);
86 }
cursor_abs_col(Vt100::value_type n)87 std::string cursor_abs_col(Vt100::value_type n) {
88 return csi_default<1>(Csi::CHA, n);
89 }
cursor_abs_row(Vt100::value_type n)90 std::string cursor_abs_row(Vt100::value_type n) {
91 return csi_default<1>(Csi::VPA, n);
92 }
cursor_abs_pos(Vt100::value_type row,Vt100::value_type col)93 std::string cursor_abs_pos(Vt100::value_type row, Vt100::value_type col) {
94 return csi_default<1, 2>(Csi::CUP, {row, col});
95 }
96
erase_in_display(Vt100::Erase n)97 std::string erase_in_display(Vt100::Erase n) {
98 return csi_default<0>(Csi::ED, static_cast<Vt100::value_type>(n));
99 }
erase_in_line(Vt100::Erase n)100 std::string erase_in_line(Vt100::Erase n) {
101 return csi_default<0>(Csi::EL, static_cast<Vt100::value_type>(n));
102 }
scroll_up(Vt100::value_type n)103 std::string scroll_up(Vt100::value_type n) {
104 return csi_default<1>(Csi::SU, n);
105 }
scroll_down(Vt100::value_type n)106 std::string scroll_down(Vt100::value_type n) {
107 return csi_default<1>(Csi::SD, n);
108 }
save_cursor_pos()109 std::string save_cursor_pos() { return csi(Csi::SC); }
restore_cursor_pos()110 std::string restore_cursor_pos() { return csi(Csi::SR); }
111
window_title(const std::string & title)112 std::string window_title(const std::string &title) {
113 return OSC + std::to_string(2) + ";" + title + BEL;
114 }
115
116 /**
117 * VT100, 7-bit colors
118 */
render(Vt100::value_type n)119 static std::string render(Vt100::value_type n) {
120 return csi_default<0>(Csi::SGR, n);
121 }
122
123 template <Vt100::value_type DEF, size_t N>
render(const std::array<Vt100::value_type,N> & fields)124 static std::string render(const std::array<Vt100::value_type, N> &fields) {
125 return csi_default<DEF>(Csi::SGR, fields);
126 }
127
render(Render r)128 std::string render(Render r) {
129 return render(static_cast<Vt100::value_type>(r));
130 }
131
foreground(Color c)132 std::string foreground(Color c) {
133 return render(static_cast<Vt100::value_type>(Render::ForegroundBlack) +
134 static_cast<Vt100::value_type>(c));
135 }
136
foreground(const Rgb & rgb)137 std::string foreground(const Rgb &rgb) {
138 return render<65535, 5>(
139 {static_cast<Vt100::value_type>(Render::ForegroundExtended), 2, rgb[0],
140 rgb[1], rgb[2]});
141 }
142
foreground(uint8_t ndx)143 std::string foreground(uint8_t ndx) {
144 return render<0, 3>(
145 {static_cast<Vt100::value_type>(Render::ForegroundExtended), 5, ndx});
146 }
147
background(Color c)148 std::string background(Color c) {
149 return render(static_cast<int>(Render::BackgroundBlack) +
150 static_cast<int>(c));
151 }
152
background(const Rgb & rgb)153 std::string background(const Rgb &rgb) {
154 return render<65535, 5>(
155 {static_cast<Vt100::value_type>(Render::BackgroundExtended), 2, rgb[0],
156 rgb[1], rgb[2]});
157 }
158
background(uint8_t ndx)159 std::string background(uint8_t ndx) {
160 return render<0, 3>(
161 {static_cast<Vt100::value_type>(Render::BackgroundExtended), 5, ndx});
162 }
163
164 } // namespace Vt100
165