majerle / lwprintf Goto Github PK
View Code? Open in Web Editor NEWLightweight printf library optimized for embedded systems
License: MIT License
Lightweight printf library optimized for embedded systems
License: MIT License
lwprintf/lwprintf/src/lwprintf/lwprintf.c
Line 957 in aa38132
lwprintf/lwprintf/src/lwprintf/lwprintf.c
Line 1032 in aa38132
Tilen, look at lines 1032-1034: if (...) { ... } else if (p->m.flags.sz_t) { action1(); } else if (p->m.flags.sz_t) { action2(); }
In this case, the prv_umaxt_to_str(p, (uintmax_t)va_arg(arg, uintmax_t))
function will never get control
I suppose there should be } else if (p->m.flags.uintmax_t) {
on line 1034
Hi, first of all great work there, really useful library.
I found this weird situation where there is a null pointer dereference.
More specifically, if you specify "%s%s%s" as the format string without parameters, the 3rd formater will cause a null pointer dereference, which leads to a seg fault, while "%s", "%s%s" will work just fine.
I know it's kinda silly to specify format string without parameters, but vsnprintf works just fine for this situation, and this can be fixed easily with a checking whether the pointer is null or not.
So I'm wondering if this worth looking into? (similar thing happens to %n as well).
Hi Tilen,
I am not sure this is an issue, but still...
Tried to consume the library thru PlatformIO IDE and had some issues building the library as-is.
I have very little experience with PlatofrmIO but I assumed it should work out of the box.
Is the library.json
file for use only by the PlatformIO? or have another purpose in life?
After changing it a bit, I could build the library:
]
},
"build": {
"includeDir": "lwprintf/src/include",
"srcDir": "lwprintf",
"flags": [
"-I../../include"
]
}
}
without the includeDir
, I couldn't include the library
without the srcDir
, PlatoformIO try to build also the dev
folder
the last bit, which I found helpful, is adding another include folder (-I
) so I can place the options header, lwprintf_opts.h
, in a project folder and not inside the library itself.
For %g trailing zeros are not removed
4.0f is displayed as 4.00000
4.0e7 is displayed as 4.00000e+7
To correct, use the following statement at line 780:
if (p->m.precision > 0 && (dblnum.decimal_part > 0 || def_type != 'g')) {
Additional zero values end up in a loop.
Terminate loop by checking in_enum for zero at line 666:
for (exp_cnt = 0; in_num < 1 && in_num > 0; in_num *= 10, --exp_cnt) {}
Hello, Tilen MaJerle!
I used the develop-version of this interesting library before I noticed that you made a v1.0.0 release. When I updated to v1.0.0 with my opts used before (#define LWPRINTF_CFG_OS 1
, #define LWPRINTF_CFG_SUPPORT_TYPE_POINTER 0
, #define LWPRINTF_CFG_SUPPORT_TYPE_ENGINEERING 0
), the library cannot compile due to #define LWPRINTF_CFG_SUPPORT_TYPE_ENGINEERING 0
. The error appears on this line
lwprintf/lwprintf/src/lwprintf/lwprintf.c
Line 791 in f67bf43
digits_cnt_decimal_part_useful
is member of float_num_t
when LWPRINTF_CFG_SUPPORT_TYPE_ENGINEERING == 1
Is it a bug?
In the process of exploring #9, I have actually discovered another edge case which needs addressing. If the precision is zero, lwsnprintf()
does not print a null terminator. I do not believe this is compliant behavior, assuming that the output buffer provided to the function has size greater than zero. The MSFT function does print the null terminator.
Take the example:
printf_run(NULL, "%.*s", 0, "Text string 123")
With the current test code, this passes.
Format: "%.*s"
Params: "i, "Text string 123""
Result VSprintf: ""
Length VSprintf: 0
Result LwPRINTF: ""
Length LwPRINTF: 0
Test result: Pass
However, if the buffers used are initialized to 0xFF rather than to zero as proposed below, lwsnprintf()
will fail because of this.
/* Temporary strings array */
char b1[255] = { 0 }, b2[255] = { 0 };
int l1, l2;
memset(b1, 0xFFFFFFFF, sizeof(b1)-1);
memset(b2, 0xFFFFFFFF, sizeof(b2)-1);
Format: "%.3s"
Params: """"
Result VSprintf: ""
Length VSprintf: 0
Result LwPRINTF: ""
Length LwPRINTF: 0
Test result: Fail
%g does not round the values 5307575.0f or 1104515.0f correctly.
Result 5.30757e+6 but should be 5.30758e+6
Hello Tilen! I use your LwPRINTF v1.0.1
release version of library in my project based on FreeRTOS. The library's custom opts is
#define LWPRINFTF_CFG_OS 1
#define LWPRINTF_CFG_SUPPORT_TYPE_POINTER 0
#define LWPRINTF_CFG_SUPPORT_TYPE_ENGINEERING 0
I have initialized the library with a custom instance
void init_fcn(void)
{
...
lwprintf_init_ex(&logs, lwprintf_logs_out);
...
}
int lwprintf_logs_out(int ch, lwprintf_t* p)
{
uint8_t c = (uint8_t)ch;
/* Don't print zero */
if (c == '\0') {
return ch;
}
LL_USART_TransmitData8(UART4, (uint8_t)ch);
while (!LL_USART_IsActiveFlag_TXE(UART4)) {}
return ch;
}
and implemented the output function as follows
void PrintLogString(uint8_t crlf, const char *str, ...)
{
va_list args;
va_start(args, str);
lwprintf_vprintf_ex(&logs, str, args);
va_end(args);
if (crlf)
lwprintf_printf_ex(&logs, "\r\n");
}
Then in the application I used the implemented function
...
float batt_volt;
...
PrintLogString(1, "Inverter batt %.2f", batt_volt);
...
For example, for the batt_volt
variable, which value was 53.20
, the PrintLogString()
function prints the follow message in PuTTY terminal
Inverter batt 5320
instead of
Inverter batt 53.20
I have not studied the implementation of the library, but it seems to me that the problem arises due to setting the limit on the number of digits after the point (%.2f
). But I do not exclude that I could be wrong somewhere. Please consider this case.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.