From 680120a1d2d8f9e0014e242f011c23a72cce0594 Mon Sep 17 00:00:00 2001 From: Christian Spielberger Date: Thu, 20 Nov 2025 10:05:00 +0100 Subject: [PATCH 1/2] fmt: add pl_alloc_dup() A struct pl allocation function that duplicates pl and its content. The pl destructor is used --- include/re_fmt.h | 1 + src/fmt/pl.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/include/re_fmt.h b/include/re_fmt.h index 506b12b27..3d2607d86 100644 --- a/include/re_fmt.h +++ b/include/re_fmt.h @@ -30,6 +30,7 @@ struct pl { extern const struct pl pl_null; struct pl *pl_alloc_str(const char *str); +struct pl *pl_alloc_dup(const struct pl *src); void pl_set_str(struct pl *pl, const char *str); void pl_set_mbuf(struct pl *pl, const struct mbuf *mb); int32_t pl_i32(const struct pl *pl); diff --git a/src/fmt/pl.c b/src/fmt/pl.c index 481a8cd8b..a34eff2fa 100644 --- a/src/fmt/pl.c +++ b/src/fmt/pl.c @@ -63,6 +63,41 @@ struct pl *pl_alloc_str(const char *str) } +/** + * Duplicate a pointer-length object + * + * @param src Pointer-length object to duplicate + * + * @return Allocated Pointer-length object or NULL + */ +struct pl *pl_alloc_dup(const struct pl *src) +{ + struct pl *pl; + + if (!src) + return NULL; + + size_t sz = src->l; + + pl = mem_zalloc(sizeof(struct pl), pl_alloc_destruct); + if (!pl) + return NULL; + + if (!pl_isset(src)) + return pl; + + pl->p = mem_alloc(sz, NULL); + if (!pl->p) { + mem_deref(pl); + return NULL; + } + + memcpy((void *)pl->p, src->p, sz); + pl->l = sz; + return pl; +} + + /** * Initialise a pointer-length object from a NULL-terminated string * From e8332234c2716e3477df6faf6573ca287b5220c7 Mon Sep 17 00:00:00 2001 From: Christian Spielberger Date: Thu, 20 Nov 2025 10:22:15 +0100 Subject: [PATCH 2/2] test: add test_fmt_pl_alloc_dup --- test/fmt.c | 21 +++++++++++++++++++++ test/test.c | 1 + test/test.h | 1 + 3 files changed, 23 insertions(+) diff --git a/test/fmt.c b/test/fmt.c index 1a72d00cc..1eec25d3e 100644 --- a/test/fmt.c +++ b/test/fmt.c @@ -149,6 +149,27 @@ int test_fmt_pl(void) } +int test_fmt_pl_alloc_dup(void) +{ + int err = 0; + const struct pl pl0 = PL("rAtTaReI"); + + struct pl *pl = pl_alloc_dup(&pl0); + if (!pl) + return ENOMEM; + + TEST_EQUALS(pl0.l, pl->l); + TEST_MEMCMP(pl0.p, pl0.l, pl->p, pl->l); + err = pl_cmp(&pl0, pl); + TEST_ERR(err); + +out: + mem_deref(pl); + + return err; +} + + int test_fmt_pl_alloc_str(void) { int err = 0; diff --git a/test/test.c b/test/test.c index 724ef88ab..f55982c23 100644 --- a/test/test.c +++ b/test/test.c @@ -84,6 +84,7 @@ static const struct test tests[] = { TEST(test_fmt_human_time), TEST(test_fmt_param), TEST(test_fmt_pl), + TEST(test_fmt_pl_alloc_dup), TEST(test_fmt_pl_alloc_str), TEST(test_fmt_pl_float), TEST(test_fmt_pl_i32), diff --git a/test/test.h b/test/test.h index 222056b69..952ba80f0 100644 --- a/test/test.h +++ b/test/test.h @@ -187,6 +187,7 @@ int test_fmt_hexdump(void); int test_fmt_human_time(void); int test_fmt_param(void); int test_fmt_pl(void); +int test_fmt_pl_alloc_dup(void); int test_fmt_pl_alloc_str(void); int test_fmt_pl_float(void); int test_fmt_pl_i32(void);