Bug Summary

File:/rootdir/_build/../src/parser-glue.hh
Warning:line 754, column 33
Out of bound memory access (access exceeds upper limit of memory block)

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name parser-test.cc -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=none -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/_build -resource-dir /usr/lib/llvm-14/lib/clang/14.0.6 -I src/test-parser.p -I src -I ../src -I . -I .. -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -D _FILE_OFFSET_BITS=64 -D PARSER_INCLUDE_NOP -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/x86_64-linux-gnu/c++/12 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/backward -internal-isystem /usr/lib/llvm-14/lib/clang/14.0.6/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O3 -Wno-address-of-packed-member -Wno-missing-field-initializers -Wno-packed -Wno-switch-enum -Wno-unused-parameter -Wwrite-strings -std=gnu++17 -fdeprecated-macro -fdebug-compilation-dir=/rootdir/_build -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -fcolor-diagnostics -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2022-12-31-022803-10898-1 -x c++ ../src/parser-test.cc

../src/parser-test.cc

1/*
2 * Copyright © 2017, 2018 Christian Persch
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 3 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
18#include "config.h"
19
20#include <string.h>
21
22#include <algorithm>
23#include <cstddef>
24#include <cstdint>
25#include <string>
26#include <vector>
27
28using namespace std::literals;
29
30#include <glib.h>
31
32#include "parser.hh"
33#include "parser-glue.hh"
34#include "parser-charset-tables.hh"
35
36#ifdef PARSER_INCLUDE_NOP1
37#define _BTE_NOP(...)_BTE_CMD(...) _BTE_CMD(__VA_ARGS__)
38#define _BTE_NOQ(...)_BTE_SEQ(...) _BTE_SEQ(__VA_ARGS__)
39#else
40#define _BTE_NOP(...)_BTE_CMD(...)
41#define _BTE_NOQ(...)_BTE_SEQ(...)
42#endif
43
44using namespace bte::parser;
45
46Parser parser{};
47Sequence seq{parser};
48
49#if 0
50static char const*
51seq_to_str(unsigned int type)
52{
53 switch (type) {
54 case BTE_SEQ_NONE: return "NONE";
55 case BTE_SEQ_IGNORE: return "IGNORE";
56 case BTE_SEQ_GRAPHIC: return "GRAPHIC";
57 case BTE_SEQ_CONTROL: return "CONTROL";
58 case BTE_SEQ_ESCAPE: return "ESCAPE";
59 case BTE_SEQ_CSI: return "CSI";
60 case BTE_SEQ_DCS: return "DCS";
61 case BTE_SEQ_OSC: return "OSC";
62 case BTE_SEQ_APC: return "APC";
63 case BTE_SEQ_PM: return "PM";
64 case BTE_SEQ_SOS: return "SOS";
65 case BTE_SEQ_SCI: return "SCI";
66 default:
67 g_assert_not_reached()do { g_assertion_message_expr (((gchar*) 0), "../src/parser-test.cc"
, 67, ((const char*) (__PRETTY_FUNCTION__)), __null); } while
(0)
;
68 }
69}
70
71static char const*
72cmd_to_str(unsigned int command)
73{
74 switch (command) {
75#define _BTE_CMD(cmd) case BTE_CMD_##cmd: return #cmd;
76#include "parser-cmd.hh"
77#undef _BTE_CMD
78 default:
79 static char buf[32];
80 snprintf(buf, sizeof(buf), "UNKOWN(%u)", command);
81 return buf;
82 }
83}
84
85static char const*
86charset_to_str(unsigned int cs)
87{
88 switch (cs) {
89#define _BTE_CHARSET_PASTE(name) case BTE_CHARSET_##name: return #name;
90#define _BTE_CHARSET(name) _BTE_CHARSET_PASTE(name)
91#define _BTE_CHARSET_ALIAS_PASTE(name1,name2)
92#define _BTE_CHARSET_ALIAS(name1,name2)
93#include "parser-charset.hh"
94#undef _BTE_CHARSET_PASTE
95#undef _BTE_CHARSET
96#undef _BTE_CHARSET_ALIAS_PASTE
97#undef _BTE_CHARSET_ALIAS
98 default:
99 static char buf[32];
100 snprintf(buf, sizeof(buf), "UNKOWN(%u)", cs);
101 return buf;
102 }
103}
104#endif
105
106static const char c0str[][6] = {
107 "NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL",
108 "BS", "HT", "LF", "VT", "FF", "CR", "SO", "SI",
109 "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB",
110 "CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US",
111 "SPACE"
112};
113
114static const char c1str[][5] = {
115 "DEL",
116 "0x80", "0x81", "BPH", "NBH", "0x84", "NEL", "SSA", "ESA",
117 "HTS", "HTJ", "VTS", "PLD", "PLU", "RI", "SS2", "SS3",
118 "DCS", "PU1", "PU2", "STS", "CCH", "MW", "SPA", "EPA",
119 "SOS", "0x99", "SCI", "CSI", "ST", "OSC", "PM", "APC"
120};
121
122static void
123print_escaped(std::u32string const& s)
124{
125 for (auto it : s) {
126 uint32_t c = (char32_t)it;
127
128 if (c <= 0x20)
129 g_print("%s ", c0str[c]);
130 else if (c < 0x7f)
131 g_print("%c ", c);
132 else if (c < 0xa0)
133 g_print("%s ", c1str[c - 0x7f]);
134 else
135 g_print("U+%04X", c);
136 }
137 g_print("\n");
138}
139
140#if 0
141static void
142print_seq()
143{
144 auto c = seq.terminator();
145 if (seq.command() == BTE_CMD_GRAPHIC) {
146 char buf[7];
147 buf[g_unichar_to_utf8(c, buf)] = 0;
148 g_print("%s U+%04X [%s]\n", cmd_to_str(seq.command()),
149 c,
150 g_unichar_isprint(c) ? buf : "�");
151 } else {
152 g_print("%s", cmd_to_str(seq.command()));
153 if (seq.size()) {
154 g_print(" ");
155 for (unsigned int i = 0; i < seq.size(); i++) {
156 if (i > 0)
157 g_print(";");
158 g_print("%d", seq.param(i));
159 }
160 }
161 g_print("\n");
162 }
163}
164#endif
165
166class bte_seq_builder : public u32SequenceBuilder {
167public:
168 bte_seq_builder(unsigned int type,
169 uint32_t f)
170 : u32SequenceBuilder(type, f)
171 {
172 }
173
174 bte_seq_builder(unsigned int type,
175 u32SequenceBuilder::string_type const& str)
176 : u32SequenceBuilder(type)
177 {
178 set_string(str);
179 }
180
181 void set_intermediates(uint32_t* i,
182 unsigned int ni) noexcept
183 {
184 for (unsigned int n = 0; n < ni; ++n)
185 append_intermediate(i[n]);
186 }
187
188
189 void set_params(int* params,
190 unsigned int n) noexcept
191 {
192 for (unsigned int i = 0; i < n; ++i)
193 append_param(params[i]);
194 }
195
196 void print(bool c1 = false) const noexcept
197 {
198 std::u32string s;
199 to_string(s, c1);
200 print_escaped(s);
201 }
202};
203
204static int
205feed_parser(std::u32string const& s)
206{
207 int rv = BTE_SEQ_NONE;
208 for (auto it : s) {
209 rv = parser.feed((uint32_t)(char32_t)it);
210 if (rv < 0)
211 break;
212 }
213 return rv;
214}
215
216static int
217feed_parser(bte_seq_builder& b,
218 bool c1 = false)
219{
220 std::u32string s;
221 b.to_string(s, c1);
222
223 return feed_parser(s);
224}
225
226static void
227test_seq_arg(void)
228{
229 /* Basic test */
230 bte_seq_arg_t arg = BTE_SEQ_ARG_INIT_DEFAULT(0);
231 g_assert_false(bte_seq_arg_started(arg))do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (!(bte_seq_arg_started(arg))) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message (((
gchar*) 0), "../src/parser-test.cc", 231, ((const char*) (__PRETTY_FUNCTION__
)), "'" "bte_seq_arg_started(arg)" "' should be FALSE"); } while
(0)
;
232 g_assert_true(bte_seq_arg_default(arg))do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (bte_seq_arg_default(arg)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message (((
gchar*) 0), "../src/parser-test.cc", 232, ((const char*) (__PRETTY_FUNCTION__
)), "'" "bte_seq_arg_default(arg)" "' should be TRUE"); } while
(0)
;
233
234 bte_seq_arg_push(&arg, '1');
235 bte_seq_arg_push(&arg, '2');
236 bte_seq_arg_push(&arg, '3');
237 bte_seq_arg_finish(&arg);
238
239 g_assert_cmpint(bte_seq_arg_value(arg), ==, 123)do { gint64 __n1 = (bte_seq_arg_value(arg)), __n2 = (123); if
(__n1 == __n2) ; else g_assertion_message_cmpnum (((gchar*) 0
), "../src/parser-test.cc", 239, ((const char*) (__PRETTY_FUNCTION__
)), "bte_seq_arg_value(arg)" " " "==" " " "123", (long double
) __n1, "==", (long double) __n2, 'i'); } while (0)
;
240 g_assert_false(bte_seq_arg_default(arg))do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (!(bte_seq_arg_default(arg))) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message (((
gchar*) 0), "../src/parser-test.cc", 240, ((const char*) (__PRETTY_FUNCTION__
)), "'" "bte_seq_arg_default(arg)" "' should be FALSE"); } while
(0)
;
241
242 /* Test max value */
243 arg = BTE_SEQ_ARG_INIT_DEFAULT(0);
244 bte_seq_arg_push(&arg, '6');
245 bte_seq_arg_push(&arg, '5');
246 bte_seq_arg_push(&arg, '5');
247 bte_seq_arg_push(&arg, '3');
248 bte_seq_arg_push(&arg, '6');
249 bte_seq_arg_finish(&arg);
250
251 g_assert_cmpint(bte_seq_arg_value(arg), ==, 65535)do { gint64 __n1 = (bte_seq_arg_value(arg)), __n2 = (65535); if
(__n1 == __n2) ; else g_assertion_message_cmpnum (((gchar*) 0
), "../src/parser-test.cc", 251, ((const char*) (__PRETTY_FUNCTION__
)), "bte_seq_arg_value(arg)" " " "==" " " "65535", (long double
) __n1, "==", (long double) __n2, 'i'); } while (0)
;
252}
253
254static void
255test_seq_string(void)
256{
257 bte_seq_string_t str;
258 bte_seq_string_init(&str);
259
260 size_t len;
261 auto buf = bte_seq_string_get(&str, &len);
262 g_assert_cmpuint(len, ==, 0)do { guint64 __n1 = (len), __n2 = (0); if (__n1 == __n2) ; else
g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 262, ((const char*) (__PRETTY_FUNCTION__)), "len" " " "==" " "
"0", (long double) __n1, "==", (long double) __n2, 'i'); } while
(0)
;
263
264 for (unsigned int i = 0; i < BTE_SEQ_STRING_MAX_CAPACITY(1 << 12); ++i) {
265 auto rv = bte_seq_string_push(&str, 0xfffdU);
266 g_assert_true(rv)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (rv) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_
; }), 1)) ; else g_assertion_message (((gchar*) 0), "../src/parser-test.cc"
, 266, ((const char*) (__PRETTY_FUNCTION__)), "'" "rv" "' should be TRUE"
); } while (0)
;
267
268 buf = bte_seq_string_get(&str, &len);
269 g_assert_cmpuint(len, ==, i + 1)do { guint64 __n1 = (len), __n2 = (i + 1); if (__n1 == __n2) ;
else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 269, ((const char*) (__PRETTY_FUNCTION__)), "len" " " "==" " "
"i + 1", (long double) __n1, "==", (long double) __n2, 'i');
} while (0)
;
270 }
271
272 /* Try one more */
273 auto rv = bte_seq_string_push(&str, 0xfffdU);
274 g_assert_false(rv)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (!(rv)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_
; }), 1)) ; else g_assertion_message (((gchar*) 0), "../src/parser-test.cc"
, 274, ((const char*) (__PRETTY_FUNCTION__)), "'" "rv" "' should be FALSE"
); } while (0)
;
275
276 buf = bte_seq_string_get(&str, &len);
277 for (unsigned int i = 0; i < len; i++)
278 g_assert_cmpuint(buf[i], ==, 0xfffdU)do { guint64 __n1 = (buf[i]), __n2 = (0xfffdU); if (__n1 == __n2
) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 278, ((const char*) (__PRETTY_FUNCTION__)), "buf[i]" " " "=="
" " "0xfffdU", (long double) __n1, "==", (long double) __n2,
'i'); } while (0)
;
279
280 bte_seq_string_reset(&str);
281 buf = bte_seq_string_get(&str, &len);
282 g_assert_cmpuint(len, ==, 0)do { guint64 __n1 = (len), __n2 = (0); if (__n1 == __n2) ; else
g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 282, ((const char*) (__PRETTY_FUNCTION__)), "len" " " "==" " "
"0", (long double) __n1, "==", (long double) __n2, 'i'); } while
(0)
;
283
284 bte_seq_string_free(&str);
285}
286
287static void
288test_seq_control(void)
289{
290 static struct {
291 uint32_t c;
292 unsigned int cmd;
293 } const controls [] = {
294#define _BTE_SEQ(cmd,type,f,pi,ni,i0) { f, BTE_CMD_##cmd },
295#include "parser-c01.hh"
296#undef _BTE_SEQ
297 };
298
299 for (unsigned int i = 0; i < G_N_ELEMENTS(controls)(sizeof (controls) / sizeof ((controls)[0])); i++) {
300 parser.reset();
301 auto rv = parser.feed(controls[i].c);
302 g_assert_cmpuint(rv, ==, BTE_SEQ_CONTROL)do { guint64 __n1 = (rv), __n2 = (BTE_SEQ_CONTROL); if (__n1 ==
__n2) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 302, ((const char*) (__PRETTY_FUNCTION__)), "rv" " " "==" " "
"BTE_SEQ_CONTROL", (long double) __n1, "==", (long double) __n2
, 'i'); } while (0)
;
303 g_assert_cmpuint(controls[i].cmd, ==, seq.command())do { guint64 __n1 = (controls[i].cmd), __n2 = (seq.command())
; if (__n1 == __n2) ; else g_assertion_message_cmpnum (((gchar
*) 0), "../src/parser-test.cc", 303, ((const char*) (__PRETTY_FUNCTION__
)), "controls[i].cmd" " " "==" " " "seq.command()", (long double
) __n1, "==", (long double) __n2, 'i'); } while (0)
;
304 }
305}
306
307static void
308test_seq_esc_invalid(void)
309{
310 /* Tests invalid ESC 0/n and ESC 1/n sequences, which should never result in
311 * an BTE_SEQ_ESCAPE type sequence, but instead always in the C0 control.
312 */
313 for (uint32_t f = 0x0; f < 0x20; f++) {
314 parser.reset();
315
316 bte_seq_builder b{BTE_SEQ_ESCAPE, f};
317 auto rv = feed_parser(b);
318 g_assert_cmpint(rv, !=, BTE_SEQ_ESCAPE)do { gint64 __n1 = (rv), __n2 = (BTE_SEQ_ESCAPE); if (__n1 !=
__n2) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 318, ((const char*) (__PRETTY_FUNCTION__)), "rv" " " "!=" " "
"BTE_SEQ_ESCAPE", (long double) __n1, "!=", (long double) __n2
, 'i'); } while (0)
;
319 }
320}
321
322static void
323test_seq_esc(uint32_t f,
324 uint32_t i[],
325 unsigned int ni)
326{
327 bte_seq_builder b{BTE_SEQ_ESCAPE, f};
328 b.set_intermediates(i, ni);
329
330 parser.reset();
331 auto rv = feed_parser(b);
332 if (rv != BTE_SEQ_ESCAPE)
333 return;
334
335 b.assert_equal(seq);
336}
337
338static void
339test_seq_esc_nF(void)
340{
341 /* Tests nF sequences, that is ESC 2/n [2/m..] F with F being 3/0..7/14.
342 * They could have any number of itermediates, but we only test up to 4.
343 */
344
345 uint32_t i[4];
346 for (uint32_t f = 0x30; f < 0x7f; f++) {
347 test_seq_esc(f, i, 0);
348 for (i[0] = 0x20; i[0] < 0x30; i[0]++) {
349 test_seq_esc(f, i, 1);
350 for (i[1] = 0x20; i[1] < 0x30; i[1]++) {
351 test_seq_esc(f, i, 2);
352 for (i[2] = 0x20; i[2] < 0x30; i[2]++) {
353 test_seq_esc(f, i, 3);
354 for (i[3] = 0x20; i[3] < 0x30; i[3]++) {
355 test_seq_esc(f, i, 4);
356 }
357 }
358 }
359 }
360 }
361}
362
363static void
364test_seq_esc_charset(uint32_t f, /* final */
365 uint32_t i[], /* intermediates */
366 unsigned int ni, /* number of intermediates */
367 unsigned int cmd, /* expected command */
368 unsigned int cs /* expected charset */,
369 unsigned int slot /* expected slot */)
370{
371 bte_seq_builder b{BTE_SEQ_ESCAPE, f};
372 b.set_intermediates(i, ni);
373
374 parser.reset();
375 auto rv = feed_parser(b);
376 g_assert_cmpint(rv, ==, BTE_SEQ_ESCAPE)do { gint64 __n1 = (rv), __n2 = (BTE_SEQ_ESCAPE); if (__n1 ==
__n2) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 376, ((const char*) (__PRETTY_FUNCTION__)), "rv" " " "==" " "
"BTE_SEQ_ESCAPE", (long double) __n1, "==", (long double) __n2
, 'i'); } while (0)
;
377 b.assert_equal(seq);
378
379 g_assert_cmpint(seq.command(), ==, cmd)do { gint64 __n1 = (seq.command()), __n2 = (cmd); if (__n1 ==
__n2) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 379, ((const char*) (__PRETTY_FUNCTION__)), "seq.command()"
" " "==" " " "cmd", (long double) __n1, "==", (long double) __n2
, 'i'); } while (0)
;
380 g_assert_cmpint(seq.charset(), ==, cs)do { gint64 __n1 = (seq.charset()), __n2 = (cs); if (__n1 == __n2
) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 380, ((const char*) (__PRETTY_FUNCTION__)), "seq.charset()"
" " "==" " " "cs", (long double) __n1, "==", (long double) __n2
, 'i'); } while (0)
;
381 g_assert_cmpint(seq.slot(), ==, slot)do { gint64 __n1 = (seq.slot()), __n2 = (slot); if (__n1 == __n2
) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 381, ((const char*) (__PRETTY_FUNCTION__)), "seq.slot()" " "
"==" " " "slot", (long double) __n1, "==", (long double) __n2
, 'i'); } while (0)
;
382}
383
384static void
385test_seq_esc_charset(uint32_t i[], /* intermediates */
386 unsigned int ni, /* number of intermediates */
387 uint8_t const* const table, /* table */
388 unsigned int ntable, /* number of table entries */
389 uint32_t ts, /* start of table */
390 unsigned int cmd, /* expected command */
391 unsigned int defaultcs /* default charset */,
392 unsigned int slot /* expected slot */)
393{
394 for (uint32_t f = 0x30; f < 0x7f; f++) {
395 int cs;
396
397 if (f >= ts && f < (ts + ntable))
398 cs = table[f - ts];
399 else
400 cs = defaultcs;
401
402 test_seq_esc_charset(f, i, ni, cmd, cs, slot);
403 }
404}
405
406static void
407test_seq_esc_charset_94(void)
408{
409 uint32_t i[4];
410
411 /* Single byte 94-sets */
412 for (i[0] = 0x28; i[0] <= 0x2b; i[0]++) {
413 int slot = i[0] - 0x28;
414
415 test_seq_esc_charset(i, 1,
416 charset_graphic_94,
417 G_N_ELEMENTS(charset_graphic_94)(sizeof (charset_graphic_94) / sizeof ((charset_graphic_94)[0
]))
,
418 0x30, BTE_CMD_GnDm, BTE_CHARSET_NONE, slot);
419
420 i[1] = 0x20;
421 test_seq_esc_charset(i, 2, nullptr, 0, 0,
422 BTE_CMD_GnDm, BTE_CHARSET_DRCS, slot);
423
424 i[1] = 0x21;
425 test_seq_esc_charset(i, 2,
426 charset_graphic_94_with_2_1,
427 G_N_ELEMENTS(charset_graphic_94_with_2_1)(sizeof (charset_graphic_94_with_2_1) / sizeof ((charset_graphic_94_with_2_1
)[0]))
,
428 0x40, BTE_CMD_GnDm, BTE_CHARSET_NONE, slot);
429
430 i[1] = 0x22;
431 test_seq_esc_charset(i, 2,
432 charset_graphic_94_with_2_2,
433 G_N_ELEMENTS(charset_graphic_94_with_2_2)(sizeof (charset_graphic_94_with_2_2) / sizeof ((charset_graphic_94_with_2_2
)[0]))
,
434 0x30, BTE_CMD_GnDm, BTE_CHARSET_NONE, slot);
435
436 i[1] = 0x23;
437 test_seq_esc_charset(i, 2, nullptr, 0,
438 0x30, BTE_CMD_GnDm, BTE_CHARSET_NONE, slot);
439
440 /* 2/4 is multibyte charsets */
441
442 i[1] = 0x25;
443 test_seq_esc_charset(i, 2,
444 charset_graphic_94_with_2_5,
445 G_N_ELEMENTS(charset_graphic_94_with_2_5)(sizeof (charset_graphic_94_with_2_5) / sizeof ((charset_graphic_94_with_2_5
)[0]))
,
446 0x30, BTE_CMD_GnDm, BTE_CHARSET_NONE, slot);
447
448 i[1] = 0x26;
449 test_seq_esc_charset(i, 2,
450 charset_graphic_94_with_2_6,
451 G_N_ELEMENTS(charset_graphic_94_with_2_6)(sizeof (charset_graphic_94_with_2_6) / sizeof ((charset_graphic_94_with_2_6
)[0]))
,
452 0x30, BTE_CMD_GnDm, BTE_CHARSET_NONE, slot);
453
454 i[1] = 0x27;
455 test_seq_esc_charset(i, 2, nullptr, 0, 0,
456 BTE_CMD_GnDm, BTE_CHARSET_NONE, slot);
457 }
458}
459
460static void
461test_seq_esc_charset_96(void)
462{
463 uint32_t i[4];
464
465 /* Single byte 96-sets */
466 for (i[0] = 0x2d; i[0] <= 0x2f; i[0]++) {
467 int slot = i[0] - 0x2c;
468
469 test_seq_esc_charset(i, 1,
470 charset_graphic_96,
471 G_N_ELEMENTS(charset_graphic_96)(sizeof (charset_graphic_96) / sizeof ((charset_graphic_96)[0
]))
,
472 0x30, BTE_CMD_GnDm, BTE_CHARSET_NONE, slot);
473
474 i[1] = 0x20;
475 test_seq_esc_charset(i, 2, nullptr, 0, 0,
476 BTE_CMD_GnDm, BTE_CHARSET_DRCS, slot);
477
478 /* 2/4 is multibyte charsets, 2/5 is DOCS. Other indermediates may be present
479 * in Fp sequences, but none are actually in use.
480 */
481 for (i[1] = 0x21; i[1] < 0x28; i[1]++) {
482 if (i[1] == 0x24 || i[1] == 0x25)
483 continue;
484
485 test_seq_esc_charset(i, 2, nullptr, 0, 0,
486 BTE_CMD_GnDm, BTE_CHARSET_NONE, slot);
487 }
488 }
489}
490
491static void
492test_seq_esc_charset_94_n(void)
493{
494 uint32_t i[4];
495
496 /* Multibyte 94-sets */
497 i[0] = 0x24;
498 for (i[1] = 0x28; i[1] <= 0x2b; i[1]++) {
499 int slot = i[1] - 0x28;
500
501 test_seq_esc_charset(i, 2,
502 charset_graphic_94_n,
503 G_N_ELEMENTS(charset_graphic_94_n)(sizeof (charset_graphic_94_n) / sizeof ((charset_graphic_94_n
)[0]))
,
504 0x30, BTE_CMD_GnDMm, BTE_CHARSET_NONE, slot);
505
506 i[2] = 0x20;
507 test_seq_esc_charset(i, 3, nullptr, 0, 0,
508 BTE_CMD_GnDMm, BTE_CHARSET_DRCS, slot);
509
510 /* There could be one more intermediate byte. */
511 for (i[2] = 0x21; i[2] < 0x28; i[2]++) {
512 if (i[2] == 0x24) /* TODO */
513 continue;
514
515 test_seq_esc_charset(i, 3, nullptr, 0, 0,
516 BTE_CMD_GnDMm, BTE_CHARSET_NONE, slot);
517 }
518 }
519
520 /* As a special exception, ESC 2/4 4/[012] are also possible */
521 test_seq_esc_charset(0x40, i, 1, BTE_CMD_GnDMm, charset_graphic_94_n[0x40 - 0x30], 0);
522 test_seq_esc_charset(0x41, i, 1, BTE_CMD_GnDMm, charset_graphic_94_n[0x41 - 0x30], 0);
523 test_seq_esc_charset(0x42, i, 1, BTE_CMD_GnDMm, charset_graphic_94_n[0x42 - 0x30], 0);
524}
525
526static void
527test_seq_esc_charset_96_n(void)
528{
529 uint32_t i[4];
530
531 /* Multibyte 94-sets */
532 i[0] = 0x24;
533 for (i[1] = 0x2d; i[1] <= 0x2f; i[1]++) {
534 int slot = i[1] - 0x2c;
535
536 test_seq_esc_charset(i, 2, nullptr, 0, 0,
537 BTE_CMD_GnDMm, BTE_CHARSET_NONE, slot);
538
539 i[2] = 0x20;
540 test_seq_esc_charset(i, 3, nullptr, 0, 0,
541 BTE_CMD_GnDMm, BTE_CHARSET_DRCS, slot);
542
543 /* There could be one more intermediate byte. */
544 for (i[2] = 0x21; i[2] < 0x28; i[2]++) {
545 test_seq_esc_charset(i, 3, nullptr, 0, 0,
546 BTE_CMD_GnDMm, BTE_CHARSET_NONE, slot);
547 }
548 }
549}
550
551static void
552test_seq_esc_charset_control(void)
553{
554 uint32_t i[4];
555
556 /* C0 controls: ESC 2/1 F */
557 i[0] = 0x21;
558 test_seq_esc_charset(i, 1,
559 charset_control_c0,
560 G_N_ELEMENTS(charset_control_c0)(sizeof (charset_control_c0) / sizeof ((charset_control_c0)[0
]))
,
561 0x40, BTE_CMD_CnD, BTE_CHARSET_NONE, 0);
562
563 /* C1 controls: ESC 2/2 F */
564 i[0] = 0x22;
565 test_seq_esc_charset(i, 1,
566 charset_control_c1,
567 G_N_ELEMENTS(charset_control_c1)(sizeof (charset_control_c1) / sizeof ((charset_control_c1)[0
]))
,
568 0x40, BTE_CMD_CnD, BTE_CHARSET_NONE, 1);
569}
570
571static void
572test_seq_esc_charset_other(void)
573{
574 uint32_t i[4];
575
576 /* Other coding systems: ESC 2/5 F or ESC 2/5 I F */
577 i[0] = 0x25;
578 test_seq_esc_charset(i, 1,
579 charset_ocs,
580 G_N_ELEMENTS(charset_ocs)(sizeof (charset_ocs) / sizeof ((charset_ocs)[0])),
581 0x30, BTE_CMD_DOCS, BTE_CHARSET_NONE, 0);
582
583 i[1] = 0x20;
584 test_seq_esc_charset(i, 2,
585 charset_ocs_with_2_0,
586 G_N_ELEMENTS(charset_ocs_with_2_0)(sizeof (charset_ocs_with_2_0) / sizeof ((charset_ocs_with_2_0
)[0]))
,
587 0x30, BTE_CMD_DOCS, BTE_CHARSET_NONE, 0);
588
589 i[1] = 0x2f;
590 test_seq_esc_charset(i, 2,
591 charset_ocs_with_2_15,
592 G_N_ELEMENTS(charset_ocs_with_2_15)(sizeof (charset_ocs_with_2_15) / sizeof ((charset_ocs_with_2_15
)[0]))
,
593 0x40, BTE_CMD_DOCS, BTE_CHARSET_NONE, 0);
594}
595
596static void
597test_seq_esc_Fpes(void)
598{
599 /* Tests Fp, Fe and Ft sequences, that is ESC 3/n .. ESC 7/14 */
600
601 for (uint32_t f = 0x30; f < 0x7f; f++) {
602 parser.reset();
603
604 bte_seq_builder b{BTE_SEQ_ESCAPE, f};
605
606 auto rv = feed_parser(b);
607 int expected_rv;
608 switch (f) {
609 case 'P': /* DCS */
610 case 'X': /* SOS */
611 case 'Z': /* SCI */
612 case '_': /* APC */
613 case '[': /* CSI */
614 case ']': /* OSC */
615 case '^': /* PM */
616 expected_rv = BTE_SEQ_NONE;
617 break;
618 default:
619 expected_rv = BTE_SEQ_ESCAPE;
620 break;
621 }
622 g_assert_cmpint(rv, ==, expected_rv)do { gint64 __n1 = (rv), __n2 = (expected_rv); if (__n1 == __n2
) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 622, ((const char*) (__PRETTY_FUNCTION__)), "rv" " " "==" " "
"expected_rv", (long double) __n1, "==", (long double) __n2,
'i'); } while (0)
;
623 if (rv != BTE_SEQ_NONE)
624 b.assert_equal(seq);
625 }
626}
627
628static void
629test_seq_esc_known(uint32_t f,
630 uint32_t i,
631 unsigned int cmd)
632{
633 bte_seq_builder b{BTE_SEQ_ESCAPE, f};
634 if (i != 0)
635 b.set_intermediates(&i, 1);
636
637 auto rv = feed_parser(b);
638 g_assert_cmpint(rv, ==, BTE_SEQ_ESCAPE)do { gint64 __n1 = (rv), __n2 = (BTE_SEQ_ESCAPE); if (__n1 ==
__n2) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 638, ((const char*) (__PRETTY_FUNCTION__)), "rv" " " "==" " "
"BTE_SEQ_ESCAPE", (long double) __n1, "==", (long double) __n2
, 'i'); } while (0)
;
639 g_assert_cmpint(seq.command(), ==, cmd)do { gint64 __n1 = (seq.command()), __n2 = (cmd); if (__n1 ==
__n2) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 639, ((const char*) (__PRETTY_FUNCTION__)), "seq.command()"
" " "==" " " "cmd", (long double) __n1, "==", (long double) __n2
, 'i'); } while (0)
;
640}
641
642static void
643test_seq_esc_known(void)
644{
645 parser.reset();
646
647#define _BTE_SEQ(cmd,type,f,p,ni,i) \
648 test_seq_esc_known(f, BTE_SEQ_INTERMEDIATE_CHAR_##i, BTE_CMD_##cmd);
649#include "parser-esc.hh"
650#undef _BTE_SEQ
651}
652
653static void
654test_seq_csi(uint32_t f,
655 uint32_t p,
656 bte_seq_arg_t params[16],
657 uint32_t i[4],
658 unsigned int ni)
659{
660 bte_seq_builder b{BTE_SEQ_CSI, f};
661 b.set_intermediates(i, ni);
662 b.set_param_intro(p);
663
664 int expected_rv = (f & 0xF0) == 0x30 ? BTE_SEQ_NONE : BTE_SEQ_CSI;
5
'?' condition is true
665
666 for (unsigned int n = 0; n <= 16; n++) {
6
Loop condition is true. Entering loop body
667 b.reset_params();
668 b.set_params(params, n);
669
670 parser.reset();
671 /* First with C0 CSI */
672 auto rv = feed_parser(b, false);
673 g_assert_cmpint(rv, ==, expected_rv)do { gint64 __n1 = (rv), __n2 = (expected_rv); if (__n1 == __n2
) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 673, ((const char*) (__PRETTY_FUNCTION__)), "rv" " " "==" " "
"expected_rv", (long double) __n1, "==", (long double) __n2,
'i'); } while (0)
;
7
Assuming '__n1' is equal to '__n2'
8
Taking true branch
9
Loop condition is false. Exiting loop
674 if (rv
9.1
'rv' is equal to BTE_SEQ_NONE
9.1
'rv' is equal to BTE_SEQ_NONE
!= BTE_SEQ_NONE)
10
Taking false branch
675 b.assert_equal_full(seq);
676
677 /* Now with C1 CSI */
678 rv = feed_parser(b, true);
679 if (rv != BTE_SEQ_NONE)
11
Assuming 'rv' is not equal to BTE_SEQ_NONE
12
Taking true branch
680 b.assert_equal_full(seq);
13
Calling 'SequenceBuilder::assert_equal_full'
681 }
682}
683
684static void
685test_seq_csi(uint32_t p,
686 bte_seq_arg_t params[16])
687{
688 uint32_t i[4];
689 for (uint32_t f = 0x30; f < 0x7f; f++) {
3
Loop condition is true. Entering loop body
690 test_seq_csi(f, p, params, i, 0);
4
Calling 'test_seq_csi'
691 for (i[0] = 0x20; i[0] < 0x30; i[0]++) {
692 test_seq_csi(f, p, params, i, 1);
693 for (i[1] = 0x20; i[1] < 0x30; i[1]++) {
694 test_seq_csi(f, p, params, i, 2);
695 }
696 }
697 }
698}
699
700static void
701test_seq_csi(bte_seq_arg_t params[16])
702{
703 test_seq_csi(0, params);
2
Calling 'test_seq_csi'
704 for (uint32_t p = 0x3c; p <= 0x3f; p++)
705 test_seq_csi(p, params);
706}
707
708static void
709test_seq_csi(void)
710{
711 /* Tests CSI sequences, that is sequences of the form
712 * CSI P...P I...I F
713 * with parameter bytes P from 3/0..3/15, intermediate bytes I from 2/0..2/15 and
714 * final byte F from 4/0..7/14.
715 * There could be any number of intermediate bytes, but we only test up to 2.
716 * There could be any number of extra params bytes, but we only test up to 1.
717 * CSI can be either the C1 control itself, or ESC [
718 */
719 bte_seq_arg_t params1[16]{ -1, 0, 1, 9, 10, 99, 100, 999,
720 1000, 9999, 10000, 65534, 65535, 65536, -1, -1 };
721 test_seq_csi(params1);
1
Calling 'test_seq_csi'
722
723 bte_seq_arg_t params2[16]{ 1, -1, -1, -1, 1, -1, 1, 1,
724 1, -1, -1, -1, -1, 1, 1, 1 };
725 test_seq_csi(params2);
726}
727
728static void
729test_seq_sci(uint32_t f,
730 bool valid)
731{
732 bte_seq_builder b{BTE_SEQ_SCI, f};
733
734 /* First with C0 SCI */
735 auto rv = feed_parser(b, false);
736 if (valid) {
737 g_assert_cmpint(rv, ==, BTE_SEQ_SCI)do { gint64 __n1 = (rv), __n2 = (BTE_SEQ_SCI); if (__n1 == __n2
) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 737, ((const char*) (__PRETTY_FUNCTION__)), "rv" " " "==" " "
"BTE_SEQ_SCI", (long double) __n1, "==", (long double) __n2,
'i'); } while (0)
;
738 b.assert_equal_full(seq);
739 } else
740 g_assert_cmpint(rv, !=, BTE_SEQ_SCI)do { gint64 __n1 = (rv), __n2 = (BTE_SEQ_SCI); if (__n1 != __n2
) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 740, ((const char*) (__PRETTY_FUNCTION__)), "rv" " " "!=" " "
"BTE_SEQ_SCI", (long double) __n1, "!=", (long double) __n2,
'i'); } while (0)
;
741
742 /* Now with C1 SCI */
743 rv = feed_parser(b, true);
744 if (valid) {
745 g_assert_cmpint(rv, ==, BTE_SEQ_SCI)do { gint64 __n1 = (rv), __n2 = (BTE_SEQ_SCI); if (__n1 == __n2
) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 745, ((const char*) (__PRETTY_FUNCTION__)), "rv" " " "==" " "
"BTE_SEQ_SCI", (long double) __n1, "==", (long double) __n2,
'i'); } while (0)
;
746 b.assert_equal_full(seq);
747 } else
748 g_assert_cmpint(rv, !=, BTE_SEQ_SCI)do { gint64 __n1 = (rv), __n2 = (BTE_SEQ_SCI); if (__n1 != __n2
) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 748, ((const char*) (__PRETTY_FUNCTION__)), "rv" " " "!=" " "
"BTE_SEQ_SCI", (long double) __n1, "!=", (long double) __n2,
'i'); } while (0)
;
749}
750
751static void
752test_seq_sci(void)
753{
754 /* Tests SCI sequences, that is sequences of the form SCI F
755 * with final byte 0/8..0/13 or 2/0..7/14
756 * SCI can be either the C1 control itself, or ESC Z
757 */
758 parser.reset();
759
760 for (uint32_t f = 0x8; f <= 0xd; ++f)
761 test_seq_sci(f, true);
762 for (uint32_t f = 0x20; f <= 0x7e; ++f)
763 test_seq_sci(f, true);
764 for (uint32_t f = 0x7f; f <= 0xff; ++f)
765 test_seq_sci(f, false);
766}
767
768G_GNUC_UNUSED__attribute__ ((__unused__))
769static void
770test_seq_sci_known(uint32_t f,
771 unsigned int cmd)
772{
773 bte_seq_builder b{BTE_SEQ_SCI, f};
774
775 auto rv = feed_parser(b);
776 g_assert_cmpint(rv, ==, BTE_SEQ_SCI)do { gint64 __n1 = (rv), __n2 = (BTE_SEQ_SCI); if (__n1 == __n2
) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 776, ((const char*) (__PRETTY_FUNCTION__)), "rv" " " "==" " "
"BTE_SEQ_SCI", (long double) __n1, "==", (long double) __n2,
'i'); } while (0)
;
777 g_assert_cmpint(seq.command(), ==, cmd)do { gint64 __n1 = (seq.command()), __n2 = (cmd); if (__n1 ==
__n2) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 777, ((const char*) (__PRETTY_FUNCTION__)), "seq.command()"
" " "==" " " "cmd", (long double) __n1, "==", (long double) __n2
, 'i'); } while (0)
;
778}
779
780static void
781test_seq_sci_known(void)
782{
783 parser.reset();
784
785#define _BTE_SEQ(cmd,type,f,p,ni,i) \
786 test_seq_sci_known(f, BTE_CMD_##cmd);
787#include "parser-sci.hh"
788#undef _BTE_SEQ
789}
790
791static void
792test_seq_csi_known(uint32_t f,
793 uint32_t p,
794 uint32_t i,
795 unsigned int cmd)
796{
797 bte_seq_builder b{BTE_SEQ_CSI, f};
798 if (p != 0)
799 b.set_param_intro(p);
800 if (i != 0)
801 b.set_intermediates(&i, 1);
802
803 auto rv = feed_parser(b);
804 g_assert_cmpint(rv, ==, BTE_SEQ_CSI)do { gint64 __n1 = (rv), __n2 = (BTE_SEQ_CSI); if (__n1 == __n2
) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 804, ((const char*) (__PRETTY_FUNCTION__)), "rv" " " "==" " "
"BTE_SEQ_CSI", (long double) __n1, "==", (long double) __n2,
'i'); } while (0)
;
805 g_assert_cmpint(seq.command(), ==, cmd)do { gint64 __n1 = (seq.command()), __n2 = (cmd); if (__n1 ==
__n2) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 805, ((const char*) (__PRETTY_FUNCTION__)), "seq.command()"
" " "==" " " "cmd", (long double) __n1, "==", (long double) __n2
, 'i'); } while (0)
;
806}
807
808static void
809test_seq_csi_known(void)
810{
811 parser.reset();
812
813#define _BTE_SEQ(cmd,type,f,p,ni,i) \
814 test_seq_csi_known(f, BTE_SEQ_PARAMETER_CHAR_##p, BTE_SEQ_INTERMEDIATE_CHAR_##i, BTE_CMD_##cmd);
815#include "parser-csi.hh"
816#undef _BTE_SEQ
817}
818
819static void
820test_seq_dcs(uint32_t f,
821 uint32_t p,
822 bte_seq_arg_t params[16],
823 uint32_t i[4],
824 unsigned int ni,
825 std::u32string const& str,
826 int expected_rv = BTE_SEQ_DCS)
827{
828 bte_seq_builder b{BTE_SEQ_DCS, f};
829 b.set_intermediates(i, ni);
830 b.set_param_intro(p);
831 b.set_string(str);
832
833 int expected_rv0 = (f & 0xF0) == 0x30 || expected_rv == BTE_SEQ_NONE ? BTE_SEQ_ESCAPE /* the C0 ST */ : expected_rv;
834 int expected_rv1 = (f & 0xF0) == 0x30 ? BTE_SEQ_NONE : expected_rv;
835
836 for (unsigned int n = 0; n <= 16; n++) {
837 b.reset_params();
838 b.set_params(params, n);
839
840 parser.reset();
841
842 /* First with C0 DCS */
843 auto rv0 = feed_parser(b, false);
844 g_assert_cmpint(rv0, ==, expected_rv0)do { gint64 __n1 = (rv0), __n2 = (expected_rv0); if (__n1 == __n2
) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 844, ((const char*) (__PRETTY_FUNCTION__)), "rv0" " " "==" " "
"expected_rv0", (long double) __n1, "==", (long double) __n2
, 'i'); } while (0)
;
845 if (rv0 != BTE_SEQ_ESCAPE && rv0 != BTE_SEQ_NONE)
846 b.assert_equal_full(seq);
847 if (rv0 == BTE_SEQ_ESCAPE)
848 g_assert_cmpint(seq.command(), ==, BTE_CMD_ST)do { gint64 __n1 = (seq.command()), __n2 = (BTE_CMD_ST); if (
__n1 == __n2) ; else g_assertion_message_cmpnum (((gchar*) 0)
, "../src/parser-test.cc", 848, ((const char*) (__PRETTY_FUNCTION__
)), "seq.command()" " " "==" " " "BTE_CMD_ST", (long double) __n1
, "==", (long double) __n2, 'i'); } while (0)
;
849
850 /* Now with C1 DCS */
851 auto rv1 = feed_parser(b, true);
852 g_assert_cmpint(rv1, ==, expected_rv1)do { gint64 __n1 = (rv1), __n2 = (expected_rv1); if (__n1 == __n2
) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 852, ((const char*) (__PRETTY_FUNCTION__)), "rv1" " " "==" " "
"expected_rv1", (long double) __n1, "==", (long double) __n2
, 'i'); } while (0)
;
853 if (rv1 != BTE_SEQ_NONE)
854 b.assert_equal_full(seq);
855 }
856}
857
858static void
859test_seq_dcs(uint32_t p,
860 bte_seq_arg_t params[16],
861 std::u32string const& str,
862 int expected_rv = BTE_SEQ_DCS)
863{
864 uint32_t i[4];
865 for (uint32_t f = 0x40; f < 0x7f; f++) {
866 test_seq_dcs(f, p, params, i, 0, str, expected_rv);
867 }
868
869 for (uint32_t f = 0x30; f < 0x7f; f++) {
870 for (i[0] = 0x20; i[0] < 0x30; i[0]++) {
871 test_seq_dcs(f, p, params, i, 1, str, expected_rv);
872 for (i[1] = 0x20; i[1] < 0x30; i[1]++) {
873 test_seq_dcs(f, p, params, i, 2, str, expected_rv);
874 }
875 }
876 }
877}
878
879static void
880test_seq_dcs(bte_seq_arg_t params[16],
881 std::u32string const& str,
882 int expected_rv = BTE_SEQ_DCS)
883{
884 test_seq_dcs(0, params, str);
885 for (uint32_t p = 0x3c; p <= 0x3f; p++)
886 test_seq_dcs(p, params, str, expected_rv);
887}
888
889static void
890test_seq_dcs(std::u32string const& str,
891 int expected_rv = BTE_SEQ_DCS)
892{
893 /* Tests DCS sequences, that is sequences of the form
894 * DCS P...P I...I F D...D ST
895 * with parameter bytes P from 3/0..3/15, intermediate bytes I from 2/0..2/15 and
896 * final byte F from 4/0..7/14.
897 * There could be any number of intermediate bytes, but we only test up to 2.
898 * There could be any number of extra params bytes, but we only test up to 1.
899 * DCS can be either the C1 control itself, or ESC [; ST can be either the C1
900 * control itself, or ESC \\
901 */
902 bte_seq_arg_t params1[16]{ -1, 0, 1, 9, 10, 99, 100, 999,
903 1000, 9999, 10000, 65534, 65535, 65536, -1, -1 };
904 test_seq_dcs(params1, str, expected_rv);
905
906 bte_seq_arg_t params2[16]{ 1, -1, -1, -1, 1, -1, 1, 1,
907 1, -1, -1, -1, -1, 1, 1, 1 };
908 test_seq_dcs(params2, str, expected_rv);
909}
910
911static void
912test_seq_dcs_simple(std::u32string const& str,
913 int expected_rv = BTE_SEQ_DCS)
914{
915 bte_seq_arg_t params[16]{ 1, -1, -1, -1, 1, -1, 1, 1,
916 1, -1, -1, -1, -1, 1, 1, 1 };
917 uint32_t i[4];
918
919 test_seq_dcs(0x40, 0, params, i, 0, str, expected_rv);
920}
921
922static void
923test_seq_dcs(void)
924{
925 /* Length exceeded */
926 test_seq_dcs_simple(std::u32string(BTE_SEQ_STRING_MAX_CAPACITY(1 << 12) + 1, 0x100000), BTE_SEQ_NONE);
927
928 test_seq_dcs(U""s);
929 test_seq_dcs(U"123;TESTING"s);
930}
931
932static void
933test_seq_dcs_known(uint32_t f,
934 uint32_t p,
935 uint32_t i,
936 unsigned int cmd)
937{
938 bte_seq_builder b{BTE_SEQ_DCS, f};
939 if (p != 0)
940 b.set_param_intro(p);
941 if (i != 0)
942 b.set_intermediates(&i, 1);
943
944 auto rv = feed_parser(b);
945 g_assert_cmpint(rv, ==, BTE_SEQ_DCS)do { gint64 __n1 = (rv), __n2 = (BTE_SEQ_DCS); if (__n1 == __n2
) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 945, ((const char*) (__PRETTY_FUNCTION__)), "rv" " " "==" " "
"BTE_SEQ_DCS", (long double) __n1, "==", (long double) __n2,
'i'); } while (0)
;
946 g_assert_cmpint(seq.command(), ==, cmd)do { gint64 __n1 = (seq.command()), __n2 = (cmd); if (__n1 ==
__n2) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 946, ((const char*) (__PRETTY_FUNCTION__)), "seq.command()"
" " "==" " " "cmd", (long double) __n1, "==", (long double) __n2
, 'i'); } while (0)
;
947}
948
949static void
950test_seq_dcs_known(void)
951{
952 parser.reset();
953
954#define _BTE_SEQ(cmd,type,f,p,ni,i) \
955 test_seq_dcs_known(f, BTE_SEQ_PARAMETER_CHAR_##p, BTE_SEQ_INTERMEDIATE_CHAR_##i, BTE_CMD_##cmd);
956#include "parser-dcs.hh"
957#undef _BTE_SEQ
958}
959
960static void
961test_seq_parse(char const* str)
962{
963 std::u32string s;
964 s.push_back(0x9B); /* CSI */
965 for (unsigned int i = 0; str[i]; i++)
966 s.push_back(str[i]);
967 s.push_back(0x6d); /* m = SGR */
968
969 parser.reset();
970 auto rv = feed_parser(s);
971 g_assert_cmpint(rv, ==, BTE_SEQ_CSI)do { gint64 __n1 = (rv), __n2 = (BTE_SEQ_CSI); if (__n1 == __n2
) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 971, ((const char*) (__PRETTY_FUNCTION__)), "rv" " " "==" " "
"BTE_SEQ_CSI", (long double) __n1, "==", (long double) __n2,
'i'); } while (0)
;
972}
973
974static void
975test_seq_csi_param(char const* str,
976 std::vector<int> args,
977 std::vector<bool> args_nonfinal)
978{
979 g_assert_cmpuint(args.size(), ==, args_nonfinal.size())do { guint64 __n1 = (args.size()), __n2 = (args_nonfinal.size
()); if (__n1 == __n2) ; else g_assertion_message_cmpnum (((gchar
*) 0), "../src/parser-test.cc", 979, ((const char*) (__PRETTY_FUNCTION__
)), "args.size()" " " "==" " " "args_nonfinal.size()", (long double
) __n1, "==", (long double) __n2, 'i'); } while (0)
;
980
981 test_seq_parse(str);
982
983 if (seq.size() < BTE_PARSER_ARG_MAX(32))
984 g_assert_cmpuint(seq.size(), ==, args.size())do { guint64 __n1 = (seq.size()), __n2 = (args.size()); if (__n1
== __n2) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 984, ((const char*) (__PRETTY_FUNCTION__)), "seq.size()" " "
"==" " " "args.size()", (long double) __n1, "==", (long double
) __n2, 'i'); } while (0)
;
985
986 unsigned int n_final_args = 0;
987 for (unsigned int i = 0; i < seq.size(); i++) {
988 g_assert_cmpint(seq.param(i), ==, args[i])do { gint64 __n1 = (seq.param(i)), __n2 = (args[i]); if (__n1
== __n2) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 988, ((const char*) (__PRETTY_FUNCTION__)), "seq.param(i)" " "
"==" " " "args[i]", (long double) __n1, "==", (long double) __n2
, 'i'); } while (0)
;
989
990 auto is_nonfinal = args_nonfinal[i];
991 if (!is_nonfinal)
992 n_final_args++;
993
994 g_assert_cmpint(seq.param_nonfinal(i), ==, is_nonfinal)do { gint64 __n1 = (seq.param_nonfinal(i)), __n2 = (is_nonfinal
); if (__n1 == __n2) ; else g_assertion_message_cmpnum (((gchar
*) 0), "../src/parser-test.cc", 994, ((const char*) (__PRETTY_FUNCTION__
)), "seq.param_nonfinal(i)" " " "==" " " "is_nonfinal", (long
double) __n1, "==", (long double) __n2, 'i'); } while (0)
;
995 }
996
997 g_assert_cmpuint(seq.size_final(), ==, n_final_args)do { guint64 __n1 = (seq.size_final()), __n2 = (n_final_args)
; if (__n1 == __n2) ; else g_assertion_message_cmpnum (((gchar
*) 0), "../src/parser-test.cc", 997, ((const char*) (__PRETTY_FUNCTION__
)), "seq.size_final()" " " "==" " " "n_final_args", (long double
) __n1, "==", (long double) __n2, 'i'); } while (0)
;
998}
999
1000static void
1001test_seq_csi_param(void)
1002{
1003 /* Tests that CSI parameters and subparameters are parsed correctly. */
1004
1005 test_seq_csi_param("", { }, { });
1006 test_seq_csi_param(";", { -1, -1 }, { false, false });
1007 test_seq_csi_param(":", { -1, -1 }, { true, false });
1008 test_seq_csi_param(";:", { -1, -1, -1 }, { false, true, false });
1009 test_seq_csi_param("::;;", { -1, -1, -1, -1, -1 }, { true, true, false, false, false });
1010
1011 test_seq_csi_param("1;2:3:4:5:6;7:8;9:0",
1012 { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 },
1013 { false, true, true, true, true, false, true, false, true, false });
1014
1015 test_seq_csi_param("1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1",
1016 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
1017 { false, false, false, false, false, false, false, false,
1018 false, false, false, false, false, false, false, false });
1019
1020 test_seq_csi_param("1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1",
1021 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
1022 { true, true, true, true, true, true, true, true,
1023 true, true, true, true, true, true, true, false });
1024
1025}
1026
1027static void
1028test_seq_csi_clear(void)
1029{
1030 /* Check that parameters are cleared from when a sequence was aborted. */
1031
1032 bte_seq_builder b0{BTE_SEQ_CSI, 'm'};
1033 b0.set_param_intro(BTE_SEQ_PARAMETER_CHAR_WHAT);
1034 for (unsigned int i = 0; i < BTE_PARSER_ARG_MAX(32); ++i)
1035 b0.append_param(127 * i + 17);
1036
1037 std::u32string str0;
1038 b0.to_string(str0);
1039
1040 parser.reset();
1041 for (size_t len0 = 1; len0 <= str0.size(); ++len0) {
1042 for (unsigned int n_args = 0; n_args < BTE_PARSER_ARG_MAX(32); ++n_args) {
1043 feed_parser(str0.substr(0, len0));
1044
1045 bte_seq_builder b1{BTE_SEQ_CSI, 'n'};
1046 b1.set_param_intro(BTE_SEQ_PARAMETER_CHAR_GT);
1047 for (unsigned int i = 0; i < n_args; ++i)
1048 b1.append_param(257 * i + 31);
1049
1050 std::u32string str1;
1051 b1.to_string(str1);
1052
1053 auto rv = feed_parser(str1);
1054 g_assert_cmpint(rv, ==, BTE_SEQ_CSI)do { gint64 __n1 = (rv), __n2 = (BTE_SEQ_CSI); if (__n1 == __n2
) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1054, ((const char*) (__PRETTY_FUNCTION__)), "rv" " " "==" " "
"BTE_SEQ_CSI", (long double) __n1, "==", (long double) __n2,
'i'); } while (0)
;
1055 b1.assert_equal_full(seq);
1056 for (unsigned int n = seq.size(); n < BTE_PARSER_ARG_MAX(32); n++)
1057 g_assert_true(seq.param_default(n))do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (seq.param_default(n)) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message (((
gchar*) 0), "../src/parser-test.cc", 1057, ((const char*) (__PRETTY_FUNCTION__
)), "'" "seq.param_default(n)" "' should be TRUE"); } while (
0)
;
1058 }
1059 }
1060}
1061
1062static void
1063test_seq_csi_max(std::u32string const& start,
1064 std::u32string const& more,
1065 int expected_rv = BTE_SEQ_NONE)
1066{
1067 parser.reset();
1068 feed_parser(start);
1069 feed_parser(more);
1070 auto rv = feed_parser(U"m"s); /* final character */
1071 g_assert_cmpint(rv, ==, expected_rv)do { gint64 __n1 = (rv), __n2 = (expected_rv); if (__n1 == __n2
) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1071, ((const char*) (__PRETTY_FUNCTION__)), "rv" " " "==" " "
"expected_rv", (long double) __n1, "==", (long double) __n2,
'i'); } while (0)
;
1072}
1073
1074static void
1075test_seq_csi_max(void)
1076{
1077 /* Check that an excessive number of parameters causes the
1078 * sequence to be ignored.
1079 *
1080 * Since SequenceBuilder is limited in the same number of
1081 * parameters as the parser, can't use it directly to
1082 * produce a sequence with too may parameters.
1083 */
1084
1085 bte_seq_builder b{BTE_SEQ_CSI, 'm'};
1086 b.set_param_intro(BTE_SEQ_PARAMETER_CHAR_WHAT);
1087 for (unsigned int i = 0; i < BTE_PARSER_ARG_MAX(32); ++i)
1088 b.append_param(i);
1089
1090 std::u32string str;
1091 b.to_string(str);
1092
1093 /* The sequence with BTE_PARSER_ARG_MAX args must be parsed */
1094 auto rv = feed_parser(str);
1095 g_assert_cmpint(rv, ==, BTE_SEQ_CSI)do { gint64 __n1 = (rv), __n2 = (BTE_SEQ_CSI); if (__n1 == __n2
) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1095, ((const char*) (__PRETTY_FUNCTION__)), "rv" " " "==" " "
"BTE_SEQ_CSI", (long double) __n1, "==", (long double) __n2,
'i'); } while (0)
;
1096
1097 /* Now test that adding one more parameter (whether with an
1098 * explicit value, or default, causes the sequence to be ignored.
1099 */
1100 str.pop_back(); /* erase final character */
1101 test_seq_csi_max(str, U":"s);
1102 test_seq_csi_max(str, U";"s);
1103 test_seq_csi_max(str, U":12345"s);
1104 test_seq_csi_max(str, U";12345"s);
1105 test_seq_csi_max(str, U":12345;"s);
1106 test_seq_csi_max(str, U";12345:"s);
1107 test_seq_csi_max(str, U":12345;"s);
1108 test_seq_csi_max(str, U":12345:"s);
1109}
1110
1111static void
1112test_seq_glue_arg(char const* str,
1113 unsigned int n_args,
1114 unsigned int n_final_args)
1115{
1116 test_seq_parse(str);
1117
1118 auto raw_seq = *seq.seq_ptr();
1119 g_assert_cmpuint(seq.size(), ==, n_args)do { guint64 __n1 = (seq.size()), __n2 = (n_args); if (__n1 ==
__n2) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1119, ((const char*) (__PRETTY_FUNCTION__)), "seq.size()" " "
"==" " " "n_args", (long double) __n1, "==", (long double) __n2
, 'i'); } while (0)
;
1120 g_assert_cmpuint(raw_seq->n_args, ==, n_args)do { guint64 __n1 = (raw_seq->n_args), __n2 = (n_args); if
(__n1 == __n2) ; else g_assertion_message_cmpnum (((gchar*) 0
), "../src/parser-test.cc", 1120, ((const char*) (__PRETTY_FUNCTION__
)), "raw_seq->n_args" " " "==" " " "n_args", (long double)
__n1, "==", (long double) __n2, 'i'); } while (0)
;
1121 g_assert_cmpuint(seq.size_final(), ==, n_final_args)do { guint64 __n1 = (seq.size_final()), __n2 = (n_final_args)
; if (__n1 == __n2) ; else g_assertion_message_cmpnum (((gchar
*) 0), "../src/parser-test.cc", 1121, ((const char*) (__PRETTY_FUNCTION__
)), "seq.size_final()" " " "==" " " "n_final_args", (long double
) __n1, "==", (long double) __n2, 'i'); } while (0)
;
1122 g_assert_cmpuint(raw_seq->n_final_args, ==, n_final_args)do { guint64 __n1 = (raw_seq->n_final_args), __n2 = (n_final_args
); if (__n1 == __n2) ; else g_assertion_message_cmpnum (((gchar
*) 0), "../src/parser-test.cc", 1122, ((const char*) (__PRETTY_FUNCTION__
)), "raw_seq->n_final_args" " " "==" " " "n_final_args", (
long double) __n1, "==", (long double) __n2, 'i'); } while (0
)
;
1123
1124 g_assert_cmpuint(seq.type(), ==, raw_seq->type)do { guint64 __n1 = (seq.type()), __n2 = (raw_seq->type); if
(__n1 == __n2) ; else g_assertion_message_cmpnum (((gchar*) 0
), "../src/parser-test.cc", 1124, ((const char*) (__PRETTY_FUNCTION__
)), "seq.type()" " " "==" " " "raw_seq->type", (long double
) __n1, "==", (long double) __n2, 'i'); } while (0)
;
1125 g_assert_cmpuint(seq.command(), ==, raw_seq->command)do { guint64 __n1 = (seq.command()), __n2 = (raw_seq->command
); if (__n1 == __n2) ; else g_assertion_message_cmpnum (((gchar
*) 0), "../src/parser-test.cc", 1125, ((const char*) (__PRETTY_FUNCTION__
)), "seq.command()" " " "==" " " "raw_seq->command", (long
double) __n1, "==", (long double) __n2, 'i'); } while (0)
;
1126 g_assert_cmpuint(seq.terminator(), ==, raw_seq->terminator)do { guint64 __n1 = (seq.terminator()), __n2 = (raw_seq->terminator
); if (__n1 == __n2) ; else g_assertion_message_cmpnum (((gchar
*) 0), "../src/parser-test.cc", 1126, ((const char*) (__PRETTY_FUNCTION__
)), "seq.terminator()" " " "==" " " "raw_seq->terminator",
(long double) __n1, "==", (long double) __n2, 'i'); } while (
0)
;
1127
1128 for (unsigned int i = 0; i < raw_seq->n_args; i++)
1129 g_assert_cmpuint(seq.param(i), ==, bte_seq_arg_value(raw_seq->args[i]))do { guint64 __n1 = (seq.param(i)), __n2 = (bte_seq_arg_value
(raw_seq->args[i])); if (__n1 == __n2) ; else g_assertion_message_cmpnum
(((gchar*) 0), "../src/parser-test.cc", 1129, ((const char*)
(__PRETTY_FUNCTION__)), "seq.param(i)" " " "==" " " "bte_seq_arg_value(raw_seq->args[i])"
, (long double) __n1, "==", (long double) __n2, 'i'); } while
(0)
;
1130}
1131
1132static void
1133test_seq_glue_arg(void)
1134{
1135 test_seq_glue_arg(":0:1000;2;3;4;:;", 9, 6);
1136 g_assert_cmpuint(seq.cbegin(), ==, 0)do { guint64 __n1 = (seq.cbegin()), __n2 = (0); if (__n1 == __n2
) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1136, ((const char*) (__PRETTY_FUNCTION__)), "seq.cbegin()"
" " "==" " " "0", (long double) __n1, "==", (long double) __n2
, 'i'); } while (0)
;
1137 g_assert_cmpuint(seq.cend(), ==, 9)do { guint64 __n1 = (seq.cend()), __n2 = (9); if (__n1 == __n2
) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1137, ((const char*) (__PRETTY_FUNCTION__)), "seq.cend()" " "
"==" " " "9", (long double) __n1, "==", (long double) __n2, 'i'
); } while (0)
;
1138
1139 auto it = seq.cbegin();
1140 g_assert_cmpuint(it, ==, 0)do { guint64 __n1 = (it), __n2 = (0); if (__n1 == __n2) ; else
g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1140, ((const char*) (__PRETTY_FUNCTION__)), "it" " " "==" " "
"0", (long double) __n1, "==", (long double) __n2, 'i'); } while
(0)
;
1141 it = seq.next(it);
1142 g_assert_cmpuint(it, ==, 3)do { guint64 __n1 = (it), __n2 = (3); if (__n1 == __n2) ; else
g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1142, ((const char*) (__PRETTY_FUNCTION__)), "it" " " "==" " "
"3", (long double) __n1, "==", (long double) __n2, 'i'); } while
(0)
;
1143 it = seq.next(it);
1144 g_assert_cmpuint(it, ==, 4)do { guint64 __n1 = (it), __n2 = (4); if (__n1 == __n2) ; else
g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1144, ((const char*) (__PRETTY_FUNCTION__)), "it" " " "==" " "
"4", (long double) __n1, "==", (long double) __n2, 'i'); } while
(0)
;
1145 it = seq.next(it);
1146 g_assert_cmpuint(it, ==, 5)do { guint64 __n1 = (it), __n2 = (5); if (__n1 == __n2) ; else
g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1146, ((const char*) (__PRETTY_FUNCTION__)), "it" " " "==" " "
"5", (long double) __n1, "==", (long double) __n2, 'i'); } while
(0)
;
1147 it = seq.next(it);
1148 g_assert_cmpuint(it, ==, 6)do { guint64 __n1 = (it), __n2 = (6); if (__n1 == __n2) ; else
g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1148, ((const char*) (__PRETTY_FUNCTION__)), "it" " " "==" " "
"6", (long double) __n1, "==", (long double) __n2, 'i'); } while
(0)
;
1149 it = seq.next(it);
1150 g_assert_cmpuint(it, ==, 8)do { guint64 __n1 = (it), __n2 = (8); if (__n1 == __n2) ; else
g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1150, ((const char*) (__PRETTY_FUNCTION__)), "it" " " "==" " "
"8", (long double) __n1, "==", (long double) __n2, 'i'); } while
(0)
;
1151 it = seq.next(it);
1152 g_assert_cmpuint(it, ==, 9)do { guint64 __n1 = (it), __n2 = (9); if (__n1 == __n2) ; else
g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1152, ((const char*) (__PRETTY_FUNCTION__)), "it" " " "==" " "
"9", (long double) __n1, "==", (long double) __n2, 'i'); } while
(0)
;
1153
1154 it = seq.cbegin();
1155 g_assert_cmpint(seq.param(it++), ==, -1)do { gint64 __n1 = (seq.param(it++)), __n2 = (-1); if (__n1 ==
__n2) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1155, ((const char*) (__PRETTY_FUNCTION__)), "seq.param(it++)"
" " "==" " " "-1", (long double) __n1, "==", (long double) __n2
, 'i'); } while (0)
;
1156 g_assert_cmpint(seq.param(it++), ==, 0)do { gint64 __n1 = (seq.param(it++)), __n2 = (0); if (__n1 ==
__n2) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1156, ((const char*) (__PRETTY_FUNCTION__)), "seq.param(it++)"
" " "==" " " "0", (long double) __n1, "==", (long double) __n2
, 'i'); } while (0)
;
1157 g_assert_cmpint(seq.param(it++), ==, 1000)do { gint64 __n1 = (seq.param(it++)), __n2 = (1000); if (__n1
== __n2) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1157, ((const char*) (__PRETTY_FUNCTION__)), "seq.param(it++)"
" " "==" " " "1000", (long double) __n1, "==", (long double)
__n2, 'i'); } while (0)
;
1158 g_assert_cmpint(seq.param(it++), ==, 2)do { gint64 __n1 = (seq.param(it++)), __n2 = (2); if (__n1 ==
__n2) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1158, ((const char*) (__PRETTY_FUNCTION__)), "seq.param(it++)"
" " "==" " " "2", (long double) __n1, "==", (long double) __n2
, 'i'); } while (0)
;
1159 g_assert_cmpint(seq.param(it++), ==, 3)do { gint64 __n1 = (seq.param(it++)), __n2 = (3); if (__n1 ==
__n2) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1159, ((const char*) (__PRETTY_FUNCTION__)), "seq.param(it++)"
" " "==" " " "3", (long double) __n1, "==", (long double) __n2
, 'i'); } while (0)
;
1160 g_assert_cmpint(seq.param(it++), ==, 4)do { gint64 __n1 = (seq.param(it++)), __n2 = (4); if (__n1 ==
__n2) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1160, ((const char*) (__PRETTY_FUNCTION__)), "seq.param(it++)"
" " "==" " " "4", (long double) __n1, "==", (long double) __n2
, 'i'); } while (0)
;
1161 g_assert_cmpint(seq.param(it++), ==, -1)do { gint64 __n1 = (seq.param(it++)), __n2 = (-1); if (__n1 ==
__n2) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1161, ((const char*) (__PRETTY_FUNCTION__)), "seq.param(it++)"
" " "==" " " "-1", (long double) __n1, "==", (long double) __n2
, 'i'); } while (0)
;
1162 g_assert_cmpint(seq.param(it++), ==, -1)do { gint64 __n1 = (seq.param(it++)), __n2 = (-1); if (__n1 ==
__n2) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1162, ((const char*) (__PRETTY_FUNCTION__)), "seq.param(it++)"
" " "==" " " "-1", (long double) __n1, "==", (long double) __n2
, 'i'); } while (0)
;
1163 g_assert_cmpint(seq.param(it++), ==, -1)do { gint64 __n1 = (seq.param(it++)), __n2 = (-1); if (__n1 ==
__n2) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1163, ((const char*) (__PRETTY_FUNCTION__)), "seq.param(it++)"
" " "==" " " "-1", (long double) __n1, "==", (long double) __n2
, 'i'); } while (0)
;
1164 g_assert_cmpint(it, ==, seq.cend())do { gint64 __n1 = (it), __n2 = (seq.cend()); if (__n1 == __n2
) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1164, ((const char*) (__PRETTY_FUNCTION__)), "it" " " "==" " "
"seq.cend()", (long double) __n1, "==", (long double) __n2, 'i'
); } while (0)
;
1165
1166 it = seq.cbegin();
1167 g_assert_cmpint(seq.param(it, -2), ==, -2)do { gint64 __n1 = (seq.param(it, -2)), __n2 = (-2); if (__n1
== __n2) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1167, ((const char*) (__PRETTY_FUNCTION__)), "seq.param(it, -2)"
" " "==" " " "-2", (long double) __n1, "==", (long double) __n2
, 'i'); } while (0)
;
1168 g_assert_cmpint(seq.param(it, -2, 0, 100), ==, 0)do { gint64 __n1 = (seq.param(it, -2, 0, 100)), __n2 = (0); if
(__n1 == __n2) ; else g_assertion_message_cmpnum (((gchar*) 0
), "../src/parser-test.cc", 1168, ((const char*) (__PRETTY_FUNCTION__
)), "seq.param(it, -2, 0, 100)" " " "==" " " "0", (long double
) __n1, "==", (long double) __n2, 'i'); } while (0)
;
1169 it++; it++;
1170 g_assert_cmpint(seq.param(it, -2), ==, seq.param(it))do { gint64 __n1 = (seq.param(it, -2)), __n2 = (seq.param(it)
); if (__n1 == __n2) ; else g_assertion_message_cmpnum (((gchar
*) 0), "../src/parser-test.cc", 1170, ((const char*) (__PRETTY_FUNCTION__
)), "seq.param(it, -2)" " " "==" " " "seq.param(it)", (long double
) __n1, "==", (long double) __n2, 'i'); } while (0)
;
1171 g_assert_cmpint(seq.param(it, -2, 20, 100), ==, 100)do { gint64 __n1 = (seq.param(it, -2, 20, 100)), __n2 = (100)
; if (__n1 == __n2) ; else g_assertion_message_cmpnum (((gchar
*) 0), "../src/parser-test.cc", 1171, ((const char*) (__PRETTY_FUNCTION__
)), "seq.param(it, -2, 20, 100)" " " "==" " " "100", (long double
) __n1, "==", (long double) __n2, 'i'); } while (0)
;
1172 g_assert_cmpint(seq.param(it, -2, 200, 2000), ==, 1000)do { gint64 __n1 = (seq.param(it, -2, 200, 2000)), __n2 = (1000
); if (__n1 == __n2) ; else g_assertion_message_cmpnum (((gchar
*) 0), "../src/parser-test.cc", 1172, ((const char*) (__PRETTY_FUNCTION__
)), "seq.param(it, -2, 200, 2000)" " " "==" " " "1000", (long
double) __n1, "==", (long double) __n2, 'i'); } while (0)
;
1173 g_assert_cmpint(seq.param(it, -2, 2000, 4000), ==, 2000)do { gint64 __n1 = (seq.param(it, -2, 2000, 4000)), __n2 = (2000
); if (__n1 == __n2) ; else g_assertion_message_cmpnum (((gchar
*) 0), "../src/parser-test.cc", 1173, ((const char*) (__PRETTY_FUNCTION__
)), "seq.param(it, -2, 2000, 4000)" " " "==" " " "2000", (long
double) __n1, "==", (long double) __n2, 'i'); } while (0)
;
1174
1175 int a, b, c,d ;
1176 it = seq.cbegin();
1177 g_assert_false(seq.collect(it, {&a, &b, &c}))do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (!(seq.collect(it, {&a, &b, &c}))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1)) ; else
g_assertion_message (((gchar*) 0), "../src/parser-test.cc", 1177
, ((const char*) (__PRETTY_FUNCTION__)), "'" "seq.collect(it, {&a, &b, &c})"
"' should be FALSE"); } while (0)
;
1178 g_assert_true(seq.collect_subparams(it, {&a}))do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (seq.collect_subparams(it, {&a})) _g_boolean_var_ = 1
; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1)) ; else g_assertion_message
(((gchar*) 0), "../src/parser-test.cc", 1178, ((const char*)
(__PRETTY_FUNCTION__)), "'" "seq.collect_subparams(it, {&a})"
"' should be TRUE"); } while (0)
;
1179 g_assert_true(seq.collect_subparams(it, {&a, &b}))do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (seq.collect_subparams(it, {&a, &b})) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1)) ; else
g_assertion_message (((gchar*) 0), "../src/parser-test.cc", 1179
, ((const char*) (__PRETTY_FUNCTION__)), "'" "seq.collect_subparams(it, {&a, &b})"
"' should be TRUE"); } while (0)
;
1180 g_assert_true(seq.collect_subparams(it, {&a, &b, &c}))do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (seq.collect_subparams(it, {&a, &b, &c})) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1)) ; else
g_assertion_message (((gchar*) 0), "../src/parser-test.cc", 1180
, ((const char*) (__PRETTY_FUNCTION__)), "'" "seq.collect_subparams(it, {&a, &b, &c})"
"' should be TRUE"); } while (0)
;
1181 g_assert_cmpint(a, ==, -1)do { gint64 __n1 = (a), __n2 = (-1); if (__n1 == __n2) ; else
g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1181, ((const char*) (__PRETTY_FUNCTION__)), "a" " " "==" " "
"-1", (long double) __n1, "==", (long double) __n2, 'i'); } while
(0)
;
1182 g_assert_cmpint(b, ==, 0)do { gint64 __n1 = (b), __n2 = (0); if (__n1 == __n2) ; else g_assertion_message_cmpnum
(((gchar*) 0), "../src/parser-test.cc", 1182, ((const char*)
(__PRETTY_FUNCTION__)), "b" " " "==" " " "0", (long double) __n1
, "==", (long double) __n2, 'i'); } while (0)
;
1183 g_assert_cmpint(c, ==, 1000)do { gint64 __n1 = (c), __n2 = (1000); if (__n1 == __n2) ; else
g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1183, ((const char*) (__PRETTY_FUNCTION__)), "c" " " "==" " "
"1000", (long double) __n1, "==", (long double) __n2, 'i'); }
while (0)
;
1184 g_assert_false(seq.collect_subparams(it, {&a, &b, &c, &d}))do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (!(seq.collect_subparams(it, {&a, &b, &c, &
d}))) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_
; }), 1)) ; else g_assertion_message (((gchar*) 0), "../src/parser-test.cc"
, 1184, ((const char*) (__PRETTY_FUNCTION__)), "'" "seq.collect_subparams(it, {&a, &b, &c, &d})"
"' should be FALSE"); } while (0)
;
1185
1186 it = seq.next(it);
1187 g_assert_true(seq.collect(it, {&a}))do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (seq.collect(it, {&a})) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message (((
gchar*) 0), "../src/parser-test.cc", 1187, ((const char*) (__PRETTY_FUNCTION__
)), "'" "seq.collect(it, {&a})" "' should be TRUE"); } while
(0)
;
1188 g_assert_true(seq.collect(it, {&a, &b}))do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (seq.collect(it, {&a, &b})) _g_boolean_var_ = 1;
else _g_boolean_var_ = 0; _g_boolean_var_; }), 1)) ; else g_assertion_message
(((gchar*) 0), "../src/parser-test.cc", 1188, ((const char*)
(__PRETTY_FUNCTION__)), "'" "seq.collect(it, {&a, &b})"
"' should be TRUE"); } while (0)
;
1189 g_assert_true(seq.collect(it, {&a, &b, &c}))do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (seq.collect(it, {&a, &b, &c})) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1)) ; else
g_assertion_message (((gchar*) 0), "../src/parser-test.cc", 1189
, ((const char*) (__PRETTY_FUNCTION__)), "'" "seq.collect(it, {&a, &b, &c})"
"' should be TRUE"); } while (0)
;
1190 g_assert_cmpint(a, ==, 2)do { gint64 __n1 = (a), __n2 = (2); if (__n1 == __n2) ; else g_assertion_message_cmpnum
(((gchar*) 0), "../src/parser-test.cc", 1190, ((const char*)
(__PRETTY_FUNCTION__)), "a" " " "==" " " "2", (long double) __n1
, "==", (long double) __n2, 'i'); } while (0)
;
1191 g_assert_cmpint(b, ==, 3)do { gint64 __n1 = (b), __n2 = (3); if (__n1 == __n2) ; else g_assertion_message_cmpnum
(((gchar*) 0), "../src/parser-test.cc", 1191, ((const char*)
(__PRETTY_FUNCTION__)), "b" " " "==" " " "3", (long double) __n1
, "==", (long double) __n2, 'i'); } while (0)
;
1192 g_assert_cmpint(c, ==, 4)do { gint64 __n1 = (c), __n2 = (4); if (__n1 == __n2) ; else g_assertion_message_cmpnum
(((gchar*) 0), "../src/parser-test.cc", 1192, ((const char*)
(__PRETTY_FUNCTION__)), "c" " " "==" " " "4", (long double) __n1
, "==", (long double) __n2, 'i'); } while (0)
;
1193 g_assert_false(seq.collect(it, {&a, &b, &c, &d}))do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (!(seq.collect(it, {&a, &b, &c, &d}))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1)) ; else
g_assertion_message (((gchar*) 0), "../src/parser-test.cc", 1193
, ((const char*) (__PRETTY_FUNCTION__)), "'" "seq.collect(it, {&a, &b, &c, &d})"
"' should be FALSE"); } while (0)
;
1194
1195 it = seq.next(it);
1196 it = seq.next(it);
1197 it = seq.next(it);
1198 g_assert_false(seq.collect(it, {&a}))do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (!(seq.collect(it, {&a}))) _g_boolean_var_ = 1; else
_g_boolean_var_ = 0; _g_boolean_var_; }), 1)) ; else g_assertion_message
(((gchar*) 0), "../src/parser-test.cc", 1198, ((const char*)
(__PRETTY_FUNCTION__)), "'" "seq.collect(it, {&a})" "' should be FALSE"
); } while (0)
;
1199 g_assert_true(seq.collect_subparams(it, {&a}))do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (seq.collect_subparams(it, {&a})) _g_boolean_var_ = 1
; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1)) ; else g_assertion_message
(((gchar*) 0), "../src/parser-test.cc", 1199, ((const char*)
(__PRETTY_FUNCTION__)), "'" "seq.collect_subparams(it, {&a})"
"' should be TRUE"); } while (0)
;
1200 g_assert_true(seq.collect_subparams(it, {&a, &b}))do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (seq.collect_subparams(it, {&a, &b})) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1)) ; else
g_assertion_message (((gchar*) 0), "../src/parser-test.cc", 1200
, ((const char*) (__PRETTY_FUNCTION__)), "'" "seq.collect_subparams(it, {&a, &b})"
"' should be TRUE"); } while (0)
;
1201 g_assert_cmpint(a, ==, -1)do { gint64 __n1 = (a), __n2 = (-1); if (__n1 == __n2) ; else
g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1201, ((const char*) (__PRETTY_FUNCTION__)), "a" " " "==" " "
"-1", (long double) __n1, "==", (long double) __n2, 'i'); } while
(0)
;
1202 g_assert_cmpint(b, ==, -1)do { gint64 __n1 = (b), __n2 = (-1); if (__n1 == __n2) ; else
g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1202, ((const char*) (__PRETTY_FUNCTION__)), "b" " " "==" " "
"-1", (long double) __n1, "==", (long double) __n2, 'i'); } while
(0)
;
1203 g_assert_false(seq.collect_subparams(it, {&a, &b, &c}))do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (!(seq.collect_subparams(it, {&a, &b, &c})))
_g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_
; }), 1)) ; else g_assertion_message (((gchar*) 0), "../src/parser-test.cc"
, 1203, ((const char*) (__PRETTY_FUNCTION__)), "'" "seq.collect_subparams(it, {&a, &b, &c})"
"' should be FALSE"); } while (0)
;
1204 it = seq.next(it);
1205 g_assert_true(seq.collect(it, {&a}))do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (seq.collect(it, {&a})) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message (((
gchar*) 0), "../src/parser-test.cc", 1205, ((const char*) (__PRETTY_FUNCTION__
)), "'" "seq.collect(it, {&a})" "' should be TRUE"); } while
(0)
;
1206 g_assert_cmpint(a, ==, -1)do { gint64 __n1 = (a), __n2 = (-1); if (__n1 == __n2) ; else
g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1206, ((const char*) (__PRETTY_FUNCTION__)), "a" " " "==" " "
"-1", (long double) __n1, "==", (long double) __n2, 'i'); } while
(0)
;
1207 g_assert_true(seq.collect(it, {&a, &b}))do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (seq.collect(it, {&a, &b})) _g_boolean_var_ = 1;
else _g_boolean_var_ = 0; _g_boolean_var_; }), 1)) ; else g_assertion_message
(((gchar*) 0), "../src/parser-test.cc", 1207, ((const char*)
(__PRETTY_FUNCTION__)), "'" "seq.collect(it, {&a, &b})"
"' should be TRUE"); } while (0)
; /* past-the-end params are final and default */
1208 g_assert_cmpint(a, ==, -1)do { gint64 __n1 = (a), __n2 = (-1); if (__n1 == __n2) ; else
g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1208, ((const char*) (__PRETTY_FUNCTION__)), "a" " " "==" " "
"-1", (long double) __n1, "==", (long double) __n2, 'i'); } while
(0)
;
1209 g_assert_cmpint(b, ==, -1)do { gint64 __n1 = (b), __n2 = (-1); if (__n1 == __n2) ; else
g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1209, ((const char*) (__PRETTY_FUNCTION__)), "b" " " "==" " "
"-1", (long double) __n1, "==", (long double) __n2, 'i'); } while
(0)
;
1210 g_assert_true(seq.collect(it, {&a, &b, &c}))do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (seq.collect(it, {&a, &b, &c})) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1)) ; else
g_assertion_message (((gchar*) 0), "../src/parser-test.cc", 1210
, ((const char*) (__PRETTY_FUNCTION__)), "'" "seq.collect(it, {&a, &b, &c})"
"' should be TRUE"); } while (0)
; /* past-the-end params are final and default */
1211 g_assert_cmpint(a, ==, -1)do { gint64 __n1 = (a), __n2 = (-1); if (__n1 == __n2) ; else
g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1211, ((const char*) (__PRETTY_FUNCTION__)), "a" " " "==" " "
"-1", (long double) __n1, "==", (long double) __n2, 'i'); } while
(0)
;
1212 g_assert_cmpint(b, ==, -1)do { gint64 __n1 = (b), __n2 = (-1); if (__n1 == __n2) ; else
g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1212, ((const char*) (__PRETTY_FUNCTION__)), "b" " " "==" " "
"-1", (long double) __n1, "==", (long double) __n2, 'i'); } while
(0)
;
1213 g_assert_cmpint(c, ==, -1)do { gint64 __n1 = (c), __n2 = (-1); if (__n1 == __n2) ; else
g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1213, ((const char*) (__PRETTY_FUNCTION__)), "c" " " "==" " "
"-1", (long double) __n1, "==", (long double) __n2, 'i'); } while
(0)
;
1214
1215 it = seq.cbegin();
1216 g_assert_cmpint(seq.collect1(it, -2), ==, -2)do { gint64 __n1 = (seq.collect1(it, -2)), __n2 = (-2); if (__n1
== __n2) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1216, ((const char*) (__PRETTY_FUNCTION__)), "seq.collect1(it, -2)"
" " "==" " " "-2", (long double) __n1, "==", (long double) __n2
, 'i'); } while (0)
;
1217 it = seq.next(it);
1218 g_assert_cmpint(seq.collect1(it), ==, 2)do { gint64 __n1 = (seq.collect1(it)), __n2 = (2); if (__n1 ==
__n2) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1218, ((const char*) (__PRETTY_FUNCTION__)), "seq.collect1(it)"
" " "==" " " "2", (long double) __n1, "==", (long double) __n2
, 'i'); } while (0)
;
1219 g_assert_cmpint(seq.collect1(it), ==, 2)do { gint64 __n1 = (seq.collect1(it)), __n2 = (2); if (__n1 ==
__n2) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1219, ((const char*) (__PRETTY_FUNCTION__)), "seq.collect1(it)"
" " "==" " " "2", (long double) __n1, "==", (long double) __n2
, 'i'); } while (0)
;
1220 it = seq.next(it);
1221 g_assert_cmpint(seq.collect1(it), ==, 3)do { gint64 __n1 = (seq.collect1(it)), __n2 = (3); if (__n1 ==
__n2) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1221, ((const char*) (__PRETTY_FUNCTION__)), "seq.collect1(it)"
" " "==" " " "3", (long double) __n1, "==", (long double) __n2
, 'i'); } while (0)
;
1222 it = seq.next(it);
1223 g_assert_cmpint(seq.collect1(it), ==, 4)do { gint64 __n1 = (seq.collect1(it)), __n2 = (4); if (__n1 ==
__n2) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1223, ((const char*) (__PRETTY_FUNCTION__)), "seq.collect1(it)"
" " "==" " " "4", (long double) __n1, "==", (long double) __n2
, 'i'); } while (0)
;
1224 it = seq.next(it);
1225 g_assert_cmpint(seq.collect1(it, -3), ==, -3)do { gint64 __n1 = (seq.collect1(it, -3)), __n2 = (-3); if (__n1
== __n2) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1225, ((const char*) (__PRETTY_FUNCTION__)), "seq.collect1(it, -3)"
" " "==" " " "-3", (long double) __n1, "==", (long double) __n2
, 'i'); } while (0)
;
1226 it = seq.next(it);
1227 g_assert_cmpint(seq.collect1(it), ==, -1)do { gint64 __n1 = (seq.collect1(it)), __n2 = (-1); if (__n1 ==
__n2) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1227, ((const char*) (__PRETTY_FUNCTION__)), "seq.collect1(it)"
" " "==" " " "-1", (long double) __n1, "==", (long double) __n2
, 'i'); } while (0)
;
1228 g_assert_cmpint(seq.collect1(it, 42), ==, 42)do { gint64 __n1 = (seq.collect1(it, 42)), __n2 = (42); if (__n1
== __n2) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1228, ((const char*) (__PRETTY_FUNCTION__)), "seq.collect1(it, 42)"
" " "==" " " "42", (long double) __n1, "==", (long double) __n2
, 'i'); } while (0)
;
1229 g_assert_cmpint(seq.collect1(it, -1, 0, 100), ==, 0)do { gint64 __n1 = (seq.collect1(it, -1, 0, 100)), __n2 = (0)
; if (__n1 == __n2) ; else g_assertion_message_cmpnum (((gchar
*) 0), "../src/parser-test.cc", 1229, ((const char*) (__PRETTY_FUNCTION__
)), "seq.collect1(it, -1, 0, 100)" " " "==" " " "0", (long double
) __n1, "==", (long double) __n2, 'i'); } while (0)
;
1230 g_assert_cmpint(seq.collect1(it, 42, 0, 100), ==, 42)do { gint64 __n1 = (seq.collect1(it, 42, 0, 100)), __n2 = (42
); if (__n1 == __n2) ; else g_assertion_message_cmpnum (((gchar
*) 0), "../src/parser-test.cc", 1230, ((const char*) (__PRETTY_FUNCTION__
)), "seq.collect1(it, 42, 0, 100)" " " "==" " " "42", (long double
) __n1, "==", (long double) __n2, 'i'); } while (0)
;
1231 g_assert_cmpint(seq.collect1(it, 42, 0, 10), ==, 10)do { gint64 __n1 = (seq.collect1(it, 42, 0, 10)), __n2 = (10)
; if (__n1 == __n2) ; else g_assertion_message_cmpnum (((gchar
*) 0), "../src/parser-test.cc", 1231, ((const char*) (__PRETTY_FUNCTION__
)), "seq.collect1(it, 42, 0, 10)" " " "==" " " "10", (long double
) __n1, "==", (long double) __n2, 'i'); } while (0)
;
1232 g_assert_cmpint(seq.collect1(it, 42, 100, 200), ==, 100)do { gint64 __n1 = (seq.collect1(it, 42, 100, 200)), __n2 = (
100); if (__n1 == __n2) ; else g_assertion_message_cmpnum (((
gchar*) 0), "../src/parser-test.cc", 1232, ((const char*) (__PRETTY_FUNCTION__
)), "seq.collect1(it, 42, 100, 200)" " " "==" " " "100", (long
double) __n1, "==", (long double) __n2, 'i'); } while (0)
;
1233}
1234
1235static int
1236feed_parser_st(bte_seq_builder& b,
1237 bool c1 = false,
1238 ssize_t max_arg_str_len = -1,
1239 u32SequenceBuilder::Introducer introducer = u32SequenceBuilder::Introducer::DEFAULT,
1240 u32SequenceBuilder::ST st = u32SequenceBuilder::ST::DEFAULT)
1241{
1242 std::u32string s;
1243 b.to_string(s, c1, max_arg_str_len, introducer, st);
1244
1245 auto rv = feed_parser(s);
1246 if (rv != BTE_SEQ_OSC)
1247 return rv;
1248
1249 switch (st) {
1250 case u32SequenceBuilder::ST::NONE:
1251 g_assert_cmpuint(seq.terminator(), ==, 0)do { guint64 __n1 = (seq.terminator()), __n2 = (0); if (__n1 ==
__n2) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1251, ((const char*) (__PRETTY_FUNCTION__)), "seq.terminator()"
" " "==" " " "0", (long double) __n1, "==", (long double) __n2
, 'i'); } while (0)
;
1252 break;
1253 case u32SequenceBuilder::ST::DEFAULT:
1254 g_assert_cmpuint(seq.terminator(), ==, c1 ? 0x9c /* ST */ : 0x5c /* BACKSLASH */)do { guint64 __n1 = (seq.terminator()), __n2 = (c1 ? 0x9c : 0x5c
); if (__n1 == __n2) ; else g_assertion_message_cmpnum (((gchar
*) 0), "../src/parser-test.cc", 1254, ((const char*) (__PRETTY_FUNCTION__
)), "seq.terminator()" " " "==" " " "c1 ? 0x9c : 0x5c", (long
double) __n1, "==", (long double) __n2, 'i'); } while (0)
;
1255 break;
1256 case u32SequenceBuilder::ST::C0:
1257 g_assert_cmpuint(seq.terminator(), ==, 0x5c /* BACKSLASH */)do { guint64 __n1 = (seq.terminator()), __n2 = (0x5c); if (__n1
== __n2) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1257, ((const char*) (__PRETTY_FUNCTION__)), "seq.terminator()"
" " "==" " " "0x5c", (long double) __n1, "==", (long double)
__n2, 'i'); } while (0)
;
1258 break;
1259 case u32SequenceBuilder::ST::C1:
1260 g_assert_cmpuint(seq.terminator(), ==, 0x9c /* ST */)do { guint64 __n1 = (seq.terminator()), __n2 = (0x9c); if (__n1
== __n2) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1260, ((const char*) (__PRETTY_FUNCTION__)), "seq.terminator()"
" " "==" " " "0x9c", (long double) __n1, "==", (long double)
__n2, 'i'); } while (0)
;
1261 break;
1262 case u32SequenceBuilder::ST::BEL:
1263 g_assert_cmpuint(seq.terminator(), ==, 0x7 /* BEL */)do { guint64 __n1 = (seq.terminator()), __n2 = (0x7); if (__n1
== __n2) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1263, ((const char*) (__PRETTY_FUNCTION__)), "seq.terminator()"
" " "==" " " "0x7", (long double) __n1, "==", (long double) __n2
, 'i'); } while (0)
;
1264 break;
1265 }
1266
1267 return rv;
1268}
1269
1270static void
1271test_seq_osc(std::u32string const& str,
1272 int expected_rv = BTE_SEQ_OSC,
1273 bool c1 = true,
1274 ssize_t max_arg_str_len = -1,
1275 u32SequenceBuilder::Introducer introducer = u32SequenceBuilder::Introducer::DEFAULT,
1276 u32SequenceBuilder::ST st = u32SequenceBuilder::ST::DEFAULT)
1277{
1278 bte_seq_builder b{BTE_SEQ_OSC, str};
1279
1280 parser.reset();
1281 auto rv = feed_parser_st(b, c1, max_arg_str_len, introducer, st);
1282 g_assert_cmpint(rv, ==, expected_rv)do { gint64 __n1 = (rv), __n2 = (expected_rv); if (__n1 == __n2
) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1282, ((const char*) (__PRETTY_FUNCTION__)), "rv" " " "==" " "
"expected_rv", (long double) __n1, "==", (long double) __n2,
'i'); } while (0)
;
1283 #if 0
1284 if (rv != BTE_SEQ_NONE)
1285 b.assert_equal(seq);
1286 #endif
1287
1288 if (expected_rv != BTE_SEQ_OSC)
1289 return;
1290
1291 if (max_arg_str_len < 0 || size_t(max_arg_str_len) == str.size())
1292 g_assert_true(seq.string() == str)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (seq.string() == str) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message (((
gchar*) 0), "../src/parser-test.cc", 1292, ((const char*) (__PRETTY_FUNCTION__
)), "'" "seq.string() == str" "' should be TRUE"); } while (0
)
;
1293 else
1294 g_assert_true(seq.string() == str.substr(0, max_arg_str_len))do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (seq.string() == str.substr(0, max_arg_str_len)) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1)) ; else
g_assertion_message (((gchar*) 0), "../src/parser-test.cc", 1294
, ((const char*) (__PRETTY_FUNCTION__)), "'" "seq.string() == str.substr(0, max_arg_str_len)"
"' should be TRUE"); } while (0)
;
1295}
1296
1297static int
1298controls_match(bool c1,
1299 u32SequenceBuilder::Introducer introducer,
1300 u32SequenceBuilder::ST st,
1301 bool allow_bel,
1302 int expected_rv)
1303{
1304 if (introducer == u32SequenceBuilder::Introducer::DEFAULT)
1305 introducer = c1 ? u32SequenceBuilder::Introducer::C1 : u32SequenceBuilder::Introducer::C0;
1306 if (st == u32SequenceBuilder::ST::DEFAULT)
1307 st = c1 ? u32SequenceBuilder::ST::C1 : u32SequenceBuilder::ST::C0;
1308 if ((introducer == u32SequenceBuilder::Introducer::C0 &&
1309 (st == u32SequenceBuilder::ST::C0 || (allow_bel && st == u32SequenceBuilder::ST::BEL))) ||
1310 (introducer == u32SequenceBuilder::Introducer::C1 &&
1311 st == u32SequenceBuilder::ST::C1))
1312 return expected_rv;
1313 return BTE_SEQ_IGNORE;
1314}
1315
1316static void
1317test_seq_osc(void)
1318{
1319 /* Simple */
1320 test_seq_osc(U""s);
1321 test_seq_osc(U"TEST"s);
1322
1323 /* String of any supported length */
1324 for (unsigned int len = 0; len < BTE_SEQ_STRING_MAX_CAPACITY(1 << 12); ++len)
1325 test_seq_osc(std::u32string(len, 0x10000+len));
1326
1327 /* Length exceeded */
1328 test_seq_osc(std::u32string(BTE_SEQ_STRING_MAX_CAPACITY(1 << 12) + 1, 0x100000), BTE_SEQ_IGNORE);
1329
1330 /* Test all introducer/ST combinations */
1331 for (auto introducer : { u32SequenceBuilder::Introducer::DEFAULT,
1332 u32SequenceBuilder::Introducer::C0,
1333 u32SequenceBuilder::Introducer::C1 }) {
1334 for (auto st : {u32SequenceBuilder::ST::DEFAULT,
1335 u32SequenceBuilder::ST::C0,
1336 u32SequenceBuilder::ST::C1,
1337 u32SequenceBuilder::ST::BEL }) {
1338 for (auto c1 : { false, true }) {
1339 int expected_rv = controls_match(c1, introducer, st, true, BTE_SEQ_OSC);
1340 test_seq_osc(U"TEST"s, expected_rv, c1, -1, introducer, st);
1341 }
1342 }
1343 }
1344}
1345
1346static void
1347test_seq_glue_string(void)
1348{
1349 std::u32string str{U"TEST"s};
1350 test_seq_osc(str);
1351
1352 g_assert_true(seq.string() == str)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (seq.string() == str) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message (((
gchar*) 0), "../src/parser-test.cc", 1352, ((const char*) (__PRETTY_FUNCTION__
)), "'" "seq.string() == str" "' should be TRUE"); } while (0
)
;
1353}
1354
1355static void
1356test_seq_glue_string_tokeniser(void)
1357{
1358 std::string str{"a;1b:17:test::b:;3;5;def;17 a;ghi;"s};
1359
1360 StringTokeniser tokeniser{str, ';'};
1361
1362 auto start = tokeniser.cbegin();
1363 auto end = tokeniser.cend();
1364
1365 auto pit = start;
1366 for (auto it : {"a"s, "1b:17:test::b:"s, "3"s, "5"s, "def"s, "17 a"s, "ghi"s, ""s}) {
1367 g_assert_true(it == *pit)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (it == *pit) _g_boolean_var_ = 1; else _g_boolean_var_ =
0; _g_boolean_var_; }), 1)) ; else g_assertion_message (((gchar
*) 0), "../src/parser-test.cc", 1367, ((const char*) (__PRETTY_FUNCTION__
)), "'" "it == *pit" "' should be TRUE"); } while (0)
;
1368
1369 /* Use std::find to see if the InputIterator implementation
1370 * is complete and correct.
1371 */
1372 auto fit = std::find(start, end, it);
1373 g_assert_true(fit == pit)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (fit == pit) _g_boolean_var_ = 1; else _g_boolean_var_ =
0; _g_boolean_var_; }), 1)) ; else g_assertion_message (((gchar
*) 0), "../src/parser-test.cc", 1373, ((const char*) (__PRETTY_FUNCTION__
)), "'" "fit == pit" "' should be TRUE"); } while (0)
;
1374
1375 ++pit;
1376 }
1377 g_assert_true(pit == end)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (pit == end) _g_boolean_var_ = 1; else _g_boolean_var_ =
0; _g_boolean_var_; }), 1)) ; else g_assertion_message (((gchar
*) 0), "../src/parser-test.cc", 1377, ((const char*) (__PRETTY_FUNCTION__
)), "'" "pit == end" "' should be TRUE"); } while (0)
;
1378
1379 auto len = str.size();
1380 size_t pos = 0;
1381 pit = start;
1382 for (auto it : {1, 14, 1, 1, 3, 4, 3, 0}) {
1383 g_assert_cmpuint(it, ==, pit.size())do { guint64 __n1 = (it), __n2 = (pit.size()); if (__n1 == __n2
) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1383, ((const char*) (__PRETTY_FUNCTION__)), "it" " " "==" " "
"pit.size()", (long double) __n1, "==", (long double) __n2, 'i'
); } while (0)
;
1384 g_assert_cmpuint(len, ==, pit.size_remaining())do { guint64 __n1 = (len), __n2 = (pit.size_remaining()); if (
__n1 == __n2) ; else g_assertion_message_cmpnum (((gchar*) 0)
, "../src/parser-test.cc", 1384, ((const char*) (__PRETTY_FUNCTION__
)), "len" " " "==" " " "pit.size_remaining()", (long double) __n1
, "==", (long double) __n2, 'i'); } while (0)
;
1385
1386 g_assert_true(pit.string_remaining() == str.substr(pos, std::string::npos))do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (pit.string_remaining() == str.substr(pos, std::string::
npos)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_
; }), 1)) ; else g_assertion_message (((gchar*) 0), "../src/parser-test.cc"
, 1386, ((const char*) (__PRETTY_FUNCTION__)), "'" "pit.string_remaining() == str.substr(pos, std::string::npos)"
"' should be TRUE"); } while (0)
;
1387
1388 len -= it + 1;
1389 pos += it + 1;
1390
1391 ++pit;
1392 }
1393 g_assert_cmpuint(len + 1, ==, 0)do { guint64 __n1 = (len + 1), __n2 = (0); if (__n1 == __n2) ;
else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1393, ((const char*) (__PRETTY_FUNCTION__)), "len + 1" " " "=="
" " "0", (long double) __n1, "==", (long double) __n2, 'i');
} while (0)
;
1394 g_assert_cmpuint(pos, ==, str.size() + 1)do { guint64 __n1 = (pos), __n2 = (str.size() + 1); if (__n1 ==
__n2) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1394, ((const char*) (__PRETTY_FUNCTION__)), "pos" " " "=="
" " "str.size() + 1", (long double) __n1, "==", (long double
) __n2, 'i'); } while (0)
;
1395
1396 pit = start;
1397 for (auto it : {-2, -2, 3, 5, -2, -2, -2, -1}) {
1398 int num;
1399 bool v = pit.number(num);
1400 if (it == -2)
1401 g_assert_false(v)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (!(v)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_
; }), 1)) ; else g_assertion_message (((gchar*) 0), "../src/parser-test.cc"
, 1401, ((const char*) (__PRETTY_FUNCTION__)), "'" "v" "' should be FALSE"
); } while (0)
;
1402 else
1403 g_assert_cmpint(it, ==, num)do { gint64 __n1 = (it), __n2 = (num); if (__n1 == __n2) ; else
g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-test.cc"
, 1403, ((const char*) (__PRETTY_FUNCTION__)), "it" " " "==" " "
"num", (long double) __n1, "==", (long double) __n2, 'i'); }
while (0)
;
1404
1405 ++pit;
1406 }
1407
1408 /* Test range for */
1409 for (auto it : tokeniser)
1410 ;
1411
1412 /* Test different separator */
1413 pit = start;
1414 ++pit;
1415
1416 auto substr = *pit;
1417 StringTokeniser subtokeniser{substr, ':'};
1418
1419 auto subpit = subtokeniser.cbegin();
1420 for (auto it : {"1b"s, "17"s, "test"s, ""s, "b"s, ""s}) {
1421 g_assert_true(it == *subpit)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (it == *subpit) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message (((
gchar*) 0), "../src/parser-test.cc", 1421, ((const char*) (__PRETTY_FUNCTION__
)), "'" "it == *subpit" "' should be TRUE"); } while (0)
;
1422
1423 ++subpit;
1424 }
1425 g_assert_true(subpit == subtokeniser.cend())do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (subpit == subtokeniser.cend()) _g_boolean_var_ = 1; else
_g_boolean_var_ = 0; _g_boolean_var_; }), 1)) ; else g_assertion_message
(((gchar*) 0), "../src/parser-test.cc", 1425, ((const char*)
(__PRETTY_FUNCTION__)), "'" "subpit == subtokeniser.cend()" "' should be TRUE"
); } while (0)
;
1426
1427 /* Test another string, one that doesn't end with an empty token */
1428 std::string str2{"abc;defghi"s};
1429 StringTokeniser tokeniser2{str2, ';'};
1430
1431 g_assert_cmpint(std::distance(tokeniser2.cbegin(), tokeniser2.cend()), ==, 2)do { gint64 __n1 = (std::distance(tokeniser2.cbegin(), tokeniser2
.cend())), __n2 = (2); if (__n1 == __n2) ; else g_assertion_message_cmpnum
(((gchar*) 0), "../src/parser-test.cc", 1431, ((const char*)
(__PRETTY_FUNCTION__)), "std::distance(tokeniser2.cbegin(), tokeniser2.cend())"
" " "==" " " "2", (long double) __n1, "==", (long double) __n2
, 'i'); } while (0)
;
1432 auto pit2 = tokeniser2.cbegin();
1433 g_assert_true(*pit2 == "abc"s)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (*pit2 == "abc"s) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message (((
gchar*) 0), "../src/parser-test.cc", 1433, ((const char*) (__PRETTY_FUNCTION__
)), "'" "*pit2 == \"abc\"s" "' should be TRUE"); } while (0)
;
1434 ++pit2;
1435 g_assert_true(*pit2 == "defghi"s)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (*pit2 == "defghi"s) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message (((
gchar*) 0), "../src/parser-test.cc", 1435, ((const char*) (__PRETTY_FUNCTION__
)), "'" "*pit2 == \"defghi\"s" "' should be TRUE"); } while (
0)
;
1436 ++pit2;
1437 g_assert_true(pit2 == tokeniser2.cend())do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (pit2 == tokeniser2.cend()) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message (((
gchar*) 0), "../src/parser-test.cc", 1437, ((const char*) (__PRETTY_FUNCTION__
)), "'" "pit2 == tokeniser2.cend()" "' should be TRUE"); } while
(0)
;
1438
1439 /* Test another string, one that starts with an empty token */
1440 std::string str3{";abc"s};
1441 StringTokeniser tokeniser3{str3, ';'};
1442
1443 g_assert_cmpint(std::distance(tokeniser3.cbegin(), tokeniser3.cend()), ==, 2)do { gint64 __n1 = (std::distance(tokeniser3.cbegin(), tokeniser3
.cend())), __n2 = (2); if (__n1 == __n2) ; else g_assertion_message_cmpnum
(((gchar*) 0), "../src/parser-test.cc", 1443, ((const char*)
(__PRETTY_FUNCTION__)), "std::distance(tokeniser3.cbegin(), tokeniser3.cend())"
" " "==" " " "2", (long double) __n1, "==", (long double) __n2
, 'i'); } while (0)
;
1444 auto pit3 = tokeniser3.cbegin();
1445 g_assert_true(*pit3 == ""s)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (*pit3 == ""s) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message (((
gchar*) 0), "../src/parser-test.cc", 1445, ((const char*) (__PRETTY_FUNCTION__
)), "'" "*pit3 == \"\"s" "' should be TRUE"); } while (0)
;
1446 ++pit3;
1447 g_assert_true(*pit3 == "abc"s)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (*pit3 == "abc"s) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message (((
gchar*) 0), "../src/parser-test.cc", 1447, ((const char*) (__PRETTY_FUNCTION__
)), "'" "*pit3 == \"abc\"s" "' should be TRUE"); } while (0)
;
1448 ++pit3;
1449 g_assert_true(pit3 == tokeniser3.cend())do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (pit3 == tokeniser3.cend()) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message (((
gchar*) 0), "../src/parser-test.cc", 1449, ((const char*) (__PRETTY_FUNCTION__
)), "'" "pit3 == tokeniser3.cend()" "' should be TRUE"); } while
(0)
;
1450
1451 /* And try an empty string, which should split into one empty token */
1452 std::string str4{""s};
1453 StringTokeniser tokeniser4{str4, ';'};
1454
1455 g_assert_cmpint(std::distance(tokeniser4.cbegin(), tokeniser4.cend()), ==, 1)do { gint64 __n1 = (std::distance(tokeniser4.cbegin(), tokeniser4
.cend())), __n2 = (1); if (__n1 == __n2) ; else g_assertion_message_cmpnum
(((gchar*) 0), "../src/parser-test.cc", 1455, ((const char*)
(__PRETTY_FUNCTION__)), "std::distance(tokeniser4.cbegin(), tokeniser4.cend())"
" " "==" " " "1", (long double) __n1, "==", (long double) __n2
, 'i'); } while (0)
;
1456 auto pit4 = tokeniser4.cbegin();
1457 g_assert_true(*pit4 == ""s)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (*pit4 == ""s) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message (((
gchar*) 0), "../src/parser-test.cc", 1457, ((const char*) (__PRETTY_FUNCTION__
)), "'" "*pit4 == \"\"s" "' should be TRUE"); } while (0)
;
1458 ++pit4;
1459 g_assert_true(pit4 == tokeniser4.cend())do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (pit4 == tokeniser4.cend()) _g_boolean_var_ = 1; else _g_boolean_var_
= 0; _g_boolean_var_; }), 1)) ; else g_assertion_message (((
gchar*) 0), "../src/parser-test.cc", 1459, ((const char*) (__PRETTY_FUNCTION__
)), "'" "pit4 == tokeniser4.cend()" "' should be TRUE"); } while
(0)
;
1460}
1461
1462static void
1463test_seq_glue_sequence_builder(void)
1464{
1465 /* This is sufficiently tested by being used in all the other tests,
1466 * but if there's anything remaining to be tested, do it here.
1467 */
1468}
1469
1470static void
1471test_seq_glue_reply_builder(void)
1472{
1473 /* Nothing to test here; ReplyBuilder is just a constructor for
1474 * SequenceBuilder.
1475 */
1476}
1477
1478int
1479main(int argc,
1480 char* argv[])
1481{
1482 g_test_init(&argc, &argv, nullptr);
1483
1484 g_test_add_func("/bte/parser/sequences/arg", test_seq_arg);
1485 g_test_add_func("/bte/parser/sequences/string", test_seq_string);
1486 g_test_add_func("/bte/parser/sequences/glue/arg", test_seq_glue_arg);
1487 g_test_add_func("/bte/parser/sequences/glue/string", test_seq_glue_string);
1488 g_test_add_func("/bte/parser/sequences/glue/string-tokeniser", test_seq_glue_string_tokeniser);
1489 g_test_add_func("/bte/parser/sequences/glue/sequence-builder", test_seq_glue_sequence_builder);
1490 g_test_add_func("/bte/parser/sequences/glue/reply-builder", test_seq_glue_reply_builder);
1491 g_test_add_func("/bte/parser/sequences/control", test_seq_control);
1492 g_test_add_func("/bte/parser/sequences/escape/invalid", test_seq_esc_invalid);
1493 g_test_add_func("/bte/parser/sequences/escape/charset/94", test_seq_esc_charset_94);
1494 g_test_add_func("/bte/parser/sequences/escape/charset/96", test_seq_esc_charset_96);
1495 g_test_add_func("/bte/parser/sequences/escape/charset/94^n", test_seq_esc_charset_94_n);
1496 g_test_add_func("/bte/parser/sequences/escape/charset/96^n", test_seq_esc_charset_96_n);
1497 g_test_add_func("/bte/parser/sequences/escape/charset/control", test_seq_esc_charset_control);
1498 g_test_add_func("/bte/parser/sequences/escape/charset/other", test_seq_esc_charset_other);
1499 g_test_add_func("/bte/parser/sequences/escape/nF", test_seq_esc_nF);
1500 g_test_add_func("/bte/parser/sequences/escape/F[pes]", test_seq_esc_Fpes);
1501 g_test_add_func("/bte/parser/sequences/escape/known", test_seq_esc_known);
1502 g_test_add_func("/bte/parser/sequences/csi", test_seq_csi);
1503 g_test_add_func("/bte/parser/sequences/csi/known", test_seq_csi_known);
1504 g_test_add_func("/bte/parser/sequences/csi/parameters", test_seq_csi_param);
1505 g_test_add_func("/bte/parser/sequences/csi/clear", test_seq_csi_clear);
1506 g_test_add_func("/bte/parser/sequences/csi/max", test_seq_csi_max);
1507 g_test_add_func("/bte/parser/sequences/sci", test_seq_sci);
1508 g_test_add_func("/bte/parser/sequences/sci/known", test_seq_sci_known);
1509 g_test_add_func("/bte/parser/sequences/dcs", test_seq_dcs);
1510 g_test_add_func("/bte/parser/sequences/dcs/known", test_seq_dcs_known);
1511 g_test_add_func("/bte/parser/sequences/osc", test_seq_osc);
1512
1513 return g_test_run();
1514}

