Generates the formatted version of the input and appends it to an existing dynamically allocated string, growing it as necessary using realloc().
Signed-off-by: Tobias Waldekranz <tob...@waldekranz.com> --- include/stdio.h | 10 ++++++++++ include/xfuncs.h | 4 ++++ lib/vsprintf.c | 35 +++++++++++++++++++++++++++++++++++ lib/xfuncs.c | 24 ++++++++++++++++++++++++ 4 files changed, 73 insertions(+) diff --git a/include/stdio.h b/include/stdio.h index cecb97ea1a..f3e430b3b3 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -21,6 +21,8 @@ int vscnprintf(char *buf, size_t size, const char *fmt, va_list args); int asprintf(char **strp, const char *fmt, ...) __printf(2, 3); char *bvasprintf(const char *fmt, va_list ap); int vasprintf(char **strp, const char *fmt, va_list ap); +int vrasprintf(char **strp, const char *fmt, va_list ap); +int rasprintf(char **strp, const char *fmt, ...) __printf(2, 3); #else static inline __printf(2, 3) int asprintf(char **strp, const char *fmt, ...) { @@ -34,6 +36,14 @@ static inline int vasprintf(char **strp, const char *fmt, va_list ap) { return -1; } +static inline int vrasprintf(char **strp, const char *fmt, va_list ap) +{ + return -1; +} +static inline __printf(2, 3) int rasprintf(char **strp, const char *fmt, ...) +{ + return -1; +} #endif #define basprintf xasprintf diff --git a/include/xfuncs.h b/include/xfuncs.h index eb4050f489..2cc2048bd5 100644 --- a/include/xfuncs.h +++ b/include/xfuncs.h @@ -19,6 +19,8 @@ void* xmemalign(size_t alignment, size_t bytes) __xalloc_size(2); void* xmemdup(const void *orig, size_t size) __returns_nonnull; char *xasprintf(const char *fmt, ...) __printf(1, 2) __returns_nonnull; char *xvasprintf(const char *fmt, va_list ap) __returns_nonnull; +char *xvrasprintf(char *str, const char *fmt, va_list ap) __returns_nonnull; +char *xrasprintf(char *str, const char *fmt, ...) __printf(2, 3) __returns_nonnull; wchar_t *xstrdup_wchar(const wchar_t *src); wchar_t *xstrdup_char_to_wchar(const char *src); @@ -35,6 +37,8 @@ static inline void* xmemalign(size_t alignment, size_t bytes) { BUG(); } static inline void* xmemdup(const void *orig, size_t size) { BUG(); } static inline __printf(1, 2) char *xasprintf(const char *fmt, ...) { BUG(); } static inline char *xvasprintf(const char *fmt, va_list ap) { BUG(); } +static inline char *xvrasprintf(char *str, const char *fmt, va_list ap) { BUG(); } +static inline __printf(2, 3) char *xrasprintf(char *str, const char *fmt, ...) { BUG(); } static inline wchar_t *xstrdup_wchar(const wchar_t *src) { BUG(); } static inline wchar_t *xstrdup_char_to_wchar(const char *src) { BUG(); } diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 409a8f02de..c7295c1067 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -1005,3 +1005,38 @@ int asprintf(char **strp, const char *fmt, ...) return len; } EXPORT_SYMBOL(asprintf); + +int vrasprintf(char **strp, const char *fmt, va_list ap) +{ + int fmtlen, inlen = *strp ? strlen(*strp) : 0; + va_list aq; + char *p; + + va_copy(aq, ap); + fmtlen = vsnprintf(NULL, 0, fmt, aq); + va_end(aq); + + p = realloc(*strp, inlen + fmtlen + 1); + if (!p) + return -1; + + vsnprintf(&p[inlen], fmtlen + 1, fmt, ap); + + *strp = p; + + return inlen + fmtlen; +} +EXPORT_SYMBOL(vrasprintf); + +int rasprintf(char **strp, const char *fmt, ...) +{ + va_list ap; + int len; + + va_start(ap, fmt); + len = vrasprintf(strp, fmt, ap); + va_end(ap); + + return len; +} +EXPORT_SYMBOL(rasprintf); diff --git a/lib/xfuncs.c b/lib/xfuncs.c index d4beecddf5..4c69451305 100644 --- a/lib/xfuncs.c +++ b/lib/xfuncs.c @@ -144,6 +144,30 @@ char *xasprintf(const char *fmt, ...) } EXPORT_SYMBOL(xasprintf); +char *xvrasprintf(char *str, const char *fmt, va_list ap) +{ + int len; + + len = vrasprintf(&str, fmt, ap); + if (len < 0) + enomem_panic(0); + + return str; +} +EXPORT_SYMBOL(xvrasprintf); + +char *xrasprintf(char *str, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + str = xvrasprintf(str, fmt, ap); + va_end(ap); + + return str; +} +EXPORT_SYMBOL(xrasprintf); + wchar_t *xstrdup_wchar(const wchar_t *s) { wchar_t *p; -- 2.43.0