chiark / gitweb /
terminal/screen: add color converter
[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
34 static void test_term_utf8_invalid(void) {
35         term_utf8 p = { };
36         uint32_t *res;
37         size_t len;
38
39         len = term_utf8_decode(NULL, NULL, 0);
40         assert_se(!len);
41
42         len = term_utf8_decode(&p, NULL, 0);
43         assert_se(len == 1);
44
45         res = NULL;
46         len = term_utf8_decode(NULL, &res, 0);
47         assert_se(!len);
48         assert_se(res != NULL);
49         assert_se(!*res);
50
51         len = term_utf8_decode(&p, &res, 0);
52         assert_se(len == 1);
53         assert_se(res != NULL);
54         assert_se(!*res);
55
56         len = term_utf8_decode(&p, &res, 0xCf);
57         assert_se(len == 0);
58         assert_se(res != NULL);
59         assert_se(!*res);
60
61         len = term_utf8_decode(&p, &res, 0);
62         assert_se(len == 2);
63         assert_se(res != NULL);
64         assert_se(res[0] == 0xCf && res[1] == 0);
65 }
66
67 static void test_term_utf8_range(void) {
68         term_utf8 p = { };
69         uint32_t *res;
70         char u8[4];
71         uint32_t i, j;
72         size_t ulen, len;
73
74         /* Convert all ucs-4 chars to utf-8 and back */
75
76         for (i = 0; i < 0x10FFFF; ++i) {
77                 ulen = term_utf8_encode(u8, i);
78                 if (!ulen)
79                         continue;
80
81                 for (j = 0; j < ulen; ++j) {
82                         len = term_utf8_decode(&p, &res, u8[j]);
83                         if (len < 1) {
84                                 assert_se(j + 1 != ulen);
85                                 continue;
86                         }
87
88                         assert_se(j + 1 == ulen);
89                         assert_se(len == 1 && *res == i);
90                         assert_se(i <= 127 || ulen >= 2);
91                 }
92         }
93 }
94
95 static void test_term_utf8_mix(void) {
96         static const char source[] = {
97                 0x00,                           /* normal 0 */
98                 0xC0, 0x80,                     /* overlong 0 */
99                 0xC0, 0x81,                     /* overlong 1 */
100                 0xE0, 0x80, 0x81,               /* overlong 1 */
101                 0xF0, 0x80, 0x80, 0x81,         /* overlong 1 */
102                 0xC0, 0x00,                     /* invalid continuation */
103                 0xC0, 0xC0, 0x81,               /* invalid continuation with a following overlong 1 */
104                 0xF8, 0x80, 0x80, 0x80, 0x81,   /* overlong 1 with 5 bytes */
105                 0xE0, 0x80, 0xC0, 0x81,         /* invalid 3-byte followed by valid 2-byte */
106                 0xF0, 0x80, 0x80, 0xC0, 0x81,   /* invalid 4-byte followed by valid 2-byte */
107         };
108         static const uint32_t result[] = {
109                 0x0000,
110                 0x0000,
111                 0x0001,
112                 0x0001,
113                 0x0001,
114                 0x00C0, 0x0000,
115                 0x00C0, 0x0001,
116                 0x00F8, 0x0080, 0x0080, 0x0080, 0x0081,
117                 0x00E0, 0x0080, 0x0001,
118                 0x00F0, 0x0080, 0x0080, 0x0001,
119         };
120         term_utf8 p = { };
121         uint32_t *res;
122         unsigned int i, j;
123         size_t len;
124
125         for (i = 0, j = 0; i < sizeof(source); ++i) {
126                 len = term_utf8_decode(&p, &res, source[i]);
127                 if (len < 1)
128                         continue;
129
130                 assert_se(j + len <= ELEMENTSOF(result));
131                 assert_se(!memcmp(res, &result[j], sizeof(uint32_t) * len));
132                 j += len;
133         }
134
135         assert_se(j == ELEMENTSOF(result));
136 }
137
138 int main(int argc, char *argv[]) {
139         test_term_utf8_invalid();
140         test_term_utf8_range();
141         test_term_utf8_mix();
142
143         return 0;
144 }