]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
stat: make --format=%N honor the QUOTING_STYLE env var
authorPádraig Brady <P@draigBrady.com>
Thu, 3 Nov 2016 15:36:48 +0000 (15:36 +0000)
committerPádraig Brady <P@draigBrady.com>
Sat, 5 Nov 2016 00:44:06 +0000 (00:44 +0000)
* doc/coreutils.texi (stat invocation): Describe the
QUOTING_STYLE values now supported.
* src/stat.c (getenv_quoting_style): A new function called
from main, that sets the default quoting style for quotearg.
(main): Call getenv_quoting_style() when %N specified.
* tests/misc/stat-fmt.sh: Add a test case.
* NEWS: Mention the improvement.
Fixes http://bugs.gnu.org/23422

NEWS
doc/coreutils.texi
src/stat.c
tests/misc/stat-fmt.sh

diff --git a/NEWS b/NEWS
index 9548de885cf7ecaa7a205f0a8fb9b9a7f4fbdd94..844e23332e6dd65eb3ff901a170a2d799af4b18a 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -85,6 +85,9 @@ GNU coreutils NEWS                                    -*- outline -*-
   tail -f uses polling for "prl_fs" and "smb2", inotify for "m1fs",
   and attempts inotify for "wslfs".
 
+  stat --format=%N for quoting file names now honors the
+  same QUOTING_STYLE environment variable values as ls.
+
 ** New Features
 
   date now accepts the --debug option, to annotate the parsed date string,
index 95419b44ed3935d7371e286066a49d62903110af..927e552ab67abcd33abc354356d6d3372645f5f8 100644 (file)
@@ -7724,6 +7724,7 @@ Use style @var{word} to quote file names and other strings that may
 contain arbitrary characters.  The @var{word} should
 be one of the following:
 
+@macro quotingStyles
 @table @samp
 @item literal
 Output strings as-is; this is the same as the @option{-N} or
@@ -7761,6 +7762,8 @@ surrounding quotation marks appropriate for the locale, and quote
 @t{'like this'} instead of @t{"like
 this"} in the default C locale.  This looks nicer on many displays.
 @end table
+@end macro
+@quotingStyles
 
 You can specify the default value of the @option{--quoting-style} option
 with the environment variable @env{QUOTING_STYLE}@.  If that environment
@@ -11775,7 +11778,7 @@ The valid @var{format} directives for files with @option{--format} and
 @item %i - Inode number
 @item %m - Mount point (See note below)
 @item %n - File name
-@item %N - Quoted file name with dereference if symbolic link
+@item %N - Quoted file name with dereference if symbolic link (see below)
 @item %o - Optimal I/O transfer size hint
 @item %s - Total size, in bytes
 @item %t - Major device type in hex (see below)
@@ -11797,6 +11800,11 @@ to control the zero padding of the output with the @samp{#} and @samp{0}
 printf flags. For example to pad to at least 3 wide while making larger
 numbers unambiguously octal, you can use @samp{%#03a}.
 
+The @samp{%N} format can be set with the environment variable
+@env{QUOTING_STYLE}@.  If that environment variable is not set,
+the default value is @samp{shell-escape}.  Valid quoting styles are:
+@quotingStyles
+
 The @samp{%t} and @samp{%T} formats operate on the st_rdev member of
 the stat(2) structure, and are only defined for character and block
 special files.  On some systems or file types, st_rdev may be used to
index 53a6cb7bb8e3c1091bdec599d38e9414d41e1679..a43eca4d294489838c9d3601bd2760416f9a63b8 100644 (file)
@@ -59,6 +59,7 @@
 #include "system.h"
 
 #include "areadlink.h"
+#include "argmatch.h"
 #include "die.h"
 #include "error.h"
 #include "file-type.h"
@@ -997,6 +998,32 @@ neg_to_zero (struct timespec ts)
   return z;
 }
 
+/* Set the quoting style default if the environment variable
+   QUOTING_STYLE is set.  */
+
+static void
+getenv_quoting_style (void)
+{
+  char const *q_style = getenv ("QUOTING_STYLE");
+  if (q_style)
+    {
+      int i = ARGMATCH (q_style, quoting_style_args, quoting_style_vals);
+      if (0 <= i)
+        set_quoting_style (NULL, quoting_style_vals[i]);
+      else
+        {
+          set_quoting_style (NULL, shell_escape_always_quoting_style);
+          error (0, 0, _("ignoring invalid value of environment "
+                         "variable QUOTING_STYLE: %s"), quote (q_style));
+        }
+    }
+  else
+    set_quoting_style (NULL, shell_escape_always_quoting_style);
+}
+
+/* Equivalent to quotearg(), but explicit to avoid syntax checks.  */
+#define quoteN(x) quotearg_style (get_quoting_style (NULL), x)
+
 /* Print stat info.  Return zero upon success, nonzero upon failure.  */
 static bool
 print_stat (char *pformat, size_t prefix_len, unsigned int m,
@@ -1013,7 +1040,7 @@ print_stat (char *pformat, size_t prefix_len, unsigned int m,
       out_string (pformat, prefix_len, filename);
       break;
     case 'N':
-      out_string (pformat, prefix_len, quoteaf (filename));
+      out_string (pformat, prefix_len, quoteN (filename));
       if (S_ISLNK (statbuf->st_mode))
         {
           char *linkname = areadlink_with_size (filename, statbuf->st_size);
@@ -1024,7 +1051,7 @@ print_stat (char *pformat, size_t prefix_len, unsigned int m,
               return true;
             }
           printf (" -> ");
-          out_string (pformat, prefix_len, quoteaf (linkname));
+          out_string (pformat, prefix_len, quoteN (linkname));
           free (linkname);
         }
       break;
@@ -1602,11 +1629,15 @@ main (int argc, char *argv[])
     }
 
   if (format)
-    format2 = format;
+    {
+      if (strstr (format, "%N"))
+        getenv_quoting_style ();
+      format2 = format;
+    }
   else
     {
-      format = default_format (fs, terse, false);
-      format2 = default_format (fs, terse, true);
+      format = default_format (fs, terse, /* device= */ false);
+      format2 = default_format (fs, terse, /* device= */ true);
     }
 
   for (i = optind; i < argc; i++)
index baa7ca775aea2f6549e4420bc3aba5f36d89a778..1245ddb9e9ebcb385966277ac59ee97fae5d4bfb 100755 (executable)
 print_ver_ stat
 
 
-
+# ensure that stat properly handles a format string ending with %
 for i in $(seq 50); do
   fmt=$(printf "%${i}s" %)
   out=$(stat --form="$fmt" .)
   test "$out" = "$fmt" || fail=1
 done
 
+# ensure QUOTING_STYLE is honored by %N
+touch "'" || framework_failure_
+# Default since v8.25
+stat -c%N \' >> out || fail=1
+# Default before v8.25
+QUOTING_STYLE=locale stat -c%N \' >> out || fail=1
+cat <<\EOF >exp
+"'"
+'\''
+EOF
+compare exp out || fail=1
+
+
 Exit $fail