View | Details | Raw Unified | Return to bug 219933 | Differences between
and this patch

Collapse All | Expand All

(-)diff.1 (-2 / +37 lines)
Lines 41-47 Link Here
41
.Op Fl aBbdipTtw
41
.Op Fl aBbdipTtw
42
.Oo
42
.Oo
43
.Fl c | e | f |
43
.Fl c | e | f |
44
.Fl n | q | u
44
.Fl n | q | u | y
45
.Oc
45
.Oc
46
.Op Fl -brief
46
.Op Fl -brief
47
.Op Fl -changed-group-format Ar GFMT
47
.Op Fl -changed-group-format Ar GFMT
Lines 182-187 Link Here
182
.Op Fl x Ar pattern | Fl -exclude Ar pattern
182
.Op Fl x Ar pattern | Fl -exclude Ar pattern
183
.Ek
183
.Ek
184
.Ar dir1 dir2
184
.Ar dir1 dir2
185
.Nm diff
186
.Op Fl aBbditwW
187
.Op --expand-tabs
188
.Op --ignore-all-blanks
189
.Op --ignore-blank-lines
190
.Op --ignore-case
191
.Op --minimal
192
.Op --no-ignore-file-name-case
193
.Op --strip-trailing-cr
194
.Op --suppress-common-lines
195
.Op --tabsize
196
.Op --text
197
.Op --width
198
.Fl y | Fl -side-by-side
199
.Ar file1 file2
185
.Sh DESCRIPTION
200
.Sh DESCRIPTION
186
The
201
The
187
.Nm
202
.Nm
Lines 284-290 Link Here
284
.Fl c ,
299
.Fl c ,
285
all lines to be changed (added and/or removed) are present in
300
all lines to be changed (added and/or removed) are present in
286
a single section.
301
a single section.
302
.It Fl y Fl -side-by-side
303
Output in two columns with a marker between them. The marker can be one 
304
of the following:
305
.Pp
306
.Bl -tag -width Ds -offset indent -compact
307
.It space 
308
Corresponding lines are identical.
309
.It '|'
310
Corresponding lines are different.
311
.It '<'
312
Files differ and only the first file contains the line.
313
.It '>'
314
Files differ and only the second file contains the line.
287
.El
315
.El
316
.El
288
.Pp
317
.Pp
289
Comparison options:
318
Comparison options:
290
.Bl -tag -width Ds
319
.Bl -tag -width Ds
Lines 362-367 Link Here
362
.Dq if (\ \&a == b \&)
391
.Dq if (\ \&a == b \&)
363
will compare equal to
392
will compare equal to
364
.Dq if(a==b) .
393
.Dq if(a==b) .
394
.It Fl W Ar number Fl -width Ar number
395
Output at most
396
.Ar number
397
columns when using side by side format. The default value is 130.
365
.It Fl -changed-group-format Ar GFMT
398
.It Fl -changed-group-format Ar GFMT
366
Format input groups in the provided
399
Format input groups in the provided
367
.Pp
400
.Pp
Lines 382-388 Link Here
382
stub option for compatibility with GNU diff
415
stub option for compatibility with GNU diff
383
.It Fl -strip-trailing-cr
416
.It Fl -strip-trailing-cr
384
strip carriage return on input files
417
strip carriage return on input files
385
.It Fl tabsize Ar number
418
.It Fl -suppress-common-lines
419
Do not output common lines when using the side by side format
420
.It Fl -tabsize Ar number
386
Number of spaces representing a tab (default 8)
421
Number of spaces representing a tab (default 8)
387
.El
422
.El
388
.Pp
423
.Pp
(-)diff.c (-5 / +28 lines)
Lines 37-45 Link Here
37
#include "diff.h"
37
#include "diff.h"
38
#include "xmalloc.h"
38
#include "xmalloc.h"
39
39
40
int	 lflag, Nflag, Pflag, rflag, sflag, Tflag, cflag;
40
int	 lflag, Nflag, Pflag, rflag, sflag, Tflag, cflag, Wflag;
41
int	 diff_format, diff_context, status, ignore_file_case;
41
int	 diff_format, diff_context, status, ignore_file_case, suppress_common;
42
int	 tabsize = 8;
42
int	 tabsize = 8, width = 130;
43
char	*start, *ifdefname, *diffargs, *label[2], *ignore_pats;
43
char	*start, *ifdefname, *diffargs, *label[2], *ignore_pats;
44
char	*group_format = NULL;
44
char	*group_format = NULL;
45
struct stat stb1, stb2;
45
struct stat stb1, stb2;
Lines 46-52 Link Here
46
struct excludes *excludes_list;
46
struct excludes *excludes_list;
47
regex_t	 ignore_re;
47
regex_t	 ignore_re;
48
48
49
#define	OPTIONS	"0123456789aBbC:cdD:efHhI:iL:lnNPpqrS:sTtU:uwX:x:"
49
#define	OPTIONS	"0123456789aBbC:cdD:efHhI:iL:lnNPpqrS:sTtU:uwW:X:x:y"
50
enum {
50
enum {
51
	OPT_TSIZE = CHAR_MAX + 1,
51
	OPT_TSIZE = CHAR_MAX + 1,
52
	OPT_STRIPCR,
52
	OPT_STRIPCR,
Lines 55-60 Link Here
55
	OPT_NORMAL,
55
	OPT_NORMAL,
56
	OPT_HORIZON_LINES,
56
	OPT_HORIZON_LINES,
57
	OPT_CHANGED_GROUP_FORMAT,
57
	OPT_CHANGED_GROUP_FORMAT,
58
	OPT_SUPPRESS_COMMON,
58
};
59
};
59
60
60
static struct option longopts[] = {
61
static struct option longopts[] = {
Lines 83-90 Link Here
83
	{ "initial-tab",		no_argument,		0,	'T' },
84
	{ "initial-tab",		no_argument,		0,	'T' },
84
	{ "unified",			optional_argument,	0,	'U' },
85
	{ "unified",			optional_argument,	0,	'U' },
85
	{ "ignore-all-space",		no_argument,		0,	'w' },
86
	{ "ignore-all-space",		no_argument,		0,	'w' },
87
	{ "width",			required_argument,	0,	'W' },
86
	{ "exclude",			required_argument,	0,	'x' },
88
	{ "exclude",			required_argument,	0,	'x' },
87
	{ "exclude-from",		required_argument,	0,	'X' },
89
	{ "exclude-from",		required_argument,	0,	'X' },
90
	{ "side-by-side",		no_argument,		NULL,	'y' },
88
	{ "ignore-file-name-case",	no_argument,		NULL,	OPT_IGN_FN_CASE },
91
	{ "ignore-file-name-case",	no_argument,		NULL,	OPT_IGN_FN_CASE },
89
	{ "horizon-lines",		required_argument,	NULL,	OPT_HORIZON_LINES },
92
	{ "horizon-lines",		required_argument,	NULL,	OPT_HORIZON_LINES },
90
	{ "no-ignore-file-name-case",	no_argument,		NULL,	OPT_NO_IGN_FN_CASE },
93
	{ "no-ignore-file-name-case",	no_argument,		NULL,	OPT_NO_IGN_FN_CASE },
Lines 92-97 Link Here
92
	{ "strip-trailing-cr",		no_argument,		NULL,	OPT_STRIPCR },
95
	{ "strip-trailing-cr",		no_argument,		NULL,	OPT_STRIPCR },
93
	{ "tabsize",			optional_argument,	NULL,	OPT_TSIZE },
96
	{ "tabsize",			optional_argument,	NULL,	OPT_TSIZE },
94
	{ "changed-group-format",	required_argument,	NULL,	OPT_CHANGED_GROUP_FORMAT},
97
	{ "changed-group-format",	required_argument,	NULL,	OPT_CHANGED_GROUP_FORMAT},
98
	{ "suppress-common-lines",	no_argument,		NULL,	OPT_SUPPRESS_COMMON },
95
	{ NULL,				0,			0,	'\0'}
99
	{ NULL,				0,			0,	'\0'}
96
};
100
};
97
101
Lines 230-235 Link Here
230
		case 'w':
