From d8e5bc07aa4a6884ed160739a8420baca0c5ac4f Mon Sep 17 00:00:00 2001 From: Peter Oberparleiter Date: Mon, 5 Feb 2024 14:40:25 +0100 Subject: [PATCH] libutil: add function to concatenate a format string in place MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add function util_concatf() that appends the result of a format string expansion to the end of an existing string while taking care of the required memory allocations. Usage example: char *str = NULL; util_concatf(&str, "list:"); for (int i = 1; i <= 3; i++) util_concatf(&str, "%spart%d", (i > 1 ? "," : ""), i); printf("%s\n", str); /* list:part1,part2,part3 */ Reviewed-by: Jan Höppner Signed-off-by: Peter Oberparleiter Signed-off-by: Steffen Eiden --- include/lib/util_libc.h | 1 + libutil/util_libc.c | 20 ++++++++++++++++++++ libutil/util_libc_example.c | 8 ++++++++ 3 files changed, 29 insertions(+) diff --git a/include/lib/util_libc.h b/include/lib/util_libc.h index 394aca1a..6b77876e 100644 --- a/include/lib/util_libc.h +++ b/include/lib/util_libc.h @@ -127,6 +127,7 @@ do { \ int __util_vsprintf(const char *func, const char *file, int line, char *str, const char *fmt, va_list ap); char *util_strcat_realloc(char *str1, const char *str2); +void util_concatf(char **str1, const char *fmt, ...); void util_str_toupper(char *str); char *util_strstrip(char *s); diff --git a/libutil/util_libc.c b/libutil/util_libc.c index 8ea421b4..8ffd1116 100644 --- a/libutil/util_libc.c +++ b/libutil/util_libc.c @@ -139,6 +139,26 @@ char *util_strcat_realloc(char *str1, const char *str2) return buf; } +/** + * Concatenate a string with the result of a format string expansion + * + * @param[in, out] str1 Pointer to pointer to first string + * @param[in] fmt Format string for generation of the second string + * @param[in] ... Parameters for format string + */ +void util_concatf(char **str1, const char *fmt, ...) +{ + va_list args; + char *str2; + + va_start(args, fmt); + util_vasprintf(&str2, fmt, args); + va_end(args); + + *str1 = util_strcat_realloc(*str1, str2); + free(str2); +} + /** * Convert string to uppercase * diff --git a/libutil/util_libc_example.c b/libutil/util_libc_example.c index 3789c3a6..6c7fbd6e 100644 --- a/libutil/util_libc_example.c +++ b/libutil/util_libc_example.c @@ -40,6 +40,14 @@ int main(void) fprintf(stderr, "result = \"%s\"\n", str); free(str); + /* Use util_concatf() for string concatenation */ + fprintf(stderr, "Try to concatenate \"list\" plus comma-separated list of numbers 1 to 3: "); + str = NULL; + util_concatf(&str, "list:"); + for (int i = 1; i <= 3; i++) + util_concatf(&str, "%s%d", (i > 1 ? "," : ""), i); + fprintf(stderr, "result = %s\n", str); /* list:part1,part2,part3 */ + /* One byte allocation should work */ fprintf(stderr, "Try to allocate 1 byte: "); ptr = util_malloc(1);