diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2009-10-24 17:11:55 +0200 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2009-10-24 17:11:55 +0200 |
| commit | 17c838bc6da9ff7defb2a8d5ff539ec743acc1fc (patch) | |
| tree | 1f22614f7fa3b230f25066174ac7fd5504400d36 | |
| parent | 1dacfbb1f466a2964cbf49855f336bcc1d25ebc0 (diff) | |
| download | busybox-w32-17c838bc6da9ff7defb2a8d5ff539ec743acc1fc.tar.gz busybox-w32-17c838bc6da9ff7defb2a8d5ff539ec743acc1fc.tar.bz2 busybox-w32-17c838bc6da9ff7defb2a8d5ff539ec743acc1fc.zip | |
patch: add longopts, --dry-run, add one more test
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@googlemail.com>
| -rw-r--r-- | editors/patch.c | 35 | ||||
| -rw-r--r-- | include/usage.h | 15 | ||||
| -rwxr-xr-x | testsuite/patch.tests | 47 |
3 files changed, 82 insertions, 15 deletions
diff --git a/editors/patch.c b/editors/patch.c index 4a9715144..580ee147c 100644 --- a/editors/patch.c +++ b/editors/patch.c | |||
| @@ -78,12 +78,23 @@ int patch_main(int argc UNUSED_PARAM, char **argv) | |||
| 78 | enum { | 78 | enum { |
| 79 | OPT_R = (1 << 2), | 79 | OPT_R = (1 << 2), |
| 80 | OPT_N = (1 << 3), | 80 | OPT_N = (1 << 3), |
| 81 | OPT_dry_run = (1 << 4) * ENABLE_LONG_OPTS, | ||
| 81 | }; | 82 | }; |
| 82 | 83 | ||
| 83 | xfunc_error_retval = 2; | 84 | xfunc_error_retval = 2; |
| 84 | { | 85 | { |
| 85 | const char *p = "-1"; | 86 | const char *p = "-1"; |
| 86 | const char *i = "-"; /* compat */ | 87 | const char *i = "-"; /* compat */ |
| 88 | #if ENABLE_LONG_OPTS | ||
| 89 | static const char patch_longopts[] ALIGN1 = | ||
| 90 | "strip\0" Required_argument "p" | ||
| 91 | "input\0" Required_argument "i" | ||
| 92 | "reverse\0" No_argument "R" | ||
| 93 | "forward\0" No_argument "N" | ||
| 94 | "dry-run\0" No_argument "\xff" | ||
| 95 | ; | ||
| 96 | applet_long_options = patch_longopts; | ||
| 97 | #endif | ||
| 87 | opt = getopt32(argv, "p:i:RN", &p, &i); | 98 | opt = getopt32(argv, "p:i:RN", &p, &i); |
| 88 | if (opt & OPT_R) | 99 | if (opt & OPT_R) |
| 89 | plus = '-'; | 100 | plus = '-'; |
| @@ -97,7 +108,7 @@ int patch_main(int argc UNUSED_PARAM, char **argv) | |||
| 97 | FILE *dst_stream; | 108 | FILE *dst_stream; |
| 98 | //char *old_filename; | 109 | //char *old_filename; |
| 99 | char *new_filename; | 110 | char *new_filename; |
| 100 | char *backup_filename; | 111 | char *backup_filename = NULL; |
| 101 | unsigned src_cur_line = 1; | 112 | unsigned src_cur_line = 1; |
| 102 | unsigned dst_cur_line = 0; | 113 | unsigned dst_cur_line = 0; |
| 103 | unsigned dst_beg_line; | 114 | unsigned dst_beg_line; |
| @@ -131,16 +142,21 @@ int patch_main(int argc UNUSED_PARAM, char **argv) | |||
| 131 | bb_make_directory(new_filename, -1, FILEUTILS_RECUR); | 142 | bb_make_directory(new_filename, -1, FILEUTILS_RECUR); |
| 132 | *slash = '/'; | 143 | *slash = '/'; |
| 133 | } | 144 | } |
| 134 | backup_filename = NULL; | ||
| 135 | src_stream = NULL; | 145 | src_stream = NULL; |
| 136 | saved_stat.st_mode = 0644; | 146 | saved_stat.st_mode = 0644; |
| 137 | } else { | 147 | } else if (!(opt & OPT_dry_run)) { |
| 138 | backup_filename = xasprintf("%s.orig", new_filename); | 148 | backup_filename = xasprintf("%s.orig", new_filename); |
| 139 | xrename(new_filename, backup_filename); | 149 | xrename(new_filename, backup_filename); |
| 140 | src_stream = xfopen_for_read(backup_filename); | 150 | src_stream = xfopen_for_read(backup_filename); |
| 151 | } else | ||
| 152 | src_stream = xfopen_for_read(new_filename); | ||
| 153 | |||
| 154 | if (opt & OPT_dry_run) { | ||
| 155 | dst_stream = xfopen_for_write("/dev/null"); | ||
| 156 | } else { | ||
| 157 | dst_stream = xfopen_for_write(new_filename); | ||
| 158 | fchmod(fileno(dst_stream), saved_stat.st_mode); | ||
| 141 | } | 159 | } |
| 142 | dst_stream = xfopen_for_write(new_filename); | ||
| 143 | fchmod(fileno(dst_stream), saved_stat.st_mode); | ||
| 144 | 160 | ||
| 145 | printf("patching file %s\n", new_filename); | 161 | printf("patching file %s\n", new_filename); |
| 146 | 162 | ||
| @@ -189,6 +205,11 @@ int patch_main(int argc UNUSED_PARAM, char **argv) | |||
| 189 | patch_line = xmalloc_fgets(patch_file); | 205 | patch_line = xmalloc_fgets(patch_file); |
| 190 | if (patch_line == NULL) | 206 | if (patch_line == NULL) |
| 191 | break; /* EOF */ | 207 | break; /* EOF */ |
| 208 | if (!*patch_line) { | ||
| 209 | /* whitespace-damaged patch with "" lines */ | ||
| 210 | free(patch_line); | ||
| 211 | patch_line = xstrdup(" "); | ||
| 212 | } | ||
| 192 | if ((*patch_line != '-') && (*patch_line != '+') | 213 | if ((*patch_line != '-') && (*patch_line != '+') |
| 193 | && (*patch_line != ' ') | 214 | && (*patch_line != ' ') |
| 194 | ) { | 215 | ) { |
| @@ -244,7 +265,9 @@ int patch_main(int argc UNUSED_PARAM, char **argv) | |||
| 244 | if (backup_filename) { | 265 | if (backup_filename) { |
| 245 | unlink(backup_filename); | 266 | unlink(backup_filename); |
| 246 | } | 267 | } |
| 247 | if ((dst_cur_line == 0) || (dst_beg_line == 0)) { | 268 | if (!(opt & OPT_dry_run) |
| 269 | && ((dst_cur_line == 0) || (dst_beg_line == 0)) | ||
| 270 | ) { | ||
| 248 | /* The new patched file is empty, remove it */ | 271 | /* The new patched file is empty, remove it */ |
| 249 | xunlink(new_filename); | 272 | xunlink(new_filename); |
| 250 | // /* old_filename and new_filename may be the same file */ | 273 | // /* old_filename and new_filename may be the same file */ |
diff --git a/include/usage.h b/include/usage.h index d03ec2295..85561c558 100644 --- a/include/usage.h +++ b/include/usage.h | |||
| @@ -898,7 +898,7 @@ | |||
| 898 | "\n -d Daemonize" \ | 898 | "\n -d Daemonize" \ |
| 899 | 899 | ||
| 900 | #define dos2unix_trivial_usage \ | 900 | #define dos2unix_trivial_usage \ |
| 901 | "[OPTION] [FILE]" | 901 | "[OPTIONS] [FILE]" |
| 902 | #define dos2unix_full_usage "\n\n" \ | 902 | #define dos2unix_full_usage "\n\n" \ |
| 903 | "Convert FILE in-place from DOS to Unix format.\n" \ | 903 | "Convert FILE in-place from DOS to Unix format.\n" \ |
| 904 | "When no file is given, use stdin/stdout.\n" \ | 904 | "When no file is given, use stdin/stdout.\n" \ |
| @@ -907,7 +907,7 @@ | |||
| 907 | "\n -d unix2dos" \ | 907 | "\n -d unix2dos" \ |
| 908 | 908 | ||
| 909 | #define unix2dos_trivial_usage \ | 909 | #define unix2dos_trivial_usage \ |
| 910 | "[OPTION] [FILE]" | 910 | "[OPTIONS] [FILE]" |
| 911 | #define unix2dos_full_usage "\n\n" \ | 911 | #define unix2dos_full_usage "\n\n" \ |
| 912 | "Convert FILE in-place from Unix to DOS format.\n" \ | 912 | "Convert FILE in-place from Unix to DOS format.\n" \ |
| 913 | "When no file is given, use stdin/stdout.\n" \ | 913 | "When no file is given, use stdin/stdout.\n" \ |
| @@ -3250,12 +3250,21 @@ | |||
| 3250 | ) | 3250 | ) |
| 3251 | 3251 | ||
| 3252 | #define patch_trivial_usage \ | 3252 | #define patch_trivial_usage \ |
| 3253 | "[-p NUM] [-i DIFF] [-R] [-N]" | 3253 | "[OPTIONS] [ORIGFILE [PATCHFILE]]" |
| 3254 | #define patch_full_usage "\n\n" \ | 3254 | #define patch_full_usage "\n\n" \ |
| 3255 | IF_LONG_OPTS( \ | ||
| 3256 | " -p,--strip NUM Strip NUM leading components from file names" \ | ||
| 3257 | "\n -i,--input DIFF Read DIFF instead of stdin" \ | ||
| 3258 | "\n -R,--reverse Reverse patch" \ | ||
| 3259 | "\n -N,--forward Ignore already applied patches" \ | ||
| 3260 | "\n --dry-run Don't actually change files" \ | ||
| 3261 | ) \ | ||
| 3262 | IF_NOT_LONG_OPTS( \ | ||
| 3255 | " -p NUM Strip NUM leading components from file names" \ | 3263 | " -p NUM Strip NUM leading components from file names" \ |
| 3256 | "\n -i DIFF Read DIFF instead of stdin" \ | 3264 | "\n -i DIFF Read DIFF instead of stdin" \ |
| 3257 | "\n -R Reverse patch" \ | 3265 | "\n -R Reverse patch" \ |
| 3258 | "\n -N Ignore already applied patches" \ | 3266 | "\n -N Ignore already applied patches" \ |
| 3267 | ) | ||
| 3259 | 3268 | ||
| 3260 | #define patch_example_usage \ | 3269 | #define patch_example_usage \ |
| 3261 | "$ patch -p1 < example.diff\n" \ | 3270 | "$ patch -p1 < example.diff\n" \ |
diff --git a/testsuite/patch.tests b/testsuite/patch.tests index cfe69b76a..178048d2a 100755 --- a/testsuite/patch.tests +++ b/testsuite/patch.tests | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | # testing "test name" "options" "expected result" "file input" "stdin" | 7 | # testing "test name" "options" "expected result" "file input" "stdin" |
| 8 | 8 | ||
| 9 | testing "patch with old_file == new_file" \ | 9 | testing "patch with old_file == new_file" \ |
| 10 | "patch; echo $?; cat input" \ | 10 | 'patch; echo $?; cat input' \ |
| 11 | "\ | 11 | "\ |
| 12 | patching file input | 12 | patching file input |
| 13 | 0 | 13 | 0 |
| @@ -15,7 +15,10 @@ qwe | |||
| 15 | asd | 15 | asd |
| 16 | zxc | 16 | zxc |
| 17 | " \ | 17 | " \ |
| 18 | "qwe\nzxc\n" \ | 18 | "\ |
| 19 | qwe | ||
| 20 | zxc | ||
| 21 | " \ | ||
| 19 | "\ | 22 | "\ |
| 20 | --- input Jan 01 01:01:01 2000 | 23 | --- input Jan 01 01:01:01 2000 |
| 21 | +++ input Jan 01 01:01:01 2000 | 24 | +++ input Jan 01 01:01:01 2000 |
| @@ -26,7 +29,7 @@ zxc | |||
| 26 | " \ | 29 | " \ |
| 27 | 30 | ||
| 28 | testing "patch with nonexistent old_file" \ | 31 | testing "patch with nonexistent old_file" \ |
| 29 | "patch; echo $?; cat input" \ | 32 | 'patch; echo $?; cat input' \ |
| 30 | "\ | 33 | "\ |
| 31 | patching file input | 34 | patching file input |
| 32 | 0 | 35 | 0 |
| @@ -34,7 +37,10 @@ qwe | |||
| 34 | asd | 37 | asd |
| 35 | zxc | 38 | zxc |
| 36 | " \ | 39 | " \ |
| 37 | "qwe\nzxc\n" \ | 40 | "\ |
| 41 | qwe | ||
| 42 | zxc | ||
| 43 | " \ | ||
| 38 | "\ | 44 | "\ |
| 39 | --- input.doesnt_exist Jan 01 01:01:01 2000 | 45 | --- input.doesnt_exist Jan 01 01:01:01 2000 |
| 40 | +++ input Jan 01 01:01:01 2000 | 46 | +++ input Jan 01 01:01:01 2000 |
| @@ -45,14 +51,18 @@ zxc | |||
| 45 | " \ | 51 | " \ |
| 46 | 52 | ||
| 47 | testing "patch -R with nonexistent old_file" \ | 53 | testing "patch -R with nonexistent old_file" \ |
| 48 | "patch -R; echo $?; cat input" \ | 54 | 'patch -R; echo $?; cat input' \ |
| 49 | "\ | 55 | "\ |
| 50 | patching file input | 56 | patching file input |
| 51 | 0 | 57 | 0 |
| 52 | qwe | 58 | qwe |
| 53 | zxc | 59 | zxc |
| 54 | " \ | 60 | " \ |
| 55 | "qwe\nasd\nzxc\n" \ | 61 | "\ |
| 62 | qwe | ||
| 63 | asd | ||
| 64 | zxc | ||
| 65 | " \ | ||
| 56 | "\ | 66 | "\ |
| 57 | --- input.doesnt_exist Jan 01 01:01:01 2000 | 67 | --- input.doesnt_exist Jan 01 01:01:01 2000 |
| 58 | +++ input Jan 01 01:01:01 2000 | 68 | +++ input Jan 01 01:01:01 2000 |
| @@ -62,4 +72,29 @@ zxc | |||
| 62 | zxc | 72 | zxc |
| 63 | " \ | 73 | " \ |
| 64 | 74 | ||
| 75 | testing "patch detects already applied hunk" \ | ||
| 76 | 'patch 2>&1; echo $?; cat input' \ | ||
| 77 | "\ | ||
| 78 | patching file input | ||
| 79 | patch: hunk #1 FAILED at 1 | ||
| 80 | patch: 1 out of 1 hunk FAILED | ||
| 81 | 1 | ||
| 82 | abc | ||
| 83 | def | ||
| 84 | 123 | ||
| 85 | " \ | ||
| 86 | "\ | ||
| 87 | abc | ||
| 88 | def | ||
| 89 | 123 | ||
| 90 | " \ | ||
| 91 | "\ | ||
| 92 | --- input.old Jan 01 01:01:01 2000 | ||
| 93 | +++ input Jan 01 01:01:01 2000 | ||
| 94 | @@ -1,2 +1,3 @@ | ||
| 95 | abc | ||
| 96 | +def | ||
| 97 | 123 | ||
| 98 | " \ | ||
| 99 | |||
| 65 | exit $FAILCOUNT | 100 | exit $FAILCOUNT |