234
		case 'w':
231
			dflags |= D_IGNOREBLANKS;
235
			dflags |= D_IGNOREBLANKS;
232
			break;
236
			break;
237
		case 'W':
238
			Wflag = 1;
239
			width = (int) strtonum(optarg, 1, INT_MAX, &errstr);
240
			if (errstr) {
241
				warnx("Invalid argument for width");
242
				usage();
243
			}
244
			break;
233
		case 'X':
245
		case 'X':
234
			read_excludes_file(optarg);
246
			read_excludes_file(optarg);
235
			break;
247
			break;
Lines 236-241 Link Here
236
		case 'x':
248
		case 'x':
237
			push_excludes(optarg);
249
			push_excludes(optarg);
238
			break;
250
			break;
251
		case 'y':
252
			diff_format = D_SIDEBYSIDE;
253
			break;
239
		case OPT_CHANGED_GROUP_FORMAT:
254
		case OPT_CHANGED_GROUP_FORMAT:
240
			diff_format = D_GFORMAT;
255
			diff_format = D_GFORMAT;
241
			group_format = optarg;
256
			group_format = optarg;
Lines 261-266 Link Here
261
		case OPT_STRIPCR:
276
		case OPT_STRIPCR:
262
			dflags |= D_STRIPCR;
277
			dflags |= D_STRIPCR;
