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