diff --git a/lib/string/sprintf.c b/lib/string/sprintf.c index 5b421ad0..cf3c210b 100644 --- a/lib/string/sprintf.c +++ b/lib/string/sprintf.c @@ -17,3 +17,8 @@ extern inline int xasprintf(char **restrict s, const char *restrict fmt, ...); extern inline int xvasprintf(char **restrict s, const char *restrict fmt, va_list ap); + +extern inline int snprintf_(char *restrict s, size_t size, + const char *restrict fmt, ...); +extern inline int vsnprintf_(char *restrict s, size_t size, + const char *restrict fmt, va_list ap); diff --git a/lib/string/sprintf.h b/lib/string/sprintf.h index 33e0bc2d..74853694 100644 --- a/lib/string/sprintf.h +++ b/lib/string/sprintf.h @@ -20,14 +20,7 @@ #define SNPRINTF(s, fmt, ...) \ -({ \ - size_t sz_, len_; \ - \ - sz_ = NITEMS(s); \ - len_ = snprintf(s, sz_, fmt __VA_OPT__(,) __VA_ARGS__); \ - \ - (len_ >= sz_) ? -1 : len_; \ -}) + snprintf_(s, NITEMS(s), fmt __VA_OPT__(,) __VA_ARGS__) format_attr(printf, 2, 3) @@ -35,6 +28,13 @@ inline int xasprintf(char **restrict s, const char *restrict fmt, ...); format_attr(printf, 2, 0) inline int xvasprintf(char **restrict s, const char *restrict fmt, va_list ap); +format_attr(printf, 3, 4) +inline int snprintf_(char *restrict s, size_t size, const char *restrict fmt, + ...); +format_attr(printf, 3, 0) +inline int vsnprintf_(char *restrict s, size_t size, const char *restrict fmt, + va_list ap); + inline int xasprintf(char **restrict s, const char *restrict fmt, ...) @@ -65,4 +65,33 @@ xvasprintf(char **restrict s, const char *restrict fmt, va_list ap) } +inline int +snprintf_(char *restrict s, size_t size, const char *restrict fmt, ...) +{ + int len; + va_list ap; + + va_start(ap, fmt); + len = vsnprintf_(s, size, fmt, ap); + va_end(ap); + + return len; +} + + +inline int +vsnprintf_(char *restrict s, size_t size, const char *restrict fmt, va_list ap) +{ + int len; + + len = vsnprintf(s, size, fmt, ap); + if (len == -1) + return -1; + if ((size_t) len >= size) + return -1; + + return len; +} + + #endif // include guard