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