263
			break;
278
			break;
279
		case OPT_SUPPRESS_COMMON:
280
			suppress_common = 1;
281
			break;
264
		default:
282
		default:
265
			usage();
283
			usage();
266
			break;
284
			break;
Lines 464-470 Link Here
464
	    "            -U number file1 file2\n"
482
	    "            -U number file1 file2\n"
465
	    "       diff [-aBbdilNPprsTtw] [-c | -e | -f | -n | -q | -u] [--ignore-case]\n"
483
	    "       diff [-aBbdilNPprsTtw] [-c | -e | -f | -n | -q | -u] [--ignore-case]\n"
466
	    "            [--no-ignore-case] [--normal] [--tabsize] [-I pattern] [-L label]\n"
484
	    "            [--no-ignore-case] [--normal] [--tabsize] [-I pattern] [-L label]\n"
467
	    "            [-S name] [-X file] [-x pattern] dir1 dir2\n");
485
	    "            [-S name] [-X file] [-x pattern] dir1 dir2\n"
486
	    "       diff [-aBbditwW] [--expand-tabs] [--ignore-all-blanks]\n"
487
            "            [--ignore-blank-lines] [--ignore-case] [--minimal]\n"
488
            "            [--no-ignore-file-name-case] [--strip-trailing-cr]\n"
489
            "            [--suppress-common-lines] [--tabsize] [--text] [--width]\n"
490
            "            -y | --side-by-side file1 file2\n");
468
491
469
	exit(2);
492
	exit(2);
470
}
493
}
(-)diff.h (-2 / +4 lines)
Lines 48-53 Link Here
48
				   lines and no trailing . */
48
				   lines and no trailing . */
