diff options
author | Jeff King <peff@peff.net> | 2015-06-25 12:55:02 -0400 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2015-06-29 11:39:07 -0700 |
commit | a5481a6c9438cbd9c246cfa59ff49c31a0926fb6 (patch) | |
tree | 7992773f5ae1687c910e602b6286f3f1cbe116aa /date.c | |
parent | b7c1e11dc43e3dbd9eb2da20476c4c55dda5e84b (diff) | |
download | git-a5481a6c9438cbd9c246cfa59ff49c31a0926fb6.tar.gz git-a5481a6c9438cbd9c246cfa59ff49c31a0926fb6.tar.xz |
convert "enum date_mode" into a struct
In preparation for adding date modes that may carry extra
information beyond the mode itself, this patch converts the
date_mode enum into a struct.
Most of the conversion is fairly straightforward; we pass
the struct as a pointer and dereference the type field where
necessary. Locations that declare a date_mode can use a "{}"
constructor. However, the tricky case is where we use the
enum labels as constants, like:
show_date(t, tz, DATE_NORMAL);
Ideally we could say:
show_date(t, tz, &{ DATE_NORMAL });
but of course C does not allow that. Likewise, we cannot
cast the constant to a struct, because we need to pass an
actual address. Our options are basically:
1. Manually add a "struct date_mode d = { DATE_NORMAL }"
definition to each caller, and pass "&d". This makes
the callers uglier, because they sometimes do not even
have their own scope (e.g., they are inside a switch
statement).
2. Provide a pre-made global "date_normal" struct that can
be passed by address. We'd also need "date_rfc2822",
"date_iso8601", and so forth. But at least the ugliness
is defined in one place.
3. Provide a wrapper that generates the correct struct on
the fly. The big downside is that we end up pointing to
a single global, which makes our wrapper non-reentrant.
But show_date is already not reentrant, so it does not
matter.
This patch implements 3, along with a minor macro to keep
the size of the callers sane.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'date.c')
-rw-r--r-- | date.c | 43 |
1 files changed, 25 insertions, 18 deletions
@@ -160,18 +160,25 @@ void show_date_relative(unsigned long time, int tz, (diff + 183) / 365); } -const char *show_date(unsigned long time, int tz, enum date_mode mode) +struct date_mode *date_mode_from_type(enum date_mode_type type) +{ + static struct date_mode mode; + mode.type = type; + return &mode; +} + +const char *show_date(unsigned long time, int tz, const struct date_mode *mode) { struct tm *tm; static struct strbuf timebuf = STRBUF_INIT; - if (mode == DATE_RAW) { + if (mode->type == DATE_RAW) { strbuf_reset(&timebuf); strbuf_addf(&timebuf, "%lu %+05d", time, tz); return timebuf.buf; } - if (mode == DATE_RELATIVE) { + if (mode->type == DATE_RELATIVE) { struct timeval now; strbuf_reset(&timebuf); @@ -180,7 +187,7 @@ const char *show_date(unsigned long time, int tz, enum date_mode mode) return timebuf.buf; } - if (mode == DATE_LOCAL) + if (mode->type == DATE_LOCAL) tz = local_tzoffset(time); tm = time_to_tm(time, tz); @@ -190,17 +197,17 @@ const char *show_date(unsigned long time, int tz, enum date_mode mode) } strbuf_reset(&timebuf); - if (mode == DATE_SHORT) + if (mode->type == DATE_SHORT) strbuf_addf(&timebuf, "%04d-%02d-%02d", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday); - else if (mode == DATE_ISO8601) + else if (mode->type == DATE_ISO8601) strbuf_addf(&timebuf, "%04d-%02d-%02d %02d:%02d:%02d %+05d", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, tz); - else if (mode == DATE_ISO8601_STRICT) { + else if (mode->type == DATE_ISO8601_STRICT) { char sign = (tz >= 0) ? '+' : '-'; tz = abs(tz); strbuf_addf(&timebuf, "%04d-%02d-%02dT%02d:%02d:%02d%c%02d:%02d", @@ -209,7 +216,7 @@ const char *show_date(unsigned long time, int tz, enum date_mode mode) tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, sign, tz / 100, tz % 100); - } else if (mode == DATE_RFC2822) + } else if (mode->type == DATE_RFC2822) strbuf_addf(&timebuf, "%.3s, %d %.3s %d %02d:%02d:%02d %+05d", weekday_names[tm->tm_wday], tm->tm_mday, month_names[tm->tm_mon], tm->tm_year + 1900, @@ -221,7 +228,7 @@ const char *show_date(unsigned long time, int tz, enum date_mode mode) tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, tm->tm_year + 1900, - (mode == DATE_LOCAL) ? 0 : ' ', + (mode->type == DATE_LOCAL) ? 0 : ' ', tz); return timebuf.buf; } @@ -759,27 +766,27 @@ int parse_date(const char *date, struct strbuf *result) return 0; } -enum date_mode parse_date_format(const char *format) +void parse_date_format(const char *format, struct date_mode *mode) { if (!strcmp(format, "relative")) - return DATE_RELATIVE; + mode->type = DATE_RELATIVE; else if (!strcmp(format, "iso8601") || !strcmp(format, "iso")) - return DATE_ISO8601; + mode->type = DATE_ISO8601; else if (!strcmp(format, "iso8601-strict") || !strcmp(format, "iso-strict")) - return DATE_ISO8601_STRICT; + mode->type = DATE_ISO8601_STRICT; else if (!strcmp(format, "rfc2822") || !strcmp(format, "rfc")) - return DATE_RFC2822; + mode->type = DATE_RFC2822; else if (!strcmp(format, "short")) - return DATE_SHORT; + mode->type = DATE_SHORT; else if (!strcmp(format, "local")) - return DATE_LOCAL; + mode->type = DATE_LOCAL; else if (!strcmp(format, "default")) - return DATE_NORMAL; + mode->type = DATE_NORMAL; else if (!strcmp(format, "raw")) - return DATE_RAW; + mode->type = DATE_RAW; else die("unknown date format %s", format); } |