From 59403690ca6253835ce7577f3eee7d04893b6950 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=81lvaro=20Herrera?= <alvherre@kurilemu.de>
Date: Fri, 14 Nov 2025 16:25:46 +0100
Subject: [PATCH] Split out entry names in pg_resetwal

---
 src/bin/pg_resetwal/entries.h     |  62 ++++++++++++++
 src/bin/pg_resetwal/nls.mk        |   4 +-
 src/bin/pg_resetwal/pg_resetwal.c | 132 ++++++++++++++++--------------
 3 files changed, 134 insertions(+), 64 deletions(-)
 create mode 100644 src/bin/pg_resetwal/entries.h

diff --git a/src/bin/pg_resetwal/entries.h b/src/bin/pg_resetwal/entries.h
new file mode 100644
index 00000000000..6b7686da83a
--- /dev/null
+++ b/src/bin/pg_resetwal/entries.h
@@ -0,0 +1,62 @@
+CONTROLDATA_LINE("pg_control version number",
+				 "%u", ControlFile.pg_control_version)
+CONTROLDATA_LINE("Catalog version number",
+				 "%u", ControlFile.catalog_version_no)
+CONTROLDATA_LINE("Database system identifier",
+				 "%" PRIu64, ControlFile.system_identifier)
+CONTROLDATA_LINE("Latest checkpoint's TimeLineID",
+				 "%u", ControlFile.checkPointCopy.ThisTimeLineID)
+CONTROLDATA_LINE("Latest checkpoint's full_page_writes",
+				 "%s", (ControlFile.checkPointCopy.fullPageWrites ? _("on") : _("off")))
+CONTROLDATA_LINE("Latest checkpoint's NextXID",
+				 "%u:%u", EpochFromFullTransactionId(ControlFile.checkPointCopy.nextXid), XidFromFullTransactionId(ControlFile.checkPointCopy.nextXid))
+CONTROLDATA_LINE("Latest checkpoint's NextOID",
+				 "%u", ControlFile.checkPointCopy.nextOid)
+CONTROLDATA_LINE("Latest checkpoint's NextMultiXactId",
+				 "%u", ControlFile.checkPointCopy.nextMulti)
+CONTROLDATA_LINE("Latest checkpoint's NextMultiOffset",
+				 "%" PRIu64, ControlFile.checkPointCopy.nextMultiOffset)
+CONTROLDATA_LINE("Latest checkpoint's oldestXID",
+				 "%u", ControlFile.checkPointCopy.oldestXid)
+CONTROLDATA_LINE("Latest checkpoint's oldestXID's DB",
+				 "%u", ControlFile.checkPointCopy.oldestXidDB)
+CONTROLDATA_LINE("Latest checkpoint's oldestActiveXID",
+				 "%u", ControlFile.checkPointCopy.oldestActiveXid)
+CONTROLDATA_LINE("Latest checkpoint's oldestMultiXid",
+				 "%u", ControlFile.checkPointCopy.oldestMulti)
+CONTROLDATA_LINE("Latest checkpoint's oldestMulti's DB",
+				 "%u", ControlFile.checkPointCopy.oldestMultiDB)
+CONTROLDATA_LINE("Latest checkpoint's oldestCommitTsXid",
+				 "%u", ControlFile.checkPointCopy.oldestCommitTsXid)
+CONTROLDATA_LINE("Latest checkpoint's newestCommitTsXid",
+				 "%u", ControlFile.checkPointCopy.newestCommitTsXid)
+CONTROLDATA_LINE("Maximum data alignment",
+				 "%u", ControlFile.maxAlign)
+CONTROLDATA_LINE("Database block size",
+				 "%u", ControlFile.blcksz)
+CONTROLDATA_LINE("Blocks per segment of large relation",
+				 "%u", ControlFile.relseg_size)
+CONTROLDATA_LINE("Pages per SLRU segment",
+				 "%u", ControlFile.slru_pages_per_segment)
+CONTROLDATA_LINE("WAL block size",
+				 "%u", ControlFile.xlog_blcksz)
+CONTROLDATA_LINE("Bytes per WAL segment",
+				 "%u", ControlFile.xlog_seg_size)
+CONTROLDATA_LINE("Maximum length of identifiers",
+				 "%u", ControlFile.nameDataLen)
+CONTROLDATA_LINE("Maximum columns in an index",
+				 "%u", ControlFile.indexMaxKeys)
+CONTROLDATA_LINE("Maximum size of a TOAST chunk",
+				 "%u", ControlFile.toast_max_chunk_size)
+CONTROLDATA_LINE("Size of a large-object chunk",
+				 "%u", ControlFile.loblksize)
+
+/* This is no longer configurable, but users may still expect to see it: */
+CONTROLDATA_LINE("Date/time type storage",
+				 "%s", _("64-bit integers"))
+CONTROLDATA_LINE("Float8 argument passing",
+				 "%s", ControlFile.float8ByVal ? _("by value") : _("by reference"))
+CONTROLDATA_LINE("Data page checksum version",
+				 "%u", ControlFile.data_checksum_version)
+CONTROLDATA_LINE("Default char data signedness",
+				 "%s", ControlFile.default_char_signedness ? _("signed") : _("unsigned"))
diff --git a/src/bin/pg_resetwal/nls.mk b/src/bin/pg_resetwal/nls.mk
index 694d5420a29..8dabee72bef 100644
--- a/src/bin/pg_resetwal/nls.mk
+++ b/src/bin/pg_resetwal/nls.mk
@@ -2,10 +2,12 @@
 CATALOG_NAME     = pg_resetwal
 GETTEXT_FILES    = $(FRONTEND_COMMON_GETTEXT_FILES) \
                    pg_resetwal.c \
