summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>2002-11-08 09:39:36 +0000
committerJim Meyering <jim@meyering.net>2002-11-08 09:39:36 +0000
commit95b50fa1ac036a3e85226b508de5505b3a873fbb (patch)
treebd7840947f5b231e9f39dd22367d81b50fa7ab87
parent98f748e64c5e1cb16b27cb859a137055b78cd2f5 (diff)
downloadcoreutils-95b50fa1ac036a3e85226b508de5505b3a873fbb.tar.xz
(print_header): Use primitives from inttostr.h, not
human.h, to print large numbers simply. (human_output_opts): New var. (output_block_size): Now uintmax_t, not int, to handle larger block sizes. All uses changed. (print_header): In the header line, prefer SI to human representation if it's shorter; if neither is shorter, try to intuit what the user would prefer.
-rw-r--r--src/df.c102
1 files changed, 68 insertions, 34 deletions
diff --git a/src/df.c b/src/df.c
index 8c07eacbf..df143739b 100644
--- a/src/df.c
+++ b/src/df.c
@@ -34,6 +34,7 @@
#include "error.h"
#include "fsusage.h"
#include "human.h"
+#include "inttostr.h"
#include "mountlist.h"
#include "path-concat.h"
#include "quote.h"
@@ -64,9 +65,11 @@ static int show_local_fs;
command line argument -- even if it's a dummy (automounter) entry. */
static int show_listed_fs;
-/* If positive, the units to use when printing sizes;
- if negative, the human-readable base. */
-static int output_block_size;
+/* Human-readable options for output. */
+static int human_output_opts;
+
+/* The units to use when printing sizes. */
+static uintmax_t output_block_size;
/* If nonzero, use the POSIX output format. */
static int posix_format;
@@ -144,6 +147,8 @@ static struct option const long_options[] =
static void
print_header (void)
{
+ char buf[MAX (LONGEST_HUMAN_READABLE + 1, INT_BUFSIZE_BOUND (uintmax_t))];
+
printf (_("Filesystem "));
if (print_type)
@@ -153,26 +158,47 @@ print_header (void)
if (inode_format)
printf (_(" Inodes IUsed IFree IUse%%"));
- else if (output_block_size < 0)
+ else if (human_output_opts & human_autoscale)
{
- if (output_block_size == -1000)
- printf (_(" Size Used Avail Use%%"));
- else
+ if (human_output_opts & human_base_1024)
printf (_(" Size Used Avail Use%%"));
+ else
+ printf (_(" Size Used Avail Use%%"));
}
else if (posix_format)
- printf (_(" %4d-blocks Used Available Capacity"), output_block_size);
+ printf (_(" %4s-blocks Used Available Capacity"),
+ umaxtostr (output_block_size, buf));
else
{
- char buf[LONGEST_HUMAN_READABLE + 1];
- char *p = human_readable (output_block_size, buf, 1, -1024);
+ int opts = (human_suppress_point_zero
+ | human_autoscale | human_SI
+ | (human_output_opts
+ & (human_group_digits | human_base_1024 | human_B)));
- /* Replace e.g. "1.0K" by "1K". */
- size_t plen = strlen (p);
- if (3 <= plen && strncmp (p + plen - 3, ".0", 2) == 0)
- strcpy (p + plen - 3, p + plen - 1);
+ /* Prefer the base that makes the human-readable value more exact,
+ if there is a difference. */
- printf (_(" %4s-blocks Used Available Use%%"), p);
+ uintmax_t q1000 = output_block_size;
+ uintmax_t q1024 = output_block_size;
+ bool divisible_by_1000;
+ bool divisible_by_1024;
+
+ do
+ {
+ divisible_by_1000 = q1000 % 1000 == 0; q1000 /= 1000;
+ divisible_by_1024 = q1024 % 1024 == 0; q1024 /= 1024;
+ }
+ while (divisible_by_1000 & divisible_by_1024);
+
+ if (divisible_by_1000 < divisible_by_1024)
+ opts |= human_base_1024;
+ if (divisible_by_1024 < divisible_by_1000)
+ opts &= ~human_base_1024;
+ if (! (opts & human_base_1024))
+ opts |= human_B;
+
+ printf (_(" %4s-blocks Used Available Use%%"),
+ human_readable (output_block_size, buf, opts, 1, 1));
}
printf (_(" Mounted on\n"));
@@ -210,23 +236,23 @@ excluded_fstype (const char *fstype)
return 0;
}
-/* Like human_readable_inexact with a human_ceiling
- human_inexact_style, except return "-" if the argument is -1, and
- if NEGATIVE is 1 then N represents a negative number, expressed in
- two's complement. */
+/* Like human_readable (N, BUF, human_output_opts, INPUT_UNITS, OUTPUT_UNITS),
+ except:
+
+ - Return "-" if N is -1,
+ - If NEGATIVE is 1 then N represents a negative number,
+ expressed in two's complement. */
static char const *
df_readable (int negative, uintmax_t n, char *buf,
- int from_block_size, int t_output_block_size)
+ uintmax_t input_units, uintmax_t output_units)
{
if (n == -1)
return "-";
else
{
- char *p = human_readable_inexact (negative ? - n : n,
- buf + negative, from_block_size,
- t_output_block_size,
- human_ceiling);
+ char *p = human_readable (negative ? -n : n, buf + negative,
+ human_output_opts, input_units, output_units);
if (negative)
*--p = '-';
return p;
@@ -250,8 +276,8 @@ show_dev (const char *disk, const char *mount_point, const char *fstype,
char buf[3][LONGEST_HUMAN_READABLE + 2];
int width;
int use_width;
- int input_units;
- int output_units;
+ uintmax_t input_units;
+ uintmax_t output_units;
uintmax_t total;
uintmax_t available;
int negate_available;
@@ -315,8 +341,7 @@ show_dev (const char *disk, const char *mount_point, const char *fstype,
{
width = 7;
use_width = 5;
- input_units = 1;
- output_units = output_block_size < 0 ? output_block_size : 1;
+ input_units = output_units = 1;
total = fsu.fsu_files;
available = fsu.fsu_ffree;
negate_available = 0;
@@ -324,8 +349,12 @@ show_dev (const char *disk, const char *mount_point, const char *fstype,
}
else
{
- width = output_block_size < 0 ? 5 + (output_block_size == -1000) : 9;
- use_width = (posix_format && 0 <= output_block_size) ? 8 : 4;
+ width = (human_output_opts & human_autoscale
+ ? 5 + ! (human_output_opts & human_base_1024)
+ : 9);
+ use_width = ((posix_format
+ && ! (human_output_opts & human_autoscale))
+ ? 8 : 4);
input_units = fsu.fsu_blocksize;
output_units = output_block_size;
total = fsu.fsu_blocks;
@@ -808,7 +837,8 @@ main (int argc, char **argv)
show_all_fs = 0;
show_listed_fs = 0;
- human_block_size (getenv ("DF_BLOCK_SIZE"), 0, &output_block_size);
+ human_output_opts = human_options (getenv ("DF_BLOCK_SIZE"), false,
+ &output_block_size);
print_type = 0;
posix_format = 0;
@@ -825,24 +855,28 @@ main (int argc, char **argv)
show_all_fs = 1;
break;
case 'B':
- human_block_size (optarg, 1, &output_block_size);
+ human_output_opts = human_options (optarg, true, &output_block_size);
break;
case 'i':
inode_format = 1;
break;
case 'h':
- output_block_size = -1024;
+ human_output_opts = human_autoscale | human_SI | human_base_1024;
+ output_block_size = 1;
break;
case 'H':
- output_block_size = -1000;
+ human_output_opts = human_autoscale | human_SI;
+ output_block_size = 1;
break;
case 'k':
+ human_output_opts = 0;
output_block_size = 1024;
break;
case 'l':
show_local_fs = 1;
break;
case 'm': /* obsolescent */
+ human_output_opts = 0;
output_block_size = 1024 * 1024;
break;
case 'T':