summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2010-08-22 03:39:15 (GMT)
committer Denys Vlasenko <vda.linux@googlemail.com>2010-08-22 03:39:15 (GMT)
commite7b0a9e5bc60617fb00c321430253d7771d40fd3 (patch)
tree5152c7e606fb72423de8d56c5c97a977c6852033
parentfd27fa83094a85b3e8cb0485467ffa65b572b923 (diff)
downloadbusybox-e7b0a9e5bc60617fb00c321430253d777.tar.gz
busybox-e7b0a9e5bc60617fb00c321430253d777.tar.bz2
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>
-rw-r--r--editors/patch.c35
-rw-r--r--include/libbb.h1
-rw-r--r--libbb/wfopen_input.c8
-rwxr-xr-xtestsuite/patch.tests24
4 files changed, 56 insertions, 12 deletions
diff --git a/editors/patch.c b/editors/patch.c
index 3ed4eba..c40f541 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 ac818a9..3fd7545 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 7263c93..422a58e 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 cd0e965..e482304 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