From 1ef0fbaafcb5378525376fd5961bf72918846f4e Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Fri, 13 Dec 2024 19:19:02 +0000 Subject: [PATCH] Add helper function dupwcscat(). The wide-string version of dupcat(), with an identical wrapper macro to automatically append a correctly typed NULL. --- misc.h | 2 ++ utils/CMakeLists.txt | 1 + utils/dupwcscat.c | 48 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+) create mode 100644 utils/dupwcscat.c diff --git a/misc.h b/misc.h index 7d94e7e6..c64eb01b 100644 --- a/misc.h +++ b/misc.h @@ -29,6 +29,8 @@ char *dupstr(const char *s); wchar_t *dupwcs(const wchar_t *s); char *dupcat_fn(const char *s1, ...); #define dupcat(...) dupcat_fn(__VA_ARGS__, (const char *)NULL) +wchar_t *dupwcscat_fn(const wchar_t *s1, ...); +#define dupwcscat(...) dupwcscat_fn(__VA_ARGS__, (const wchar_t *)NULL) char *dupprintf(const char *fmt, ...) PRINTF_LIKE(1, 2); char *dupvprintf(const char *fmt, va_list ap); void burnstr(char *string); diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt index 7accda5f..2581559e 100644 --- a/utils/CMakeLists.txt +++ b/utils/CMakeLists.txt @@ -29,6 +29,7 @@ add_sources_from_current_dir(utils dupprintf.c dupstr.c dupwcs.c + dupwcscat.c dup_mb_to_wc.c dup_wc_to_mb.c encode_utf8.c diff --git a/utils/dupwcscat.c b/utils/dupwcscat.c new file mode 100644 index 00000000..4b9ed5a9 --- /dev/null +++ b/utils/dupwcscat.c @@ -0,0 +1,48 @@ +/* + * Implementation function behind dupwcscat() in misc.h. + * + * This function is called with an arbitrary number of 'const wchar_t + * *' parameters, of which the last one is a null pointer. The wrapper + * macro puts on the null pointer itself, so normally callers don't + * have to. + */ + +#include +#include + +#include "defs.h" +#include "misc.h" + +wchar_t *dupwcscat_fn(const wchar_t *s1, ...) +{ + int len; + wchar_t *p, *q, *sn; + va_list ap; + + len = wcslen(s1); + va_start(ap, s1); + while (1) { + sn = va_arg(ap, wchar_t *); + if (!sn) + break; + len += wcslen(sn); + } + va_end(ap); + + p = snewn(len + 1, wchar_t); + wcscpy(p, s1); + q = p + wcslen(p); + + va_start(ap, s1); + while (1) { + sn = va_arg(ap, wchar_t *); + if (!sn) + break; + wcscpy(q, sn); + q += wcslen(q); + } + va_end(ap); + + return p; +} +