libutil: add function to concatenate a format string in place

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 <hoeppner@linux.ibm.com>
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
This commit is contained in:
Peter Oberparleiter
2024-02-05 14:40:25 +01:00
committed by Steffen Eiden
parent 3b26f79143
commit d8e5bc07aa
3 changed files with 29 additions and 0 deletions

View File

@@ -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);

View File

@@ -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
*

View File

@@ -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);