[git commit master 1/1] patch: support "patch [FILE [PATCH]]" format

Denys Vlasenko vda.linux at googlemail.com
Sun Aug 22 03:39:15 UTC 2010


commit: http://git.busybox.net/busybox/commit/?id=e7b0a9e5bc60617fb00c321430253d7771d40fd3
branch: http://git.busybox.net/busybox/commit/?id=refs/heads/master

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

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 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 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
-- 
1.7.1



More information about the busybox-cvs mailing list