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

[RFC PATCH 20/21] usage API: make the "{usage,fatal,error,warning,BUG}: " translatable

From
Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Date
Nov 15, 2021, 22:18 UTC
Message-ID
<RFC-patch-20.21-69426ddb992-20211115T220831Z-avarab@gmail.com>
In-Reply-To
<RFC-cover-00.21-00000000000-20211115T220831Z-avarab@gmail.com>

In preceding commits the vreportf() function was made static, so we know it's only being called with a limited set of fixed prefixes. Pass an enum indicating the kind of usage message we're emitting instead, which means that we can fold the BUG_vfl_common() functionality directly into it.

Since we've now got one place were we're emitting these usage messages we can make them translatable.

We need to be careful with this function to not malloc() anything, as a failure in say a use of strbuf_vaddf() would call xmalloc(), which would in turn call die(), but here we're using static strings, either from libintl or not.

I was on the fence about making the "BUG: " message translatable, but let's do it for consistency. Someone who doesn't speak a word of English may not know what "BUG" means, but if it's translated they might have an easier time knowing that they have to report a bug upstream. Since we'll always emit the line number it's unlikely that we're going to be confused by such a report.

As we've moved the BUG_vfl_common() code into vsnprintf() we can do away with one of the two checks for buffer sizes added in 116d1fa6c69 (vreportf(): avoid relying on stdio buffering, 2019-10-30) and ac4896f007a (fmt_with_err: add a comment that truncation is OK, 2018-05-18).

I.e. we're being overly paranoid if we define the fixed-size "prefix" and "msg" buffers, are OK with the former being truncated, and then effectively check if our 256-byte buffer is larger than our 4096-byte buffer. I wondered about adding a:

    assert(sizeof(prefix) < sizeof(msg)); /* overly paranoid much? */

But I think that would be overdoing it. Anyone modifying this function will keep these two buffer sizes in mind, so let's just remove one of the checks instead.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 usage.c | 68 ++++++++++++++++++++++++++++++++++++++-------------------
 1 file changed, 45 insertions(+), 23 deletions(-)
diff --git a/usage.c b/usage.c
index e6f609fe49a..62313862977 100644
--- a/usage.c
+++ b/usage.c
@@ -6,16 +6,49 @@
 #include "git-compat-util.h"
 #include "cache.h"
 
