summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.bin/patch/inp.c14
-rw-r--r--usr.bin/patch/patch.113
-rw-r--r--usr.bin/patch/patch.c45
-rw-r--r--usr.bin/patch/pch.c17
4 files changed, 62 insertions, 27 deletions
diff --git a/usr.bin/patch/inp.c b/usr.bin/patch/inp.c
index f5f43659dd3..bab3562943a 100644
--- a/usr.bin/patch/inp.c
+++ b/usr.bin/patch/inp.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: inp.c,v 1.6 1997/09/22 05:45:26 millert Exp $ */
+/* $OpenBSD: inp.c,v 1.7 1998/11/25 00:30:25 espie Exp $ */
#ifndef lint
-static char rcsid[] = "$OpenBSD: inp.c,v 1.6 1997/09/22 05:45:26 millert Exp $";
+static char rcsid[] = "$OpenBSD: inp.c,v 1.7 1998/11/25 00:30:25 espie Exp $";
#endif /* not lint */
#include "EXTERN.h"
@@ -11,6 +11,8 @@ static char rcsid[] = "$OpenBSD: inp.c,v 1.6 1997/09/22 05:45:26 millert Exp $";
#include "INTERN.h"
#include "inp.h"
+extern bool check_only;
+
/* Input-file-with-indexable-lines abstract type */
static off_t i_size; /* size of the input file */
@@ -80,10 +82,18 @@ char *filename;
if (statfailed && ok_to_create_file) {
if (verbose)
say2("(Creating file %s...)\n",filename);
+ /* in check_patch case, we still display `Creating file' even
+ though we're not. The rule is that -C should be as similar
+ to normal patch behavior as possible
+ */
+ if (check_only)
+ return TRUE;
makedirs(filename, TRUE);
close(creat(filename, 0666));
statfailed = stat(filename, &filestat);
}
+ if (statfailed && check_only)
+ fatal2("%s not found, -C mode, can't probe further\n", filename);
/* For nonexistent or read-only files, look for RCS or SCCS versions. */
if (statfailed
/* No one can write to it. */
diff --git a/usr.bin/patch/patch.1 b/usr.bin/patch/patch.1
index 8fb35d5bf4b..18beb6e46f7 100644
--- a/usr.bin/patch/patch.1
+++ b/usr.bin/patch/patch.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: patch.1,v 1.2 1996/06/10 11:21:30 niklas Exp $ -*- nroff -*-
+.\" $OpenBSD: patch.1,v 1.3 1998/11/25 00:30:25 espie Exp $ -*- nroff -*-
.rn '' }`
.de Sh
.br
@@ -218,6 +218,9 @@ forces
.I patch
to interpret the patch file as a context diff.
.TP 5
+.B \-C or \-\-check
+checks that the patch would apply cleanly, but does not modify anything.
+.TP 5
.B \-d or \-\-directory
causes
.I patch
@@ -505,6 +508,14 @@ generated from.
Could be smarter about partial matches, excessively \&deviant offsets and
swapped code, but that would take an extra pass.
.PP
+Check patch mode (
+.BR -C )
+will fail if you try to check several patches in succession that build on
+each other. The whole code of
+.I patch
+would have to be restructured to keep temporary files around so that it can
+handle this situation.
+.PP
If code has been duplicated (for instance with #ifdef OLDCODE ... #else ...
#endif),
.I patch
diff --git a/usr.bin/patch/patch.c b/usr.bin/patch/patch.c
index b1810671167..3fd24810bc4 100644
--- a/usr.bin/patch/patch.c
+++ b/usr.bin/patch/patch.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: patch.c,v 1.10 1997/09/22 05:45:27 millert Exp $ */
+/* $OpenBSD: patch.c,v 1.11 1998/11/25 00:30:26 espie Exp $ */
/* patch - a program to apply diffs to original files
*
@@ -6,10 +6,13 @@
*
* This program may be copied as long as you don't try to make any
* money off of it, or pretend that you wrote it.
+ *
+ * -C option added in 1998, original code by Marc Espie,
+ * based on FreeBSD behaviour
*/
#ifndef lint
-static char rcsid[] = "$OpenBSD: patch.c,v 1.10 1997/09/22 05:45:27 millert Exp $";
+static char rcsid[] = "$OpenBSD: patch.c,v 1.11 1998/11/25 00:30:26 espie Exp $";
#endif /* not lint */
#include "INTERN.h"
@@ -48,6 +51,9 @@ static int remove_empty_files = FALSE;
/* TRUE if -R was specified on command line. */
static int reverse_flag_specified = FALSE;
+/* TRUE if -C was specified on command line. */
+bool check_only = FALSE;
+
/* Apply a set of diffs as appropriate. */
int
@@ -282,19 +288,21 @@ char **argv;
struct stat statbuf;
char *realout = outname;
- if (move_file(TMPOUTNAME, outname) < 0) {
- toutkeep = TRUE;
- realout = TMPOUTNAME;
- chmod(TMPOUTNAME, filemode);
- }
- else
- chmod(outname, filemode);
-
- if (remove_empty_files && stat(realout, &statbuf) == 0
- && statbuf.st_size == 0) {
- if (verbose)
- say2("Removing %s (empty after patching).\n", realout);
- while (unlink(realout) >= 0) ; /* while is for Eunice. */
+ if (!check_only) {
+ if (move_file(TMPOUTNAME, outname) < 0) {
+ toutkeep = TRUE;
+ realout = TMPOUTNAME;
+ chmod(TMPOUTNAME, filemode);
+ }
+ else
+ chmod(outname, filemode);
+
+ if (remove_empty_files && stat(realout, &statbuf) == 0
+ && statbuf.st_size == 0) {
+ if (verbose)
+ say2("Removing %s (empty after patching).\n", realout);
+ while (unlink(realout) >= 0) ; /* while is for Eunice. */
+ }
}
}
Fclose(rejfp);
@@ -325,7 +333,7 @@ char **argv;
say4("%d out of %d hunks failed--saving rejects to %s\n",
failed, hunk, rejname);
}
- if (move_file(TMPREJNAME, rejname) < 0)
+ if (!check_only && move_file(TMPREJNAME, rejname) < 0)
trejkeep = TRUE;
}
set_signals(1);
@@ -481,6 +489,9 @@ get_some_switches()
case 'c':
diff_type = CONTEXT_DIFF;
break;
+ case 'C':
+ check_only = TRUE;
+ break;
case 'd':
if (!*++s)
s = nextarg();
@@ -571,7 +582,7 @@ get_some_switches()
fprintf(stderr, "\
Usage: patch [options] [origfile [patchfile]] [+ [options] [origfile]]...\n\
Options:\n\
- [-ceEflnNRsStuv] [-b backup-ext] [-B backup-prefix] [-d directory]\n\
+ [-cCeEflnNRsStuv] [-b backup-ext] [-B backup-prefix] [-d directory]\n\
[-D symbol] [-Fmax-fuzz] [-o out-file] [-p[strip-count]]\n\
[-r rej-name] [-V {numbered,existing,simple}]\n");
my_exit(1);
diff --git a/usr.bin/patch/pch.c b/usr.bin/patch/pch.c
index c5f57bdfb37..6e9b1ce6546 100644
--- a/usr.bin/patch/pch.c
+++ b/usr.bin/patch/pch.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: pch.c,v 1.8 1997/04/03 07:07:36 imp Exp $ */
+/* $OpenBSD: pch.c,v 1.9 1998/11/25 00:30:26 espie Exp $ */
#ifndef lint
-static char rcsid[] = "$OpenBSD: pch.c,v 1.8 1997/04/03 07:07:36 imp Exp $";
+static char rcsid[] = "$OpenBSD: pch.c,v 1.9 1998/11/25 00:30:26 espie Exp $";
#endif /* not lint */
#include "EXTERN.h"
@@ -10,6 +10,7 @@ static char rcsid[] = "$OpenBSD: pch.c,v 1.8 1997/04/03 07:07:36 imp Exp $";
#include "INTERN.h"
#include "pch.h"
+extern bool check_only;
/* Patch (diff listing) abstract type. */
static long p_filesize; /* size of the patch file */
@@ -1270,11 +1271,13 @@ do_ed_script()
Fflush(pipefp);
Pclose(pipefp);
ignore_signals();
- if (move_file(TMPOUTNAME, outname) < 0) {
- toutkeep = TRUE;
- chmod(TMPOUTNAME, filemode);
+ if (!check_only) {
+ if (move_file(TMPOUTNAME, outname) < 0) {
+ toutkeep = TRUE;
+ chmod(TMPOUTNAME, filemode);
+ }
+ else
+ chmod(outname, filemode);
}
- else
- chmod(outname, filemode);
set_signals(1);
}