X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fhuman.c;h=5cfbce9df4ddef46b66ab67d8b1216f759344985;hb=abde38362f9239723c9b762d1b2ac41af575e6d5;hp=7b923dc89df92fbe0dfa9d56b73d656d2f6e7861;hpb=615e02f2ec6db2f56400bbcf608d6d85aa89a6b7;p=gnulib.git diff --git a/lib/human.c b/lib/human.c index 7b923dc89..5cfbce9df 100644 --- a/lib/human.c +++ b/lib/human.c @@ -1,5 +1,5 @@ /* human.c -- print human readable file size - Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc. + Copyright (C) 1996, 1997, 1998, 1999, 2000 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 @@ -44,6 +44,9 @@ #endif #ifndef HAVE_DECL_GETENV +"this configure-time declaration test was not run" +#endif +#if !HAVE_DECL_GETENV char *getenv (); #endif @@ -73,6 +76,15 @@ static const char suffixes[] = 'Y' /* Yotta */ }; +/* Like human_readable_inexact, except always round to even. */ +char * +human_readable (uintmax_t n, char *buf, + int from_block_size, int output_block_size) +{ + return human_readable_inexact (n, buf, from_block_size, output_block_size, + human_round_to_even); +} + /* Convert N to a human readable format in BUF. N is expressed in units of FROM_BLOCK_SIZE. FROM_BLOCK_SIZE must @@ -82,6 +94,9 @@ static const char suffixes[] = the output number. OUTPUT_BLOCK_SIZE must be a multiple of FROM_BLOCK_SIZE or vice versa. + Use INEXACT_STYLE to determine whether to take the ceiling or floor + of any result that cannot be expressed exactly. + If OUTPUT_BLOCK_SIZE is negative, use a format like "127k" if possible, using powers of -OUTPUT_BLOCK_SIZE; otherwise, use ordinary decimal format. Normally -OUTPUT_BLOCK_SIZE is either @@ -95,8 +110,9 @@ static const char suffixes[] = than -OUTPUT_BLOCK_SIZE aren't modified. */ char * -human_readable (uintmax_t n, char *buf, - int from_block_size, int output_block_size) +human_readable_inexact (uintmax_t n, char *buf, + int from_block_size, int output_block_size, + enum human_inexact_style inexact_style) { uintmax_t amt; int base; @@ -207,24 +223,33 @@ human_readable (uintmax_t n, char *buf, if (amt < 10) { - tenths += 2 < rounding + (tenths & 1); - - if (tenths == 10) + if (2 * (1 - (int) inexact_style) + < rounding + (tenths & (inexact_style == human_round_to_even))) { - amt++; - tenths = 0; + tenths++; + rounding = 0; + + if (tenths == 10) + { + amt++; + tenths = 0; + } } if (amt < 10) { *--p = '0' + tenths; *--p = '.'; - tenths = 0; + tenths = rounding = 0; } } } - if (5 < tenths + (2 < rounding + (amt & 1))) + if (inexact_style == human_ceiling + ? 0 < tenths + rounding + : inexact_style == human_round_to_even + ? 5 < tenths + (2 < rounding + (amt & 1)) + : /* inexact_style == human_floor */ 0) { amt++; @@ -254,13 +279,19 @@ human_readable (uintmax_t n, char *buf, static char const *const block_size_args[] = { "human-readable", "si", 0 }; static int const block_size_types[] = { -1024, -1000 }; +static int +default_block_size (void) +{ + return getenv ("POSIXLY_CORRECT") ? 512 : DEFAULT_BLOCK_SIZE; +} + static strtol_error humblock (char const *spec, int *block_size) { int i; if (! spec && ! (spec = getenv ("BLOCK_SIZE"))) - *block_size = getenv ("POSIXLY_CORRECT") ? 512 : DEFAULT_BLOCK_SIZE; + *block_size = default_block_size (); else if (0 <= (i = ARGMATCH (spec, block_size_args, block_size_types))) *block_size = block_size_types[i]; else @@ -284,6 +315,11 @@ void human_block_size (char const *spec, int report_errors, int *block_size) { strtol_error e = humblock (spec, block_size); + if (*block_size == 0) + { + *block_size = default_block_size (); + e = LONGINT_INVALID; + } if (e != LONGINT_OK && report_errors) STRTOL_FATAL_ERROR (spec, _("block size"), e); }