-
-
Notifications
You must be signed in to change notification settings - Fork 345
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
fix m_vsnprintf return value #1077
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding a lambda to take care of size every byte is a great idea. But i don' t like use of gotos especially copy label that jumps cases it's hard to follow imho. No chance of loops instead of gotos?
Well, C is not my primary language, but I will try to reduce the number of gotos ;-) |
s = dtostrf_p(va_arg(args, double), width, precision, tempNum, pad); | ||
break; | ||
|
||
case 'o': |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would rewrite as
case 'o':
case 'x':
case 'X':
if('o' == f)
base=8;
else
base=16;
case 'u':
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are very strict regarding gotos ;-)
I changed it a bit to get rid of the fall-through, too.
Have no other remarks. If "unit tests" in basic_string example work ok it's fine with me. Thanks again! |
Sming/system/m_printf.cpp
Outdated
static void defaultPrintChar(uart_t *uart, char c) { | ||
return uart_tx_one_char(c); | ||
return uart_tx_one_char(c); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The are multiple white-space changes that are not related to this PR. Please, revert them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, if this is a FAQ - is there a guide regarding source code formatting for Sming (or even better, a command line tool for windows to do the correct formatting)?
I tried to follow the rule 38 here: Special characters like TAB and page break must be avoided.
These characters are bound to cause problem for editors, printers, terminal emulators or debuggers when used in a multi-programmer, multi-platform environment.
That's why I converted all tabs to space before committing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's why I converted all tabs to space before committing.
Changing of formatting and coding style can happen in another PR. This PR is only related to m_vsnprintf
changes.
There is no longer a need for separate *_P methods, this should make it easier to solve the conflicts created by the macro printf_P in FakePgmSpace.h. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please, move the PROGMEM changes to another PR. This one should be only related to return value of m_vsnprinf
. If we have two PRs it will be easier to test and easier to find the cause of the issues, if any.
Sming/system/m_printf.cpp
Outdated
// need to retry if size is not big enough | ||
while (1) { | ||
char buffer[size + 1]; | ||
auto sz = m_vsnprintf(buffer, sizeof(buffer), fmt, va); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please, change auto
to size_t
.
Sming/system/m_printf.cpp
Outdated
n++; | ||
p++; | ||
const char *p = buffer; | ||
while (char c = *p++) cbc_printchar(cbc_printchar_uart, c); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Format the while with opening and closing curly braces.
while (char c = *p++) {
cbc_printchar(cbc_printchar_uart, c);
}
Sming/system/m_printf.cpp
Outdated
if (++size < maxLen) *buf++ = c; | ||
}; | ||
|
||
while ( char f = pgm_read_byte(fmt) ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you read every byte using pgm_read_byte
that will cause overhead. Is that really needed in a very core component? What are the advantages?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You a right, this will make every call to *printf a tiny bit slower. The code size is almost identical. I see the following advantages:
- it will reduce total flash size and complexity as a many additional methods are no longer needed
- all classes and methods using m_printf will benefit immediately
- life will be much easier for users as they do not need to care which method to call and which format specifier to use
- format strings should go to flashmem anyway to reduce ram size
- it is faster and uses less memory than the existing implementation for format strings in flashmem
- printf is mostly used for serial output where execution speed does not matter that much
- for time critical operations direct c string manipulation should be used instead of the printf functions
IMHO the main advantage is that it eliminated a major pitfall for users working with progmem.
I'm quite new to GitHub - how can I create a PR that depends on another PR? |
Create a branch for PR 1. Work on it until you are ready. Then create another branch for PR1 that is based on PR1.
If there are changes in PR1 you can keep PR2 up to date using the following commands:
That should be it. |
Changed the logic of m_vsnprintf() to return the correct value if the buffer is not large enough (see #1066 ). The overflow guard is no longer required. Unfortunately this required some changes to the existing logic, I hope I did not break anything. Here is a minimal test application: