feat(esp_rom): Support precision attr for esp_rom_vprintf

This commit is contained in:
Konstantin Kondrashov 2024-06-06 15:18:11 +03:00
parent 13e5b6f335
commit fc5ce967a6
3 changed files with 121 additions and 5 deletions

View File

@ -8,6 +8,7 @@
#include <stdbool.h>
#include <stdarg.h>
#include <stddef.h>
#include <sys/param.h>
#include "esp_rom_caps.h"
#include "esp_rom_sys.h"
#include "rom/ets_sys.h"
@ -54,7 +55,7 @@ static int ets_vprintf(void (*putc)(char c), const char *fmt, va_list ap)
islong, islonglong;
long long val = 0;
int res = 0, length = 0;
// %[flags][left_prec][.right_prec][sub_type]type
while ((c = *fmt++) != '\0') {
if (c == '%') {
c = *fmt++;
@ -75,13 +76,11 @@ static int ets_vprintf(void (*putc)(char c), const char *fmt, va_list ap)
}
if (c == '.') {
c = *fmt++;
zero_fill++;
zero_fill = false;
while (is_digit(c)) {
right_prec = (right_prec * 10) + (c - '0');
c = *fmt++;
}
} else {
right_prec = left_prec;
}
sign = '\0';
if (c == 'l') {
@ -168,10 +167,14 @@ static int ets_vprintf(void (*putc)(char c), const char *fmt, va_list ap)
case 'S':
cp = va_arg(ap, char *);
if (cp == NULL) {
cp = (char *)"<null000>";
cp = (char *)"<null>";
}
length = 0;
while (cp[length] != '\0') length++;
if (right_prec) {
length = MIN(right_prec, length);
right_prec = 0;
}
break;
case 'c':
case 'C':
@ -206,6 +209,10 @@ static int ets_vprintf(void (*putc)(char c), const char *fmt, va_list ap)
res += 2;
}
pad = left_prec - length;
right_prec = right_prec - length;
if (right_prec > 0) {
pad -= right_prec;
}
if (sign != '\0') {
pad--;
}
@ -229,6 +236,10 @@ static int ets_vprintf(void (*putc)(char c), const char *fmt, va_list ap)
(*putc)(sign);
res++;
}
while (right_prec-- > 0) {
(*putc)('0');
res++;
}
while (length-- > 0) {
c = *cp++;
(*putc)(c);

View File

@ -1,4 +1,5 @@
idf_component_register(SRCS "rom_test.cpp"
"rom_printf_test.cpp"
INCLUDE_DIRS "."
REQUIRES esp_rom
WHOLE_ARCHIVE)

View File

@ -0,0 +1,104 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include <cstdio>
#include <regex>
#include <cstring>
#include "esp_rom_sys.h"
#include "esp_err.h"
#include <catch2/catch_test_macros.hpp>
using namespace std;
#define BUFFER_SIZE (128)
static char s_print_buffer[BUFFER_SIZE];
static unsigned s_counter = 0;
static void reset_buffer(void)
{
s_counter = 0;
memset(s_print_buffer, 0, BUFFER_SIZE);
}
void putc_to_buffer(char c)
{
s_print_buffer[s_counter++] = c;
}
static esp_err_t test_printf(const char *format, ...)
{
esp_err_t error = ESP_OK;
va_list list1, list2;
char expected_str[BUFFER_SIZE];
char *tested_str = s_print_buffer;
va_start(list1, format);
va_copy(list2, list1);
reset_buffer();
int len1 = esp_rom_vprintf(format, list1);
int len2 = vsnprintf(expected_str, BUFFER_SIZE, format, list2);
va_end(list2);
va_end(list1);
if (len1 != len2) {
error = ESP_FAIL;
}
if (strcmp(tested_str, expected_str) != 0) {
error = ESP_FAIL;
}
if (error) {
printf("BAD: ");
} else {
printf("OK : ");
}
printf("'%s' -> %s", format, tested_str);
if (error) {
printf(" != ");
} else {
printf(" == ");
}
printf("%s\n", expected_str);
return error;
}
TEST_CASE("Test precisions attrs of esp_rom_vprintf")
{
esp_rom_install_channel_putc(1, putc_to_buffer);
esp_err_t error = ESP_OK;
error |= test_printf("[%d|%3d|%6d|%03d|%06d|%0d]", 1, 2, 3, 4, 5, 6);
error |= test_printf("[%d|%3d|%6d|%03d|%06d|%0d]", -1, -2, -3, -4, -5, -6);
error |= test_printf("[%d|%3d|%6d|%03d|%06d|%0d]", 10, 11, 12, 13, 14, 15);
error |= test_printf("[%d|%3d|%6d|%03d|%06d|%0d]", -10, -11, -12, -13, -14, -15);
error |= test_printf("[%d|%3d|%6d|%03d|%06d|%0d]", 12345, 12346, 12347, 12348, 12349, 12350);
error |= test_printf("[%d|%3d|%6d|%03d|%06d|%0d]", -12345, -12346, -12347, -12348, -12349, -12350);
error |= test_printf("[%.3d|%.1d|%.0d|%0.0d|%0.3d|%0.1d|%03.3d]", 1, 2, 3, 4, 5, 6, 7);
error |= test_printf("[%.3d|%.1d|%.0d|%0.0d|%0.3d|%0.1d|%03.3d]", -1, -2, -3, -4, -5, -6, -7);
error |= test_printf("[%.3d|%.1d|%.0d|%0.0d|%0.3d|%0.1d|%03.3d]", 10, 11, 12, 13, 14, 15, 16);
error |= test_printf("[%.3d|%.1d|%.0d|%0.0d|%0.3d|%0.1d|%03.3d]", -10, -11, -12, -13, -14, -15, -16);
error |= test_printf("[%.3d|%.1d|%.0d|%0.0d|%0.3d|%0.1d|%03.3d]", 12345, 12346, 12347, 12348, 12349, 12350, 123451);
error |= test_printf("[%.3d|%.1d|%.0d|%0.0d|%0.3d|%0.1d|%03.3d]", -12345, -12346, -12347, -12348, -12349, -12350, 123451);
error |= test_printf("[%6.4d|%06.4d|%04.6d|%4.6d|%8.4d|%08.4d]", 1, 2, 3, 4, 5, 6);
error |= test_printf("[%6.4d|%06.4d|%04.6d|%4.6d|%8.4d|%08.4d]", -1, -2, -3, -4, -5, -6);
error |= test_printf("[%6.4d|%06.4d|%04.6d|%4.6d|%8.4d|%08.4d]", 10, 11, 12, 13, 14, 15);
error |= test_printf("[%6.4d|%06.4d|%04.6d|%4.6d|%8.4d|%08.4d]", -10, -11, -12, -13, -14, -15);
error |= test_printf("[%6.4d|%06.4d|%04.6d|%4.6d|%8.4d|%08.4d]", 12340, 12341, 12342, 12343, 12344, 12345);
error |= test_printf("[%6.4d|%06.4d|%04.6d|%4.6d|%8.4d|%08.4d]", -12340, -12341, -12342, -12343, -12344, -12345);
error |= test_printf("[%-20s]", "1TEST_STR");
error |= test_printf("[%-20.5s]", "8TEST_STR");
error |= test_printf("[%20s]", "2TEST_STR");
error |= test_printf("[%3s]", "3TEST_STR");
error |= test_printf("[%.3s]", "4TEST_STR");
error |= test_printf("[%.20s]", "5TEST_STR");
error |= test_printf("[%6.3s]", "6TEST_STR");
error |= test_printf("[%06.3s]", "7TEST_STR");
esp_rom_install_uart_printf();
CHECK(error == ESP_OK);
}