svn commit: r298823 - in head: gnu/usr.bin gnu/usr.bin/sdiff usr.bin usr.bin/sdiff usr.bin/sdiff/tests

Kamil Czekirda kczekirda at gmail.com
Wed May 4 05:55:18 UTC 2016


Hi,

make ftp stops here since r298823:

===> usr.bin/sdiff/tests (distribute)
cd /usr/src/usr.bin/sdiff/tests;  make install -DNO_SUBDIR
DESTDIR=/usr/src/release/dist/tests SHARED=copies
install  -o root  -g wheel -m 555  sdiff
 /usr/src/release/dist/tests/usr/tests/usr.bin/sdiff/sdiff
install: /usr/src/release/dist/tests/usr/tests/usr.bin/sdiff/sdiff: No such
file or directory
*** Error code 71

Stop.
make[8]: stopped in /usr/src/usr.bin/sdiff/tests
*** Error code 1

Stop.
make[7]: stopped in /usr/src/usr.bin/sdiff/tests
*** Error code 1

Stop.
make[6]: stopped in /usr/src/usr.bin/sdiff
*** Error code 1

Stop.
make[5]: stopped in /usr/src/usr.bin
*** Error code 1

Stop.
make[4]: stopped in /usr/src
*** Error code 1

Stop.
make[3]: stopped in /usr/src
*** Error code 1

Stop.
make[2]: stopped in /usr/src
*** Error code 1

Stop.
make[1]: stopped in /usr/src
*** Error code 1

Stop.
make: stopped in /usr/src/release




2016-04-30 1:27 GMT+02:00 Baptiste Daroussin <bapt at freebsd.org>:

> Author: bapt
> Date: Fri Apr 29 23:27:15 2016
> New Revision: 298823
> URL: https://svnweb.freebsd.org/changeset/base/298823
>
> Log:
>   import sdiff(1) from GSoC 2012
>
>   Import sdiff(1) from the diff version written by Raymond Lai,
>   improved during GSoC 2012 by Jesse Hagewood.
>
>   Compared to the version done in during that summer of code:
>   - Remove the zlib frontend: zsdiff
>   - Compatible output (column size and separators) with GNU sdiff
>
>   Compared to GNU sdiff in ports:
>   - The only difference is padding using spaces vs tabs
>
>   Compared to OpenBSD and NetBSD import:
>   - Implement missing options (including long options) from GNU sdiff
>   - Improved support for the edition mode (signal handling)
>   - Output visually compatible with GNU sdiff: size of columns
>
>   While here import regression tests from NetBSD adapted to fit the output
> as
>   expected by GNU sdiff
>
>   Reviewed by:  emaste (in part)
>   Obtained from:        OpenBSD, NetBSD, GSoC 2012
>   Relnotes:     yes
>   Differential Revision:        https://reviews.freebsd.org/D5981
>   Differential Revision:        https://reviews.freebsd.org/D6032 (diff
> with NetBSD version)
>   Differential Revision:        https://reviews.freebsd.org/D6033 (diff
> with OpenBSD version)
>
> Added:
>   head/usr.bin/sdiff/
>   head/usr.bin/sdiff/Makefile   (contents, props changed)
>   head/usr.bin/sdiff/common.c   (contents, props changed)
>   head/usr.bin/sdiff/common.h   (contents, props changed)
>   head/usr.bin/sdiff/edit.c   (contents, props changed)
>   head/usr.bin/sdiff/extern.h   (contents, props changed)
>   head/usr.bin/sdiff/sdiff.1   (contents, props changed)
>   head/usr.bin/sdiff/sdiff.c   (contents, props changed)
>   head/usr.bin/sdiff/tests/
>   head/usr.bin/sdiff/tests/Makefile   (contents, props changed)
>   head/usr.bin/sdiff/tests/d_dot.in   (contents, props changed)
>   head/usr.bin/sdiff/tests/d_flags_l.out   (contents, props changed)
>   head/usr.bin/sdiff/tests/d_flags_s.out   (contents, props changed)
>   head/usr.bin/sdiff/tests/d_flags_w.out   (contents, props changed)
>   head/usr.bin/sdiff/tests/d_iflags_a1.out   (contents, props changed)
>   head/usr.bin/sdiff/tests/d_iflags_a2.out   (contents, props changed)
>   head/usr.bin/sdiff/tests/d_iflags_b1.out   (contents, props changed)
>   head/usr.bin/sdiff/tests/d_iflags_b2.out   (contents, props changed)
>   head/usr.bin/sdiff/tests/d_iflags_c1.out   (contents, props changed)
>   head/usr.bin/sdiff/tests/d_iflags_c2.out   (contents, props changed)
>   head/usr.bin/sdiff/tests/d_iflags_d1.out   (contents, props changed)
>   head/usr.bin/sdiff/tests/d_iflags_d2.out   (contents, props changed)
>   head/usr.bin/sdiff/tests/d_input1   (contents, props changed)
>   head/usr.bin/sdiff/tests/d_input2   (contents, props changed)
>   head/usr.bin/sdiff/tests/d_oneline.in   (contents, props changed)
>   head/usr.bin/sdiff/tests/d_oneline_a.out   (contents, props changed)
>   head/usr.bin/sdiff/tests/d_oneline_b.out   (contents, props changed)
>   head/usr.bin/sdiff/tests/d_same.out   (contents, props changed)
>   head/usr.bin/sdiff/tests/d_short.out   (contents, props changed)
>   head/usr.bin/sdiff/tests/d_tabends.in   (contents, props changed)
>   head/usr.bin/sdiff/tests/d_tabends_a.out   (contents, props changed)
>   head/usr.bin/sdiff/tests/d_tabends_b.out   (contents, props changed)
>   head/usr.bin/sdiff/tests/d_tabends_c.out   (contents, props changed)
>   head/usr.bin/sdiff/tests/d_tabs.out   (contents, props changed)
>   head/usr.bin/sdiff/tests/d_tabs1.in   (contents, props changed)
>   head/usr.bin/sdiff/tests/d_tabs2.in   (contents, props changed)
>   head/usr.bin/sdiff/tests/sdiff.sh   (contents, props changed)
> Deleted:
>   head/gnu/usr.bin/sdiff/
> Modified:
>   head/gnu/usr.bin/Makefile
>   head/usr.bin/Makefile
>
> Modified: head/gnu/usr.bin/Makefile
>
> ==============================================================================
> --- head/gnu/usr.bin/Makefile   Fri Apr 29 22:43:11 2016        (r298822)
> +++ head/gnu/usr.bin/Makefile   Fri Apr 29 23:27:15 2016        (r298823)
> @@ -13,7 +13,6 @@ SUBDIR= ${_binutils} \
>         grep \
>         ${_groff} \
>         ${_rcs} \
> -       sdiff \
>         ${_tests}
>
>  SUBDIR_DEPEND_gdb= ${_binutils}
>
> Modified: head/usr.bin/Makefile
>
> ==============================================================================
> --- head/usr.bin/Makefile       Fri Apr 29 22:43:11 2016        (r298822)
> +++ head/usr.bin/Makefile       Fri Apr 29 23:27:15 2016        (r298823)
> @@ -134,6 +134,7 @@ SUBDIR=     alias \
>         rusers \
>         rwall \
>         script \
> +       sdiff \
>         sed \
>         send-pr \
>         seq \
>
> Added: head/usr.bin/sdiff/Makefile
>
> ==============================================================================
> --- /dev/null   00:00:00 1970   (empty, because file is newly added)
> +++ head/usr.bin/sdiff/Makefile Fri Apr 29 23:27:15 2016        (r298823)
> @@ -0,0 +1,16 @@
> +# $FreeBSD$
> +
> +.include <src.opts.mk>
> +
> +PROG=  sdiff
> +SRCS=  common.c edit.c sdiff.c
> +WARNS= 3
> +
> +LIBADD=        util
> +MAN1=  sdiff.1
> +
> +.if ${MK_TESTS} != "no"
> +SUBDIR+= tests
> +.endif
> +
> +.include <bsd.progs.mk>
>
> Added: head/usr.bin/sdiff/common.c
>
> ==============================================================================
> --- /dev/null   00:00:00 1970   (empty, because file is newly added)
> +++ head/usr.bin/sdiff/common.c Fri Apr 29 23:27:15 2016        (r298823)
> @@ -0,0 +1,24 @@
> +/*     $OpenBSD: common.c,v 1.4 2006/05/25 03:20:32 ray Exp $  */
> +
> +/*
> + * Written by Raymond Lai <ray at cyth.net>.
> + * Public domain.
> + */
> +
> +#include <sys/cdefs.h>
> +__FBSDID("$FreeBSD$");
> +
> +#include <err.h>
> +#include <stdlib.h>
> +#include <unistd.h>
> +
> +#include "common.h"
> +
> +void
> +cleanup(const char *filename)
> +{
> +
> +       if (unlink(filename))
> +               err(2, "could not delete: %s", filename);
> +       exit(2);
> +}
>
> Added: head/usr.bin/sdiff/common.h
>
> ==============================================================================
> --- /dev/null   00:00:00 1970   (empty, because file is newly added)
> +++ head/usr.bin/sdiff/common.h Fri Apr 29 23:27:15 2016        (r298823)
> @@ -0,0 +1,9 @@
> +/*     $OpenBSD: common.h,v 1.2 2006/05/25 03:20:32 ray Exp $  */
> +/*     $FreeBSD$       */
> +
> +/*
> + * Written by Raymond Lai <ray at cyth.net>.
> + * Public domain.
> + */
> +
> +void cleanup(const char *) __dead2;
>
> Added: head/usr.bin/sdiff/edit.c
>
> ==============================================================================
> --- /dev/null   00:00:00 1970   (empty, because file is newly added)
> +++ head/usr.bin/sdiff/edit.c   Fri Apr 29 23:27:15 2016        (r298823)
> @@ -0,0 +1,209 @@
> +/*     $OpenBSD: edit.c,v 1.19 2009/06/07 13:29:50 ray Exp $ */
> +
> +/*
> + * Written by Raymond Lai <ray at cyth.net>.
> + * Public domain.
> + */
> +
> +#include <sys/cdefs.h>
> +__FBSDID("$FreeBSD$");
> +
> +#include <sys/types.h>
> +#include <sys/wait.h>
> +
> +#include <ctype.h>
> +#include <err.h>
> +#include <errno.h>
> +#include <paths.h>
> +#include <signal.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <unistd.h>
> +
> +#include "common.h"
> +#include "extern.h"
> +
> +int editit(const char *);
> +
> +/*
> + * Execute an editor on the specified pathname, which is interpreted
> + * from the shell.  This means flags may be included.
> + *
> + * Returns -1 on error, or the exit value on success.
> + */
> +int
> +editit(const char *pathname)
> +{
> +       char *argp[] = {"sh", "-c", NULL, NULL}, *ed, *p;
> +       sig_t sighup, sigint, sigquit, sigchld;
> +       pid_t pid;
> +       int saved_errno, st, ret = -1;
> +
> +       ed = getenv("VISUAL");
> +       if (ed == NULL || ed[0] == '\0')
> +               ed = getenv("EDITOR");
> +       if (ed == NULL || ed[0] == '\0')
> +               ed = _PATH_VI;
> +       if (asprintf(&p, "%s %s", ed, pathname) == -1)
> +               return (-1);
> +       argp[2] = p;
> +
> +       sighup = signal(SIGHUP, SIG_IGN);
> +       sigint = signal(SIGINT, SIG_IGN);
> +       sigquit = signal(SIGQUIT, SIG_IGN);
> +       sigchld = signal(SIGCHLD, SIG_DFL);
> +       if ((pid = fork()) == -1)
> +               goto fail;
> +       if (pid == 0) {
> +               execv(_PATH_BSHELL, argp);
> +               _exit(127);
> +       }
> +       while (waitpid(pid, &st, 0) == -1)
> +               if (errno != EINTR)
> +                       goto fail;
> +       if (!WIFEXITED(st))
> +               errno = EINTR;
> +       else
> +               ret = WEXITSTATUS(st);
> +
> + fail:
> +       saved_errno = errno;
> +       (void)signal(SIGHUP, sighup);
> +       (void)signal(SIGINT, sigint);
> +       (void)signal(SIGQUIT, sigquit);
> +       (void)signal(SIGCHLD, sigchld);
> +       free(p);
> +       errno = saved_errno;
> +       return (ret);
> +}
> +
> +/*
> + * Parse edit command.  Returns 0 on success, -1 on error.
> + */
> +int
> +eparse(const char *cmd, const char *left, const char *right)
> +{
> +       FILE *file;
> +       size_t nread;
> +       int fd;
> +       char *filename;
> +       char buf[BUFSIZ], *text;
> +
> +       /* Skip whitespace. */
> +       while (isspace(*cmd))
> +               ++cmd;
> +
> +       text = NULL;
> +       switch (*cmd) {
> +       case '\0':
> +               /* Edit empty file. */
> +               break;
> +
> +       case 'b':
> +               /* Both strings. */
> +               if (left == NULL)
> +                       goto RIGHT;
> +               if (right == NULL)
> +                       goto LEFT;
> +
> +               /* Neither column is blank, so print both. */
> +               if (asprintf(&text, "%s\n%s\n", left, right) == -1)
> +                       err(2, "could not allocate memory");
> +               break;
> +
> +       case 'l':
> +LEFT:
> +               /* Skip if there is no left column. */
> +               if (left == NULL)
> +                       break;
> +
> +               if (asprintf(&text, "%s\n", left) == -1)
> +                       err(2, "could not allocate memory");
> +
> +               break;
> +
> +       case 'r':
> +RIGHT:
> +               /* Skip if there is no right column. */
> +               if (right == NULL)
> +                       break;
> +
> +               if (asprintf(&text, "%s\n", right) == -1)
> +                       err(2, "could not allocate memory");
> +
> +               break;
> +
> +       default:
> +               return (-1);
> +       }
> +
> +       /* Create temp file. */
> +       if (asprintf(&filename, "%s/sdiff.XXXXXXXXXX", tmpdir) == -1)
> +               err(2, "asprintf");
> +       if ((fd = mkstemp(filename)) == -1)
> +               err(2, "mkstemp");
> +       if (text != NULL) {
> +               size_t len;
> +               ssize_t nwritten;
> +
> +               len = strlen(text);
> +               if ((nwritten = write(fd, text, len)) == -1 ||
> +                   (size_t)nwritten != len) {
> +                       warn("error writing to temp file");
> +                       cleanup(filename);
> +               }
> +       }
> +       close(fd);
> +
> +       /* text is no longer used. */
> +       free(text);
> +
> +       /* Edit temp file. */
> +       if (editit(filename) == -1) {
> +               warn("error editing %s", filename);
> +               cleanup(filename);
> +       }
> +
> +       /* Open temporary file. */
> +       if (!(file = fopen(filename, "r"))) {
> +               warn("could not open edited file: %s", filename);
> +               cleanup(filename);
> +       }
> +
> +       /* Copy temporary file contents to output file. */
> +       for (nread = sizeof(buf); nread == sizeof(buf);) {
> +               size_t nwritten;
> +
> +               nread = fread(buf, sizeof(*buf), sizeof(buf), file);
> +               /* Test for error or end of file. */
> +               if (nread != sizeof(buf) &&
> +                   (ferror(file) || !feof(file))) {
> +                       warnx("error reading edited file: %s", filename);
> +                       cleanup(filename);
> +               }
> +
> +               /*
> +                * If we have nothing to read, break out of loop
> +                * instead of writing nothing.
> +                */
> +               if (!nread)
> +                       break;
> +
> +               /* Write data we just read. */
> +               nwritten = fwrite(buf, sizeof(*buf), nread, outfp);
> +               if (nwritten != nread) {
> +                       warnx("error writing to output file");
> +                       cleanup(filename);
> +               }
> +       }
> +
> +       /* We've reached the end of the temporary file, so remove it. */
> +       if (unlink(filename))
> +               warn("could not delete: %s", filename);
> +       fclose(file);
> +
> +       free(filename);
> +
> +       return (0);
> +}
>
> Added: head/usr.bin/sdiff/extern.h
>
> ==============================================================================
> --- /dev/null   00:00:00 1970   (empty, because file is newly added)
> +++ head/usr.bin/sdiff/extern.h Fri Apr 29 23:27:15 2016        (r298823)
> @@ -0,0 +1,12 @@
> +/*     $OpenBSD: extern.h,v 1.5 2009/06/07 13:29:50 ray Exp $ */
> +/*     $FreeBSD$       */
> +
> +/*
> + * Written by Raymond Lai <ray at cyth.net>.
> + * Public domain.
> + */
> +
> +extern FILE            *outfp;         /* file to save changes to */
> +extern const char      *tmpdir;
> +
> +int eparse(const char *, const char *, const char *);
>
> Added: head/usr.bin/sdiff/sdiff.1
>
> ==============================================================================
> --- /dev/null   00:00:00 1970   (empty, because file is newly added)
> +++ head/usr.bin/sdiff/sdiff.1  Fri Apr 29 23:27:15 2016        (r298823)
> @@ -0,0 +1,174 @@
> +.\" $FreeBSD$
> +.\" $OpenBSD: sdiff.1,v 1.15 2007/06/29 14:48:07 jmc Exp $
> +.\"
> +.\" Written by Raymond Lai <ray at cyth.net>.
> +.\" Public domain.
> +.\"
> +.Dd $Mdocdate: July 5 2012 $
> +.Dt SDIFF 1
> +.Os
> +.Sh NAME
> +.Nm sdiff
> +.Nd side-by-side diff
> +.Sh SYNOPSIS
> +.Nm
> +.Op Fl abdilstW
> +.Op Fl I Ar regexp
> +.Op Fl o Ar outfile
> +.Op Fl w Ar width
> +.Ar file1
> +.Ar file2
> +.Sh DESCRIPTION
> +.Nm
> +displays two files side by side,
> +with any differences between the two highlighted as follows:
> +new lines are marked with
> +.Sq \*(Gt ;
> +deleted lines are marked with
> +.Sq \*(Lt ;
> +and changed lines are marked with
> +.Sq \*(Ba .
> +.Pp
> +.Nm
> +can also be used to interactively merge two files,
> +prompting at each set of differences.
> +See the
> +.Fl o
> +option for an explanation.
> +.Pp
> +The options are:
> +.Bl -tag -width Ds
> +.It Fl l -left-column
> +Only print the left column for identical lines.
> +.It Fl o -output Ar outfile
> +Interactively merge
> +.Ar file1
> +and
> +.Ar file2
> +into
> +.Ar outfile .
> +In this mode, the user is prompted for each set of differences.
> +See
> +.Ev EDITOR
> +and
> +.Ev VISUAL ,
> +below,
> +for details of which editor, if any, is invoked.
> +.Pp
> +The commands are as follows:
> +.Bl -tag -width Ds
> +.It Cm l | 1
> +Choose left set of diffs.
> +.It Cm r | 2
> +Choose right set of diffs.
> +.It Cm s
> +Silent mode \(en identical lines are not printed.
> +.It Cm v
> +Verbose mode \(en identical lines are printed.
> +.It Cm e
> +Start editing an empty file, which will be merged into
> +.Ar outfile
> +upon exiting the editor.
> +.It Cm e Cm l
> +Start editing file with left set of diffs.
> +.It Cm e Cm r
> +Start editing file with right set of diffs.
> +.It Cm e Cm b
> +Start editing file with both sets of diffs.
> +.It Cm q
> +Quit
> +.Nm .
> +.El
> +.It Fl s -suppress-common-lines
> +Skip identical lines.
> +.It Fl w -width Ar width
> +Print a maximum of
> +.Ar width
> +characters on each line.
> +The default is 130 characters.
> +.El
> +.Pp
> +Options passed to
> +.Xr diff 1
> +are:
> +.Bl -tag -width Ds
> +.It Fl a -text
> +Treat
> +.Ar file1
> +and
> +.Ar file2
> +as text files.
> +.It Fl b -ignore-space-change
> +Ignore trailing blank spaces.
> +.It Fl d -minimal
> +Minimize diff size.
> +.It Fl I -ignore-matching-lines Ar regexp
> +Ignore line changes matching
> +.Ar regexp .
> +All lines in the change must match
> +.Ar regexp
> +for the change to be ignored.
> +.It Fl i -ignore-case
> +Do a case-insensitive comparison.
> +.It Fl t -expand-tabs
> +Expand tabs to spaces.
> +.It Fl W -ignore-all-space
> +Ignore all spaces.
> +.It Fl B -ignore-blank-lines
> +Ignore blank lines.
> +.It Fl E -ignore-tab-expansion
> +Treat tabs and eight spaces as the same.
> +.It Fl t -ignore-tabs
> +Ignore tabs.
> +.It Fl H -speed-large-files
> +Assume scattered small changes in a large file.
> +.It Fl -ignore-file-name-case
> +Ignore the case of file names.
> +.It Fl -no-ignore-file-name-case
> +Do not ignore file name case.
> +.It Fl -strip-trailing-cr
> +Skip identical lines.
> +.It Fl -tabsize Ar NUM
> +Change the size of tabs (default is 8.)
> +.El
> +.Sh ENVIRONMENT
> +.Bl -tag -width Ds
> +.It Ev EDITOR , VISUAL
> +Specifies an editor to use with the
> +.Fl o
> +option.
> +If both
> +.Ev EDITOR
> +and
> +.Ev VISUAL
> +are set,
> +.Ev VISUAL
> +takes precedence.
> +If neither
> +.Ev EDITOR
> +nor
> +.Ev VISUAL
> +are set,
> +the default is
> +.Xr vi 1 .
> +.It Ev TMPDIR
> +Specifies a directory for temporary files to be created.
> +The default is
> +.Pa /tmp .
> +.El
> +.Sh SEE ALSO
> +.Xr cmp 1 ,
> +.Xr diff 1 ,
> +.Xr diff3 1 ,
> +.Xr vi 1 ,
> +.Xr re_format 7
> +.Sh AUTHORS
> +.Nm
> +was written from scratch for the public domain by
> +.An Ray Lai Aq ray at cyth.net .
> +.Sh CAVEATS
> +.Pp
> +Tabs are treated as anywhere from one to eight characters wide,
> +depending on the current column.
> +Terminals that treat tabs as eight characters wide will look best.
> +
>
> Added: head/usr.bin/sdiff/sdiff.c
>
> ==============================================================================
> --- /dev/null   00:00:00 1970   (empty, because file is newly added)
> +++ head/usr.bin/sdiff/sdiff.c  Fri Apr 29 23:27:15 2016        (r298823)
> @@ -0,0 +1,1184 @@
> +/*     $OpenBSD: sdiff.c,v 1.36 2015/12/29 19:04:46 gsoares Exp $ */
> +
> +/*
> + * Written by Raymond Lai <ray at cyth.net>.
> + * Public domain.
> + */
> +
> +#include <sys/cdefs.h>
> +__FBSDID("$FreeBSD$");
> +
> +#include <sys/param.h>
> +#include <sys/queue.h>
> +#include <sys/stat.h>
> +#include <sys/types.h>
> +#include <sys/wait.h>
> +
> +#include <ctype.h>
> +#include <err.h>
> +#include <errno.h>
> +#include <fcntl.h>
> +#include <getopt.h>
> +#include <limits.h>
> +#include <paths.h>
> +#include <stdint.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <unistd.h>
> +#include <libutil.h>
> +
> +#include "common.h"
> +#include "extern.h"
> +
> +#define DIFF_PATH      "/usr/bin/diff"
> +
> +#define WIDTH 126
> +/*
> + * Each column must be at least one character wide, plus three
> + * characters between the columns (space, [<|>], space).
> + */
> +#define WIDTH_MIN 5
> +
> +/* 3 kilobytes of chars */
> +#define MAX_CHECK 768
> +
> +/* A single diff line. */
> +struct diffline {
> +       STAILQ_ENTRY(diffline) diffentries;
> +       char    *left;
> +       char     div;
> +       char    *right;
> +};
> +
> +static void astrcat(char **, const char *);
> +static void enqueue(char *, char, char *);
> +static char *mktmpcpy(const char *);
> +static int istextfile(FILE *);
> +static void binexec(char *, char *, char *) __dead2;
> +static void freediff(struct diffline *);
> +static void int_usage(void);
> +static int parsecmd(FILE *, FILE *, FILE *);
> +static void printa(FILE *, size_t);
> +static void printc(FILE *, size_t, FILE *, size_t);
> +static void printcol(const char *, size_t *, const size_t);
> +static void printd(FILE *, size_t);
> +static void println(const char *, const char, const char *);
> +static void processq(void);
> +static void prompt(const char *, const char *);
> +static void usage(void) __dead2;
> +static char *xfgets(FILE *);
> +
> +static STAILQ_HEAD(, diffline) diffhead =
> STAILQ_HEAD_INITIALIZER(diffhead);
> +static size_t line_width;      /* width of a line (two columns and
> divider) */
> +static size_t width;           /* width of each column */
> +static size_t file1ln, file2ln;        /* line number of file1 and file2
> */
> +static int Iflag = 0;  /* ignore sets matching regexp */
> +static int     lflag;          /* print only left column for identical
> lines */
> +static int     sflag;          /* skip identical lines */
> +FILE *outfp;           /* file to save changes to */
> +const char *tmpdir;    /* TMPDIR or /tmp */
> +
> +enum {
> +       HELP_OPT = CHAR_MAX + 1,
> +       NORMAL_OPT,
> +       FCASE_SENSITIVE_OPT,
> +       FCASE_IGNORE_OPT,
> +       FROMFILE_OPT,
> +       TOFILE_OPT,
> +       UNIDIR_OPT,
> +       STRIPCR_OPT,
> +       HORIZ_OPT,
> +       LEFTC_OPT,
> +       SUPCL_OPT,
> +       LF_OPT,
> +       /* the following groupings must be in sequence */
> +       OLDGF_OPT,
> +       NEWGF_OPT,
> +       UNCGF_OPT,
> +       CHGF_OPT,
> +       OLDLF_OPT,
> +       NEWLF_OPT,
> +       UNCLF_OPT,
> +       /* end order-sensitive enums */
> +       TSIZE_OPT,
> +       HLINES_OPT,
> +       LFILES_OPT,
> +       DIFFPROG_OPT,
> +       PIPE_FD,
> +       /* pid from the diff parent (if applicable) */
> +       DIFF_PID,
> +
> +       NOOP_OPT,
> +};
> +
> +static struct option longopts[] = {
> +       /* options only processed in sdiff */
> +       { "left-column",                no_argument,            NULL,
>  LEFTC_OPT },
> +       { "suppress-common-lines",      no_argument,            NULL,
>  's' },
> +       { "width",                      required_argument,      NULL,
>  'w' },
> +
> +       { "output",                     required_argument,      NULL,
>  'o' },
> +       { "diff-program",               required_argument,      NULL,
>  DIFFPROG_OPT },
> +
> +       { "pipe-fd",                    required_argument,      NULL,
>  PIPE_FD },
> +       { "diff-pid",                   required_argument,      NULL,
>  DIFF_PID },
> +       /* Options processed by diff. */
> +       { "ignore-file-name-case",      no_argument,            NULL,
>  FCASE_IGNORE_OPT },
> +       { "no-ignore-file-name-case",   no_argument,            NULL,
>  FCASE_SENSITIVE_OPT },
> +       { "strip-trailing-cr",          no_argument,            NULL,
>  STRIPCR_OPT },
> +       { "tabsize",                    required_argument,      NULL,
>  TSIZE_OPT },
> +       { "help",                       no_argument,            NULL,
>  HELP_OPT },
> +       { "text",                       no_argument,            NULL,
>  'a' },
> +       { "ignore-blank-lines",         no_argument,            NULL,
>  'B' },
> +       { "ignore-space-change",        no_argument,            NULL,
>  'b' },
> +       { "minimal",                    no_argument,            NULL,
>  'd' },
> +       { "ignore-tab-expansion",       no_argument,            NULL,
>  'E' },
> +       { "ignore-matching-lines",      required_argument,      NULL,
>  'I' },
> +       { "ignore-case",                no_argument,            NULL,
>  'i' },
> +       { "expand-tabs",                no_argument,            NULL,
>  't' },
> +       { "speed-large-files",          no_argument,            NULL,
>  'H' },
> +       { "ignore-all-space",           no_argument,            NULL,
>  'W' },
> +
> +       { NULL,                         0,                      NULL,
>  '\0'}
> +};
> +
> +static const char *help_msg[] = {
> +       "\nusage: sdiff [-abdilstW] [-I regexp] [-o outfile] [-w width]
> file1 file2\n",
> +       "\t-l, --left-column, Only print the left column for identical
> lines.",
> +       "\t-o OUTFILE, --output=OUTFILE, nteractively merge file1 and
> file2 into outfile.",
> +       "\t-s, --suppress-common-lines, Skip identical lines.",
> +       "\t-w WIDTH, --width=WIDTH, Print a maximum of WIDTH characters on
> each line.",
> +       "\tOptions passed to diff(1) are:",
> +       "\t\t-a, --text, Treat file1 and file2 as text files.",
> +       "\t\t-b, --ignore-trailing-cr, Ignore trailing blank spaces.",
> +       "\t\t-d, --minimal, Minimize diff size.",
> +       "\t\t-I RE, --ignore-matching-lines=RE, Ignore changes whose line
> matches RE.",
> +       "\t\t-i, --ignore-case, Do a case-insensitive comparison.",
> +       "\t\t-t, --expand-tabs Expand tabs to spaces.",
> +       "\t\t-W, --ignore-all-spaces, Ignore all spaces.",
> +       "\t\t--speed-large-files, Assume large file with scattered
> changes.",
> +       "\t\t--strip-trailing-cr, Strip trailing carriage return.",
> +       "\t\t--ignore-file-name-case, Ignore case of file names.",
> +       "\t\t--no-ignore-file-name-case, Do not ignore file name case",
> +       "\t\t--tabsize NUM, Change size of tabs (default 8.)",
> +
> +       NULL,
> +};
> +
> +/*
> + * Create temporary file if source_file is not a regular file.
> + * Returns temporary file name if one was malloced, NULL if unnecessary.
> + */
> +static char *
> +mktmpcpy(const char *source_file)
> +{
> +       struct stat sb;
> +       ssize_t rcount;
> +       int ifd, ofd;
> +       u_char buf[BUFSIZ];
> +       char *target_file;
> +
> +       /* Open input and output. */
> +       ifd = open(source_file, O_RDONLY, 0);
> +       /* File was opened successfully. */
> +       if (ifd != -1) {
> +               if (fstat(ifd, &sb) == -1)
> +                       err(2, "error getting file status from %s",
> source_file);
> +
> +               /* Regular file. */
> +               if (S_ISREG(sb.st_mode)) {
> +                       close(ifd);
> +                       return (NULL);
> +               }
> +       } else {
> +               /* If ``-'' does not exist the user meant stdin. */
> +               if (errno == ENOENT && strcmp(source_file, "-") == 0)
> +                       ifd = STDIN_FILENO;
> +               else
> +                       err(2, "error opening %s", source_file);
> +       }
> +
> +       /* Not a regular file, so copy input into temporary file. */
> +       if (asprintf(&target_file, "%s/sdiff.XXXXXXXXXX", tmpdir) == -1)
> +               err(2, "asprintf");
> +       if ((ofd = mkstemp(target_file)) == -1) {
> +               warn("error opening %s", target_file);
> +               goto FAIL;
> +       }
> +       while ((rcount = read(ifd, buf, sizeof(buf))) != -1 &&
> +           rcount != 0) {
> +               ssize_t wcount;
> +
> +               wcount = write(ofd, buf, (size_t)rcount);
> +               if (-1 == wcount || rcount != wcount) {
> +                       warn("error writing to %s", target_file);
> +                       goto FAIL;
> +               }
> +       }
> +       if (rcount == -1) {
> +               warn("error reading from %s", source_file);
> +               goto FAIL;
> +       }
> +
> +       close(ifd);
> +       close(ofd);
> +
> +       return (target_file);
> +
> +FAIL:
> +       unlink(target_file);
> +       exit(2);
> +}
> +
> +int
> +main(int argc, char **argv)
> +{
> +       FILE *diffpipe=NULL, *file1, *file2;
> +       size_t diffargc = 0, wflag = WIDTH;
> +       int ch, fd[2] = {-1}, status;
> +       pid_t pid=0; pid_t ppid =-1;
> +       const char *outfile = NULL;
> +       struct option *popt;
> +       char **diffargv, *diffprog = DIFF_PATH, *filename1, *filename2,
> +            *tmp1, *tmp2, *s1, *s2;
> +       int i;
> +
> +       /*
> +        * Process diff flags.
> +        */
> +       /*
> +        * Allocate memory for diff arguments and NULL.
> +        * Each flag has at most one argument, so doubling argc gives an
> +        * upper limit of how many diff args can be passed.  argv[0],
> +        * file1, and file2 won't have arguments so doubling them will
> +        * waste some memory; however we need an extra space for the
> +        * NULL at the end, so it sort of works out.
> +        */
> +       if (!(diffargv = calloc(argc, sizeof(char **) * 2)))
> +               err(2, "main");
> +
> +       /* Add first argument, the program name. */
> +       diffargv[diffargc++] = diffprog;
> +
> +       /* create a dynamic string for merging single-switch options */
> +       if ( asprintf(&diffargv[diffargc++], "-")  < 0 )
> +               err(2, "main");
> +
> +       while ((ch = getopt_long(argc, argv, "aBbdEHI:ilo:stWw:",
> +           longopts, NULL)) != -1) {
> +               const char *errstr;
> +
> +               switch (ch) {
> +               /* only compatible --long-name-form with diff */
> +               case FCASE_IGNORE_OPT:
> +               case FCASE_SENSITIVE_OPT:
> +               case STRIPCR_OPT:
> +               case TSIZE_OPT:
> +               case 'S':
> +               break;
> +               /* combine no-arg single switches */
> +               case 'a':
> +               case 'B':
> +               case 'b':
> +               case 'd':
> +               case 'E':
> +               case 'i':
> +               case 't':
> +               case 'H':
> +               case 'W':
> +                       for(popt = longopts; ch != popt->val && popt->name
> != NULL; popt++);
> +                       diffargv[1]  = realloc(diffargv[1], sizeof(char) *
> strlen(diffargv[1]) + 2);
> +                       /*
> +                        * In diff, the 'W' option is 'w' and the 'w' is
> 'W'.
> +                        */
> +                       if (ch == 'W')
> +                               sprintf(diffargv[1], "%sw", diffargv[1]);
> +                       else
> +                               sprintf(diffargv[1], "%s%c", diffargv[1],
> ch);
> +                       break;
> +               case DIFFPROG_OPT:
> +                       diffargv[0] = diffprog = optarg;
> +                       break;
> +               case 'I':
> +                       Iflag = 1;
> +                       diffargv[diffargc++] = "-I";
> +                       diffargv[diffargc++] = optarg;
> +                       break;
> +               case 'l':
> +                       lflag = 1;
> +                       break;
> +               case 'o':
> +                       outfile = optarg;
> +                       break;
> +               case 's':
> +                       sflag = 1;
> +                       break;
> +               case 'w':
> +                       wflag = strtonum(optarg, WIDTH_MIN,
> +                           INT_MAX, &errstr);
> +                       if (errstr)
> +                               errx(2, "width is %s: %s", errstr, optarg);
> +                       break;
> +               case DIFF_PID:
> +                       ppid = strtonum(optarg, 0, INT_MAX, &errstr);
> +                       if (errstr)
> +                               errx(2, "diff pid value is %s: %s",
> errstr, optarg);
> +                       break;
> +               case HELP_OPT:
> +                       for (i = 0; help_msg[i] != NULL; i++)
> +                               printf("%s\n", help_msg[i]);
> +                       exit(0);
> +                       break;
> +               default:
> +                       usage();
> +                       break;
> +               }
> +       }
> +
> +       /* no single switches were used */
> +       if (strcmp(diffargv[1], "-") == 0 ) {
> +               for ( i = 1; i < argc-1; i++) {
> +                       diffargv[i] = diffargv[i+1];
> +               }
> +               diffargv[diffargc-1] = NULL;
> +               diffargc--;
> +       }
> +
> +       argc -= optind;
> +       argv += optind;
> +
> +       if (argc != 2)
> +               usage();
> +
> +       if (outfile && (outfp = fopen(outfile, "w")) == NULL)
> +               err(2, "could not open: %s", optarg);
> +
> +       if ((tmpdir = getenv("TMPDIR")) == NULL || *tmpdir == '\0')
> +               tmpdir = _PATH_TMP;
> +
> +       filename1 = argv[0];
> +       filename2 = argv[1];
> +
> +       /*
> +        * Create temporary files for diff and sdiff to share if file1
> +        * or file2 are not regular files.  This allows sdiff and diff
> +        * to read the same inputs if one or both inputs are stdin.
> +        *
> +        * If any temporary files were created, their names would be
> +        * saved in tmp1 or tmp2.  tmp1 should never equal tmp2.
> +        */
> +       tmp1 = tmp2 = NULL;
> +       /* file1 and file2 are the same, so copy to same temp file. */
> +       if (strcmp(filename1, filename2) == 0) {
> +               if ((tmp1 = mktmpcpy(filename1)))
> +                       filename1 = filename2 = tmp1;
> +       /* Copy file1 and file2 into separate temp files. */
> +       } else {
> +               if ((tmp1 = mktmpcpy(filename1)))
> +                       filename1 = tmp1;
> +               if ((tmp2 = mktmpcpy(filename2)))
> +                       filename2 = tmp2;
> +       }
> +
> +       diffargv[diffargc++] = filename1;
> +       diffargv[diffargc++] = filename2;
> +       /* Add NULL to end of array to indicate end of array. */
> +       diffargv[diffargc++] = NULL;
> +
> +       /* Subtract column divider and divide by two. */
> +       width = (wflag - 3) / 2;
> +       /* Make sure line_width can fit in size_t. */
> +       if (width > (SIZE_MAX - 3) / 2)
> +               errx(2, "width is too large: %zu", width);
> +       line_width = width * 2 + 3;
> +
> +       if (ppid == -1 ) {
> +               if (pipe(fd))
> +                       err(2, "pipe");
> +
> +               switch (pid = fork()) {
> +               case 0:
> +                       /* child */
> +                       /* We don't read from the pipe. */
> +                       close(fd[0]);
> +                       if (dup2(fd[1], STDOUT_FILENO) == -1)
> +                               err(2, "child could not duplicate
> descriptor");
> +                       /* Free unused descriptor. */
> +                       close(fd[1]);
> +                       execvp(diffprog, diffargv);
> +                       err(2, "could not execute diff: %s", diffprog);
> +                       break;
> +               case -1:
> +                       err(2, "could not fork");
> +                       break;
> +               }
> +
> +               /* parent */
> +               /* We don't write to the pipe. */
> +               close(fd[1]);
> +
> +               /* Open pipe to diff command. */
> +               if ((diffpipe = fdopen(fd[0], "r")) == NULL)
> +                       err(2, "could not open diff pipe");
> +       }
> +       if ((file1 = fopen(filename1, "r")) == NULL)
> +               err(2, "could not open %s", filename1);
> +       if ((file2 = fopen(filename2, "r")) == NULL)
> +               err(2, "could not open %s", filename2);
> +       if (!istextfile(file1) || !istextfile(file2)) {
> +               /* Close open files and pipe, delete temps */
> +               fclose(file1);
> +               fclose(file2);
> +               fclose(diffpipe);
> +               if (tmp1)
> +                       if (unlink(tmp1))
> +                               warn("Error deleting %s.", tmp1);
> +               if (tmp2)
> +                       if (unlink(tmp2))
> +                               warn("Error deleting %s.", tmp2);
> +               free(tmp1);
> +               free(tmp2);
> +               binexec(diffprog, filename1, filename2);
> +       }
> +       /* Line numbers start at one. */
> +       file1ln = file2ln = 1;
> +
> +       /* Read and parse diff output. */
> +       while (parsecmd(diffpipe, file1, file2) != EOF)
> +               ;
> +       fclose(diffpipe);
> +
> +       /* Wait for diff to exit. */
> +       if (waitpid(pid, &status, 0) == -1 || !WIFEXITED(status) ||
> +           WEXITSTATUS(status) >= 2)
> +               err(2, "diff exited abnormally.");
> +
> +       /* Delete and free unneeded temporary files. */
> +       if (tmp1)
> +               if (unlink(tmp1))
> +                       warn("Error deleting %s.", tmp1);
> +       if (tmp2)
> +               if (unlink(tmp2))
> +                       warn("Error deleting %s.", tmp2);
> +       free(tmp1);
> +       free(tmp2);
> +       filename1 = filename2 = tmp1 = tmp2 = NULL;
> +
> +       /* No more diffs, so print common lines. */
> +       if (lflag)
> +               while ((s1 = xfgets(file1)))
> +                       enqueue(s1, ' ', NULL);
> +       else
> +               for (;;) {
> +                       s1 = xfgets(file1);
> +                       s2 = xfgets(file2);
> +                       if (s1 || s2)
> +                               enqueue(s1, ' ', s2);
> +                       else
> +                               break;
> +               }
> +       fclose(file1);
> +       fclose(file2);
> +       /* Process unmodified lines. */
> +       processq();
> +
> +       /* Return diff exit status. */
> +       return (WEXITSTATUS(status));
> +}
> +
> +/*
> + * When sdiff/zsdiff detects a binary file as input, executes them with
> + * diff/zdiff to maintain the same behavior as GNU sdiff with binary
> input.
> + */
> +static void
> +binexec(char *diffprog, char *f1, char *f2)
> +{
> +
> +       char *args[] = {diffprog, f1, f2, (char *) 0};
> +       execv(diffprog, args);
> +
> +       /* If execv() fails, sdiff's execution will continue below. */
> +       errx(1, "Could not execute diff process.\n");
> +}
> +
> +/*
> + * Checks whether a file appears to be a text file.
> + */
> +static int
> +istextfile(FILE *f)
> +{
> +       int     i;
> +       char ch;
> +
> +       if (f == NULL)
> +               return (1);
>
> *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
> _______________________________________________
> svn-src-head at freebsd.org mailing list
> https://lists.freebsd.org/mailman/listinfo/svn-src-head
> To unsubscribe, send any mail to "svn-src-head-unsubscribe at freebsd.org"
>


More information about the svn-src-all mailing list