[git commit master] patch: add longopts, --dry-run, add one more test

Denys Vlasenko vda.linux at googlemail.com
Sat Oct 24 15:11:55 UTC 2009


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

function                                             old     new   delta
patch_main                                          1110    1214    +104
static.patch_longopts                                  -      47     +47
packed_usage                                       26738   26761     +23
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 2/0 up/down: 174/0)             Total: 174 bytes

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 editors/patch.c       |   35 +++++++++++++++++++++++++++++------
 include/usage.h       |   15 ++++++++++++---
 testsuite/patch.tests |   47 +++++++++++++++++++++++++++++++++++++++++------
 3 files changed, 82 insertions(+), 15 deletions(-)

diff --git a/editors/patch.c b/editors/patch.c
index 4a97151..580ee14 100644
--- a/editors/patch.c
+++ b/editors/patch.c
@@ -78,12 +78,23 @@ int patch_main(int argc UNUSED_PARAM, char **argv)
 	enum {
 		OPT_R = (1 << 2),
 		OPT_N = (1 << 3),
+		OPT_dry_run = (1 << 4) * ENABLE_LONG_OPTS,
 	};
 
 	xfunc_error_retval = 2;
 	{
 		const char *p = "-1";
 		const char *i = "-"; /* compat */
+#if ENABLE_LONG_OPTS
+		static const char patch_longopts[] ALIGN1 =
+			"strip\0"   Required_argument "p"
+			"input\0"   Required_argument "i"
+			"reverse\0" No_argument       "R"
+			"forward\0" No_argument       "N"
+			"dry-run\0" No_argument       "\xff"
+			;
+		applet_long_options = patch_longopts;
+#endif
 		opt = getopt32(argv, "p:i:RN", &p, &i);
 		if (opt & OPT_R)
 			plus = '-';
@@ -97,7 +108,7 @@ int patch_main(int argc UNUSED_PARAM, char **argv)
 		FILE *dst_stream;
 		//char *old_filename;
 		char *new_filename;
-		char *backup_filename;
+		char *backup_filename = NULL;
 		unsigned src_cur_line = 1;
 		unsigned dst_cur_line = 0;
 		unsigned dst_beg_line;
@@ -131,16 +142,21 @@ int patch_main(int argc UNUSED_PARAM, char **argv)
 				bb_make_directory(new_filename, -1, FILEUTILS_RECUR);
 				*slash = '/';
 			}
-			backup_filename = NULL;
 			src_stream = NULL;
 			saved_stat.st_mode = 0644;
-		} else {
+		} else if (!(opt & OPT_dry_run)) {
 			backup_filename = xasprintf("%s.orig", new_filename);
 			xrename(new_filename, backup_filename);
 			src_stream = xfopen_for_read(backup_filename);
+		} else
+			src_stream = xfopen_for_read(new_filename);
+
+		if (opt & OPT_dry_run) {
+			dst_stream = xfopen_for_write("/dev/null");
+		} else {
+			dst_stream = xfopen_for_write(new_filename);
+			fchmod(fileno(dst_stream), saved_stat.st_mode);
 		}
-		dst_stream = xfopen_for_write(new_filename);
-		fchmod(fileno(dst_stream), saved_stat.st_mode);
 
 		printf("patching file %s\n", new_filename);
 
@@ -189,6 +205,11 @@ int patch_main(int argc UNUSED_PARAM, char **argv)
 				patch_line = xmalloc_fgets(patch_file);
 				if (patch_line == NULL)
 					break; /* EOF */
