25#define LELY_UTIL_PRINT_INLINE extern inline
40print_fmt(
char **pbegin,
char *end,
const char *format, ...)
44 size_t chars =
vprint_fmt(pbegin, end, format, ap);
50vprint_fmt(
char **pbegin,
char *end,
const char *format, va_list ap)
53 if (pbegin && *pbegin && (!end || *pbegin < end)) {
61 memcpy(*pbegin, buf, end ?
MIN(end - *pbegin, chars) : chars);
66 return vsnprintf(NULL, 0, format, ap);
70 int chars = vsnprintf(NULL, 0, format, aq);
73 if (pbegin && *pbegin && (!end || *pbegin < end)) {
75 vsprintf(buf, format, ap);
76 memcpy(*pbegin, buf, end ?
MIN(end - *pbegin, chars) : chars);
86 static const unsigned char mark[] = { 0x00, 0xc0, 0xe0, 0xf0 };
93 if ((c32 >= 0xd800 && c32 <= 0xdfff) || c32 > 0x10ffff)
96 int n = c32 <= 0x07ff ? 1 : (c32 <= 0xffff ? 2 : 3);
98 pbegin, end, ((c32 >> (n * 6)) & 0x3f) | mark[n]);
101 pbegin, end, ((c32 >> (n * 6)) & 0x3f) | 0x80);
169 }
else if ((c32 < 0xd800 || c32 > 0xdfff) && c32 <= 0x10ffff) {
178 while (c32 >> (4 * n))
181 for (
int i = 0; i < n; i++)
183 xtoc(c32 >> (4 * (n - i - 1))));
194 const char *ends = s + (s ? n : 0);
205#define LELY_UTIL_DEFINE_PRINT(type, suffix, name, format) \
206 size_t print_c99_##suffix(char **pbegin, char *end, type name) \
208 return print_fmt(pbegin, end, format, name); \
211LELY_UTIL_DEFINE_PRINT(
long,
long, l,
"%li")
212LELY_UTIL_DEFINE_PRINT(
unsigned long, ulong, ul, "%lu")
213LELY_UTIL_DEFINE_PRINT(
long long, llong, ll, "%"
LENll "i")
214LELY_UTIL_DEFINE_PRINT(
unsigned long long, ullong, ull, "%"
LENll "u")
216#undef LELY_UTIL_DEFINE_PRINT
218#define LELY_UTIL_DEFINE_PRINT(type, suffix, name, format, dig) \
219 size_t print_c99_##suffix(char **pbegin, char *end, type name) \
221 return print_fmt(pbegin, end, format, dig, name); \
224LELY_UTIL_DEFINE_PRINT(
float, flt, f,
"%.*g", FLT_DIG)
225LELY_UTIL_DEFINE_PRINT(
double, dbl, d, "%.*g", DBL_DIG)
227LELY_UTIL_DEFINE_PRINT(
long double, ldbl, ld,
"%.*Lg", LDBL_DIG)
230#undef LELY_UTIL_DEFINE_PRINT
232#define LELY_UTIL_DEFINE_PRINT(type, suffix, name, alias) \
233 size_t print_c99_##suffix(char **pbegin, char *end, type name) \
235 return print_c99_##alias(pbegin, end, name); \
238LELY_UTIL_DEFINE_PRINT(int_least8_t, i8, i8,
long)
239LELY_UTIL_DEFINE_PRINT(int_least16_t, i16, i16,
long)
240LELY_UTIL_DEFINE_PRINT(int_least32_t, i32, i32,
long)
242LELY_UTIL_DEFINE_PRINT(int_least64_t, i64, i64, llong)
244LELY_UTIL_DEFINE_PRINT(int_least64_t, i64, i64,
long)
246LELY_UTIL_DEFINE_PRINT(uint_least8_t, u8, u8, ulong)
247LELY_UTIL_DEFINE_PRINT(uint_least16_t, u16, u16, ulong)
248LELY_UTIL_DEFINE_PRINT(uint_least32_t, u32, u32, ulong)
250LELY_UTIL_DEFINE_PRINT(uint_least64_t, u64, u64, ullong)
252LELY_UTIL_DEFINE_PRINT(uint_least64_t, u64, u64, ulong)
255#undef LELY_UTIL_DEFINE_PRINT
261 static const char tab[64] =
262 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef"
263 "ghijklmnopqrstuvwxyz0123456789+/";
268 const uint8_t *bp = ptr;
270 char c = tab[(bp[0] >> 2) & 0x3f];
272 if (!((chars + 2) % 78)) {
277 c = tab[((bp[0] << 4) + (--n ? (bp[1] >> 4) : 0)) & 0x3f];
279 if (!((chars + 2) % 78)) {
285 c = n ? tab[((bp[1] << 2) + (--n ? (bp[2] >> 6) : 0)) & 0x3f]
289 if (!((chars + 2) % 78)) {
294 c = n ? (--n, tab[bp[2] & 0x3f]) :
'=';
296 if (n && !((chars + 2) % 78)) {
This header file is part of the utilities library; it contains the IEEE 754 floating-point format typ...
#define MIN(a, b)
Returns the minimum of a and b.
This header file is part of the utilities library; it contains the lexer function declarations.
size_t lex_utf8(const char *begin, const char *end, struct floc *at, char32_t *pc32)
Lexes a UTF-8 encoded Unicode character from a memory buffer.
size_t print_c99_str(char **pbegin, char *end, const char *s, size_t n)
Prints a UTF-8 encoded Unicode string to a memory buffer.
size_t vprint_fmt(char **pbegin, char *end, const char *format, va_list ap)
Prints a formatted string to a memory buffer.
size_t print_c99_esc(char **pbegin, char *end, char32_t c32)
Prints a UTF-8 encoded Unicode character to a memory buffer.
size_t print_base64(char **pbegin, char *end, const void *ptr, size_t n)
Prints the Base64 representation of binary data to a memory buffer.
size_t print_utf8(char **pbegin, char *end, char32_t c32)
Prints a UTF-8 encoded Unicode character to a memory buffer.
size_t print_fmt(char **pbegin, char *end, const char *format,...)
Prints a formatted string to a memory buffer.
This header file is part of the utilities library; it contains the printing function declarations.
#define LENll
A cross-platform "ll" length modifier macro for format specifiers.
size_t print_char(char **pbegin, char *end, int c)
Prints a single character to a memory buffer.
int xtoc(int i)
Returns the character corresponding to the hexadecimal digit i.
int otoc(int i)
Returns the character corresponding to the octal digit i.
This is the internal header file of the utilities library.
This header file is part of the C11 and POSIX compatibility library; it includes <stdint....
This header file is part of the C11 and POSIX compatibility library; it includes <stdio....
int vasprintf(char **strp, const char *fmt, va_list ap)
Equivalent to vsprintf(), except that it allocates a string large enough to hold the output,...
This header file is part of the C11 and POSIX compatibility library; it includes <stdlib....
This header file is part of the C11 and POSIX compatibility library; it includes <string....
This header file is part of the C11 and POSIX compatibility library; it includes <uchar....