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)) {
311 #endif // !LELY_NO_STDIO