Browse Source

Merge branch 'rs/maint-tformat-foldline' into maint

* rs/maint-tformat-foldline:
  pretty: support multiline subjects with format:
  pretty: factor out format_subject()
  pretty: factor out skip_empty_lines()
maint
Junio C Hamano 16 years ago
parent
commit
a9012e343e
  1. 119
      pretty.c

119
pretty.c

@ -181,6 +181,20 @@ static int is_empty_line(const char *line, int *len_p)
return !len; return !len;
} }


static const char *skip_empty_lines(const char *msg)
{
for (;;) {
int linelen = get_one_line(msg);
int ll = linelen;
if (!linelen)
break;
if (!is_empty_line(msg, &ll))
break;
msg += linelen;
}
return msg;
}

static void add_merge_info(enum cmit_fmt fmt, struct strbuf *sb, static void add_merge_info(enum cmit_fmt fmt, struct strbuf *sb,
const struct commit *commit, int abbrev) const struct commit *commit, int abbrev)
{ {
@ -410,13 +424,15 @@ struct chunk {
struct format_commit_context { struct format_commit_context {
const struct commit *commit; const struct commit *commit;
enum date_mode dmode; enum date_mode dmode;
unsigned commit_header_parsed:1;
unsigned commit_message_parsed:1;


/* These offsets are relative to the start of the commit message. */ /* These offsets are relative to the start of the commit message. */
int commit_header_parsed;
struct chunk subject;
struct chunk author; struct chunk author;
struct chunk committer; struct chunk committer;
struct chunk encoding; struct chunk encoding;
size_t message_off;
size_t subject_off;
size_t body_off; size_t body_off;


/* The following ones are relative to the result struct strbuf. */ /* The following ones are relative to the result struct strbuf. */
@ -446,23 +462,14 @@ static void parse_commit_header(struct format_commit_context *context)
{ {
const char *msg = context->commit->buffer; const char *msg = context->commit->buffer;
int i; int i;
enum { HEADER, SUBJECT, BODY } state;


for (i = 0, state = HEADER; msg[i] && state < BODY; i++) { for (i = 0; msg[i]; i++) {
int eol; int eol;
for (eol = i; msg[eol] && msg[eol] != '\n'; eol++) for (eol = i; msg[eol] && msg[eol] != '\n'; eol++)
; /* do nothing */ ; /* do nothing */


if (state == SUBJECT) {
context->subject.off = i;
context->subject.len = eol - i;
i = eol;
}
if (i == eol) { if (i == eol) {
state++; break;
/* strip empty lines */
while (msg[eol] == '\n' && msg[eol + 1] == '\n')
eol++;
} else if (!prefixcmp(msg + i, "author ")) { } else if (!prefixcmp(msg + i, "author ")) {
context->author.off = i + 7; context->author.off = i + 7;
context->author.len = eol - i - 7; context->author.len = eol - i - 7;
@ -474,13 +481,50 @@ static void parse_commit_header(struct format_commit_context *context)
context->encoding.len = eol - i - 9; context->encoding.len = eol - i - 9;
} }
i = eol; i = eol;
if (!msg[i])
break;
} }
context->body_off = i; context->message_off = i;
context->commit_header_parsed = 1; context->commit_header_parsed = 1;
} }


static const char *format_subject(struct strbuf *sb, const char *msg,
const char *line_separator)
{
int first = 1;

for (;;) {
const char *line = msg;
int linelen = get_one_line(line);

msg += linelen;
if (!linelen || is_empty_line(line, &linelen))
break;

if (!sb)
continue;
strbuf_grow(sb, linelen + 2);
if (!first)
strbuf_addstr(sb, line_separator);
strbuf_add(sb, line, linelen);
first = 0;
}
return msg;
}

static void parse_commit_message(struct format_commit_context *c)
{
const char *msg = c->commit->buffer + c->message_off;
const char *start = c->commit->buffer;

msg = skip_empty_lines(msg);
c->subject_off = msg - start;

msg = format_subject(NULL, msg, NULL);
msg = skip_empty_lines(msg);
c->body_off = msg - start;

c->commit_message_parsed = 1;
}

static void format_decoration(struct strbuf *sb, const struct commit *commit) static void format_decoration(struct strbuf *sb, const struct commit *commit)
{ {
struct name_decoration *d; struct name_decoration *d;
@ -600,9 +644,6 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
parse_commit_header(c); parse_commit_header(c);


switch (placeholder[0]) { switch (placeholder[0]) {
case 's': /* subject */
strbuf_add(sb, msg + c->subject.off, c->subject.len);
return 1;
case 'a': /* author ... */ case 'a': /* author ... */
return format_person_part(sb, placeholder[1], return format_person_part(sb, placeholder[1],
msg + c->author.off, c->author.len, msg + c->author.off, c->author.len,
@ -614,6 +655,16 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
case 'e': /* encoding */ case 'e': /* encoding */
strbuf_add(sb, msg + c->encoding.off, c->encoding.len); strbuf_add(sb, msg + c->encoding.off, c->encoding.len);
return 1; return 1;
}

/* Now we need to parse the commit message. */
if (!c->commit_message_parsed)
parse_commit_message(c);

switch (placeholder[0]) {
case 's': /* subject */
format_subject(sb, msg + c->subject_off, " ");
return 1;
case 'b': /* body */ case 'b': /* body */
strbuf_addstr(sb, msg + c->body_off); strbuf_addstr(sb, msg + c->body_off);
return 1; return 1;
@ -704,27 +755,11 @@ void pp_title_line(enum cmit_fmt fmt,
const char *encoding, const char *encoding,
int need_8bit_cte) int need_8bit_cte)
{ {
const char *line_separator = (fmt == CMIT_FMT_EMAIL) ? "\n " : " ";
struct strbuf title; struct strbuf title;


strbuf_init(&title, 80); strbuf_init(&title, 80);

*msg_p = format_subject(&title, *msg_p, line_separator);
for (;;) {
const char *line = *msg_p;
int linelen = get_one_line(line);

*msg_p += linelen;
if (!linelen || is_empty_line(line, &linelen))
break;

strbuf_grow(&title, linelen + 2);
if (title.len) {
if (fmt == CMIT_FMT_EMAIL) {
strbuf_addch(&title, '\n');
}
strbuf_addch(&title, ' ');
}
strbuf_add(&title, line, linelen);
}


strbuf_grow(sb, title.len + 1024); strbuf_grow(sb, title.len + 1024);
if (subject) { if (subject) {
@ -850,15 +885,7 @@ void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,
} }


/* Skip excess blank lines at the beginning of body, if any... */ /* Skip excess blank lines at the beginning of body, if any... */
for (;;) { msg = skip_empty_lines(msg);
int linelen = get_one_line(msg);
int ll = linelen;
if (!linelen)
break;
if (!is_empty_line(msg, &ll))
break;
msg += linelen;
}


/* These formats treat the title line specially. */ /* These formats treat the title line specially. */
if (fmt == CMIT_FMT_ONELINE || fmt == CMIT_FMT_EMAIL) if (fmt == CMIT_FMT_ONELINE || fmt == CMIT_FMT_EMAIL)

Loading…
Cancel
Save