coreutils
[Top][All Lists]
Advanced

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

[coreutils] [PATCH] stat: optimize and translate default format strings


From: Eric Blake
Subject: [coreutils] [PATCH] stat: optimize and translate default format strings
Date: Fri, 1 Oct 2010 11:47:19 -0600

* src/stat.c (main): Hoist default format computation out of loop.
(do_statfs, do_stat): Move default format generation...
(default_format): ...into new function.  Allocate the result in
pieces, rather than repeating mostly-similar chunks.  Allow
translation of verbose format.  Pass a second format to do_stat,
for the one aspect of the default format that is conditional on
file type.
* NEWS: Document the translation aspect.
---

> Hmm, in looking at this, I'm wondering if an even better patch would
> be to build the default format string incrementally, using asnprintf,
> rather than repeating so many lines.

Like this, and I'll rebase the -Z vs. %C patch on top of this.

This one should be uncontroversial, but just to be safe: OK to push?

 NEWS       |    2 +
 src/stat.c |  110 ++++++++++++++++++++++++++++++++++++++++++------------------
 2 files changed, 79 insertions(+), 33 deletions(-)

diff --git a/NEWS b/NEWS
index 2ce03e3..dd8a18b 100644
--- a/NEWS
+++ b/NEWS
@@ -71,6 +71,8 @@ GNU coreutils NEWS                                    -*- 
outline -*-
   limited with the --parallel option or with external process
   control like taskset for example.

+  stat now provides translated output when no format is specified.
+
   stat no longer accepts the --context (-Z) option.  Initially it was
   merely accepted and ignored, for compatibility.  Starting two years
   ago, with coreutils-7.0, its use evoked a warning.
diff --git a/src/stat.c b/src/stat.c
index 6b2e99b..4e3ec12 100644
--- a/src/stat.c
+++ b/src/stat.c
@@ -70,6 +70,7 @@
 #include "stat-time.h"
 #include "strftime.h"
 #include "find-mount-point.h"
+#include "xvasprintf.h"

 #if USE_STATVFS
 # define STRUCT_STATVFS struct statvfs
@@ -1027,24 +1028,14 @@ do_statfs (char const *filename, bool terse, char const 
*format)
       return false;
     }

-  if (format == NULL)
-    {
-      format = (terse
-                ? "%n %i %l %t %s %S %b %f %a %c %d\n"
-                : "  File: \"%n\"\n"
-                "    ID: %-8i Namelen: %-7l Type: %T\n"
-                "Block size: %-10s Fundamental block size: %S\n"
-                "Blocks: Total: %-10b Free: %-10f Available: %a\n"
-                "Inodes: Total: %-10c Free: %d\n");
-    }
-
   bool fail = print_it (format, filename, print_statfs, &statfsbuf);
   return ! fail;
 }

 /* stat the file and print what we find */
 static bool ATTRIBUTE_WARN_UNUSED_RESULT
-do_stat (char const *filename, bool terse, char const *format)
+do_stat (char const *filename, bool terse, char const *format,
+         char const *format2)
 {
   struct stat statbuf;

@@ -1067,39 +1058,83 @@ do_stat (char const *filename, bool terse, char const 
*format)
       return false;
     }

-  if (format == NULL)
+  if (S_ISBLK (statbuf.st_mode) || S_ISCHR (statbuf.st_mode))
+    format = format2;
+
+  bool fail = print_it (format, filename, print_stat, &statbuf);
+  return ! fail;
+}
+
+/* Return an allocated format string in static storage that
+   corresponds to whether FS and TERSE options were declared.  */
+static char *
+default_format (bool fs, bool terse, bool device)
+{
+  char *format;
+  if (fs)
     {
       if (terse)
+        format = xstrdup ("%n %i %l %t %s %S %b %f %a %c %d\n");
+      else
         {
-          format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %W %o\n";
+          /* TRANSLATORS: This string uses format specifiers from
+             'stat --help' with --file-system, and NOT from printf.  */
+          format = xstrdup (_("\
+  File: \"%n\"\n\
+    ID: %-8i Namelen: %-7l Type: %T\n\
+Block size: %-10s Fundamental block size: %S\n\
+Blocks: Total: %-10b Free: %-10f Available: %a\n\
+Inodes: Total: %-10c Free: %d\n\
+"));
         }
+    }
+  else /* ! fs */
+    {
+      if (terse)
+        format = xstrdup ("%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %W %o\n");
       else
         {
-          /* Temporary hack to match original output until conditional
-             implemented.  */
-          if (S_ISBLK (statbuf.st_mode) || S_ISCHR (statbuf.st_mode))
+          char *temp;
+          /* TRANSLATORS: This string uses format specifiers from
+             'stat --help' without --file-system, and NOT from printf.  */
+          format = xstrdup (_("\
+  File: %N\n\
+  Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n\
+"));
+
+          temp = format;
+          if (device)
             {
-              format =
-                "  File: %N\n"
-                "  Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
-                "Device: %Dh/%dd\tInode: %-10i  Links: %-5h"
-                " Device type: %t,%T\n"
-                "Access: (%04a/%10.10A)  Uid: (%5u/%8U)   Gid: (%5g/%8G)\n"
-                "Access: %x\n" "Modify: %y\n" "Change: %z\n" " Birth: %w\n";
+              /* TRANSLATORS: This string uses format specifiers from
+                 'stat --help' without --file-system, and NOT from printf.  */
+              format = xasprintf ("%s%s", format, _("\
+Device: %Dh/%dd\tInode: %-10i  Links: %-5h Device type: %t,%T\n\
+"));
             }
           else
             {
-              format =
-                "  File: %N\n"
-                "  Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
-                "Device: %Dh/%dd\tInode: %-10i  Links: %h\n"
-                "Access: (%04a/%10.10A)  Uid: (%5u/%8U)   Gid: (%5g/%8G)\n"
-                "Access: %x\n" "Modify: %y\n" "Change: %z\n" " Birth: %w\n";
+              /* TRANSLATORS: This string uses format specifiers from
+                 'stat --help' without --file-system, and NOT from printf.  */
+              format = xasprintf ("%s%s", format, _("\
+Device: %Dh/%dd\tInode: %-10i  Links: %h\n\
+"));
             }
+          free (temp);
+
+          temp = format;
+          /* TRANSLATORS: This string uses format specifiers from
+             'stat --help' without --file-system, and NOT from printf.  */
+          format = xasprintf ("%s%s", format, _("\
+Access: (%04a/%10.10A)  Uid: (%5u/%8U)   Gid: (%5g/%8G)\n\
+Access: %x\n\
+Modify: %y\n\
+Change: %z\n\
+ Birth: %w\n\
+"));
+          free (temp);
         }
     }
-  bool fail = print_it (format, filename, print_stat, &statbuf);
-  return ! fail;
+  return format;
 }

 void
@@ -1203,6 +1238,7 @@ main (int argc, char *argv[])
   bool fs = false;
   bool terse = false;
   char *format = NULL;
+  char *format2;
   bool ok = true;

   initialize_main (&argc, &argv);
@@ -1256,10 +1292,18 @@ main (int argc, char *argv[])
       usage (EXIT_FAILURE);
     }

+  if (format)
+    format2 = format;
+  else
+    {
+      format = default_format (fs, terse, false);
+      format2 = default_format (fs, terse, true);
+    }
+
   for (i = optind; i < argc; i++)
     ok &= (fs
            ? do_statfs (argv[i], terse, format)
-           : do_stat (argv[i], terse, format));
+           : do_stat (argv[i], terse, format, format2));

   exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
 }
-- 
1.7.2.3




reply via email to

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