.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 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)