git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* [RFC PATCH 0/2] Localize log output
@ 2012-10-23 12:24 Peter Krefting
  2012-10-23 12:25 ` [RFC PATCH 1/2] Use localized date in " Peter Krefting
  2012-10-23 12:25 ` [RFC PATCH 2/2] Localize diff and " Peter Krefting
  0 siblings, 2 replies; 3+ messages in thread
From: Peter Krefting @ 2012-10-23 12:24 UTC (permalink / raw)
  To: Git Mailing List

In v1.8.0, I saw a regression in, among other, "git show --stat" in
that it would no longer output the diffstat in Swedish. This turned
out to be intentional, to fix format-patch and friends, but I liked
the old behaviour.

This series tries to fix that, and related code such as "git log",
while making sure that "git format-patch" still outputs in English.

I am posting this as a RFC, as I might very well have broken something
else in the process, from not knowing the code well enough.

The branch is also available from
https://github.com/nafmo/git-l10n-sv/commits/fix-diff-translation-20121023-1.8.0
with an updated Swedish translation.

Peter Krefting (2):
   Use localized date in log output
   Localize diff and log output

  builtin/apply.c  |  2 +-
  builtin/commit.c |  4 +--
  builtin/log.c    |  6 ++--
  commit.h         |  3 +-
  date.c           |  4 ++-
  diff.c           | 22 +++++++++-----
  diff.h           |  5 +++-
  gettext.c        |  1 +
  log-tree.c       | 11 +++++--
  pretty.c         | 87 +++++++++++++++++++++++++++++++++++++++++++-------------
  strbuf.c         | 10 +++++++
  strbuf.h         |  1 +
  12 files changed, 119 insertions(+), 37 deletions(-)

-- 
1.8.0

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [RFC PATCH 1/2] Use localized date in log output
  2012-10-23 12:24 [RFC PATCH 0/2] Localize log output Peter Krefting
@ 2012-10-23 12:25 ` Peter Krefting
  2012-10-23 12:25 ` [RFC PATCH 2/2] Localize diff and " Peter Krefting
  1 sibling, 0 replies; 3+ messages in thread
From: Peter Krefting @ 2012-10-23 12:25 UTC (permalink / raw)
  To: Git Mailing List

When outputting a normal log, without having specified which date format
to use, we should output the current user locale's default format. Do this
by initializing LC_TIME properly and using strftime() to format the date.
---
  date.c    |  4 +++-
  gettext.c |  1 +
  strbuf.c  | 10 ++++++++++
  strbuf.h  |  1 +
  4 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/date.c b/date.c
index 57331ed..88f928c 100644
--- a/date.c
+++ b/date.c
@@ -203,7 +203,7 @@ const char *show_date(unsigned long time, int tz, enum date_mode mode)
  			weekday_names[tm->tm_wday], tm->tm_mday,
  			month_names[tm->tm_mon], tm->tm_year + 1900,
  			tm->tm_hour, tm->tm_min, tm->tm_sec, tz);
-	else
+	else if (mode == DATE_RAW)
  		strbuf_addf(&timebuf, "%.3s %.3s %d %02d:%02d:%02d %d%c%+05d",
  				weekday_names[tm->tm_wday],
  				month_names[tm->tm_mon],
@@ -212,6 +212,8 @@ const char *show_date(unsigned long time, int tz, enum date_mode mode)
  				tm->tm_year + 1900,
  				(mode == DATE_LOCAL) ? 0 : ' ',
  				tz);
+	else
+		strbuf_strftime(&timebuf,"%c",tm);
  	return timebuf.buf;
  }

diff --git a/gettext.c b/gettext.c
index 71e9545..a87d144 100644
--- a/gettext.c
+++ b/gettext.c
@@ -126,6 +126,7 @@ void git_setup_gettext(void)
  		podir = GIT_LOCALE_PATH;
  	bindtextdomain("git", podir);
  	setlocale(LC_MESSAGES, "");
+	setlocale(LC_TIME, "");
  	init_gettext_charset("git");
  	textdomain("git");
  }
diff --git a/strbuf.c b/strbuf.c
index 0510f76..d393de9 100644
--- a/strbuf.c
+++ b/strbuf.c
@@ -228,6 +228,16 @@ void strbuf_vaddf(struct strbuf *sb, const char *fmt, va_list ap)
  	strbuf_setlen(sb, sb->len + len);
  }

