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
|
.TH MPU_UTF8ING 3 "August 2026" "libmpuio" "LIBMPUIO Programmer's Manual"
.SH NAME
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 string and character operations
.SH SYNOPSIS
.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 DESCRIPTION
The
.B mpu_utf8*
family operates on NUL-terminated UTF-8 byte strings. UTF-8 decoding is
strict: only modern one- through four-byte sequences representing Unicode
scalar values through U+10FFFF are accepted. Overlong encodings, surrogate
code points, malformed continuations and historical five- or six-byte forms
are rejected.
.PP
.BR mpu_utf8next (),
.BR mpu_utf8prev ()
and
.BR mpu_utf8last ()
return character boundaries.
.B mpu_utf8get()
decodes one character into
.I *value
and returns the next character boundary. At the terminating NUL it stores zero
and returns the same pointer.
.PP
.B mpu_utf8len()
returns the number of Unicode characters, not the number of bytes.
.B mpu_utf8nlen()
returns at most
.I maxlen
characters.
.B mpu_utf8bytes()
validates the complete string and returns its byte length excluding the terminating NUL.
.B mpu_utf8nbytes()
returns the byte length occupied by at most the first
.I n
UTF-8 characters. It never stops inside a multibyte sequence.
.B mpu_utf8valid()
returns nonzero only if the complete string is well-formed UTF-8.
.PP
.B mpu_utf8_offset2index()
converts a zero-based character offset to a byte index.
.B mpu_utf8_index2offset()
converts a byte index to a character offset. If
.I index
lies in the middle of a multibyte character, the returned offset denotes the
character following that byte position, matching the historical LIBMPUIO
string convention.
.PP
.BR mpu_utf8cmp ()
and
.BR mpu_utf8ncmp ()
compare decoded Unicode scalar values. The
.I n
argument of
.B mpu_utf8ncmp()
is a character count.
.PP
.BR mpu_utf8cpy ()
and
.BR mpu_utf8cat ()
copy complete valid byte strings in the same storage form as ordinary C
strings. The bounded functions
.B mpu_utf8ncpy()
and
.B mpu_utf8ncat()
interpret
.I n
as a number of UTF-8 characters and never split a multibyte character.
The result is NUL-terminated.
.BR mpu_utf8pcpy ()
copies a complete UTF-8 string and returns a pointer to the terminating NUL.
.BR mpu_utf8pncpy ()
copies at most
.I n
UTF-8 characters, never splits a multibyte sequence, always writes a
terminating NUL, and returns a pointer to that NUL.
.PP
.BR mpu_utf8chr ()
and
.BR mpu_utf8rchr ()
search for a Unicode scalar value.
.B mpu_utf8chrnul()
returns the matching character or the terminating NUL if no match exists.
.PP
.BR mpu_utf8spn ()
and
.BR mpu_utf8cspn ()
return character counts, not byte counts.
.B mpu_utf8pbrk()
returns the first character in
.I s
which is present in the UTF-8 character set
.IR accept .
.BR mpu_utf8str ()
and
.BR mpu_utf8rstr ()
search for UTF-8 substrings.
.B mpu_utf8tok()
is the stateful tokenizer analogous to strtok(3), but delimiter sets are
interpreted as UTF-8 characters. Its continuation pointer is thread-local,
so different threads have independent tokenizer state; nested use within one
thread is not reentrant.
.PP
.B mpu_utf8tok_r()
is a reentrant tokenizer analogous to strtok_r(3), except that delimiter sets
are interpreted as UTF-8 characters. Delimiters may therefore be multibyte.
.BR mpu_utf8dup ()
and
.B mpu_utf8ndup()
return malloc-allocated UTF-8 strings. The bounded form duplicates at most
.I n
characters and never splits a multibyte sequence.
.SH ERRORS
On malformed UTF-8, character-decoding functions set
.B errno
to
.B EILSEQ
and return NULL or
.BR (__mpu_size_t)-1 ,
as appropriate.
.SH RETURN VALUE
Unless otherwise stated, pointer-returning functions return NULL on failure.
Character-count, byte-count and conversion-index functions return
.B (__mpu_size_t)-1
for invalid UTF-8.
.B mpu_utf8valid()
returns zero for invalid UTF-8 and leaves
.B errno
set to
.BR EILSEQ .
.SH NOTES
These functions do not perform Unicode normalization, collation or case
folding. Substring search operates on the UTF-8 byte representation; valid
UTF-8 guarantees that a valid encoded character cannot begin at a continuation
byte.
.SH SEE ALSO
.BR mpu_str8ing (3),
.BR mpu_str16ing (3),
.BR mpu_string_conversion (3)
|