git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 02/11] Support GIT_TEST_GETTEXT_POISON=rot13

From
Johannes Schindelin via GitGitGadget <gitgitgadget@gmail.com>
Date
Jan 12, 2021, 08:47 UTC
Message-ID
<ab7832fc7ac783bc8f8c10014fc9747128fc37bc.1610441263.git.gitgitgadget@gmail.com>
In-Reply-To
<pull.836.git.1610441262.gitgitgadget@gmail.com>
From: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 gettext.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
 gettext.h |  5 +++--
 2 files changed, 66 insertions(+), 4 deletions(-)
diff --git a/gettext.c b/gettext.c
index 35d2c1218db..7e8966d8326 100644
--- a/gettext.c
+++ b/gettext.c
@@ -68,11 +68,72 @@ const char *get_preferred_languages(void)
 int use_gettext_poison(void)
 {
 	static int poison_requested = -1;
-	if (poison_requested == -1)
-		poison_requested = git_env_bool("GIT_TEST_GETTEXT_POISON", 0);
+	if (poison_requested == -1) {
+		const char *v = getenv("GIT_TEST_GETTEXT_POISON");
+		if (v && !strcmp(v, "rot13"))
+			poison_requested = 2;
+		else
+			poison_requested =
+				git_env_bool("GIT_TEST_GETTEXT_POISON", 0);
+	}
 	return poison_requested;
 }
 
+static inline char do_rot13(char c)
+{
+	if (c >= 'a' && c <= 'm')
+		return c + 'n' - 'a';
+	if (c >= 'n' && c <= 'z')
+		return c + 'a' - 'n';
+	if (c >= 'A' && c <= 'M')
+		return c + 'N' - 'A';
+	if (c >= 'N' && c <= 'Z')
+		return c + 'A' - 'N';
+	return c;
+}
+
+const char *gettext_maybe_rot13(const char *msgid)
+{
+	static struct strbuf round_robin[4] = {
+		STRBUF_INIT, STRBUF_INIT, STRBUF_INIT, STRBUF_INIT
+	};
+	static int current;
+	struct strbuf *buf;
+
+	if (use_gettext_poison() != 2)
+		return "# GETTEXT POISON #";
+
+	buf = &round_robin[current++];
+	if (current >= ARRAY_SIZE(round_robin))
+		current = 0;
+
+	strbuf_reset(buf);
+	while (*msgid) {
+		const char *p = strchrnul(msgid, '%'), *spec;
+
+		while (*p && p[1] == '%')
+			p = strchrnul(p + 2, '%');
+
+		if (p != msgid) {
+			strbuf_addstr(buf, "<rot13>");
+			while (p != msgid)
+				strbuf_addch(buf, do_rot13(*(msgid++)));
+			strbuf_addstr(buf, "</rot13>");
+		}
+
+		if (!*p)
+			break;
+
+		spec = strpbrk(p + 1, "diouxXeEfFgGaAcsCSpnm%");
+		if (!spec)
+			BUG("Unrecognized format string: %s", p);
+		strbuf_add(buf, p, spec + 1 - p);
+		msgid = spec + 1;
+	}
+
+	return buf->buf;
+}
+
 #ifndef NO_GETTEXT
 static int test_vsnprintf(const char *fmt, ...)
 {
diff --git a/gettext.h b/gettext.h
index bee52eb1134..298adda7e15 100644
--- a/gettext.h
+++ b/gettext.h
@@ -29,6 +29,7 @@
 #define FORMAT_PRESERVING(n) __attribute__((format_arg(n)))
 
 int use_gettext_poison(void);
+const char *gettext_maybe_rot13(const char *msgid);
 
 #ifndef NO_GETTEXT
 void git_setup_gettext(void);
@@ -48,14 +49,14 @@ static inline FORMAT_PRESERVING(1) const char *_(const char *msgid)
 {
 	if (!*msgid)
 		return "";
-	return use_gettext_poison() ? "# GETTEXT POISON #" : gettext(msgid);
+	return use_gettext_poison() ? gettext_maybe_rot13(msgid) : gettext(msgid);
 }
 
 static inline FORMAT_PRESERVING(1) FORMAT_PRESERVING(2)
 const char *Q_(const char *msgid, const char *plu, unsigned long n)
 {
 	if (use_gettext_poison())
-		return "# GETTEXT POISON #";
+		return gettext_maybe_rot13(n < 2 ? msgid : plu);
 	return ngettext(msgid, plu, n);
 }
 
-- 
gitgitgadget
Previous: Johannes Schindelin via GitGitGadgetNext: Junio C Hamano
Message 3 of 31 in “[RFH] Introduce support for GETTEXT_POISON=rot13”
  1. 00/11 [RFH] Introduce support for GETTEXT_POISON=rot13Johannes Schindelin via GitGitGadget, Jan 12, 2021
  2. 03/11 parse-options: add forgotten translationsJohannes Schindelin via GitGitGadget, Jan 12, 2021
  3. 02/11 Support GIT_TEST_GETTEXT_POISON=rot13Johannes Schindelin via GitGitGadget, Jan 12, 2021
  4. Junio C HamanoJan 12, 2021
  5. 01/11 tests: remove unnecessary GIT_TEST_GETTEXT_POISON=false constructsJohannes Schindelin via GitGitGadget, Jan 12, 2021
  6. SZEDER GáborJan 12, 2021
  7. 06/11 t0041: stop using `test_i18ngrep` on untranslated outputJohannes Schindelin via GitGitGadget, Jan 12, 2021
  8. 05/11 t0006: use `test_i18ncmp` only for C localesJohannes Schindelin via GitGitGadget, Jan 12, 2021
  9. 07/11 t0027: mark a function as requiring the C localeJohannes Schindelin via GitGitGadget, Jan 12, 2021
  10. 08/11 t6301: do not expect the output of `for-each-ref` to be translatedJohannes Schindelin via GitGitGadget, Jan 12, 2021
  11. 10/11 GETTEXT_POISON=rot13: perform actual checks in `test_i18ngrep`Johannes Schindelin via GitGitGadget, Jan 12, 2021
  12. 09/11 GETTEXT_POISON=rot13: do compare the output in `test_i18ncmp`Johannes Schindelin via GitGitGadget, Jan 12, 2021
  13. Junio C HamanoJan 12, 2021
  14. Johannes SchindelinJan 15, 2021
  15. Junio C HamanoJan 15, 2021
  16. Johannes SchindelinJan 18, 2021
  17. 11/11 test-tool i18n: do not complain about empty messagesJohannes Schindelin via GitGitGadget, Jan 12, 2021
  18. 04/11 sha1dc: mark forgotten message for translationJohannes Schindelin via GitGitGadget, Jan 12, 2021
  19. Jeff KingJan 12, 2021
  20. Junio C HamanoJan 12, 2021
  21. Johannes SchindelinJan 15, 2021
  22. Jeff KingJan 15, 2021
  23. Johannes SchindelinJan 18, 2021
  24. Junio C HamanoJan 18, 2021
  25. Johannes SchindelinJan 19, 2021
  26. Jeff KingJan 12, 2021
  27. Junio C HamanoJan 12, 2021
  28. Jeff KingJan 13, 2021
  29. Junio C HamanoJan 16, 2021
  30. Ævar Arnfjörð BjarmasonJan 12, 2021
  31. Johannes SchindelinJan 15, 2021

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.