summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Blake <eblake@redhat.com>2010-10-01 11:44:05 -0600
committerEric Blake <eblake@redhat.com>2010-10-01 15:24:39 -0600
commit2c14ec962a46ae53d39149112ae6902ed771d497 (patch)
tree12e5f290f2d543e6155894bf6339a398768030ee
parent9069af45e691d1252c727da66aa4f3f3c7f1ea29 (diff)
downloadcoreutils-2c14ec962a46ae53d39149112ae6902ed771d497.tar.xz
stat: optimize and translate default format strings
Yes, this patch intentionally leaks the results of default_format(), since it is called only twice, and since the results are in scope until main() exits. Not worth the extra code to pacify valgrind. * 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.
-rw-r--r--NEWS2
-rw-r--r--src/stat.c110
2 files changed, 79 insertions, 33 deletions
diff --git a/NEWS b/NEWS
index 2ce03e312..dd8a18b51 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 6b2e99b77..4e3ec1200 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);
}