-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathutf32.c
More file actions
173 lines (152 loc) · 3.84 KB
/
Copy pathutf32.c
File metadata and controls
173 lines (152 loc) · 3.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/* -*- Mode: C -*- */
/* (c) Henrik Theiling, LICENSE: BSD-3-Clause */
#include <stddef.h>
#include <assert.h>
#include <va_print/char.h>
#include <va_print/utf32.h>
#include <va_print/core.h>
#include <va_print/impl.h>
/* ********************************************************************** */
/* extern objects */
va_read_iter_vtab_t const va_char32_p_read_vtab_utf32 = {
"char32_t*",
va_char32_p_take_utf32,
va_char32_p_end,
NULL,
false,
false,
'U',
{0}
};
va_read_iter_vtab_t const va_span32_p_read_vtab_utf32 = {
"char32_t*",
va_span32_p_take_utf32,
va_char32_p_end,
NULL,
true,
false,
'U',
{0}
};
/* ********************************************************************** */
/* extern functions */
extern unsigned va_char32_p_take_utf32(
va_read_iter_t *iter,
void const *end)
{
assert(iter->cur != NULL);
if (iter->cur == end) {
return VA_U_EOT;
}
char32_t const *s = iter->cur;
unsigned c0 = *s;
if (c0 == 0) {
/* possible end of string */
if (!iter->vtab->has_size) {
return VA_U_EOT;
}
}
iter->cur = (s + 1);
if (va_u_valid(c0)) {
return c0;
}
if (c0 > VA_U_MAXMAX) {
/* There is no way we can reproduce the same value, unfortunately,
* because there's not enough space in the internal representation
* of characters. */
return VA_U_REPLACEMENT;
}
return c0 | VA_U_ENC_UTF32;
}
extern void va_put_utf32(
va_stream_t *s,
unsigned c,
void (*put)(va_stream_t *, char32_t))
{
/* decoder errors */
if ((c & VA_U_ENC) != 0) {
if ((c & VA_U_ENC) == VA_U_ENC_UTF32) {
/* pass-through erroneous word */
put(s, c & VA_U_DATA);
return;
}
c = VA_U_REPLACEMENT;
}
/* encoding errors */
if (!va_u_valid(c)) {
va_stream_set_error(s, VA_E_ENCODE);
c = VA_U_REPLACEMENT;
}
put(s, c);
}
extern va_stream_t *va_xprintf_char32_p_utf32(
va_stream_t *s,
char32_t const *x)
{
va_read_iter_t iter = VA_READ_ITER(&va_char32_p_read_vtab_utf32, x);
return va_xprintf_iter(s, &iter);
}
extern va_stream_t *va_xprintf_char32_const_pp_utf32(
va_stream_t *s,
char32_t const **x)
{
va_read_iter_t iter = VA_READ_ITER(&va_char32_p_read_vtab_utf32, *x);
(void)va_xprintf_iter(s, &iter);
*x = iter.cur;
return s;
}
extern va_stream_t *va_xprintf_char32_pp_utf32(
va_stream_t *s,
char32_t **x)
{
return va_xprintf_char32_const_pp_utf32(s, (char32_t const **)x);
}
extern va_stream_t *va_xprintf_last_char32_p_utf32(
va_stream_t *s,
char32_t const *x)
{
s->opt |= VA_OPT_LAST;
return va_xprintf_char32_p_utf32(s,x);
}
extern va_stream_t *va_xprintf_last_char32_const_pp_utf32(
va_stream_t *s,
char32_t const **x)
{
s->opt |= VA_OPT_LAST;
return va_xprintf_char32_const_pp_utf32(s,x);
}
extern va_stream_t *va_xprintf_last_char32_pp_utf32(
va_stream_t *s,
char32_t **x)
{
s->opt |= VA_OPT_LAST;
return va_xprintf_char32_pp_utf32(s,x);
}
extern unsigned va_span32_p_take_utf32(
va_read_iter_t *iter_super,
void const *end)
{
assert(iter_super->cur != NULL);
va_read_iter_end_t *iter= va_boxof(iter_super, *iter, super);
if (iter_super->cur == iter->end) {
return VA_U_EOT;
}
return va_char32_p_take_utf32(iter_super, end);
}
extern va_stream_t *va_xprintf_span32_p_utf32(
va_stream_t *s,
va_span32_t const *x)
{
va_read_iter_end_t iter = {
.super = VA_READ_ITER(&va_span32_p_read_vtab_utf32, x->data),
.end = x->data + x->size
};
return va_xprintf_iter(s, &iter.super);
}
extern va_stream_t *va_xprintf_last_span32_p_utf32(
va_stream_t *s,
va_span32_t const *x)
{
s->opt |= VA_OPT_LAST;
return va_xprintf_span32_p_utf32(s,x);
}