Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F108654892
D30545.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D30545.diff
View Options
diff --git a/usr.bin/diff/diff.h b/usr.bin/diff/diff.h
--- a/usr.bin/diff/diff.h
+++ b/usr.bin/diff/diff.h
@@ -87,17 +87,25 @@
#define D_SKIPPED2 6 /* path2 was a special file */
#define D_ERROR 7 /* A file access error occurred */
+/*
+ * Color options
+ */
+#define COLORFLAG_NEVER 0
+#define COLORFLAG_AUTO 1
+#define COLORFLAG_ALWAYS 2
+
struct excludes {
char *pattern;
struct excludes *next;
};
extern bool lflag, Nflag, Pflag, rflag, sflag, Tflag, cflag;
-extern bool ignore_file_case, suppress_common;
+extern bool ignore_file_case, suppress_common, color;
extern int diff_format, diff_context, status;
extern int tabsize, width;
extern char *start, *ifdefname, *diffargs, *label[2], *ignore_pats;
extern char *group_format;
+extern const char *add_code, *del_code;
extern struct stat stb1, stb2;
extern struct excludes *excludes_list;
extern regex_t ignore_re;
diff --git a/usr.bin/diff/diff.1 b/usr.bin/diff/diff.1
--- a/usr.bin/diff/diff.1
+++ b/usr.bin/diff/diff.1
@@ -44,6 +44,7 @@
.Fl n | q | u | y
.Oc
.Op Fl -brief
+.Op Fl -color Ns = Ns Ar when
.Op Fl -changed-group-format Ar GFMT
.Op Fl -ed
.Op Fl -expand-tabs
@@ -71,6 +72,7 @@
.Op Fl I Ar pattern | Fl -ignore-matching-lines Ar pattern
.Op Fl L Ar label | Fl -label Ar label
.Op Fl -brief
+.Op Fl -color Ns = Ns Ar when
.Op Fl -changed-group-format Ar GFMT
.Op Fl -ed
.Op Fl -expand-tabs
@@ -96,6 +98,7 @@
.Op Fl aBbdiltw
.Op Fl I Ar pattern | Fl -ignore-matching-lines Ar pattern
.Op Fl -brief
+.Op Fl -color Ns = Ns Ar when
.Op Fl -changed-group-format Ar GFMT
.Op Fl -ed
.Op Fl -expand-tabs
@@ -122,6 +125,7 @@
.Op Fl I Ar pattern | Fl -ignore-matching-lines Ar pattern
.Op Fl L Ar label | Fl -label Ar label
.Op Fl -brief
+.Op Fl -color Ns = Ns Ar when
.Op Fl -changed-group-format Ar GFMT
.Op Fl -ed
.Op Fl -expand-tabs
@@ -150,6 +154,7 @@
.Fl n | q | u
.Oc
.Op Fl -brief
+.Op Fl -color Ns = Ns Ar when
.Op Fl -changed-group-format Ar GFMT
.Op Fl -context
.Op Fl -ed
@@ -184,6 +189,7 @@
.Ar dir1 dir2
.Nm diff
.Op Fl aBbditwW
+.Op Fl -color Ns = Ns Ar when
.Op Fl -expand-tabs
.Op Fl -ignore-all-blanks
.Op Fl -ignore-blank-lines
@@ -332,6 +338,21 @@
.It Fl b -ignore-space-change
Causes trailing blanks (spaces and tabs) to be ignored, and other
strings of blanks to compare equal.
+.It Fl -color= Ns Oo Ar when Oc
+Color the additions green, and removals red, or the value in the
+.Ev DIFFCOLORS
+environment variable.
+The possible values of
+.Ar when
+are
+.Dq Cm never ,
+.Dq Cm always
+and
+.Dq Cm auto .
+.Cm auto
+will use color if the output is a tty and the
+.Ev COLORTERM
+environment variable is set to a non-empty string.
.It Fl d -minimal
Try very hard to produce a diff as small as possible.
This may consume a lot of processing power and memory when processing
@@ -592,6 +613,20 @@
identical
pairs (where num1 = num2) are abbreviated as a single
number.
+.Sh ENVIRONMENT
+.Bl -tag -width DIFFCOLORS
+.It Ev DIFFCOLORS
+The value of this variable is the form
+.Ar add Ns : Ns Ar rm ,
+where
+.Ar add
+is the ASCII escape sequence for additions and
+.Ar rm
+is the ASCII escape sequence for deletions.
+If this is unset,
+.Nm
+uses green for additions and red for removals.
+.El
.Sh FILES
.Bl -tag -width /tmp/diff.XXXXXXXX -compact
.It Pa /tmp/diff.XXXXXXXX
diff --git a/usr.bin/diff/diff.c b/usr.bin/diff/diff.c
--- a/usr.bin/diff/diff.c
+++ b/usr.bin/diff/diff.c
@@ -39,11 +39,13 @@
#include "xmalloc.h"
bool lflag, Nflag, Pflag, rflag, sflag, Tflag, cflag;
-bool ignore_file_case, suppress_common;
+bool ignore_file_case, suppress_common, color;
int diff_format, diff_context, status;
int tabsize = 8, width = 130;
+static int colorflag = COLORFLAG_NEVER;
char *start, *ifdefname, *diffargs, *label[2], *ignore_pats;
char *group_format = NULL;
+const char *add_code, *del_code;
struct stat stb1, stb2;
struct excludes *excludes_list;
regex_t ignore_re;
@@ -58,6 +60,7 @@
OPT_HORIZON_LINES,
OPT_CHANGED_GROUP_FORMAT,
OPT_SUPPRESS_COMMON,
+ OPT_COLOR,
};
static struct option longopts[] = {
@@ -98,6 +101,7 @@
{ "tabsize", required_argument, NULL, OPT_TSIZE },
{ "changed-group-format", required_argument, NULL, OPT_CHANGED_GROUP_FORMAT},
{ "suppress-common-lines", no_argument, NULL, OPT_SUPPRESS_COMMON },
+ { "color", optional_argument, NULL, OPT_COLOR },
{ NULL, 0, 0, '\0'}
};
@@ -108,6 +112,7 @@
static void read_excludes_file(char *file);
static void set_argstr(char **, char **);
static char *splice(char *, char *);
+static bool do_color(void);
int
main(int argc, char **argv)
@@ -301,6 +306,17 @@
case OPT_SUPPRESS_COMMON:
suppress_common = 1;
break;
+ case OPT_COLOR:
+ if (optarg == NULL || strncmp(optarg, "auto", 4) == 0)
+ colorflag = COLORFLAG_AUTO;
+ else if (strncmp(optarg, "always", 6) == 0)
+ colorflag = COLORFLAG_ALWAYS;
+ else if (strncmp(optarg, "never", 5) == 0)
+ colorflag = COLORFLAG_NEVER;
+ else
+ errx(2, "unsupported --color value '%s' (must be always, auto, or never)",
+ optarg);
+ break;
default:
usage();
break;
@@ -316,6 +332,22 @@
argc -= optind;
argv += optind;
+ if (do_color()) {
+ char *p;
+ const char *env;
+
+ color = true;
+ add_code = "32";
+ del_code = "31";
+ env = getenv("DIFFCOLORS");
+ if (env != NULL && *env != '\0' && (p = strdup(env))) {
+ add_code = p;
+ strsep(&p, ":");
+ if (p != NULL)
+ del_code = p;
+ }
+ }
+
#ifdef __OpenBSD__
if (pledge("stdio rpath tmppath", NULL) == -1)
err(2, "pledge");
@@ -545,6 +577,27 @@
usage();
}
+static bool
+do_color(void)
+{
+ const char *p, *p2;
+
+ switch (colorflag) {
+ case COLORFLAG_AUTO:
+ p = getenv("CLICOLOR");
+ p2 = getenv("COLORTERM");
+ if ((p != NULL && *p != '\0') || (p2 != NULL && *p2 != '\0'))
+ return isatty(STDOUT_FILENO);
+ break;
+ case COLORFLAG_ALWAYS:
+ return (true);
+ case COLORFLAG_NEVER:
+ return (false);
+ }
+
+ return (false);
+}
+
static char *
splice(char *dir, char *path)
{
diff --git a/usr.bin/diff/diffreg.c b/usr.bin/diff/diffreg.c
--- a/usr.bin/diff/diffreg.c
+++ b/usr.bin/diff/diffreg.c
@@ -1140,13 +1140,23 @@
}
}
if (diff_format == D_SIDEBYSIDE) {
+ if (color && a > b)
+ printf("\033[%sm", add_code);
+ else if (color && c > d)
+ printf("\033[%sm", del_code);
if (a > b) {
print_space(0, hw + padding , *pflags);
} else {
nc = fetch(ixold, a, b, f1, '\0', 1, *pflags);
print_space(nc, hw - nc + padding, *pflags);
}
+ if (color && a > b)
+ printf("\033[%sm", add_code);
+ else if (color && c > d)
+ printf("\033[%sm", del_code);
printf("%c", (a > b) ? '>' : ((c > d) ? '<' : '|'));
+ if (color && c > d)
+ printf("\033[m");
print_space(hw + padding + 1 , padding, *pflags);
fetch(ixnew, c, d, f2, '\0', 0, *pflags);
printf("\n");
@@ -1220,6 +1230,10 @@
nc = hw;
if (diff_format != D_IFDEF && diff_format != D_GFORMAT &&
ch != '\0') {
+ if (color && (ch == '>' || ch == '+'))
+ printf("\033[%sm", add_code);
+ else if (color && (ch == '<' || ch == '-'))
+ printf("\033[%sm", del_code);
printf("%c", ch);
if (Tflag && (diff_format == D_NORMAL ||
diff_format == D_CONTEXT ||
@@ -1290,12 +1304,17 @@
}
/* when side-by-side, do not print a newline */
if (diff_format != D_SIDEBYSIDE || c != '\n') {
- printf("%c", c);
+ if (color && c == '\n')
+ printf("\033[m%c", c);
+ else
+ printf("%c", c);
col++;
}
}
}
}
+ if (color && diff_format == D_SIDEBYSIDE)
+ printf("\033[m");
return (col);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Jan 28, 2:46 AM (10 h, 26 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16205907
Default Alt Text
D30545.diff (7 KB)
Attached To
Mode
D30545: diff(1): Add --color support
Attached
Detach File
Event Timeline
Log In to Comment