chiark / gitweb /
e22614d06dd2e521081297c78826f25d7b9e0a31
[elogind.git] / src / libsystemd-terminal / test-term-parser.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2 /***
3   This file is part of systemd.
4
5   Copyright (C) 2014 David Herrmann <dh.herrmann@gmail.com>
6
7   systemd is free software; you can redistribute it and/or modify it
8   under the terms of the GNU Lesser General Public License as published by
9   the Free Software Foundation; either version 2.1 of the License, or
10   (at your option) any later version.
11
12   systemd is distributed in the hope that it will be useful, but
13   WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   Lesser General Public License for more details.
16
17   You should have received a copy of the GNU Lesser General Public License
18   along with systemd; If not, see <http://www.gnu.org/licenses/>.
19 ***/
20
21 /*
22  * Terminal Parser Tests
23  */
24
25 #include <assert.h>
26 #include <errno.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include "macro.h"
31 #include "term-internal.h"
32 #include "util.h"
33 #include "utf8.h"
34
35 static void test_term_utf8_invalid(void) {
36         term_utf8 p = { };
37         uint32_t *res;
38         size_t len;
39
40         len = term_utf8_decode(NULL, NULL, 0);
41         assert_se(!len);
42
43         len = term_utf8_decode(&p, NULL, 0);
44         assert_se(len == 1);
45
46         res = NULL;
47         len = term_utf8_decode(NULL, &res, 0);
48         assert_se(!len);
49         assert_se(res != NULL);
50         assert_se(!*res);
51
52         len = term_utf8_decode(&p, &res, 0);
53         assert_se(len == 1);
54         assert_se(res != NULL);
55         assert_se(!*res);
56
57         len = term_utf8_decode(&p, &res, 0xCf);
58         assert_se(len == 0);
59         assert_se(res != NULL);
60         assert_se(!*res);
61
62         len = term_utf8_decode(&p, &res, 0);
63         assert_se(len == 2);
64         assert_se(res != NULL);
65         assert_se(res[0] == 0xCf && res[1] == 0);
66 }
67
68 static void test_term_utf8_range(void) {
69         term_utf8 p = { };
70         uint32_t *res;
71         char u8[4];
72         uint32_t i, j;
73         size_t ulen, len;
74
75         /* Convert all ucs-4 chars to utf-8 and back */
76
77         for (i = 0; i < 0x10FFFF; ++i) {
78                 ulen = utf8_encode_unichar(u8, i);
79                 if (!ulen)
80                         continue;
81
82                 for (j = 0; j < ulen; ++j) {
83                         len = term_utf8_decode(&p, &res, u8[j]);
84                         if (len < 1) {
85                                 assert_se(j + 1 != ulen);
86                                 continue;
87                         }
88
89                         assert_se(j + 1 == ulen);
90                         assert_se(len == 1 && *res == i);
91                         assert_se(i <= 127 || ulen >= 2);
92                 }
93         }
94 }
95
96 static void test_term_utf8_mix(void) {
97         static const char source[] = {
98                 0x00,                           /* normal 0 */
99                 0xC0, 0x80,                     /* overlong 0 */
100                 0xC0, 0x81,                     /* overlong 1 */
101                 0xE0, 0x80, 0x81,               /* overlong 1 */
102                 0xF0, 0x80, 0x80, 0x81,         /* overlong 1 */
103                 0xC0, 0x00,                     /* invalid continuation */
104                 0xC0, 0xC0, 0x81,               /* invalid continuation with a following overlong 1 */
105                 0xF8, 0x80, 0x80, 0x80, 0x81,   /* overlong 1 with 5 bytes */
106                 0xE0, 0x80, 0xC0, 0x81,         /* invalid 3-byte followed by valid 2-byte */
107                 0xF0, 0x80, 0x80, 0xC0, 0x81,   /* invalid 4-byte followed by valid 2-byte */
108         };
109         static const uint32_t result[] = {
110                 0x0000,
111                 0x0000,
112                 0x0001,
113                 0x0001,
114                 0x0001,
115                 0x00C0, 0x0000,
116                 0x00C0, 0x0001,
117                 0x00F8, 0x0080, 0x0080, 0x0080, 0x0081,
118                 0x00E0, 0x0080, 0x0001,
119                 0x00F0, 0x0080, 0x0080, 0x0001,
120         };
121         term_utf8 p = { };
122         uint32_t *res;
123         unsigned int i, j;
124         size_t len;
125
126         for (i = 0, j = 0; i < sizeof(source); ++i) {
127                 len = term_utf8_decode(&p, &res, source[i]);
128                 if (len < 1)
129                         continue;
130
131                 assert_se(j + len <= ELEMENTSOF(result));
132                 assert_se(!memcmp(res, &result[j], sizeof(uint32_t) * len));
133                 j += len;
134         }
135
136         assert_se(j == ELEMENTSOF(result));
137 }
138
139 int main(int argc, char *argv[]) {
140         test_term_utf8_invalid();
141         test_term_utf8_range();
142         test_term_utf8_mix();
143
144         return 0;
145 }