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

[PATCH v5 27/38] i18n: config: unfold error messages marked for translation

From
Vasco Almeida <vascomalmeida@sapo.pt>
Date
Jun 17, 2016, 20:21 UTC
Message-ID
<1466194887-18236-28-git-send-email-vascomalmeida@sapo.pt>
In-Reply-To
<1466194887-18236-1-git-send-email-vascomalmeida@sapo.pt>

Introduced in 473166b ("config: add 'origin_type' to config_source struct", 2016-02-19), Git can inform the user about the origin of a config error, but the implementation does not allow translators to translate the keywords 'file', 'blob, 'standard input', and 'submodule-blob'. Moreover, for the second message, a reason for the error is appended to the message, not allowing translators to translate that reason either.

Unfold the message into several templates for each known origin_type. That would result in better translation at the expense of code verbosity.

Add enum git_config_oringin_type to ease management of the various configuration origin types (blob, file, etc).

For the first instance, use xstrfmt() function to prepare the message string, instead of doing something like it's done for the second one, because intelligibility and code conciseness are improved for that instance.

Signed-off-by: Vasco Almeida <vascomalmeida@sapo.pt>
---
 cache.h            |   9 ++++-
 config.c           | 101 ++++++++++++++++++++++++++++++++++++++++++++---------
 submodule-config.c |   2 +-
 3 files changed, 94 insertions(+), 18 deletions(-)
diff --git a/cache.h b/cache.h
index 6049f86..4bded9a 100644
--- a/cache.h
+++ b/cache.h
@@ -1559,10 +1559,17 @@ struct git_config_source {
 	const char *blob;
 };
 
+enum git_config_origin_type {
+	CFG_BLOB,
+	CFG_FILE,
+	CFG_STDIN,
+	CFG_SUBMODULE_BLOB
+};
+
 typedef int (*config_fn_t)(const char *, const char *, void *);
 extern int git_default_config(const char *, const char *, void *);
 extern int git_config_from_file(config_fn_t fn, const char *, void *);
-extern int git_config_from_mem(config_fn_t fn, const char *origin_type,
+extern int git_config_from_mem(config_fn_t fn, const enum git_config_origin_type,
 					const char *name, const char *buf, size_t len, void *data);
 extern void git_config_push_parameter(const char *text);
 extern int git_config_from_parameters(config_fn_t fn, void *data);
diff --git a/config.c b/config.c
index f51c56b..e86f0aa 100644
--- a/config.c
+++ b/config.c
@@ -24,7 +24,7 @@ struct config_source {
 			size_t pos;
 		} buf;
 	} u;
-	const char *origin_type;
+	enum git_config_origin_type origin_type;
 	const char *name;
 	const char *path;
 	int die_on_error;
@@ -417,6 +417,8 @@ static int git_parse_source(config_fn_t fn, void *data)
 	int comment = 0;
 	int baselen = 0;
 	struct strbuf *var = &cf->var;
+	int error_return = 0;
+	char *error_msg = NULL;
 
 	/* U+FEFF Byte Order Mark in UTF8 */
 	const char *bomptr = utf8_bom;
@@ -471,10 +473,36 @@ static int git_parse_source(config_fn_t fn, void *data)
 		if (get_value(fn, data, var) < 0)
 			break;
 	}
+
+	switch (cf->origin_type) {
+	case CFG_BLOB:
+		error_msg = xstrfmt(_("bad config line %d in blob %s"),
+				      cf->linenr, cf->name);
+		break;
+	case CFG_FILE:
+		error_msg = xstrfmt(_("bad config line %d in file %s"),
+				      cf->linenr, cf->name);
+		break;
+	case CFG_STDIN:
+		error_msg = xstrfmt(_("bad config line %d in standard input"),
+				      cf->linenr);
+		break;
+	case CFG_SUBMODULE_BLOB:
+		error_msg = xstrfmt(_("bad config line %d in submodule-blob %s"),
+				       cf->linenr, cf->name);
+		break;
+	default:
+		error_msg = xstrfmt(_("bad config line %d in %s"),
+				      cf->linenr, cf->name);
+	}
+
 	if (cf->die_on_error)
-		die(_("bad config line %d in %s %s"), cf->linenr, cf->origin_type, cf->name);
+		die(error_msg);
 	else
-		return error(_("bad config line %d in %s %s"), cf->linenr, cf->origin_type, cf->name);
+		error_return =  error(error_msg);
+
+	free(error_msg);
+	return error_return;
 }
 
 static int parse_unit_factor(const char *end, uintmax_t *val)
