patch: support "patch [FILE [PATCH]]" format

function                                             old     new   delta
xopen_stdin                                            -      15     +15
patch_main                                          2075    2041     -34

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2010-08-22 05:39:15 +02:00
parent fd27fa8309
commit e7b0a9e5bc
4 changed files with 56 additions and 12 deletions

View File

@ -447,10 +447,21 @@ int patch_main(int argc UNUSED_PARAM, char **argv)
INIT_TT();
opts = getopt32(argv, FLAG_STR, &opt_p, &opt_i);
argv += optind;
reverse = opts & FLAG_REVERSE;
TT.prefix = (opts & FLAG_PATHLEN) ? xatoi(opt_p) : 0; // can be negative!
if (opts & FLAG_INPUT) TT.filepatch = xopen(opt_i, O_RDONLY);
TT.filein = TT.fileout = -1;
if (opts & FLAG_INPUT) {
TT.filepatch = xopen_stdin(opt_i);
} else {
if (argv[0] && argv[1]) {
TT.filepatch = xopen_stdin(argv[1]);
}
}
if (argv[0]) {
oldname = xstrdup(argv[0]);
newname = xstrdup(argv[0]);
}
// Loop through the lines in the patch
for(;;) {
@ -498,18 +509,20 @@ int patch_main(int argc UNUSED_PARAM, char **argv)
state = 1;
}
free(*name);
finish_oldfile();
// Trim date from end of filename (if any). We don't care.
for (s = patchline+4; *s && *s!='\t'; s++)
if (*s=='\\' && s[1]) s++;
i = atoi(s);
if (i>1900 && i<=1970)
*name = xstrdup("/dev/null");
else {
*s = 0;
*name = xstrdup(patchline+4);
if (!argv[0]) {
free(*name);
// Trim date from end of filename (if any). We don't care.
for (s = patchline+4; *s && *s!='\t'; s++)
if (*s=='\\' && s[1]) s++;
i = atoi(s);
if (i>1900 && i<=1970)
*name = xstrdup("/dev/null");
else {
*s = 0;
*name = xstrdup(patchline+4);
}
}
// We defer actually opening the file because svn produces broken

View File

@ -417,6 +417,7 @@ int xopen3(const char *pathname, int flags, int mode) FAST_FUNC;
int open_or_warn(const char *pathname, int flags) FAST_FUNC;
int open3_or_warn(const char *pathname, int flags, int mode) FAST_FUNC;
int open_or_warn_stdin(const char *pathname) FAST_FUNC;
int xopen_stdin(const char *pathname) FAST_FUNC;
void xrename(const char *oldpath, const char *newpath) FAST_FUNC;
int rename_or_warn(const char *oldpath, const char *newpath) FAST_FUNC;
off_t xlseek(int fd, off_t offset, int whence) FAST_FUNC;

View File

@ -46,3 +46,11 @@ int FAST_FUNC open_or_warn_stdin(const char *filename)
return fd;
}
int FAST_FUNC xopen_stdin(const char *filename)
{
int fd = open_or_warn_stdin(filename);
if (fd >= 0)
return fd;
xfunc_die(); /* We already output an error message. */
}

View File

@ -129,7 +129,6 @@ abc
" \
# testing "test name" "command(s)" "expected result" "file input" "stdin"
testing "patch -N ignores already applied hunk" \
'patch -N 2>&1; echo $?; cat input' \
"\
@ -153,6 +152,29 @@ def
123
" \
# testing "test name" "command(s)" "expected result" "file input" "stdin"
testing "patch FILE PATCH" \
'cat >a.patch; patch input a.patch 2>&1; echo $?; cat input; rm a.patch' \
"\
patching file input
0
abc
def
123
" \
"\
abc
123
" \
"\
--- foo.old
+++ foo
@@ -1,2 +1,3 @@
abc
+def
123
" \
rm input.orig 2>/dev/null
exit $FAILCOUNT