-static void vreportf(const char *prefix, const char *err, va_list params)
+enum usage_kind {
+	USAGE_USAGE,
+	USAGE_DIE,
+	USAGE_ERROR,
+	USAGE_WARNING,
+	USAGE_BUG,
+};
+
+static void vreportf(enum usage_kind kind,
+		     const char *file, int line,
+		     const char *err, va_list params)
 {
+	const char *prefix_i18n;
+	char prefix[256];
 	char msg[4096];
 	char *p, *pend = msg + sizeof(msg);
-	size_t prefix_len = strlen(prefix);
-
-	if (sizeof(msg) <= prefix_len) {
-		fprintf(stderr, "BUG!!! too long a prefix '%s'\n", prefix);
-		abort();
+	size_t prefix_len;
+
+	switch (kind) {
+	case USAGE_USAGE:
+		prefix_i18n =_("usage: ");
+		break;
+	case USAGE_DIE:
+		prefix_i18n =_("fatal: ");
+		break;
+	case USAGE_ERROR:
+		prefix_i18n =_("error: ");
+		break;
+	case USAGE_WARNING:
+		prefix_i18n =_("warning: ");
+		break;
+	case USAGE_BUG:
+		prefix_i18n =_("BUG: ");
+		break;
 	}
+
+	/* truncation via snprintf is OK here */
+	if (kind == USAGE_BUG)
+		snprintf(prefix, sizeof(prefix), "%s%s:%d: ", prefix_i18n, file, line);
+	else
+		snprintf(prefix, sizeof(prefix), "%s", prefix_i18n);
+
+	prefix_len = strlen(prefix);
 	memcpy(msg, prefix, prefix_len);
 	p = msg + prefix_len;
 	if (vsnprintf(p, pend - p, err, params) < 0)
@@ -33,7 +66,7 @@ static void vreportf(const char *prefix, const char *err, va_list params)
 
 static NORETURN void usage_builtin(const char *file, int line, const char *err, va_list params)
 {
-	vreportf("usage: ", err, params);
+	vreportf(USAGE_USAGE, file, line, err, params);
 
 	/*
 	 * When we detect a usage error *before* the command dispatch in
@@ -58,7 +91,7 @@ static NORETURN void usage_builtin(const char *file, int line, const char *err,
 static void die_message_builtin(const char *file, int line, const char *err, va_list params)
 {
 	trace2_cmd_error_va_fl(file, line, err, params);
-	vreportf("fatal: ", err, params);
+	vreportf(USAGE_DIE, file, line, err, params);
 }
 
 /*
@@ -78,14 +111,14 @@ static void error_builtin(const char *file, int line, const char *err, va_list p
 {
 	trace2_cmd_error_va_fl(file, line, err, params);
 
-	vreportf("error: ", err, params);
+	vreportf(USAGE_ERROR, file, line, err, params);
 }
 
 static void warning_builtin(const char *file, int line, const char *warn, va_list params)
 {
 	trace2_cmd_error_va_fl(file, line, warn, params);
 
-	vreportf("warning: ", warn, params);
+	vreportf(USAGE_WARNING, file, line, warn, params);
 }
 
 static int die_is_recursing_builtin(void)
@@ -283,24 +316,13 @@ void warning_errno_fl(const char *file, int line, const char *fmt, ...)
 /* Only set this, ever, from t/helper/, when verifying that bugs are caught. */
 int BUG_exit_code;
 
-static void BUG_vfl_common(const char *file, int line, const char *fmt,
-			   va_list params)
-{
-	char prefix[256];
-
-	/* truncation via snprintf is OK here */
-	snprintf(prefix, sizeof(prefix), "BUG: %s:%d: ", file, line);
-
-	vreportf(prefix, fmt, params);
-}
-
 static NORETURN void BUG_vfl(const char *file, int line, const char *fmt, va_list params)
 {
 	va_list params_copy;
 	static int in_bug;
 
 	va_copy(params_copy, params);
-	BUG_vfl_common(file, line, fmt, params);
+	vreportf(USAGE_BUG, file, line, fmt, params);
 
 	if (in_bug)
 		abort();
@@ -330,7 +352,7 @@ int bug_fl(const char *file, int line, const char *fmt, ...)
 
 	va_copy(cp, ap);
 	va_start(ap, fmt);
-	BUG_vfl_common(file, line, fmt, ap);
+	vreportf(USAGE_BUG, file, line, fmt, ap);
 	va_end(ap);
 	trace2_cmd_error_va_fl(file, line, fmt, cp);
 
-- 
2.34.0.rc2.809.g11e21d44b24
Previous: Ævar Arnfjörð BjarmasonNext: Ævar Arnfjörð Bjarmason
Message 15 of 34 in “C99: show meaningful <file>:<line> in trace2 via macros”
  1. 00/21 C99: show meaningful <file>:<line> in trace2 via macrosÆvar Arnfjörð Bjarmason, Nov 15, 2021
  2. 01/21 git-compat-util.h: clarify GCC v.s. C99-specific in commentÆvar Arnfjörð Bjarmason, Nov 15, 2021
  3. 03/21 usage.c: add a die_message() routineÆvar Arnfjörð Bjarmason, Nov 15, 2021
  4. 02/21 C99 support: hard-depend on C99 variadic macrosÆvar Arnfjörð Bjarmason, Nov 15, 2021
  5. 04/21 usage.c API users: use die_message() where appropriateÆvar Arnfjörð Bjarmason, Nov 15, 2021
  6. 05/21 usage.c + gc: add and use a die_message_errno()Ævar Arnfjörð Bjarmason, Nov 15, 2021
  7. 07/21 common-main.c: call exit(), don't returnÆvar Arnfjörð Bjarmason, Nov 15, 2021
  8. 06/21 config API: don't use vreportf(), make it static in usage.cÆvar Arnfjörð Bjarmason, Nov 15, 2021
  9. 08/21 usage.c: add a non-fatal bug() function to go with BUG()Ævar Arnfjörð Bjarmason, Nov 15, 2021
  10. 10/21 receive-pack: use bug() and BUG_if_bug()Ævar Arnfjörð Bjarmason, Nov 15, 2021
  11. 11/21 cache-tree.c: use bug() and BUG_if_bug()Ævar Arnfjörð Bjarmason, Nov 15, 2021
  12. 12/21 pack-objects: use BUG(...) not die("BUG: ...")Ævar Arnfjörð Bjarmason, Nov 15, 2021
  13. 17/21 usage.c: move usage routines aroundÆvar Arnfjörð Bjarmason, Nov 15, 2021
  14. 21/21 usage API: add "core.usageAddSource" config to add <file>:<line>Ævar Arnfjörð Bjarmason, Nov 15, 2021
  15. 20/21 usage API: make the "{usage,fatal,error,warning,BUG}: " translatableÆvar Arnfjörð Bjarmason, Nov 15, 2021
  16. 19/21 usage API: use C99 macros for {usage,usagef,die,error,warning,die}*()Ævar Arnfjörð Bjarmason, Nov 15, 2021
  17. Jeff HostetlerDec 27, 2021
  18. Ævar Arnfjörð BjarmasonDec 27, 2021
  19. Jeff HostetlerDec 28, 2021
  20. Elijah NewrenDec 28, 2021
  21. Ævar Arnfjörð BjarmasonDec 28, 2021
  22. Elijah NewrenDec 29, 2021
  23. Ævar Arnfjörð BjarmasonDec 28, 2021
  24. Jeff HostetlerDec 29, 2021
  25. 18/21 usage.c: move rename variables in usage routines aroundÆvar Arnfjörð Bjarmason, Nov 15, 2021
  26. 16/21 usage.[ch] API: rename "warn" vars functions to "warning"Ævar Arnfjörð Bjarmason, Nov 15, 2021
  27. 14/21 usage API: create a new usage.h, move API docs thereÆvar Arnfjörð Bjarmason, Nov 15, 2021
  28. 15/21 usage.[ch] API users: use report_fn, not hardcoded prototypeÆvar Arnfjörð Bjarmason, Nov 15, 2021
  29. 13/21 strbuf.h: use BUG(...) not die("BUG: ...")Ævar Arnfjörð Bjarmason, Nov 15, 2021
  30. 09/21 parse-options.[ch] API: use bug() to improve error outputÆvar Arnfjörð Bjarmason, Nov 15, 2021
  31. Taylor BlauNov 16, 2021
  32. Ævar Arnfjörð BjarmasonNov 16, 2021
  33. Taylor BlauNov 16, 2021
  34. Ævar Arnfjörð BjarmasonNov 16, 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.