ttx 0.1.0
Loading...
Searching...
No Matches
escape_sequence_parser.h
Go to the documentation of this file.
1#pragma once
2
3#include "di/container/string/string.h"
4#include "di/container/string/string_view.h"
5#include "di/function/container/function.h"
6#include "di/reflect/prelude.h"
7#include "di/vocab/variant/prelude.h"
8#include "ttx/params.h"
9
10namespace ttx {
12 c32 code_point = 0;
13
14 auto operator==(PrintableCharacter const&) const -> bool = default;
15
16 constexpr friend auto tag_invoke(di::Tag<di::reflect>, di::InPlaceType<PrintableCharacter>) {
17 return di::make_fields<"PrintableCharacter">(di::field<"code_point", &PrintableCharacter::code_point>);
18 }
19};
20
21struct DCS {
22 di::String intermediate;
24 di::String data;
25
26 auto operator==(DCS const&) const -> bool = default;
27
28 constexpr friend auto tag_invoke(di::Tag<di::reflect>, di::InPlaceType<DCS>) {
29 return di::make_fields<"DCS">(di::field<"intermediate", &DCS::intermediate>, di::field<"params", &DCS::params>,
30 di::field<"data", &DCS::data>);
31 }
32};
33
34struct OSC {
35 di::String data;
36 di::StringView terminator; // Either BEL (\a) or ST (ESC \‍)
37
38 auto operator==(OSC const&) const -> bool = default;
39
40 constexpr friend auto tag_invoke(di::Tag<di::reflect>, di::InPlaceType<OSC>) {
41 return di::make_fields<"OSC">(di::field<"data", &OSC::data>, di::field<"terminator", &OSC::terminator>);
42 }
43};
44
45struct APC {
46 di::String data;
47
48 auto operator==(APC const&) const -> bool = default;
49
50 constexpr friend auto tag_invoke(di::Tag<di::reflect>, di::InPlaceType<APC>) {
51 return di::make_fields<"APC">(di::field<"data", &APC::data>);
52 }
53};
54
55struct CSI {
56 di::String intermediate;
58 c32 terminator = 0;
59
60 auto operator==(CSI const&) const -> bool = default;
61
62 constexpr friend auto tag_invoke(di::Tag<di::reflect>, di::InPlaceType<CSI>) {
63 return di::make_fields<"CSI">(di::field<"intermediate", &CSI::intermediate>, di::field<"params", &CSI::params>,
64 di::field<"terminator", &CSI::terminator>);
65 }
66};
67
68struct Escape {
69 di::String intermediate;
70 c32 terminator = 0;
71
72 auto operator==(Escape const&) const -> bool = default;
73
74 constexpr friend auto tag_invoke(di::Tag<di::reflect>, di::InPlaceType<Escape>) {
75 return di::make_fields<"Escape">(di::field<"intermediate", &Escape::intermediate>,
76 di::field<"terminator", &Escape::terminator>);
77 }
78};
79
81 u32 code_point { 0 }; // Not a c32, so that it will be printed as a decimal.
82 bool was_in_escape { false }; // This is true if the control character occurred in the middle of an escape sequence.
83
84 auto operator==(ControlCharacter const&) const -> bool = default;
85
86 constexpr friend auto tag_invoke(di::Tag<di::reflect>, di::InPlaceType<ControlCharacter>) {
87 return di::make_fields<"ControlCharacter">(di::field<"code_point", &ControlCharacter::code_point>,
88 di::field<"was_in_escape", &ControlCharacter::was_in_escape>);
89 }
90};
91
92using ParserResult = di::Variant<PrintableCharacter, DCS, OSC, APC, CSI, Escape, ControlCharacter>;
93
95public:
96 enum class Mode {
99 };
100
101 auto parse_application_escape_sequences(di::StringView data) -> di::Vector<ParserResult>;
102 auto parse_input_escape_sequences(di::StringView data, bool flush = true) -> di::Vector<ParserResult>;
103
104private:
105// VT500-Series parser states from https://vt100.net/emu/dec_ansi_parser
106// For parsing input escape sequences, the following state is added:
107// - SS3
108// Additionally, non CSI related states are ignored when parsing input
109// sequences.
110#define __ENUMERATE_STATES(M) \
111 M(Ground, ground) \
112 M(Escape, escape) \
113 M(EscapeIntermediate, escape_intermediate) \
114 M(CsiEntry, csi_entry) \
115 M(CsiParam, csi_param) \
116 M(CsiIntermediate, csi_intermediate) \
117 M(CsiIgnore, csi_ignore) \
118 M(DcsEntry, dcs_entry) \
119 M(DcsParam, dcs_param) \
120 M(DcsIntermediate, dcs_intermediate) \
121 M(DcsPassthrough, dcs_passthrough) \
122 M(DcsIgnore, dcs_ignore) \
123 M(OscString, osc_string) \
124 M(ApcString, apc_string) \
125 M(SosPmString, sos_pm_string) \
126 M(Ss3, ss3)
127
128 enum class State {
129#define __ENUMERATE_STATE(N, n) N,
131#undef __ENUMERATE_STATE
132 };
133
134#define __ENUMERATE_STATE(N, n) void n##_state(c32 code_point);
135 __ENUMERATE_STATES(__ENUMERATE_STATE)
136#undef __ENUMERATE_STATE
137
138 void ignore(c32 code_point);
139 void print(c32 code_point);
140 void execute(c32 code_point);
141 void clear();
142 void collect(c32 code_point);
143 void param(c32 code_point);
144 void esc_dispatch(c32 code_point);
145 void csi_dispatch(c32 code_point);
146 void hook();
147 void put(c32 code_point);
148 void unhook();
149 void osc_start();
150 void osc_put(c32 code_point);
151 void osc_end();
152 void apc_start();
153 void apc_put(c32 code_point);
154 void apc_end();
155 void output_ss3(c32 code_point);
156
157 void transition(State state);
158
159 void on_input(c32 code_point);
160
161 void add_param(di::Optional<u32> param);
162
163 State m_last_state { State::Ground };
164 State m_next_state { State::Ground };
165 di::Function<void()> m_on_state_exit;
166
167 di::String m_intermediate;
168 di::String m_current_param;
169 di::String m_data;
170 Params m_params;
171 bool m_last_separator_was_colon { false };
172 bool m_saw_legacy_string_terminator { false };
173 Mode m_mode { Mode::Application };
174 di::Vector<ParserResult> m_result;
175};
176}
Definition escape_sequence_parser.h:94
auto parse_input_escape_sequences(di::StringView data, bool flush=true) -> di::Vector< ParserResult >
Definition escape_sequence_parser.cpp:659
auto parse_application_escape_sequences(di::StringView data) -> di::Vector< ParserResult >
Definition escape_sequence_parser.cpp:650
Mode
Definition escape_sequence_parser.h:96
@ Input
Definition escape_sequence_parser.h:98
@ Application
Definition escape_sequence_parser.h:97
Definition params.h:67
#define __ENUMERATE_STATES(M)
Definition escape_sequence_parser.h:110
#define __ENUMERATE_STATE(N, n)
Definition escape_sequence_parser.h:129
Definition test_params.cpp:4
Definition cursor_style.h:5
di::Variant< PrintableCharacter, DCS, OSC, APC, CSI, Escape, ControlCharacter > ParserResult
Definition escape_sequence_parser.h:92
Definition escape_sequence_parser.h:45
constexpr friend auto tag_invoke(di::Tag< di::reflect >, di::InPlaceType< APC >)
Definition escape_sequence_parser.h:50
auto operator==(APC const &) const -> bool=default
di::String data
Definition escape_sequence_parser.h:46
Definition escape_sequence_parser.h:55
constexpr friend auto tag_invoke(di::Tag< di::reflect >, di::InPlaceType< CSI >)
Definition escape_sequence_parser.h:62
auto operator==(CSI const &) const -> bool=default
c32 terminator
Definition escape_sequence_parser.h:58
di::String intermediate
Definition escape_sequence_parser.h:56
Params params
Definition escape_sequence_parser.h:57
Definition escape_sequence_parser.h:80
bool was_in_escape
Definition escape_sequence_parser.h:82
constexpr friend auto tag_invoke(di::Tag< di::reflect >, di::InPlaceType< ControlCharacter >)
Definition escape_sequence_parser.h:86
auto operator==(ControlCharacter const &) const -> bool=default
u32 code_point
Definition escape_sequence_parser.h:81
Definition escape_sequence_parser.h:21
constexpr friend auto tag_invoke(di::Tag< di::reflect >, di::InPlaceType< DCS >)
Definition escape_sequence_parser.h:28
di::String intermediate
Definition escape_sequence_parser.h:22
auto operator==(DCS const &) const -> bool=default
Params params
Definition escape_sequence_parser.h:23
di::String data
Definition escape_sequence_parser.h:24
Definition escape_sequence_parser.h:68
c32 terminator
Definition escape_sequence_parser.h:70
auto operator==(Escape const &) const -> bool=default
constexpr friend auto tag_invoke(di::Tag< di::reflect >, di::InPlaceType< Escape >)
Definition escape_sequence_parser.h:74
di::String intermediate
Definition escape_sequence_parser.h:69
Definition escape_sequence_parser.h:34
auto operator==(OSC const &) const -> bool=default
di::StringView terminator
Definition escape_sequence_parser.h:36
di::String data
Definition escape_sequence_parser.h:35
constexpr friend auto tag_invoke(di::Tag< di::reflect >, di::InPlaceType< OSC >)
Definition escape_sequence_parser.h:40
Definition escape_sequence_parser.h:11
constexpr friend auto tag_invoke(di::Tag< di::reflect >, di::InPlaceType< PrintableCharacter >)
Definition escape_sequence_parser.h:16
c32 code_point
Definition escape_sequence_parser.h:12
auto operator==(PrintableCharacter const &) const -> bool=default