The branch main has been updated by des:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=4e859e67dde2cb4a583d340b27793a255f62f53e

commit 4e859e67dde2cb4a583d340b27793a255f62f53e
Author:     Dag-Erling Smørgrav <[email protected]>
AuthorDate: 2024-10-02 15:54:48 +0000
Commit:     Dag-Erling Smørgrav <[email protected]>
CommitDate: 2024-10-02 15:55:06 +0000

    libdiff: Implement diff coloring.
    
    This patch got accidentally left out when libdiff was imported.  The
    rest of the code (command-line option etc.) was present, just not the
    part that actually prints ANSI color codes.
    
    Sponsored by:   Klara, Inc.
    Reviewed by:    kevans
    Differential Revision:  https://reviews.freebsd.org/D46873
---
 contrib/libdiff/include/diff_output.h |  4 ++
 contrib/libdiff/lib/diff_output.c     | 69 ++++++++++++++++++++++++++++-------
 usr.bin/diff/diffreg_new.c            |  2 +
 3 files changed, 62 insertions(+), 13 deletions(-)

diff --git a/contrib/libdiff/include/diff_output.h 
b/contrib/libdiff/include/diff_output.h
index d2568c5a2b50..500ee6427574 100644
--- a/contrib/libdiff/include/diff_output.h
+++ b/contrib/libdiff/include/diff_output.h
@@ -110,3 +110,7 @@ int diff_output_chunk_right_version(struct diff_output_info 
**output_info,
 
 const char *diff_output_get_label_left(const struct diff_input_info *info);
 const char *diff_output_get_label_right(const struct diff_input_info *info);
+
+void diff_output_set_colors(bool _color,
+                           const char *_del_code,
+                           const char *_add_code);
diff --git a/contrib/libdiff/lib/diff_output.c 
b/contrib/libdiff/lib/diff_output.c
index 3b84608882f6..2a0d95896e1a 100644
--- a/contrib/libdiff/lib/diff_output.c
+++ b/contrib/libdiff/lib/diff_output.c
@@ -30,6 +30,22 @@
 
 #include "diff_internal.h"
 
+static bool color;
+static const char *del_code = "31";
+static const char *add_code = "32";
+
+void
+diff_output_set_colors(bool _color,
+                      const char *_del_code,
+                      const char *_add_code)
+{
+       color = _color;
+       if (_del_code)
+               del_code = _del_code;
+       if (_add_code)
+               add_code = _add_code;
+}
+
 static int
 get_atom_byte(int *ch, struct diff_atom *atom, off_t off)
 {
@@ -66,12 +82,25 @@ diff_output_lines(struct diff_output_info *outinfo, FILE 
*dest,
        off_t outoff = 0, *offp;
        uint8_t *typep;
        int rc;
+       bool colored;
 
        if (outinfo && outinfo->line_offsets.len > 0) {
                unsigned int idx = outinfo->line_offsets.len - 1;
                outoff = outinfo->line_offsets.head[idx];
        }
 
+       if (color) {
+               colored = true;
+               if (*prefix == '-' || *prefix == '<')
+                       printf("\033[%sm", del_code);
+               else if (*prefix == '+' || *prefix == '>')
+                       printf("\033[%sm", add_code);
+               else
+                       colored = false;
+       } else {
+               colored = false;
+       }
+
        foreach_diff_atom(atom, start_atom, count) {
                off_t outlen = 0;
                int i, ch, nbuf = 0;
@@ -80,14 +109,16 @@ diff_output_lines(struct diff_output_info *outinfo, FILE 
*dest,
                size_t n;
 
                n = strlcpy(buf, prefix, sizeof(buf));
-               if (n >= DIFF_OUTPUT_BUF_SIZE) /* leave room for '\n' */
-                       return ENOBUFS;
+               if (n >= DIFF_OUTPUT_BUF_SIZE) { /* leave room for '\n' */
+                       rc = ENOBUFS;
+                       goto out;
+               }
                nbuf += n;
 
                if (len) {
                        rc = get_atom_byte(&ch, atom, len - 1);
                        if (rc)
-                               return rc;
+                               goto out;
                        if (ch == '\n')
                                len--;
                }
@@ -95,11 +126,13 @@ diff_output_lines(struct diff_output_info *outinfo, FILE 
*dest,
                for (i = 0; i < len; i++) {
                        rc = get_atom_byte(&ch, atom, i);
                        if (rc)
-                               return rc;
+                               goto out;
                        if (nbuf >= DIFF_OUTPUT_BUF_SIZE) {
                                wlen = fwrite(buf, 1, nbuf, dest);
-                               if (wlen != nbuf)
-                                       return errno;
+                               if (wlen != nbuf) {
+                                       rc = errno;
+                                       goto out;
+                               }
                                outlen += wlen;
                                nbuf = 0;
                        }
@@ -107,25 +140,35 @@ diff_output_lines(struct diff_output_info *outinfo, FILE 
*dest,
                }
                buf[nbuf++] = '\n';
                wlen = fwrite(buf, 1, nbuf, dest);
-               if (wlen != nbuf)
-                       return errno;
+               if (wlen != nbuf) {
+                       rc = errno;
+                       goto out;
+               }
                outlen += wlen;
                if (outinfo) {
                        ARRAYLIST_ADD(offp, outinfo->line_offsets);
-                       if (offp == NULL)
-                               return ENOMEM;
+                       if (offp == NULL) {
+                               rc = ENOMEM;
+                               goto out;
+                       }
                        outoff += outlen;
                        *offp = outoff;
                        ARRAYLIST_ADD(typep, outinfo->line_types);
-                       if (typep == NULL)
-                               return ENOMEM;
+                       if (typep == NULL) {
+                               rc = ENOMEM;
+                               goto out;
+                       }
                        *typep = *prefix == ' ' ? DIFF_LINE_CONTEXT :
                            *prefix == '-' ? DIFF_LINE_MINUS :
                            *prefix == '+' ? DIFF_LINE_PLUS : DIFF_LINE_NONE;
                }
        }
 
-       return DIFF_RC_OK;
+       rc = DIFF_RC_OK;
+out:
+       if (colored)
+               printf("\033[m");
+       return rc;
 }
 
 int
diff --git a/usr.bin/diff/diffreg_new.c b/usr.bin/diff/diffreg_new.c
index a7a40ec12ec9..af9104559986 100644
--- a/usr.bin/diff/diffreg_new.c
+++ b/usr.bin/diff/diffreg_new.c
@@ -253,6 +253,8 @@ diffreg_new(char *file1, char *file2, int flags, int 
capsicum)
                goto done;
        }
 
+       if (color)
+               diff_output_set_colors(color, del_code, add_code);
        if (diff_format == D_NORMAL) {
                rc = diff_output_plain(NULL, stdout, &info, result, false);
        } else if (diff_format == D_EDIT) {

Reply via email to