Skip to content

Commit

Permalink
convert "enum date_mode" into a struct
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jeff King authored and Junio C Hamano committed Jun 29, 2015
1 parent b7c1e11 commit a5481a6
Show file tree
Hide file tree
Showing 23 changed files with 97 additions and 77 deletions.
2 changes: 1 addition & 1 deletion archive.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ static void format_subst(const struct commit *commit,
char *to_free = NULL;
struct strbuf fmt = STRBUF_INIT;
struct pretty_print_context ctx = {0};
ctx.date_mode = DATE_NORMAL;
ctx.date_mode.type = DATE_NORMAL;
ctx.abbrev = DEFAULT_ABBREV;

if (src == buf->buf)
Expand Down
10 changes: 5 additions & 5 deletions builtin/blame.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ static int xdl_opts;
static int abbrev = -1;
static int no_whole_file_rename;

static enum date_mode blame_date_mode = DATE_ISO8601;
static struct date_mode blame_date_mode = { DATE_ISO8601 };
static size_t blame_date_width;

static struct string_list mailmap;
Expand Down Expand Up @@ -1827,7 +1827,7 @@ static const char *format_time(unsigned long time, const char *tz_str,
size_t time_width;
int tz;
tz = atoi(tz_str);
time_str = show_date(time, tz, blame_date_mode);
time_str = show_date(time, tz, &blame_date_mode);
strbuf_addstr(&time_buf, time_str);
/*
* Add space paddings to time_buf to display a fixed width
Expand Down Expand Up @@ -2187,7 +2187,7 @@ static int git_blame_config(const char *var, const char *value, void *cb)
if (!strcmp(var, "blame.date")) {
if (!value)
return config_error_nonbool(var);
blame_date_mode = parse_date_format(value);
parse_date_format(value, &blame_date_mode);
return 0;
}

Expand Down Expand Up @@ -2569,13 +2569,13 @@ int cmd_blame(int argc, const char **argv, const char *prefix)

if (cmd_is_annotate) {
output_option |= OUTPUT_ANNOTATE_COMPAT;
blame_date_mode = DATE_ISO8601;
blame_date_mode.type = DATE_ISO8601;
} else {
blame_date_mode = revs.date_mode;
}

/* The maximum width used to show the dates */
switch (blame_date_mode) {
switch (blame_date_mode.type) {
case DATE_RFC2822:
blame_date_width = sizeof("Thu, 19 Oct 2006 16:00:04 -0700");
break;
Expand Down
4 changes: 2 additions & 2 deletions builtin/commit.c
Original file line number Diff line number Diff line change
Expand Up @@ -856,7 +856,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
_("%s"
"Date: %s"),
ident_shown++ ? "" : "\n",
show_ident_date(&ai, DATE_NORMAL));
show_ident_date(&ai, DATE_MODE(NORMAL)));

if (!committer_ident_sufficiently_given())
status_printf_ln(s, GIT_COLOR_NORMAL,
Expand Down Expand Up @@ -1046,7 +1046,7 @@ static const char *find_author_by_nickname(const char *name)
commit = get_revision(&revs);
if (commit) {
struct pretty_print_context ctx = {0};
ctx.date_mode = DATE_NORMAL;
ctx.date_mode.type = DATE_NORMAL;
strbuf_release(&buf);
format_commit_message(commit, "%aN <%aE>", &buf, &ctx);
clear_mailmap(&mailmap);
Expand Down
6 changes: 3 additions & 3 deletions builtin/for-each-ref.c
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ static void grab_date(const char *buf, struct atom_value *v, const char *atomnam
char *zone;
unsigned long timestamp;
long tz;
enum date_mode date_mode = DATE_NORMAL;
struct date_mode date_mode = { DATE_NORMAL };
const char *formatp;

/*
Expand All @@ -401,7 +401,7 @@ static void grab_date(const char *buf, struct atom_value *v, const char *atomnam
formatp = strchr(atomname, ':');
if (formatp != NULL) {
formatp++;
date_mode = parse_date_format(formatp);
parse_date_format(formatp, &date_mode);
}

if (!eoemail)
Expand All @@ -412,7 +412,7 @@ static void grab_date(const char *buf, struct atom_value *v, const char *atomnam
tz = strtol(zone, NULL, 10);
if ((tz == LONG_MIN || tz == LONG_MAX) && errno == ERANGE)
goto bad;
v->s = xstrdup(show_date(timestamp, tz, date_mode));
v->s = xstrdup(show_date(timestamp, tz, &date_mode));
v->ul = timestamp;
return;
bad:
Expand Down
4 changes: 2 additions & 2 deletions builtin/log.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ static void cmd_log_init_defaults(struct rev_info *rev)
DIFF_OPT_SET(&rev->diffopt, ALLOW_TEXTCONV);

if (default_date_mode)
rev->date_mode = parse_date_format(default_date_mode);
parse_date_format(default_date_mode, &rev->date_mode);
rev->diffopt.touched_flags = 0;
}

Expand Down Expand Up @@ -939,7 +939,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.date_mode.type = DATE_RFC2822;
pp_user_info(&pp, NULL, &sb, committer, encoding);
pp_title_line(&pp, &msg, &sb, encoding, need_8bit_cte);
pp_remainder(&pp, &msg, &sb, 0);
Expand Down
2 changes: 1 addition & 1 deletion builtin/shortlog.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ void shortlog_add_commit(struct shortlog *log, struct commit *commit)
ctx.abbrev = log->abbrev;
ctx.subject = "";
ctx.after_subject = "";
ctx.date_mode = DATE_NORMAL;
ctx.date_mode.type = DATE_NORMAL;
ctx.output_encoding = get_log_output_encoding();
pretty_print_commit(&ctx, commit, &ufbuf);
buffer = ufbuf.buf;
Expand Down
3 changes: 2 additions & 1 deletion builtin/show-branch.c
Original file line number Diff line number Diff line change
Expand Up @@ -784,7 +784,8 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
else
msg++;
reflog_msg[i] = xstrfmt("(%s) %s",
show_date(timestamp, tz, DATE_RELATIVE),
show_date(timestamp, tz,
DATE_MODE(RELATIVE)),
msg);
free(logmsg);
sprintf(nth_desc, "%s@{%d}", *av, base+i);
Expand Down
35 changes: 23 additions & 12 deletions cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -1105,18 +1105,28 @@ extern void *read_object_with_reference(const unsigned char *sha1,
extern struct object *peel_to_type(const char *name, int namelen,
struct object *o, enum object_type);

enum date_mode {
DATE_NORMAL = 0,
DATE_RELATIVE,
DATE_SHORT,
DATE_LOCAL,
DATE_ISO8601,
DATE_ISO8601_STRICT,
DATE_RFC2822,
DATE_RAW
struct date_mode {
enum date_mode_type {
DATE_NORMAL = 0,
DATE_RELATIVE,
DATE_SHORT,
DATE_LOCAL,
DATE_ISO8601,
DATE_ISO8601_STRICT,
DATE_RFC2822,
DATE_RAW
} type;
};

const char *show_date(unsigned long time, int timezone, enum date_mode mode);
/*
* Convenience helper for passing a constant type, like:
*
* show_date(t, tz, DATE_MODE(NORMAL));
*/
#define DATE_MODE(t) date_mode_from_type(DATE_##t)
struct date_mode *date_mode_from_type(enum date_mode_type type);

const char *show_date(unsigned long time, int timezone, const struct date_mode *mode);
void show_date_relative(unsigned long time, int tz, const struct timeval *now,
struct strbuf *timebuf);
int parse_date(const char *date, struct strbuf *out);
Expand All @@ -1126,7 +1136,7 @@ void datestamp(struct strbuf *out);
#define approxidate(s) approxidate_careful((s), NULL)
unsigned long approxidate_careful(const char *, int *);
unsigned long approxidate_relative(const char *date, const struct timeval *now);
enum date_mode parse_date_format(const char *format);
void parse_date_format(const char *format, struct date_mode *mode);
int date_overflows(unsigned long date);

#define IDENT_STRICT 1
Expand Down Expand Up @@ -1163,7 +1173,8 @@ extern int split_ident_line(struct ident_split *, const char *, int);
* the ident_split. It will also sanity-check the values and produce
* a well-known sentinel date if they appear bogus.
*/
const char *show_ident_date(const struct ident_split *id, enum date_mode mode);
const char *show_ident_date(const struct ident_split *id,
const struct date_mode *mode);

/*
* Compare split idents for equality or strict ordering. Note that we
Expand Down
2 changes: 1 addition & 1 deletion commit.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ struct pretty_print_context {
const char *subject;
const char *after_subject;
int preserve_subject;
enum date_mode date_mode;
struct date_mode date_mode;
unsigned date_mode_explicit:1;
int need_8bit_cte;
char *notes_message;
Expand Down
43 changes: 25 additions & 18 deletions date.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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",
Expand All @@ -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,
Expand All @@ -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;
}
Expand Down Expand Up @@ -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);
}
Expand Down
2 changes: 1 addition & 1 deletion fast-import.c
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ static void write_crash_report(const char *err)
fprintf(rpt, "fast-import crash report:\n");
fprintf(rpt, " fast-import process: %"PRIuMAX"\n", (uintmax_t) getpid());
fprintf(rpt, " parent process : %"PRIuMAX"\n", (uintmax_t) getppid());
fprintf(rpt, " at %s\n", show_date(time(NULL), 0, DATE_LOCAL));
fprintf(rpt, " at %s\n", show_date(time(NULL), 0, DATE_MODE(LOCAL)));
fputc('\n', rpt);

fputs("fatal: ", rpt);
Expand Down
2 changes: 1 addition & 1 deletion http-backend.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ static void hdr_int(const char *name, uintmax_t value)

static void hdr_date(const char *name, unsigned long when)
{
const char *value = show_date(when, 0, DATE_RFC2822);
const char *value = show_date(when, 0, DATE_MODE(RFC2822));
hdr_str(name, value);
}

Expand Down
2 changes: 1 addition & 1 deletion log-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -639,7 +639,7 @@ void show_log(struct rev_info *opt)
*/
show_reflog_message(opt->reflog_info,
opt->commit_format == CMIT_FMT_ONELINE,
opt->date_mode,
&opt->date_mode,
opt->date_mode_explicit);
if (opt->commit_format == CMIT_FMT_ONELINE)
return;
Expand Down
Loading

0 comments on commit a5481a6

Please sign in to comment.