patch: support "patch [FILE [PATCH]]" format
authorDenys Vlasenko <vda.linux@googlemail.com>
Sun, 22 Aug 2010 03:39:15 +0000 (05:39 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Sun, 22 Aug 2010 03:39:15 +0000 (05:39 +0200)
function                                             old     new   delta
xopen_stdin                                            -      15     +15
patch_main                                          2075    2041     -34

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
editors/patch.c
include/libbb.h
libbb/wfopen_input.c
testsuite/patch.tests

index 3ed4eba4550f827bb8a339abab9f6ccc2be6a7a5..c40f54155e0419928d838d7693c1fd99dd40f3c3 100644 (file)
@@ -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
index ac818a9eaaadd5f3fde47fea9b76c4bf57626ca5..3fd75451158b1f09c78049319eb75adbc79b5d4b 100644 (file)
@@ -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;
index 7263c933a4dfe7fba797525248daf4ecc40c80ec..422a58ecffda9ad30dbfb1abe1718c88768f6900 100644 (file)
@@ -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. */
+}
index cd0e965cfe34f615b20ce531123fb2b587876b5a..e482304f6f53ee9347f87a524fcef124d76e5ccb 100755 (executable)
@@ -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