28 #define LELY_UTIL_PRINT_INLINE extern inline
43 print_fmt(
char **pbegin,
char *end,
const char *format, ...)
47 size_t chars =
vprint_fmt(pbegin, end, format, ap);
53 vprint_fmt(
char **pbegin,
char *end,
const char *format, va_list ap)
56 if (pbegin && *pbegin && (!end || *pbegin < end)) {
64 memcpy(*pbegin, buf, end ?
MIN(end - *pbegin, chars) : chars);
69 return vsnprintf(NULL, 0, format, ap);
73 int chars = vsnprintf(NULL, 0, format, aq);
76 if (pbegin && *pbegin && (!end || *pbegin < end)) {
78 vsprintf(buf, format, ap);
79 memcpy(*pbegin, buf, end ?
MIN(end - *pbegin, chars) : chars);
89 static const unsigned char mark[] = { 0x00, 0xc0, 0xe0, 0xf0 };
96 if ((c32 >= 0xd800 && c32 <= 0xdfff) || c32 > 0x10ffff)
99 int n = c32 <= 0x07ff ? 1 : (c32 <= 0xffff ? 2 : 3);
101 pbegin, end, ((c32 >> (n * 6)) & 0x3f) | mark[n]);
104 pbegin, end, ((c32 >> (n * 6)) & 0x3f) | 0x80);
172 }
else if ((c32 < 0xd800 || c32 > 0xdfff) && c32 <= 0x10ffff) {
181 while (c32 >> (4 * n))
184 for (
int i = 0; i < n; i++)
186 xtoc(c32 >> (4 * (n - i - 1))));
198 const char *ends = s + (s ? n : 0);
209 #define LELY_UTIL_DEFINE_PRINT(type, suffix, name, format) \
210 size_t print_c99_##suffix(char **pbegin, char *end, type name) \
212 return print_fmt(pbegin, end, format, name); \
215 LELY_UTIL_DEFINE_PRINT(
long,
long, l,
"%li")
216 LELY_UTIL_DEFINE_PRINT(
unsigned long, ulong, ul, "%lu")
217 LELY_UTIL_DEFINE_PRINT(
long long, llong, ll, "%"
LENll "i")
218 LELY_UTIL_DEFINE_PRINT(
unsigned long long, ullong, ull, "%"
LENll "u")
220 #undef LELY_UTIL_DEFINE_PRINT
222 #define LELY_UTIL_DEFINE_PRINT(type, suffix, name, format, dig) \
223 size_t print_c99_##suffix(char **pbegin, char *end, type name) \
225 return print_fmt(pbegin, end, format, dig, name); \
228 LELY_UTIL_DEFINE_PRINT(
float, flt, f,
"%.*g", FLT_DIG)
229 LELY_UTIL_DEFINE_PRINT(
double, dbl, d, "%.*g", DBL_DIG)
231 LELY_UTIL_DEFINE_PRINT(
long double, ldbl, ld,
"%.*Lg", LDBL_DIG)
234 #undef LELY_UTIL_DEFINE_PRINT
236 #define LELY_UTIL_DEFINE_PRINT(type, suffix, name, alias) \
237 size_t print_c99_##suffix(char **pbegin, char *end, type name) \
239 return print_c99_##alias(pbegin, end, name); \
242 LELY_UTIL_DEFINE_PRINT(int_least8_t, i8, i8,
long)
243 LELY_UTIL_DEFINE_PRINT(int_least16_t, i16, i16,
long)
244 LELY_UTIL_DEFINE_PRINT(int_least32_t, i32, i32,
long)
246 LELY_UTIL_DEFINE_PRINT(int_least64_t, i64, i64, llong)
248 LELY_UTIL_DEFINE_PRINT(int_least64_t, i64, i64,
long)
250 LELY_UTIL_DEFINE_PRINT(uint_least8_t, u8, u8, ulong)
251 LELY_UTIL_DEFINE_PRINT(uint_least16_t, u16, u16, ulong)
252 LELY_UTIL_DEFINE_PRINT(uint_least32_t, u32, u32, ulong)
254 LELY_UTIL_DEFINE_PRINT(uint_least64_t, u64, u64, ullong)
256 LELY_UTIL_DEFINE_PRINT(uint_least64_t, u64, u64, ulong)
259 #undef LELY_UTIL_DEFINE_PRINT
265 static const char tab[64] =
266 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef"
267 "ghijklmnopqrstuvwxyz0123456789+/";
272 const unsigned char *bp = ptr;
274 char c = tab[(bp[0] >> 2) & 0x3f];
276 if (!((chars + 2) % 78)) {
281 c = tab[((bp[0] << 4) + (--n ? (bp[1] >> 4) : 0)) & 0x3f];
283 if (!((chars + 2) % 78)) {
289 c = n ? tab[((bp[1] << 2) + (--n ? (bp[2] >> 6) : 0)) & 0x3f]
293 if (!((chars + 2) % 78)) {
298 c = n ? (--n, tab[bp[2] & 0x3f]) :
'=';
300 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....