+				if (!*patch_line) {
+					/* whitespace-damaged patch with "" lines */
+					free(patch_line);
+					patch_line = xstrdup(" ");
+				}
 				if ((*patch_line != '-') && (*patch_line != '+')
 				 && (*patch_line != ' ')
 				) {
@@ -244,7 +265,9 @@ int patch_main(int argc UNUSED_PARAM, char **argv)
 			if (backup_filename) {
 				unlink(backup_filename);
 			}
-			if ((dst_cur_line == 0) || (dst_beg_line == 0)) {
+			if (!(opt & OPT_dry_run)
+			 && ((dst_cur_line == 0) || (dst_beg_line == 0))
+			) {
 				/* The new patched file is empty, remove it */
 				xunlink(new_filename);
 				// /* old_filename and new_filename may be the same file */
diff --git a/include/usage.h b/include/usage.h
index d03ec22..85561c5 100644
--- a/include/usage.h
+++ b/include/usage.h
@@ -898,7 +898,7 @@
      "\n	-d	Daemonize" \
 
 #define dos2unix_trivial_usage \
-       "[OPTION] [FILE]"
+       "[OPTIONS] [FILE]"
 #define dos2unix_full_usage "\n\n" \
        "Convert FILE in-place from DOS to Unix format.\n" \
        "When no file is given, use stdin/stdout.\n" \
@@ -907,7 +907,7 @@
      "\n	-d	unix2dos" \
 
 #define unix2dos_trivial_usage \
-       "[OPTION] [FILE]"
+       "[OPTIONS] [FILE]"
 #define unix2dos_full_usage "\n\n" \
        "Convert FILE in-place from Unix to DOS format.\n" \
        "When no file is given, use stdin/stdout.\n" \
@@ -3250,12 +3250,21 @@
 	)
 
 #define patch_trivial_usage \
-       "[-p NUM] [-i DIFF] [-R] [-N]"
+       "[OPTIONS] [ORIGFILE [PATCHFILE]]"
 #define patch_full_usage "\n\n" \
+	IF_LONG_OPTS( \
+       "	-p,--strip NUM	Strip NUM leading components from file names" \
+     "\n	-i,--input DIFF	Read DIFF instead of stdin" \
+     "\n	-R,--reverse	Reverse patch" \
+     "\n	-N,--forward	Ignore already applied patches" \
+     "\n	--dry-run	Don't actually change files" \
+	) \
+	IF_NOT_LONG_OPTS( \
        "	-p NUM	Strip NUM leading components from file names" \
      "\n	-i DIFF	Read DIFF instead of stdin" \
      "\n	-R	Reverse patch" \
      "\n	-N	Ignore already applied patches" \
+	)
 
 #define patch_example_usage \
        "$ patch -p1 < example.diff\n" \
diff --git a/testsuite/patch.tests b/testsuite/patch.tests
index cfe69b7..178048d 100755
--- a/testsuite/patch.tests
+++ b/testsuite/patch.tests
@@ -7,7 +7,7 @@
 # testing "test name" "options" "expected result" "file input" "stdin"
 
 testing "patch with old_file == new_file" \
-	"patch; echo $?; cat input" \
+	'patch; echo $?; cat input' \
 "\
 patching file input
 0
@@ -15,7 +15,10 @@ qwe
 asd
 zxc
 " \
-	"qwe\nzxc\n" \
+"\
+qwe
+zxc
+" \
 "\
 --- input	Jan 01 01:01:01 2000
 +++ input	Jan 01 01:01:01 2000
@@ -26,7 +29,7 @@ zxc
 " \
 
 testing "patch with nonexistent old_file" \
-	"patch; echo $?; cat input" \
+	'patch; echo $?; cat input' \
 "\
 patching file input
 0
@@ -34,7 +37,10 @@ qwe
 asd
 zxc
 " \
-	"qwe\nzxc\n" \
+"\
+qwe
+zxc
+" \
 "\
 --- input.doesnt_exist	Jan 01 01:01:01 2000
 +++ input	Jan 01 01:01:01 2000
@@ -45,14 +51,18 @@ zxc
 " \
 
 testing "patch -R with nonexistent old_file" \
-	"patch -R; echo $?; cat input" \
+	'patch -R; echo $?; cat input' \
 "\
 patching file input
 0
 qwe
 zxc
 " \
-	"qwe\nasd\nzxc\n" \
+"\
+qwe
+asd
+zxc
+" \
 "\
 --- input.doesnt_exist	Jan 01 01:01:01 2000
 +++ input	Jan 01 01:01:01 2000
@@ -62,4 +72,29 @@ zxc
  zxc
 " \
 
+testing "patch detects already applied hunk" \
+	'patch 2>&1; echo $?; cat input' \
+"\
+patching file input
+patch: hunk #1 FAILED at 1
+patch: 1 out of 1 hunk FAILED
+1
+abc
+def
+123
+" \
+"\
+abc
+def
+123
+" \
+"\
+--- input.old	Jan 01 01:01:01 2000
++++ input	Jan 01 01:01:01 2000
+@@ -1,2 +1,3 @@
+ abc
++def
+ 123
+" \
+
 exit $FAILCOUNT
-- 
1.6.3.3



More information about the busybox-cvs mailing list