Stefan Beller <sbel...@google.com> 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 <sbel...@google.com>
> ---
>  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);
>       }
>  }

Reply via email to