25 #define LELY_UTIL_PRINT_INLINE extern inline 40 print_fmt(
char **pbegin,
char *end,
const char *format, ...)
44 size_t chars =
vprint_fmt(pbegin, end, format, ap);
50 vprint_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))));
195 const char *ends = s + (s ? n : 0);
206 #define LELY_UTIL_DEFINE_PRINT(type, suffix, name, format) \ 207 size_t print_c99_##suffix(char **pbegin, char *end, type name) \ 209 return print_fmt(pbegin, end, format, name); \ 212 LELY_UTIL_DEFINE_PRINT(
long,
long, l,
"%li")
213 LELY_UTIL_DEFINE_PRINT(
unsigned long, ulong, ul, "%lu")
214 LELY_UTIL_DEFINE_PRINT(
long long, llong, ll, "%"
LENll "i")
215 LELY_UTIL_DEFINE_PRINT(
unsigned long long, ullong, ull, "%"
LENll "u")
217 #undef LELY_UTIL_DEFINE_PRINT 219 #define LELY_UTIL_DEFINE_PRINT(type, suffix, name, format, dig) \ 220 size_t print_c99_##suffix(char **pbegin, char *end, type name) \ 222 return print_fmt(pbegin, end, format, dig, name); \ 225 LELY_UTIL_DEFINE_PRINT(
float, flt, f,
"%.*g", FLT_DIG)
226 LELY_UTIL_DEFINE_PRINT(
double, dbl, d, "%.*g", DBL_DIG)
228 LELY_UTIL_DEFINE_PRINT(
long double, ldbl, ld,
"%.*Lg", LDBL_DIG)
231 #undef LELY_UTIL_DEFINE_PRINT 233 #define LELY_UTIL_DEFINE_PRINT(type, suffix, name, alias) \ 234 size_t print_c99_##suffix(char **pbegin, char *end, type name) \ 236 return print_c99_##alias(pbegin, end, name); \ 239 LELY_UTIL_DEFINE_PRINT(int_least8_t, i8, i8,
long)
240 LELY_UTIL_DEFINE_PRINT(int_least16_t, i16, i16,
long)
241 LELY_UTIL_DEFINE_PRINT(int_least32_t, i32, i32,
long)
243 LELY_UTIL_DEFINE_PRINT(int_least64_t, i64, i64, llong)
245 LELY_UTIL_DEFINE_PRINT(int_least64_t, i64, i64,
long)
247 LELY_UTIL_DEFINE_PRINT(uint_least8_t, u8, u8, ulong)
248 LELY_UTIL_DEFINE_PRINT(uint_least16_t, u16, u16, ulong)
249 LELY_UTIL_DEFINE_PRINT(uint_least32_t, u32, u32, ulong)
251 LELY_UTIL_DEFINE_PRINT(uint_least64_t, u64, u64, ullong)
253 LELY_UTIL_DEFINE_PRINT(uint_least64_t, u64, u64, ulong)
256 #undef LELY_UTIL_DEFINE_PRINT 262 static const char tab[64] =
263 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef" 264 "ghijklmnopqrstuvwxyz0123456789+/";
269 const unsigned char *bp = ptr;
271 char c = tab[(bp[0] >> 2) & 0x3f];
273 if (!((chars + 2) % 78)) {
278 c = tab[((bp[0] << 4) + (--n ? (bp[1] >> 4) : 0)) & 0x3f];
280 if (!((chars + 2) % 78)) {
286 c = n ? tab[((bp[1] << 2) + (--n ? (bp[2] >> 6) : 0)) & 0x3f]
290 if (!((chars + 2) % 78)) {
295 c = n ? (--n, tab[bp[2] & 0x3f]) :
'=';
297 if (n && !((chars + 2) % 78)) {
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 <string.h> and defines any missing functionality.
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_utf8(char **pbegin, char *end, char32_t c32)
Prints a UTF-8 encoded Unicode character to a memory buffer.
size_t print_char(char **pbegin, char *end, int c)
Prints a single character to a memory buffer.
#define MIN(a, b)
Returns the minimum of a and b.
This header file is part of the utilities library; it contains the IEEE 754 floating-point format typ...
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.
This header file is part of the utilities library; it contains the lexer function declarations...
This is the internal header file of the utilities library.
int xtoc(int i)
Returns the character corresponding to the hexadecimal digit i.
This header file is part of the C11 and POSIX compatibility library; it includes <uchar.h>, if it exists, and defines any missing functionality.
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.
This header file is part of the C11 and POSIX compatibility library; it includes <stdint.h> and defines any missing functionality.
This header file is part of the C11 and POSIX compatibility library; it includes <stdio.h> and defines any missing functionality.
This header file is part of the utilities library; it contains the printing function declarations...
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 print_fmt(char **pbegin, char *end, const char *format,...)
Prints a formatted string to a memory buffer.
This header file is part of the C11 and POSIX compatibility library; it includes <stdlib.h> and defines any missing functionality.
#define LENll
A cross-platform "ll" length modifier macro for format specifiers.
int otoc(int i)
Returns the character corresponding to the octal digit i.
size_t print_c99_esc(char **pbegin, char *end, char32_t c32)
Prints a UTF-8 encoded Unicode character to a memory buffer.