49
#define	D_BRIEF		6	/* Say if the files differ */
49
#define	D_BRIEF		6	/* Say if the files differ */
50
#define	D_GFORMAT	7	/* Diff with defined changed group format */
50
#define	D_GFORMAT	7	/* Diff with defined changed group format */
51
#define D_SIDEBYSIDE    8	/* Side by side */
51
52
52
/*
53
/*
53
 * Output flags
54
 * Output flags
Lines 85-93 Link Here
85
	struct excludes *next;
86
	struct excludes *next;
86
};
87
};
87
88
88
extern int	lflag, Nflag, Pflag, rflag, sflag, Tflag, cflag;
89
extern int	lflag, Nflag, Pflag, rflag, sflag, Tflag, cflag, Wflag;
89
extern int	diff_format, diff_context, status, ignore_file_case;
90
extern int	diff_format, diff_context, status, ignore_file_case;
90
extern int	tabsize;
91
extern int	suppress_common;
92
extern int	tabsize, width;
91
extern char	*start, *ifdefname, *diffargs, *label[2], *ignore_pats;
93
extern char	*start, *ifdefname, *diffargs, *label[2], *ignore_pats;
92
extern char	*group_format;
94
extern char	*group_format;
93
extern struct	stat stb1, stb2;
95
extern struct	stat stb1, stb2;
(-)diffreg.c (-32 / +159 lines)
Lines 181-186 Link Here
181
};
181
};
182
182
183
#define	diff_output	printf
183
#define	diff_output	printf
184
#define MIN_PAD		1
184
static FILE	*opentemp(const char *);
185
static FILE	*opentemp(const char *);
185
static void	 output(char *, FILE *, char *, FILE *, int);
186
static void	 output(char *, FILE *, char *, FILE *, int);
186
static void	 check(FILE *, FILE *, int);
187
static void	 check(FILE *, FILE *, int);
Lines 196-201 Link Here
196
static void	 change(char *, FILE *, char *, FILE *, int, int, int, int, int *);
197
static void	 change(char *, FILE *, char *, FILE *, int, int, int, int, int *);
197
static void	 sort(struct line *, int);
198
static void	 sort(struct line *, int);
198
static void	 print_header(const char *, const char *);
199
static void	 print_header(const char *, const char *);
200
static void	 print_space(int, int, int);
199
static bool	 ignoreline_pattern(char *);
201
static bool	 ignoreline_pattern(char *);
200
static bool	 ignoreline(char *, bool);
202
static bool	 ignoreline(char *, bool);
201
static int	 asciifile(FILE *);
203
static int	 asciifile(FILE *);
Lines 220-225 Link Here
220
static int   pref, suff;	/* length of prefix and suffix */
222
static int   pref, suff;	/* length of prefix and suffix */
221
static int   slen[2];
223
static int   slen[2];
222
static int   anychange;
224
static int   anychange;
225
static int   hw, padding;	/* half width and padding */
226
static int   edoffset;
223
static long *ixnew;		/* will be overlaid on file[1] */
227
static long *ixnew;		/* will be overlaid on file[1] */
224
static long *ixold;		/* will be overlaid on klist */
228
static long *ixold;		/* will be overlaid on klist */
225
static struct cand *clist;	/* merely a free storage pot for candidates */
229
static struct cand *clist;	/* merely a free storage pot for candidates */
Lines 263-268 Link Here
263
	lastline = 0;
267
	lastline = 0;
264
	lastmatchline = 0;
268
	lastmatchline = 0;
265
	context_vec_ptr = context_vec_start - 1;
269
	context_vec_ptr = context_vec_start - 1;
270
271
	 /* 
272
	  * hw excludes padding and make sure when -t is not used, 
273
	  * the second column always starts from the closest tab stop
274
	  */
275
	if (diff_format == D_SIDEBYSIDE) { 
276
		hw = width >> 1;
277
		padding = tabsize - (hw % tabsize);
278
		if ((flags & D_EXPANDTABS) != 0 || (padding % tabsize == 0))
279
			padding = MIN_PAD;
280
	
281
		hw = (width >> 1) - 
282
		    ((padding == MIN_PAD) ? (padding << 1) : padding) - 1;
283
	}
284
	
285
266
	if (flags & D_IGNORECASE)
286
	if (flags & D_IGNORECASE)
267
		chrtran = cup2low;
287
		chrtran = cup2low;
268
	else
288
	else
