--- /dev/null
+/* $OpenBSD: test_xextendf.c,v 1.1 2025/09/02 11:04:58 djm Exp $ */
+/*
+ * Regress test for misc xextendf() function.
+ *
+ * Placed in the public domain.
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+
+#include "../test_helper/test_helper.h"
+
+#include "log.h"
+#include "misc.h"
+#include "xmalloc.h"
+
+void test_xextendf(void);
+
+void
+test_xextendf(void)
+{
+ char *s = NULL;
+
+ TEST_START("xextendf NULL string");
+ xextendf(&s, ",", "hello");
+ ASSERT_STRING_EQ(s, "hello");
+ free(s);
+ s = NULL;
+ TEST_DONE();
+
+ TEST_START("xextendf empty string");
+ s = xstrdup("");
+ xextendf(&s, ",", "world");
+ ASSERT_STRING_EQ(s, "world");
+ free(s);
+ s = NULL;
+ TEST_DONE();
+
+ TEST_START("xextendf append to string");
+ s = xstrdup("foo");
+ xextendf(&s, ",", "bar");
+ ASSERT_STRING_EQ(s, "foo,bar");
+ free(s);
+ s = NULL;
+ TEST_DONE();
+
+ TEST_START("xextendf append with NULL separator");
+ s = xstrdup("foo");
+ xextendf(&s, NULL, "bar");
+ ASSERT_STRING_EQ(s, "foobar");
+ free(s);
+ s = NULL;
+ TEST_DONE();
+
+ TEST_START("xextendf append with empty separator");
+ s = xstrdup("foo");
+ xextendf(&s, "", "bar");
+ ASSERT_STRING_EQ(s, "foobar");
+ free(s);
+ s = NULL;
+ TEST_DONE();
+
+ TEST_START("xextendf with format string");
+ s = xstrdup("start");
+ xextendf(&s, ":", "s=%s,d=%d", "string", 123);
+ ASSERT_STRING_EQ(s, "start:s=string,d=123");
+ free(s);
+ s = NULL;
+ TEST_DONE();
+
+ TEST_START("xextendf multiple appends");
+ s = NULL;
+ xextendf(&s, ",", "one");
+ ASSERT_STRING_EQ(s, "one");
+ xextendf(&s, ",", "two");
+ ASSERT_STRING_EQ(s, "one,two");
+ xextendf(&s, ":", "three=%d", 3);
+ ASSERT_STRING_EQ(s, "one,two:three=3");
+ xextendf(&s, NULL, "four");
+ ASSERT_STRING_EQ(s, "one,two:three=3four");
+ free(s);
+ s = NULL;
+ TEST_DONE();
+}