Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F107043441
D44014.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D44014.diff
View Options
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
@@ -427,6 +427,15 @@
.Ar number
columns when using side by side format.
The default value is 130.
+Note that unless
+.It Fl t
+was specified,
+.Nm
+will always align the second column to a tab stop, so values of
+.Fl -width
+smaller than approximately five times the value of
+.Fl -tabsize
+may yield surprising results.
.It Fl -changed-group-format Ar GFMT
Format input groups in the provided
.Pp
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
@@ -276,10 +276,8 @@
break;
case 'W':
width = (int) strtonum(optarg, 1, INT_MAX, &errstr);
- if (errstr) {
- warnx("Invalid argument for width");
- usage();
- }
+ if (errstr)
+ errx(1, "width is %s: %s", errstr, optarg);
break;
case 'X':
read_excludes_file(optarg);
@@ -317,10 +315,8 @@
break;
case OPT_TSIZE:
tabsize = (int) strtonum(optarg, 1, INT_MAX, &errstr);
- if (errstr) {
- warnx("Invalid argument for tabsize");
- usage();
- }
+ if (errstr)
+ errx(1, "tabsize is %s: %s", errstr, optarg);
break;
case OPT_STRIPCR:
dflags |= D_STRIPCR;
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
@@ -166,7 +166,6 @@
enum readhash { RH_BINARY, RH_OK, RH_EOF };
-#define MIN_PAD 1
static FILE *opentemp(const char *);
static void output(char *, FILE *, char *, FILE *, int);
static void check(FILE *, FILE *, int);
@@ -206,7 +205,7 @@
static int pref, suff; /* length of prefix and suffix */
static int slen[2];
static int anychange;
-static int hw, padding; /* half width and padding */
+static int hw, lpad, rpad; /* half width and padding */
static int edoffset;
static long *ixnew; /* will be overlaid on file[1] */
static long *ixold; /* will be overlaid on klist */
@@ -251,21 +250,44 @@
lastline = 0;
lastmatchline = 0;
- /*
- * hw excludes padding and make sure when -t is not used,
- * the second column always starts from the closest tab stop
- */
+ /*
+ * In side-by-side mode, we need to print the left column, a
+ * change marker surrounded by padding, and the right column.
+ *
+ * If expanding tabs, we don't care about alignment, so we simply
+ * subtract 3 from the width and divide by two.
+ *
+ * If not expanding tabs, we need to ensure that the right column
+ * is aligned to a tab stop. We start with the same formula, then
+ * decrement until we reach a size that lets us tab-align the
+ * right column. We then adjust the width down if necessary for
+ * the padding calculation to work.
+ *
+ * Left padding is half the space left over, rounded down; right
+ * padding is whatever is needed to match the width.
+ */
if (diff_format == D_SIDEBYSIDE) {
- hw = width >> 1;
- padding = tabsize - (hw % tabsize);
- if ((flags & D_EXPANDTABS) != 0 || (padding % tabsize == 0))
- padding = MIN_PAD;
-
- hw = (width >> 1) -
- ((padding == MIN_PAD) ? (padding << 1) : padding) - 1;
+ if (flags & D_EXPANDTABS) {
+ if (width > 3) {
+ hw = (width - 3) / 2;
+ } else {
+ /* not enough space */
+ hw = 0;
+ }
+ } else if (width <= 3 || width <= tabsize) {
+ /* not enough space */
+ hw = 0;
+ } else {
+ hw = (width - 3) / 2;
+ while (hw > 0 && roundup(hw + 3, tabsize) + hw > width)
+ hw--;
+ if (width - (roundup(hw + 3, tabsize) + hw) < tabsize)
+ width = roundup(hw + 3, tabsize) + hw;
+ }
+ lpad = (width - hw * 2 - 1) / 2;
+ rpad = (width - hw * 2 - 1) - lpad;
}
-
if (flags & D_IGNORECASE)
chrtran = cup2low;
else
@@ -866,7 +888,7 @@
while (i0 <= m && J[i0] == J[i0 - 1] + 1) {
if (diff_format == D_SIDEBYSIDE && suppress_common != 1) {
nc = fetch(ixold, i0, i0, f1, '\0', 1, flags);
- print_space(nc, (hw - nc) + (padding << 1) + 1, flags);
+ print_space(nc, hw - nc + lpad + 1 + rpad, flags);
fetch(ixnew, J[i0], J[i0], f2, '\0', 0, flags);
printf("\n");
}
@@ -1144,10 +1166,10 @@
else if (color && c > d)
printf("\033[%sm", del_code);
if (a > b) {
- print_space(0, hw + padding , *pflags);
+ print_space(0, hw + lpad, *pflags);
} else {
nc = fetch(ixold, a, b, f1, '\0', 1, *pflags);
- print_space(nc, hw - nc + padding, *pflags);
+ print_space(nc, hw - nc + lpad, *pflags);
}
if (color && a > b)
printf("\033[%sm", add_code);
@@ -1156,7 +1178,7 @@
printf("%c", (a > b) ? '>' : ((c > d) ? '<' : '|'));
if (color && c > d)
printf("\033[m");
- print_space(hw + padding + 1 , padding, *pflags);
+ print_space(hw + lpad + 1, rpad, *pflags);
fetch(ixnew, c, d, f2, '\0', 0, *pflags);
printf("\n");
}
@@ -1262,30 +1284,24 @@
printf("\n\\ No newline at end of file\n");
return (col);
}
- /*
- * when using --side-by-side, col needs to be increased
- * in any case to keep the columns aligned
- */
if (c == '\t') {
- if (flags & D_EXPANDTABS) {
- newcol = ((col / tabsize) + 1) * tabsize;
- do {
- printf(" ");
- } while (++col < newcol && col < hw);
+ /*
+ * Calculate where the tab would bring us.
+ * If it would take us to the end of the
+ * column, either clip it (if expanding
+ * tabs) or return right away (if not).
+ */
+ newcol = roundup(col + 1, tabsize);
+ if ((flags & D_EXPANDTABS) == 0) {
+ if (hw > 0 && newcol >= hw)
+ return (col);
+ printf("\t");
} else {
- if (diff_format == D_SIDEBYSIDE) {
- if ((col + tabsize) > hw) {
- printf("%*s", hw - col, "");
- col = hw;
- } else {
- printf("\t");
- col += tabsize - 1;
- }
- } else {
- printf("\t");
- col++;
- }
+ if (hw > 0 && newcol > hw)
+ newcol = hw;
+ printf("%*s", newcol - col, "");
}
+ col = newcol;
} else {
if (diff_format == D_EDIT && j == 1 && c == '\n' &&
lastc == '.') {
@@ -1665,18 +1681,19 @@
* nc is the preceding number of characters
*/
static void
-print_space(int nc, int n, int flags) {
- int i, col;
+print_space(int nc, int n, int flags)
+{
+ int col, newcol, tabstop;
- col = n;
+ col = nc;
+ newcol = nc + n;
+ /* first, use tabs if allowed */
if ((flags & D_EXPANDTABS) == 0) {
- /* first tabstop may be closer than tabsize */
- i = tabsize - (nc % tabsize);
- while (col >= tabsize) {
+ while ((tabstop = roundup(col + 1, tabsize)) <= newcol) {
printf("\t");
- col -= i;
- i = tabsize;
+ col = tabstop;
}
}
- printf("%*s", col, "");
+ /* finish with spaces */
+ printf("%*s", newcol - col, "");
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Jan 10, 9:03 AM (13 h, 30 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15741268
Default Alt Text
D44014.diff (6 KB)
Attached To
Mode
D44014: diff: Fix --expand-tabs and --side-by-side.
Attached
Detach File
Event Timeline
Log In to Comment