summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Gruenbacher <agruen@suse.de>2009-03-12 15:15:49 +0100
committerAndreas Gruenbacher <agruen@suse.de>2009-03-12 15:15:49 +0100
commit6b2b4620383eb47f4979b936b266708ed7812788 (patch)
treeb1c2ee2a1958b134cb13b4d809e9f20d32818cd3
parent6263c220df2b94ae8156c378dc5161779d894297 (diff)
downloadpatch-6b2b4620383eb47f4979b936b266708ed7812788.tar.gz
Import of patch-2.5.tar.gzv2.5
-rw-r--r--ChangeLog79
-rw-r--r--Makefile.in6
-rw-r--r--NEWS19
-rw-r--r--backupfile.c5
-rwxr-xr-xconfigure2
-rw-r--r--configure.in2
-rw-r--r--inp.c68
-rw-r--r--patch.c59
-rw-r--r--patch.man75
-rw-r--r--pch.c80
-rw-r--r--util.c23
-rw-r--r--util.h8
12 files changed, 300 insertions, 126 deletions
diff --git a/ChangeLog b/ChangeLog
index ea9ed3d..80cfc8b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,81 @@
-1997-06-19 Paul Eggert <eggert@pogo.gnu.ai.mit.edu>
+1997-08-31 Paul Eggert <eggert@twinsun.com>
+
+ * configure.in (VERSION): Version 2.5 released.
+
+1997-07-21 Paul Eggert <eggert@twinsun.com>
+
+ * configure.in (VERSION): Bump to 2.4.4.
+ * pch.c (there_is_another_patch), NEWS: Report an error if the patch
+ input contains garbage but no patches.
+
+ * pch.c (open_patch_file):
+ Check for patch file too long (i.e., its size
+ doesn't fit in a `long', and LFS isn't available).
+
+ * inp.c (plan_a):
+ Cast malloc return value, in case malloc returns char *.
+
+1997-07-16 Paul Eggert <eggert@twinsun.com>
+
+ * configure.in (VERSION): Bump to 2.4.3.
+
+ * NEWS, patch.man, pch.c (intuit_diff_type, get_line, pget_line):
+ Now demangles RFC 934 encapsulation.
+ * pch.c (p_rfc934_nesting): New var.
+
+ * pch.c (intuit_diff_type): Don't bother to check file names carefully
+ if we're going to return NO_DIFF.
+
+ * inp.c (plan_a): Count the number of lines before allocating
+ pointer-to-line buffer; this reduces memory requirements
+ considerably (roughly by a factor of 5 on 32-bit hosts).
+ Decrease `size' only when read unexpectedly reports EOF.
+ (i_buffer): New var.
+ (too_many_lines): New fn.
+ (re_input): Free i_buffer if using plan A.
+ Free buffers unconditionally; they can't be zero.
+
+ * inp.c (plan_a, plan_b): Check for overflow of line counter.
+
+ * pch.c (malformed), util.h (memory_fatal, read_fatal, write_fatal):
+ Declare as noreturn.
+
+1997-07-10 Paul Eggert <eggert@twinsun.com>
+
+ * configure.in (VERSION): Bump to 2.4.2.
+
+ * util.c (ok_to_reverse), NEWS: The default answer is now `n';
+ this is better for Emacs.
+
+ * Makefile.in (dist): Use cp -p, not ln;
+ some hosts do the wrong thing with ln if the source is a symbolic link.
+
+ * patch.man: Fix typo: -y -> -Y.
+
+1997-07-05 Paul Eggert <eggert@twinsun.com>
+
+ * configure.in (VERSION): Bump to 2.4.1.
+
+ * patch.c: (main, get_some_switches), NEWS, patch.man:
+ Version control is now independent of whether backups are made.
+ * patch.c (option_help): Put version control options together.
+ (get_some_switches): With CVS 1.9 hack, treat -b foo like -b -z foo,
+ not just -z foo. This change is needed due to recent change in -z.
+ * backupfile.c (find_backup_file_name):
+ backup_type == none causes undefined behavior;
+ this undoes the previous change to this file.
+
+ * patch.c (locate_hunk): Fix bug when locating context diff hunks
+ near end of file with nonzero fuzz.
+
+ * util.c (move_file): Don't assume that ENOENT is reported when both
+ ENOENT and EXDEV apply; this isn't true with DJGPP, and
+ Posix doesn't require it.
+
+ * pch.c (there_is_another_patch):
+ Suggest -p when we can't intuit a file.
+
+1997-06-19 Paul Eggert <eggert@twinsun.com>
* configure.in (VERSION): Version 2.4 released.
* NEWS: Patch is now verbose when patches do not match exactly.
diff --git a/Makefile.in b/Makefile.in
index 9f0b14a..c73010a 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -136,9 +136,9 @@ PV = $(PACKAGE)-$(VERSION)
dist:: $(DISTFILES) $(DISTFILES_PC) $(DISTFILES_PC_DJGPP)
rm -rf $(PV)
mkdir $(PV) $(PV)/pc $(PV)/pc/djgpp
- ln $(DISTFILES) $(PV)
- ln $(DISTFILES_PC) $(PV)/pc
- ln $(DISTFILES_PC_DJGPP) $(PV)/pc/djgpp
+ cp -p $(DISTFILES) $(PV)
+ cp -p $(DISTFILES_PC) $(PV)/pc
+ cp -p $(DISTFILES_PC_DJGPP) $(PV)/pc/djgpp
tar -chf - $(PV) | gzip -9 >$(PV).tar.gz
rm -rf $(PV)
diff --git a/NEWS b/NEWS
index de0f757..e984ba7 100644
--- a/NEWS
+++ b/NEWS
@@ -3,7 +3,22 @@ Known problems:
* The diffutils 2.7 documentation for `patch' is obsolete; this should be
fixed in diffutils 2.8. Until then, see `patch --help' or `man patch'.
-Change in version 2.4:
+Changes in version 2.5:
+
+* Version control is now independent of whether backups are made.
+ The -V or --version-control option and the VERSION_CONTROL and
+ PATCH_VERSION_CONTROL environment variables no longer affect whether
+ backups are made; they affect only the names of the backup files.
+
+* When asking the user whether to reverse a patch,
+ the default answer is now `no' instead of `yes'.
+
+* `patch' can now recognize context diffs that have been encapsulated
+ by prepending "- " to lines beginning with "-" (as per Internet RFC 934).
+
+* `patch' now reports an error if the input contains garbage and no patches.
+
+Changes in version 2.4:
* New options:
-Z or --set-utc sets times of patched files, assuming diff uses UTC (GMT).
@@ -90,7 +105,7 @@ Changes in version 2.2:
--help
--verbose
-i FILE or --input=FILE
- -y PREF or --basename-prefix=PREF
+ -Y PREF or --basename-prefix=PREF
* patch is now quieter by default; use --verbose for the old chatty behavior.
diff --git a/backupfile.c b/backupfile.c
index 3b91be0..4b0f2ec 100644
--- a/backupfile.c
+++ b/backupfile.c
@@ -109,7 +109,8 @@ static int version_number __BACKUPFILE_P ((const char *, const char *, size_t));
/* Return the name of the new backup file for file FILE,
allocated with malloc. Return 0 if out of memory.
- FILE must not end with a '/' unless it is the root directory. */
+ FILE must not end with a '/' unless it is the root directory.
+ Do not call this function if backup_type == none. */
char *
find_backup_file_name (file)
@@ -132,7 +133,7 @@ find_backup_file_name (file)
strcpy (s, file);
#if HAVE_DIR
- if (backup_type != simple && backup_type != none)
+ if (backup_type != simple)
{
int highest_backup;
size_t dir_len = base_name (s) - s;
diff --git a/configure b/configure
index 593e37a..125632a 100755
--- a/configure
+++ b/configure
@@ -540,7 +540,7 @@ test "$program_transform_name" = "" && program_transform_name="s,x,x,"
PACKAGE=patch
-VERSION=2.4
+VERSION=2.5
diff --git a/configure.in b/configure.in
index 7d5b0e8..eb1c32b 100644
--- a/configure.in
+++ b/configure.in
@@ -8,7 +8,7 @@ AC_CONFIG_HEADER(config.h:config.hin)
AC_ARG_PROGRAM
PACKAGE=patch
-VERSION=2.4
+VERSION=2.5
AC_SUBST(PACKAGE)
AC_SUBST(VERSION)
diff --git a/inp.c b/inp.c
index ebc2a03..880b90e 100644
--- a/inp.c
+++ b/inp.c
@@ -1,6 +1,6 @@
/* inputting files to be patched */
-/* $Id: inp.c,v 1.16 1997/06/13 06:28:37 eggert Exp $ */
+/* $Id: inp.c,v 1.18 1997/07/21 17:59:46 eggert Exp $ */
/*
Copyright 1986, 1988 Larry Wall
@@ -33,6 +33,7 @@ If not, write to the Free Software Foundation,
/* Input-file-with-indexable-lines abstract type */
+static char *i_buffer; /* plan A buffer */
static char const **i_ptr; /* pointers to lines in plan A buffer */
static size_t tibufsize; /* size of plan b buffers */
@@ -49,6 +50,7 @@ static size_t last_line_size; /* size of last input line */
static bool plan_a PARAMS ((char const *));/* yield FALSE if memory runs out */
static void plan_b PARAMS ((char const *));
static void report_revision PARAMS ((int));
+static void too_many_lines PARAMS ((char const *)) __attribute__((noreturn));
/* New patch--prepare to edit another file. */
@@ -56,10 +58,8 @@ void
re_input()
{
if (using_plan_a) {
- if (i_ptr) {
- free (i_ptr);
- i_ptr = 0;
- }
+ free (i_buffer);
+ free (i_ptr);
}
else {
close (tifd);
@@ -128,6 +128,14 @@ report_revision (found_revision)
}
+static void
+too_many_lines (filename)
+ char const *filename;
+{
+ fatal ("File `%s' has too many lines.", filename);
+}
+
+
void
get_input_file (filename, outname)
char const *filename;
@@ -210,19 +218,13 @@ plan_a(filename)
register char *buffer;
register LINENUM iline;
size_t size = instat.st_size;
- size_t allocated_bytes_per_input_byte = sizeof *i_ptr + sizeof (char);
- size_t allocated_bytes = (size + 2) * allocated_bytes_per_input_byte;
- /* Fail if arithmetic overflow occurs during size calculations,
+ /* Fail if the file size doesn't fit in a size_t,
or if storage isn't available. */
- if (size != instat.st_size
- || size + 2 < 2
- || allocated_bytes / allocated_bytes_per_input_byte != size + 2
- || ! (ptr = (char const **) malloc (allocated_bytes)))
+ if (! (size == instat.st_size
+ && (buffer = malloc (size ? size : (size_t) 1))))
return FALSE;
- buffer = (char *) (ptr + (size + 2));
-
/* Read the input file, but don't bother reading it if it's empty.
When creating files, the files do not actually exist. */
if (size)
@@ -231,30 +233,45 @@ plan_a(filename)
size_t buffered = 0, n;
if (ifd < 0)
pfatal ("can't open file `%s'", filename);
- while (size - buffered != 0
- && (n = read (ifd, buffer + buffered, size - buffered)) != 0)
+
+ while (size - buffered != 0)
{
- if (n == -1)
+ n = read (ifd, buffer + buffered, size - buffered);
+ if (n == 0)
+ {
+ /* Some non-POSIX hosts exaggerate st_size in text mode;
+ or the file may have shrunk! */
+ size = buffered;
+ break;
+ }
+ if (n == (size_t) -1)
{
/* Perhaps size is too large for this host. */
close (ifd);
- free (ptr);
+ free (buffer);
return FALSE;
}
buffered += n;
}
- /* Some non-POSIX hosts exaggerate st_size in text mode;
- or the file may have shrunk! */
- size = buffered;
-
if (close (ifd) != 0)
read_fatal ();
}
/* Scan the buffer and build array of pointers to lines. */
- iline = 0;
lim = buffer + size;
+ iline = 3; /* 1 unused, 1 for SOF, 1 for EOF if last line is incomplete */
+ for (s = buffer; (s = (char *) memchr (s, '\n', lim - s)); s++)
+ if (++iline < 0)
+ too_many_lines (filename);
+ if (! (iline == (size_t) iline
+ && (size_t) iline * sizeof *ptr / sizeof *ptr == (size_t) iline
+ && (ptr = (char const **) malloc ((size_t) iline * sizeof *ptr))))
+ {
+ free (buffer);
+ return FALSE;
+ }
+ iline = 0;
for (s = buffer; ; s++)
{
ptr[++iline] = s;
@@ -290,6 +307,7 @@ plan_a(filename)
}
/* Plan A will work. */
+ i_buffer = buffer;
i_ptr = ptr;
return TRUE;
}
@@ -308,7 +326,7 @@ plan_b(filename)
register size_t i;
register char const *rev;
register size_t revlen;
- register LINENUM line;
+ register LINENUM line = 1;
if (instat.st_size == 0)
filename = NULL_DEVICE;
@@ -328,6 +346,8 @@ plan_b(filename)
if (c == '\n')
{
+ if (++line < 0)
+ too_many_lines (filename);
if (maxlen < len)
maxlen = len;
len = 0;
diff --git a/patch.c b/patch.c
index e976204..7eb83f5 100644
--- a/patch.c
+++ b/patch.c
@@ -1,6 +1,6 @@
/* patch - a program to apply diffs to original files */
-/* $Id: patch.c,v 1.22 1997/06/17 22:32:49 eggert Exp $ */
+/* $Id: patch.c,v 1.23 1997/07/05 10:32:23 eggert Exp $ */
/*
Copyright 1984, 1985, 1986, 1987, 1988 Larry Wall
@@ -73,7 +73,9 @@ static void init_reject PARAMS ((char const *));
static void reinitialize_almost_everything PARAMS ((void));
static void usage PARAMS ((FILE *, int)) __attribute__((noreturn));
+static int make_backups;
static int backup_if_mismatch;
+static char const *version_control;
static int remove_empty_files;
/* TRUE if -R was specified on command line. */
@@ -133,19 +135,15 @@ char **argv;
: posixly_correct - 1);
{
- char const *v;
-
- v = getenv ("SIMPLE_BACKUP_SUFFIX");
+ char const *v = getenv ("SIMPLE_BACKUP_SUFFIX");
if (v && *v)
simple_backup_suffix = v;
-
- v = getenv ("PATCH_VERSION_CONTROL");
- if (! v)
- v = getenv ("VERSION_CONTROL");
- if (v && *v)
- backup_type = get_version (v);
}
+ version_control = getenv ("PATCH_VERSION_CONTROL");
+ if (! version_control)
+ version_control = getenv ("VERSION_CONTROL");
+
/* Cons up the names of the global temporary files.
Do this before `cleanup' can possibly be called (e.g. by `pfatal'). */
TMPOUTNAME = make_temp ('o');
@@ -158,6 +156,9 @@ char **argv;
Argv = argv;
get_some_switches();
+ if (make_backups | backup_if_mismatch)
+ backup_type = get_version (version_control);
+
init_output (outfile, &outstate);
/* Make sure we clean up in case of disaster. */
@@ -340,7 +341,7 @@ char **argv;
if (! dry_run)
{
move_file ((char *) 0, outname, (mode_t) 0,
- (backup_type != none
+ (make_backups
|| (backup_if_mismatch && (mismatch | failed))));
removedirs (outname);
}
@@ -361,7 +362,7 @@ char **argv;
time_t t;
move_file (TMPOUTNAME, outname, instat.st_mode,
- (backup_type != none
+ (make_backups
|| (backup_if_mismatch && (mismatch | failed))));
if ((set_time | set_utc)
@@ -529,12 +530,12 @@ static char const *const option_help[] =
"",
"Backup and version control options:",
"",
-" -V STYLE --version-control=STYLE Use STYLE version control.",
-" STYLE is either 'simple', 'numbered', or 'existing'.",
-"",
" -b --backup Back up the original contents of each file.",
" --backup-if-mismatch Back up if the patch does not match exactly.",
" --no-backup-if-mismatch Back up mismatches only if otherwise requested.",
+"",
+" -V STYLE --version-control=STYLE Use STYLE version control.",
+" STYLE is either 'simple', 'numbered', or 'existing'.",
" -B PREFIX --prefix=PREFIX Prepend PREFIX to backup file names.",
" -Y PREFIX --basename-prefix=PREFIX Prepend PREFIX to backup file basenames.",
" -z SUFFIX --suffix=SUFFIX Append SUFFIX to backup file names.",
@@ -602,9 +603,10 @@ get_some_switches()
!= -1) {
switch (optc) {
case 'b':
+ make_backups = 1;
/* Special hack for backward compatibility with CVS 1.9.
If the last 4 args are `-b SUFFIX ORIGFILE PATCHFILE',
- treat `-b' as if it were `-z'. */
+ treat `-b' as if it were `-b -z'. */
if (Argc - optind == 3
&& strcmp (Argv[optind - 1], "-b") == 0
&& ! (Argv[optind + 0][0] == '-' && Argv[optind + 0][1])
@@ -613,11 +615,10 @@ get_some_switches()
{
optarg = Argv[optind++];
if (verbosity != SILENT)
- say ("warning: the `-b %s' option is obsolete; use `-z %s' instead\n",
+ say ("warning: the `-b %s' option is obsolete; use `-b -z %s' instead\n",
optarg, optarg);
goto case_z;
}
- backup_type = simple;
break;
case 'B':
if (!*optarg)
@@ -693,7 +694,7 @@ get_some_switches()
exit (0);
break;
case 'V':
- backup_type = get_version (optarg);
+ version_control = optarg;
break;
#if DEBUGGING
case 'x':
@@ -833,21 +834,29 @@ LINENUM fuzz;
return 0;
offset = 1 - first_guess;
- return
- ((last_frozen_line <= prefix_context
+ if (last_frozen_line <= prefix_context
&& offset <= max_pos_offset
&& patch_match (first_guess, offset, (LINENUM) 0, suffix_fuzz))
- ? first_guess : 0);
+ {
+ last_offset = offset;
+ return first_guess + offset;
+ }
+ else
+ return 0;
}
if (suffix_fuzz < 0)
{
/* Can only match end of file. */
offset = first_guess - (input_lines - pat_lines + 1);
- return
- ((offset <= max_neg_offset
+ if (offset <= max_neg_offset
&& patch_match (first_guess, -offset, prefix_fuzz, (LINENUM) 0))
- ? first_guess : 0);
+ {
+ last_offset = - offset;
+ return first_guess - offset;
+ }
+ else
+ return 0;
}
for (offset = 0; offset <= max_offset; offset++) {
diff --git a/patch.man b/patch.man
index 13fa1b9..e3589ba 100644
--- a/patch.man
+++ b/patch.man
@@ -2,7 +2,7 @@
.de Id
.ds Dt \\$4
..
-.Id $Id: patch.man,v 1.20 1997/06/17 22:32:49 eggert Exp $
+.Id $Id: patch.man,v 1.23 1997/07/16 12:26:36 eggert Exp $
.ds = \-\^\-
.de Sp
.if t .sp .3
@@ -32,9 +32,9 @@ program and applies those differences to one or more original files,
producing patched versions.
Normally the patched versions are put in place of the originals.
Backups can be made; see the
-.B \-V
+.B \-b
or
-.B \*=version\-control
+.B \*=backup
option.
The names of the files to be patched are usually taken from the patch file,
but if there's just one file to be patched it can specified on the
@@ -66,6 +66,8 @@ diff listing to
.BR patch ,
and it should work.
If the entire diff is indented by a consistent amount,
+or if a context diff is encapsulated one or more times by prepending
+"\fB\- \fP" to lines starting with "\fB\-\fP" as specified by Internet RFC 934,
this is taken into account.
.PP
With context diffs, and to a lesser extent with normal diffs,
@@ -171,7 +173,7 @@ environment variable is set, and the best name otherwise.
If
.B patch
is not ignoring \s-1RCS\s0 and \s-1SCCS\s0 (see the
-.BI "\-g " num
+.BI "\-g\ " num
or
.BI \*=get= num
option), and no named files exist
@@ -237,22 +239,15 @@ rename or copy the original instead of removing it.
When backing up a file that does not exist,
an empty, unreadable backup file is created
as a placeholder to represent the nonexistent file.
-.Sp
-This option is equivalent to
-.BR \*=version\-control=simple ;
-see the
+See the
.B \-V
or
.B \*=version\-control
-option.
+option for details about how backup file names are determined.
.TP
.B \*=backup\-if\-mismatch
Back up a file if the patch does not match the file exactly
and if backups are not otherwise requested.
-The backup file name is calculated as usual,
-except that if the version control method is
-.BR none ,
-a simple backup name is used.
This is the default unless the
.B POSIXLY_CORRECT
environment variable is set.
@@ -265,10 +260,11 @@ This is the default if the
environment variable is set.
.TP
\fB\-B\fP \fIpref\fP or \fB\*=prefix=\fP\fIpref\fP
-Prefix simple backup file names with
-.IR pref .
+Prefix
+.I pref
+to a file name when generating its simple backup file name.
For example, with
-.B "\-B /junk/"
+.B "\-B\ /junk/"
the simple backup file name for
.B src/patch/util.c
is
@@ -510,6 +506,8 @@ backup file names. The method can also be given by the
(or, if that's not set, the
.BR VERSION_CONTROL )
environment variable, which is overridden by this option.
+The method does not affect whether backup files are made;
+it affects only the names of any backup files that are made.
.Sp
The value of
.I method
@@ -526,10 +524,6 @@ accepted):
\fBexisting\fP or \fBnil\fP
Make numbered backups of files that already have them,
otherwise simple backups.
-.TP
-\fBnone\fP
-Do not make backups, unless backup-if-mismatch is in effect
-and patches do not match files.
This is the default.
.TP
\fBnumbered\fP or \fBt\fP
@@ -547,7 +541,7 @@ The
.B \-B
or
.BR \*=prefix ,
-.B \-y
+.B \-Y
or
.BR \*=basename\-prefix ,
and
@@ -580,12 +574,13 @@ Set internal debugging flags of interest only to
.B patch
patchers.
.TP
-\fB\-y\fP \fIpref\fP or \fB\*=basename\-prefix=\fP\fIpref\fP
-Prefix the basename of the simple backup file name with
-.IR pref .
+\fB\-Y\fP \fIpref\fP or \fB\*=basename\-prefix=\fP\fIpref\fP
+Prefix
+.I pref
+to the basename of a file name when generating its simple backup file name.
For example, with
-.B "\-y .del/"
-the backup file name for
+.B "\-Y\ .del/"
+the simple backup file name for
.B src/patch/util.c
is
.BR src/patch/.del/util.c .
@@ -594,7 +589,13 @@ is
Use
.I suffix
as the simple backup suffix.
-The backup extension may also be specified by the
+For example, with
+.B "\-z\ -"
+the simple backup file name for
+.B src/patch/util.c
+is
+.BR src/patch/util.c- .
+The backup suffix may also be specified by the
.B SIMPLE_BACKUP_SUFFIX
environment variable, which is overridden by this option.
.TP
@@ -653,9 +654,8 @@ it takes the first existing file from the list (old, new, index)
when intuiting file names from diff headers,
it does not remove files that are empty after patching,
it does not ask whether to get files from \s-1RCS\s0 or \s-1SCCS\s0,
-it requires that all options precede the
-files in the command line,
-and by default it does not make backup files.
+it requires that all options precede the files in the command line,
+and it does not backup files when there is a mismatch.
.TP
.B SIMPLE_BACKUP_SUFFIX
Extension to use for simple backup file names instead of
@@ -686,6 +686,10 @@ controlling terminal; used to get answers to questions asked of the user
.SH "SEE ALSO"
.BR diff (1),
.BR ed (1)
+.Sp
+Marshall T. Rose and Einar A. Stefferud,
+Proposed Standard for Message Encapsulation,
+Internet RFC 934 <URL:ftp://ftp.isi.edu/in-notes/rfc934.txt> (1985-01).
.SH "NOTES FOR PATCH SENDERS"
There are several things you should bear in mind if you are going to
be sending out patches.
@@ -912,15 +916,12 @@ in file names.
.B " \(bu"
In traditional
.BR patch ,
-simple backups were enabled by default.
+backups were enabled by default.
This behavior is now enabled with the
.B \-b
or
.B \*=backup
-option, or by setting the
-.B VERSION_CONTROL
-environment variable to
-.BR simple .
+option.
.Sp
Conversely, in \s-1POSIX\s0
.BR patch ,
@@ -934,12 +935,12 @@ option or by setting the
environment variable.
.Sp
The
-.BI \-b " suffix"
+.BI \-b "\ suffix"
option
of traditional
.B patch
is equivalent to the
-.BI "\-b \-z" " suffix"
+.BI "\-b\ \-z" "\ suffix"
options of \s-1GNU\s0
.BR patch .
.TP
diff --git a/pch.c b/pch.c
index 64a627a..f5c0ce0 100644
--- a/pch.c
+++ b/pch.c
@@ -1,6 +1,6 @@
/* reading patches */
-/* $Id: pch.c,v 1.23 1997/06/17 06:52:12 eggert Exp $ */
+/* $Id: pch.c,v 1.26 1997/07/21 17:59:46 eggert Exp $ */
/*
Copyright 1986, 1987, 1988 Larry Wall
@@ -38,6 +38,7 @@ If not, write to the Free Software Foundation,
static FILE *pfp; /* patch file pointer */
static int p_says_nonexistent[2]; /* [0] for old file, [1] for new;
value is 0 for nonempty, 1 for empty, 2 for nonexistent */
+static int p_rfc934_nesting; /* RFC 934 nesting level */
static time_t p_timestamp[2]; /* timestamps in patch headers */
static off_t p_filesize; /* size of the patch file */
static LINENUM p_first; /* 1st line number */
@@ -67,11 +68,11 @@ enum nametype { OLD, NEW, INDEX, NONE };
static enum diff intuit_diff_type PARAMS ((void));
static enum nametype best_name PARAMS ((char * const *, int const *));
static int prefix_components PARAMS ((char *, int));
-static size_t pget_line PARAMS ((int));
+static size_t pget_line PARAMS ((int, int));
static size_t get_line PARAMS ((void));
static bool incomplete_line PARAMS ((void));
static bool grow_hunkmax PARAMS ((void));
-static void malformed PARAMS ((void));
+static void malformed PARAMS ((void)) __attribute__ ((noreturn));
static void next_intuit_at PARAMS ((file_offset, LINENUM));
static void skip_to PARAMS ((file_offset, LINENUM));
@@ -142,6 +143,8 @@ open_patch_file(filename)
pfatal ("fstat");
}
p_filesize = st.st_size;
+ if (p_filesize != (file_offset) p_filesize)
+ fatal ("patch file is too long");
next_intuit_at (file_pos, (LINENUM) 1);
set_hunkmax();
}
@@ -197,6 +200,8 @@ there_is_another_patch()
say (p_base
? " Ignoring the trailing garbage.\ndone\n"
: " I can't seem to find a patch in there anywhere.\n");
+ if (! p_base && p_filesize)
+ fatal ("Only garbage was found in the patch input.");
return FALSE;
}
if (skip_rest_of_patch)
@@ -219,8 +224,13 @@ there_is_another_patch()
if (p_indent)
say ("(Patch is indented %d space%s.)\n", p_indent, p_indent==1?"":"s");
if (! inname)
- say ("can't find file to patch at input line %ld\n",
- p_sline);
+ {
+ say ("can't find file to patch at input line %ld\n",
+ p_sline);
+ say (strippath == INT_MAX
+ ? "Perhaps you should have used the -p or --strip option?\n"
+ : "Perhaps you used the wrong -p or --strip option?\n");
+ }
}
skip_to(p_start,p_sline);
@@ -286,6 +296,7 @@ intuit_diff_type()
version_controlled[OLD] = -1;
version_controlled[NEW] = -1;
version_controlled[INDEX] = -1;
+ p_rfc934_nesting = 0;
p_timestamp[OLD] = p_timestamp[NEW] = (time_t) -1;
p_says_nonexistent[OLD] = p_says_nonexistent[NEW] = 0;
Fseek (pfp, p_base, SEEK_SET);
@@ -296,7 +307,7 @@ intuit_diff_type()
stars_last_line = stars_this_line;
this_line = file_tell (pfp);
indent = 0;
- if (! pget_line (0)) {
+ if (! pget_line (0, 0)) {
if (first_command_line >= 0) {
/* nothing but deletes!? */
p_start = first_command_line;
@@ -307,8 +318,7 @@ intuit_diff_type()
else {
p_start = this_line;
p_sline = p_input_line;
- retval = NO_DIFF;
- goto scan_exit;
+ return NO_DIFF;
}
}
for (s = buf; *s == ' ' || *s == '\t' || *s == 'X'; s++) {
@@ -328,8 +338,6 @@ intuit_diff_type()
}
if (!stars_last_line && strnEQ(s, "*** ", 4))
name[OLD] = fetchname (s+4, strippath, &p_timestamp[OLD]);
- else if (strnEQ(s, "--- ", 4))
- name[NEW] = fetchname (s+4, strippath, &p_timestamp[NEW]);
else if (strnEQ(s, "+++ ", 4))
/* Swap with NEW below. */
name[OLD] = fetchname (s+4, strippath, &p_timestamp[OLD]);
@@ -349,7 +357,21 @@ intuit_diff_type()
revision = savestr (revision);
*t = oldc;
}
- }
+ } else
+ {
+ for (t = s; t[0] == '-' && t[1] == ' '; t += 2)
+ continue;
+ if (strnEQ(t, "--- ", 4))
+ {
+ time_t timestamp = (time_t) -1;
+ name[NEW] = fetchname (t+4, strippath, &timestamp);
+ if (timestamp != (time_t) -1)
+ {
+ p_timestamp[NEW] = timestamp;
+ p_rfc934_nesting = (t - s) >> 1;
+ }
+ }
+ }
if ((diff_type == NO_DIFF || diff_type == ED_DIFF) &&
first_command_line >= 0 &&
strEQ(s, ".\n") ) {
@@ -1424,19 +1446,21 @@ another_hunk (difftype, rev)
static size_t
get_line ()
{
- return pget_line (p_indent);
+ return pget_line (p_indent, p_rfc934_nesting);
}
/* Input a line from the patch file, worrying about indentation.
Strip up to INDENT characters' worth of leading indentation.
+ Then remove up to RFC934_NESTING instances of leading "- ".
Ignore any partial lines at end of input, but warn about them.
Succeed if a line was read; it is terminated by "\n\0" for convenience.
Return the number of characters read, including '\n' but not '\0'.
Return -1 if we ran out of memory. */
static size_t
-pget_line (indent)
+pget_line (indent, rfc934_nesting)
int indent;
+ int rfc934_nesting;
{
register FILE *fp = pfp;
register int c;
@@ -1465,6 +1489,23 @@ pget_line (indent)
i = 0;
b = buf;
+
+ while (c == '-' && 0 <= --rfc934_nesting)
+ {
+ c = getc (fp);
+ if (c == EOF)
+ goto patch_ends_in_middle_of_line;
+ if (c != ' ')
+ {
+ i = 1;
+ b[0] = '-';
+ break;
+ }
+ c = getc (fp);
+ if (c == EOF)
+ goto patch_ends_in_middle_of_line;
+ }
+
s = bufsize;
for (;;)
@@ -1487,17 +1528,18 @@ pget_line (indent)
break;
c = getc (fp);
if (c == EOF)
- {
- if (ferror (fp))
- read_fatal ();
- say ("patch unexpectedly ends in middle of line\n");
- return 0;
- }
+ goto patch_ends_in_middle_of_line;
}
b[i] = '\0';
p_input_line++;
return i;
+
+ patch_ends_in_middle_of_line:
+ if (ferror (fp))
+ read_fatal ();
+ say ("patch unexpectedly ends in middle of line\n");
+ return 0;
}
static bool
diff --git a/util.c b/util.c
index 935b325..03a8e16 100644
--- a/util.c
+++ b/util.c
@@ -1,6 +1,6 @@
/* utility functions for `patch' */
-/* $Id: util.c,v 1.22 1997/06/13 06:28:37 eggert Exp $ */
+/* $Id: util.c,v 1.24 1997/07/10 08:16:12 eggert Exp $ */
/*
Copyright 1986 Larry Wall
@@ -154,23 +154,32 @@ move_file (from, to, mode, backup)
if (rename (from, to) != 0)
{
+ int to_dir_known_to_exist = 0;
+
if (errno == ENOENT
&& (to_errno == -1 || to_errno == ENOENT))
{
makedirs (to);
+ to_dir_known_to_exist = 1;
if (rename (from, to) == 0)
return;
}
-#ifdef EXDEV
if (errno == EXDEV)
{
- if (! backup && unlink (to) != 0 && errno != ENOENT)
- pfatal ("can't remove `%s'", to);
+ if (! backup)
+ {
+ if (unlink (to) == 0)
+ to_dir_known_to_exist = 1;
+ else if (errno != ENOENT)
+ pfatal ("can't remove `%s'", to);
+ }
+ if (! to_dir_known_to_exist)
+ makedirs (to);
copy_file (from, to, mode);
return;
}
-#endif
+
pfatal ("can't rename `%s' to `%s'", from, to);
}
}
@@ -649,8 +658,8 @@ ok_to_reverse (format, va_alist)
}
else
{
- ask (reverse ? " Ignore -R? [y] " : " Assume -R? [y] ");
- r = *buf != 'n';
+ ask (reverse ? " Ignore -R? [n] " : " Assume -R? [n] ");
+ r = *buf == 'y';
if (! r)
{
ask ("Apply anyway? [n] ");
diff --git a/util.h b/util.h
index f7fda0a..0484224 100644
--- a/util.h
+++ b/util.h
@@ -1,6 +1,6 @@
/* utility functions for `patch' */
-/* $Id: util.h,v 1.14 1997/06/13 06:28:37 eggert Exp $ */
+/* $Id: util.h,v 1.15 1997/07/16 12:26:36 eggert Exp $ */
int ok_to_reverse PARAMS ((char const *, ...)) __attribute__ ((format (printf, 1, 2)));
void ask PARAMS ((char const *, ...)) __attribute__ ((format (printf, 1, 2)));
@@ -23,10 +23,10 @@ void copy_file PARAMS ((char const *, char const *, mode_t));
void exit_with_signal PARAMS ((int)) __attribute__ ((noreturn));
void ignore_signals PARAMS ((void));
void init_time PARAMS ((void));
-void memory_fatal PARAMS ((void));
+void memory_fatal PARAMS ((void)) __attribute__ ((noreturn));
void move_file PARAMS ((char const *, char *, mode_t, int));
-void read_fatal PARAMS ((void));
+void read_fatal PARAMS ((void)) __attribute__ ((noreturn));
void remove_prefix PARAMS ((char *, size_t));
void removedirs PARAMS ((char *));
void set_signals PARAMS ((int));
-void write_fatal PARAMS ((void));
+void write_fatal PARAMS ((void)) __attribute__ ((noreturn));