+                   entries.h \
                    ../../common/controldata_utils.c \
                    ../../common/fe_memutils.c \
                    ../../common/file_utils.c \
                    ../../common/restricted_token.c \
                    ../../fe_utils/option_utils.c
-GETTEXT_TRIGGERS = $(FRONTEND_COMMON_GETTEXT_TRIGGERS)
+GETTEXT_TRIGGERS = $(FRONTEND_COMMON_GETTEXT_TRIGGERS) \
+				   CONTROLDATA_LINE:1
 GETTEXT_FLAGS    = $(FRONTEND_COMMON_GETTEXT_FLAGS)
diff --git a/src/bin/pg_resetwal/pg_resetwal.c b/src/bin/pg_resetwal/pg_resetwal.c
index 431b83a67da..fb17b6f80e0 100644
--- a/src/bin/pg_resetwal/pg_resetwal.c
+++ b/src/bin/pg_resetwal/pg_resetwal.c
@@ -57,6 +57,7 @@
 #include "fe_utils/option_utils.h"
 #include "fe_utils/version.h"
 #include "getopt_long.h"
+#include "mb/pg_wchar.h"
 #include "pg_getopt.h"
 #include "storage/large_object.h"
 
@@ -114,6 +115,7 @@ static void KillExistingArchiveStatus(void);
 static void KillExistingWALSummaries(void);
 static void WriteEmptyXLOG(void);
 static void usage(void);
+static int	internal_wcswidth(const char *pwcs, size_t len, int encoding);
 static uint32 strtouint32_strict(const char *restrict s, char **restrict endptr, int base);
 static uint64 strtouint64_strict(const char *restrict s, char **restrict endptr, int base);
 