Lines 865-871 Link Here
865
static void
885
static void
866
output(char *file1, FILE *f1, char *file2, FILE *f2, int flags)
886
output(char *file1, FILE *f1, char *file2, FILE *f2, int flags)
867
{
887
{
868
	int m, i0, i1, j0, j1;
888
	int i, j, m, i0, i1, j0, j1, nc;
869
889
870
	rewind(f1);
890
	rewind(f1);
871
	rewind(f2);
891
	rewind(f2);
Lines 874-881 Link Here
874
	J[m + 1] = len[1] + 1;
894
	J[m + 1] = len[1] + 1;
875
	if (diff_format != D_EDIT) {
895
	if (diff_format != D_EDIT) {
876
		for (i0 = 1; i0 <= m; i0 = i1 + 1) {
896
		for (i0 = 1; i0 <= m; i0 = i1 + 1) {
877
			while (i0 <= m && J[i0] == J[i0 - 1] + 1)
897
			while (i0 <= m && J[i0] == J[i0 - 1] + 1){
898
				if (diff_format == D_SIDEBYSIDE && 
899
				    suppress_common != 1) {
900
					nc = fetch(ixold, i0, i0, f1, '\0', 
901
					    1, flags);
902
					print_space(nc, 
903
					    (hw - nc) + (padding << 1) + 1, 
904
					    flags);
905
					fetch(ixnew, J[i0], J[i0], f2, '\0', 
906
					    0, flags);
907
					diff_output("\n");
908
				}
878
				i0++;
909
				i0++;
910
			}
879
			j0 = J[i0 - 1] + 1;
911
			j0 = J[i0 - 1] + 1;
880
			i1 = i0 - 1;
912
			i1 = i0 - 1;
881
			while (i1 < m && J[i1 + 1] == 0)
913
			while (i1 < m && J[i1 + 1] == 0)
Lines 882-888 Link Here
882
				i1++;
914
				i1++;
883
			j1 = J[i1 + 1] - 1;
915
			j1 = J[i1 + 1] - 1;
884
			J[i1] = j1;
916
			J[i1] = j1;
885
			change(file1, f1, file2, f2, i0, i1, j0, j1, &flags);
917
918
			/*
919
			 * When using side-by-side, lines from both of the 
920
			 * files are printed. The algorithm used by diff(1) 
921
			 * identifies the ranges in which two files differ. 
922
			 * See the change() function below. 
923
			 * The for loop below consumes the shorter range, 
924
			 * whereas one of the while loops deals with the 
925
			 * longer one.
926
			 */
927
			if (diff_format == D_SIDEBYSIDE) {
928
				for (i=i0, j=j0; i<=i1 && j<=j1; i++, j++) 
929
					change(file1, f1, file2, f2, i, i, 
930
					    j, j, &flags);
931
932
				while (i <= i1) {
933
					change(file1, f1, file2, f2, 
934
					    i, i, j+1, j, &flags);
935
					i++;
936
				}
937
938
				while (j <= j1) {
939
					change(file1, f1, file2, f2, 
940
					    i+1, i, j, j, &flags);
941
					j++;
942
				}
943
			} else
944
				change(file1, f1, file2, f2, i0, i1, j0, 
945
				    j1, &flags);
886
		}
946
		}
887
	} else {
947
	} else {
888
		for (i0 = m; i0 >= 1; i0 = i1 - 1) {
948
		for (i0 = m; i0 >= 1; i0 = i1 - 1) {
Lines 987-993 Link Here
987
{
1047
{
988
	static size_t max_context = 64;
1048
	static size_t max_context = 64;
989
	long curpos;
1049
	long curpos;
990
	int i, nc, f;
1050
	int i, nc;
991
	const char *walk;
1051
	const char *walk;
992
	bool skip_blanks;
1052
	bool skip_blanks;
993
1053
Lines 1116-1132 Link Here
1116
			diff_output("%c", *walk);
1176
			diff_output("%c", *walk);
1117
		}
1177
		}
1118
	}
1178
	}
1179
	if (diff_format == D_SIDEBYSIDE) {
1180
		if (a > b) {
1181
			print_space(0, hw + padding , *pflags);
1182
		} else {
1183
			nc = fetch(ixold, a, b, f1, '\0', 1, *pflags);
1184
			print_space(nc, hw - nc + padding, *pflags); 
1185
		}
1186
		diff_output("%c", (a>b)? '>' : ((c>d)? '<' : '|'));
1187
		print_space(hw + padding + 1 , padding, *pflags); 
1188
		fetch(ixnew, c, d, f2, '\0', 0, *pflags);
1189
		diff_output("\n");
1190
	}
1119
	if (diff_format == D_NORMAL || diff_format == D_IFDEF) {
1191
	if (diff_format == D_NORMAL || diff_format == D_IFDEF) {
1120
		fetch(ixold, a, b, f1, '<', 1, *pflags);
1192
		fetch(ixold, a, b, f1, '<', 1, *pflags);
1121
		if (a <= b && c <= d && diff_format == D_NORMAL)
1193
		if (a <= b && c <= d && diff_format == D_NORMAL)
1122
			diff_output("---\n");
1194
			diff_output("---\n");
1123
	}
1195
	}
1124
	f = 0;
1196
	if (diff_format != D_GFORMAT && diff_format != D_SIDEBYSIDE)
1125
	if (diff_format != D_GFORMAT)
1197
		fetch(ixnew, c, d, f2, diff_format == D_NORMAL ? '>' : '\0', 0, *pflags);
1126
		f = fetch(ixnew, c, d, f2, diff_format == D_NORMAL ? '>' : '\0', 0, *pflags);
1198
	if (edoffset != 0 && diff_format == D_EDIT) {
1127
	if (f != 0 && diff_format == D_EDIT) {
1128
		/*
1199
		/*
1129
		 * A non-zero return value for D_EDIT indicates that the
1200
		 * A non-zero edoffset value for D_EDIT indicates that the
1130
		 * last line printed was a bare dot (".") that has been
1201
		 * last line printed was a bare dot (".") that has been
1131
		 * escaped as ".." to prevent ed(1) from misinterpreting
1202
		 * escaped as ".." to prevent ed(1) from misinterpreting
1132
		 * it.  We have to add a substitute command to change this
1203
		 * it.  We have to add a substitute command to change this
Lines 1133-1142 Link Here
1133
		 * back and restart where we left off.
1204
		 * back and restart where we left off.
1134
		 */
1205
		 */
1135
		diff_output(".\n");
1206
		diff_output(".\n");
1136
		diff_output("%ds/.//\n", a + f - 1);
1207
		diff_output("%ds/.//\n", a + edoffset - 1);
1137
		b = a + f - 1;
1208
		b = a + edoffset - 1;
1138
		a = b + 1;
1209
		a = b + 1;
1139
		c += f;
1210
		c += edoffset;
1140
		goto restart;
1211
		goto restart;
1141
	}
1212
	}
1142
	if ((diff_format == D_EDIT || diff_format == D_REVERSE) && c <= d)
1213
	if ((diff_format == D_EDIT || diff_format == D_REVERSE) && c <= d)
Lines 1150-1158 Link Here
1150
static int
1221
static int
1151
fetch(long *f, int a, int b, FILE *lb, int ch, int oldfile, int flags)
1222
fetch(long *f, int a, int b, FILE *lb, int ch, int oldfile, int flags)
1152
{
1223
{
1153
	int i, j, c, lastc, col, nc;
1224
	int i, j, c, lastc, col, nc, newcol;
1154
	int	newcol;
1155
1225
1226
	edoffset = 0;
1227
	nc = 0;
1156
	/*
1228
	/*
1157
	 * When doing #ifdef's, copy down to current line
1229
	 * When doing #ifdef's, copy down to current line
1158
	 * if this is the first file, so that stuff makes it to output.
1230
	 * if this is the first file, so that stuff makes it to output.
Lines 1180-1191 Link Here
1180
	}
1252
	}
1181
	for (i = a; i <= b; i++) {
1253
	for (i = a; i <= b; i++) {
1182
		fseek(lb, f[i - 1], SEEK_SET);
1254
		fseek(lb, f[i - 1], SEEK_SET);
1183
		nc = f[i] - f[i - 1];
1255
		nc = (f[i] - f[i - 1]);
1184
		if ((diff_format != D_IFDEF && diff_format != D_GFORMAT) &&
1256
		if (diff_format == D_SIDEBYSIDE && hw < nc) 
1257
			nc = hw;
1258
		if ((diff_format != D_IFDEF && diff_format != D_GFORMAT) && 
1185
		    ch != '\0') {
1259
		    ch != '\0') {
1186
			diff_output("%c", ch);
1260
			diff_output("%c", ch);
1187
			if (Tflag && (diff_format == D_NORMAL || diff_format == D_CONTEXT
1261
			if (Tflag && (diff_format == D_NORMAL || 
1188
			    || diff_format == D_UNIFIED))
1262
			    diff_format == D_CONTEXT || 
1263
			    diff_format == D_UNIFIED))
1189
				diff_output("\t");
1264
				diff_output("\t");
1190
			else if (diff_format != D_UNIFIED)
1265
			else if (diff_format != D_UNIFIED)
1191
				diff_output(" ");
1266
				diff_output(" ");
Lines 1193-1211 Link Here
1193
		col = 0;
1268
		col = 0;
1194
		for (j = 0, lastc = '\0'; j < nc; j++, lastc = c) {
1269
		for (j = 0, lastc = '\0'; j < nc; j++, lastc = c) {
1195
			if ((c = getc(lb)) == EOF) {
1270
			if ((c = getc(lb)) == EOF) {
1196
				if (diff_format == D_EDIT || diff_format == D_REVERSE ||
1271
				if (diff_format == D_EDIT || 
1272
				    diff_format == D_REVERSE ||
1197
				    diff_format == D_NREVERSE)
1273
				    diff_format == D_NREVERSE)
1198
					warnx("No newline at end of file");
1274
					warnx("No newline at end of file");
1199
				else
1275
				else
1200
					diff_output("\n\\ No newline at end of "
1276
					diff_output("\n\\ No newline at end of "
1201
					    "file\n");
1277
					    "file\n");
1202
				return (0);
1278
				return col;
1203
			}
1279
			}
1204
			if (c == '\t' && (flags & D_EXPANDTABS)) {
1280
			/* 
1205
				newcol = ((col/tabsize)+1)*tabsize;
1281
			 * when using --side-by-side, col needs to be increased 
1206
				do {
1282
			 * in any case to keep the columns aligned
1207
					diff_output(" ");
1283
			 */
1208
				} while (++col < newcol);
1284
			if (c == '\t') {
1285
				if (flags & D_EXPANDTABS) {
1286
					newcol = ((col/tabsize)+1)*tabsize;
1287
					do {	
1288
						if (diff_format == D_SIDEBYSIDE)
1289
							j++;
1290
						diff_output(" ");
1291
					} while (++col < newcol && j < nc);
1292
				} else {
1293
					if (diff_format == D_SIDEBYSIDE) { 
1294
						if ((j + tabsize) > nc) {
1295
							diff_output("%*s", 
1296
							nc - j,"");
1297
							j = col = nc;
1298
						} else {
1299
							diff_output("\t");
1300
							col += tabsize - 1;
1301
							j += tabsize - 1;
1302
						}
1303
					} else {
1304
						diff_output("\t");
1305
						col++;
1306
					}
1307
				}
1209
			} else {
1308
			} else {
1210
				if (diff_format == D_EDIT && j == 1 && c == '\n'
1309
				if (diff_format == D_EDIT && j == 1 && c == '\n'
1211
				    && lastc == '.') {
1310
				    && lastc == '.') {
Lines 1212-1230 Link Here
1212
					/*
1311
					/*
1213
					 * Don't print a bare "." line
1312
					 * Don't print a bare "." line
1214
					 * since that will confuse ed(1).
1313
					 * since that will confuse ed(1).
1215
					 * Print ".." instead and return,
1314
					 * Print ".." instead and set the,
1216
					 * giving the caller an offset
1315
					 * global variable edoffset to an
1217
					 * from which to restart.
1316
					 * offset from which to restart.
1317
					 * The caller must check the value
1318
					 * of edoffset
1218
					 */
1319
					 */
1219
					diff_output(".\n");
1320
					diff_output(".\n");
1220
					return (i - a + 1);
1321
					edoffset = i - a + 1;
1322
					return edoffset;
1221
				}
1323
				}
1222
				diff_output("%c", c);
1324
				/* when side-by-side, do not print a newline */
1223
				col++;
1325
				if (diff_format != D_SIDEBYSIDE || c != '\n') {
1326
					diff_output("%c", c);
1327
					col++;
1328
				}
1224
			}
1329
			}
1225
		}
1330
		}
1226
	}
1331
	}
1227
	return (0);
1332
	return col;
1228
}
1333
}
1229
1334
1230
/*
1335
/*
Lines 1578-1580 Link Here
1578
		diff_output("%s %s\t%s\n", diff_format == D_CONTEXT ? "---" : "+++",
1683
		diff_output("%s %s\t%s\n", diff_format == D_CONTEXT ? "---" : "+++",
1579
		    file2, buf2);
1684
		    file2, buf2);
1580
}
1685
}
1686
1687
/* 
1688
 * Prints n number of space characters either by using tab
1689
 * or single space characters. 
1690
 * nc is the preceding number of characters
1691
 */
1692
static void
1693
print_space(int nc, int n, int flags) {
1694
	int i, col;
1695
1696
	col = n;
1697
	if ((flags & D_EXPANDTABS) == 0) {
1698
		/* first tabstop may be closer than tabsize */
1699
		i = tabsize - (nc % tabsize);
1700
		while (col >= tabsize) {
1701
			diff_output("\t");
1702
			col -= i;
1703
			i = tabsize;
1704
		}
1705
	}
1706
	diff_output("%*s", col, "");
1707
}

Return to bug 219933