diff --git a/src/util/strings.c b/src/util/strings.c index e469c2a18..df15ab588 100644 --- a/src/util/strings.c +++ b/src/util/strings.c @@ -256,6 +256,26 @@ char *str_strdup(const char *s) { #endif } +void sbs_printf(struct sbstring *sbs, const char *format, ...) +{ + size_t size = sbs->size - (sbs->end - sbs->begin); + + if (size > 0) { + va_list argp; + va_start(argp, format); + int bytes = vsnprintf(sbs->end, size, format, argp); + if (bytes > 0) { + if ((size_t)bytes >= size) { + bytes = size - 1; + /* terminate truncated output */ + sbs->end[bytes] = '\0'; + } + sbs->end += bytes; + } + va_end(argp); + } +} + void sbs_init(struct sbstring *sbs, char *buffer, size_t size) { assert(sbs); diff --git a/src/util/strings.h b/src/util/strings.h index 29ca11ef7..acce3767b 100644 --- a/src/util/strings.h +++ b/src/util/strings.h @@ -48,6 +48,7 @@ extern "C" { char *end; } sbstring; + void sbs_printf(struct sbstring *sbs, const char *format, ...); void sbs_init(struct sbstring *sbs, char *buffer, size_t size); void sbs_adopt(struct sbstring *sbs, char *buffer, size_t size); void sbs_strcat(struct sbstring *sbs, const char *str); diff --git a/src/util/strings.test.c b/src/util/strings.test.c index b9ab8c729..399f6a4dd 100644 --- a/src/util/strings.test.c +++ b/src/util/strings.test.c @@ -234,6 +234,31 @@ static void test_sbs_substr(CuTest * tc) CuAssertIntEquals(tc, 'A', buffer[9]); } +static void test_sbs_printf(CuTest * tc) +{ + char buffer[10]; + sbstring sbs; + + sbs_init(&sbs, buffer, sizeof(buffer)); + sbs_printf(&sbs, "%s %d", "1234", 5678); + CuAssertStrEquals(tc, "1234 5678", buffer); + + sbs_init(&sbs, buffer, sizeof(buffer)); + sbs_printf(&sbs, "%s", "12345"); + sbs_printf(&sbs, "%d", 6789); + CuAssertStrEquals(tc, "123456789", buffer); + + sbs_init(&sbs, buffer, sizeof(buffer)); + sbs_printf(&sbs, "%s", "1234567890"); + CuAssertStrEquals(tc, "123456789", buffer); + + sbs_init(&sbs, buffer, sizeof(buffer)); + sbs_printf(&sbs, "%d", 123456789); + CuAssertStrEquals(tc, "123456789", buffer); + sbs_printf(&sbs, "%s", "Hodor"); + CuAssertStrEquals(tc, "123456789", buffer); +} + CuSuite *get_strings_suite(void) { CuSuite *suite = CuSuiteNew(); @@ -249,5 +274,6 @@ CuSuite *get_strings_suite(void) SUITE_ADD_TEST(suite, test_sbstring); SUITE_ADD_TEST(suite, test_sbs_strcat); SUITE_ADD_TEST(suite, test_sbs_substr); + SUITE_ADD_TEST(suite, test_sbs_printf); return suite; }