[PATCH 1/2] date: refactor the relative date logic from presentation

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Separate the logic to decide which presentation (e.g. "N months") to
use based on the length of the time from the present and actual
presentation (i.e. "strbuf_addf()").  This is not strictly needed
but will make the next step easier to read.

The format strings lost N_() markings along the way; help from the
i18n folks to come up with the best and sane way to mark them up is
very much appreciated.

Signed-off-by: Junio C Hamano <gitster@xxxxxxxxx>
---
 date.c | 170 ++++++++++++++++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 127 insertions(+), 43 deletions(-)

diff --git a/date.c b/date.c
index 57331ed..b6ff04e 100644
--- a/date.c
+++ b/date.c
@@ -86,78 +86,162 @@ static int local_tzoffset(unsigned long time)
 	return offset * eastwest;
 }
 
-void show_date_relative(unsigned long time, int tz,
-			       const struct timeval *now,
-			       struct strbuf *timebuf)
+enum relative_style {
+	rd_seconds = 0, rd_minutes, rd_hours, rd_days, rd_weeks, rd_months, rd_years
+};
+
+struct relative_date {
+	int seconds;
+	int minutes;
+	int hours;
+	int days;
+	int weeks;
+	int months;
+	int years;
+};
+
+static enum relative_style format_relative_date(unsigned long diff,
+						struct relative_date *rd)
 {
-	unsigned long diff;
-	if (now->tv_sec < time) {
-		strbuf_addstr(timebuf, _("in the future"));
-		return;
-	}
-	diff = now->tv_sec - time;
+	memset(rd, 0, sizeof(*rd));
 	if (diff < 90) {
-		strbuf_addf(timebuf,
-			 Q_("%lu second ago", "%lu seconds ago", diff), diff);
-		return;
+		rd->seconds = diff;
+		return rd_seconds;
 	}
 	/* Turn it into minutes */
 	diff = (diff + 30) / 60;
 	if (diff < 90) {
-		strbuf_addf(timebuf,
-			 Q_("%lu minute ago", "%lu minutes ago", diff), diff);
-		return;
+		rd->minutes = diff;
+		return rd_minutes;
 	}
 	/* Turn it into hours */
 	diff = (diff + 30) / 60;
 	if (diff < 36) {
-		strbuf_addf(timebuf,
-			 Q_("%lu hour ago", "%lu hours ago", diff), diff);
-		return;
+		rd->hours = diff;
+		return rd_hours;
 	}
 	/* We deal with number of days from here on */
 	diff = (diff + 12) / 24;
 	if (diff < 14) {
-		strbuf_addf(timebuf,
-			 Q_("%lu day ago", "%lu days ago", diff), diff);
-		return;
+		rd->days = diff;
+		return rd_days;
 	}
 	/* Say weeks for the past 10 weeks or so */
 	if (diff < 70) {
-		strbuf_addf(timebuf,
-			 Q_("%lu week ago", "%lu weeks ago", (diff + 3) / 7),
-			 (diff + 3) / 7);
-		return;
+		rd->weeks = (diff + 3) / 7;
+		return rd_weeks;
 	}
 	/* Say months for the past 12 months or so */
 	if (diff < 365) {
-		strbuf_addf(timebuf,
-			 Q_("%lu month ago", "%lu months ago", (diff + 15) / 30),
-			 (diff + 15) / 30);
-		return;
+		rd->months = (diff + 15) / 30;
+		return rd_months;
 	}
 	/* Give years and months for 5 years or so */
 	if (diff < 1825) {
 		unsigned long totalmonths = (diff * 12 * 2 + 365) / (365 * 2);
-		unsigned long years = totalmonths / 12;
-		unsigned long months = totalmonths % 12;
-		if (months) {
+		rd->years = totalmonths / 12;
+		rd->months = totalmonths % 12;
+		return rd_years;
+	}
+	/* Otherwise, just years. Centuries is probably overkill. */
+	rd->years = (diff + 183) / 365;
+	return rd_years;
+}
+
+void show_date_relative(unsigned long time, int tz,
+			       const struct timeval *now,
+			       struct strbuf *timebuf)
+{
+	unsigned long diff;
+	struct relative_date rd;
+	int pf = 0; /* past or future */
+
+	struct {
+		struct { const char *s, *p; } msg_seconds;
+		struct { const char *s, *p; } msg_minutes;
+		struct { const char *s, *p; } msg_hours;
+		struct { const char *s, *p; } msg_days;
+		struct { const char *s, *p; } msg_weeks;
+		struct { const char *s, *p; } msg_months;
+		struct { const char *s, *p; } msg_years_only;
+		struct { const char *s, *p; } msg_years_months;
+		struct { const char *s, *p; } msg_years;
+	} msg[1] = {
+		{
+			{ "%lu second ago", "%lu seconds ago" },
+			{ "%lu minute ago", "%lu minutes ago" },
+			{ "%lu hour ago", "%lu hours ago" },
+			{ "%lu day ago", "%lu days ago" },
+			{ "%lu week ago", "%lu weeks ago" },
+			{ "%lu month ago", "%lu months ago" },
+			{ "%lu year", "%lu years" },
+			{
+				/* TRANSLATORS: "%s" is "<n> years" */
+				"%s, %lu month ago",
+				/* TRANSLATORS: "%s" is "<n> years" */
+				"%s, %lu months ago"
+			},
+			{ "%lu year ago", "%lu years ago" },
+		}
+	};
+
+	if (now->tv_sec < time) {
+		strbuf_addstr(timebuf, _("in the future"));
+		return;
+	}
+	diff = now->tv_sec - time;
+
+	switch (format_relative_date(diff, &rd)) {
+	case rd_seconds:
+		strbuf_addf(timebuf,
+			    Q_(msg[pf].msg_seconds.s, msg[pf].msg_seconds.p,
+			       rd.seconds), rd.seconds);
+		break;
+	case rd_minutes:
+		strbuf_addf(timebuf,
+			    Q_(msg[pf].msg_minutes.s, msg[pf].msg_minutes.p,
+			       rd.minutes), rd.minutes);
+		break;
+	case rd_hours:
+		strbuf_addf(timebuf,
+			    Q_(msg[pf].msg_hours.s, msg[pf].msg_hours.p,
+			       rd.hours), rd.hours);
+		break;
+	case rd_days:
+		strbuf_addf(timebuf,
+			    Q_(msg[pf].msg_days.s, msg[pf].msg_days.p,
+			       rd.days), rd.days);
+		break;
+	case rd_weeks:
+		strbuf_addf(timebuf,
+			    Q_(msg[pf].msg_weeks.s, msg[pf].msg_weeks.p,
+			       rd.weeks), rd.weeks);
+		break;
+	case rd_months:
+		strbuf_addf(timebuf,
+			    Q_(msg[pf].msg_months.s, msg[pf].msg_months.p,
+			       rd.months), rd.months);
+		break;
+
+	case rd_years:
+		if (rd.months) {
 			struct strbuf sb = STRBUF_INIT;
-			strbuf_addf(&sb, Q_("%lu year", "%lu years", years), years);
-			/* TRANSLATORS: "%s" is "<n> years" */
+			strbuf_addf(&sb, Q_(msg[pf].msg_years_only.s,
+					    msg[pf].msg_years_only.p,
+					    rd.years), rd.years);
 			strbuf_addf(timebuf,
-				 Q_("%s, %lu month ago", "%s, %lu months ago", months),
-				 sb.buf, months);
+				    Q_(msg[pf].msg_years_months.s,
+				       msg[pf].msg_years_months.p,
+				       rd.months),
+				    sb.buf, rd.months);
 			strbuf_release(&sb);
-		} else
+		} else {
 			strbuf_addf(timebuf,
-				 Q_("%lu year ago", "%lu years ago", years), years);
-		return;
+				    Q_(msg[pf].msg_years.s, msg[pf].msg_years.p,
+				       rd.years), rd.years);
+		}
+		break;
 	}
-	/* Otherwise, just years. Centuries is probably overkill. */
-	strbuf_addf(timebuf,
-		 Q_("%lu year ago", "%lu years ago", (diff + 183) / 365),
-		 (diff + 183) / 365);
 }
 
 const char *show_date(unsigned long time, int tz, enum date_mode mode)
-- 
1.7.12.rc3.69.gaf0166d

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]