From 14ce34d755f828feb89381777a9170d5839cca61 Mon Sep 17 00:00:00 2001 From: Lucas De Marchi Date: Wed, 13 Nov 2024 23:02:07 -0600 Subject: [PATCH] strbuf: Add strbuf_shrink_to() Useful when working with paths on a loop and resetting to a base path component on every loop iteration. Signed-off-by: Lucas De Marchi Reviewed-by: Emil Velikov Link: https://github.com/kmod-project/kmod/pull/239 --- shared/strbuf.c | 6 ++++++ shared/strbuf.h | 5 +++++ testsuite/test-strbuf.c | 31 +++++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+) diff --git a/shared/strbuf.c b/shared/strbuf.c index 6a4c8d93..dad5da52 100644 --- a/shared/strbuf.c +++ b/shared/strbuf.c @@ -121,6 +121,12 @@ void strbuf_popchars(struct strbuf *buf, size_t n) buf->used -= n; } +void strbuf_shrink_to(struct strbuf *buf, size_t sz) +{ + assert(buf->used >= sz); + buf->used = sz; +} + void strbuf_clear(struct strbuf *buf) { buf->used = 0; diff --git a/shared/strbuf.h b/shared/strbuf.h index 96e6ed24..02ec8955 100644 --- a/shared/strbuf.h +++ b/shared/strbuf.h @@ -102,6 +102,11 @@ void strbuf_popchar(struct strbuf *buf); */ void strbuf_popchars(struct strbuf *buf, size_t n); +/* + * Shrink buffer to the final size @sz, which must be less or equal the current size. + */ +void strbuf_shrink_to(struct strbuf *buf, size_t sz); + /* * Return number of used chars. This may different than calling strlen() in a C string * since '\0' is considered a valid char - this only keeps track of how many slots are diff --git a/testsuite/test-strbuf.c b/testsuite/test-strbuf.c index 859f9b26..e77fbdb9 100644 --- a/testsuite/test-strbuf.c +++ b/testsuite/test-strbuf.c @@ -227,4 +227,35 @@ static int test_strbuf_used(const struct test *t) } DEFINE_TEST(test_strbuf_used, .description = "test strbuf_used"); +static int test_strbuf_shrink_to(const struct test *t) +{ + _cleanup_strbuf_ struct strbuf buf; + + strbuf_init(&buf); + strbuf_shrink_to(&buf, 0); + assert_return(strbuf_used(&buf) == 0, EXIT_FAILURE); + + strbuf_pushchars(&buf, TEXT); + strbuf_shrink_to(&buf, strlen(TEXT) - 1); + assert_return(strbuf_used(&buf) == strlen(TEXT) - 1, EXIT_FAILURE); + + return 0; +} +DEFINE_TEST(test_strbuf_shrink_to, .description = "test strbuf_shrink_to"); + +static int xfail_strbuf_shrink_to(const struct test *t) +{ + _cleanup_strbuf_ struct strbuf buf; + + strbuf_init(&buf); + strbuf_pushchar(&buf, '/'); + + /* This should crash on assert */ + strbuf_shrink_to(&buf, 2); + + return 0; +} +DEFINE_TEST(xfail_strbuf_shrink_to, .description = "xfail strbuf_shrink_to", + .expected_fail = true); + TESTSUITE_MAIN(); -- 2.47.2