-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
sys/string_utils: add string_writer helper #20843
Conversation
That API indeed disarms the usual footguns :) I wonder if there is some BSD / whatever API already that we could steal? |
815f30d
to
b2b49d3
Compare
b2b49d3
to
e52ffe9
Compare
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.
All in all looks good. Some nits, some ideas.
You mentioned that this is often done manually in RIOT, could you also replace such instances with this helper right away?
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.
Great improvements.
Squash & Ci? |
6eea402
to
62e0d3f
Compare
ce88749
to
0fe3ac4
Compare
sys/include/string_utils.h
Outdated
* @return number of bytes written on success | ||
* -E2BIG if the string was truncated | ||
*/ | ||
int swprintf(string_writer_t *sw, const char *restrict format, ...); |
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 can add
__attribute__ ((format (printf, 2, 3)))
to enable static printf-like compiler checks for the format string and arguments, see https://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Function-Attributes.html.
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.
GCC doesn't like it if the variable args are empty
/home/benpicco/dev/RIOT/tests/unittests/tests-libc/tests-libc.c: In function ‘test_libc_swprintf’:
/home/benpicco/dev/RIOT/tests/unittests/tests-libc/tests-libc.c:42:5: error: format not a string literal and no format arguments [-Werror=format-security]
res = swprintf(&sw, "Hello World!");
^~~
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.
Odd, I tried now and works for me:
__attribute__ ((format (printf, 2, 3)))
int __swprintf(string_writer_t *sw, FLASH_ATTR const char *restrict format, ...);
Then:
res = swprintf(&sw, "Hello World!");
works just fine, while:
res = swprintf(&sw, "Hello World%s!");
results in
/home/mihai.renea@ml-pa.loc/proj/RIOT/tests/unittests/tests-libc/tests-libc.c: In function ‘test_libc_s
wprintf’:
/home/mihai.renea@ml-pa.loc/proj/RIOT/tests/unittests/tests-libc/tests-libc.c:42:38: error: format ‘%s’
expects a matching ‘char *’ argument [-Werror=format=]
42 | res = swprintf(&sw, "Hello World%s!");
| ~^
| |
| char *
Which compiler version are you using? Mine:
$ arm-none-eabi-gcc --version
arm-none-eabi-gcc (15:10.3-2021.07-4) 10.3.1 20210621 (release)
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.
This is only happens with avr-gcc (GCC) 7.3.0
/home/benpicco/dev/RIOT/tests/unittests/tests-libc/tests-libc.c: In function ‘test_libc_swprintf’:
/home/benpicco/dev/RIOT/tests/unittests/tests-libc/tests-libc.c:42:5: error: format not a string literal and no format arguments [-Werror=format-security]
res = swprintf(&sw, "Hello World!");
^~~
/home/benpicco/dev/RIOT/tests/unittests/tests-libc/tests-libc.c:49:5: error: format not a string literal and no format arguments [-Werror=format-security]
res = swprintf(&sw, "0123456789");
^~~
/home/benpicco/dev/RIOT/tests/unittests/tests-libc/tests-libc.c:54:5: error: format not a string literal and no format arguments [-Werror=format-security]
res = swprintf(&sw, "01234567891");
^~~
/home/benpicco/dev/RIOT/tests/unittests/tests-libc/tests-libc.c:59:5: error: format not a string literal and no format arguments [-Werror=format-security]
res = swprintf(&sw, "###");
^~~
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.
Ah I think it's because the TO_FLASH()
is interfering
096f71f
to
2041c82
Compare
2041c82
to
2bf4c71
Compare
9623e4f
to
40b1188
Compare
40b1188
to
db6196e
Compare
Contribution description
Assembling a string through multiple writes if often open-coded like this
This is error prone (the above example foregoes any error handling) and ugly.
This introduces a small helper function to achieve the same in a much more convenient fasion:
Testing procedure
A new unit test has been added.
Issues/PRs references