35inline int vformat(
char* buf,
size_t size,
const char* fmt, va_list args) {
36 if (size == 0 || buf ==
nullptr || fmt ==
nullptr) {
41 const size_t max_pos = size - 1;
43 auto put_char = [&](
char c) {
50 auto put_string_padded = [&](
const char* s,
int width) {
60 for (
int i = slen; i < width; ++i) put_char(
' ');
62 while (*p) put_char(*p++);
66 auto render_uint = [](
char* tmp, uint32_t val,
int base,
bool uppercase) ->
int {
67 const char* hex_chars = uppercase ?
"0123456789ABCDEF" :
"0123456789abcdef";
75 rev[rlen++] = hex_chars[val % base];
78 while (rlen > 0) tmp[len++] = rev[--rlen];
83 auto put_padded = [&](
const char* digits,
int len,
int width,
char fill,
bool negative) {
84 int content_len = len + (negative ? 1 : 0);
85 if (fill ==
'0' && negative) {
88 for (
int i = content_len; i < width; ++i) put_char(fill);
89 if (fill !=
'0' && negative) {
92 for (
int i = 0; i < len; ++i) put_char(digits[i]);
95 auto put_uint_padded = [&](uint32_t val,
int base,
bool uppercase,
int width,
char fill) {
97 int len = render_uint(tmp, val, base, uppercase);
98 put_padded(tmp, len, width, fill,
false);
101 auto put_int_padded = [&](int32_t val,
int width,
char fill) {
103 uint32_t uval = neg ?
static_cast<uint32_t
>(-val) :
static_cast<uint32_t
>(val);
105 int len = render_uint(tmp, uval, 10,
false);
106 put_padded(tmp, len, width, fill, neg);
109 auto put_float = [&](
double val,
int precision,
int width,
char fill) {
121 uint32_t int_part =
static_cast<uint32_t
>(val);
122 tpos += render_uint(tmp + tpos, int_part, 10,
false);
126 double frac = val - int_part;
127 for (
int i = 0; i < precision; i++) {
129 int digit =
static_cast<int>(frac);
130 tmp[tpos++] =
static_cast<char>(
'0' + digit);
134 put_padded(tmp, tpos, width, fill, neg);
154 while (*fmt >=
'0' && *fmt <=
'9') {
155 width = width * 10 + (*fmt -
'0');
164 while (*fmt >=
'0' && *fmt <=
'9') {
165 precision = precision * 10 + (*fmt -
'0');
171 bool is_long =
false;
178 }
else if (*fmt ==
'h') {
189 put_int_padded(
static_cast<int32_t
>(va_arg(args,
long)), width, fill);
191 put_int_padded(va_arg(args,
int), width, fill);
197 put_uint_padded(
static_cast<uint32_t
>(va_arg(args,
unsigned long)), 10,
false, width, fill);
199 put_uint_padded(va_arg(args,
unsigned int), 10,
false, width, fill);
205 put_uint_padded(
static_cast<uint32_t
>(va_arg(args,
unsigned long)), 16,
false, width, fill);
207 put_uint_padded(va_arg(args,
unsigned int), 16,
false, width, fill);
213 put_uint_padded(
static_cast<uint32_t
>(va_arg(args,
unsigned long)), 16,
true, width, fill);
215 put_uint_padded(va_arg(args,
unsigned int), 16,
true, width, fill);
220 put_string_padded(va_arg(args,
const char*), width);
224 put_char(
static_cast<char>(va_arg(args,
int)));
228 put_float(va_arg(args,
double), precision, width, fill);
251 buf[pos < size ? pos : max_pos] =
'\0';
253 return static_cast<int>(pos);
int vformat(char *buf, size_t size, const char *fmt, va_list args)
Format a string into a buffer (vsnprintf-style)
int format(char *buf, size_t size, const char *fmt,...)
Format a string into a buffer (snprintf-style)