X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fhuman.c;h=ed15c6a24a3511f6699a15151f8d39a4ff4154a0;hb=7b06e21eb5e8f585b20346271cbf241bad612f64;hp=558263473a0d0e82a140654e9de579eb520b5232;hpb=ac600b55c5015bdab12df91e8d0d408031bcbb60;p=gnulib.git diff --git a/lib/human.c b/lib/human.c index 558263473..ed15c6a24 100644 --- a/lib/human.c +++ b/lib/human.c @@ -1,7 +1,7 @@ /* human.c -- print human readable file size - Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free - Software Foundation, Inc. + Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 + 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 @@ -15,52 +15,36 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Written by Paul Eggert and Larry McVoy. */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H # include #endif #include "human.h" -#ifndef SIZE_MAX -# define SIZE_MAX ((size_t) -1) -#endif -#ifndef UINTMAX_MAX -# define UINTMAX_MAX ((uintmax_t) -1) -#endif - -#if HAVE_LOCALE_H && HAVE_LOCALECONV -# include -#endif - -#if HAVE_STDLIB_H -# include -#endif -#ifndef HAVE_DECL_GETENV -"this configure-time declaration test was not run" -#endif -#if !HAVE_DECL_GETENV -char *getenv (); -#endif - -#if HAVE_STRING_H -# include -#endif - -#if HAVE_STRINGS_H -# include -#endif +#include +#include +#include +#include #include "gettext.h" #define _(msgid) gettext (msgid) #include #include +#include #include +#ifndef SIZE_MAX +# define SIZE_MAX ((size_t) -1) +#endif +#ifndef UINTMAX_MAX +# define UINTMAX_MAX ((uintmax_t) -1) +#endif + /* The maximum length of a suffix like "KiB". */ #define HUMAN_READABLE_SUFFIX_LENGTH_MAX 3 @@ -116,10 +100,8 @@ group_number (char *number, size_t numberlen, size_t i = numberlen; /* The maximum possible value for NUMBERLEN is the number of digits - in the square of the largest uintmax_t, so double the size of - uintmax_t before converting to a bound. 302 / 1000 is ceil - (log10 (2.0)). Add 1 for integer division truncation. */ - char buf[2 * sizeof (uintmax_t) * CHAR_BIT * 302 / 1000 + 1]; + in the square of the largest uintmax_t, so double the size needed. */ + char buf[2 * INT_STRLEN_BOUND (uintmax_t) + 1]; memcpy (buf, number, numberlen); d = number + numberlen; @@ -172,6 +154,9 @@ group_number (char *number, size_t numberlen, so on. Numbers smaller than the power aren't modified. human_autoscale is normally used together with human_SI. + If (OPTS & human_space_before_unit), use a space to separate the + number from any suffix that is appended as described below. + If (OPTS & human_SI), append an SI prefix indicating which power is being used. If in addition (OPTS & human_B), append "B" (if base 1000) or "iB" (if base 1024) to the SI prefix. When ((OPTS & @@ -204,7 +189,6 @@ human_readable (uintmax_t n, char *buf, int opts, size_t decimal_pointlen = 1; char const *grouping = ""; char const *thousands_sep = ""; -#if HAVE_LOCALE_H && HAVE_LOCALECONV struct lconv const *l = localeconv (); size_t pointlen = strlen (l->decimal_point); if (0 < pointlen && pointlen <= MB_LEN_MAX) @@ -215,7 +199,6 @@ human_readable (uintmax_t n, char *buf, int opts, grouping = l->grouping; if (strlen (l->thousands_sep) <= MB_LEN_MAX) thousands_sep = l->thousands_sep; -#endif psuffix = buf + LONGEST_HUMAN_READABLE - HUMAN_READABLE_SUFFIX_LENGTH_MAX; p = psuffix; @@ -314,8 +297,8 @@ human_readable (uintmax_t n, char *buf, int opts, { do { - unsigned r10 = (amt % base) * 10 + tenths; - unsigned r2 = (r10 % base) * 2 + (rounding >> 1); + unsigned int r10 = (amt % base) * 10 + tenths; + unsigned int r2 = (r10 % base) * 2 + (rounding >> 1); amt /= base; tenths = r10 / base; rounding = (r2 < base @@ -353,11 +336,9 @@ human_readable (uintmax_t n, char *buf, int opts, } } - if (inexact_style == human_ceiling - ? 0 < tenths + rounding - : inexact_style == human_round_to_nearest - ? 5 < tenths + (2 < rounding + (amt & 1)) - : /* inexact_style == human_floor */ 0) + if (inexact_style == human_round_to_nearest + ? 5 < tenths + (0 < rounding + (amt & 1)) + : inexact_style == human_ceiling && 0 < tenths + rounding) { amt++; @@ -400,6 +381,9 @@ human_readable (uintmax_t n, char *buf, int opts, break; } + if ((exponent | (opts & human_B)) && (opts & human_space_before_unit)) + *psuffix++ = ' '; + if (exponent) *psuffix++ = (! (opts & human_base_1024) && exponent == 1 ? 'k' @@ -444,7 +428,9 @@ humblock (char const *spec, uintmax_t *block_size, int *options) int i; int opts = 0; - if (! spec && ! (spec = getenv ("BLOCK_SIZE"))) + if (! spec + && ! (spec = getenv ("BLOCK_SIZE")) + && ! (spec = getenv ("BLOCKSIZE"))) *block_size = default_block_size (); else { @@ -465,9 +451,10 @@ humblock (char const *spec, uintmax_t *block_size, int *options) strtol_error e = xstrtoumax (spec, &ptr, 0, block_size, "eEgGkKmMpPtTyYzZ0"); if (e != LONGINT_OK) - return e; - if (*ptr) - return LONGINT_INVALID_SUFFIX_CHAR; + { + *options = 0; + return e; + } for (; ! ('0' <= *spec && *spec <= '9'); spec++) if (spec == ptr) {