@@ -583,16 +611,42 @@ int git_parse_ulong(const char *value, unsigned long *ret)
 NORETURN
 static void die_bad_number(const char *name, const char *value)
 {
-	const char *reason = errno == ERANGE ?
-			     "out of range" :
-			     "invalid unit";
 	if (!value)
 		value = "";
 
-	if (cf && cf->origin_type && cf->name)
-		die(_("bad numeric config value '%s' for '%s' in %s %s: %s"),
-		    value, name, cf->origin_type, cf->name, reason);
-	die(_("bad numeric config value '%s' for '%s': %s"), value, name, reason);
+	if (!(cf && cf->name))
+		die(errno == ERANGE
+		    ? _("bad numeric config value '%s' for '%s': out of range")
+		    : _("bad numeric config value '%s' for '%s': invalid unit"),
+		    value, name);
+
+	switch (cf->origin_type) {
+	case CFG_BLOB:
+		die(errno == ERANGE
+		    ? _("bad numeric config value '%s' for '%s' in blob %s: out of range")
+		    : _("bad numeric config value '%s' for '%s' in blob %s: invalid unit"),
+		    value, name, cf->name);
+	case CFG_FILE:
+		die(errno == ERANGE
+		    ? _("bad numeric config value '%s' for '%s' in file %s: out of range")
+		    : _("bad numeric config value '%s' for '%s' in file %s: invalid unit"),
+		    value, name, cf->name);
+	case CFG_STDIN:
+		die(errno == ERANGE
+		    ? _("bad numeric config value '%s' for '%s' in standard input: out of range")
+		    : _("bad numeric config value '%s' for '%s' in standard input: invalid unit"),
+		    value, name);
+	case CFG_SUBMODULE_BLOB:
+		die(errno == ERANGE
+		    ? _("bad numeric config value '%s' for '%s' in submodule-blob %s: out of range")
+		    : _("bad numeric config value '%s' for '%s' in submodule-blob %s: invalid unit"),
+		    value, name, cf->name);
+	default:
+		die(errno == ERANGE
+		    ? _("bad numeric config value '%s' for '%s' in %s: out of range")
+		    : _("bad numeric config value '%s' for '%s' in %s: invalid unit"),
+		    value, name, cf->name);
+	}
 }
 
 int git_config_int(const char *name, const char *value)