+void strbuf_strftime(struct strbuf *sb, const char *fmt, struct tm *tm)
+{
+	int len;
+
+	if (!strbuf_avail(sb))
+		strbuf_grow(sb, 256);
+	len = strftime(sb->buf + sb->len, sb->alloc - sb->len, fmt, tm);
+	strbuf_setlen(sb, sb->len + len);
+}
+
  void strbuf_expand(struct strbuf *sb, const char *format, expand_fn_t fn,
  		   void *context)
  {
diff --git a/strbuf.h b/strbuf.h
index be941ee..9ca1d59 100644
--- a/strbuf.h
+++ b/strbuf.h
@@ -99,6 +99,7 @@ __attribute__((format (printf,2,3)))
  extern void strbuf_addf(struct strbuf *sb, const char *fmt, ...);
  __attribute__((format (printf,2,0)))
  extern void strbuf_vaddf(struct strbuf *sb, const char *fmt, va_list ap);
+extern void strbuf_strfime(struct strbuf *sb, const char *fmt, struct tm *tm);

  extern void strbuf_add_lines(struct strbuf *sb, const char *prefix, const char *buf, size_t size);

-- 
1.8.0

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [RFC PATCH 2/2] Localize diff and log output
  2012-10-23 12:24 [RFC PATCH 0/2] Localize log output Peter Krefting
  2012-10-23 12:25 ` [RFC PATCH 1/2] Use localized date in " Peter Krefting
@ 2012-10-23 12:25 ` Peter Krefting
  1 sibling, 0 replies; 3+ messages in thread
From: Peter Krefting @ 2012-10-23 12:25 UTC (permalink / raw)
  To: Git Mailing List

The output of "git diff --stat", "git show --stat" and "git log" should be
translated to the local user language. The output of "git format-patch"
should not, however. Add localization where needed, and add a flag for
making sure that "format-patch"'s output remains in English.

This partially reverts commit 218adaaaa064c436115dbcd5705a0e2c42e90a25 (Revert
diffstat back to English; 2012-09-13).
---
  builtin/apply.c  |  2 +-
  builtin/commit.c |  4 +--
  builtin/log.c    |  6 ++--
  commit.h         |  3 +-
  diff.c           | 22 +++++++++-----
  diff.h           |  5 +++-
  log-tree.c       | 11 +++++--
  pretty.c         | 87 +++++++++++++++++++++++++++++++++++++++++++-------------
  8 files changed, 104 insertions(+), 36 deletions(-)

diff --git a/builtin/apply.c b/builtin/apply.c
index 156b3ce..9ead305 100644
--- a/builtin/apply.c
+++ b/builtin/apply.c
@@ -3644,7 +3644,7 @@ static void stat_patch_list(struct patch *patch)
  		show_stats(patch);
  	}

-	print_stat_summary(stdout, files, adds, dels);
+	print_stat_summary(stdout, files, adds, dels, NULL);
  }

  static void numstat_patch_list(struct patch *patch)
