Page MenuHomeFreeBSD

D44014.diff
No OneTemporary

D44014.diff

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

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)

Event Timeline