Stefan Beller <[email protected]> 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 <[email protected]>
> ---
> 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);
> }
> }