From e7b0a9e5bc60617fb00c321430253d7771d40fd3 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 22 Aug 2010 05:39:15 +0200 Subject: [PATCH] patch: support "patch [FILE [PATCH]]" format function old new delta xopen_stdin - 15 +15 patch_main 2075 2041 -34 Signed-off-by: Denys Vlasenko --- editors/patch.c | 35 ++++++++++++++++++++++++----------- include/libbb.h | 1 + libbb/wfopen_input.c | 8 ++++++++ testsuite/patch.tests | 24 +++++++++++++++++++++++- 4 files changed, 56 insertions(+), 12 deletions(-) diff --git a/editors/patch.c b/editors/patch.c index 3ed4eba45..c40f54155 100644 --- a/editors/patch.c +++ b/editors/patch.c @@ -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 diff --git a/include/libbb.h b/include/libbb.h index ac818a9ea..3fd754511 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -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; diff --git a/libbb/wfopen_input.c b/libbb/wfopen_input.c index 7263c933a..422a58ecf 100644 --- a/libbb/wfopen_input.c +++ b/libbb/wfopen_input.c @@ -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. */ +} diff --git a/testsuite/patch.tests b/testsuite/patch.tests index cd0e965cf..e482304f6 100755 --- a/testsuite/patch.tests +++ b/testsuite/patch.tests @@ -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 -- 2.25.1