../src/parser-glue.hh

1/*
2 * Copyright © 2017, 2018 Christian Persch
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 3 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#pragma once
19
20#include <cstdint>
21#include <algorithm>
22#include <string>
23
24#include "parser.hh"
25
26namespace bte {
27
28namespace parser {
29
30class Sequence;
31
32class Parser {
33public:
34 friend class Sequence;
35
36 Parser() noexcept
37 {
38 bte_parser_init(&m_parser);
39 }
40 Parser(Parser const&) = delete;
41 Parser(Parser&&) = delete;
42
43 ~Parser() noexcept
44 {
45 bte_parser_deinit(&m_parser);
46 }
47
48 Parser& operator=(Parser const&) = delete;
49 Parser& operator=(Parser&&) = delete;
50
51 inline int feed(uint32_t raw) noexcept
52 {
53 return bte_parser_feed(&m_parser, raw);
54 }
55
56 inline void reset() noexcept
57 {
58 bte_parser_reset(&m_parser);
59 }
60
61protected:
62 bte_parser_t m_parser;
63}; // class Parser
64
65class Sequence {
66public:
67
68 Sequence() = default;
69 Sequence(Sequence const&) = delete;
70 Sequence(Sequence&&) = delete;
71 ~Sequence() = default;
72
73 Sequence(Parser& parser)
74 {
75 m_seq = &parser.m_parser.seq;
76 }
77
78 typedef int number;
79
80 char* ucs4_to_utf8(gunichar const* str,
81 ssize_t len = -1) const noexcept;
82
83 void print() const noexcept;
84
85 /* type:
86 *
87 *
88 * Returns: the type of the sequence, a value from the BTE_SEQ_* enum
89 */
90 inline constexpr unsigned int type() const noexcept
91 {
92 return m_seq->type;
93 }
94
95 /* command:
96 *
97 * Returns: the command the sequence codes for, a value
98 * from the BTE_CMD_* enum, or %BTE_CMD_NONE if the command is
99 * unknown
100 */
101 inline constexpr unsigned int command() const noexcept
102 {
103 return m_seq->command;
104 }
105
106 /* charset:
107 *
108 * This is the charset to use in a %BTE_CMD_GnDm, %BTE_CMD_GnDMm,
109 * %BTE_CMD_CnD or %BTE_CMD_DOCS command.
110 *
111 * Returns: the charset, a value from the BTE_CHARSET_* enum.
112 */
113 inline constexpr unsigned int charset() const noexcept
114 {
115 return BTE_CHARSET_GET_CHARSET(m_seq->charset)((m_seq->charset) & ((1U << 16) - 1U));
116 }
117
118 /* slot:
119 *
120 * This is the slot in a %BTE_CMD_GnDm, %BTE_CMD_GnDMm,
121 * or %BTE_CMD_CnD command.
122 *
123 * Returns: the slot, a value from the 0..3 for Gn*, or 0..1 for CnD
124 */
125 inline constexpr unsigned int slot() const noexcept
126 {
127 return BTE_CHARSET_GET_SLOT(m_seq->charset)((m_seq->charset) >> (16));
128 }
129
130 /* introducer:
131 *
132 * This is the character introducing the sequence, if any.
133 *
134 * Returns: the introducing character
135 */
136 inline constexpr uint32_t introducer() const noexcept
137 {
138 return m_seq->introducer;
139 }
140
141 /* terminator:
142 *
143 * This is the character terminating the sequence, or, for a
144 * %BTE_SEQ_GRAPHIC sequence, the graphic character.
145 *
146 * Returns: the terminating character
147 */
148 inline constexpr uint32_t terminator() const noexcept
149 {
150 return m_seq->terminator;
151 }
152
153
154 /* is_c1:
155 *
156 * Whether the sequence was introduced with a C0 or C1 control.
157 *
158 * Returns: the introducing character
159 */
160 inline constexpr bool is_c1() const noexcept
161 {
162 return (introducer() & 0x80) != 0;
163 }
164
165 /* intermediates:
166 *
167 * This is the pintro and intermediate characters in the sequence, if any.
168 *
169 * Returns: the intermediates
170 */
171 inline constexpr unsigned int intermediates() const noexcept
172 {
173 return m_seq->intermediates;
174 }
175
176 // FIXMEchpe: upgrade to C++17 and use the u32string_view version below, instead
177 /*
178 * string:
179 *
180 * This is the string argument of a DCS or OSC sequence.
181 *
182 * Returns: the string argument
183 */
184 inline std::u32string string() const noexcept
185 {
186 size_t len;
187 auto buf = bte_seq_string_get(&m_seq->arg_str, &len);
188 return std::u32string(reinterpret_cast<char32_t*>(buf), len);
189 }
190
191 #if 0
192 /*
193 * string:
194 *
195 * This is the string argument of a DCS or OSC sequence.
196 *
197 * Returns: the string argument
198 */
199 inline constexpr std::u32string_view string() const noexcept
200 {
201 size_t len = 0;
202 auto buf = bte_seq_string_get(&m_seq->arg_str, &len);
203 return std::u32string_view(buf, len);
204 }
205 #endif
206
207 /*
208 * string:
209 *
210 * This is the string argument of a DCS or OSC sequence.
211 *
212 * Returns: the string argument
213 */
214 std::string string_utf8() const noexcept;
215
216 inline char* string_param() const noexcept
217 {
218 size_t len = 0;
219 auto buf = bte_seq_string_get(&m_seq->arg_str, &len);
220 return ucs4_to_utf8(buf, len);
221 }
222
223 /* size:
224 *
225 * Returns: the number of parameters
226 */
227 inline constexpr unsigned int size() const noexcept
228 {
229 return m_seq->n_args;
230 }
231
232
233 /* size:
234 *
235 * Returns: the number of parameter blocks, counting runs of subparameters
236 * as only one parameter
237 */
238 inline constexpr unsigned int size_final() const noexcept
239 {
240 return m_seq->n_final_args;
241 }
242
243 /* capacity:
244 *
245 * Returns: the number of parameter blocks, counting runs of subparameters
246 * as only one parameter
247 */
248 inline constexpr unsigned int capacity() const noexcept
249 {
250 return G_N_ELEMENTS(m_seq->args)(sizeof (m_seq->args) / sizeof ((m_seq->args)[0]));
251 }
252
253 /* param:
254 * @idx:
255 * @default_v: the value to use for default parameters
256 *
257 * Returns: the value of the parameter at index @idx, or @default_v if
258 * the parameter at this index has default value, or the index
259 * is out of bounds
260 */
261 inline constexpr int param(unsigned int idx,
262 int default_v = -1) const noexcept
263 {
264 return __builtin_expect(idx < size(), 1) ? bte_seq_arg_value(m_seq->args[idx], default_v) : default_v;
265 }
266
267 /* param:
268 * @idx:
269 * @default_v: the value to use for default parameters
270 * @min_v: the minimum value
271 * @max_v: the maximum value
272 *
273 * Returns: the value of the parameter at index @idx, or @default_v if
274 * the parameter at this index has default value, or the index
275 * is out of bounds. The returned value is clamped to the
276 * range @min_v..@max_v (or returns min_v, if min_v > max_v).
277 */
278 inline constexpr int param(unsigned int idx,
279 int default_v,
280 int min_v,
281 int max_v) const noexcept
282 {
283 auto v = param(idx, default_v);
284 // not using std::clamp() since it's not guaranteed that min_v <= max_v
285 return std::max(std::min(v, max_v), min_v);
286 }
287
288 /* param_nonfinal:
289 * @idx:
290 *
291 * Returns: whether the parameter at @idx is nonfinal, i.e.
292 * there are more subparameters after it.
293 */
294 inline constexpr bool param_nonfinal(unsigned int idx) const noexcept
295 {
296 return __builtin_expect(idx < size(), 1) ? bte_seq_arg_nonfinal(m_seq->args[idx]) : false;
297 }
298
299 /* param_default:
300 * @idx:
301 *
302 * Returns: whether the parameter at @idx has default value
303 */
304 inline constexpr bool param_default(unsigned int idx) const noexcept
305 {
306 return __builtin_expect(idx < size(), 1) ? bte_seq_arg_default(m_seq->args[idx]) : true;
307 }
308
309 /* next:
310 * @idx:
311 *
312 * Returns: the index of the next parameter block
313 */
314 inline constexpr unsigned int next(unsigned int idx) const noexcept
315 {
316 /* Find the final parameter */
317 while (param_nonfinal(idx))
318 ++idx;
319 /* And return the index after that one */
320 return ++idx;
321 }
322
323 inline constexpr unsigned int cbegin() const noexcept
324 {
325 return 0;
326 }
327
328 inline constexpr unsigned int cend() const noexcept
329 {
330 return size();
331 }
332
333 /* collect:
334 *
335 * Collects some final parameters.
336 *
337 * Returns: %true if the sequence parameter list begins with
338 * a run of final parameters that were collected.
339 */
340 inline constexpr bool collect(unsigned int start_idx,
341 std::initializer_list<int*> params,
342 int default_v = -1) const noexcept
343 {
344 unsigned int idx = start_idx;
345 for (auto i : params) {
346 *i = param(idx, default_v);
347 idx = next(idx);
348 }
349
350 return (idx - start_idx) == params.size();
351 }
352
353 /* collect1:
354 * @idx:
355 * @default_v:
356 *
357 * Collects one final parameter.
358 *
359 * Returns: the parameter value, or @default_v if the parameter has
360 * default value or is not a final parameter
361 */
362 inline constexpr int collect1(unsigned int idx,
363 int default_v = -1) const noexcept
364 {
365 return __builtin_expect(idx < size(), 1) ? bte_seq_arg_value_final(m_seq->args[idx], default_v) : default_v;
366 }
367
368 /* collect1:
369 * @idx:
370 * @default_v:
371 * @min_v:
372 * @max_v
373 *
374 * Collects one final parameter.
375 *
376 * Returns: the parameter value clamped to the @min_v .. @max_v range (or @min_v,
377 * if min_v > max_v),
378 * or @default_v if the parameter has default value or is not a final parameter
379 */
380 inline constexpr int collect1(unsigned int idx,
381 int default_v,
382 int min_v,
383 int max_v) const noexcept
384 {
385 int v = __builtin_expect(idx < size(), 1) ? bte_seq_arg_value_final(m_seq->args[idx], default_v) : default_v;
386 // not using std::clamp() since it's not guaranteed that min_v <= max_v
387 return std::max(std::min(v, max_v), min_v);
388 }
389
390 /* collect_subparams:
391 *
392 * Collects some subparameters.
393 *
394 * Returns: %true if the sequence parameter list contains enough
395 * subparams at @start_idx
396 */
397 inline constexpr bool collect_subparams(unsigned int start_idx,
398 std::initializer_list<int*> params,
399 int default_v = -1) const noexcept
400 {
401 unsigned int idx = start_idx;
402 for (auto i : params) {
403 *i = param(idx++, default_v);
404 }
405
406 return idx <= next(start_idx);
407 }
408
409 inline explicit operator bool() const { return m_seq != nullptr; }
410
411 /* This is only used in the test suite */
412 bte_seq_t** seq_ptr() { return &m_seq; }
413
414private:
415 bte_seq_t* m_seq{nullptr};
416
417 char const* type_string() const;
418 char const* command_string() const;
419}; // class Sequence
420
421/* Helper classes to unify UTF-32 and UTF-8 versions of SequenceBuilder.
422 * ::put will only be called with C1 controls, so it's ok to simplify
423 * the UTF-8 version to simply prepend 0xc2.
424 */
425template<typename C>
426class DirectEncoder {
427public:
428 using string_type = std::basic_string<C>;
429 inline void put(string_type& s, C const c) const noexcept
430 {
431 s.push_back(c);
432 }
433}; // class DirectEncoder
434
435class UTF8Encoder {
436public:
437 using string_type = std::basic_string<char>;
438 inline void put(string_type& s, unsigned char const c) const noexcept
439 {
440 s.push_back(0xc2);
441 s.push_back(c);
442 }
443}; // class UTF8Encoder
444
445template<class S, class E = DirectEncoder<typename S::value_type>>
446class SequenceBuilder {
447public:
448 using string_type = S;
449 using encoder_type = E;
450
451private:
452 bte_seq_t m_seq;
453 string_type m_arg_str;
454 unsigned char m_intermediates[4];
455 unsigned char m_n_intermediates{0};
456 unsigned char m_param_intro{0};
457 encoder_type m_encoder;
458
459public:
460 SequenceBuilder(unsigned int type = BTE_SEQ_NONE)
461 {
462 memset(&m_seq, 0, sizeof(m_seq));
463 set_type(type);
464 }
465
466 SequenceBuilder(unsigned int type,
467 uint32_t f)
468 : SequenceBuilder(type)
469 {
470 set_final(f);
471 }
472
473 SequenceBuilder(unsigned int type,
474 string_type const& str)
475 : SequenceBuilder(type)
476 {
477 set_string(str);
478 }
479
480 SequenceBuilder(unsigned int type,
481 string_type&& str)
482 : SequenceBuilder(type)
483 {
484 set_string(str);
485 }
486
487 SequenceBuilder(SequenceBuilder const&) = delete;
488 SequenceBuilder(SequenceBuilder&&) = delete;
489 ~SequenceBuilder() = default;
490
491 SequenceBuilder& operator= (SequenceBuilder const&) = delete;
492 SequenceBuilder& operator= (SequenceBuilder&&) = delete;
493
494 inline constexpr unsigned int type() const noexcept { return m_seq.type; }
495
496 inline void set_type(unsigned int type) noexcept
497 {
498 m_seq.type = type;
499 }
500
501 inline void set_final(uint32_t t) noexcept
502 {
503 m_seq.terminator = t;
504 }
505
506 inline void append_intermediate(unsigned char i) noexcept
507 {
508 assert(unsigned(m_n_intermediates + 1) <= (sizeof(m_intermediates)/sizeof(m_intermediates[0])))(static_cast <bool> (unsigned(m_n_intermediates + 1) <=
(sizeof(m_intermediates)/sizeof(m_intermediates[0]))) ? void
(0) : __assert_fail ("unsigned(m_n_intermediates + 1) <= (sizeof(m_intermediates)/sizeof(m_intermediates[0]))"
, "../src/parser-glue.hh", 508, __extension__ __PRETTY_FUNCTION__
))
;
509
510 m_intermediates[m_n_intermediates++] = i;
511 }
512
513 inline void append_intermediates(std::initializer_list<unsigned char> l) noexcept
514 {
515 assert(m_n_intermediates + l.size() <= (sizeof(m_intermediates)/sizeof(m_intermediates[0])))(static_cast <bool> (m_n_intermediates + l.size() <=
(sizeof(m_intermediates)/sizeof(m_intermediates[0]))) ? void
(0) : __assert_fail ("m_n_intermediates + l.size() <= (sizeof(m_intermediates)/sizeof(m_intermediates[0]))"
, "../src/parser-glue.hh", 515, __extension__ __PRETTY_FUNCTION__
))
;
516
517 for (uint32_t i : l) {
518 m_intermediates[m_n_intermediates++] = i;
519 }
520 }
521
522 inline void set_param_intro(unsigned char p) noexcept
523 {
524 m_param_intro = p;
525 }
526
527 inline void append_param(int p) noexcept
528 {
529 assert(m_seq.n_args + 1 <= (sizeof(m_seq.args) / sizeof(m_seq.args[0])))(static_cast <bool> (m_seq.n_args + 1 <= (sizeof(m_seq
.args) / sizeof(m_seq.args[0]))) ? void (0) : __assert_fail (
"m_seq.n_args + 1 <= (sizeof(m_seq.args) / sizeof(m_seq.args[0]))"
, "../src/parser-glue.hh", 529, __extension__ __PRETTY_FUNCTION__
))
;
530 m_seq.args[m_seq.n_args++] = bte_seq_arg_init(std::min(p, 0xffff));
531 }
532
533 inline void append_params(std::initializer_list<int> params) noexcept
534 {
535 assert(m_seq.n_args + params.size() <= (sizeof(m_seq.args) / sizeof(m_seq.args[0])))(static_cast <bool> (m_seq.n_args + params.size() <=
(sizeof(m_seq.args) / sizeof(m_seq.args[0]))) ? void (0) : __assert_fail
("m_seq.n_args + params.size() <= (sizeof(m_seq.args) / sizeof(m_seq.args[0]))"
, "../src/parser-glue.hh", 535, __extension__ __PRETTY_FUNCTION__
))
;
536 for (int p : params)
537 m_seq.args[m_seq.n_args++] = bte_seq_arg_init(std::min(p, 0xffff));
538 }
539
540 inline void append_subparams(std::initializer_list<int> subparams) noexcept
541 {
542 assert(m_seq.n_args + subparams.size() <= (sizeof(m_seq.args) / sizeof(m_seq.args[0])))(static_cast <bool> (m_seq.n_args + subparams.size() <=
(sizeof(m_seq.args) / sizeof(m_seq.args[0]))) ? void (0) : __assert_fail
("m_seq.n_args + subparams.size() <= (sizeof(m_seq.args) / sizeof(m_seq.args[0]))"
, "../src/parser-glue.hh", 542, __extension__ __PRETTY_FUNCTION__
))
;
543 for (int p : subparams) {
544 int* arg = &m_seq.args[m_seq.n_args++];
545 *arg = bte_seq_arg_init(std::min(p, 0xffff));
546 bte_seq_arg_finish(arg, false);
547 }
548 bte_seq_arg_refinish(&m_seq.args[m_seq.n_args - 1], true);
549 }
550
551 inline void set_string(string_type const& str) noexcept
552 {
553 m_arg_str = str;
554 }
555
556 inline void set_string(string_type&& str) noexcept
557 {
558 m_arg_str = str;
559 }
560
561 enum class Introducer {
562 NONE,
563 DEFAULT,
564 C0,
565 C1
566 };
567
568 enum class ST {
569 NONE,
570 DEFAULT,
571 C0,
572 C1,
573 BEL
574 };
575
576
577private:
578 void append_introducer_(string_type& s,
579 bool c1 = true) const noexcept
580 {
581 /* Introducer */
582 if (c1) {
583 switch (m_seq.type) {
584 case BTE_SEQ_ESCAPE: m_encoder.put(s, 0x1b); break; // ESC
585 case BTE_SEQ_CSI: m_encoder.put(s, 0x9b); break; // CSI
586 case BTE_SEQ_DCS: m_encoder.put(s, 0x90); break; // DCS
587 case BTE_SEQ_OSC: m_encoder.put(s, 0x9d); break; // OSC
588 case BTE_SEQ_APC: m_encoder.put(s, 0x9f); break; // APC
589 case BTE_SEQ_PM: m_encoder.put(s, 0x9e); break; // PM
590 case BTE_SEQ_SOS: m_encoder.put(s, 0x98); break; // SOS
591 case BTE_SEQ_SCI: m_encoder.put(s, 0x9a); break; // SCI
592 default: return;
593 }
594 } else {
595 s.push_back(0x1B); // ESC
596 switch (m_seq.type) {
597 case BTE_SEQ_ESCAPE: break; // nothing more
598 case BTE_SEQ_CSI: s.push_back(0x5b); break; // [
599 case BTE_SEQ_DCS: s.push_back(0x50); break; // P
600 case BTE_SEQ_OSC: s.push_back(0x5d); break; // ]
601 case BTE_SEQ_APC: s.push_back(0x5f); break; // _
602 case BTE_SEQ_PM: s.push_back(0x5e); break; // ^
603 case BTE_SEQ_SOS: s.push_back(0x58); break; // X
604 case BTE_SEQ_SCI: s.push_back(0x5a); break; // Z
605 default: return;
606 }
607 }
608 }
609
610 void append_introducer(string_type& s,
611 bool c1 = true,
612 Introducer introducer = Introducer::DEFAULT) const noexcept
613 {
614 switch (introducer) {
615 case Introducer::NONE:
616 break;
617 case Introducer::DEFAULT:
618 append_introducer_(s, c1);
619 break;
620 case Introducer::C0:
621 append_introducer_(s, false);
622 break;
623 case Introducer::C1:
624 append_introducer_(s, true);
625 }
626 }
627
628 void append_params(string_type& s) const noexcept
629 {
630 /* Parameters */
631 switch (m_seq.type) {
632 case BTE_SEQ_CSI:
633 case BTE_SEQ_DCS: {
634
635 if (m_param_intro != 0)
636 s.push_back(m_param_intro);
637 auto n_args = m_seq.n_args;
638 for (unsigned int n = 0; n < n_args; n++) {
639 auto arg = bte_seq_arg_value(m_seq.args[n]);
640 if (n > 0) {
641 s.push_back(";:"[bte_seq_arg_nonfinal(m_seq.args[n])]);
642 }
643 if (arg >= 0) {
644 char buf[16];
645 int l = g_snprintf(buf, sizeof(buf), "%d", arg);
646 for (int j = 0; j < l; j++)
647 s.push_back(buf[j]);
648 }
649 }
650 break;
651 }
652 default:
653 break;
654 }
655 }
656
657 void append_intermediates_and_final(string_type& s) const noexcept
658 {
659 /* Intermediates and Final */
660 switch (m_seq.type) {
661 case BTE_SEQ_ESCAPE:
662 case BTE_SEQ_CSI:
663 case BTE_SEQ_DCS:
664 for (unsigned char n = 0; n < m_n_intermediates; n++)
665 s.push_back(m_intermediates[n]);
666 [[fallthrough]];
667 case BTE_SEQ_SCI:
668 if (m_seq.terminator != 0)
669 s.push_back(m_seq.terminator);
670 break;
671 default:
672 break;
673 }
674 }
675
676 void append_arg_string(string_type& s,
677 bool c1 = false,
678 ssize_t max_arg_str_len = -1,
679 ST st = ST::DEFAULT) const noexcept
680 {
681 /* String and ST */
682 switch (m_seq.type) {
683 case BTE_SEQ_DCS:
684 case BTE_SEQ_OSC:
685
686 if (max_arg_str_len < 0)
687 s.append(m_arg_str, 0, max_arg_str_len);
688 else
689 s.append(m_arg_str);
690
691 switch (st) {
692 case ST::NONE:
693 // omit ST
694 break;
695 case ST::DEFAULT:
696 if (c1) {
697 m_encoder.put(s, 0x9c); // ST
698 } else {
699 s.push_back(0x1b); // ESC
700 s.push_back(0x5c); // BACKSLASH
701 }
702 break;
703 case ST::C0:
704 s.push_back(0x1b); // ESC
705 s.push_back(0x5c); // BACKSLASH
706 break;
707 case ST::C1:
708 m_encoder.put(s, 0x9c); // ST
709 break;
710 case ST::BEL:
711 s.push_back(0x7); // BEL
712 break;
713 default:
714 break;
715 }
716 }
717 }
718
719public:
720 void to_string(string_type& s,
721 bool c1 = false,
722 ssize_t max_arg_str_len = -1,
723 Introducer introducer = Introducer::DEFAULT,
724 ST st = ST::DEFAULT) const noexcept
725 {
726 append_introducer(s, c1, introducer);
727 append_params(s);
728 append_intermediates_and_final(s);
729 append_arg_string(s, c1, max_arg_str_len, st);
730 }
731
732 /* The following are only used in the test suite */
733 void reset_params() noexcept
734 {
735 m_seq.n_args = 0;
736 }
737
738 void assert_equal(Sequence const& seq) const noexcept
739 {
740 g_assert_cmpuint(seq.type(), ==, m_seq.type)do { guint64 __n1 = (seq.type()), __n2 = (m_seq.type); if (__n1
== __n2) ; else g_assertion_message_cmpnum (((gchar*) 0), "../src/parser-glue.hh"
, 740, ((const char*) (__PRETTY_FUNCTION__)), "seq.type()" " "
"==" " " "m_seq.type", (long double) __n1, "==", (long double
) __n2, 'i'); } while (0)
;
741 g_assert_cmphex(seq.terminator(), ==, m_seq.terminator)do { guint64 __n1 = (seq.terminator()), __n2 = (m_seq.terminator
); if (__n1 == __n2) ; else g_assertion_message_cmpnum (((gchar
*) 0), "../src/parser-glue.hh", 741, ((const char*) (__PRETTY_FUNCTION__
)), "seq.terminator()" " " "==" " " "m_seq.terminator", (long
double) __n1, "==", (long double) __n2, 'x'); } while (0)
;
742 }
743
744 void assert_equal_full(Sequence const& seq) const noexcept
745 {
746 assert_equal(seq);
747
748 auto type = seq.type();
749 if (type
13.1
'type' is equal to BTE_SEQ_CSI
13.1
'type' is equal to BTE_SEQ_CSI
== BTE_SEQ_CSI ||
750 type == BTE_SEQ_DCS) {
751 /* We may get one arg less back, if it's at default */
752 if (m_seq.n_args != seq.size()) {
14
Assuming the condition is true
15
Taking true branch
753 g_assert_cmpuint(m_seq.n_args, ==, seq.size() + 1)do { guint64 __n1 = (m_seq.n_args), __n2 = (seq.size() + 1); if
(__n1 == __n2) ; else g_assertion_message_cmpnum (((gchar*) 0
), "../src/parser-glue.hh", 753, ((const char*) (__PRETTY_FUNCTION__
)), "m_seq.n_args" " " "==" " " "seq.size() + 1", (long double
) __n1, "==", (long double) __n2, 'i'); } while (0)
;
16
Assuming '__n1' is equal to '__n2'
17
Taking true branch
18
Loop condition is false. Exiting loop
754 g_assert_true(bte_seq_arg_default(m_seq.args[m_seq.n_args - 1]))do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if (bte_seq_arg_default(m_seq.args[m_seq.n_args - 1])) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1)) ; else
g_assertion_message (((gchar*) 0), "../src/parser-glue.hh", 754
, ((const char*) (__PRETTY_FUNCTION__)), "'" "bte_seq_arg_default(m_seq.args[m_seq.n_args - 1])"
"' should be TRUE"); } while (0)
;
19
Out of bound memory access (access exceeds upper limit of memory block)
755 }
756 for (unsigned int n = 0; n < seq.size(); n++)
757 g_assert_cmpint(bte_seq_arg_value(m_seq.args[n]), ==, seq.param(n))do { gint64 __n1 = (bte_seq_arg_value(m_seq.args[n])), __n2 =
(seq.param(n)); if (__n1 == __n2) ; else g_assertion_message_cmpnum
(((gchar*) 0), "../src/parser-glue.hh", 757, ((const char*) (
__PRETTY_FUNCTION__)), "bte_seq_arg_value(m_seq.args[n])" " "
"==" " " "seq.param(n)", (long double) __n1, "==", (long double
) __n2, 'i'); } while (0)
;
758 }
759 }
760}; // class SequenceBuilder
761
762using u8SequenceBuilder = SequenceBuilder<std::string, UTF8Encoder>;
763using u32SequenceBuilder = SequenceBuilder<std::u32string>;
764
765class ReplyBuilder : public u8SequenceBuilder {
766public:
767 ReplyBuilder(unsigned int reply,
768 std::initializer_list<int> params)
769 {
770 switch (reply) {
771#define _BTE_REPLY_PARAMS(params) append_params(params);
772#define _BTE_REPLY_STRING(str) set_string(str);
773#define _BTE_REPLY(cmd,type,final,pintro,intermediate,code) \
774 case BTE_REPLY_##cmd: \
775 set_type(BTE_SEQ_##type); \
776 set_final(final); \
777 set_param_intro(BTE_SEQ_PARAMETER_CHAR_##pintro); \
778 if (BTE_SEQ_INTERMEDIATE_CHAR_##intermediate != BTE_SEQ_INTERMEDIATE_CHAR_NONE) \
779 append_intermediate(BTE_SEQ_INTERMEDIATE_CHAR_##intermediate); \
780 code \
781 break;
782#include "parser-reply.hh"
783#undef _BTE_REPLY
784#undef _BTE_REPLY_PARAMS
785#undef _BTE_REPLY_STRING
786 default:
787 assert(false)(static_cast <bool> (false) ? void (0) : __assert_fail (
"false", "../src/parser-glue.hh", 787, __extension__ __PRETTY_FUNCTION__
))
;
788 break;
789 }
790 append_params(params);
791 }
792
793}; // class ReplyBuilder
794
795class StringTokeniser {
796public:
797 using string_type = std::string;
798 using char_type = std::string::value_type;
799
800private:
801 string_type const& m_string;
802 char_type m_separator{';'};
803
804public:
805 StringTokeniser(string_type& s,
806 char_type separator = ';')
807 : m_string{s},
808 m_separator{separator}
809 {
810 }
811
812 StringTokeniser(string_type&& s,
813 char_type separator = ';')
814 : m_string{s},
815 m_separator{separator}
816 {
817 }
818
819 StringTokeniser(StringTokeniser const&) = delete;
820 StringTokeniser(StringTokeniser&&) = delete;
821 ~StringTokeniser() = default;
822
823 StringTokeniser& operator=(StringTokeniser const&) = delete;
824 StringTokeniser& operator=(StringTokeniser&&) = delete;
825
826 /*
827 * const_iterator:
828 *
829 * InputIterator for string tokens.
830 */
831 class const_iterator {
832 public:
833 using difference_type = ptrdiff_t;
834 using value_type = string_type;
835 using pointer = string_type;
836 using reference = string_type;
837 using iterator_category = std::input_iterator_tag;
838 using size_type = string_type::size_type;
839
840 private:
841 string_type const* m_string;
842 char_type m_separator{';'};
843 string_type::size_type m_position;
844 string_type::size_type m_next_separator;
845
846 public:
847 const_iterator(string_type const* str,
848 char_type separator,
849 size_type position)
850 : m_string{str},
851 m_separator{separator},
852 m_position{position},
853 m_next_separator{m_string->find(m_separator, m_position)}
854 {
855 }
856
857 const_iterator(string_type const* str,
858 char_type separator)
859 : m_string{str},
860 m_separator{separator},
861 m_position{string_type::npos},
862 m_next_separator{string_type::npos}
863 {
864 }
865
866 const_iterator(const_iterator const&) = default;
867 const_iterator(const_iterator&& o)
868 : m_string{o.m_string},
869 m_separator{o.m_separator},
870 m_position{o.m_position},
871 m_next_separator{o.m_next_separator}
872 {
873 }
874
875 ~const_iterator() = default;
876
877 const_iterator& operator=(const_iterator const& o)
878 {
879 m_string = o.m_string;
880 m_separator = o.m_separator;
881 m_position = o.m_position;
882 m_next_separator = o.m_next_separator;
883 return *this;
884 }
885
886 const_iterator& operator=(const_iterator&& o)
887 {
888 m_string = std::move(o.m_string);
889 m_separator = o.m_separator;
890 m_position = o.m_position;
891 m_next_separator = o.m_next_separator;
892 return *this;
893 }
894
895 inline bool operator==(const_iterator const& o) const noexcept
896 {
897 return m_position == o.m_position;
898 }
899
900 inline bool operator!=(const_iterator const& o) const noexcept
901 {
902 return m_position != o.m_position;
903 }
904
905 inline const_iterator& operator++() noexcept
906 {
907 if (m_next_separator != string_type::npos) {
908 m_position = ++m_next_separator;
909 m_next_separator = m_string->find(m_separator, m_position);
910 } else
911 m_position = string_type::npos;
912
913 return *this;
914 }
915
916 /*
917 * number:
918 *
919 * Returns the value of the iterator as a number, or -1
920 * if the string could not be parsed as a number, or
921 * the parsed values exceeds the uint16_t range.
922 *
923 * Returns: true if a number was parsed
924 */
925 bool number(int& v) const noexcept
926 {
927 auto const s = size();
928 if (s == 0) {
929 v = -1;
930 return true;
931 }
932
933 v = 0;
934 size_type i;
935 for (i = 0; i < s; ++i) {
936 char_type c = (*m_string)[m_position + i];
937 if (c < '0' || c > '9')
938 return false;
939
940 v = v * 10 + (c - '0');
941 if (v > 0xffff)
942 return false;
943 }
944
945 /* All consumed? */
946 return i == s;
947 }
948
949 inline size_type size() const noexcept
950 {
951 if (m_next_separator != string_type::npos)
952 return m_next_separator - m_position;
953 else
954 return m_string->size() - m_position;
955 }
956
957 inline size_type size_remaining() const noexcept
958 {
959 return m_string->size() - m_position;
960 }
961
962 inline string_type operator*() const noexcept
963 {
964 return m_string->substr(m_position, size());
965 }
966
967 /*
968 * string_remaining:
969 *
970 * Returns the whole string left, including possibly more separators.
971 */
972 inline string_type string_remaining() const noexcept
973 {
974 return m_string->substr(m_position);
975 }
976
977 inline void append(string_type& str) const noexcept
978 {
979 str.append(m_string->substr(m_position, size()));
980 }
981
982 inline void append_remaining(string_type& str) const noexcept
983 {
984 str.append(m_string->substr(m_position));
985 }
986
987 }; // class const_iterator
988
989 inline const_iterator cbegin(char_type c = ';') const noexcept
990 {
991 return const_iterator(&m_string, m_separator, 0);
992 }
993
994 inline const_iterator cend() const noexcept
995 {
996 return const_iterator(&m_string, m_separator);
997 }
998
999 inline const_iterator begin(char_type c = ';') const noexcept
1000 {
1001 return cbegin();
1002 }
1003
1004 inline const_iterator end() const noexcept
1005 {
1006 return cend();
1007 }
1008
1009}; // class StringTokeniser
1010
1011} // namespace parser
1012
1013} // namespace bte