mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-11-30 04:22:44 +00:00
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
This commit is contained in:
parent
fe55d62ab9
commit
4e859e67dd
@ -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_left(const struct diff_input_info *info);
|
||||||
const char *diff_output_get_label_right(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);
|
||||||
|
@ -30,6 +30,22 @@
|
|||||||
|
|
||||||
#include "diff_internal.h"
|
#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
|
static int
|
||||||
get_atom_byte(int *ch, struct diff_atom *atom, off_t off)
|
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;
|
off_t outoff = 0, *offp;
|
||||||
uint8_t *typep;
|
uint8_t *typep;
|
||||||
int rc;
|
int rc;
|
||||||
|
bool colored;
|
||||||
|
|
||||||
if (outinfo && outinfo->line_offsets.len > 0) {
|
if (outinfo && outinfo->line_offsets.len > 0) {
|
||||||
unsigned int idx = outinfo->line_offsets.len - 1;
|
unsigned int idx = outinfo->line_offsets.len - 1;
|
||||||
outoff = outinfo->line_offsets.head[idx];
|
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) {
|
foreach_diff_atom(atom, start_atom, count) {
|
||||||
off_t outlen = 0;
|
off_t outlen = 0;
|
||||||
int i, ch, nbuf = 0;
|
int i, ch, nbuf = 0;
|
||||||
@ -80,14 +109,16 @@ diff_output_lines(struct diff_output_info *outinfo, FILE *dest,
|
|||||||
size_t n;
|
size_t n;
|
||||||
|
|
||||||
n = strlcpy(buf, prefix, sizeof(buf));
|
n = strlcpy(buf, prefix, sizeof(buf));
|
||||||
if (n >= DIFF_OUTPUT_BUF_SIZE) /* leave room for '\n' */
|
if (n >= DIFF_OUTPUT_BUF_SIZE) { /* leave room for '\n' */
|
||||||
return ENOBUFS;
|
rc = ENOBUFS;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
nbuf += n;
|
nbuf += n;
|
||||||
|
|
||||||
if (len) {
|
if (len) {
|
||||||
rc = get_atom_byte(&ch, atom, len - 1);
|
rc = get_atom_byte(&ch, atom, len - 1);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
goto out;
|
||||||
if (ch == '\n')
|
if (ch == '\n')
|
||||||
len--;
|
len--;
|
||||||
}
|
}
|
||||||
@ -95,11 +126,13 @@ diff_output_lines(struct diff_output_info *outinfo, FILE *dest,
|
|||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
rc = get_atom_byte(&ch, atom, i);
|
rc = get_atom_byte(&ch, atom, i);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
goto out;
|
||||||
if (nbuf >= DIFF_OUTPUT_BUF_SIZE) {
|
if (nbuf >= DIFF_OUTPUT_BUF_SIZE) {
|
||||||
wlen = fwrite(buf, 1, nbuf, dest);
|
wlen = fwrite(buf, 1, nbuf, dest);
|
||||||
if (wlen != nbuf)
|
if (wlen != nbuf) {
|
||||||
return errno;
|
rc = errno;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
outlen += wlen;
|
outlen += wlen;
|
||||||
nbuf = 0;
|
nbuf = 0;
|
||||||
}
|
}
|
||||||
@ -107,25 +140,35 @@ diff_output_lines(struct diff_output_info *outinfo, FILE *dest,
|
|||||||
}
|
}
|
||||||
buf[nbuf++] = '\n';
|
buf[nbuf++] = '\n';
|
||||||
wlen = fwrite(buf, 1, nbuf, dest);
|
wlen = fwrite(buf, 1, nbuf, dest);
|
||||||
if (wlen != nbuf)
|
if (wlen != nbuf) {
|
||||||
return errno;
|
rc = errno;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
outlen += wlen;
|
outlen += wlen;
|
||||||
if (outinfo) {
|
if (outinfo) {
|
||||||
ARRAYLIST_ADD(offp, outinfo->line_offsets);
|
ARRAYLIST_ADD(offp, outinfo->line_offsets);
|
||||||
if (offp == NULL)
|
if (offp == NULL) {
|
||||||
return ENOMEM;
|
rc = ENOMEM;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
outoff += outlen;
|
outoff += outlen;
|
||||||
*offp = outoff;
|
*offp = outoff;
|
||||||
ARRAYLIST_ADD(typep, outinfo->line_types);
|
ARRAYLIST_ADD(typep, outinfo->line_types);
|
||||||
if (typep == NULL)
|
if (typep == NULL) {
|
||||||
return ENOMEM;
|
rc = ENOMEM;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
*typep = *prefix == ' ' ? DIFF_LINE_CONTEXT :
|
*typep = *prefix == ' ' ? DIFF_LINE_CONTEXT :
|
||||||
*prefix == '-' ? DIFF_LINE_MINUS :
|
*prefix == '-' ? DIFF_LINE_MINUS :
|
||||||
*prefix == '+' ? DIFF_LINE_PLUS : DIFF_LINE_NONE;
|
*prefix == '+' ? DIFF_LINE_PLUS : DIFF_LINE_NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return DIFF_RC_OK;
|
rc = DIFF_RC_OK;
|
||||||
|
out:
|
||||||
|
if (colored)
|
||||||
|
printf("\033[m");
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -253,6 +253,8 @@ diffreg_new(char *file1, char *file2, int flags, int capsicum)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (color)
|
||||||
|
diff_output_set_colors(color, del_code, add_code);
|
||||||
if (diff_format == D_NORMAL) {
|
if (diff_format == D_NORMAL) {
|
||||||
rc = diff_output_plain(NULL, stdout, &info, result, false);
|
rc = diff_output_plain(NULL, stdout, &info, result, false);
|
||||||
} else if (diff_format == D_EDIT) {
|
} else if (diff_format == D_EDIT) {
|
||||||
|
Loading…
Reference in New Issue
Block a user