svn commit: r310602 - user/bapt/diff

Baptiste Daroussin bapt at FreeBSD.org
Mon Dec 26 15:23:23 UTC 2016


Author: bapt
Date: Mon Dec 26 15:23:22 2016
New Revision: 310602
URL: https://svnweb.freebsd.org/changeset/base/310602

Log:
  Implement diff --tabsize
  
  Obtained from:	soc2012

Modified:
  user/bapt/diff/Makefile
  user/bapt/diff/diff.c
  user/bapt/diff/diff.h
  user/bapt/diff/diffreg.c

Modified: user/bapt/diff/Makefile
==============================================================================
--- user/bapt/diff/Makefile	Mon Dec 26 14:39:05 2016	(r310601)
+++ user/bapt/diff/Makefile	Mon Dec 26 15:23:22 2016	(r310602)
@@ -1,7 +1,7 @@
 # $FreEBSD$
 
 BINDIR?=	/usr/bin
-PROG=	diff
+PROG=	bdiff
 SRCS=	diff.c diffdir.c diffreg.c xmalloc.c
 WARNS=	7
 

Modified: user/bapt/diff/diff.c
==============================================================================
--- user/bapt/diff/diff.c	Mon Dec 26 14:39:05 2016	(r310601)
+++ user/bapt/diff/diff.c	Mon Dec 26 15:23:22 2016	(r310602)
@@ -41,15 +41,21 @@ __FBSDID("$FreeBSD$");
 
 int	 lflag, Nflag, Pflag, rflag, sflag, Tflag;
 int	 diff_format, diff_context, status;
+int	 tabsize = 8;
 char	*start, *ifdefname, *diffargs, *label[2], *ignore_pats;
 struct stat stb1, stb2;
 struct excludes *excludes_list;
 regex_t	 ignore_re;
 
