From 7d44197aef7cfc063329f2cdcc742d4d1c76af2d Mon Sep 17 00:00:00 2001 From: Tilen Majerle Date: Fri, 30 Aug 2024 10:54:45 +0200 Subject: [PATCH] Simplify output generator for integer --- dev/main.c | 5 +++- lwprintf/src/lwprintf/lwprintf.c | 39 +++++++++++++++----------------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/dev/main.c b/dev/main.c index a466bbe..0bf56fa 100644 --- a/dev/main.c +++ b/dev/main.c @@ -26,7 +26,6 @@ size_t tests_passed, tests_failed; #define do_test(buff_ptr, buff_size, exp_out, exp_out_len, fmt, ...) \ do { \ - char my_buffer[1234]; \ int len = lwprintf_snprintf((buff_ptr), (buff_size), (fmt), ##__VA_ARGS__); \ if (len != (exp_out_len)) { \ printf("Test error on line: %d\r\n", __LINE__); \ @@ -120,6 +119,10 @@ main(void) { do_test(buffer, sizeof(buffer), "1.234560e-09", 12, "%e", 0.00000000123456); do_test(buffer, sizeof(buffer), "-000000000001.2346e-01", 22, "%022.4e", -0.123456); do_test(buffer, sizeof(buffer), "-1.2346E+02", 11, "%.4E", -123.456); + do_test(buffer, sizeof(buffer), "0", 1, "%d", 0); + do_test(buffer, sizeof(buffer), "1", 1, "%d", 1); + do_test(buffer, sizeof(buffer), "10", 2, "%d", 10); + do_test(buffer, sizeof(buffer), "140", 3, "%d", 140); do_test(buffer, sizeof(buffer), " 28", 3, "% 3u", (unsigned)28); do_test(buffer, sizeof(buffer), "028", 3, "%03d", 28); do_test(buffer, sizeof(buffer), "+28", 3, "%+03d", 28); diff --git a/lwprintf/src/lwprintf/lwprintf.c b/lwprintf/src/lwprintf/lwprintf.c index 3894653..7632a2c 100644 --- a/lwprintf/src/lwprintf/lwprintf.c +++ b/lwprintf/src/lwprintf/lwprintf.c @@ -359,30 +359,27 @@ prv_out_str(lwprintf_int_t* lwi, const char* buff, size_t buff_size) { */ static int prv_longest_unsigned_int_to_str(lwprintf_int_t* lwi, uint_maxtype_t num) { - uint_maxtype_t den, digit; - uint8_t digits_cnt; - char chr; + /* Start with digits length, support binary with int, that is 32-bits maximum width */ + char num_buf[33], *num_buf_ptr = &num_buf[sizeof(num_buf)]; /* Check if number is zero */ - lwi->m.flags.is_num_zero = (num) == 0; - if ((num) == 0) { - prv_out_str_before(lwi, 1); - lwi->out_fn(lwi, '0'); - prv_out_str_after(lwi, 1); - } else { /* Start with digits length */ - for (digits_cnt = 0, den = (num); den > 0; ++digits_cnt, den /= lwi->m.base) {} - for (den = 1; ((num) / den) >= lwi->m.base; den *= lwi->m.base) {} - - prv_out_str_before(lwi, digits_cnt); - for (; den > 0;) { - digit = (num) / den; - (num) = (num) % den; - den = den / lwi->m.base; - chr = (char)digit + (char)(digit >= 10 ? ((lwi->m.flags.uc ? 'A' : 'a') - 10) : '0'); - lwi->out_fn(lwi, chr); - } - prv_out_str_after(lwi, digits_cnt); + lwi->m.flags.is_num_zero = num == 0; + + /* Fill the buffer backward */ + *--num_buf_ptr = '\0'; + do { + int digit = num % lwi->m.base; + num /= lwi->m.base; + *--num_buf_ptr = (char)digit + (char)(digit >= 10 ? ((lwi->m.flags.uc ? 'A' : 'a') - 10) : '0'); + } while (num > 0); + + /* Calculate and generate the output */ + size_t len = sizeof(num_buf) - (size_t)((uintptr_t)num_buf_ptr - (uintptr_t)num_buf) - 1; + prv_out_str_before(lwi, len); + for (; *num_buf_ptr;) { + lwi->out_fn(lwi, *num_buf_ptr++); } + prv_out_str_after(lwi, len); return 1; }