bug-diffutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [bug-diffutils] -N option doesn't work with "-" as a file argument


From: Paul Eggert
Subject: Re: [bug-diffutils] -N option doesn't work with "-" as a file argument
Date: Sat, 04 Feb 2012 22:15:21 -0800
User-agent: Mozilla/5.0 (X11; Linux i686; rv:9.0) Gecko/20111229 Thunderbird/9.0

Thanks for the bug report; I installed the following patch.

>From 96bc67a57d291edb5129f482f6304c2d8cb7e518 Mon Sep 17 00:00:00 2001
From: Paul Eggert <address@hidden>
Date: Sat, 4 Feb 2012 22:10:40 -0800
Subject: [PATCH] diff: -N, --unidirectional-new-file now compare to "-" too

* NEWS: Document this.
* doc/diffutils.texi (Comparing Directories): Likewise.
Also, document that these options work at the top level.
* src/diff.c (compare_files): Treat EBADF like ENOENT, to handle
the case where "-" is closed.  Allow the other file to be
STDIN_FILENO, in case it's "-".
* tests/Makefile.am (TESTS): Add new-file.
* tests/new-file: New file.
---
 NEWS               |    5 +++++
 doc/diffutils.texi |   33 +++++++++++++++++----------------
 src/diff.c         |   16 +++++++---------
 tests/Makefile.am  |    1 +
 tests/new-file     |   38 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 68 insertions(+), 25 deletions(-)
 create mode 100755 tests/new-file

diff --git a/NEWS b/NEWS
index 808c603..5a69cd7 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,11 @@ GNU diffutils NEWS                                    -*- 
outline -*-
 
 * Noteworthy changes in release ?.? (????-??-??) [?]
 
+** New features
+
+  --new-file (-N) and --unidirectional-new-file now allow comparisons to "-".
+  A standard input that's closed acts like a nonexistent file.
+
 
 * Noteworthy changes in release 3.2 (2011-09-02) [stable]
 
diff --git a/doc/diffutils.texi b/doc/diffutils.texi
index 00403df..d4a68f8 100644
--- a/doc/diffutils.texi
+++ b/doc/diffutils.texi
@@ -1784,20 +1784,23 @@ subdirectories' files, but if you use the @option{-r} or
 @option{--recursive} option, it compares every corresponding pair of files
 in the directory trees, as many levels deep as they go.
 
-For file names that are in only one of the directories, @command{diff}
-normally does not show the contents of the file that exists; it reports
-only that the file exists in that directory and not in the other.  You
-can make @command{diff} act as though the file existed but was empty in the
-other directory, so that it outputs the entire contents of the file that
+If only one file exists, @command{diff} normally does not show its
+contents; it merely reports that one file exists but the other does
+not.  You can make @command{diff} act as though the missing file is
+empty, so that it outputs the entire contents of the file that
 actually exists.  (It is output as either an insertion or a
-deletion, depending on whether it is in the first or the second
-directory given.)  To do this, use the @option{--new-file} (@option{-N})
-option.
-
-If the older directory contains one or more large files that are not in
+deletion, depending on whether the missing file is in the first or the
+second position.)  To do this, use the @option{--new-file}
+(@option{-N}) option.  This option affects command-line arguments as
+well as files found via directory traversal; for example, @samp{diff
+-N a b} treats @file{a} as empty if @file{a} does not exist but
address@hidden does, and similarly @samp{diff -N - b} treats standard input
+as empty if it is closed but @file{b} exists.
+
+If the older directory contains large files that are not in
 the newer directory, you can make the patch smaller by using the
 @option{--unidirectional-new-file} option instead of @option{-N}.
-This option is like @option{-N} except that it only inserts the contents
+This option is like @option{-N} except that it inserts the contents only
 of files that appear in the second directory but not the first (that is,
 files that were added).  At the top of the patch, write instructions for
 the user applying the patch to remove the files that were deleted before
@@ -3843,9 +3846,8 @@ specifies the number of lines affected.  @xref{RCS}.
 
 @item -N
 @itemx --new-file
