patch: add longopts, --dry-run, add one more test
No binary (build failed)
—
(log yok)
| @@ -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 */ | |
| @@ -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" \ | |
| @@ -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 | |