@@ -753,74 +755,48 @@ GuessControlValues(void)
 static void
 PrintControlValues(bool guessed)
 {
+	int			encoding = pg_get_encoding_from_locale(NULL, true);
+	int			maxlen = 0;
+	int			thislen;
+
 	if (guessed)
 		printf(_("Guessed pg_control values:\n\n"));
 	else
 		printf(_("Current pg_control values:\n\n"));
 
-	printf(_("pg_control version number:            %u\n"),
-		   ControlFile.pg_control_version);
-	printf(_("Catalog version number:               %u\n"),
-		   ControlFile.catalog_version_no);
-	printf(_("Database system identifier:           %" PRIu64 "\n"),
-		   ControlFile.system_identifier);
-	printf(_("Latest checkpoint's TimeLineID:       %u\n"),
-		   ControlFile.checkPointCopy.ThisTimeLineID);
-	printf(_("Latest checkpoint's full_page_writes: %s\n"),
-		   ControlFile.checkPointCopy.fullPageWrites ? _("on") : _("off"));
-	printf(_("Latest checkpoint's NextXID:          %u:%u\n"),
-		   EpochFromFullTransactionId(ControlFile.checkPointCopy.nextXid),
-		   XidFromFullTransactionId(ControlFile.checkPointCopy.nextXid));
-	printf(_("Latest checkpoint's NextOID:          %u\n"),
-		   ControlFile.checkPointCopy.nextOid);
-	printf(_("Latest checkpoint's NextMultiXactId:  %u\n"),
-		   ControlFile.checkPointCopy.nextMulti);
-	printf(_("Latest checkpoint's NextMultiOffset:  %" PRIu64 "\n"),
-		   ControlFile.checkPointCopy.nextMultiOffset);
-	printf(_("Latest checkpoint's oldestXID:        %u\n"),
-		   ControlFile.checkPointCopy.oldestXid);
-	printf(_("Latest checkpoint's oldestXID's DB:   %u\n"),
-		   ControlFile.checkPointCopy.oldestXidDB);
-	printf(_("Latest checkpoint's oldestActiveXID:  %u\n"),
-		   ControlFile.checkPointCopy.oldestActiveXid);
-	printf(_("Latest checkpoint's oldestMultiXid:   %u\n"),
-		   ControlFile.checkPointCopy.oldestMulti);
-	printf(_("Latest checkpoint's oldestMulti's DB: %u\n"),
-		   ControlFile.checkPointCopy.oldestMultiDB);
-	printf(_("Latest checkpoint's oldestCommitTsXid:%u\n"),
-		   ControlFile.checkPointCopy.oldestCommitTsXid);
-	printf(_("Latest checkpoint's newestCommitTsXid:%u\n"),
-		   ControlFile.checkPointCopy.newestCommitTsXid);
-	printf(_("Maximum data alignment:               %u\n"),
-		   ControlFile.maxAlign);
-	/* we don't print floatFormat since can't say much useful about it */
-	printf(_("Database block size:                  %u\n"),
-		   ControlFile.blcksz);
-	printf(_("Blocks per segment of large relation: %u\n"),
-		   ControlFile.relseg_size);
-	printf(_("Pages per SLRU segment:               %u\n"),
-		   ControlFile.slru_pages_per_segment);
-	printf(_("WAL block size:                       %u\n"),
-		   ControlFile.xlog_blcksz);
-	printf(_("Bytes per WAL segment:                %u\n"),
-		   ControlFile.xlog_seg_size);
-	printf(_("Maximum length of identifiers:        %u\n"),
-		   ControlFile.nameDataLen);
-	printf(_("Maximum columns in an index:          %u\n"),
-		   ControlFile.indexMaxKeys);
-	printf(_("Maximum size of a TOAST chunk:        %u\n"),
-		   ControlFile.toast_max_chunk_size);
-	printf(_("Size of a large-object chunk:         %u\n"),
-		   ControlFile.loblksize);
-	/* This is no longer configurable, but users may still expect to see it: */
-	printf(_("Date/time type storage:               %s\n"),
-		   _("64-bit integers"));
-	printf(_("Float8 argument passing:              %s\n"),
-		   (ControlFile.float8ByVal ? _("by value") : _("by reference")));
-	printf(_("Data page checksum version:           %u\n"),
-		   ControlFile.data_checksum_version);
-	printf(_("Default char data signedness:         %s\n"),
-		   (ControlFile.default_char_signedness ? _("signed") : _("unsigned")));
+	/*
+	 * First, determine the maximum length of the description of all entries,
+	 * some or all of which might be translated.
+	 */
+#define CONTROLDATA_LINE(description, fmt, ...)			\
+	thislen = internal_wcswidth(_(description),			\
+								strlen(_(description)),	\
+								encoding);				\
+	if (thislen > maxlen)								\
+		maxlen = thislen;
+#include "entries.h"
+#undef CONTROLDATA_LINE
+
+	/*
+	 * Print each line: the possibly-translated description, then some padding
+	 * spaces according to its display width, then the value.
+	 */
+#define CONTROLDATA_LINE(description, fmt, ...)			\
+	{													\
+		int		thisstrlen;								\
+														\
+		thisstrlen = strlen(_(description));			\
+		thislen = internal_wcswidth(_(description),		\
+									thisstrlen,			\
+									encoding);			\
+		printf("%s:%*s" fmt "\n",						\
+			   _(description),							\
+			   maxlen - thislen + 2,					\
+			   " ",										\
+			   __VA_ARGS__);							\
+	}
+#include "entries.h"
+#undef CONTROLDATA_LINE
 }
 
 
@@ -1238,6 +1214,36 @@ usage(void)
 	printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
 }
 
+/*
+ * Measure the display length of a single-line string in the given encoding.
+ *
+ * Similar to pg_wcswidth, written without dependency on libpq.
+ */
+static int
+internal_wcswidth(const char *pwcs, size_t len, int encoding)
+{
+	int			width = 0;
+
+	while (len > 0)
+	{
+		int			chlen,
+					chwidth;
+
+		chlen = pg_encoding_mblen(encoding, pwcs);
+		if (len < (size_t) chlen)
+			break;				/* Invalid string */
+
+		chwidth = pg_encoding_dsplen(encoding, pwcs);
+		if (chwidth > 0)
+			width += chwidth;
+
+		pwcs += chlen;
+		len -= chlen;
+	}
+	return width;
+}
+
+
 /*
  * strtouint32_strict -- like strtoul(), but returns uint32 and doesn't accept
  * negative values
-- 
2.47.3

