prf.c: remove arbitrary large stack buffer usage
The on-stack work buffer occupies 201 bytes by default. Now that we've made the code able to cope with virtually unlimited width and precision values, we can reduce stack usage to its strict minimum i.e. 25 bytes. This allows for some additional sprintf tests exercizing wide results. Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
This commit is contained in:
parent
d28434b4fa
commit
f286eda6f0
2 changed files with 40 additions and 20 deletions
|
@ -16,25 +16,14 @@
|
|||
#include <sys/types.h>
|
||||
#include <sys/util.h>
|
||||
|
||||
#ifndef MAXFLD
|
||||
#define MAXFLD 200
|
||||
#endif
|
||||
|
||||
#ifndef EOF
|
||||
#define EOF -1
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MINIMAL_LIBC_LL_PRINTF
|
||||
#define VALTYPE long long
|
||||
#define SIZEOF_VALTYPE __SIZEOF_LONG_LONG__
|
||||
#else
|
||||
#define VALTYPE long
|
||||
#define SIZEOF_VALTYPE __SIZEOF_LONG__
|
||||
#endif
|
||||
|
||||
/* this has to fit max range octal display */
|
||||
#if MAXFLD < (1 + (SIZEOF_VALTYPE*8 + 2)/3)
|
||||
#error buffer size MAXFLD is too small
|
||||
#endif
|
||||
|
||||
static void _uc(char *buf)
|
||||
|
@ -442,12 +431,14 @@ static int _atoi(const char **sptr)
|
|||
int z_prf(int (*func)(), void *dest, const char *format, va_list vargs)
|
||||
{
|
||||
/*
|
||||
* Due the fact that buffer is passed to functions in this file,
|
||||
* they assume that its size is MAXFLD + 1. In need of change
|
||||
* the buffer size, either MAXFLD should be changed or the change
|
||||
* has to be propagated across the file
|
||||
* The work buffer has to accommodate for the largest data length.
|
||||
* The max range octal length is one prefix + 3 bits per digit
|
||||
* meaning 12 bytes on 32-bit and 23 bytes on 64-bit.
|
||||
* The float code may extract up to 16 digits, plus a prefix,
|
||||
* a leading 0, a dot, and an exponent in the form e+xxx for
|
||||
* a total of 24. Add a trailing NULL so it is 25.
|
||||
*/
|
||||
char buf[MAXFLD + 1];
|
||||
char buf[25];
|
||||
char c;
|
||||
int count;
|
||||
char *cptr;
|
||||
|
@ -519,10 +510,6 @@ int z_prf(int (*func)(), void *dest, const char *format, va_list vargs)
|
|||
precision = _atoi(&format);
|
||||
}
|
||||
|
||||
if (precision > MAXFLD) {
|
||||
precision = -1;
|
||||
}
|
||||
|
||||
c = *format++;
|
||||
}
|
||||
|
||||
|
|
|
@ -216,6 +216,39 @@ void test_sprintf_double(void)
|
|||
zassert_true((strcmp(buffer, "1234.567890") == 0),
|
||||
"sprintf(-1.0) - incorrect output '%s'\n", buffer);
|
||||
|
||||
/*
|
||||
* With very large precision, the output differs significantly in
|
||||
* terms of string even if not in terms of actual value depending
|
||||
* on the library used and FPU implementation. However the length
|
||||
* and decimal position should remain identical.
|
||||
*/
|
||||
var.d = 0x1p800;
|
||||
sprintf(buffer, "%.140f", var.d);
|
||||
zassert_true((strlen(buffer) == 382),
|
||||
"sprintf(<large output>) - incorrect length %d\n",
|
||||
strlen(buffer));
|
||||
buffer[10] = 0; /* log facility doesn't support %.10s */
|
||||
zassert_true((strcmp(buffer, "6668014432") == 0),
|
||||
"sprintf(<large output>) - starts with \"%s\" "
|
||||
"expected \"6668014432\"\n", buffer);
|
||||
zassert_true((buffer[241] == '.'),
|
||||
"sprintf(<large output>) - expected '.' got '%c'\n",
|
||||
buffer[241]);
|
||||
|
||||
var.d = 0x1p-400;
|
||||
sprintf(buffer, "% .380f", var.d);
|
||||
zassert_true((strlen(buffer) == 383),
|
||||
"sprintf(<large output>) - incorrect length %d\n",
|
||||
strlen(buffer));
|
||||
buffer[10] = 0; /* log facility doesn't support %.10s */
|
||||
zassert_true((strcmp(buffer, " 0.0000000") == 0),
|
||||
"sprintf(<large output>) - starts with \"%s\" "
|
||||
"expected \" 0.0000000\"\n", buffer);
|
||||
buffer[119 + 10] = 0; /* log facility doesn't support %.10s */
|
||||
zassert_true((strcmp(buffer + 119, "0000387259") == 0),
|
||||
"sprintf(<large output>) - got \"%s\" "
|
||||
"while expecting \"0000387259\"\n", buffer + 119);
|
||||
|
||||
/*******************/
|
||||
var.d = 1234.0;
|
||||
sprintf(buffer, "%e", var.d);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue