Index: head/usr.bin/sdiff/edit.c =================================================================== --- head/usr.bin/sdiff/edit.c (revision 299219) +++ head/usr.bin/sdiff/edit.c (revision 299220) @@ -1,202 +1,205 @@ /* $OpenBSD: edit.c,v 1.19 2009/06/07 13:29:50 ray Exp $ */ /* * Written by Raymond Lai . * Public domain. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #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) { sig_t sighup, sigint, sigquit, sigchld; pid_t pid; int saved_errno, st, ret = -1; const char *ed; - if ((ed = getenv("EDITOR")) == NULL) + ed = getenv("VISUAL"); + if (ed == NULL) + ed = getenv("EDITOR"); + if (ed == NULL) ed = _PATH_VI; 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) { execlp(ed, ed, pathname, (char *)NULL); _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); 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); } Index: head/usr.bin/sdiff/sdiff.1 =================================================================== --- head/usr.bin/sdiff/sdiff.1 (revision 299219) +++ head/usr.bin/sdiff/sdiff.1 (revision 299220) @@ -1,160 +1,174 @@ .\" $FreeBSD$ .\" $OpenBSD: sdiff.1,v 1.15 2007/06/29 14:48:07 jmc Exp $ .\" .\" Written by Raymond Lai . .\" Public domain. .\" -.Dd May 7, 2016 +.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 +.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@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.