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