#pragma once /* is c the start of a utf8 sequence? */ #define isutf(c) (((c)&0xc0) != 0x80) enum { Runevs16 = 0xfe0f, Runezwj = 0x200d, }; /* next character without NUL character terminator */ Rune u8_nextmemchar(const char *s, usize *i) sl_cstr(1) sl_nonnull(1, 2); /* returns length of next utf-8 sequence */ usize u8_seqlen(const char *s) sl_cstr(1) sl_purefn sl_nonnull(1); /* length of a utf-8 string in runes */ usize u8_runelen(const char *s, usize m, bool *err) sl_cstr(1) sl_rd(1, 2) sl_nonnull(1); char read_escape_control_char(char c) sl_constfn; /* given a wide character, convert it to an ASCII escape sequence stored in buf, where buf is "sz" bytes. returns the number of characters output. sz must be at least 3. */ int u8_escape_rune(char *buf, usize sz, Rune ch) sl_wr(1, 2) sl_nonnull(1); /* convert UTF-8 "src" to escape sequences. sz is buf size in bytes. must be at least 12. if escape_quotes is nonzero, quote characters will be escaped. if ascii is nonzero, the output is 7-bit ASCII, no UTF-8 survives. starts at src[*pi], updates *pi to point to the first unprocessed byte of the input. end is one more than the last allowable value of *pi. returns number of bytes placed in buf, including a NUL terminator. */ usize u8_escape(char *buf, usize sz, const char *src, usize *pi, usize end, bool escape_quotes, bool ascii) sl_wr(1, 2) sl_cstr(3) sl_rd(3, 5) sl_nonnull(1, 3, 4); /* utility predicates used by the above */ bool octal_digit(char c) sl_constfn; bool hex_digit(char c) sl_constfn; /* searches for a rune within a buffer of a given size */ u8int *u8_memchr(u8int *s, Rune ch, usize sz, usize *charn) sl_nonnull(1, 4); /* number of columns occupied by a string */ ssize u8_strwidth(const char *s, usize n, bool *err) sl_cstr(1) sl_rd(1, 2) sl_nonnull(1); /* length (in bytes) of the longest prefix of s[0..n) whose visible width does no exceed "maxwidth". */ usize u8_strnlen(const char *s, usize n, ssize maxwidth, ssize *outwidth, bool *err) sl_cstr(1) sl_rd(1, 2) sl_nonnull(1, 4, 5); /* determine whether a sequence of bytes is valid UTF-8. length is in bytes */ bool u8_isvalid(const char *str, int length) sl_purefn sl_nonnull(1) sl_rd(1, 2); /* reverse a UTF-8 string. len is length in bytes. dest and src must both be allocated to at least len+1 bytes. returns 1 for error, 0 otherwise */ void u8_reverse(char *dest, const char *src, usize len) sl_cstr(2) sl_rd(2, 3) sl_nonnull(1, 2); int isdigit_base(char c, int base) sl_constfn; void str_init(void); usize rune_index(sl_v str, usize runeidx);