| Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/coreutils/src/gnulib/lib/human.c |
| Source code | Switch to Preprocessed file |
| Line | Source | Count | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | /* human.c -- print human readable file size | - | ||||||||||||||||||
| 2 | - | |||||||||||||||||||
| 3 | Copyright (C) 1996-2007, 2009-2018 Free Software Foundation, Inc. | - | ||||||||||||||||||
| 4 | - | |||||||||||||||||||
| 5 | This program is free software: you can redistribute it and/or modify | - | ||||||||||||||||||
| 6 | it under the terms of the GNU General Public License as published by | - | ||||||||||||||||||
| 7 | the Free Software Foundation; either version 3 of the License, or | - | ||||||||||||||||||
| 8 | (at your option) any later version. | - | ||||||||||||||||||
| 9 | - | |||||||||||||||||||
| 10 | This program is distributed in the hope that it will be useful, | - | ||||||||||||||||||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | - | ||||||||||||||||||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | - | ||||||||||||||||||
| 13 | GNU General Public License for more details. | - | ||||||||||||||||||
| 14 | - | |||||||||||||||||||
| 15 | You should have received a copy of the GNU General Public License | - | ||||||||||||||||||
| 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ | - | ||||||||||||||||||
| 17 | - | |||||||||||||||||||
| 18 | /* Written by Paul Eggert and Larry McVoy. */ | - | ||||||||||||||||||
| 19 | - | |||||||||||||||||||
| 20 | #include <config.h> | - | ||||||||||||||||||
| 21 | - | |||||||||||||||||||
| 22 | #include "human.h" | - | ||||||||||||||||||
| 23 | - | |||||||||||||||||||
| 24 | #include <locale.h> | - | ||||||||||||||||||
| 25 | #include <stdio.h> | - | ||||||||||||||||||
| 26 | #include <stdlib.h> | - | ||||||||||||||||||
| 27 | #include <string.h> | - | ||||||||||||||||||
| 28 | - | |||||||||||||||||||
| 29 | #include <argmatch.h> | - | ||||||||||||||||||
| 30 | #include <error.h> | - | ||||||||||||||||||
| 31 | #include <intprops.h> | - | ||||||||||||||||||
| 32 | - | |||||||||||||||||||
| 33 | /* The maximum length of a suffix like "KiB". */ | - | ||||||||||||||||||
| 34 | #define HUMAN_READABLE_SUFFIX_LENGTH_MAX 3 | - | ||||||||||||||||||
| 35 | - | |||||||||||||||||||
| 36 | static const char power_letter[] = | - | ||||||||||||||||||
| 37 | { | - | ||||||||||||||||||
| 38 | 0, /* not used */ | - | ||||||||||||||||||
| 39 | 'K', /* kibi ('k' for kilo is a special case) */ | - | ||||||||||||||||||
| 40 | 'M', /* mega or mebi */ | - | ||||||||||||||||||
| 41 | 'G', /* giga or gibi */ | - | ||||||||||||||||||
| 42 | 'T', /* tera or tebi */ | - | ||||||||||||||||||
| 43 | 'P', /* peta or pebi */ | - | ||||||||||||||||||
| 44 | 'E', /* exa or exbi */ | - | ||||||||||||||||||
| 45 | 'Z', /* zetta or 2**70 */ | - | ||||||||||||||||||
| 46 | 'Y' /* yotta or 2**80 */ | - | ||||||||||||||||||
| 47 | }; | - | ||||||||||||||||||
| 48 | - | |||||||||||||||||||
| 49 | - | |||||||||||||||||||
| 50 | /* If INEXACT_STYLE is not human_round_to_nearest, and if easily | - | ||||||||||||||||||
| 51 | possible, adjust VALUE according to the style. */ | - | ||||||||||||||||||
| 52 | - | |||||||||||||||||||
| 53 | static long double | - | ||||||||||||||||||
| 54 | adjust_value (int inexact_style, long double value) | - | ||||||||||||||||||
| 55 | { | - | ||||||||||||||||||
| 56 | /* Do not use the floorl or ceill functions, as that would mean | - | ||||||||||||||||||
| 57 | checking for their presence and possibly linking with the | - | ||||||||||||||||||
| 58 | standard math library, which is a porting pain. So leave the | - | ||||||||||||||||||
| 59 | value alone if it is too large to easily round. */ | - | ||||||||||||||||||
| 60 | if (inexact_style != human_round_to_nearest && value < UINTMAX_MAX)
| 0-220 | ||||||||||||||||||
| 61 | { | - | ||||||||||||||||||
| 62 | uintmax_t u = value; | - | ||||||||||||||||||
| 63 | value = u + (inexact_style == human_ceiling && u != value);
| 0 | ||||||||||||||||||
| 64 | } never executed: end of block | 0 | ||||||||||||||||||
| 65 | - | |||||||||||||||||||
| 66 | return value; executed 220 times by 1 test: return value;Executed by:
| 220 | ||||||||||||||||||
| 67 | } | - | ||||||||||||||||||
| 68 | - | |||||||||||||||||||
| 69 | /* Group the digits of NUMBER according to the grouping rules of the | - | ||||||||||||||||||
| 70 | current locale. NUMBER contains NUMBERLEN digits. Modify the | - | ||||||||||||||||||
| 71 | bytes pointed to by NUMBER in place, subtracting 1 from NUMBER for | - | ||||||||||||||||||
| 72 | each byte inserted. Return the starting address of the modified | - | ||||||||||||||||||
| 73 | number. | - | ||||||||||||||||||
| 74 | - | |||||||||||||||||||
| 75 | To group the digits, use GROUPING and THOUSANDS_SEP as in 'struct | - | ||||||||||||||||||
| 76 | lconv' from <locale.h>. */ | - | ||||||||||||||||||
| 77 | - | |||||||||||||||||||
| 78 | static char * | - | ||||||||||||||||||
| 79 | group_number (char *number, size_t numberlen, | - | ||||||||||||||||||
| 80 | char const *grouping, char const *thousands_sep) | - | ||||||||||||||||||
| 81 | { | - | ||||||||||||||||||
| 82 | register char *d; | - | ||||||||||||||||||
| 83 | size_t grouplen = SIZE_MAX; | - | ||||||||||||||||||
| 84 | size_t thousands_seplen = strlen (thousands_sep); | - | ||||||||||||||||||
| 85 | size_t i = numberlen; | - | ||||||||||||||||||
| 86 | - | |||||||||||||||||||
| 87 | /* The maximum possible value for NUMBERLEN is the number of digits | - | ||||||||||||||||||
| 88 | in the square of the largest uintmax_t, so double the size needed. */ | - | ||||||||||||||||||
| 89 | char buf[2 * INT_STRLEN_BOUND (uintmax_t) + 1]; | - | ||||||||||||||||||
| 90 | - | |||||||||||||||||||
| 91 | memcpy (buf, number, numberlen); | - | ||||||||||||||||||
| 92 | d = number + numberlen; | - | ||||||||||||||||||
| 93 | - | |||||||||||||||||||
| 94 | for (;;) | - | ||||||||||||||||||
| 95 | { | - | ||||||||||||||||||
| 96 | unsigned char g = *grouping; | - | ||||||||||||||||||
| 97 | - | |||||||||||||||||||
| 98 | if (g)
| 0 | ||||||||||||||||||
| 99 | { | - | ||||||||||||||||||
| 100 | grouplen = g < CHAR_MAX ? g : i;
| 0 | ||||||||||||||||||
| 101 | grouping++; | - | ||||||||||||||||||
| 102 | } never executed: end of block | 0 | ||||||||||||||||||
| 103 | - | |||||||||||||||||||
| 104 | if (i < grouplen)
| 0 | ||||||||||||||||||
| 105 | grouplen = i; never executed: grouplen = i; | 0 | ||||||||||||||||||
| 106 | - | |||||||||||||||||||
| 107 | d -= grouplen; | - | ||||||||||||||||||
| 108 | i -= grouplen; | - | ||||||||||||||||||
| 109 | memcpy (d, buf + i, grouplen); | - | ||||||||||||||||||
| 110 | if (i == 0)
| 0 | ||||||||||||||||||
| 111 | return d; never executed: return d; | 0 | ||||||||||||||||||
| 112 | - | |||||||||||||||||||
| 113 | d -= thousands_seplen; | - | ||||||||||||||||||
| 114 | memcpy (d, thousands_sep, thousands_seplen); | - | ||||||||||||||||||
| 115 | } never executed: end of block | 0 | ||||||||||||||||||
| 116 | } never executed: end of block | 0 | ||||||||||||||||||
| 117 | - | |||||||||||||||||||
| 118 | /* Convert N to a human readable format in BUF, using the options OPTS. | - | ||||||||||||||||||
| 119 | - | |||||||||||||||||||
| 120 | N is expressed in units of FROM_BLOCK_SIZE. FROM_BLOCK_SIZE must | - | ||||||||||||||||||
| 121 | be nonnegative. | - | ||||||||||||||||||
| 122 | - | |||||||||||||||||||
| 123 | Use units of TO_BLOCK_SIZE in the output number. TO_BLOCK_SIZE | - | ||||||||||||||||||
| 124 | must be positive. | - | ||||||||||||||||||
| 125 | - | |||||||||||||||||||
| 126 | Use (OPTS & (human_round_to_nearest | human_floor | human_ceiling)) | - | ||||||||||||||||||
| 127 | to determine whether to take the ceiling or floor of any result | - | ||||||||||||||||||
| 128 | that cannot be expressed exactly. | - | ||||||||||||||||||
| 129 | - | |||||||||||||||||||
| 130 | If (OPTS & human_group_digits), group the thousands digits | - | ||||||||||||||||||
| 131 | according to the locale, e.g., "1,000,000" in an American English | - | ||||||||||||||||||
| 132 | locale. | - | ||||||||||||||||||
| 133 | - | |||||||||||||||||||
| 134 | If (OPTS & human_autoscale), deduce the output block size | - | ||||||||||||||||||
| 135 | automatically; TO_BLOCK_SIZE must be 1 but it has no effect on the | - | ||||||||||||||||||
| 136 | output. Use powers of 1024 if (OPTS & human_base_1024), and powers | - | ||||||||||||||||||
| 137 | of 1000 otherwise. For example, assuming powers of 1024, 8500 | - | ||||||||||||||||||
| 138 | would be converted to 8.3, 133456345 to 127, 56990456345 to 53, and | - | ||||||||||||||||||
| 139 | so on. Numbers smaller than the power aren't modified. | - | ||||||||||||||||||
| 140 | human_autoscale is normally used together with human_SI. | - | ||||||||||||||||||
| 141 | - | |||||||||||||||||||
| 142 | If (OPTS & human_space_before_unit), use a space to separate the | - | ||||||||||||||||||
| 143 | number from any suffix that is appended as described below. | - | ||||||||||||||||||
| 144 | - | |||||||||||||||||||
| 145 | If (OPTS & human_SI), append an SI prefix indicating which power is | - | ||||||||||||||||||
| 146 | being used. If in addition (OPTS & human_B), append "B" (if base | - | ||||||||||||||||||
| 147 | 1000) or "iB" (if base 1024) to the SI prefix. When ((OPTS & | - | ||||||||||||||||||
| 148 | human_SI) && ! (OPTS & human_autoscale)), TO_BLOCK_SIZE must be a | - | ||||||||||||||||||
| 149 | power of 1024 or of 1000, depending on (OPTS & | - | ||||||||||||||||||
| 150 | human_base_1024). */ | - | ||||||||||||||||||
| 151 | - | |||||||||||||||||||
| 152 | char * | - | ||||||||||||||||||
| 153 | human_readable (uintmax_t n, char *buf, int opts, | - | ||||||||||||||||||
| 154 | uintmax_t from_block_size, uintmax_t to_block_size) | - | ||||||||||||||||||
| 155 | { | - | ||||||||||||||||||
| 156 | int inexact_style = | - | ||||||||||||||||||
| 157 | opts & (human_round_to_nearest | human_floor | human_ceiling); | - | ||||||||||||||||||
| 158 | unsigned int base = opts & human_base_1024 ? 1024 : 1000;
| 224-4623 | ||||||||||||||||||
| 159 | uintmax_t amt; | - | ||||||||||||||||||
| 160 | int tenths; | - | ||||||||||||||||||
| 161 | int exponent = -1; | - | ||||||||||||||||||
| 162 | int exponent_max = sizeof power_letter - 1; | - | ||||||||||||||||||
| 163 | char *p; | - | ||||||||||||||||||
| 164 | char *psuffix; | - | ||||||||||||||||||
| 165 | char const *integerlim; | - | ||||||||||||||||||
| 166 | - | |||||||||||||||||||
| 167 | /* 0 means adjusted N == AMT.TENTHS; | - | ||||||||||||||||||
| 168 | 1 means AMT.TENTHS < adjusted N < AMT.TENTHS + 0.05; | - | ||||||||||||||||||
| 169 | 2 means adjusted N == AMT.TENTHS + 0.05; | - | ||||||||||||||||||
| 170 | 3 means AMT.TENTHS + 0.05 < adjusted N < AMT.TENTHS + 0.1. */ | - | ||||||||||||||||||
| 171 | int rounding; | - | ||||||||||||||||||
| 172 | - | |||||||||||||||||||
| 173 | char const *decimal_point = "."; | - | ||||||||||||||||||
| 174 | size_t decimal_pointlen = 1; | - | ||||||||||||||||||
| 175 | char const *grouping = ""; | - | ||||||||||||||||||
| 176 | char const *thousands_sep = ""; | - | ||||||||||||||||||
| 177 | struct lconv const *l = localeconv (); | - | ||||||||||||||||||
| 178 | size_t pointlen = strlen (l->decimal_point); | - | ||||||||||||||||||
| 179 | if (0 < pointlen && pointlen <= MB_LEN_MAX)
| 0-4847 | ||||||||||||||||||
| 180 | { | - | ||||||||||||||||||
| 181 | decimal_point = l->decimal_point; | - | ||||||||||||||||||
| 182 | decimal_pointlen = pointlen; | - | ||||||||||||||||||
| 183 | } executed 4847 times by 6 tests: end of blockExecuted by:
| 4847 | ||||||||||||||||||
| 184 | grouping = l->grouping; | - | ||||||||||||||||||
| 185 | if (strlen (l->thousands_sep) <= MB_LEN_MAX)
| 0-4847 | ||||||||||||||||||
| 186 | thousands_sep = l->thousands_sep; executed 4847 times by 6 tests: thousands_sep = l->thousands_sep;Executed by:
| 4847 | ||||||||||||||||||
| 187 | - | |||||||||||||||||||
| 188 | /* Leave room for a trailing space and following suffix. */ | - | ||||||||||||||||||
| 189 | psuffix = buf + LONGEST_HUMAN_READABLE - 1 - HUMAN_READABLE_SUFFIX_LENGTH_MAX; | - | ||||||||||||||||||
| 190 | p = psuffix; | - | ||||||||||||||||||
| 191 | - | |||||||||||||||||||
| 192 | /* Adjust AMT out of FROM_BLOCK_SIZE units and into TO_BLOCK_SIZE | - | ||||||||||||||||||
| 193 | units. If this can be done exactly with integer arithmetic, do | - | ||||||||||||||||||
| 194 | not use floating point operations. */ | - | ||||||||||||||||||
| 195 | if (to_block_size <= from_block_size)
| 1975-2872 | ||||||||||||||||||
| 196 | { | - | ||||||||||||||||||
| 197 | if (from_block_size % to_block_size == 0)
| 147-1828 | ||||||||||||||||||
| 198 | { | - | ||||||||||||||||||
| 199 | uintmax_t multiplier = from_block_size / to_block_size; | - | ||||||||||||||||||
| 200 | amt = n * multiplier; | - | ||||||||||||||||||
| 201 | if (amt / multiplier == n)
| 0-1828 | ||||||||||||||||||
| 202 | { | - | ||||||||||||||||||
| 203 | tenths = 0; | - | ||||||||||||||||||
| 204 | rounding = 0; | - | ||||||||||||||||||
| 205 | goto use_integer_arithmetic; executed 1828 times by 5 tests: goto use_integer_arithmetic;Executed by:
| 1828 | ||||||||||||||||||
| 206 | } | - | ||||||||||||||||||
| 207 | } never executed: end of block | 0 | ||||||||||||||||||
| 208 | } executed 147 times by 1 test: end of blockExecuted by:
| 147 | ||||||||||||||||||
| 209 | else if (from_block_size != 0 && to_block_size % from_block_size == 0)
| 0-2872 | ||||||||||||||||||
| 210 | { | - | ||||||||||||||||||
| 211 | uintmax_t divisor = to_block_size / from_block_size; | - | ||||||||||||||||||
| 212 | uintmax_t r10 = (n % divisor) * 10; | - | ||||||||||||||||||
| 213 | uintmax_t r2 = (r10 % divisor) * 2; | - | ||||||||||||||||||
| 214 | amt = n / divisor; | - | ||||||||||||||||||
| 215 | tenths = r10 / divisor; | - | ||||||||||||||||||
| 216 | rounding = r2 < divisor ? 0 < r2 : 2 + (divisor < r2);
| 4-2865 | ||||||||||||||||||
| 217 | goto use_integer_arithmetic; executed 2869 times by 5 tests: goto use_integer_arithmetic;Executed by:
| 2869 | ||||||||||||||||||
| 218 | } | - | ||||||||||||||||||
| 219 | - | |||||||||||||||||||
| 220 | { | - | ||||||||||||||||||
| 221 | /* Either the result cannot be computed easily using uintmax_t, | - | ||||||||||||||||||
| 222 | or from_block_size is zero. Fall back on floating point. | - | ||||||||||||||||||
| 223 | FIXME: This can yield answers that are slightly off. */ | - | ||||||||||||||||||
| 224 | - | |||||||||||||||||||
| 225 | long double dto_block_size = to_block_size; | - | ||||||||||||||||||
| 226 | long double damt = n * (from_block_size / dto_block_size); | - | ||||||||||||||||||
| 227 | size_t buflen; | - | ||||||||||||||||||
| 228 | size_t nonintegerlen; | - | ||||||||||||||||||
| 229 | - | |||||||||||||||||||
| 230 | if (! (opts & human_autoscale))
| 0-150 | ||||||||||||||||||
| 231 | { | - | ||||||||||||||||||
| 232 | sprintf (buf, "%.0Lf", adjust_value (inexact_style, damt)); | - | ||||||||||||||||||
| 233 | buflen = strlen (buf); | - | ||||||||||||||||||
| 234 | nonintegerlen = 0; | - | ||||||||||||||||||
| 235 | } never executed: end of block | 0 | ||||||||||||||||||
| 236 | else | - | ||||||||||||||||||
| 237 | { | - | ||||||||||||||||||
| 238 | long double e = 1; | - | ||||||||||||||||||
| 239 | exponent = 0; | - | ||||||||||||||||||
| 240 | - | |||||||||||||||||||
| 241 | do | - | ||||||||||||||||||
| 242 | { | - | ||||||||||||||||||
| 243 | e *= base; | - | ||||||||||||||||||
| 244 | exponent++; | - | ||||||||||||||||||
| 245 | } executed 237 times by 1 test: end of blockExecuted by:
| 237 | ||||||||||||||||||
| 246 | while (e * base <= damt && exponent < exponent_max);
| 0-150 | ||||||||||||||||||
| 247 | - | |||||||||||||||||||
| 248 | damt /= e; | - | ||||||||||||||||||
| 249 | - | |||||||||||||||||||
| 250 | sprintf (buf, "%.1Lf", adjust_value (inexact_style, damt)); | - | ||||||||||||||||||
| 251 | buflen = strlen (buf); | - | ||||||||||||||||||
| 252 | nonintegerlen = decimal_pointlen + 1; | - | ||||||||||||||||||
| 253 | - | |||||||||||||||||||
| 254 | if (1 + nonintegerlen + ! (opts & human_base_1024) < buflen
| 70-80 | ||||||||||||||||||
| 255 | || ((opts & human_suppress_point_zero)
| 0-80 | ||||||||||||||||||
| 256 | && buf[buflen - 1] == '0'))
| 0 | ||||||||||||||||||
| 257 | { | - | ||||||||||||||||||
| 258 | sprintf (buf, "%.0Lf", | - | ||||||||||||||||||
| 259 | adjust_value (inexact_style, damt * 10) / 10); | - | ||||||||||||||||||
| 260 | buflen = strlen (buf); | - | ||||||||||||||||||
| 261 | nonintegerlen = 0; | - | ||||||||||||||||||
| 262 | } executed 70 times by 1 test: end of blockExecuted by:
| 70 | ||||||||||||||||||
| 263 | } executed 150 times by 1 test: end of blockExecuted by:
| 150 | ||||||||||||||||||
| 264 | - | |||||||||||||||||||
| 265 | p = psuffix - buflen; | - | ||||||||||||||||||
| 266 | memmove (p, buf, buflen); | - | ||||||||||||||||||
| 267 | integerlim = p + buflen - nonintegerlen; | - | ||||||||||||||||||
| 268 | } | - | ||||||||||||||||||
| 269 | goto do_grouping; executed 150 times by 1 test: goto do_grouping;Executed by:
| 150 | ||||||||||||||||||
| 270 | - | |||||||||||||||||||
| 271 | use_integer_arithmetic: | - | ||||||||||||||||||
| 272 | { | - | ||||||||||||||||||
| 273 | /* The computation can be done exactly, with integer arithmetic. | - | ||||||||||||||||||
| 274 | - | |||||||||||||||||||
| 275 | Use power of BASE notation if requested and if adjusted AMT is | - | ||||||||||||||||||
| 276 | large enough. */ | - | ||||||||||||||||||
| 277 | - | |||||||||||||||||||
| 278 | if (opts & human_autoscale)
| 375-4322 | ||||||||||||||||||
| 279 | { | - | ||||||||||||||||||
| 280 | exponent = 0; | - | ||||||||||||||||||
| 281 | - | |||||||||||||||||||
| 282 | if (base <= amt)
| 134-241 | ||||||||||||||||||
| 283 | { | - | ||||||||||||||||||
| 284 | do | - | ||||||||||||||||||
| 285 | { | - | ||||||||||||||||||
| 286 | unsigned int r10 = (amt % base) * 10 + tenths; | - | ||||||||||||||||||
| 287 | unsigned int r2 = (r10 % base) * 2 + (rounding >> 1); | - | ||||||||||||||||||
| 288 | amt /= base; | - | ||||||||||||||||||
| 289 | tenths = r10 / base; | - | ||||||||||||||||||
| 290 | rounding = (r2 < base
| 68-316 | ||||||||||||||||||
| 291 | ? (r2 + rounding) != 0 | - | ||||||||||||||||||
| 292 | : 2 + (base < r2 + rounding)); | - | ||||||||||||||||||
| 293 | exponent++; | - | ||||||||||||||||||
| 294 | } executed 384 times by 3 tests: end of blockExecuted by:
| 384 | ||||||||||||||||||
| 295 | while (base <= amt && exponent < exponent_max);
| 0-241 | ||||||||||||||||||
| 296 | - | |||||||||||||||||||
| 297 | if (amt < 10)
| 108-133 | ||||||||||||||||||
| 298 | { | - | ||||||||||||||||||
| 299 | if (inexact_style == human_round_to_nearest
| 14-94 | ||||||||||||||||||
| 300 | ? 2 < rounding + (tenths & 1)
| 14-94 | ||||||||||||||||||
| 301 | : inexact_style == human_ceiling && 0 < rounding)
| 0-94 | ||||||||||||||||||
| 302 | { | - | ||||||||||||||||||
| 303 | tenths++; | - | ||||||||||||||||||
| 304 | rounding = 0; | - | ||||||||||||||||||
| 305 | - | |||||||||||||||||||
| 306 | if (tenths == 10)
| 1-13 | ||||||||||||||||||
| 307 | { | - | ||||||||||||||||||
| 308 | amt++; | - | ||||||||||||||||||
| 309 | tenths = 0; | - | ||||||||||||||||||
| 310 | } executed 1 time by 1 test: end of blockExecuted by:
| 1 | ||||||||||||||||||
| 311 | } executed 14 times by 3 tests: end of blockExecuted by:
| 14 | ||||||||||||||||||
| 312 | - | |||||||||||||||||||
| 313 | if (amt < 10
| 0-108 | ||||||||||||||||||
| 314 | && (tenths || ! (opts & human_suppress_point_zero)))
| 27-81 | ||||||||||||||||||
| 315 | { | - | ||||||||||||||||||
| 316 | *--p = '0' + tenths; | - | ||||||||||||||||||
| 317 | p -= decimal_pointlen; | - | ||||||||||||||||||
| 318 | memcpy (p, decimal_point, decimal_pointlen); | - | ||||||||||||||||||
| 319 | tenths = rounding = 0; | - | ||||||||||||||||||
| 320 | } executed 56 times by 3 tests: end of blockExecuted by:
| 56 | ||||||||||||||||||
| 321 | } executed 108 times by 3 tests: end of blockExecuted by:
| 108 | ||||||||||||||||||
| 322 | } executed 241 times by 3 tests: end of blockExecuted by:
| 241 | ||||||||||||||||||
| 323 | } executed 375 times by 3 tests: end of blockExecuted by:
| 375 | ||||||||||||||||||
| 324 | - | |||||||||||||||||||
| 325 | if (inexact_style == human_round_to_nearest
| 47-4650 | ||||||||||||||||||
| 326 | ? 5 < tenths + (0 < rounding + (amt & 1))
| 47-4650 | ||||||||||||||||||
| 327 | : inexact_style == human_ceiling && 0 < tenths + rounding)
| 0-4650 | ||||||||||||||||||
| 328 | { | - | ||||||||||||||||||
| 329 | amt++; | - | ||||||||||||||||||
| 330 | - | |||||||||||||||||||
| 331 | if ((opts & human_autoscale)
| 16-31 | ||||||||||||||||||
| 332 | && amt == base && exponent < exponent_max)
| 0-31 | ||||||||||||||||||
| 333 | { | - | ||||||||||||||||||
| 334 | exponent++; | - | ||||||||||||||||||
| 335 | if (! (opts & human_suppress_point_zero))
| 0 | ||||||||||||||||||
| 336 | { | - | ||||||||||||||||||
| 337 | *--p = '0'; | - | ||||||||||||||||||
| 338 | p -= decimal_pointlen; | - | ||||||||||||||||||
| 339 | memcpy (p, decimal_point, decimal_pointlen); | - | ||||||||||||||||||
| 340 | } never executed: end of block | 0 | ||||||||||||||||||
| 341 | amt = 1; | - | ||||||||||||||||||
| 342 | } never executed: end of block | 0 | ||||||||||||||||||
| 343 | } executed 47 times by 3 tests: end of blockExecuted by:
| 47 | ||||||||||||||||||
| 344 | - | |||||||||||||||||||
| 345 | integerlim = p; | - | ||||||||||||||||||
| 346 | - | |||||||||||||||||||
| 347 | do | - | ||||||||||||||||||
| 348 | { | - | ||||||||||||||||||
| 349 | int digit = amt % 10; | - | ||||||||||||||||||
| 350 | *--p = digit + '0'; | - | ||||||||||||||||||
| 351 | } executed 10791 times by 6 tests: end of blockExecuted by:
| 10791 | ||||||||||||||||||
| 352 | while ((amt /= 10) != 0);
| 4697-6094 | ||||||||||||||||||
| 353 | } | - | ||||||||||||||||||
| 354 | - | |||||||||||||||||||
| 355 | do_grouping: code before this statement executed 4697 times by 6 tests: do_grouping:Executed by:
| 4697 | ||||||||||||||||||
| 356 | if (opts & human_group_digits)
| 0-4847 | ||||||||||||||||||
| 357 | p = group_number (p, integerlim - p, grouping, thousands_sep); never executed: p = group_number (p, integerlim - p, grouping, thousands_sep); | 0 | ||||||||||||||||||
| 358 | - | |||||||||||||||||||
| 359 | if (opts & human_SI)
| 525-4322 | ||||||||||||||||||
| 360 | { | - | ||||||||||||||||||
| 361 | if (exponent < 0)
| 0-525 | ||||||||||||||||||
| 362 | { | - | ||||||||||||||||||
| 363 | uintmax_t power; | - | ||||||||||||||||||
| 364 | exponent = 0; | - | ||||||||||||||||||
| 365 | for (power = 1; power < to_block_size; power *= base)
| 0 | ||||||||||||||||||
| 366 | if (++exponent == exponent_max)
| 0 | ||||||||||||||||||
| 367 | break; never executed: break; | 0 | ||||||||||||||||||
| 368 | } never executed: end of block | 0 | ||||||||||||||||||
| 369 | - | |||||||||||||||||||
| 370 | if ((exponent | (opts & human_B)) && (opts & human_space_before_unit))
| 0-525 | ||||||||||||||||||
| 371 | *psuffix++ = ' '; executed 454 times by 1 test: *psuffix++ = ' ';Executed by:
| 454 | ||||||||||||||||||
| 372 | - | |||||||||||||||||||
| 373 | if (exponent)
| 134-391 | ||||||||||||||||||
| 374 | *psuffix++ = (! (opts & human_base_1024) && exponent == 1 executed 391 times by 3 tests: *psuffix++ = (! (opts & human_base_1024) && exponent == 1 ? 'k' : power_letter[exponent]);Executed by:
| 86-391 | ||||||||||||||||||
| 375 | ? 'k' executed 391 times by 3 tests: *psuffix++ = (! (opts & human_base_1024) && exponent == 1 ? 'k' : power_letter[exponent]);Executed by:
| 391 | ||||||||||||||||||
| 376 | : power_letter[exponent]); executed 391 times by 3 tests: *psuffix++ = (! (opts & human_base_1024) && exponent == 1 ? 'k' : power_letter[exponent]);Executed by:
| 391 | ||||||||||||||||||
| 377 | - | |||||||||||||||||||
| 378 | if (opts & human_B)
| 71-454 | ||||||||||||||||||
| 379 | { | - | ||||||||||||||||||
| 380 | if ((opts & human_base_1024) && exponent)
| 67-300 | ||||||||||||||||||
| 381 | *psuffix++ = 'i'; executed 87 times by 1 test: *psuffix++ = 'i';Executed by:
| 87 | ||||||||||||||||||
| 382 | *psuffix++ = 'B'; | - | ||||||||||||||||||
| 383 | } executed 454 times by 1 test: end of blockExecuted by:
| 454 | ||||||||||||||||||
| 384 | } executed 525 times by 3 tests: end of blockExecuted by:
| 525 | ||||||||||||||||||
| 385 | - | |||||||||||||||||||
| 386 | *psuffix = '\0'; | - | ||||||||||||||||||
| 387 | - | |||||||||||||||||||
| 388 | return p; executed 4847 times by 6 tests: return p;Executed by:
| 4847 | ||||||||||||||||||
| 389 | } | - | ||||||||||||||||||
| 390 | - | |||||||||||||||||||
| 391 | - | |||||||||||||||||||
| 392 | /* The default block size used for output. This number may change in | - | ||||||||||||||||||
| 393 | the future as disks get larger. */ | - | ||||||||||||||||||
| 394 | #ifndef DEFAULT_BLOCK_SIZE | - | ||||||||||||||||||
| 395 | # define DEFAULT_BLOCK_SIZE 1024 | - | ||||||||||||||||||
| 396 | #endif | - | ||||||||||||||||||
| 397 | - | |||||||||||||||||||
| 398 | static char const *const block_size_args[] = { "human-readable", "si", 0 }; | - | ||||||||||||||||||
| 399 | static int const block_size_opts[] = | - | ||||||||||||||||||
| 400 | { | - | ||||||||||||||||||
| 401 | human_autoscale + human_SI + human_base_1024, | - | ||||||||||||||||||
| 402 | human_autoscale + human_SI | - | ||||||||||||||||||
| 403 | }; | - | ||||||||||||||||||
| 404 | - | |||||||||||||||||||
| 405 | static uintmax_t | - | ||||||||||||||||||
| 406 | default_block_size (void) | - | ||||||||||||||||||
| 407 | { | - | ||||||||||||||||||
| 408 | return getenv ("POSIXLY_CORRECT") ? 512 : DEFAULT_BLOCK_SIZE; executed 1622 times by 5 tests: return getenv ("POSIXLY_CORRECT") ? 512 : 1024;Executed by:
| 1622 | ||||||||||||||||||
| 409 | } | - | ||||||||||||||||||
| 410 | - | |||||||||||||||||||
| 411 | static strtol_error | - | ||||||||||||||||||
| 412 | humblock (char const *spec, uintmax_t *block_size, int *options) | - | ||||||||||||||||||
| 413 | { | - | ||||||||||||||||||
| 414 | int i; | - | ||||||||||||||||||
| 415 | int opts = 0; | - | ||||||||||||||||||
| 416 | - | |||||||||||||||||||
| 417 | if (! spec
| 183-1618 | ||||||||||||||||||
| 418 | && ! (spec = getenv ("BLOCK_SIZE"))
| 0-1618 | ||||||||||||||||||
| 419 | && ! (spec = getenv ("BLOCKSIZE")))
| 0-1618 | ||||||||||||||||||
| 420 | *block_size = default_block_size (); executed 1618 times by 5 tests: *block_size = default_block_size ();Executed by:
| 1618 | ||||||||||||||||||
| 421 | else | - | ||||||||||||||||||
| 422 | { | - | ||||||||||||||||||
| 423 | if (*spec == '\'')
| 0-183 | ||||||||||||||||||
| 424 | { | - | ||||||||||||||||||
| 425 | opts |= human_group_digits; | - | ||||||||||||||||||
| 426 | spec++; | - | ||||||||||||||||||
| 427 | } never executed: end of block | 0 | ||||||||||||||||||
| 428 | - | |||||||||||||||||||
| 429 | if (0 <= (i = ARGMATCH (spec, block_size_args, block_size_opts)))
| 0-183 | ||||||||||||||||||
| 430 | { | - | ||||||||||||||||||
| 431 | opts |= block_size_opts[i]; | - | ||||||||||||||||||
| 432 | *block_size = 1; | - | ||||||||||||||||||
| 433 | } never executed: end of block | 0 | ||||||||||||||||||
| 434 | else | - | ||||||||||||||||||
| 435 | { | - | ||||||||||||||||||
| 436 | char *ptr; | - | ||||||||||||||||||
| 437 | strtol_error e = xstrtoumax (spec, &ptr, 0, block_size, | - | ||||||||||||||||||
| 438 | "eEgGkKmMpPtTyYzZ0"); | - | ||||||||||||||||||
| 439 | if (e != LONGINT_OK)
| 6-177 | ||||||||||||||||||
| 440 | { | - | ||||||||||||||||||
| 441 | *options = 0; | - | ||||||||||||||||||
| 442 | return e; executed 6 times by 4 tests: return e;Executed by:
| 6 | ||||||||||||||||||
| 443 | } | - | ||||||||||||||||||
| 444 | for (; ! ('0' <= *spec && *spec <= '9'); spec++)
| 0-177 | ||||||||||||||||||
| 445 | if (spec == ptr)
| 0 | ||||||||||||||||||
| 446 | { | - | ||||||||||||||||||
| 447 | opts |= human_SI; | - | ||||||||||||||||||
| 448 | if (ptr[-1] == 'B')
| 0 | ||||||||||||||||||
| 449 | opts |= human_B; never executed: opts |= human_B; | 0 | ||||||||||||||||||
| 450 | if (ptr[-1] != 'B' || ptr[-2] == 'i')
| 0 | ||||||||||||||||||
| 451 | opts |= human_base_1024; never executed: opts |= human_base_1024; | 0 | ||||||||||||||||||
| 452 | break; never executed: break; | 0 | ||||||||||||||||||
| 453 | } | - | ||||||||||||||||||
| 454 | } executed 177 times by 2 tests: end of blockExecuted by:
| 177 | ||||||||||||||||||
| 455 | } | - | ||||||||||||||||||
| 456 | - | |||||||||||||||||||
| 457 | *options = opts; | - | ||||||||||||||||||
| 458 | return LONGINT_OK; executed 1795 times by 5 tests: return LONGINT_OK;Executed by:
| 1795 | ||||||||||||||||||
| 459 | } | - | ||||||||||||||||||
| 460 | - | |||||||||||||||||||
| 461 | enum strtol_error | - | ||||||||||||||||||
| 462 | human_options (char const *spec, int *opts, uintmax_t *block_size) | - | ||||||||||||||||||
| 463 | { | - | ||||||||||||||||||
| 464 | strtol_error e = humblock (spec, block_size, opts); | - | ||||||||||||||||||
| 465 | if (*block_size == 0)
| 4-1797 | ||||||||||||||||||
| 466 | { | - | ||||||||||||||||||
| 467 | *block_size = default_block_size (); | - | ||||||||||||||||||
| 468 | e = LONGINT_INVALID; | - | ||||||||||||||||||
| 469 | } executed 4 times by 3 tests: end of blockExecuted by:
| 4 | ||||||||||||||||||
| 470 | return e; executed 1801 times by 5 tests: return e;Executed by:
| 1801 | ||||||||||||||||||
| 471 | } | - | ||||||||||||||||||
| Source code | Switch to Preprocessed file |