This commit is contained in:
2026-09-28 17:46:45 +02:00
committed by Marvin Friedrich
parent 09926f45ee
commit 4a20a5b0af
62 changed files with 1266 additions and 554 deletions
+65 -42
View File
@@ -10,6 +10,11 @@
typedef void (*log_fn_t)(void* ctx, const char* buf, size_t len);
static void print_pad(log_fn_t callback, void* ctx, char c, size_t count) {
for (size_t i = 0; i < count; i++)
callback(ctx, &c, 1);
}
static void do_print(log_fn_t callback, void* ctx, const char* restrict fmt, va_list args) {
// Amount of bytes written.
int32_t written = 0;
@@ -37,7 +42,7 @@ static void do_print(log_fn_t callback, void* ctx, const char* restrict fmt, va_
bool blank_sign = false;
bool write_prefix = false;
bool pad_zero = false;
bool has_width = false;
bool left_align = false;
size_t width = 0;
bool has_precision = false;
size_t precision = 0;
@@ -68,6 +73,11 @@ check_fmt:
fmt++;
goto check_fmt;
}
case '-': {
left_align = true;
fmt++;
goto check_fmt;
}
// Width
case '1':
case '2':
@@ -78,14 +88,11 @@ check_fmt:
case '7':
case '8':
case '9': {
has_width = true;
char number[10 + 1] = {0};
size_t idx = 0;
width = 0;
while (*fmt >= '0' && *fmt <= '9') {
number[idx++] = *fmt;
width = width * 10 + (*fmt - '0');
fmt++;
}
width = atolu(number, 10);
goto check_fmt;
}
@@ -93,16 +100,19 @@ check_fmt:
case '.': {
has_precision = true;
fmt++;
precision = 0;
if (*fmt == '*') {
precision = (char)va_arg(args, int32_t);
const int32_t arg = va_arg(args, int32_t);
if (arg < 0)
has_precision = false;
else
precision = arg;
fmt++;
} else {
char number[10 + 1] = {0};
size_t idx = 0;
while (*fmt >= '0' && *fmt <= '9') {
number[idx++] = *fmt;
precision = precision * 10 + (*fmt - '0');
fmt++;
}
precision = atolu(number, 10);
}
goto check_fmt;
}
@@ -133,10 +143,15 @@ check_fmt:
// Character
case 'c': {
char c = (char)va_arg(args, int32_t);
const size_t pad = width > 1 ? width - 1 : 0;
if (!left_align)
print_pad(callback, ctx, ' ', pad);
callback(ctx, &c, sizeof(c));
if (left_align)
print_pad(callback, ctx, ' ', pad);
written++;
written += 1 + pad;
fmt++;
break;
}
@@ -150,10 +165,15 @@ check_fmt:
len = strnlen(str, precision);
else
len = strlen(str);
const size_t pad = width > len ? width - len : 0;
if (!left_align)
print_pad(callback, ctx, ' ', pad);
callback(ctx, str, len);
if (left_align)
print_pad(callback, ctx, ' ', pad);
written += len;
written += len + pad;
fmt++;
break;
}
@@ -212,36 +232,38 @@ check_fmt:
break;
}
print_num:
size_t len = strlen(number);
if (has_precision) {
for (size_t i = 0; i < precision - len; i++)
callback(ctx, " ", 1);
const char* digits = number;
char sign = 0;
if (digits[0] == '-') {
sign = '-';
digits++;
} else if (force_sign) {
sign = '+';
} else if (blank_sign) {
sign = ' ';
}
if (has_width) {
char c = pad_zero ? '0' : ' ';
// We don't have to pad anything.
if (len < width) {
for (size_t i = 0; i < width - len; i++)
callback(ctx, &c, 1);
}
const size_t len = strlen(digits);
size_t zeros = (has_precision && precision > len) ? precision - len : 0;
const size_t total = (sign ? 1 : 0) + (write_prefix ? 2 : 0) + zeros + len;
size_t pad = width > total ? width - total : 0;
if (pad_zero && !left_align && !has_precision) {
zeros += pad;
pad = 0;
}
if (write_prefix) {
if (!left_align)
print_pad(callback, ctx, ' ', pad);
if (sign)
callback(ctx, &sign, 1);
if (write_prefix)
callback(ctx, "0x", 2);
}
if (force_sign) {
char c = '+';
if (number[0] != '-')
callback(ctx, &c, 1);
}
if (blank_sign) {
char c = ' ';
if (number[0] != '-')
callback(ctx, &c, 1);
}
callback(ctx, number, len);
print_pad(callback, ctx, '0', zeros);
callback(ctx, digits, len);
if (left_align)
print_pad(callback, ctx, ' ', pad);
written += len;
written += width > total ? width : total;
fmt++;
break;
}
@@ -272,13 +294,14 @@ print_num:
}
// No format, just normal text.
default: {
fmt = format_begun_at;
size_t len = strlen(fmt);
size_t len = fmt - format_begun_at;
if (*fmt)
len++;
callback(ctx, fmt, len);
callback(ctx, format_begun_at, len);
written += len;
fmt += len;
fmt = format_begun_at + len;
break;
}
}