@@ -1069,7 +1123,8 @@ static int do_config_from(struct config_source *top, config_fn_t fn, void *data)
 }
 
 static int do_config_from_file(config_fn_t fn,
-		const char *origin_type, const char *name, const char *path, FILE *f,
+		const enum git_config_origin_type origin_type,
+		const char *name, const char *path, FILE *f,
 		void *data)
 {
 	struct config_source top;
@@ -1088,7 +1143,7 @@ static int do_config_from_file(config_fn_t fn,
 
 static int git_config_from_stdin(config_fn_t fn, void *data)
 {
-	return do_config_from_file(fn, "standard input", "", NULL, stdin, data);
+	return do_config_from_file(fn, CFG_STDIN, "", NULL, stdin, data);
 }
 
 int git_config_from_file(config_fn_t fn, const char *filename, void *data)
@@ -1099,14 +1154,14 @@ int git_config_from_file(config_fn_t fn, const char *filename, void *data)
 	f = fopen(filename, "r");
 	if (f) {
 		flockfile(f);
-		ret = do_config_from_file(fn, "file", filename, filename, f, data);
+		ret = do_config_from_file(fn, CFG_FILE, filename, filename, f, data);
 		funlockfile(f);
 		fclose(f);
 	}
 	return ret;
 }
 
-int git_config_from_mem(config_fn_t fn, const char *origin_type,
+int git_config_from_mem(config_fn_t fn, const enum git_config_origin_type origin_type,
 			const char *name, const char *buf, size_t len, void *data)
 {
 	struct config_source top;
@@ -1143,7 +1198,7 @@ static int git_config_from_blob_sha1(config_fn_t fn,
 		return error("reference '%s' does not point to a blob", name);
 	}
 
-	ret = git_config_from_mem(fn, "blob", name, buf, size, data);
+	ret = git_config_from_mem(fn, CFG_BLOB, name, buf, size, data);
 	free(buf);
 
 	return ret;
@@ -2442,7 +2497,21 @@ int parse_config_key(const char *var,
 
 const char *current_config_origin_type(void)
 {
-	return cf && cf->origin_type ? cf->origin_type : "command line";
+	if (!cf)
+		return "command line";
+
+	switch (cf->origin_type) {
+	case CFG_BLOB:
+		return "blob";
+	case CFG_FILE:
+		return "file";
+	case CFG_STDIN:
+		return "standard input";
+	case CFG_SUBMODULE_BLOB:
+		return "submodule-blob";
+	default:
+		return "command line";
+	}
 }
 
 const char *current_config_name(void)
diff --git a/submodule-config.c b/submodule-config.c
index debab29..f53f6bd 100644
--- a/submodule-config.c
+++ b/submodule-config.c
@@ -439,7 +439,7 @@ static const struct submodule *config_from(struct submodule_cache *cache,
 	parameter.commit_sha1 = commit_sha1;
 	parameter.gitmodules_sha1 = sha1;
 	parameter.overwrite = 0;
-	git_config_from_mem(parse_config, "submodule-blob", rev.buf,
+	git_config_from_mem(parse_config, CFG_SUBMODULE_BLOB, rev.buf,
 			config, config_size, &parameter);
 	free(config);
 
-- 
2.6.6
Previous: Vasco AlmeidaNext: Vasco Almeida
Message 22 of 41 in “i18n and test updates”
  1. 00/38 i18n and test updatesVasco Almeida, Jun 17, 2016
  2. 01/38 i18n: builtin/remote.c: fix mark for translationVasco Almeida, Jun 17, 2016
  3. 02/38 i18n: advice: mark string about detached head for translationVasco Almeida, Jun 17, 2016
  4. 03/38 i18n: advice: internationalize message for conflictsVasco Almeida, Jun 17, 2016
  5. 04/38 i18n: transport: mark strings for translationVasco Almeida, Jun 17, 2016
  6. 05/38 i18n: sequencer: mark entire sentences for translationVasco Almeida, Jun 17, 2016
  7. 06/38 i18n: sequencer: mark string for translationVasco Almeida, Jun 17, 2016
  8. 07/38 i18n: merge-octopus: mark messages for translationVasco Almeida, Jun 17, 2016
  9. 08/38 merge-octupus: use die shell function from git-sh-setup.shVasco Almeida, Jun 17, 2016
  10. 09/38 i18n: rebase: fix marked string to use eval_gettext variantVasco Almeida, Jun 17, 2016
  11. 12/38 t6030: update to use test_i18ncmpVasco Almeida, Jun 17, 2016
  12. 11/38 i18n: bisect: simplify error message for i18nVasco Almeida, Jun 17, 2016
  13. 17/38 i18n: setup: mark strings for translationVasco Almeida, Jun 17, 2016
  14. 14/38 i18n: rebase-interactive: mark strings for translationVasco Almeida, Jun 17, 2016
  15. 22/38 t5523: use test_i18ngrep for negationVasco Almeida, Jun 17, 2016
  16. 20/38 t9003: become resilient to GETTEXT_POISONVasco Almeida, Jun 17, 2016
  17. 28/38 i18n: merge: mark messages for translationVasco Almeida, Jun 17, 2016
  18. 31/38 i18n: standardise messagesVasco Almeida, Jun 17, 2016
  19. 33/38 i18n: remote: allow translations to reorder messageVasco Almeida, Jun 17, 2016
  20. 30/38 i18n: sequencer: add period to error messageVasco Almeida, Jun 17, 2016
  21. 32/38 i18n: remote: mark URL fallback text for translationVasco Almeida, Jun 17, 2016
  22. 27/38 i18n: config: unfold error messages marked for translationVasco Almeida, Jun 17, 2016
  23. 29/38 i18n: merge: change command option help to lowercaseVasco Almeida, Jun 17, 2016
  24. 23/38 i18n: bisect: mark strings for translationVasco Almeida, Jun 17, 2016
  25. 24/38 i18n: transport-helper.c: change N_() call to _()Vasco Almeida, Jun 17, 2016
  26. 26/38 i18n: notes: mark options for translationVasco Almeida, Jun 17, 2016
  27. 18/38 tests: use test_i18n* functions to suppress false positivesVasco Almeida, Jun 17, 2016
  28. 21/38 t4153: fix negated test_i18ngrep callVasco Almeida, Jun 17, 2016
  29. 25/38 i18n: notes: mark strings for translationVasco Almeida, Jun 17, 2016
  30. 19/38 tests: unpack-trees: update to use test_i18n* functionsVasco Almeida, Jun 17, 2016
  31. 15/38 i18n: rebase-interactive: mark here-doc strings for translationVasco Almeida, Jun 17, 2016
  32. 10/38 i18n: rebase: mark placeholder for translationVasco Almeida, Jun 17, 2016
  33. 13/38 i18n: git-sh-setup.sh: mark strings for translationVasco Almeida, Jun 17, 2016
  34. 16/38 i18n: rebase-interactive: mark comments of squash for translationVasco Almeida, Jun 17, 2016
  35. Junio C HamanoJun 17, 2016
  36. Junio C HamanoJun 17, 2016
  37. 34/38 i18n: init-db: join message piecesVasco Almeida, Jun 17, 2016
  38. 36/38 i18n: submodule: escape shell variables inside eval_gettextVasco Almeida, Jun 17, 2016
  39. 37/38 i18n: unmark die messages for translationVasco Almeida, Jun 17, 2016
  40. 35/38 i18n: submodule: join strings marked for translationVasco Almeida, Jun 17, 2016
  41. 38/38 i18n: branch: mark comment when editing branch description for translationVasco Almeida, Jun 17, 2016

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.