1 /*
2  * Copyright © 2015 David Herrmann <dh.herrmann@gmail.com>
3  * Copyright © 2018 Christian Persch
4  *
5  * This library is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Lesser General Public License as published
7  * by the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with this library.  If not, see <https://www.gnu.org/licenses/>.
17  */
18 
19 #pragma once
20 
21 #include <cstdint>
22 #include <cstdio>
23 
24 #include "parser-arg.hh"
25 #include "parser-string.hh"
26 
27 struct vte_parser_t;
28 struct vte_seq_t;
29 
30 /*
31  * Parsers
32  * The vte_parser object parses control-sequences for both host and terminal
33  * side. Based on this parser, there is a set of command-parsers that take a
34  * vte_seq sequence and returns the command it represents. This is different
35  * for host and terminal side, and so far we only provide the terminal side, as
36  * host side is not used by anyone.
37  */
38 
39 #define VTE_PARSER_ARG_MAX (32)
40 
41 enum {
42         VTE_SEQ_NONE,        /* placeholder, no sequence parsed */
43 
44         VTE_SEQ_IGNORE,      /* no-op character */
45         VTE_SEQ_GRAPHIC,     /* graphic character */
46         VTE_SEQ_CONTROL,     /* control character */
47         VTE_SEQ_ESCAPE,      /* escape sequence */
48         VTE_SEQ_CSI,         /* control sequence function */
49         VTE_SEQ_DCS,         /* device control string */
50         VTE_SEQ_OSC,         /* operating system control */
51         VTE_SEQ_SCI,         /* single character control function */
52         VTE_SEQ_APC,         /* application program command */
53         VTE_SEQ_PM,          /* privacy message */
54         VTE_SEQ_SOS,         /* start of string */
55 
56         VTE_SEQ_N,
57 };
58 
59 enum {
60         VTE_SEQ_INTERMEDIATE_CHAR_NONE    = 0,
61 
62         VTE_SEQ_INTERMEDIATE_CHAR_SPACE   = ' ',  /* 02/00 */
63         VTE_SEQ_INTERMEDIATE_CHAR_BANG    = '!',  /* 02/01 */
64         VTE_SEQ_INTERMEDIATE_CHAR_DQUOTE  = '"',  /* 02/02 */
65         VTE_SEQ_INTERMEDIATE_CHAR_HASH    = '#',  /* 02/03 */
66         VTE_SEQ_INTERMEDIATE_CHAR_CASH    = '$',  /* 02/04 */
67         VTE_SEQ_INTERMEDIATE_CHAR_PERCENT = '%',  /* 02/05 */
68         VTE_SEQ_INTERMEDIATE_CHAR_AND     = '&',  /* 02/06 */
69         VTE_SEQ_INTERMEDIATE_CHAR_SQUOTE  = '\'', /* 02/07 */
70         VTE_SEQ_INTERMEDIATE_CHAR_POPEN   = '(',  /* 02/08 */
71         VTE_SEQ_INTERMEDIATE_CHAR_PCLOSE  = ')',  /* 02/09 */
72         VTE_SEQ_INTERMEDIATE_CHAR_MULT    = '*',  /* 02/10 */
73         VTE_SEQ_INTERMEDIATE_CHAR_PLUS    = '+',  /* 02/11 */
74         VTE_SEQ_INTERMEDIATE_CHAR_COMMA   = ',',  /* 02/12 */
75         VTE_SEQ_INTERMEDIATE_CHAR_MINUS   = '-',  /* 02/13 */
76         VTE_SEQ_INTERMEDIATE_CHAR_DOT     = '.',  /* 02/14 */
77         VTE_SEQ_INTERMEDIATE_CHAR_SLASH   = '/',  /* 02/15 */
78 };
79 
80 enum {
81         VTE_SEQ_PARAMETER_CHAR_NONE  = 0,
82 
83         /* Numbers; not used         *  03/00..03/09 */
84         /* COLON is reserved         = ':'   * 03/10 */
85         /* SEMICOLON is reserved     = ';'   * 03/11 */
86         VTE_SEQ_PARAMETER_CHAR_LT    = '<', /* 03/12 */
87         VTE_SEQ_PARAMETER_CHAR_EQUAL = '=', /* 03/13 */
88         VTE_SEQ_PARAMETER_CHAR_GT    = '>', /* 03/14 */
89         VTE_SEQ_PARAMETER_CHAR_WHAT  = '?'  /* 03/15 */
90 };
91 
92 #define VTE_SEQ_MAKE_INTERMEDIATE(c) ((c) - ' ' + 1)
93 
94 enum {
95         VTE_SEQ_INTERMEDIATE_NONE      = 0,
96 
97         VTE_SEQ_INTERMEDIATE_SPACE     = VTE_SEQ_MAKE_INTERMEDIATE(VTE_SEQ_INTERMEDIATE_CHAR_SPACE  ),
98         VTE_SEQ_INTERMEDIATE_BANG      = VTE_SEQ_MAKE_INTERMEDIATE(VTE_SEQ_INTERMEDIATE_CHAR_BANG   ),
99         VTE_SEQ_INTERMEDIATE_DQUOTE    = VTE_SEQ_MAKE_INTERMEDIATE(VTE_SEQ_INTERMEDIATE_CHAR_DQUOTE ),
100         VTE_SEQ_INTERMEDIATE_HASH      = VTE_SEQ_MAKE_INTERMEDIATE(VTE_SEQ_INTERMEDIATE_CHAR_HASH   ),
101         VTE_SEQ_INTERMEDIATE_CASH      = VTE_SEQ_MAKE_INTERMEDIATE(VTE_SEQ_INTERMEDIATE_CHAR_CASH   ),
102         VTE_SEQ_INTERMEDIATE_PERCENT   = VTE_SEQ_MAKE_INTERMEDIATE(VTE_SEQ_INTERMEDIATE_CHAR_PERCENT),
103         VTE_SEQ_INTERMEDIATE_AND       = VTE_SEQ_MAKE_INTERMEDIATE(VTE_SEQ_INTERMEDIATE_CHAR_AND    ),
104         VTE_SEQ_INTERMEDIATE_SQUOTE    = VTE_SEQ_MAKE_INTERMEDIATE(VTE_SEQ_INTERMEDIATE_CHAR_SQUOTE ),
105         VTE_SEQ_INTERMEDIATE_POPEN     = VTE_SEQ_MAKE_INTERMEDIATE(VTE_SEQ_INTERMEDIATE_CHAR_POPEN  ),
106         VTE_SEQ_INTERMEDIATE_PCLOSE    = VTE_SEQ_MAKE_INTERMEDIATE(VTE_SEQ_INTERMEDIATE_CHAR_PCLOSE ),
107         VTE_SEQ_INTERMEDIATE_MULT      = VTE_SEQ_MAKE_INTERMEDIATE(VTE_SEQ_INTERMEDIATE_CHAR_MULT   ),
108         VTE_SEQ_INTERMEDIATE_PLUS      = VTE_SEQ_MAKE_INTERMEDIATE(VTE_SEQ_INTERMEDIATE_CHAR_PLUS   ),
109         VTE_SEQ_INTERMEDIATE_COMMA     = VTE_SEQ_MAKE_INTERMEDIATE(VTE_SEQ_INTERMEDIATE_CHAR_COMMA  ),
110         VTE_SEQ_INTERMEDIATE_MINUS     = VTE_SEQ_MAKE_INTERMEDIATE(VTE_SEQ_INTERMEDIATE_CHAR_MINUS  ),
111         VTE_SEQ_INTERMEDIATE_DOT       = VTE_SEQ_MAKE_INTERMEDIATE(VTE_SEQ_INTERMEDIATE_CHAR_DOT    ),
112         VTE_SEQ_INTERMEDIATE_SLASH     = VTE_SEQ_MAKE_INTERMEDIATE(VTE_SEQ_INTERMEDIATE_CHAR_SLASH  ),
113 };
114 
115 #define VTE_SEQ_MAKE_PARAMETER(c) ('?' - (c) + 1)
116 
117 enum {
118         VTE_SEQ_PARAMETER_NONE  = 0,
119 
120         VTE_SEQ_PARAMETER_LT    = VTE_SEQ_MAKE_PARAMETER(VTE_SEQ_PARAMETER_CHAR_LT   ),
121         VTE_SEQ_PARAMETER_EQUAL = VTE_SEQ_MAKE_PARAMETER(VTE_SEQ_PARAMETER_CHAR_EQUAL),
122         VTE_SEQ_PARAMETER_GT    = VTE_SEQ_MAKE_PARAMETER(VTE_SEQ_PARAMETER_CHAR_GT   ),
123         VTE_SEQ_PARAMETER_WHAT  = VTE_SEQ_MAKE_PARAMETER(VTE_SEQ_PARAMETER_CHAR_WHAT ),
124 };
125 
126 enum {
127 #define _VTE_CMD(cmd) VTE_CMD_##cmd,
128 #define _VTE_NOP(cmd) VTE_CMD_##cmd,
129 #include "parser-cmd.hh"
130 #undef _VTE_CMD
131 #undef _VTE_NOP
132 
133         VTE_CMD_N,
134         VTE_CMD_NOP_FIRST = VTE_CMD_ACK
135 };
136 
137 enum {
138 #define _VTE_REPLY(cmd,type,final,pintro,intermediate,code) VTE_REPLY_##cmd,
139 #include "parser-reply.hh"
140 #undef _VTE_REPLY
141 
142         VTE_REPLY_N
143 };
144 
145 enum {
146 #define _VTE_CHARSET_PASTE(name) VTE_CHARSET_##name,
147 #define _VTE_CHARSET(name) _VTE_CHARSET_PASTE(name)
148 #define _VTE_CHARSET_ALIAS_PASTE(name1,name2) VTE_CHARSET_##name1 = VTE_CHARSET_##name2,
149 #define _VTE_CHARSET_ALIAS(name1,name2) _VTE_CHARSET_ALIAS_PASTE(name1,name2)
150 #include "parser-charset.hh"
151 #undef _VTE_CHARSET_PASTE
152 #undef _VTE_CHARSET
153 #undef _VTE_CHARSET_ALIAS_PASTE
154 #undef _VTE_CHARSET_ALIAS
155 };
156 
157 enum {
158 #define _VTE_OSC(osc,value) VTE_OSC_##osc = value,
159 #include "parser-osc.hh"
160 #undef _VTE_OSC
161 
162         VTE_OSC_N
163 };
164 
165 enum {
166 #define _VTE_SGR(name, value) VTE_SGR_##name = value,
167 #define _VTE_NGR(...)
168 #include "parser-sgr.hh"
169 #undef _VTE_SGR
170 #undef _VTE_NGR
171 };
172 
173 #pragma GCC diagnostic push
174 #pragma GCC diagnostic ignored "-Wmissing-declarations"
175 enum {
176 #define _VTE_SGR(name, value) VTE_DECSGR_##name = value,
177 #define _VTE_NGR(...)
178 #include "parser-decsgr.hh"
179 #undef _VTE_SGR
180 #undef _VTE_NGR
181 };
182 #pragma GCC diagnostic pop
183 
184 #define VTE_CHARSET_CHARSET_MASK   ((1U << 16) - 1U)
185 #define VTE_CHARSET_SLOT_OFFSET    (16)
186 #define VTE_CHARSET_GET_CHARSET(c) ((c) & VTE_CHARSET_CHARSET_MASK)
187 #define VTE_CHARSET_GET_SLOT(c)    ((c) >> VTE_CHARSET_SLOT_OFFSET)
188 
189 enum {
190       VTE_DISPATCH_UNRIPE = 1u << 0,
191 };
192 
193 struct vte_seq_t {
194         unsigned int type;
195         unsigned int command;
196         uint32_t terminator;
197         unsigned int intermediates;
198         unsigned int n_intermediates;
199         unsigned int charset;
200         unsigned int n_args;
201         unsigned int n_final_args;
202         vte_seq_arg_t args[VTE_PARSER_ARG_MAX];
203         vte_seq_string_t arg_str;
204         uint32_t introducer;
205         uint32_t st;
206 };
207 
208 struct vte_parser_t {
209         vte_seq_t seq;
210         unsigned int state;
211         bool dispatch_unripe;
212 };
213 
214 void vte_parser_init(vte_parser_t* parser);
215 void vte_parser_deinit(vte_parser_t* parser);
216 int vte_parser_feed(vte_parser_t* parser,
217                     uint32_t raw);
218 void vte_parser_reset(vte_parser_t* parser);
219 void vte_parser_set_dispatch_unripe(vte_parser_t* parser,
220                                     bool enable);
221 void vte_parser_ignore_until_st(vte_parser_t* parser);
222