-
Notifications
You must be signed in to change notification settings - Fork 474
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Preview of changes, for discussion #56
base: master
Are you sure you want to change the base?
Conversation
This is work in progress, needs cleanup
Hello @ledvinap , |
@mpaland : Hi! I'll prepare some parts as separate PRs, fixing bugs and sometimes improving existing code. Then it can be decided about more philosophical changes ... Can you please overview list of changes and do a quick comment about them (OK/don't like/not sure/needs further work)? |
When I can expect to pull these commits into main branch and have new release? |
This is work in progress, needs BIG cleanup. It's here only for discussion
Rough overview of changes:
use
struct printf_state
to pass around % specifier info.Mostly it seems to work fine and reduces register pressure, but sometimes it's a bit cumbersome. I'll look into it further.
use
struct out_base
to handleout
callback.Personally I prefer this way of handling callbacks - parameters can be easily added,
out_base
can be included in any other object (for example serial driver struct) etc.In case of out function it is a bit overkill - it is undesirable to include
printf_state
inout_base
(a lot of compiler optimizations would be disabled) and it is possible to store both function pointer and argument in state.change
idx
to beuintptr_t
and allow starting from any value.idx
is incremented on each output, so it is desirable to have it in register. Withuintptr_t
it is possible to store output buffer pointer directly, saving some instruction, with almost zero penalty (for example it is impossible to write last byte of memory)test
idx < maxidx
before output function callbetter caching of values in register, simpler output functions
add FLAGS_ZERO
I hope it's consistent with rest of flags
unify _ntoa_long and _ntoa_long_long using macro (only parameter type differs)
Removes code duplication at cost of more complicated debugging
implement (almost?) correct rounding for
%f
fmsub
is relatively simple, some FPUs (Cortex-M4) support equivalent instructionfix
%g
trailing zeroesThe implementation isn't as elegant as I'd like, it may be conditional or maybe there is better way to rewrite it
I encountered interesting unspecified case:
(unsigned int)-INT_MIN
(and(unsigned int)(0 - value)
in current code) is causing integer overflow, which is unspecified behavior in C standard. gcc was able to use this to sign-extend long first, producing incorrect result forprintf("%d", INT_MIN);
move zero-termination from
_vsnprintf
tosnprintf
fixes
printf("%c", 0);
, is cleaner (only string needs termination), simplifies code a littleuintptr_t idx
removes need to special-casesprintf(NULL, ...)
case, just pass0
as limitadded new test cases from other sources (mainly libsanity), discovering some bugs (mostly opened as issues).
modified tests are just temporary hack to get testing quickly, I'll clean it up