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 = [&](
const char* s) {
59 auto put_uint = [&](uint32_t val,
int base,
bool uppercase) {
62 const char* hex_chars = uppercase ?
"0123456789ABCDEF" :
"0123456789abcdef";
70 digits[len++] = hex_chars[val % base];
75 put_char(digits[--len]);
79 auto put_int = [&](int32_t val) {
84 put_uint(
static_cast<uint32_t
>(val), 10,
false);
87 auto put_float = [&](
double val,
int precision) {
95 uint32_t int_part =
static_cast<uint32_t
>(val);
96 put_uint(int_part, 10,
false);
102 double frac = val - int_part;
103 for (
int i = 0; i < precision; i++) {
105 int digit =
static_cast<int>(frac);
106 put_char(
'0' + digit);
120 while (*fmt >=
'0' && *fmt <=
'9') {
129 while (*fmt >=
'0' && *fmt <=
'9') {
130 precision = precision * 10 + (*fmt -
'0');
136 bool is_long =
false;
143 }
else if (*fmt ==
'h') {
154 put_int(
static_cast<int32_t
>(va_arg(args,
long)));
156 put_int(va_arg(args,
int));
162 put_uint(
static_cast<uint32_t
>(va_arg(args,
unsigned long)), 10,
false);
164 put_uint(va_arg(args,
unsigned int), 10,
false);
170 put_uint(
static_cast<uint32_t
>(va_arg(args,
unsigned long)), 16,
false);
172 put_uint(va_arg(args,
unsigned int), 16,
false);
178 put_uint(
static_cast<uint32_t
>(va_arg(args,
unsigned long)), 16,
true);
180 put_uint(va_arg(args,
unsigned int), 16,
true);
185 put_string(va_arg(args,
const char*));
189 put_char(
static_cast<char>(va_arg(args,
int)));
193 put_float(va_arg(args,
double), precision);
216 buf[pos < size ? pos : max_pos] =
'\0';
218 return static_cast<int>(pos);