Enforce simple backup mode and compute the backup file name if -B, -Y, or -z is used

This fixes the case where -B or -Y is combined with -z (bug 25968).
This commit is contained in:
Andreas Gruenbacher 2009-03-27 23:05:40 +01:00
parent 19947785bf
commit 8a3f4d70e4
7 changed files with 151 additions and 23 deletions

View File

@ -16,6 +16,18 @@
* util.h (append_to_file): Update definition.
* Makefile.in: Remove timespec.h and m4/timespec.m4.
* common.h (origsuff): New variable.
* patch.c (main): Remember when -z was used.
* util.c (contains_slash): New function.
(move_file): Enforce simple backup mode and compute the backup file
name here if -B, -Y, or -z is used. Fix the case where -B or -Y is
combined with -z.
* patch.man: Document this change.
* tests/backup-prefix-suffix: New test case.
* Makefile.in (TESTS): Add test case.
2009-03-25 Andreas Gruenbacher <agruen@suse.de>
* patch.c (main): Avoid replacing files when nothing has changed.
* tests/unmodified-files: New test case.
* Makefile.in (TESTS): Add test case.

View File

@ -90,8 +90,8 @@ MISC = AUTHORS COPYING ChangeLog INSTALL Makefile.in NEWS README VERSION \
aclocal.m4 config.hin configure configure.ac install-sh \
mkinstalldirs patch.man stdbool_.h tests/test-lib.sh \
update-version.sh
TESTS = tests/corrupt-reject-files tests/crlf-handling \
tests/global-reject-files tests/need-filename \
TESTS = tests/backup-prefix-suffix tests/corrupt-reject-files \
tests/crlf-handling tests/global-reject-files tests/need-filename \
tests/no-newline-triggers-assert tests/preserve-c-function-names \
tests/preserve-mode-and-timestamp tests/reject-format \
tests/remember-backup-files tests/remember-reject-files \

View File

@ -123,6 +123,7 @@ XTERN bool posixly_correct;
XTERN char const *origprae;
XTERN char const *origbase;
XTERN char const *origsuff;
XTERN char const * volatile TMPINNAME;
XTERN char const * volatile TMPOUTNAME;

View File

@ -775,7 +775,7 @@ get_some_switches (void)
case_z:
if (!*optarg)
fatal ("backup suffix is empty");
simple_backup_suffix = savestr (optarg);
origsuff = savestr (optarg);
break;
case 'Z':
set_utc = true;

View File

@ -280,9 +280,15 @@ This is the default if
is conforming to \s-1POSIX\s0.
.TP
\fB\-B\fP \fIpref\fP or \fB\*=prefix=\fP\fIpref\fP
Prefix
Use the
.B simple
method to determine backup file names (see the
.BI "\-V " method
or
.BI "\*=version\-control " method
option), and append
.I pref
to a file name when generating its simple backup file name.
to a file name when generating its backup file name.
For example, with
.B "\-B\ /junk/"
the simple backup file name for
@ -665,9 +671,15 @@ Set internal debugging flags of interest only to
patchers.
.TP
\fB\-Y\fP \fIpref\fP or \fB\*=basename\-prefix=\fP\fIpref\fP
Prefix
Use the
.B simple
method to determine backup file names (see the
.BI "\-V " method
or
.BI "\*=version\-control " method
option), and prefix
.I pref
to the basename of a file name when generating its simple backup file name.
to the basename of a file name when generating its backup file name.
For example, with
.B "\-Y\ .del/"
the simple backup file name for
@ -676,18 +688,21 @@ is
.BR src/patch/.del/util.c .
.TP
\fB\-z\fP \fIsuffix\fP or \fB\*=suffix=\fP\fIsuffix\fP
Use
Use the
.B simple
method to determine backup file names (see the
.BI "\-V " method
or
.BI "\*=version\-control " method
option), and use
.I suffix
as the simple backup suffix.
as the suffix.
For example, with
.B "\-z\ -"
the simple backup file name for
the 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
\fB\-Z\fP or \fB\*=set\-utc\fP
Set the modification and access times of patched files from time stamps

