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 block Executed 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 block Executed 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 block Executed 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 block Executed by:
| 70 | ||||||||||||||||||
263 | } executed 150 times by 1 test: end of block Executed 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 block Executed 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 block Executed by:
| 1 | ||||||||||||||||||
311 | } executed 14 times by 3 tests: end of block Executed 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 block Executed by:
| 56 | ||||||||||||||||||
321 | } executed 108 times by 3 tests: end of block Executed by:
| 108 | ||||||||||||||||||
322 | } executed 241 times by 3 tests: end of block Executed by:
| 241 | ||||||||||||||||||
323 | } executed 375 times by 3 tests: end of block Executed 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 block Executed 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 block Executed 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 block Executed by:
| 454 | ||||||||||||||||||
384 | } executed 525 times by 3 tests: end of block Executed 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 block Executed 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 block Executed by:
| 4 | ||||||||||||||||||
470 | return e; executed 1801 times by 5 tests: return e; Executed by:
| 1801 | ||||||||||||||||||
471 | } | - | ||||||||||||||||||
Source code | Switch to Preprocessed file |