diff --git a/builtin/commit.c b/builtin/commit.c
index a17a5df..406346e 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -1248,11 +1248,11 @@ static void print_summary(const char *prefix, const unsigned char *sha1,
  	format_commit_message(commit, "%an <%ae>", &author_ident, &pctx);
  	format_commit_message(commit, "%cn <%ce>", &committer_ident, &pctx);
  	if (strbuf_cmp(&author_ident, &committer_ident)) {
-		strbuf_addstr(&format, "\n Author: ");
+		strbuf_addstr(&format, _("\n Author: "));
  		strbuf_addbuf_percentquote(&format, &author_ident);
  	}
  	if (!user_ident_sufficiently_given()) {
-		strbuf_addstr(&format, "\n Committer: ");
+		strbuf_addstr(&format, _("\n Committer: "));
  		strbuf_addbuf_percentquote(&format, &committer_ident);
  		if (advice_implicit_identity) {
  			strbuf_addch(&format, '\n');
diff --git a/builtin/log.c b/builtin/log.c
index 09cf43e..0c579d7 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -381,7 +381,7 @@ static void show_tagger(char *buf, int len, struct rev_info *rev)

  	pp.fmt = rev->commit_format;
  	pp.date_mode = rev->date_mode;
-	pp_user_info(&pp, "Tagger", &out, buf, get_log_output_encoding());
+	pp_user_info(&pp, _("Tagger"), _("TaggerDate"), 0, &out, buf, get_log_output_encoding());
  	printf("%s", out.buf);
  	strbuf_release(&out);
  }
@@ -804,7 +804,7 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
  	msg = body;
  	pp.fmt = CMIT_FMT_EMAIL;
  	pp.date_mode = DATE_RFC2822;
-	pp_user_info(&pp, NULL, &sb, committer, encoding);
+	pp_user_info(&pp, NULL, NULL, 0, &sb, committer, encoding);
  	pp_title_line(&pp, &msg, &sb, encoding, need_8bit_cte);
  	pp_remainder(&pp, &msg, &sb, 0);
  	add_branch_description(&sb, branch_name);
@@ -1222,6 +1222,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)

  	/* Always generate a patch */
  	rev.diffopt.output_format |= DIFF_FORMAT_PATCH;
+	/* Never translate format-patch output */
+	rev.diffopt.output_format |= DIFF_FORMAT_ENGLISH;

  	if (!DIFF_OPT_TST(&rev.diffopt, TEXT) && !no_binary_diff)
  		DIFF_OPT_SET(&rev.diffopt, BINARY);
diff --git a/commit.h b/commit.h
index 9f21313..2a9ac6a 100644
--- a/commit.h
+++ b/commit.h
@@ -114,7 +114,8 @@ extern void pretty_print_commit(const struct pretty_print_context *pp,
  extern void pp_commit_easy(enum cmit_fmt fmt, const struct commit *commit,
  			   struct strbuf *sb);
  void pp_user_info(const struct pretty_print_context *pp,
-		  const char *what, struct strbuf *sb,
+		  const char *what, const char *whatdate, int extra_padding,
+		  struct strbuf *sb,
  		  const char *line, const char *encoding);
  void pp_title_line(const struct pretty_print_context *pp,
  		   const char **msg_p,
diff --git a/diff.c b/diff.c
index 35d3f07..ef655d1 100644
--- a/diff.c
+++ b/diff.c
@@ -1391,18 +1391,22 @@ static void fill_print_name(struct diffstat_file *file)
  	file->print_name = pname;
  }

-int print_stat_summary(FILE *fp, int files, int insertions, int deletions)
+int print_stat_summary(FILE *fp, int files, int insertions, int deletions, struct diff_options *options)
  {
  	struct strbuf sb = STRBUF_INIT;
  	int ret;

+	int english = options && !!(options->output_format & DIFF_FORMAT_ENGLISH);
+
  	if (!files) {
  		assert(insertions == 0 && deletions == 0);
-		return fprintf(fp, "%s\n", " 0 files changed");
+		return fprintf(fp, "%s\n", english ? " 0 files changed"
+		                                   : _(" 0 files changed"));
  	}

  	strbuf_addf(&sb,
-		    (files == 1) ? " %d file changed" : " %d files changed",
+		    english ? ((files == 1) ? " %d file changed" : " %d files changed")
+		            : Q_(" %d file changed", " %d files changed", files),
  		    files);

  	/*
@@ -1419,7 +1423,9 @@ int print_stat_summary(FILE *fp, int files, int insertions, int deletions)
  		 * do not translate it.
  		 */
  		strbuf_addf(&sb,
-			    (insertions == 1) ? ", %d insertion(+)" : ", %d insertions(+)",
+			    english ? ((insertions == 1) ? ", %d insertion(+)" : ", %d insertions(+)")
+			            : Q_(", %d insertion(+)", ", %d insertions(+)",
+			                 insertions),
  			    insertions);
  	}

@@ -1429,7 +1435,9 @@ int print_stat_summary(FILE *fp, int files, int insertions, int deletions)
  		 * do not translate it.
  		 */
  		strbuf_addf(&sb,
-			    (deletions == 1) ? ", %d deletion(-)" : ", %d deletions(-)",
+			    english ? ((deletions == 1) ? ", %d deletion(-)" : ", %d deletions(-)")
+			            : Q_(", %d deletion(-)", ", %d deletions(-)",
+			                 deletions),
  			    deletions);
  	}
  	strbuf_addch(&sb, '\n');
@@ -1681,7 +1689,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
  		extra_shown = 1;
  	}
  	fprintf(options->file, "%s", line_prefix);
-	print_stat_summary(options->file, total_files, adds, dels);
+	print_stat_summary(options->file, total_files, adds, dels, options);
  }

  static void show_shortstats(struct diffstat_t *data, struct diff_options *options)