View File

@ -0,0 +1,88 @@
# Copyright (C) 2009 Free Software Foundation, Inc.
#
# Copying and distribution of this file, with or without modification,
# in any medium, are permitted without royalty provided the copyright
# notice and this notice are preserved.
. $srcdir/test-lib.sh
require_cat
use_local_patch
use_tmpdir
# ==============================================================
cat > ab.diff <<EOF
--- a/f
+++ b/f
@@ -1 +1 @@
-one
+two
EOF
echo one > f
check 'patch -b -p1 < ab.diff' <<EOF
patching file f
EOF
check 'cat f.orig' <<EOF
one
EOF
echo one > f
check 'patch -b -B prefix. -p1 < ab.diff' <<EOF
patching file f
EOF
check 'cat prefix.f' <<EOF
one
EOF
echo one > f
check 'patch -b -z .suffix -p1 < ab.diff' <<EOF
patching file f
EOF
check 'cat f.suffix' <<EOF
one
EOF
echo one > f
check 'patch -b -B prefix. -z .suffix -p1 < ab.diff' <<EOF
patching file f
EOF
check 'cat prefix.f.suffix' <<EOF
one
EOF
export PATCH_VERSION_CONTROL=existing
export SIMPLE_BACKUP_SUFFIX=.bak
echo one > f
check 'patch -b -p1 < ab.diff' <<EOF
patching file f
EOF
check 'cat f.bak' <<EOF
one
EOF
touch f.~1~
echo one > f
check 'patch -b -p1 < ab.diff' <<EOF
patching file f
EOF
check 'cat f.~2~' <<EOF
one
EOF
export PATCH_VERSION_CONTROL=numbered
echo one > f
check 'patch -b -p1 < ab.diff' <<EOF
patching file f
EOF
check 'cat f.~3~' <<EOF
one
EOF

32
util.c
View File

@ -117,6 +117,15 @@ file_already_seen (struct stat const *st)
return hash_lookup (file_id_table, &f) != 0;
}
static bool
contains_slash (const char *s)
{
for (; *s; s++)
if (ISSLASH(*s))
return true;
return false;
}
/* Move a file FROM (where *FROM_NEEDS_REMOVAL is nonzero if FROM
needs removal when cleaning up at the end of execution, and where
*FROMST is FROM's status if known),
@ -140,26 +149,29 @@ move_file (char const *from, int volatile *from_needs_removal,
int try_makedirs_errno = 0;
char *bakname;
if (origprae || origbase)
if (origprae || origbase || origsuff)
{
char const *p = origprae ? origprae : "";
char const *b = origbase ? origbase : "";
char const *s = origsuff ? origsuff : "";
char const *o = base_name (to);
size_t plen = strlen (p);
size_t tlen = o - to;
size_t blen = strlen (b);
size_t osize = strlen (o) + 1;
bakname = xmalloc (plen + tlen + blen + osize);
size_t olen = strlen (o);
size_t slen = strlen (s);
bakname = xmalloc (plen + tlen + blen + olen + slen + 1);
memcpy (bakname, p, plen);
memcpy (bakname + plen, to, tlen);
memcpy (bakname + plen + tlen, b, blen);
memcpy (bakname + plen + tlen + blen, o, osize);
for (p += FILESYSTEM_PREFIX_LEN (p); *p; p++)
if (ISSLASH (*p))
{
try_makedirs_errno = ENOENT;
break;
}
memcpy (bakname + plen + tlen + blen, o, olen);
memcpy (bakname + plen + tlen + blen + olen, s, slen + 1);
if ((origprae
&& contains_slash (origprae
+ FILESYSTEM_PREFIX_LEN (origprae)))
|| (origbase && contains_slash (origbase))
|| (origsuff && contains_slash (origsuff)))
try_makedirs_errno = ENOENT;
}
else
{