foo
This commit is contained in:
+65
-42
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user