Subject: bug#6186: du in coreutils should add the -d flag as a shortcut to --max-depth

From: Jim Meyering <[email-masked]>
Date: Tue, 18 May 2010 08:56:10 +0200

Jon Ringuette wrote:
...
>> Your patch did not reach the list.
> I believe it shows up as an attachment on the http://debbugs.gnu.org/cgi/bugreport.cgi?bug=6186 with my last email : [du_add_d.patch (application/octet-stream, attachment)]

I had not seen that.
Besides, that is not the mailing list ;-)

> I can also post the patch directly instead of as a file attachment if that is easier.
>
> Just doing a normal #define DU_DEBUG 1  was giving me an error about lower case function fts_cross_check not existing.  Is there a better way for me to test this to ensure my modification of the debug flag to --debug did not negatively impact past work?

I was going to request this:

    Please do post to the list.
    However, a few guidelines:

    - post git format-patch output, not diff -c output
    - please update NEWS with a sentence describing your change
    - also update doc/coreutils.texi (that's the primary documentation)
    - change/extend a test to exercise the new option
      (hmm... no test exercises --max-depth=N, so asking you to do
       this isn't really fair)

    If you're not familiar with git, a quick how-to is
    in readme files.  Start with README-hacking to checkout the sources,
    then read the first few paragraphs of HACKING for instructions
    on setting up and using git.

but I've decided to do it all for you, and
in so doing discovered one part that has to be changed:
we can't introduce the --debug option your patch adds,
since that shares a prefix with --dereference-args.
Currently, both --d and --de serve as abbreviations for that long-named
option.  If we were to add --debug, they would become ambiguous and make
those uses stop working.  Besides, --debug can't do anything unless
gnulib's fts.c is compiled with debugging enabled.

Eventually, or while debugging, I may add the three-hyphen ---debug
option, but for now have simply commented that out.

I've added a test for --max-depth=N, then wrote the commit log,
NEWS, .texi and test changes to go with your code patch.

-------------------------------

>From a1b74559f1b0dc60b866fa9c0220096fa4abffeb Mon Sep 17 00:00:00 2001
From: Jim Meyering <[email-masked]>
Date: Tue, 18 May 2010 08:39:40 +0200
Subject: [PATCH 1/2] tests: exercise du's --max-depth option

* tests/Makefile.am (TESTS): Add du/max-depth.
* tests/du/max-depth: New file.
---
 tests/Makefile.am  |    1 +
 tests/du/max-depth |   31 +++++++++++++++++++++++++++++++
 2 files changed, 32 insertions(+), 0 deletions(-)
 create mode 100755 tests/du/max-depth

diff --git a/tests/Makefile.am b/tests/Makefile.am
index a732c63..c458574 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -350,6 +350,7 @@ TESTS =						\
   du/inaccessible-cwd				\
   du/long-from-unreadable			\
   du/long-sloop					\
+  du/max-depth					\
   du/no-deref					\
   du/no-x					\
   du/one-file-system				\
diff --git a/tests/du/max-depth b/tests/du/max-depth
new file mode 100755
index 0000000..4ddb6b7
--- /dev/null
+++ b/tests/du/max-depth
@@ -0,0 +1,31 @@
+#!/bin/sh
+# exercise du's --max-depth=N option
+
+# Copyright (C) 2010 Free Software Foundation, Inc.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/init.sh"; path_prepend_ ../src
+
+mkdir -p a/b/c/d/e || framework_failure_
+printf 'a/b/c\na/b\na\n' > exp || framework_failure_
+
+du --max-depth=2 a > out 2>err || fail=1
+
+# Remove the sizes.  They vary between file systems.
+cut -f2- out > k && mv k out
+compare out exp || fail=1
+compare err /dev/null || fail=1
+
+Exit $fail
--
1.7.1.250.g7d1e8

>From 1ccacf7a1b5b93f9e4c8ef562ceceab9726f8656 Mon Sep 17 00:00:00 2001
From: Jon Ringuette <[email-masked]>
Date: Tue, 18 May 2010 08:26:11 +0200
Subject: [PATCH 2/2] du: recognize -d N as equivalent to --max-depth=N

* NEWS (New features): Mention it.
* src/du.c (DEBUG_OPT): Remove.  Use long-named ---debug instead.
Commented out.
(MAX_DEPTH_OPTION): Remove.  Use 'd' instead.
(main): Insert literal "d:"; remove DEBUG_OPT.
* doc/coreutils.texi (du invocation): Add -d to indices.
* tests/du/max-depth: Exercise -d, too.
---
 NEWS               |    3 +++
 doc/coreutils.texi |    2 ++
 src/du.c           |   15 +++++++--------
 tests/du/max-depth |    7 +++++++
 4 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/NEWS b/NEWS
index 5d7b81f..19436fe 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,9 @@ GNU coreutils NEWS                                    -*- outline -*-

 ** New features

+  du recognizes -d N as equivalent to --max-depth=N, for compatibility
+  with FreeBSD.
+
   sort now accepts the --debug option, to highlight the part of the
   line significant in the sort, and warn about questionable options.

diff --git a/doc/coreutils.texi b/doc/coreutils.texi
index 77434e9..115e5fb 100644
--- a/doc/coreutils.texi
+++ b/doc/coreutils.texi
@@ -10427,7 +10427,9 @@ du invocation
 For each symbolic links encountered by @command{du},
 consider the disk space used by the symbolic link.

+@item -d @var{depth}
 @item --max-depth=@var{depth}
+@opindex -d @var{depth}
 @opindex --max-depth=@var{depth}
 @cindex limiting output of @command{du}
 Show the total for each directory (and file if --all) that is at
diff --git a/src/du.c b/src/du.c
index 907ad79..5d83dc6 100644
--- a/src/du.c
+++ b/src/du.c
@@ -56,10 +56,8 @@ extern bool fts_debug;

 #if DU_DEBUG
 # define FTS_CROSS_CHECK(Fts) fts_cross_check (Fts)
-# define DEBUG_OPT "d"
 #else
 # define FTS_CROSS_CHECK(Fts)
-# define DEBUG_OPT
 #endif

 /* Initial size of the hash table.  */
@@ -192,7 +190,7 @@ enum
   EXCLUDE_OPTION,
   FILES0_FROM_OPTION,
   HUMAN_SI_OPTION,
-  MAX_DEPTH_OPTION,
+  FTS_DEBUG,
   TIME_OPTION,
   TIME_STYLE_OPTION
 };
@@ -204,6 +202,7 @@ static struct option const long_options[] =
   {"block-size", required_argument, NULL, 'B'},
   {"bytes", no_argument, NULL, 'b'},
   {"count-links", no_argument, NULL, 'l'},
+  /* {"-debug", no_argument, NULL, FTS_DEBUG}, */
   {"dereference", no_argument, NULL, 'L'},
   {"dereference-args", no_argument, NULL, 'D'},
   {"exclude", required_argument, NULL, EXCLUDE_OPTION},
@@ -211,7 +210,7 @@ static struct option const long_options[] =
   {"files0-from", required_argument, NULL, FILES0_FROM_OPTION},
   {"human-readable", no_argument, NULL, 'h'},
   {"si", no_argument, NULL, HUMAN_SI_OPTION},
-  {"max-depth", required_argument, NULL, MAX_DEPTH_OPTION},
+  {"max-depth", required_argument, NULL, 'd'},
   {"null", no_argument, NULL, '0'},
   {"no-dereference", no_argument, NULL, 'P'},
   {"one-file-system", no_argument, NULL, 'x'},
@@ -312,7 +311,7 @@ Mandatory arguments to long options are mandatory for short options too.\n\
   -x, --one-file-system    skip directories on different file systems\n\
   -X, --exclude-from=FILE  exclude files that match any pattern in FILE\n\
       --exclude=PATTERN    exclude files that match PATTERN\n\
-      --max-depth=N     print the total for a directory (or file, with --all)\n\
+  -d, --max-depth=N     print the total for a directory (or file, with --all)\n\
                           only if it is N or fewer levels below the command\n\
                           line argument;  --max-depth=0 is the same as\n\
                           --summarize\n\
@@ -694,7 +693,7 @@ main (int argc, char **argv)
   for (;;)
     {
       int oi = -1;
-      int c = getopt_long (argc, argv, DEBUG_OPT "0abchHklmsxB:DLPSX:",
+      int c = getopt_long (argc, argv, "0abd:chHklmsxB:DLPSX:",
                            long_options, &oi);
       if (c == -1)
         break;
@@ -702,7 +701,7 @@ main (int argc, char **argv)
       switch (c)
         {
 #if DU_DEBUG
-        case 'd':
+        case FTS_DEBUG:
           fts_debug = true;
           break;
 #endif
@@ -744,7 +743,7 @@ main (int argc, char **argv)
           output_block_size = 1024;
           break;

-        case MAX_DEPTH_OPTION:		/* --max-depth=N */
+        case 'd':		/* --max-depth=N */
           {
             unsigned long int tmp_ulong;
             if (xstrtoul (optarg, NULL, 0, &tmp_ulong, NULL) == LONGINT_OK
diff --git a/tests/du/max-depth b/tests/du/max-depth
index 4ddb6b7..ec22989 100755
--- a/tests/du/max-depth
+++ b/tests/du/max-depth
@@ -28,4 +28,11 @@ cut -f2- out > k && mv k out
 compare out exp || fail=1
 compare err /dev/null || fail=1

+# Repeat, but use -d 1.
+printf 'a/b\na\n' > exp || framework_failure_
+du -d 1 a > out 2>err || fail=1
+cut -f2- out > k && mv k out
+compare out exp || fail=1
+compare err /dev/null || fail=1
+
 Exit $fail
--
1.7.1.250.g7d1e8