-In directory comparison, if a file is found in only one directory,
-treat it as present but empty in the other directory.  @xref{Comparing
-Directories}.
+If one file is missing, treat it as present but empty.
address@hidden Directories}.
 
 @item address@hidden
 Use @var{format} to output a group of lines taken from just the second
@@ -3937,8 +3939,7 @@ Use @var{format} to output a line common to both files in 
if-then-else
 format.  @xref{Line Formats}.
 
 @item --unidirectional-new-file
-When comparing directories, if a file appears only in the second
-directory of the two, treat it as present but empty in the other.
+If a first file is missing, treat it as present but empty.
 @xref{Comparing Directories}.
 
 @item -U @var{lines}
diff --git a/src/diff.c b/src/diff.c
index 972d84d..200112b 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -92,15 +92,11 @@ static bool binary;
 enum { binary = true };
 #endif
 
-/* When comparing directories, if a file appears only in one
-   directory, treat it as present but empty in the other (-N).
-   Then 'patch' would create the file with appropriate contents.  */
+/* If one file is missing, treat it as present but empty (-N).  */
 static bool new_file;
 
-/* When comparing directories, if a file appears only in the second
-   directory of the two, treat it as present but empty in the other
-   (--unidirectional-new-file).
-   Then 'patch' would create the file with appropriate contents.  */
+/* If the first file is missing, treat it as present but empty
+   (--unidirectional-new-file).  */
 static bool unidirectional_new_file;
 
 /* Report files compared that are the same (-s).
@@ -1155,9 +1151,11 @@ compare_files (struct comparison const *parent,
            ? (S_ISREG (cmp.file[f].stat.st_mode)
               && ! (cmp.file[f].stat.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO))
               && cmp.file[f].stat.st_size == 0)
-           : (cmp.file[f].desc == ERRNO_ENCODE (ENOENT)
+           : ((cmp.file[f].desc == ERRNO_ENCODE (ENOENT)
+               || cmp.file[f].desc == ERRNO_ENCODE (EBADF))
               && ! parent
-              && cmp.file[1 - f].desc == UNOPENED)))
+              && (cmp.file[1 - f].desc == UNOPENED
+                  || cmp.file[1 - f].desc == STDIN_FILENO))))
       cmp.file[f].desc = NONEXISTENT;
 
   for (f = 0; f < 2; f++)
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 2f6ad53..afc9aad 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -8,6 +8,7 @@ TESTS = \
   help-version \
   function-line-vs-leading-space \
   label-vs-func        \
+  new-file \
   no-dereference \
   no-newline-at-eof \
   stdin
diff --git a/tests/new-file b/tests/new-file
new file mode 100755
index 0000000..af7cc4c
--- /dev/null
+++ b/tests/new-file
@@ -0,0 +1,38 @@
+#!/bin/sh
+# Test --new-file (-N) and --unidirectional-new-file.
+
+. "${srcdir=.}/init.sh"; path_prepend_ ../src
+
+fail=0
+
+echo a > a || fail=1
+
+echo '0a1
+> a' > exp || fail=1
+
+diff -N - a <&- > out; test $? = 1 || fail=1
+compare exp out || fail=1
+
+diff --unidirectional-new-file - a <&- > out; test $? = 1 || fail=1
+compare exp out || fail=1
+
+diff -N b - < a > out; test $? = 1 || fail=1
+compare exp out || fail=1
+
+diff --unidirectional-new-file b - < a > out; test $? = 1 || fail=1
+compare exp out || fail=1
+
+echo '1d0
+< a' > exp || fail=1
+
+diff -N a - <&- > out; test $? = 1 || fail=1
+compare exp out || fail=1
+
+diff --unidirectional-new-file a - <&- > out; test $? = 2 || fail=1
+
+diff -N - b < a > out; test $? = 1 || fail=1
+compare exp out || fail=1
+
+diff --unidirectional-new-file - b < a > out; test $? = 2 || fail=1
+
+Exit $fail
-- 
1.7.6.5




reply via email to

[Prev in Thread] Current Thread [Next in Thread]