@@ -1710,7 +1718,7 @@ static void show_shortstats(struct diffstat_t *data, struct diff_options *option
  				options->output_prefix_data);
  		fprintf(options->file, "%s", msg->buf);
  	}
-	print_stat_summary(options->file, total_files, adds, dels);
+	print_stat_summary(options->file, total_files, adds, dels, options);
  }

  static void show_numstat(struct diffstat_t *data, struct diff_options *options)
diff --git a/diff.h b/diff.h
index a658f85..73684f7 100644
--- a/diff.h
+++ b/diff.h
@@ -54,6 +54,9 @@ typedef struct strbuf *(*diff_prefix_fn_t)(struct diff_options *opt, void *data)

  #define DIFF_FORMAT_CALLBACK	0x1000

+/* Never output translated content, used by format-patch et.al */
+#define DIFF_FORMAT_ENGLISH		0x2000
+
  #define DIFF_OPT_RECURSIVE           (1 <<  0)
  #define DIFF_OPT_TREE_IN_RECURSIVE   (1 <<  1)
  #define DIFF_OPT_BINARY              (1 <<  2)
@@ -334,6 +337,6 @@ extern struct userdiff_driver *get_textconv(struct diff_filespec *one);
  extern int parse_rename_score(const char **cp_p);

  extern int print_stat_summary(FILE *fp, int files,
-			      int insertions, int deletions);
+			      int insertions, int deletions, struct diff_options *options);

  #endif /* DIFF_H */
diff --git a/log-tree.c b/log-tree.c
index c894930..0f68413 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -601,8 +601,12 @@ void show_log(struct rev_info *opt)
  					&ctx.need_8bit_cte);
  	} else if (opt->commit_format != CMIT_FMT_USERFORMAT) {
  		fputs(diff_get_color_opt(&opt->diffopt, DIFF_COMMIT), stdout);
+		/*
+		 * TRANSLATORS: This string precedes the commit identifier in git log
+		 * output.
+		 */
  		if (opt->commit_format != CMIT_FMT_ONELINE)
-			fputs("commit ", stdout);
+			fputs(_("commit "), stdout);

  		if (!opt->graph)
  			put_revision_mark(opt, commit);
@@ -612,8 +616,11 @@ void show_log(struct rev_info *opt)
  			show_parents(commit, abbrev_commit);
  		if (opt->children.name)
  			show_children(opt, commit, abbrev_commit);
+		/*
+		 * TRANSLATORS: %s is a commit identifier.
+		 */
  		if (parent)
-			printf(" (from %s)",
+			printf(_(" (from %s)"),
  			       find_unique_abbrev(parent->object.sha1,
  						  abbrev_commit));
  		show_decorations(opt, commit);
diff --git a/pretty.c b/pretty.c
index 8b1ea9f..8623bbd 100644
--- a/pretty.c
+++ b/pretty.c
@@ -320,7 +320,8 @@ needquote:
  }

  void pp_user_info(const struct pretty_print_context *pp,
-		  const char *what, struct strbuf *sb,
+		  const char *what, const char *whatdate, int extra_padding,
+		  struct strbuf *sb,
  		  const char *line, const char *encoding)
  {
  	char *date;
@@ -365,24 +366,37 @@ void pp_user_info(const struct pretty_print_context *pp,
  		}
  		strbuf_add(sb, name_tail, namelen - display_name_length);
  		strbuf_addch(sb, '\n');
-	} else {
-		strbuf_addf(sb, "%s: %.*s%.*s\n", what,
-			      (pp->fmt == CMIT_FMT_FULLER) ? 4 : 0,
-			      "    ", namelen, line);
-	}
-	switch (pp->fmt) {
-	case CMIT_FMT_MEDIUM:
-		strbuf_addf(sb, "Date:   %s\n", show_date(time, tz, pp->date_mode));
-		break;
-	case CMIT_FMT_EMAIL:
  		strbuf_addf(sb, "Date: %s\n", show_date(time, tz, DATE_RFC2822));
-		break;
-	case CMIT_FMT_FULLER:
-		strbuf_addf(sb, "%sDate: %s\n", what, show_date(time, tz, pp->date_mode));
-		break;
-	default:
-		/* notin' */
-		break;
+	} else {
+		/*
+		 * Calculate the padding to use to get the two fields we are outputting
+		 * here aligned. We are passed the padding we need to get these fields
+		 * aligned with whatever fields are output in other calls to
+		 * pp_user_info().
+		 *
+		 * FIXME: strlen() used to measure string width; should use mblen()
+		 * or similar, but since that is expensive, it should be done further
+		 * up the callstack, not on each commit. */
+		int datelen = 0, whatlen = 0;
+
+		if (pp->fmt != CMIT_FMT_FULLER)
+			whatdate = _("Date");
+		if (pp->fmt == CMIT_FMT_MEDIUM || pp->fmt == CMIT_FMT_FULLER) {
+			datelen = whatdate ? strlen(whatdate) : 0;
+			whatlen = what ? strlen(what) : 0;
+		}
+
+		strbuf_addf(sb, "%s: %.*s%.*s%.*s\n", what,
+		            (datelen > whatlen ? datelen - whatlen : 0), "                ",
+		            extra_padding, "                ",
+			        namelen, line);
+
+ 		if (pp->fmt == CMIT_FMT_MEDIUM || pp->fmt == CMIT_FMT_FULLER) {
+			strbuf_addf(sb, "%s: %.*s%.*s%s\n", whatdate,
+				        (whatlen > datelen ? whatlen - datelen : 0), "                ",
+			            extra_padding, "                ",
+			            show_date(time, tz, pp->date_mode));
+		}
  	}
  }