-#define	OPTIONS	"0123456789abC:cdD:efhI:iL:lnNPpqrS:sTtU:uwX:x:"
+#define	OPTIONS	"0123456789aBbC:cdD:efhI:iL:lnNPpqrS:sTtU:uwX:x:"
+enum {
+	OPT_TSIZE = CHAR_MAX + 1,
+};
+
 static struct option longopts[] = {
 	{ "text",			no_argument,		0,	'a' },
 	{ "ignore-space-change",	no_argument,		0,	'b' },
+	{ "ignore-blank-lines",		no_argument,		NULL,	'B' },
 	{ "context",			optional_argument,	0,	'C' },
 	{ "ifdef",			required_argument,	0,	'D' },
 	{ "minimal",			no_argument,		0,	'd' },
@@ -73,6 +79,7 @@ static struct option longopts[] = {
 	{ "ignore-all-space",		no_argument,		0,	'w' },
 	{ "exclude",			required_argument,	0,	'x' },
 	{ "exclude-from",		required_argument,	0,	'X' },
+	{ "tabsize",			optional_argument,	NULL,	OPT_TSIZE },
 	{ NULL,				0,			0,	'\0'}
 };
 
@@ -85,6 +92,7 @@ void set_argstr(char **, char **);
 int
 main(int argc, char **argv)
 {
+	const char *errstr = NULL;
 	char *ep, **oargv;
 	long  l;
 	int   ch, dflags, lastch, gotstdin, prevoptind, newarg;
@@ -115,6 +123,9 @@ main(int argc, char **argv)
 		case 'b':
 			dflags |= D_FOLDBLANKS;
 			break;
+		case 'B':
+			dflags |= D_IGNOREBLANKLINES;
+			break;
 		case 'C':
 		case 'c':
 			diff_format = D_CONTEXT;
@@ -209,6 +220,13 @@ main(int argc, char **argv)
 		case 'x':
 			push_excludes(optarg);
 			break;
+		case OPT_TSIZE:
+			tabsize = (int) strtonum(optarg, 1, INT_MAX, &errstr);
+			if (errstr) {
+				warnx("Invalid argument for tabsize");
+				usage();
+			}
+			break;
 		default:
 			usage();
 			break;
@@ -400,12 +418,12 @@ void
 usage(void)
 {
 	(void)fprintf(stderr,
-	    "usage: diff [-abdipTtw] [-c | -e | -f | -n | -q | -u] [-I pattern] [-L label]\n"
+	    "usage: diff [-aBbdipTtw] [-c | -e | -f | -n | -q | -u] [-I pattern] [-L label]\n"
 	    "            file1 file2\n"
-	    "       diff [-abdipTtw] [-I pattern] [-L label] -C number file1 file2\n"
-	    "       diff [-abditw] [-I pattern] -D string file1 file2\n"
-	    "       diff [-abdipTtw] [-I pattern] [-L label] -U number file1 file2\n"
-	    "       diff [-abdiNPprsTtw] [-c | -e | -f | -n | -q | -u] [-I pattern]\n"
+	    "       diff [-aBbdipTtw] [-I pattern] [-L label] -C number file1 file2\n"
+	    "       diff [-aBbditw] [-I pattern] -D string file1 file2\n"
+	    "       diff [-aBbdipTtw] [-I pattern] [-L label] -U number file1 file2\n"
+	    "       diff [-aBbdiNPprsTtw] [-c | -e | -f | -n | -q | -u] [-I pattern]\n"
 	    "            [-L label] [-S name] [-X file] [-x pattern] dir1 dir2\n");
 
 	exit(2);

Modified: user/bapt/diff/diff.h
==============================================================================
--- user/bapt/diff/diff.h	Mon Dec 26 14:39:05 2016	(r310601)
+++ user/bapt/diff/diff.h	Mon Dec 26 15:23:22 2016	(r310602)
@@ -58,13 +58,14 @@
 /*
  * Command line flags
  */
-#define D_FORCEASCII	0x008	/* Treat file as ascii regardless of content */
-#define D_FOLDBLANKS	0x010	/* Treat all white space as equal */
-#define D_MINIMAL	0x020	/* Make diff as small as possible */
-#define D_IGNORECASE	0x040	/* Case-insensitive matching */
-#define D_PROTOTYPE	0x080	/* Display C function prototype */
-#define D_EXPANDTABS	0x100	/* Expand tabs to spaces */
-#define D_IGNOREBLANKS	0x200	/* Ignore white space changes */
+#define D_FORCEASCII		0x008	/* Treat file as ascii regardless of content */
+#define D_FOLDBLANKS		0x010	/* Treat all white space as equal */
+#define D_MINIMAL		0x020	/* Make diff as small as possible */
+#define D_IGNORECASE		0x040	/* Case-insensitive matching */
+#define D_PROTOTYPE		0x080	/* Display C function prototype */
+#define D_EXPANDTABS		0x100	/* Expand tabs to spaces */
+#define D_IGNOREBLANKS		0x200	/* Ignore white space changes */
+#define D_IGNOREBLANKLINES	0x400	/* Ignore blank lines changes */
 
 /*
  * Status values for print_status() and diffreg() return values
@@ -84,6 +85,7 @@ struct excludes {
 
 extern int	lflag, Nflag, Pflag, rflag, sflag, Tflag;
 extern int	diff_format, diff_context, status;
+extern int	tabsize;
 extern char	*start, *ifdefname, *diffargs, *label[2], *ignore_pats;
 extern struct	stat stb1, stb2;
 extern struct	excludes *excludes_list;

Modified: user/bapt/diff/diffreg.c
==============================================================================
--- user/bapt/diff/diffreg.c	Mon Dec 26 14:39:05 2016	(r310601)
+++ user/bapt/diff/diffreg.c	Mon Dec 26 15:23:22 2016	(r310602)
@@ -770,7 +770,7 @@ check(FILE *f1, FILE *f2, int flags)
 			ixnew[j] = ctnew += skipline(f2);
 			j++;
 		}
-		if (flags & (D_FOLDBLANKS|D_IGNOREBLANKS|D_IGNORECASE)) {
+		if (flags & (D_FOLDBLANKS|D_IGNOREBLANKS|D_IGNORECASE|D_IGNOREBLANKLINES)) {
 			for (;;) {
 				c = getc(f1);
 				d = getc(f2);
@@ -778,7 +778,7 @@ check(FILE *f1, FILE *f2, int flags)
 				 * GNU diff ignores a missing newline
 				 * in one file for -b or -w.
 				 */
-				if (flags & (D_FOLDBLANKS|D_IGNOREBLANKS)) {
+				if (flags & (D_FOLDBLANKS|D_IGNOREBLANKS|D_IGNOREBLANKLINES)) {
 					if (c == EOF && d == '\n') {
 						ctnew++;
 						break;
@@ -810,6 +810,15 @@ check(FILE *f1, FILE *f2, int flags)
 						d = getc(f2);
 						ctnew++;
 					}
+				} else if (flags & D_IGNOREBLANKLINES) {
+					while (isspace(c) && c == '\n') {
+						c = getc(f1);
+						ctold++;
+					}
+					while (isspace(d) && d == '\n') {
+						d = getc(f2);
+						ctnew++;
+					}
 				}
 				if (chrtran[c] != chrtran[d]) {
 					jackpot++;
@@ -1151,6 +1160,7 @@ static int
 fetch(long *f, int a, int b, FILE *lb, int ch, int oldfile, int flags)
 {
 	int i, j, c, lastc, col, nc;
+	int	newcol;
 
 	/*
 	 * When doing #ifdef's, copy down to current line
@@ -1200,9 +1210,10 @@ fetch(long *f, int a, int b, FILE *lb, i
 				return (0);
 			}
 			if (c == '\t' && (flags & D_EXPANDTABS)) {
+				newcol = ((col/tabsize)+1)*tabsize;
 				do {
 					diff_output(" ");
-				} while (++col & 7);
+				} while (++col < newcol);
 			} else {
 				if (diff_format == D_EDIT && j == 1 && c == '\n'
 				    && lastc == '.') {


More information about the svn-src-user mailing list