xref: /freebsd/lib/libutil/tests/humanize_number_test.c (revision b3e7694832e81d7a904a10f525f8797b753bf0d3)
15aa45fcbSEnji Cooper /*-
25aa45fcbSEnji Cooper  * Copyright 2012 Clifton Royston
35aa45fcbSEnji Cooper  * Copyright 2013 John-Mark Gurney
45aa45fcbSEnji Cooper  * All rights reserved.
55aa45fcbSEnji Cooper  *
65aa45fcbSEnji Cooper  * Redistribution and use in source and binary forms, with or without
75aa45fcbSEnji Cooper  * modification, are permitted provided that the following conditions
85aa45fcbSEnji Cooper  * are met:
95aa45fcbSEnji Cooper  * 1. Redistributions of source code must retain the above copyright
105aa45fcbSEnji Cooper  *    notice, this list of conditions and the following disclaimer.
115aa45fcbSEnji Cooper  * 2. Redistributions in binary form must reproduce the above copyright
125aa45fcbSEnji Cooper  *    notice, this list of conditions and the following disclaimer in the
135aa45fcbSEnji Cooper  *    documentation and/or other materials provided with the distribution.
145aa45fcbSEnji Cooper  *
155aa45fcbSEnji Cooper  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
165aa45fcbSEnji Cooper  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
175aa45fcbSEnji Cooper  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
185aa45fcbSEnji Cooper  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
195aa45fcbSEnji Cooper  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
205aa45fcbSEnji Cooper  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
215aa45fcbSEnji Cooper  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
225aa45fcbSEnji Cooper  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
235aa45fcbSEnji Cooper  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
245aa45fcbSEnji Cooper  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
255aa45fcbSEnji Cooper  * SUCH DAMAGE.
265aa45fcbSEnji Cooper  *
275aa45fcbSEnji Cooper  */
285aa45fcbSEnji Cooper 
295aa45fcbSEnji Cooper #include <sys/param.h>
305aa45fcbSEnji Cooper #include <inttypes.h>
315aa45fcbSEnji Cooper #include <libutil.h>
325aa45fcbSEnji Cooper #include <limits.h>
335aa45fcbSEnji Cooper #include <math.h>
345aa45fcbSEnji Cooper #include <stdio.h>
355aa45fcbSEnji Cooper #include <stdlib.h>
365aa45fcbSEnji Cooper #include <string.h>
375aa45fcbSEnji Cooper #include <unistd.h>
385aa45fcbSEnji Cooper 
395aa45fcbSEnji Cooper #define	MAX_STR_FLAGS_RESULT	80
405aa45fcbSEnji Cooper #define MAX_INT_STR_DIGITS	12
415aa45fcbSEnji Cooper 
425aa45fcbSEnji Cooper static const int64_t halfExabyte = (int64_t)500*1000*1000*1000*1000*1000L;
435aa45fcbSEnji Cooper 
445aa45fcbSEnji Cooper static struct {
455aa45fcbSEnji Cooper 	int retval;
465aa45fcbSEnji Cooper 	const char *res;
475aa45fcbSEnji Cooper 	int64_t num;
485aa45fcbSEnji Cooper 	int flags;
495aa45fcbSEnji Cooper 	int scale;
50*e285e32eSBartek Rutkowski 	size_t buflen;
515aa45fcbSEnji Cooper } test_args[] = {
525aa45fcbSEnji Cooper 	/* tests 0-13 test 1000 suffixes */
53*e285e32eSBartek Rutkowski 	{ 2, "0 ", (int64_t)0L, HN_DIVISOR_1000, HN_AUTOSCALE, 4 },
54*e285e32eSBartek Rutkowski 	{ 3, "1 k", (int64_t)500L, HN_DIVISOR_1000, HN_AUTOSCALE, 4 },
55*e285e32eSBartek Rutkowski 	{ 3, "1 M", (int64_t)500*1000L, HN_DIVISOR_1000, HN_AUTOSCALE, 4 },
56*e285e32eSBartek Rutkowski 	{ 3, "1 G", (int64_t)500*1000*1000L, HN_DIVISOR_1000, HN_AUTOSCALE, 4 },
57*e285e32eSBartek Rutkowski 	{ 3, "1 T", (int64_t)500*1000*1000*1000L, HN_DIVISOR_1000, HN_AUTOSCALE, 4 },
58*e285e32eSBartek Rutkowski 	{ 3, "1 P", (int64_t)500*1000*1000*1000*1000L, HN_DIVISOR_1000, HN_AUTOSCALE, 4 },
59*e285e32eSBartek Rutkowski 	{ 3, "1 E", (int64_t)500*1000*1000*1000*1000*1000L, HN_DIVISOR_1000, HN_AUTOSCALE, 4 },
60*e285e32eSBartek Rutkowski 	{ 2, "1 ", (int64_t)1L, HN_DIVISOR_1000, HN_AUTOSCALE, 4 },
61*e285e32eSBartek Rutkowski 	{ 3, "2 k", (int64_t)1500L, HN_DIVISOR_1000, HN_AUTOSCALE, 4 },
62*e285e32eSBartek Rutkowski 	{ 3, "2 M", (int64_t)1500*1000L, HN_DIVISOR_1000, HN_AUTOSCALE, 4 },
63*e285e32eSBartek Rutkowski 	{ 3, "2 G", (int64_t)1500*1000*1000L, HN_DIVISOR_1000, HN_AUTOSCALE, 4 },
64*e285e32eSBartek Rutkowski 	{ 3, "2 T", (int64_t)1500*1000*1000*1000L, HN_DIVISOR_1000, HN_AUTOSCALE, 4 },
65*e285e32eSBartek Rutkowski 	{ 3, "2 P", (int64_t)1500*1000*1000*1000*1000L, HN_DIVISOR_1000, HN_AUTOSCALE, 4 },
66*e285e32eSBartek Rutkowski 	{ 3, "2 E", (int64_t)1500*1000*1000*1000*1000*1000L, HN_DIVISOR_1000, HN_AUTOSCALE, 4 },
675aa45fcbSEnji Cooper 
685aa45fcbSEnji Cooper 	/* tests 14-27 test 1024 suffixes */
69*e285e32eSBartek Rutkowski 	{ 2, "0 ", (int64_t)0L, 0, HN_AUTOSCALE, 4 },
70*e285e32eSBartek Rutkowski 	{ 3, "1 K", (int64_t)512L, 0, HN_AUTOSCALE, 4 },
71*e285e32eSBartek Rutkowski 	{ 3, "1 M", (int64_t)512*1024L, 0, HN_AUTOSCALE, 4 },
72*e285e32eSBartek Rutkowski 	{ 3, "1 G", (int64_t)512*1024*1024L, 0, HN_AUTOSCALE, 4 },
73*e285e32eSBartek Rutkowski 	{ 3, "1 T", (int64_t)512*1024*1024*1024L, 0, HN_AUTOSCALE, 4 },
74*e285e32eSBartek Rutkowski 	{ 3, "1 P", (int64_t)512*1024*1024*1024*1024L, 0, HN_AUTOSCALE, 4 },
75*e285e32eSBartek Rutkowski 	{ 3, "1 E", (int64_t)512*1024*1024*1024*1024*1024L, 0, HN_AUTOSCALE, 4 },
76*e285e32eSBartek Rutkowski 	{ 2, "1 ", (int64_t)1L, 0, HN_AUTOSCALE, 4 },
77*e285e32eSBartek Rutkowski 	{ 3, "2 K", (int64_t)1536L, 0, HN_AUTOSCALE, 4 },
78*e285e32eSBartek Rutkowski 	{ 3, "2 M", (int64_t)1536*1024L, 0, HN_AUTOSCALE, 4 },
79*e285e32eSBartek Rutkowski 	{ 3, "2 G", (int64_t)1536*1024*1024L, 0, HN_AUTOSCALE, 4 },
80*e285e32eSBartek Rutkowski 	{ 3, "2 T", (int64_t)1536*1024*1024*1024L, 0, HN_AUTOSCALE, 4 },
81*e285e32eSBartek Rutkowski 	{ 3, "2 P", (int64_t)1536*1024*1024*1024*1024L, 0, HN_AUTOSCALE, 4 },
82*e285e32eSBartek Rutkowski 	{ 3, "2 E", (int64_t)1536*1024*1024*1024*1024*1024L, 0, HN_AUTOSCALE, 4 },
835aa45fcbSEnji Cooper 
845aa45fcbSEnji Cooper 	/* tests 28-37 test rounding */
85*e285e32eSBartek Rutkowski 	{ 3, "0 M", (int64_t)500*1000L-1, HN_DIVISOR_1000, HN_AUTOSCALE, 4 },
86*e285e32eSBartek Rutkowski 	{ 3, "1 M", (int64_t)500*1000L, HN_DIVISOR_1000, HN_AUTOSCALE, 4 },
87*e285e32eSBartek Rutkowski 	{ 3, "1 M", (int64_t)1000*1000L + 500*1000L-1, HN_DIVISOR_1000, HN_AUTOSCALE, 4 },
88*e285e32eSBartek Rutkowski 	{ 3, "2 M", (int64_t)1000*1000L + 500*1000L, HN_DIVISOR_1000, HN_AUTOSCALE, 4 },
89*e285e32eSBartek Rutkowski 	{ 3, "0 K", (int64_t)512L-1, 0, HN_AUTOSCALE, 4 },
90*e285e32eSBartek Rutkowski 	{ 3, "1 K", (int64_t)512L, 0, HN_AUTOSCALE, 4 },
91*e285e32eSBartek Rutkowski 	{ 3, "0 M", (int64_t)512*1024L-1, 0, HN_AUTOSCALE, 4 },
92*e285e32eSBartek Rutkowski 	{ 3, "1 M", (int64_t)512*1024L, 0, HN_AUTOSCALE, 4 },
93*e285e32eSBartek Rutkowski 	{ 3, "1 M", (int64_t)1024*1024L + 512*1024L-1, 0, HN_AUTOSCALE, 4 },
94*e285e32eSBartek Rutkowski 	{ 3, "2 M", (int64_t)1024*1024L + 512*1024L, 0, HN_AUTOSCALE, 4 },
955aa45fcbSEnji Cooper 
965aa45fcbSEnji Cooper 	/* tests 38-61 test specific scale factors with 1000 divisor */
97*e285e32eSBartek Rutkowski 	{ 3, "0 k", (int64_t)0L, HN_DIVISOR_1000, 1, 4 },
98*e285e32eSBartek Rutkowski 	{ 3, "1 k", (int64_t)500L, HN_DIVISOR_1000, 1, 4 },
99*e285e32eSBartek Rutkowski 	{ 3, "0 M", (int64_t)500L, HN_DIVISOR_1000, 2, 4 },
100*e285e32eSBartek Rutkowski 	{ 3, "1 M", (int64_t)500*1000L, HN_DIVISOR_1000, 2, 4 },
101*e285e32eSBartek Rutkowski 	{ 3, "0 G", (int64_t)500*1000L, HN_DIVISOR_1000, 3, 4 },
102*e285e32eSBartek Rutkowski 	{ 3, "1 G", (int64_t)500*1000*1000L, HN_DIVISOR_1000, 3, 4 },
103*e285e32eSBartek Rutkowski 	{ 3, "0 T", (int64_t)500*1000*1000L, HN_DIVISOR_1000, 4, 4 },
104*e285e32eSBartek Rutkowski 	{ 3, "1 T", (int64_t)500*1000*1000*1000L, HN_DIVISOR_1000, 4, 4 },
105*e285e32eSBartek Rutkowski 	{ 3, "0 P", (int64_t)500*1000*1000*1000L, HN_DIVISOR_1000, 5, 4 },
106*e285e32eSBartek Rutkowski 	{ 3, "1 P", (int64_t)500*1000*1000*1000*1000L, HN_DIVISOR_1000, 5, 4 },
107*e285e32eSBartek Rutkowski 	{ 3, "0 E", (int64_t)500*1000*1000*1000*1000L, HN_DIVISOR_1000, 6, 4 },
108*e285e32eSBartek Rutkowski 	{ 3, "1 E", (int64_t)500*1000*1000*1000*1000*1000L, HN_DIVISOR_1000, 6, 4 },
109*e285e32eSBartek Rutkowski 	{ 3, "0 k", (int64_t)1L, HN_DIVISOR_1000, 1, 4 },
110*e285e32eSBartek Rutkowski 	{ 3, "2 k", (int64_t)1500L, HN_DIVISOR_1000, 1, 4 },
111*e285e32eSBartek Rutkowski 	{ 3, "0 M", (int64_t)1500L, HN_DIVISOR_1000, 2, 4 },
112*e285e32eSBartek Rutkowski 	{ 3, "2 M", (int64_t)1500*1000L, HN_DIVISOR_1000, 2, 4 },
113*e285e32eSBartek Rutkowski 	{ 3, "0 G", (int64_t)1500*1000L, HN_DIVISOR_1000, 3, 4 },
114*e285e32eSBartek Rutkowski 	{ 3, "2 G", (int64_t)1500*1000*1000L, HN_DIVISOR_1000, 3, 4 },
115*e285e32eSBartek Rutkowski 	{ 3, "0 T", (int64_t)1500*1000*1000L, HN_DIVISOR_1000, 4, 4 },
116*e285e32eSBartek Rutkowski 	{ 3, "2 T", (int64_t)1500*1000*1000*1000L, HN_DIVISOR_1000, 4, 4 },
117*e285e32eSBartek Rutkowski 	{ 3, "0 P", (int64_t)1500*1000*1000*1000L, HN_DIVISOR_1000, 5, 4 },
118*e285e32eSBartek Rutkowski 	{ 3, "2 P", (int64_t)1500*1000*1000*1000*1000L, HN_DIVISOR_1000, 5, 4 },
119*e285e32eSBartek Rutkowski 	{ 3, "0 E", (int64_t)1500*1000*1000*1000*1000L, HN_DIVISOR_1000, 6, 4 },
120*e285e32eSBartek Rutkowski 	{ 3, "2 E", (int64_t)1500*1000*1000*1000*1000*1000L, HN_DIVISOR_1000, 6, 4 },
1215aa45fcbSEnji Cooper 
1225aa45fcbSEnji Cooper 	/* tests 62-85 test specific scale factors with 1024 divisor */
123*e285e32eSBartek Rutkowski 	{ 3, "0 K", (int64_t)0L, 0, 1, 4 },
124*e285e32eSBartek Rutkowski 	{ 3, "1 K", (int64_t)512L, 0, 1, 4 },
125*e285e32eSBartek Rutkowski 	{ 3, "0 M", (int64_t)512L, 0, 2, 4 },
126*e285e32eSBartek Rutkowski 	{ 3, "1 M", (int64_t)512*1024L, 0, 2, 4 },
127*e285e32eSBartek Rutkowski 	{ 3, "0 G", (int64_t)512*1024L, 0, 3, 4 },
128*e285e32eSBartek Rutkowski 	{ 3, "1 G", (int64_t)512*1024*1024L, 0, 3, 4 },
129*e285e32eSBartek Rutkowski 	{ 3, "0 T", (int64_t)512*1024*1024L, 0, 4, 4 },
130*e285e32eSBartek Rutkowski 	{ 3, "1 T", (int64_t)512*1024*1024*1024L, 0, 4, 4 },
131*e285e32eSBartek Rutkowski 	{ 3, "0 P", (int64_t)512*1024*1024*1024L, 0, 5, 4 },
132*e285e32eSBartek Rutkowski 	{ 3, "1 P", (int64_t)512*1024*1024*1024*1024L, 0, 5, 4 },
133*e285e32eSBartek Rutkowski 	{ 3, "0 E", (int64_t)512*1024*1024*1024*1024L, 0, 6, 4 },
134*e285e32eSBartek Rutkowski 	{ 3, "1 E", (int64_t)512*1024*1024*1024*1024*1024L, 0, 6, 4 },
135*e285e32eSBartek Rutkowski 	{ 3, "0 K", (int64_t)1L, 0, 1, 4 },
136*e285e32eSBartek Rutkowski 	{ 3, "2 K", (int64_t)1536L, 0, 1, 4 },
137*e285e32eSBartek Rutkowski 	{ 3, "0 M", (int64_t)1536L, 0, 2, 4 },
138*e285e32eSBartek Rutkowski 	{ 3, "2 M", (int64_t)1536*1024L, 0, 2, 4 },
139*e285e32eSBartek Rutkowski 	{ 3, "0 G", (int64_t)1536*1024L, 0, 3, 4 },
140*e285e32eSBartek Rutkowski 	{ 3, "2 G", (int64_t)1536*1024*1024L, 0, 3, 4 },
141*e285e32eSBartek Rutkowski 	{ 3, "0 T", (int64_t)1536*1024*1024L, 0, 4, 4 },
142*e285e32eSBartek Rutkowski 	{ 3, "2 T", (int64_t)1536*1024*1024*1024L, 0, 4, 4 },
143*e285e32eSBartek Rutkowski 	{ 3, "0 P", (int64_t)1536*1024*1024*1024L, 0, 5, 4 },
144*e285e32eSBartek Rutkowski 	{ 3, "2 P", (int64_t)1536*1024*1024*1024*1024L, 0, 5, 4 },
145*e285e32eSBartek Rutkowski 	{ 3, "0 E", (int64_t)1536*1024*1024*1024*1024L, 0, 6, 4 },
146*e285e32eSBartek Rutkowski 	{ 3, "2 E", (int64_t)1536*1024*1024*1024*1024*1024L, 0, 6, 4 },
1475aa45fcbSEnji Cooper 
1485aa45fcbSEnji Cooper 	/* tests 86-99 test invalid specific scale values of < 0 or >= 7 with
1495aa45fcbSEnji Cooper 	and without HN_DIVISOR_1000 set */
1505aa45fcbSEnji Cooper 	/*  all should return errors with new code; with old, the latter 3
1515aa45fcbSEnji Cooper 	are instead processed as if having AUTOSCALE and/or GETSCALE set */
152*e285e32eSBartek Rutkowski 	{ -1, "", (int64_t)1L, 0, 7, 4 },
153*e285e32eSBartek Rutkowski 	{ -1, "", (int64_t)1L, HN_DIVISOR_1000, 7, 4 },
154*e285e32eSBartek Rutkowski 	{ -1, "", (int64_t)1L, 0, 1000, 4 },
155*e285e32eSBartek Rutkowski 	{ -1, "", (int64_t)1L, HN_DIVISOR_1000, 1000, 4 },
156*e285e32eSBartek Rutkowski 	{ -1, "", (int64_t)0L, 0, 1000*1000, 4 },
157*e285e32eSBartek Rutkowski 	{ -1, "", (int64_t)0L, HN_DIVISOR_1000, 1000*1000, 4 },
158*e285e32eSBartek Rutkowski 	{ -1, "", (int64_t)0L, 0, INT_MAX, 4 },
159*e285e32eSBartek Rutkowski 	{ -1, "", (int64_t)0L, HN_DIVISOR_1000, INT_MAX, 4 },
1605aa45fcbSEnji Cooper 
1615aa45fcbSEnji Cooper 	/* Negative scale values are not handled well
1625aa45fcbSEnji Cooper 	 by the existing library routine - should report as error */
1635aa45fcbSEnji Cooper 	/*  all should return errors with new code, fail assertion with old */
1645aa45fcbSEnji Cooper 
165*e285e32eSBartek Rutkowski 	{ -1, "", (int64_t)1L, 0, -1, 4 },
166*e285e32eSBartek Rutkowski 	{ -1, "", (int64_t)1L, HN_DIVISOR_1000, -1, 4 },
167*e285e32eSBartek Rutkowski 	{ -1, "", (int64_t)1L, 0, -1000, 4 },
168*e285e32eSBartek Rutkowski 	{ -1, "", (int64_t)1L, HN_DIVISOR_1000, -1000, 4 },
1695aa45fcbSEnji Cooper 
1705aa45fcbSEnji Cooper 	/* __INT_MIN doesn't print properly, skipped. */
1715aa45fcbSEnji Cooper 
172*e285e32eSBartek Rutkowski 	{ -1, "", (int64_t)1L, 0, -__INT_MAX, 4 },
173*e285e32eSBartek Rutkowski 	{ -1, "", (int64_t)1L, HN_DIVISOR_1000, -__INT_MAX, 4 },
1745aa45fcbSEnji Cooper 
1755aa45fcbSEnji Cooper 
1765aa45fcbSEnji Cooper 	/* tests for scale == 0, without autoscale */
1775aa45fcbSEnji Cooper 	/* tests 100-114 test scale 0 with 1000 divisor - print first N digits */
178*e285e32eSBartek Rutkowski 	{ 2, "0 ", (int64_t)0L, HN_DIVISOR_1000, 0, 4 },
179*e285e32eSBartek Rutkowski 	{ 2, "1 ", (int64_t)1L, HN_DIVISOR_1000, 0, 4 },
180*e285e32eSBartek Rutkowski 	{ 3, "10 ", (int64_t)10L, HN_DIVISOR_1000, 0, 4 },
181*e285e32eSBartek Rutkowski 	{ 3, "0 M", (int64_t)150L, HN_DIVISOR_1000, HN_NOSPACE, 4 },
182*e285e32eSBartek Rutkowski 	{ 3, "0 M", (int64_t)500L, HN_DIVISOR_1000, HN_NOSPACE, 4 },
183*e285e32eSBartek Rutkowski 	{ 3, "0 M", (int64_t)999L, HN_DIVISOR_1000, HN_NOSPACE, 4 },
184*e285e32eSBartek Rutkowski 	{ 4, "150", (int64_t)150L, HN_DIVISOR_1000, 0, 4 },
185*e285e32eSBartek Rutkowski 	{ 4, "500", (int64_t)500L, HN_DIVISOR_1000, 0, 4 },
186*e285e32eSBartek Rutkowski 	{ 4, "999", (int64_t)999L, HN_DIVISOR_1000, 0, 4 },
187*e285e32eSBartek Rutkowski 	{ 5, "100", (int64_t)1000L, HN_DIVISOR_1000, 0, 4 },
188*e285e32eSBartek Rutkowski 	{ 5, "150", (int64_t)1500L, HN_DIVISOR_1000, 0, 4 },
189*e285e32eSBartek Rutkowski 	{ 7, "500", (int64_t)500*1000L, HN_DIVISOR_1000, 0, 4 },
190*e285e32eSBartek Rutkowski 	{ 8, "150", (int64_t)1500*1000L, HN_DIVISOR_1000, 0, 4 },
191*e285e32eSBartek Rutkowski 	{ 10, "500", (int64_t)500*1000*1000L, HN_DIVISOR_1000, 0, 4 },
192*e285e32eSBartek Rutkowski 	{ 11, "150", (int64_t)1500*1000*1000L, HN_DIVISOR_1000, 0, 4 },
1935aa45fcbSEnji Cooper 
1945aa45fcbSEnji Cooper 	/* tests 115-126 test scale 0 with 1024 divisor - print first N digits */
195*e285e32eSBartek Rutkowski 	{ 2, "0 ", (int64_t)0L, 0, 0, 4 },
196*e285e32eSBartek Rutkowski 	{ 2, "1 ", (int64_t)1L, 0, 0, 4 },
197*e285e32eSBartek Rutkowski 	{ 3, "10 ", (int64_t)10L, 0, 0, 4 },
198*e285e32eSBartek Rutkowski 	{ 4, "150", (int64_t)150L, 0, 0, 4 },
199*e285e32eSBartek Rutkowski 	{ 4, "500", (int64_t)500L, 0, 0, 4 },
200*e285e32eSBartek Rutkowski 	{ 4, "999", (int64_t)999L, 0, 0, 4 },
201*e285e32eSBartek Rutkowski 	{ 5, "100", (int64_t)1000L, 0, 0, 4 },
202*e285e32eSBartek Rutkowski 	{ 5, "150", (int64_t)1500L, 0, 0, 4 },
203*e285e32eSBartek Rutkowski 	{ 7, "500", (int64_t)500*1000L, 0, 0, 4 },
204*e285e32eSBartek Rutkowski 	{ 8, "150", (int64_t)1500*1000L, 0, 0, 4 },
205*e285e32eSBartek Rutkowski 	{ 10, "500", (int64_t)500*1000*1000L, 0, 0, 4 },
206*e285e32eSBartek Rutkowski 	{ 11, "150", (int64_t)1500*1000*1000L, 0, 0, 4 },
207*e285e32eSBartek Rutkowski 
208*e285e32eSBartek Rutkowski 	/* Test case for rounding of edge numbers around 999.5+, see PR224498.
209*e285e32eSBartek Rutkowski 	 * Require buflen >= 5 */
210*e285e32eSBartek Rutkowski 	{ 4, "1.0M", (int64_t)1023500, HN_DECIMAL|HN_B|HN_NOSPACE, HN_AUTOSCALE, 5 },
2115aa45fcbSEnji Cooper 
2125aa45fcbSEnji Cooper 	/* Test boundary cases for very large positive/negative number formatting */
2135aa45fcbSEnji Cooper 	/* Explicit scale, divisor 1024 */
2145aa45fcbSEnji Cooper 
215*e285e32eSBartek Rutkowski 	/* Requires buflen >= 6 */
216*e285e32eSBartek Rutkowski 	{ 3, "8 E",   INT64_MAX, 0, 6, 6 },
217*e285e32eSBartek Rutkowski 	{ 4, "-8 E", -INT64_MAX, 0, 6, 6 },
218*e285e32eSBartek Rutkowski 	{ 3, "0 E", (int64_t)92*1024*1024*1024*1024*1024L, 0, 6, 6 },
219*e285e32eSBartek Rutkowski 	{ 3, "0 E", -(int64_t)92*1024*1024*1024*1024*1024L, 0, 6, 6 },
220*e285e32eSBartek Rutkowski 	{ 3, "0 E", (int64_t)82*1024*1024*1024*1024*1024L, 0, 6, 6 },
221*e285e32eSBartek Rutkowski 	{ 3, "0 E", -(int64_t)82*1024*1024*1024*1024*1024L, 0, 6, 6 },
222*e285e32eSBartek Rutkowski 	{ 3, "0 E", (int64_t)81*1024*1024*1024*1024*1024L, 0, 6, 6 },
223*e285e32eSBartek Rutkowski 	{ 3, "0 E", -(int64_t)81*1024*1024*1024*1024*1024L, 0, 6, 6 },
224*e285e32eSBartek Rutkowski 	{ 4, "92 P", (int64_t)92*1024*1024*1024*1024*1024L, 0, 5, 6 },
225*e285e32eSBartek Rutkowski 	{ 5, "-92 P", -(int64_t)92*1024*1024*1024*1024*1024L, 0, 5, 6 },
226*e285e32eSBartek Rutkowski 	{ 4, "82 P", (int64_t)82*1024*1024*1024*1024*1024L, 0, 5, 6 },
227*e285e32eSBartek Rutkowski 	{ 5, "-82 P", -(int64_t)82*1024*1024*1024*1024*1024L, 0, 5, 6 },
228*e285e32eSBartek Rutkowski 	{ 4, "81 P", (int64_t)81*1024*1024*1024*1024*1024L, 0, 5, 6 },
229*e285e32eSBartek Rutkowski 	{ 5, "-81 P", -(int64_t)81*1024*1024*1024*1024*1024L, 0, 5, 6 },
2305aa45fcbSEnji Cooper 
2315aa45fcbSEnji Cooper 	/* Explicit scale, divisor 1000 */
232*e285e32eSBartek Rutkowski 	{ 3, "9 E",   INT64_MAX, HN_DIVISOR_1000, 6, 6 },
233*e285e32eSBartek Rutkowski 	{ 4, "-9 E", -INT64_MAX, HN_DIVISOR_1000,  6, 6 },
234*e285e32eSBartek Rutkowski 	{ 3, "0 E", (int64_t)82*1024*1024*1024*1024*1024L, HN_DIVISOR_1000,  6, 6 },
235*e285e32eSBartek Rutkowski 	{ 3, "0 E", -(int64_t)82*1024*1024*1024*1024*1024L, HN_DIVISOR_1000,  6, 6 },
236*e285e32eSBartek Rutkowski 	{ 3, "0 E", (int64_t)82*1024*1024*1024*1024*1024L, HN_DIVISOR_1000,  6, 6 },
237*e285e32eSBartek Rutkowski 	{ 3, "0 E", -(int64_t)82*1024*1024*1024*1024*1024L, HN_DIVISOR_1000,  6, 6 },
238*e285e32eSBartek Rutkowski 	{ 4, "92 P", (int64_t)82*1024*1024*1024*1024*1024L, HN_DIVISOR_1000,  5, 6 },
239*e285e32eSBartek Rutkowski 	{ 5, "-92 P", -(int64_t)82*1024*1024*1024*1024*1024L, HN_DIVISOR_1000,  5, 6 },
240*e285e32eSBartek Rutkowski 	{ 4, "91 P", (int64_t)81*1024*1024*1024*1024*1024L, HN_DIVISOR_1000,  5, 6 },
241*e285e32eSBartek Rutkowski 	{ 5, "-91 P", -(int64_t)81*1024*1024*1024*1024*1024L, HN_DIVISOR_1000,  5, 6 },
2425aa45fcbSEnji Cooper 
2435aa45fcbSEnji Cooper 	/* Autoscale, divisor 1024 */
244*e285e32eSBartek Rutkowski 	{ 3, "8 E",   INT64_MAX, 0, HN_AUTOSCALE, 6 },
245*e285e32eSBartek Rutkowski 	{ 4, "-8 E", -INT64_MAX, 0, HN_AUTOSCALE, 6 },
246*e285e32eSBartek Rutkowski 	{ 4, "92 P", (int64_t)92*1024*1024*1024*1024*1024L, 0, HN_AUTOSCALE, 6 },
247*e285e32eSBartek Rutkowski 	{ 5, "-92 P", -(int64_t)92*1024*1024*1024*1024*1024L, 0, HN_AUTOSCALE, 6 },
248*e285e32eSBartek Rutkowski 	{ 4, "82 P", (int64_t)82*1024*1024*1024*1024*1024L, 0, HN_AUTOSCALE, 6 },
249*e285e32eSBartek Rutkowski 	{ 5, "-82 P", -(int64_t)82*1024*1024*1024*1024*1024L, 0, HN_AUTOSCALE, 6 },
250*e285e32eSBartek Rutkowski 	{ 4, "81 P", (int64_t)81*1024*1024*1024*1024*1024L, 0, HN_AUTOSCALE, 6 },
251*e285e32eSBartek Rutkowski 	{ 5, "-81 P", -(int64_t)81*1024*1024*1024*1024*1024L, 0, HN_AUTOSCALE, 6 },
2525aa45fcbSEnji Cooper 	/* Autoscale, divisor 1000 */
253*e285e32eSBartek Rutkowski 	{ 3, "9 E",   INT64_MAX, HN_DIVISOR_1000, HN_AUTOSCALE, 6 },
254*e285e32eSBartek Rutkowski 	{ 4, "-9 E", -INT64_MAX, HN_DIVISOR_1000, HN_AUTOSCALE, 6 },
255*e285e32eSBartek Rutkowski 	{ 4, "92 P", (int64_t)82*1024*1024*1024*1024*1024L, HN_DIVISOR_1000, HN_AUTOSCALE, 6 },
256*e285e32eSBartek Rutkowski 	{ 5, "-92 P", -(int64_t)82*1024*1024*1024*1024*1024L, HN_DIVISOR_1000, HN_AUTOSCALE, 6 },
257*e285e32eSBartek Rutkowski 	{ 4, "91 P", (int64_t)81*1024*1024*1024*1024*1024L, HN_DIVISOR_1000, HN_AUTOSCALE, 6 },
258*e285e32eSBartek Rutkowski 	{ 5, "-91 P", -(int64_t)81*1024*1024*1024*1024*1024L, HN_DIVISOR_1000, HN_AUTOSCALE, 6 },
2595aa45fcbSEnji Cooper 
2605aa45fcbSEnji Cooper 	/* 0 scale, divisor 1024 */
261*e285e32eSBartek Rutkowski 	{ 12, "skdj",  INT64_MAX, 0, 0, 6 },
262*e285e32eSBartek Rutkowski 	{ 21, "-9223", -INT64_MAX, 0, 0, 6 },
263*e285e32eSBartek Rutkowski 	{ 19, "10358", (int64_t)92*1024*1024*1024*1024*1024L, 0, 0, 6 },
264*e285e32eSBartek Rutkowski 	{ 20, "-1035", -(int64_t)92*1024*1024*1024*1024*1024L, 0, 0, 6 },
265*e285e32eSBartek Rutkowski 	{ 18, "92323", (int64_t)82*1024*1024*1024*1024*1024L, 0, 0, 6 },
266*e285e32eSBartek Rutkowski 	{ 19, "-9232", -(int64_t)82*1024*1024*1024*1024*1024L, 0, 0, 6 },
267*e285e32eSBartek Rutkowski 	{ 18, "91197", (int64_t)81*1024*1024*1024*1024*1024L, 0, 0, 6 },
268*e285e32eSBartek Rutkowski 	{ 19, "-9119", -(int64_t)81*1024*1024*1024*1024*1024L, 0, 0, 6 },
2695aa45fcbSEnji Cooper 
2705aa45fcbSEnji Cooper 	/* 0 scale, divisor 1000 */
2715aa45fcbSEnji Cooper 	/* XXX - why does this fail? */
272*e285e32eSBartek Rutkowski 	{ -1, "", INT64_MAX, HN_DIVISOR_1000, 0, 6 },
273*e285e32eSBartek Rutkowski 	{ 21, "-9223", -INT64_MAX, HN_DIVISOR_1000,  0, 6 },
274*e285e32eSBartek Rutkowski 	{ 19, "10358", (int64_t)92*1024*1024*1024*1024*1024L, HN_DIVISOR_1000,  0, 6 },
275*e285e32eSBartek Rutkowski 	{ 20, "-1035", -(int64_t)92*1024*1024*1024*1024*1024L, HN_DIVISOR_1000,  0, 6 },
276*e285e32eSBartek Rutkowski 	{ 18, "92323", (int64_t)82*1024*1024*1024*1024*1024L, HN_DIVISOR_1000,  0, 6 },
277*e285e32eSBartek Rutkowski 	{ 19, "-9232", -(int64_t)82*1024*1024*1024*1024*1024L, HN_DIVISOR_1000,  0, 6 },
2785aa45fcbSEnji Cooper 	/* Expected to pass */
279*e285e32eSBartek Rutkowski 	{ 18, "91197", (int64_t)81*1024*1024*1024*1024*1024L, HN_DIVISOR_1000,  0, 6 },
280*e285e32eSBartek Rutkowski 	{ 19, "-9119", -(int64_t)81*1024*1024*1024*1024*1024L, HN_DIVISOR_1000,  0, 6 },
2815aa45fcbSEnji Cooper 
2825aa45fcbSEnji Cooper 
2835aa45fcbSEnji Cooper 
2845aa45fcbSEnji Cooper 	/* Need to implement tests for GETSCALE */
285*e285e32eSBartek Rutkowski /*	{ ?, "", (int64_t)0L, HN_DIVISOR_1000, HN_GETSCALE, 6 },
2865aa45fcbSEnji Cooper 	...
2875aa45fcbSEnji Cooper */
2885aa45fcbSEnji Cooper         /* Tests for HN_DECIMAL */
2895aa45fcbSEnji Cooper         /* Positive, Autoscale */
290*e285e32eSBartek Rutkowski 	{ 5, "500 k", (int64_t)500*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE, 6 },
291*e285e32eSBartek Rutkowski 	{ 5, "994 k", (int64_t)994*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE, 6 },
292*e285e32eSBartek Rutkowski 	{ 5, "995 k", (int64_t)995*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE, 6 },
293*e285e32eSBartek Rutkowski 	{ 5, "999 k", (int64_t)999*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE, 6 },
294*e285e32eSBartek Rutkowski 	{ 5, "1.0 M", (int64_t)1000*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE, 6 },
295*e285e32eSBartek Rutkowski 	{ 5, "1.5 M", (int64_t)1500*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE, 6 },
296*e285e32eSBartek Rutkowski 	{ 5, "1.9 M", (int64_t)1949*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE, 6 },
297*e285e32eSBartek Rutkowski 	{ 5, "2.0 M", (int64_t)1950*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE, 6 },
298*e285e32eSBartek Rutkowski 	{ 5, "9.9 M", (int64_t)9949*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE, 6 },
299*e285e32eSBartek Rutkowski 	{ 4, "10 M", (int64_t)9950*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE, 6 },
300*e285e32eSBartek Rutkowski 	{ 5, "500 M", (int64_t)500*1000*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE, 6 },
301*e285e32eSBartek Rutkowski 	{ 5, "994 M", (int64_t)994*1000*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE, 6 },
302*e285e32eSBartek Rutkowski 	{ 5, "995 M", (int64_t)995*1000*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE, 6 },
303*e285e32eSBartek Rutkowski 	{ 5, "999 M", (int64_t)999*1000*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE, 6 },
3045aa45fcbSEnji Cooper 
305*e285e32eSBartek Rutkowski 	{ 5, "500 K", (int64_t)500*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 },
306*e285e32eSBartek Rutkowski 	{ 5, "994 K", (int64_t)994*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 },
307*e285e32eSBartek Rutkowski 	{ 5, "995 K", (int64_t)995*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 },
308*e285e32eSBartek Rutkowski 	{ 5, "999 K", (int64_t)999*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 },
309*e285e32eSBartek Rutkowski 	{ 5, "1.0 M", (int64_t)1000*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 },
310*e285e32eSBartek Rutkowski 	{ 5, "1.0 M", (int64_t)1018*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 },
311*e285e32eSBartek Rutkowski 	{ 5, "1.0 M", (int64_t)1019*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 },
312*e285e32eSBartek Rutkowski 	{ 5, "1.5 M", (int64_t)1536*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 },
313*e285e32eSBartek Rutkowski 	{ 5, "1.9 M", (int64_t)1996*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 },
314*e285e32eSBartek Rutkowski 	{ 5, "2.0 M", (int64_t)1997*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 },
315*e285e32eSBartek Rutkowski 	{ 5, "2.0 M", (int64_t)2047*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 },
316*e285e32eSBartek Rutkowski 	{ 5, "2.0 M", (int64_t)2048*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 },
317*e285e32eSBartek Rutkowski 	{ 5, "2.0 M", (int64_t)2099*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 },
318*e285e32eSBartek Rutkowski 	{ 5, "2.1 M", (int64_t)2100*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 },
319*e285e32eSBartek Rutkowski 	{ 5, "9.9 M", (int64_t)10188*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 },
3205aa45fcbSEnji Cooper 	/* XXX - shouldn't the following two be "10. M"? */
321*e285e32eSBartek Rutkowski 	{ 4, "10 M", (int64_t)10189*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 },
322*e285e32eSBartek Rutkowski 	{ 4, "10 M", (int64_t)10240*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 },
323*e285e32eSBartek Rutkowski 	{ 5, "500 M", (int64_t)500*1024*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 },
324*e285e32eSBartek Rutkowski 	{ 5, "994 M", (int64_t)994*1024*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 },
325*e285e32eSBartek Rutkowski 	{ 5, "995 M", (int64_t)995*1024*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 },
326*e285e32eSBartek Rutkowski 	{ 5, "999 M", (int64_t)999*1024*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 },
327*e285e32eSBartek Rutkowski 	{ 5, "1.0 G", (int64_t)1000*1024*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 },
328*e285e32eSBartek Rutkowski 	{ 5, "1.0 G", (int64_t)1023*1024*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 },
3295aa45fcbSEnji Cooper 
3305aa45fcbSEnji Cooper         /* Negative, Autoscale - should pass */
331*e285e32eSBartek Rutkowski 	{ 6, "-1.5 ", -(int64_t)1500*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE, 6 },
332*e285e32eSBartek Rutkowski 	{ 6, "-1.9 ", -(int64_t)1949*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE, 6 },
333*e285e32eSBartek Rutkowski 	{ 6, "-9.9 ", -(int64_t)9949*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE, 6 },
3345aa45fcbSEnji Cooper 
335*e285e32eSBartek Rutkowski 	{ 6, "-1.5 ", -(int64_t)1536*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 },
336*e285e32eSBartek Rutkowski 	{ 6, "-1.9 ", -(int64_t)1949*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 },
337*e285e32eSBartek Rutkowski 	{ 6, "-9.7 ", -(int64_t)9949*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 },
3385aa45fcbSEnji Cooper 
3395aa45fcbSEnji Cooper 	/* Positive/negative, at maximum scale */
340*e285e32eSBartek Rutkowski 	{ 5, "500 P", (int64_t)500*1000*1000*1000*1000*1000L, HN_DIVISOR_1000, HN_AUTOSCALE, 6 },
341*e285e32eSBartek Rutkowski 	{ 5, "1.9 E", (int64_t)1949*1000*1000*1000*1000*1000L, HN_DIVISOR_1000, HN_AUTOSCALE, 6 },
342*e285e32eSBartek Rutkowski 	{ 5, "8.9 E", (int64_t)8949*1000*1000*1000*1000*1000L, HN_DIVISOR_1000, HN_AUTOSCALE, 6 },
343*e285e32eSBartek Rutkowski 	{ 5, "9.2 E", INT64_MAX, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE, 6 },
3445aa45fcbSEnji Cooper         /* Negatives work with latest rev only: */
345*e285e32eSBartek Rutkowski 	{ 6, "-9.2 ", -INT64_MAX, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE, 6 },
346*e285e32eSBartek Rutkowski 	{ 6, "-8.9 ", -(int64_t)8949*1000*1000*1000*1000*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE, 6 },
3475aa45fcbSEnji Cooper 
348*e285e32eSBartek Rutkowski 	{ 5, "8.0 E",   INT64_MAX, HN_DECIMAL, HN_AUTOSCALE, 6 },
349*e285e32eSBartek Rutkowski 	{ 5, "7.9 E",   INT64_MAX-(int64_t)100*1024*1024*1024*1024*1024LL, HN_DECIMAL, HN_AUTOSCALE, 6 },
350*e285e32eSBartek Rutkowski 	{ 6, "-8.0 ", -INT64_MAX, HN_DECIMAL, HN_AUTOSCALE, 6 },
351*e285e32eSBartek Rutkowski 	{ 6, "-7.9 ",   -INT64_MAX+(int64_t)100*1024*1024*1024*1024*1024LL, HN_DECIMAL, HN_AUTOSCALE, 6 },
3525aa45fcbSEnji Cooper 
3535aa45fcbSEnji Cooper 	/* Positive, Fixed scales */
354*e285e32eSBartek Rutkowski 	{ 5, "500 k", (int64_t)500*1000L, HN_DECIMAL|HN_DIVISOR_1000, 1, 6 },
355*e285e32eSBartek Rutkowski 	{ 5, "0.5 M", (int64_t)500*1000L, HN_DECIMAL|HN_DIVISOR_1000, 2, 6 },
356*e285e32eSBartek Rutkowski 	{ 5, "949 k", (int64_t)949*1000L, HN_DECIMAL|HN_DIVISOR_1000, 1, 6 },
357*e285e32eSBartek Rutkowski 	{ 5, "0.9 M", (int64_t)949*1000L, HN_DECIMAL|HN_DIVISOR_1000, 2, 6 },
358*e285e32eSBartek Rutkowski 	{ 5, "950 k", (int64_t)950*1000L, HN_DECIMAL|HN_DIVISOR_1000, 1, 6 },
359*e285e32eSBartek Rutkowski 	{ 5, "1.0 M", (int64_t)950*1000L, HN_DECIMAL|HN_DIVISOR_1000, 2, 6 },
360*e285e32eSBartek Rutkowski 	{ 5, "999 k", (int64_t)999*1000L, HN_DECIMAL|HN_DIVISOR_1000, 1, 6 },
361*e285e32eSBartek Rutkowski 	{ 5, "1.0 M", (int64_t)999*1000L, HN_DECIMAL|HN_DIVISOR_1000, 2, 6 },
362*e285e32eSBartek Rutkowski 	{ 5, "1.5 M", (int64_t)1500*1000L, HN_DECIMAL|HN_DIVISOR_1000, 2, 6 },
363*e285e32eSBartek Rutkowski 	{ 5, "1.9 M", (int64_t)1949*1000L, HN_DECIMAL|HN_DIVISOR_1000, 2, 6 },
364*e285e32eSBartek Rutkowski 	{ 5, "2.0 M", (int64_t)1950*1000L, HN_DECIMAL|HN_DIVISOR_1000, 2, 6 },
365*e285e32eSBartek Rutkowski 	{ 5, "9.9 M", (int64_t)9949*1000L, HN_DECIMAL|HN_DIVISOR_1000, 2, 6 },
366*e285e32eSBartek Rutkowski 	{ 4, "10 M", (int64_t)9950*1000L, HN_DECIMAL|HN_DIVISOR_1000, 2, 6 },
367*e285e32eSBartek Rutkowski 	{ 5, "500 M", (int64_t)500*1000*1000L, HN_DECIMAL|HN_DIVISOR_1000, 2, 6 },
368*e285e32eSBartek Rutkowski 	{ 5, "0.5 G", (int64_t)500*1000*1000L, HN_DECIMAL|HN_DIVISOR_1000, 3, 6 },
369*e285e32eSBartek Rutkowski 	{ 5, "999 M", (int64_t)999*1000*1000L, HN_DECIMAL|HN_DIVISOR_1000, 2, 6 },
370*e285e32eSBartek Rutkowski 	{ 5, "1.0 G", (int64_t)999*1000*1000L, HN_DECIMAL|HN_DIVISOR_1000, 3, 6 },
3715aa45fcbSEnji Cooper 	/* Positive/negative, at maximum scale */
372*e285e32eSBartek Rutkowski 	{ 5, "500 P", (int64_t)500*1000*1000*1000*1000*1000L, HN_DIVISOR_1000, 5, 6 },
373*e285e32eSBartek Rutkowski 	{ 5, "1.0 E", (int64_t)500*1000*1000*1000*1000*1000L, HN_DIVISOR_1000, 6, 6 },
374*e285e32eSBartek Rutkowski 	{ 5, "1.9 E", (int64_t)1949*1000*1000*1000*1000*1000L, HN_DIVISOR_1000, 6, 6 },
375*e285e32eSBartek Rutkowski 	{ 5, "8.9 E", (int64_t)8949*1000*1000*1000*1000*1000L, HN_DIVISOR_1000, 6, 6 },
376*e285e32eSBartek Rutkowski 	{ 5, "9.2 E", INT64_MAX, HN_DECIMAL|HN_DIVISOR_1000, 6, 6 },
3775aa45fcbSEnji Cooper 
3785aa45fcbSEnji Cooper 	/* HN_DECIMAL + binary + fixed scale cases not completed */
379*e285e32eSBartek Rutkowski 	{ 5, "512 K", (int64_t)512*1024L, HN_DECIMAL, 1, 6 },
380*e285e32eSBartek Rutkowski 	{ 5, "0.5 M", (int64_t)512*1024L, HN_DECIMAL, 2, 6 },
3815aa45fcbSEnji Cooper 
3825aa45fcbSEnji Cooper 	/* Negative, Fixed scales */
3835aa45fcbSEnji Cooper         /* Not yet added, but should work with latest rev */
3845aa45fcbSEnji Cooper 
3855aa45fcbSEnji Cooper };
3865aa45fcbSEnji Cooper 
3875aa45fcbSEnji Cooper 
3885aa45fcbSEnji Cooper /* Command line options usage */
3895aa45fcbSEnji Cooper static void
usage(char * progname)3905aa45fcbSEnji Cooper usage(char * progname) {
3915aa45fcbSEnji Cooper 	printf("%s: tests libutil humanize_number function\n", progname);
3925aa45fcbSEnji Cooper 	printf("Usage: %s [-nE] [-l num] [-v]\n\n", progname);
3935aa45fcbSEnji Cooper 	printf("Options:\n");
3945aa45fcbSEnji Cooper 	printf("\t-l num\tSet max length for result; buflen = num + 1\n");
3955aa45fcbSEnji Cooper 	printf("\t\t  (NOTE: does not change expected result strings.)\n");
3965aa45fcbSEnji Cooper 	printf("\t-n\tInclude negative scale tests, which cause older libutil\n");
3975aa45fcbSEnji Cooper 	printf("\t\t  version of function to coredump with assertion failure\n");
3985aa45fcbSEnji Cooper 	printf("\t-E\tInclude numbers > 1/2 Exa[byte] which currently fail\n");
3995aa45fcbSEnji Cooper 	printf("\t-v\tVerbose - always print summary results\n");
4005aa45fcbSEnji Cooper 	printf("\t-h, -?\tShow options\n");
4015aa45fcbSEnji Cooper }
4025aa45fcbSEnji Cooper 
4035aa45fcbSEnji Cooper /* Parse command line options */
4045aa45fcbSEnji Cooper static void
read_options(int argc,char * const argv[],size_t * bufLength,int * includeNegativeScale,int * includeExabytes,int * verbose)4055aa45fcbSEnji Cooper read_options(int argc, char * const argv[], size_t *bufLength,
4065aa45fcbSEnji Cooper     int *includeNegativeScale, int *includeExabytes, int *verbose) {
4075aa45fcbSEnji Cooper 	int ch;
4085aa45fcbSEnji Cooper 	size_t temp;
4095aa45fcbSEnji Cooper 
4105aa45fcbSEnji Cooper 	while ((ch = getopt(argc, argv, "nEh?vl:")) != -1) {
4115aa45fcbSEnji Cooper 		switch (ch) {
4125aa45fcbSEnji Cooper 			default:
4135aa45fcbSEnji Cooper 				usage(argv[0]);
4145aa45fcbSEnji Cooper 				exit(1);
4155aa45fcbSEnji Cooper 				break;	/* UNREACHABLE */
4165aa45fcbSEnji Cooper 			case 'h' :
4175aa45fcbSEnji Cooper 			case '?' :
4185aa45fcbSEnji Cooper 				usage(argv[0]);
4195aa45fcbSEnji Cooper 				exit(0);
4205aa45fcbSEnji Cooper 				break;	/* UNREACHABLE */
4215aa45fcbSEnji Cooper 			case 'l' :
4225aa45fcbSEnji Cooper 				sscanf(optarg, "%zu", &temp);
4235aa45fcbSEnji Cooper 				*bufLength = temp + 1;
4245aa45fcbSEnji Cooper 				break;
4255aa45fcbSEnji Cooper 			case 'n' :
4265aa45fcbSEnji Cooper 				*includeNegativeScale = 1;
4275aa45fcbSEnji Cooper 				break;
4285aa45fcbSEnji Cooper 			case 'E' :
4295aa45fcbSEnji Cooper 				*includeExabytes = 1;
4305aa45fcbSEnji Cooper 				break;
4315aa45fcbSEnji Cooper 			case 'v' :
4325aa45fcbSEnji Cooper 				*verbose = 1;
4335aa45fcbSEnji Cooper 				break;
4345aa45fcbSEnji Cooper 		}
4355aa45fcbSEnji Cooper 	}
4365aa45fcbSEnji Cooper }
4375aa45fcbSEnji Cooper 
4385aa45fcbSEnji Cooper static struct {
4395aa45fcbSEnji Cooper 	int value;
4405aa45fcbSEnji Cooper 	const char *name;
4415aa45fcbSEnji Cooper  } flags[] = {
4425aa45fcbSEnji Cooper 	{ HN_AUTOSCALE, "HN_AUTOSCALE" },
4435aa45fcbSEnji Cooper 	{ HN_GETSCALE, "HN_GETSCALE" },
4445aa45fcbSEnji Cooper 	{ HN_DIVISOR_1000, "HN_DIVISOR_1000" },
4455aa45fcbSEnji Cooper 	{ HN_B, "HN_B" },
4465aa45fcbSEnji Cooper 	{ HN_DECIMAL, "HN_DECIMAL" },
4475aa45fcbSEnji Cooper };
4485aa45fcbSEnji Cooper 
4495aa45fcbSEnji Cooper static const char *separator = "|";
4505aa45fcbSEnji Cooper 
4515aa45fcbSEnji Cooper /* Format flags parameter for meaningful display */
4525aa45fcbSEnji Cooper static char *
str_flags(int hn_flags,char * noFlags)4535aa45fcbSEnji Cooper str_flags(int hn_flags, char *noFlags) {
4545aa45fcbSEnji Cooper 	size_t i;
4555aa45fcbSEnji Cooper 	char * result;
4565aa45fcbSEnji Cooper 
4575aa45fcbSEnji Cooper 	result = malloc(MAX_STR_FLAGS_RESULT);
4585aa45fcbSEnji Cooper 	result[0] = '\0';
4595aa45fcbSEnji Cooper 
4605aa45fcbSEnji Cooper 	for (i = 0; i < sizeof flags / sizeof *flags; i++) {
4615aa45fcbSEnji Cooper 		if (hn_flags & flags[i].value) {
4625aa45fcbSEnji Cooper 			if (*result != 0)
4635aa45fcbSEnji Cooper 				strlcat(result, separator,
4645aa45fcbSEnji Cooper 				    MAX_STR_FLAGS_RESULT);
4655aa45fcbSEnji Cooper 			strlcat(result, flags[i].name, MAX_STR_FLAGS_RESULT);
4665aa45fcbSEnji Cooper 		}
4675aa45fcbSEnji Cooper 	}
4685aa45fcbSEnji Cooper 
4695aa45fcbSEnji Cooper 	if (strlen(result) == 0)
4705aa45fcbSEnji Cooper 		strlcat(result, noFlags, MAX_STR_FLAGS_RESULT);
4715aa45fcbSEnji Cooper 	return result;
4725aa45fcbSEnji Cooper }
4735aa45fcbSEnji Cooper 
4745aa45fcbSEnji Cooper 
4755aa45fcbSEnji Cooper /* Format scale parameter for meaningful display */
4765aa45fcbSEnji Cooper static char *
str_scale(int scale)4775aa45fcbSEnji Cooper str_scale(int scale) {
4785aa45fcbSEnji Cooper 	char *result;
4795aa45fcbSEnji Cooper 
4805aa45fcbSEnji Cooper 	if (scale == HN_AUTOSCALE || scale == HN_GETSCALE)
4815aa45fcbSEnji Cooper 		return str_flags(scale, "");
4825aa45fcbSEnji Cooper 
4835aa45fcbSEnji Cooper 	result = malloc(MAX_INT_STR_DIGITS);
4845aa45fcbSEnji Cooper 	result[0] = '\0';
4855aa45fcbSEnji Cooper 	snprintf(result, MAX_INT_STR_DIGITS, "%d", scale);
4865aa45fcbSEnji Cooper 	return result;
4875aa45fcbSEnji Cooper }
4885aa45fcbSEnji Cooper 
4895aa45fcbSEnji Cooper static void
testskipped(size_t i)4905aa45fcbSEnji Cooper testskipped(size_t i)
4915aa45fcbSEnji Cooper {
4925aa45fcbSEnji Cooper 
4935aa45fcbSEnji Cooper 	printf("ok %zu # skip - not turned on\n", i);
4945aa45fcbSEnji Cooper }
4955aa45fcbSEnji Cooper 
4965aa45fcbSEnji Cooper int
main(int argc,char * const argv[])4975aa45fcbSEnji Cooper main(int argc, char * const argv[])
4985aa45fcbSEnji Cooper {
4995aa45fcbSEnji Cooper 	char *buf;
5005aa45fcbSEnji Cooper 	char *flag_str, *scale_str;
501*e285e32eSBartek Rutkowski 	size_t blen, buflen, errcnt, i, skipped, tested;
5025aa45fcbSEnji Cooper 	int r;
5035aa45fcbSEnji Cooper 	int includeNegScale;
5045aa45fcbSEnji Cooper 	int includeExabyteTests;
5055aa45fcbSEnji Cooper 	int verbose;
5065aa45fcbSEnji Cooper 
507*e285e32eSBartek Rutkowski 	buf = NULL;
508*e285e32eSBartek Rutkowski 	buflen = 0;
5095aa45fcbSEnji Cooper 	includeNegScale = 0;
5105aa45fcbSEnji Cooper 	includeExabyteTests = 0;
5115aa45fcbSEnji Cooper 	verbose = 0;
5125aa45fcbSEnji Cooper 
5135aa45fcbSEnji Cooper 	read_options(argc, argv, &buflen, &includeNegScale,
5145aa45fcbSEnji Cooper 	    &includeExabyteTests, &verbose);
5155aa45fcbSEnji Cooper 
5165aa45fcbSEnji Cooper 	errcnt = 0;
5175aa45fcbSEnji Cooper 	tested = 0;
5185aa45fcbSEnji Cooper 	skipped = 0;
5195aa45fcbSEnji Cooper 
5205aa45fcbSEnji Cooper 	if (buflen != 4)
5215aa45fcbSEnji Cooper 		printf("Warning: buffer size %zu != 4, expect some results to differ.\n", buflen);
5225aa45fcbSEnji Cooper 
5235aa45fcbSEnji Cooper 	printf("1..%zu\n", nitems(test_args));
5245aa45fcbSEnji Cooper 	for (i = 0; i < nitems(test_args); i++) {
525*e285e32eSBartek Rutkowski 		blen = (buflen > 0) ? buflen : test_args[i].buflen;
526*e285e32eSBartek Rutkowski 		buf = realloc(buf, blen);
5275aa45fcbSEnji Cooper 
5285aa45fcbSEnji Cooper 		if (test_args[i].scale < 0 && ! includeNegScale) {
5295aa45fcbSEnji Cooper 			skipped++;
5305aa45fcbSEnji Cooper 			testskipped(i + 1);
5315aa45fcbSEnji Cooper 			continue;
5325aa45fcbSEnji Cooper 		}
5335aa45fcbSEnji Cooper 		if (test_args[i].num >= halfExabyte && ! includeExabyteTests) {
5345aa45fcbSEnji Cooper 			skipped++;
5355aa45fcbSEnji Cooper 			testskipped(i + 1);
5365aa45fcbSEnji Cooper 			continue;
5375aa45fcbSEnji Cooper 		}
5385aa45fcbSEnji Cooper 
539*e285e32eSBartek Rutkowski 		r = humanize_number(buf, blen, test_args[i].num, "",
5405aa45fcbSEnji Cooper 		    test_args[i].scale, test_args[i].flags);
5415aa45fcbSEnji Cooper 		flag_str = str_flags(test_args[i].flags, "[no flags]");
5425aa45fcbSEnji Cooper 		scale_str = str_scale(test_args[i].scale);
5435aa45fcbSEnji Cooper 
5445aa45fcbSEnji Cooper 		if (r != test_args[i].retval) {
5455aa45fcbSEnji Cooper 			if (verbose)
5465aa45fcbSEnji Cooper 				printf("wrong return value on index %zu, "
5475aa45fcbSEnji Cooper 				    "buflen: %zu, got: %d + \"%s\", "
5485aa45fcbSEnji Cooper 				    "expected %d + \"%s\"; num = %jd, "
5495aa45fcbSEnji Cooper 				    "scale = %s, flags= %s.\n",
550*e285e32eSBartek Rutkowski 				    i, blen, r, buf, test_args[i].retval,
5515aa45fcbSEnji Cooper 				    test_args[i].res,
5525aa45fcbSEnji Cooper 				    (intmax_t)test_args[i].num,
5535aa45fcbSEnji Cooper 				    scale_str, flag_str);
5545aa45fcbSEnji Cooper 			else
5555aa45fcbSEnji Cooper 				printf("not ok %zu # return %d != %d\n",
5565aa45fcbSEnji Cooper 				    i + 1, r, test_args[i].retval);
5575aa45fcbSEnji Cooper 			errcnt++;
5585aa45fcbSEnji Cooper 		} else if (strcmp(buf, test_args[i].res) != 0) {
5595aa45fcbSEnji Cooper 			if (verbose)
5605aa45fcbSEnji Cooper 				printf("result mismatch on index %zu, got: "
5615aa45fcbSEnji Cooper 				    "\"%s\", expected \"%s\"; num = %jd, "
562*e285e32eSBartek Rutkowski 				    "buflen: %zu, scale = %s, flags= %s.\n",
5635aa45fcbSEnji Cooper 				    i, buf, test_args[i].res,
5645aa45fcbSEnji Cooper 				    (intmax_t)test_args[i].num,
565*e285e32eSBartek Rutkowski 				    blen, scale_str, flag_str);
5665aa45fcbSEnji Cooper 			else
5675aa45fcbSEnji Cooper 				printf("not ok %zu # buf \"%s\" != \"%s\"\n",
5685aa45fcbSEnji Cooper 				    i + 1, buf, test_args[i].res);
5695aa45fcbSEnji Cooper 			errcnt++;
5705aa45fcbSEnji Cooper 		} else {
5715aa45fcbSEnji Cooper 			if (verbose)
5725aa45fcbSEnji Cooper 				printf("successful result on index %zu, "
5735aa45fcbSEnji Cooper 				    "returned %d, got: \"%s\"; num = %jd, "
574*e285e32eSBartek Rutkowski 				    "buflen = %zd, scale = %s, flags= %s.\n",
575*e285e32eSBartek Rutkowski 				    i, r, buf, (intmax_t)test_args[i].num,
576*e285e32eSBartek Rutkowski 				    blen, scale_str, flag_str);
5775aa45fcbSEnji Cooper 			else
5785aa45fcbSEnji Cooper 				printf("ok %zu\n", i + 1);
5795aa45fcbSEnji Cooper 		}
5805aa45fcbSEnji Cooper 		tested++;
5815aa45fcbSEnji Cooper 	}
582*e285e32eSBartek Rutkowski 	free(buf);
5835aa45fcbSEnji Cooper 
5845aa45fcbSEnji Cooper 	if (verbose)
5855aa45fcbSEnji Cooper 		printf("total errors: %zu/%zu tests, %zu skipped\n", errcnt,
5865aa45fcbSEnji Cooper 		    tested, skipped);
5875aa45fcbSEnji Cooper 
5885aa45fcbSEnji Cooper 	if (errcnt)
5895aa45fcbSEnji Cooper 		return 1;
5905aa45fcbSEnji Cooper 
5915aa45fcbSEnji Cooper 	return 0;
5925aa45fcbSEnji Cooper }
593