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
174
175
176
177
178
179
180
181
182
183
184
|
.TH MPU_UTF8ING 3 "Август 2026" "libmpuio" "Руководство программиста LIBMPUIO"
.SH ИМЯ
mpu_utf8next, mpu_utf8prev, mpu_utf8last, mpu_utf8get, mpu_utf8len,
mpu_utf8nlen, mpu_utf8bytes, mpu_utf8nbytes, mpu_utf8valid, mpu_utf8_offset2index, mpu_utf8_index2offset, mpu_utf8cmp,
mpu_utf8ncmp, mpu_utf8cpy, mpu_utf8cat, mpu_utf8ncpy, mpu_utf8ncat,
mpu_utf8pcpy, mpu_utf8pncpy, mpu_utf8chr, mpu_utf8chrnul, mpu_utf8rchr,
mpu_utf8spn, mpu_utf8cspn, mpu_utf8pbrk, mpu_utf8str, mpu_utf8rstr,
mpu_utf8tok, mpu_utf8tok_r, mpu_utf8dup, mpu_utf8ndup
\- операции со строками и символами UTF-8
.SH ОБЗОР
.nf
#include <libmpuio.h>
const __mpu_char8_t *mpu_utf8next( const __mpu_char8_t *p );
const __mpu_char8_t *mpu_utf8prev( const __mpu_char8_t *start, const __mpu_char8_t *p );
const __mpu_char8_t *mpu_utf8last( const __mpu_char8_t *s );
const __mpu_char8_t *mpu_utf8get( const __mpu_char8_t *p, __mpu_char32_t *value );
__mpu_size_t mpu_utf8len( const __mpu_char8_t *s );
__mpu_size_t mpu_utf8nlen( const __mpu_char8_t *s, __mpu_size_t maxlen );
__mpu_size_t mpu_utf8bytes( const __mpu_char8_t *s );
__mpu_size_t mpu_utf8nbytes( const __mpu_char8_t *s, __mpu_size_t n );
int mpu_utf8valid( const __mpu_char8_t *s );
__mpu_size_t mpu_utf8_offset2index( const __mpu_char8_t *s, __mpu_size_t offset );
__mpu_size_t mpu_utf8_index2offset( const __mpu_char8_t *s, __mpu_size_t index );
int mpu_utf8cmp( const __mpu_char8_t *s1, const __mpu_char8_t *s2 );
int mpu_utf8ncmp( const __mpu_char8_t *s1, const __mpu_char8_t *s2, __mpu_size_t n );
__mpu_char8_t *mpu_utf8cpy( __mpu_char8_t *dest, const __mpu_char8_t *src );
__mpu_char8_t *mpu_utf8cat( __mpu_char8_t *dest, const __mpu_char8_t *src );
__mpu_char8_t *mpu_utf8ncpy( __mpu_char8_t *dest, const __mpu_char8_t *src, __mpu_size_t n );
__mpu_char8_t *mpu_utf8ncat( __mpu_char8_t *dest, const __mpu_char8_t *src, __mpu_size_t n );
__mpu_char8_t *mpu_utf8pcpy( __mpu_char8_t *dest, const __mpu_char8_t *src );
__mpu_char8_t *mpu_utf8pncpy( __mpu_char8_t *dest, const __mpu_char8_t *src, __mpu_size_t n );
__mpu_char8_t *mpu_utf8chr( const __mpu_char8_t *s, __mpu_char32_t c );
__mpu_char8_t *mpu_utf8chrnul( const __mpu_char8_t *s, __mpu_char32_t c );
__mpu_char8_t *mpu_utf8rchr( const __mpu_char8_t *s, __mpu_char32_t c );
__mpu_size_t mpu_utf8spn( const __mpu_char8_t *s, const __mpu_char8_t *accept );
__mpu_size_t mpu_utf8cspn( const __mpu_char8_t *s, const __mpu_char8_t *reject );
__mpu_char8_t *mpu_utf8pbrk( const __mpu_char8_t *s, const __mpu_char8_t *accept );
__mpu_char8_t *mpu_utf8str( const __mpu_char8_t *haystack, const __mpu_char8_t *needle );
__mpu_char8_t *mpu_utf8rstr( const __mpu_char8_t *haystack, const __mpu_char8_t *needle );
__mpu_char8_t *mpu_utf8tok( __mpu_char8_t *s, const __mpu_char8_t *delim );
__mpu_char8_t *mpu_utf8tok_r( __mpu_char8_t *s, const __mpu_char8_t *delim, __mpu_char8_t **saveptr );
__mpu_char8_t *mpu_utf8dup( const __mpu_char8_t *s );
__mpu_char8_t *mpu_utf8ndup( const __mpu_char8_t *s, __mpu_size_t n );
.fi
.SH ОПИСАНИЕ
Семейство
.B mpu_utf8*
работает с NUL-терминированными байтовыми строками UTF-8. Декодирование UTF-8
строгое: принимаются только современные последовательности длиной от одного до
четырёх байтов, представляющие скалярные значения Unicode до U+10FFFF.
Избыточные кодировки, суррогатные кодовые точки, некорректные байты продолжения
и исторические пяти- и шестибайтовые формы отвергаются.
.PP
.BR mpu_utf8next (),
.BR mpu_utf8prev ()
и
.BR mpu_utf8last ()
возвращают границы символов.
.B mpu_utf8get()
декодирует один символ в
.I *value
и возвращает границу следующего символа. На завершающем NUL функция сохраняет
ноль и возвращает тот же указатель.
.PP
.B mpu_utf8len()
возвращает число символов Unicode, а не байтов.
.B mpu_utf8nlen()
возвращает не более
.I maxlen
символов.
.B mpu_utf8bytes()
проверяет всю строку и возвращает её длину в байтах без завершающего NUL.
.B mpu_utf8nbytes()
возвращает число байтов, занимаемое не более чем первыми
.I n
символами UTF-8. Функция никогда не останавливается внутри многобайтовой
последовательности.
.B mpu_utf8valid()
возвращает ненулевое значение только если вся строка является корректным UTF-8.
.PP
.B mpu_utf8_offset2index()
преобразует отсчитываемое от нуля смещение в символах в байтовый индекс.
.B mpu_utf8_index2offset()
преобразует байтовый индекс в смещение в символах. Если
.I index
указывает внутрь многобайтового символа, возвращаемое смещение обозначает
символ, следующий за этой байтовой позицией, в соответствии с историческим
соглашением строк LIBMPUIO.
.PP
.BR mpu_utf8cmp ()
и
.BR mpu_utf8ncmp ()
сравнивают декодированные скалярные значения Unicode. Аргумент
.I n
функции
.B mpu_utf8ncmp()
задаёт число символов.
.PP
.BR mpu_utf8cpy ()
и
.BR mpu_utf8cat ()
копируют полные корректные байтовые строки в той же форме хранения, что и
обычные строки C. Ограниченные функции
.B mpu_utf8ncpy()
и
.B mpu_utf8ncat()
интерпретируют
.I n
как число символов UTF-8 и никогда не разрывают многобайтовый символ.
Результат завершается NUL.
.BR mpu_utf8pcpy ()
копирует полную строку UTF-8 и возвращает указатель на завершающий NUL.
.BR mpu_utf8pncpy ()
копирует не более
.I n
символов UTF-8, никогда не разрывает многобайтовую последовательность, всегда
записывает завершающий NUL и возвращает указатель на этот NUL.
.PP
.BR mpu_utf8chr ()
и
.BR mpu_utf8rchr ()
ищут скалярное значение Unicode.
.B mpu_utf8chrnul()
возвращает найденный символ либо завершающий NUL, если совпадения нет.
.PP
.BR mpu_utf8spn ()
и
.BR mpu_utf8cspn ()
возвращают число символов, а не байтов.
.B mpu_utf8pbrk()
возвращает первый символ в
.IR s ,
который присутствует в наборе символов UTF-8
.IR accept .
.BR mpu_utf8str ()
и
.BR mpu_utf8rstr ()
ищут подстроки UTF-8.
.B mpu_utf8tok()
\- токенизатор с состоянием, аналогичный strtok(3), но наборы разделителей
интерпретируются как символы UTF-8. Его указатель продолжения является
thread-local, поэтому разные потоки выполнения имеют независимое состояние
токенизатора; вложенное использование в одном потоке не является
реентерабельным.
.PP
.B mpu_utf8tok_r()
\- реентерабельный токенизатор, аналогичный strtok_r(3), за исключением того,
что наборы разделителей интерпретируются как символы UTF-8. Следовательно,
разделители могут быть многобайтовыми.
.BR mpu_utf8dup ()
и
.B mpu_utf8ndup()
возвращают строки UTF-8, выделенные через malloc. Ограниченная форма копирует
не более
.I n
символов и никогда не разрывает многобайтовую последовательность.
.SH ОШИБКИ
При некорректном UTF-8 функции декодирования символов устанавливают
.B errno
в
.B EILSEQ
и возвращают NULL либо
.BR (__mpu_size_t)-1 ,
в зависимости от интерфейса.
.SH ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
Если не указано иное, функции, возвращающие указатели, возвращают NULL при
ошибке. Функции подсчёта символов, байтов и преобразования индексов возвращают
.B (__mpu_size_t)-1
для некорректного UTF-8.
.B mpu_utf8valid()
возвращает ноль для некорректного UTF-8 и оставляет
.B errno
равным
.BR EILSEQ .
.SH ПРИМЕЧАНИЯ
Эти функции не выполняют нормализацию Unicode, collation или преобразование
регистра. Поиск подстроки работает по байтовому представлению UTF-8;
корректность UTF-8 гарантирует, что корректно закодированный символ не может
начинаться с байта продолжения.
.SH СМ. ТАКЖЕ
.BR mpu_str8ing (3),
.BR mpu_str16ing (3),
.BR mpu_string_conversion (3)
|