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 <gits...@pobox.com>
---
 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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to