Stefan Beller <sbeller@xxxxxxxxxx> writes: > In a later patch, I want to propose an option to detect&color > moved lines in a diff, which cannot be done in a one-pass over > the diff. Instead we need to go over the whole diff twice, > because we cannot detect the first line of the two corresponding > lines (+ and -) that got moved. > > So to prepare the diff machinery for two pass algorithms > (i.e. buffer it all up and then operate on the result), > move all emissions to places, such that the only emitting > function is emit_line_0. > > This covers emit_rewrite_lines. > > Signed-off-by: Stefan Beller <sbeller@xxxxxxxxxx> > --- > diff.c | 27 +++++++++++++++++++-------- > 1 file changed, 19 insertions(+), 8 deletions(-) > > diff --git a/diff.c b/diff.c > index 3dda9f3c8e..690794aeb8 100644 > --- a/diff.c > +++ b/diff.c > @@ -722,15 +722,25 @@ static void add_line_count(struct strbuf *out, int count) > static void emit_rewrite_lines(struct emit_callback *ecb, > int prefix, const char *data, int size) > { > - const char *endp = NULL; > - static const char *nneof = " No newline at end of file\n"; > const char *reset = diff_get_color(ecb->color_diff, DIFF_RESET); > + struct strbuf sb = STRBUF_INIT; > > while (0 < size) { > int len; > > - endp = memchr(data, '\n', size); > - len = endp ? (endp - data + 1) : size; > + const char *endp = memchr(data, '\n', size); > + if (endp) > + len = endp - data + 1; > + else { This side does not initialize "len" at all, which means ... > + while (0 < size) { > + strbuf_addch(&sb, *data); > + size -= len; > + data += len; ... we do random computation here. > + } > + strbuf_addch(&sb, '\n'); > + data = sb.buf; > + len = sb.len; > + } > if (prefix != '+') { > ecb->lno_in_preimage++; > emit_del_line(reset, ecb, data, len); > @@ -741,12 +751,13 @@ static void emit_rewrite_lines(struct emit_callback *ecb, > size -= len; > data += len; > } > - if (!endp) { > + if (sb.len) { > + static const char *nneof = "\\ No newline at end of file\n"; > const char *context = diff_get_color(ecb->color_diff, > DIFF_CONTEXT); > - putc('\n', ecb->opt->file); > - emit_line(ecb->opt, context, reset, 1, '\\', > - nneof, strlen(nneof)); > + emit_line(ecb->opt, context, reset, 1, 0, > + nneof, strlen(nneof)); > + strbuf_release(&sb); > } > }