@@ -1218,6 +1232,39 @@ static void pp_header(const struct pretty_print_context *pp,
  		      struct strbuf *sb)
  {
  	int parents_shown = 0;
+	const char *author_label = _("Author");
+	const char *authordate_label = _("AuthorDate");
+	const char *commit_label = _("Commit");
+	const char *commitdate_label = _("CommitDate");
+	int extra_padding_author = 0, extra_padding_commit = 0;
+
+	/*
+	 * Calculate the padding to use to get all the fields aligned.
+	 *
+	 * pp_user_info() makes sure to align the Author and Date strings, but
+	 * we aso need to align between the Author and Commit block (if outputting
+	 * FULL or FULLER
+	 *
+	 * FIXME: strlen() used to measure string width; should use mblen()
+	 * or similar, but since that is expensive, it should be done further
+	 * up the callstack, not on each commit. */
+	if (pp->fmt == CMIT_FMT_FULL || pp->fmt == CMIT_FMT_FULLER) {
+		int author_label_width = strlen(author_label);
+		int commit_label_width = strlen(commit_label);
+
+		if (pp->fmt == CMIT_FMT_FULLER) {
+			int authordate_label_width = strlen(authordate_label);
+			int commitdate_label_width = strlen(commitdate_label);
+			if (authordate_label_width > author_label_width)
+				author_label_width = authordate_label_width;
+			if (commitdate_label_width > commit_label_width)
+				commit_label_width = commitdate_label_width;
+		}
+		extra_padding_author = commit_label_width > author_label_width
+			? commit_label_width - author_label_width : 0; 
+		extra_padding_commit = author_label_width > commit_label_width
+			? author_label_width - commit_label_width : 0; 
+	}

  	for (;;) {
  		const char *line = *msg_p;
@@ -1262,12 +1309,12 @@ static void pp_header(const struct pretty_print_context *pp,
  		 */
  		if (!memcmp(line, "author ", 7)) {
  			strbuf_grow(sb, linelen + 80);
-			pp_user_info(pp, "Author", sb, line + 7, encoding);
+			pp_user_info(pp, author_label, authordate_label, extra_padding_author, sb, line + 7, encoding);
  		}
  		if (!memcmp(line, "committer ", 10) &&
  		    (pp->fmt == CMIT_FMT_FULL || pp->fmt == CMIT_FMT_FULLER)) {
  			strbuf_grow(sb, linelen + 80);
-			pp_user_info(pp, "Commit", sb, line + 10, encoding);
+			pp_user_info(pp, commit_label, commitdate_label, extra_padding_commit, sb, line + 10, encoding);
  		}
  	}
  }
-- 
1.8.0

^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2012-10-23 12:25 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-10-23 12:24 [RFC PATCH 0/2] Localize log output Peter Krefting
2012-10-23 12:25 ` [RFC PATCH 1/2] Use localized date in " Peter Krefting
2012-10-23 12:25 ` [RFC PATCH 2/2] Localize diff and " Peter Krefting

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).