xref: /freebsd/lib/libutil/tests/humanize_number_test.c (revision 5aa45fcb67c077ac3bd7627d49499b3234c01e7c)
1*5aa45fcbSEnji Cooper /*-
2*5aa45fcbSEnji Cooper  * Copyright 2012 Clifton Royston
3*5aa45fcbSEnji Cooper  * Copyright 2013 John-Mark Gurney
4*5aa45fcbSEnji Cooper  * All rights reserved.
5*5aa45fcbSEnji Cooper  *
6*5aa45fcbSEnji Cooper  * Redistribution and use in source and binary forms, with or without
7*5aa45fcbSEnji Cooper  * modification, are permitted provided that the following conditions
8*5aa45fcbSEnji Cooper  * are met:
9*5aa45fcbSEnji Cooper  * 1. Redistributions of source code must retain the above copyright
10*5aa45fcbSEnji Cooper  *    notice, this list of conditions and the following disclaimer.
11*5aa45fcbSEnji Cooper  * 2. Redistributions in binary form must reproduce the above copyright
12*5aa45fcbSEnji Cooper  *    notice, this list of conditions and the following disclaimer in the
13*5aa45fcbSEnji Cooper  *    documentation and/or other materials provided with the distribution.
14*5aa45fcbSEnji Cooper  *
15*5aa45fcbSEnji Cooper  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16*5aa45fcbSEnji Cooper  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17*5aa45fcbSEnji Cooper  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18*5aa45fcbSEnji Cooper  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19*5aa45fcbSEnji Cooper  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20*5aa45fcbSEnji Cooper  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21*5aa45fcbSEnji Cooper  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22*5aa45fcbSEnji Cooper  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23*5aa45fcbSEnji Cooper  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24*5aa45fcbSEnji Cooper  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25*5aa45fcbSEnji Cooper  * SUCH DAMAGE.
26*5aa45fcbSEnji Cooper  *
27*5aa45fcbSEnji Cooper  * $FreeBSD$
28*5aa45fcbSEnji Cooper  *
29*5aa45fcbSEnji Cooper  */
30*5aa45fcbSEnji Cooper 
31*5aa45fcbSEnji Cooper #include <sys/param.h>
32*5aa45fcbSEnji Cooper #include <inttypes.h>
33*5aa45fcbSEnji Cooper #include <libutil.h>
34*5aa45fcbSEnji Cooper #include <limits.h>
35*5aa45fcbSEnji Cooper #include <math.h>
36*5aa45fcbSEnji Cooper #include <stdio.h>
37*5aa45fcbSEnji Cooper #include <stdlib.h>
38*5aa45fcbSEnji Cooper #include <string.h>
39*5aa45fcbSEnji Cooper #include <unistd.h>
40*5aa45fcbSEnji Cooper 
41*5aa45fcbSEnji Cooper #define	MAX_STR_FLAGS_RESULT	80
42*5aa45fcbSEnji Cooper #define MAX_INT_STR_DIGITS	12
43*5aa45fcbSEnji Cooper 
44*5aa45fcbSEnji Cooper static const int64_t halfExabyte = (int64_t)500*1000*1000*1000*1000*1000L;
45*5aa45fcbSEnji Cooper 
46*5aa45fcbSEnji Cooper static struct {
47*5aa45fcbSEnji Cooper 	int retval;
48*5aa45fcbSEnji Cooper 	const char *res;
49*5aa45fcbSEnji Cooper 	int64_t num;
50*5aa45fcbSEnji Cooper 	int flags;
51*5aa45fcbSEnji Cooper 	int scale;
52*5aa45fcbSEnji Cooper } test_args[] = {
53*5aa45fcbSEnji Cooper 	/* tests 0-13 test 1000 suffixes */
54*5aa45fcbSEnji Cooper 	{ 2, "0 ", (int64_t)0L, HN_DIVISOR_1000, HN_AUTOSCALE },
55*5aa45fcbSEnji Cooper 	{ 3, "1 k", (int64_t)500L, HN_DIVISOR_1000, HN_AUTOSCALE },
56*5aa45fcbSEnji Cooper 	{ 3, "1 M", (int64_t)500*1000L, HN_DIVISOR_1000, HN_AUTOSCALE },
57*5aa45fcbSEnji Cooper 	{ 3, "1 G", (int64_t)500*1000*1000L, HN_DIVISOR_1000, HN_AUTOSCALE },
58*5aa45fcbSEnji Cooper 	{ 3, "1 T", (int64_t)500*1000*1000*1000L, HN_DIVISOR_1000, HN_AUTOSCALE },
59*5aa45fcbSEnji Cooper 	{ 3, "1 P", (int64_t)500*1000*1000*1000*1000L, HN_DIVISOR_1000, HN_AUTOSCALE },
60*5aa45fcbSEnji Cooper 	{ 3, "1 E", (int64_t)500*1000*1000*1000*1000*1000L, HN_DIVISOR_1000, HN_AUTOSCALE },
61*5aa45fcbSEnji Cooper 	{ 2, "1 ", (int64_t)1L, HN_DIVISOR_1000, HN_AUTOSCALE },
62*5aa45fcbSEnji Cooper 	{ 3, "2 k", (int64_t)1500L, HN_DIVISOR_1000, HN_AUTOSCALE },
63*5aa45fcbSEnji Cooper 	{ 3, "2 M", (int64_t)1500*1000L, HN_DIVISOR_1000, HN_AUTOSCALE },
64*5aa45fcbSEnji Cooper 	{ 3, "2 G", (int64_t)1500*1000*1000L, HN_DIVISOR_1000, HN_AUTOSCALE },
65*5aa45fcbSEnji Cooper 	{ 3, "2 T", (int64_t)1500*1000*1000*1000L, HN_DIVISOR_1000, HN_AUTOSCALE },
66*5aa45fcbSEnji Cooper 	{ 3, "2 P", (int64_t)1500*1000*1000*1000*1000L, HN_DIVISOR_1000, HN_AUTOSCALE },
67*5aa45fcbSEnji Cooper 	{ 3, "2 E", (int64_t)1500*1000*1000*1000*1000*1000L, HN_DIVISOR_1000, HN_AUTOSCALE },
68*5aa45fcbSEnji Cooper 
69*5aa45fcbSEnji Cooper 	/* tests 14-27 test 1024 suffixes */
70*5aa45fcbSEnji Cooper 	{ 2, "0 ", (int64_t)0L, 0, HN_AUTOSCALE },
71*5aa45fcbSEnji Cooper 	{ 3, "1 K", (int64_t)512L, 0, HN_AUTOSCALE },
72*5aa45fcbSEnji Cooper 	{ 3, "1 M", (int64_t)512*1024L, 0, HN_AUTOSCALE },
73*5aa45fcbSEnji Cooper 	{ 3, "1 G", (int64_t)512*1024*1024L, 0, HN_AUTOSCALE },
74*5aa45fcbSEnji Cooper 	{ 3, "1 T", (int64_t)512*1024*1024*1024L, 0, HN_AUTOSCALE },
75*5aa45fcbSEnji Cooper 	{ 3, "1 P", (int64_t)512*1024*1024*1024*1024L, 0, HN_AUTOSCALE },
76*5aa45fcbSEnji Cooper 	{ 3, "1 E", (int64_t)512*1024*1024*1024*1024*1024L, 0, HN_AUTOSCALE },
77*5aa45fcbSEnji Cooper 	{ 2, "1 ", (int64_t)1L, 0, HN_AUTOSCALE },
78*5aa45fcbSEnji Cooper 	{ 3, "2 K", (int64_t)1536L, 0, HN_AUTOSCALE },
79*5aa45fcbSEnji Cooper 	{ 3, "2 M", (int64_t)1536*1024L, 0, HN_AUTOSCALE },
80*5aa45fcbSEnji Cooper 	{ 3, "2 G", (int64_t)1536*1024*1024L, 0, HN_AUTOSCALE },
81*5aa45fcbSEnji Cooper 	{ 3, "2 T", (int64_t)1536*1024*1024*1024L, 0, HN_AUTOSCALE },
82*5aa45fcbSEnji Cooper 	{ 3, "2 P", (int64_t)1536*1024*1024*1024*1024L, 0, HN_AUTOSCALE },
83*5aa45fcbSEnji Cooper 	{ 3, "2 E", (int64_t)1536*1024*1024*1024*1024*1024L, 0, HN_AUTOSCALE },
84*5aa45fcbSEnji Cooper 
85*5aa45fcbSEnji Cooper 	/* tests 28-37 test rounding */
86*5aa45fcbSEnji Cooper 	{ 3, "0 M", (int64_t)500*1000L-1, HN_DIVISOR_1000, HN_AUTOSCALE },
87*5aa45fcbSEnji Cooper 	{ 3, "1 M", (int64_t)500*1000L, HN_DIVISOR_1000, HN_AUTOSCALE },
88*5aa45fcbSEnji Cooper 	{ 3, "1 M", (int64_t)1000*1000L + 500*1000L-1, HN_DIVISOR_1000, HN_AUTOSCALE },
89*5aa45fcbSEnji Cooper 	{ 3, "2 M", (int64_t)1000*1000L + 500*1000L, HN_DIVISOR_1000, HN_AUTOSCALE },
90*5aa45fcbSEnji Cooper 	{ 3, "0 K", (int64_t)512L-1, 0, HN_AUTOSCALE },
91*5aa45fcbSEnji Cooper 	{ 3, "1 K", (int64_t)512L, 0, HN_AUTOSCALE },
92*5aa45fcbSEnji Cooper 	{ 3, "0 M", (int64_t)512*1024L-1, 0, HN_AUTOSCALE },
93*5aa45fcbSEnji Cooper 	{ 3, "1 M", (int64_t)512*1024L, 0, HN_AUTOSCALE },
94*5aa45fcbSEnji Cooper 	{ 3, "1 M", (int64_t)1024*1024L + 512*1024L-1, 0, HN_AUTOSCALE },
95*5aa45fcbSEnji Cooper 	{ 3, "2 M", (int64_t)1024*1024L + 512*1024L, 0, HN_AUTOSCALE },
96*5aa45fcbSEnji Cooper 
97*5aa45fcbSEnji Cooper 	/* tests 38-61 test specific scale factors with 1000 divisor */
98*5aa45fcbSEnji Cooper 	{ 3, "0 k", (int64_t)0L, HN_DIVISOR_1000, 1 },
99*5aa45fcbSEnji Cooper 	{ 3, "1 k", (int64_t)500L, HN_DIVISOR_1000, 1 },
100*5aa45fcbSEnji Cooper 	{ 3, "0 M", (int64_t)500L, HN_DIVISOR_1000, 2 },
101*5aa45fcbSEnji Cooper 	{ 3, "1 M", (int64_t)500*1000L, HN_DIVISOR_1000, 2 },
102*5aa45fcbSEnji Cooper 	{ 3, "0 G", (int64_t)500*1000L, HN_DIVISOR_1000, 3 },
103*5aa45fcbSEnji Cooper 	{ 3, "1 G", (int64_t)500*1000*1000L, HN_DIVISOR_1000, 3 },
104*5aa45fcbSEnji Cooper 	{ 3, "0 T", (int64_t)500*1000*1000L, HN_DIVISOR_1000, 4 },
105*5aa45fcbSEnji Cooper 	{ 3, "1 T", (int64_t)500*1000*1000*1000L, HN_DIVISOR_1000, 4 },
106*5aa45fcbSEnji Cooper 	{ 3, "0 P", (int64_t)500*1000*1000*1000L, HN_DIVISOR_1000, 5 },
107*5aa45fcbSEnji Cooper 	{ 3, "1 P", (int64_t)500*1000*1000*1000*1000L, HN_DIVISOR_1000, 5 },
108*5aa45fcbSEnji Cooper 	{ 3, "0 E", (int64_t)500*1000*1000*1000*1000L, HN_DIVISOR_1000, 6 },
109*5aa45fcbSEnji Cooper 	{ 3, "1 E", (int64_t)500*1000*1000*1000*1000*1000L, HN_DIVISOR_1000, 6 },
110*5aa45fcbSEnji Cooper 	{ 3, "0 k", (int64_t)1L, HN_DIVISOR_1000, 1 },
111*5aa45fcbSEnji Cooper 	{ 3, "2 k", (int64_t)1500L, HN_DIVISOR_1000, 1 },
112*5aa45fcbSEnji Cooper 	{ 3, "0 M", (int64_t)1500L, HN_DIVISOR_1000, 2 },
113*5aa45fcbSEnji Cooper 	{ 3, "2 M", (int64_t)1500*1000L, HN_DIVISOR_1000, 2 },
114*5aa45fcbSEnji Cooper 	{ 3, "0 G", (int64_t)1500*1000L, HN_DIVISOR_1000, 3 },
115*5aa45fcbSEnji Cooper 	{ 3, "2 G", (int64_t)1500*1000*1000L, HN_DIVISOR_1000, 3 },
116*5aa45fcbSEnji Cooper 	{ 3, "0 T", (int64_t)1500*1000*1000L, HN_DIVISOR_1000, 4 },
117*5aa45fcbSEnji Cooper 	{ 3, "2 T", (int64_t)1500*1000*1000*1000L, HN_DIVISOR_1000, 4 },
118*5aa45fcbSEnji Cooper 	{ 3, "0 P", (int64_t)1500*1000*1000*1000L, HN_DIVISOR_1000, 5 },
119*5aa45fcbSEnji Cooper 	{ 3, "2 P", (int64_t)1500*1000*1000*1000*1000L, HN_DIVISOR_1000, 5 },
120*5aa45fcbSEnji Cooper 	{ 3, "0 E", (int64_t)1500*1000*1000*1000*1000L, HN_DIVISOR_1000, 6 },
121*5aa45fcbSEnji Cooper 	{ 3, "2 E", (int64_t)1500*1000*1000*1000*1000*1000L, HN_DIVISOR_1000, 6 },
122*5aa45fcbSEnji Cooper 
123*5aa45fcbSEnji Cooper 	/* tests 62-85 test specific scale factors with 1024 divisor */
124*5aa45fcbSEnji Cooper 	{ 3, "0 K", (int64_t)0L, 0, 1 },
125*5aa45fcbSEnji Cooper 	{ 3, "1 K", (int64_t)512L, 0, 1 },
126*5aa45fcbSEnji Cooper 	{ 3, "0 M", (int64_t)512L, 0, 2 },
127*5aa45fcbSEnji Cooper 	{ 3, "1 M", (int64_t)512*1024L, 0, 2 },
128*5aa45fcbSEnji Cooper 	{ 3, "0 G", (int64_t)512*1024L, 0, 3 },
129*5aa45fcbSEnji Cooper 	{ 3, "1 G", (int64_t)512*1024*1024L, 0, 3 },
130*5aa45fcbSEnji Cooper 	{ 3, "0 T", (int64_t)512*1024*1024L, 0, 4 },
131*5aa45fcbSEnji Cooper 	{ 3, "1 T", (int64_t)512*1024*1024*1024L, 0, 4 },
132*5aa45fcbSEnji Cooper 	{ 3, "0 P", (int64_t)512*1024*1024*1024L, 0, 5 },
133*5aa45fcbSEnji Cooper 	{ 3, "1 P", (int64_t)512*1024*1024*1024*1024L, 0, 5 },
134*5aa45fcbSEnji Cooper 	{ 3, "0 E", (int64_t)512*1024*1024*1024*1024L, 0, 6 },
135*5aa45fcbSEnji Cooper 	{ 3, "1 E", (int64_t)512*1024*1024*1024*1024*1024L, 0, 6 },
136*5aa45fcbSEnji Cooper 	{ 3, "0 K", (int64_t)1L, 0, 1 },
137*5aa45fcbSEnji Cooper 	{ 3, "2 K", (int64_t)1536L, 0, 1 },
138*5aa45fcbSEnji Cooper 	{ 3, "0 M", (int64_t)1536L, 0, 2 },
139*5aa45fcbSEnji Cooper 	{ 3, "2 M", (int64_t)1536*1024L, 0, 2 },
140*5aa45fcbSEnji Cooper 	{ 3, "0 G", (int64_t)1536*1024L, 0, 3 },
141*5aa45fcbSEnji Cooper 	{ 3, "2 G", (int64_t)1536*1024*1024L, 0, 3 },
142*5aa45fcbSEnji Cooper 	{ 3, "0 T", (int64_t)1536*1024*1024L, 0, 4 },
143*5aa45fcbSEnji Cooper 	{ 3, "2 T", (int64_t)1536*1024*1024*1024L, 0, 4 },
144*5aa45fcbSEnji Cooper 	{ 3, "0 P", (int64_t)1536*1024*1024*1024L, 0, 5 },
145*5aa45fcbSEnji Cooper 	{ 3, "2 P", (int64_t)1536*1024*1024*1024*1024L, 0, 5 },
146*5aa45fcbSEnji Cooper 	{ 3, "0 E", (int64_t)1536*1024*1024*1024*1024L, 0, 6 },
147*5aa45fcbSEnji Cooper 	{ 3, "2 E", (int64_t)1536*1024*1024*1024*1024*1024L, 0, 6 },
148*5aa45fcbSEnji Cooper 
149*5aa45fcbSEnji Cooper 	/* tests 86-99 test invalid specific scale values of < 0 or >= 7 with
150*5aa45fcbSEnji Cooper 	and without HN_DIVISOR_1000 set */
151*5aa45fcbSEnji Cooper 	/*  all should return errors with new code; with old, the latter 3
152*5aa45fcbSEnji Cooper 	are instead processed as if having AUTOSCALE and/or GETSCALE set */
153*5aa45fcbSEnji Cooper 	{ -1, "", (int64_t)1L, 0, 7 },
154*5aa45fcbSEnji Cooper 	{ -1, "", (int64_t)1L, HN_DIVISOR_1000, 7 },
155*5aa45fcbSEnji Cooper 	{ -1, "", (int64_t)1L, 0, 1000 },
156*5aa45fcbSEnji Cooper 	{ -1, "", (int64_t)1L, HN_DIVISOR_1000, 1000 },
157*5aa45fcbSEnji Cooper 	{ -1, "", (int64_t)0L, 0, 1000*1000 },
158*5aa45fcbSEnji Cooper 	{ -1, "", (int64_t)0L, HN_DIVISOR_1000, 1000*1000 },
159*5aa45fcbSEnji Cooper 	{ -1, "", (int64_t)0L, 0, INT_MAX },
160*5aa45fcbSEnji Cooper 	{ -1, "", (int64_t)0L, HN_DIVISOR_1000, INT_MAX },
161*5aa45fcbSEnji Cooper 
162*5aa45fcbSEnji Cooper 	/* Negative scale values are not handled well
163*5aa45fcbSEnji Cooper 	 by the existing library routine - should report as error */
164*5aa45fcbSEnji Cooper 	/*  all should return errors with new code, fail assertion with old */
165*5aa45fcbSEnji Cooper 
166*5aa45fcbSEnji Cooper 	{ -1, "", (int64_t)1L, 0, -1 },
167*5aa45fcbSEnji Cooper 	{ -1, "", (int64_t)1L, HN_DIVISOR_1000, -1 },
168*5aa45fcbSEnji Cooper 	{ -1, "", (int64_t)1L, 0, -1000 },
169*5aa45fcbSEnji Cooper 	{ -1, "", (int64_t)1L, HN_DIVISOR_1000, -1000 },
170*5aa45fcbSEnji Cooper 
171*5aa45fcbSEnji Cooper 	/* __INT_MIN doesn't print properly, skipped. */
172*5aa45fcbSEnji Cooper 
173*5aa45fcbSEnji Cooper 	{ -1, "", (int64_t)1L, 0, -__INT_MAX },
174*5aa45fcbSEnji Cooper 	{ -1, "", (int64_t)1L, HN_DIVISOR_1000, -__INT_MAX },
175*5aa45fcbSEnji Cooper 
176*5aa45fcbSEnji Cooper 
177*5aa45fcbSEnji Cooper 	/* tests for scale == 0, without autoscale */
178*5aa45fcbSEnji Cooper 	/* tests 100-114 test scale 0 with 1000 divisor - print first N digits */
179*5aa45fcbSEnji Cooper 	{ 2, "0 ", (int64_t)0L, HN_DIVISOR_1000, 0 },
180*5aa45fcbSEnji Cooper 	{ 2, "1 ", (int64_t)1L, HN_DIVISOR_1000, 0 },
181*5aa45fcbSEnji Cooper 	{ 3, "10 ", (int64_t)10L, HN_DIVISOR_1000, 0 },
182*5aa45fcbSEnji Cooper 	{ 3, "0 M", (int64_t)150L, HN_DIVISOR_1000, HN_NOSPACE },
183*5aa45fcbSEnji Cooper 	{ 3, "0 M", (int64_t)500L, HN_DIVISOR_1000, HN_NOSPACE },
184*5aa45fcbSEnji Cooper 	{ 3, "0 M", (int64_t)999L, HN_DIVISOR_1000, HN_NOSPACE },
185*5aa45fcbSEnji Cooper 	{ 4, "150", (int64_t)150L, HN_DIVISOR_1000, 0 },
186*5aa45fcbSEnji Cooper 	{ 4, "500", (int64_t)500L, HN_DIVISOR_1000, 0 },
187*5aa45fcbSEnji Cooper 	{ 4, "999", (int64_t)999L, HN_DIVISOR_1000, 0 },
188*5aa45fcbSEnji Cooper 	{ 5, "100", (int64_t)1000L, HN_DIVISOR_1000, 0 },
189*5aa45fcbSEnji Cooper 	{ 5, "150", (int64_t)1500L, HN_DIVISOR_1000, 0 },
190*5aa45fcbSEnji Cooper 	{ 7, "500", (int64_t)500*1000L, HN_DIVISOR_1000, 0 },
191*5aa45fcbSEnji Cooper 	{ 8, "150", (int64_t)1500*1000L, HN_DIVISOR_1000, 0 },
192*5aa45fcbSEnji Cooper 	{ 10, "500", (int64_t)500*1000*1000L, HN_DIVISOR_1000, 0 },
193*5aa45fcbSEnji Cooper 	{ 11, "150", (int64_t)1500*1000*1000L, HN_DIVISOR_1000, 0 },
194*5aa45fcbSEnji Cooper 
195*5aa45fcbSEnji Cooper 	/* tests 115-126 test scale 0 with 1024 divisor - print first N digits */
196*5aa45fcbSEnji Cooper 	{ 2, "0 ", (int64_t)0L, 0, 0 },
197*5aa45fcbSEnji Cooper 	{ 2, "1 ", (int64_t)1L, 0, 0 },
198*5aa45fcbSEnji Cooper 	{ 3, "10 ", (int64_t)10L, 0, 0 },
199*5aa45fcbSEnji Cooper 	{ 4, "150", (int64_t)150L, 0, 0 },
200*5aa45fcbSEnji Cooper 	{ 4, "500", (int64_t)500L, 0, 0 },
201*5aa45fcbSEnji Cooper 	{ 4, "999", (int64_t)999L, 0, 0 },
202*5aa45fcbSEnji Cooper 	{ 5, "100", (int64_t)1000L, 0, 0 },
203*5aa45fcbSEnji Cooper 	{ 5, "150", (int64_t)1500L, 0, 0 },
204*5aa45fcbSEnji Cooper 	{ 7, "500", (int64_t)500*1000L, 0, 0 },
205*5aa45fcbSEnji Cooper 	{ 8, "150", (int64_t)1500*1000L, 0, 0 },
206*5aa45fcbSEnji Cooper 	{ 10, "500", (int64_t)500*1000*1000L, 0, 0 },
207*5aa45fcbSEnji Cooper 	{ 11, "150", (int64_t)1500*1000*1000L, 0, 0 },
208*5aa45fcbSEnji Cooper 
209*5aa45fcbSEnji Cooper 	/* Test boundary cases for very large positive/negative number formatting */
210*5aa45fcbSEnji Cooper 	/* Explicit scale, divisor 1024 */
211*5aa45fcbSEnji Cooper 
212*5aa45fcbSEnji Cooper 	/* XXX = requires length 5 (buflen 6) for some cases*/
213*5aa45fcbSEnji Cooper 	/* KLUDGE - test loop below will bump length 5 up to 5 */
214*5aa45fcbSEnji Cooper 	{ 3, "8 E",   INT64_MAX, 0, 6 },
215*5aa45fcbSEnji Cooper 	{ 4, "-8 E", -INT64_MAX, 0, 6 },
216*5aa45fcbSEnji Cooper 	{ 3, "0 E", (int64_t)92*1024*1024*1024*1024*1024L, 0, 6 },
217*5aa45fcbSEnji Cooper 	{ 3, "0 E", -(int64_t)92*1024*1024*1024*1024*1024L, 0, 6 },
218*5aa45fcbSEnji Cooper 	{ 3, "0 E", (int64_t)82*1024*1024*1024*1024*1024L, 0, 6 },
219*5aa45fcbSEnji Cooper 	{ 3, "0 E", -(int64_t)82*1024*1024*1024*1024*1024L, 0, 6 },
220*5aa45fcbSEnji Cooper 	{ 3, "0 E", (int64_t)81*1024*1024*1024*1024*1024L, 0, 6 },
221*5aa45fcbSEnji Cooper 	{ 3, "0 E", -(int64_t)81*1024*1024*1024*1024*1024L, 0, 6 },
222*5aa45fcbSEnji Cooper 	{ 4, "92 P", (int64_t)92*1024*1024*1024*1024*1024L, 0, 5 },
223*5aa45fcbSEnji Cooper 	{ 5, "-92 P", -(int64_t)92*1024*1024*1024*1024*1024L, 0, 5 },
224*5aa45fcbSEnji Cooper 	{ 4, "82 P", (int64_t)82*1024*1024*1024*1024*1024L, 0, 5 },
225*5aa45fcbSEnji Cooper 	{ 5, "-82 P", -(int64_t)82*1024*1024*1024*1024*1024L, 0, 5 },
226*5aa45fcbSEnji Cooper 	{ 4, "81 P", (int64_t)81*1024*1024*1024*1024*1024L, 0, 5 },
227*5aa45fcbSEnji Cooper 	{ 5, "-81 P", -(int64_t)81*1024*1024*1024*1024*1024L, 0, 5 },
228*5aa45fcbSEnji Cooper 
229*5aa45fcbSEnji Cooper 	/* Explicit scale, divisor 1000 */
230*5aa45fcbSEnji Cooper 	{ 3, "9 E",   INT64_MAX, HN_DIVISOR_1000, 6 },
231*5aa45fcbSEnji Cooper 	{ 4, "-9 E", -INT64_MAX, HN_DIVISOR_1000,  6 },
232*5aa45fcbSEnji Cooper 	{ 3, "0 E", (int64_t)82*1024*1024*1024*1024*1024L, HN_DIVISOR_1000,  6 },
233*5aa45fcbSEnji Cooper 	{ 3, "0 E", -(int64_t)82*1024*1024*1024*1024*1024L, HN_DIVISOR_1000,  6 },
234*5aa45fcbSEnji Cooper 	{ 3, "0 E", (int64_t)82*1024*1024*1024*1024*1024L, HN_DIVISOR_1000,  6 },
235*5aa45fcbSEnji Cooper 	{ 3, "0 E", -(int64_t)82*1024*1024*1024*1024*1024L, HN_DIVISOR_1000,  6 },
236*5aa45fcbSEnji Cooper 	{ 4, "92 P", (int64_t)82*1024*1024*1024*1024*1024L, HN_DIVISOR_1000,  5 },
237*5aa45fcbSEnji Cooper 	{ 5, "-92 P", -(int64_t)82*1024*1024*1024*1024*1024L, HN_DIVISOR_1000,  5 },
238*5aa45fcbSEnji Cooper 	{ 4, "91 P", (int64_t)81*1024*1024*1024*1024*1024L, HN_DIVISOR_1000,  5 },
239*5aa45fcbSEnji Cooper 	{ 5, "-91 P", -(int64_t)81*1024*1024*1024*1024*1024L, HN_DIVISOR_1000,  5 },
240*5aa45fcbSEnji Cooper 
241*5aa45fcbSEnji Cooper 	/* Autoscale, divisor 1024 */
242*5aa45fcbSEnji Cooper 	{ 3, "8 E",   INT64_MAX, 0, HN_AUTOSCALE },
243*5aa45fcbSEnji Cooper 	{ 4, "-8 E", -INT64_MAX, 0, HN_AUTOSCALE },
244*5aa45fcbSEnji Cooper 	{ 4, "92 P", (int64_t)92*1024*1024*1024*1024*1024L, 0, HN_AUTOSCALE },
245*5aa45fcbSEnji Cooper 	{ 5, "-92 P", -(int64_t)92*1024*1024*1024*1024*1024L, 0, HN_AUTOSCALE },
246*5aa45fcbSEnji Cooper 	{ 4, "82 P", (int64_t)82*1024*1024*1024*1024*1024L, 0, HN_AUTOSCALE },
247*5aa45fcbSEnji Cooper 	{ 5, "-82 P", -(int64_t)82*1024*1024*1024*1024*1024L, 0, HN_AUTOSCALE },
248*5aa45fcbSEnji Cooper 	{ 4, "81 P", (int64_t)81*1024*1024*1024*1024*1024L, 0, HN_AUTOSCALE },
249*5aa45fcbSEnji Cooper 	{ 5, "-81 P", -(int64_t)81*1024*1024*1024*1024*1024L, 0, HN_AUTOSCALE },
250*5aa45fcbSEnji Cooper 	/* Autoscale, divisor 1000 */
251*5aa45fcbSEnji Cooper 	{ 3, "9 E",   INT64_MAX, HN_DIVISOR_1000, HN_AUTOSCALE },
252*5aa45fcbSEnji Cooper 	{ 4, "-9 E", -INT64_MAX, HN_DIVISOR_1000, HN_AUTOSCALE },
253*5aa45fcbSEnji Cooper 	{ 4, "92 P", (int64_t)82*1024*1024*1024*1024*1024L, HN_DIVISOR_1000, HN_AUTOSCALE },
254*5aa45fcbSEnji Cooper 	{ 5, "-92 P", -(int64_t)82*1024*1024*1024*1024*1024L, HN_DIVISOR_1000, HN_AUTOSCALE },
255*5aa45fcbSEnji Cooper 	{ 4, "91 P", (int64_t)81*1024*1024*1024*1024*1024L, HN_DIVISOR_1000, HN_AUTOSCALE },
256*5aa45fcbSEnji Cooper 	{ 5, "-91 P", -(int64_t)81*1024*1024*1024*1024*1024L, HN_DIVISOR_1000, HN_AUTOSCALE },
257*5aa45fcbSEnji Cooper 
258*5aa45fcbSEnji Cooper 	/* 0 scale, divisor 1024 */
259*5aa45fcbSEnji Cooper 	{ 12, "skdj",  INT64_MAX, 0, 0 },
260*5aa45fcbSEnji Cooper 	{ 21, "-9223", -INT64_MAX, 0, 0 },
261*5aa45fcbSEnji Cooper 	{ 19, "10358", (int64_t)92*1024*1024*1024*1024*1024L, 0, 0 },
262*5aa45fcbSEnji Cooper 	{ 20, "-1035", -(int64_t)92*1024*1024*1024*1024*1024L, 0, 0 },
263*5aa45fcbSEnji Cooper 	{ 18, "92323", (int64_t)82*1024*1024*1024*1024*1024L, 0, 0 },
264*5aa45fcbSEnji Cooper 	{ 19, "-9232", -(int64_t)82*1024*1024*1024*1024*1024L, 0, 0 },
265*5aa45fcbSEnji Cooper 	{ 18, "91197", (int64_t)81*1024*1024*1024*1024*1024L, 0, 0 },
266*5aa45fcbSEnji Cooper 	{ 19, "-9119", -(int64_t)81*1024*1024*1024*1024*1024L, 0, 0 },
267*5aa45fcbSEnji Cooper 
268*5aa45fcbSEnji Cooper 	/* 0 scale, divisor 1000 */
269*5aa45fcbSEnji Cooper 	/* XXX - why does this fail? */
270*5aa45fcbSEnji Cooper 	{ -1, "", INT64_MAX, HN_DIVISOR_1000, 0 },
271*5aa45fcbSEnji Cooper 	{ 21, "-9223", -INT64_MAX, HN_DIVISOR_1000,  0 },
272*5aa45fcbSEnji Cooper 	{ 19, "10358", (int64_t)92*1024*1024*1024*1024*1024L, HN_DIVISOR_1000,  0 },
273*5aa45fcbSEnji Cooper 	{ 20, "-1035", -(int64_t)92*1024*1024*1024*1024*1024L, HN_DIVISOR_1000,  0 },
274*5aa45fcbSEnji Cooper 	{ 18, "92323", (int64_t)82*1024*1024*1024*1024*1024L, HN_DIVISOR_1000,  0 },
275*5aa45fcbSEnji Cooper 	{ 19, "-9232", -(int64_t)82*1024*1024*1024*1024*1024L, HN_DIVISOR_1000,  0 },
276*5aa45fcbSEnji Cooper 	/* Expected to pass */
277*5aa45fcbSEnji Cooper 	{ 18, "91197", (int64_t)81*1024*1024*1024*1024*1024L, HN_DIVISOR_1000,  0 },
278*5aa45fcbSEnji Cooper 	{ 19, "-9119", -(int64_t)81*1024*1024*1024*1024*1024L, HN_DIVISOR_1000,  0 },
279*5aa45fcbSEnji Cooper 
280*5aa45fcbSEnji Cooper 
281*5aa45fcbSEnji Cooper 
282*5aa45fcbSEnji Cooper 	/* Need to implement tests for GETSCALE */
283*5aa45fcbSEnji Cooper /*	{ ?, "", (int64_t)0L, HN_DIVISOR_1000, HN_GETSCALE },
284*5aa45fcbSEnji Cooper 	...
285*5aa45fcbSEnji Cooper */
286*5aa45fcbSEnji Cooper         /* Tests for HN_DECIMAL */
287*5aa45fcbSEnji Cooper         /* Positive, Autoscale */
288*5aa45fcbSEnji Cooper 	{ 5, "500 k", (int64_t)500*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE },
289*5aa45fcbSEnji Cooper 	{ 5, "994 k", (int64_t)994*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE },
290*5aa45fcbSEnji Cooper 	{ 5, "995 k", (int64_t)995*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE },
291*5aa45fcbSEnji Cooper 	{ 5, "999 k", (int64_t)999*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE },
292*5aa45fcbSEnji Cooper 	{ 5, "1.0 M", (int64_t)1000*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE },
293*5aa45fcbSEnji Cooper 	{ 5, "1.5 M", (int64_t)1500*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE },
294*5aa45fcbSEnji Cooper 	{ 5, "1.9 M", (int64_t)1949*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE },
295*5aa45fcbSEnji Cooper 	{ 5, "2.0 M", (int64_t)1950*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE },
296*5aa45fcbSEnji Cooper 	{ 5, "9.9 M", (int64_t)9949*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE },
297*5aa45fcbSEnji Cooper 	{ 4, "10 M", (int64_t)9950*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE },
298*5aa45fcbSEnji Cooper 	{ 5, "500 M", (int64_t)500*1000*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE },
299*5aa45fcbSEnji Cooper 	{ 5, "994 M", (int64_t)994*1000*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE },
300*5aa45fcbSEnji Cooper 	{ 5, "995 M", (int64_t)995*1000*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE },
301*5aa45fcbSEnji Cooper 	{ 5, "999 M", (int64_t)999*1000*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE },
302*5aa45fcbSEnji Cooper 
303*5aa45fcbSEnji Cooper 	{ 5, "500 K", (int64_t)500*1024L, HN_DECIMAL, HN_AUTOSCALE },
304*5aa45fcbSEnji Cooper 	{ 5, "994 K", (int64_t)994*1024L, HN_DECIMAL, HN_AUTOSCALE },
305*5aa45fcbSEnji Cooper 	{ 5, "995 K", (int64_t)995*1024L, HN_DECIMAL, HN_AUTOSCALE },
306*5aa45fcbSEnji Cooper 	{ 5, "999 K", (int64_t)999*1024L, HN_DECIMAL, HN_AUTOSCALE },
307*5aa45fcbSEnji Cooper 	{ 5, "1.0 M", (int64_t)1000*1024L, HN_DECIMAL, HN_AUTOSCALE },
308*5aa45fcbSEnji Cooper 	{ 5, "1.0 M", (int64_t)1018*1024L, HN_DECIMAL, HN_AUTOSCALE },
309*5aa45fcbSEnji Cooper 	{ 5, "1.0 M", (int64_t)1019*1024L, HN_DECIMAL, HN_AUTOSCALE },
310*5aa45fcbSEnji Cooper 	{ 5, "1.5 M", (int64_t)1536*1024L, HN_DECIMAL, HN_AUTOSCALE },
311*5aa45fcbSEnji Cooper 	{ 5, "1.9 M", (int64_t)1996*1024L, HN_DECIMAL, HN_AUTOSCALE },
312*5aa45fcbSEnji Cooper 	{ 5, "2.0 M", (int64_t)1997*1024L, HN_DECIMAL, HN_AUTOSCALE },
313*5aa45fcbSEnji Cooper 	{ 5, "2.0 M", (int64_t)2047*1024L, HN_DECIMAL, HN_AUTOSCALE },
314*5aa45fcbSEnji Cooper 	{ 5, "2.0 M", (int64_t)2048*1024L, HN_DECIMAL, HN_AUTOSCALE },
315*5aa45fcbSEnji Cooper 	{ 5, "2.0 M", (int64_t)2099*1024L, HN_DECIMAL, HN_AUTOSCALE },
316*5aa45fcbSEnji Cooper 	{ 5, "2.1 M", (int64_t)2100*1024L, HN_DECIMAL, HN_AUTOSCALE },
317*5aa45fcbSEnji Cooper 	{ 5, "9.9 M", (int64_t)10188*1024L, HN_DECIMAL, HN_AUTOSCALE },
318*5aa45fcbSEnji Cooper 	/* XXX - shouldn't the following two be "10. M"? */
319*5aa45fcbSEnji Cooper 	{ 4, "10 M", (int64_t)10189*1024L, HN_DECIMAL, HN_AUTOSCALE },
320*5aa45fcbSEnji Cooper 	{ 4, "10 M", (int64_t)10240*1024L, HN_DECIMAL, HN_AUTOSCALE },
321*5aa45fcbSEnji Cooper 	{ 5, "500 M", (int64_t)500*1024*1024L, HN_DECIMAL, HN_AUTOSCALE },
322*5aa45fcbSEnji Cooper 	{ 5, "994 M", (int64_t)994*1024*1024L, HN_DECIMAL, HN_AUTOSCALE },
323*5aa45fcbSEnji Cooper 	{ 5, "995 M", (int64_t)995*1024*1024L, HN_DECIMAL, HN_AUTOSCALE },
324*5aa45fcbSEnji Cooper 	{ 5, "999 M", (int64_t)999*1024*1024L, HN_DECIMAL, HN_AUTOSCALE },
325*5aa45fcbSEnji Cooper 	{ 5, "1.0 G", (int64_t)1000*1024*1024L, HN_DECIMAL, HN_AUTOSCALE },
326*5aa45fcbSEnji Cooper 	{ 5, "1.0 G", (int64_t)1023*1024*1024L, HN_DECIMAL, HN_AUTOSCALE },
327*5aa45fcbSEnji Cooper 
328*5aa45fcbSEnji Cooper         /* Negative, Autoscale - should pass */
329*5aa45fcbSEnji Cooper 	{ 6, "-1.5 ", -(int64_t)1500*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE },
330*5aa45fcbSEnji Cooper 	{ 6, "-1.9 ", -(int64_t)1949*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE },
331*5aa45fcbSEnji Cooper 	{ 6, "-9.9 ", -(int64_t)9949*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE },
332*5aa45fcbSEnji Cooper 
333*5aa45fcbSEnji Cooper 	{ 6, "-1.5 ", -(int64_t)1536*1024L, HN_DECIMAL, HN_AUTOSCALE },
334*5aa45fcbSEnji Cooper 	{ 6, "-1.9 ", -(int64_t)1949*1024L, HN_DECIMAL, HN_AUTOSCALE },
335*5aa45fcbSEnji Cooper 	{ 6, "-9.7 ", -(int64_t)9949*1024L, HN_DECIMAL, HN_AUTOSCALE },
336*5aa45fcbSEnji Cooper 
337*5aa45fcbSEnji Cooper 	/* Positive/negative, at maximum scale */
338*5aa45fcbSEnji Cooper 	{ 5, "500 P", (int64_t)500*1000*1000*1000*1000*1000L, HN_DIVISOR_1000, HN_AUTOSCALE },
339*5aa45fcbSEnji Cooper 	{ 5, "1.9 E", (int64_t)1949*1000*1000*1000*1000*1000L, HN_DIVISOR_1000, HN_AUTOSCALE },
340*5aa45fcbSEnji Cooper 	{ 5, "8.9 E", (int64_t)8949*1000*1000*1000*1000*1000L, HN_DIVISOR_1000, HN_AUTOSCALE },
341*5aa45fcbSEnji Cooper 	{ 5, "9.2 E", INT64_MAX, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE },
342*5aa45fcbSEnji Cooper         /* Negatives work with latest rev only: */
343*5aa45fcbSEnji Cooper 	{ 6, "-9.2 ", -INT64_MAX, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE },
344*5aa45fcbSEnji Cooper 	{ 6, "-8.9 ", -(int64_t)8949*1000*1000*1000*1000*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE },
345*5aa45fcbSEnji Cooper 
346*5aa45fcbSEnji Cooper 	{ 5, "8.0 E",   INT64_MAX, HN_DECIMAL, HN_AUTOSCALE },
347*5aa45fcbSEnji Cooper 	{ 5, "7.9 E",   INT64_MAX-(int64_t)100*1024*1024*1024*1024*1024LL, HN_DECIMAL, HN_AUTOSCALE },
348*5aa45fcbSEnji Cooper 	{ 6, "-8.0 ", -INT64_MAX, HN_DECIMAL, HN_AUTOSCALE },
349*5aa45fcbSEnji Cooper 	{ 6, "-7.9 ",   -INT64_MAX+(int64_t)100*1024*1024*1024*1024*1024LL, HN_DECIMAL, HN_AUTOSCALE },
350*5aa45fcbSEnji Cooper 
351*5aa45fcbSEnji Cooper 	/* Positive, Fixed scales */
352*5aa45fcbSEnji Cooper 	{ 5, "500 k", (int64_t)500*1000L, HN_DECIMAL|HN_DIVISOR_1000, 1 },
353*5aa45fcbSEnji Cooper 	{ 5, "0.5 M", (int64_t)500*1000L, HN_DECIMAL|HN_DIVISOR_1000, 2 },
354*5aa45fcbSEnji Cooper 	{ 5, "949 k", (int64_t)949*1000L, HN_DECIMAL|HN_DIVISOR_1000, 1 },
355*5aa45fcbSEnji Cooper 	{ 5, "0.9 M", (int64_t)949*1000L, HN_DECIMAL|HN_DIVISOR_1000, 2 },
356*5aa45fcbSEnji Cooper 	{ 5, "950 k", (int64_t)950*1000L, HN_DECIMAL|HN_DIVISOR_1000, 1 },
357*5aa45fcbSEnji Cooper 	{ 5, "1.0 M", (int64_t)950*1000L, HN_DECIMAL|HN_DIVISOR_1000, 2 },
358*5aa45fcbSEnji Cooper 	{ 5, "999 k", (int64_t)999*1000L, HN_DECIMAL|HN_DIVISOR_1000, 1 },
359*5aa45fcbSEnji Cooper 	{ 5, "1.0 M", (int64_t)999*1000L, HN_DECIMAL|HN_DIVISOR_1000, 2 },
360*5aa45fcbSEnji Cooper 	{ 5, "1.5 M", (int64_t)1500*1000L, HN_DECIMAL|HN_DIVISOR_1000, 2 },
361*5aa45fcbSEnji Cooper 	{ 5, "1.9 M", (int64_t)1949*1000L, HN_DECIMAL|HN_DIVISOR_1000, 2 },
362*5aa45fcbSEnji Cooper 	{ 5, "2.0 M", (int64_t)1950*1000L, HN_DECIMAL|HN_DIVISOR_1000, 2 },
363*5aa45fcbSEnji Cooper 	{ 5, "9.9 M", (int64_t)9949*1000L, HN_DECIMAL|HN_DIVISOR_1000, 2 },
364*5aa45fcbSEnji Cooper 	{ 4, "10 M", (int64_t)9950*1000L, HN_DECIMAL|HN_DIVISOR_1000, 2 },
365*5aa45fcbSEnji Cooper 	{ 5, "500 M", (int64_t)500*1000*1000L, HN_DECIMAL|HN_DIVISOR_1000, 2 },
366*5aa45fcbSEnji Cooper 	{ 5, "0.5 G", (int64_t)500*1000*1000L, HN_DECIMAL|HN_DIVISOR_1000, 3 },
367*5aa45fcbSEnji Cooper 	{ 5, "999 M", (int64_t)999*1000*1000L, HN_DECIMAL|HN_DIVISOR_1000, 2 },
368*5aa45fcbSEnji Cooper 	{ 5, "1.0 G", (int64_t)999*1000*1000L, HN_DECIMAL|HN_DIVISOR_1000, 3 },
369*5aa45fcbSEnji Cooper 	/* Positive/negative, at maximum scale */
370*5aa45fcbSEnji Cooper 	{ 5, "500 P", (int64_t)500*1000*1000*1000*1000*1000L, HN_DIVISOR_1000, 5 },
371*5aa45fcbSEnji Cooper 	{ 5, "1.0 E", (int64_t)500*1000*1000*1000*1000*1000L, HN_DIVISOR_1000, 6 },
372*5aa45fcbSEnji Cooper 	{ 5, "1.9 E", (int64_t)1949*1000*1000*1000*1000*1000L, HN_DIVISOR_1000, 6 },
373*5aa45fcbSEnji Cooper 	{ 5, "8.9 E", (int64_t)8949*1000*1000*1000*1000*1000L, HN_DIVISOR_1000, 6 },
374*5aa45fcbSEnji Cooper 	{ 5, "9.2 E", INT64_MAX, HN_DECIMAL|HN_DIVISOR_1000, 6 },
375*5aa45fcbSEnji Cooper 
376*5aa45fcbSEnji Cooper 	/* HN_DECIMAL + binary + fixed scale cases not completed */
377*5aa45fcbSEnji Cooper 	{ 5, "512 K", (int64_t)512*1024L, HN_DECIMAL, 1 },
378*5aa45fcbSEnji Cooper 	{ 5, "0.5 M", (int64_t)512*1024L, HN_DECIMAL, 2 },
379*5aa45fcbSEnji Cooper 
380*5aa45fcbSEnji Cooper 	/* Negative, Fixed scales */
381*5aa45fcbSEnji Cooper         /* Not yet added, but should work with latest rev */
382*5aa45fcbSEnji Cooper 
383*5aa45fcbSEnji Cooper };
384*5aa45fcbSEnji Cooper 
385*5aa45fcbSEnji Cooper 
386*5aa45fcbSEnji Cooper /* Command line options usage */
387*5aa45fcbSEnji Cooper static void
388*5aa45fcbSEnji Cooper usage(char * progname) {
389*5aa45fcbSEnji Cooper 	printf("%s: tests libutil humanize_number function\n", progname);
390*5aa45fcbSEnji Cooper 	printf("Usage: %s [-nE] [-l num] [-v]\n\n", progname);
391*5aa45fcbSEnji Cooper 	printf("Options:\n");
392*5aa45fcbSEnji Cooper 	printf("\t-l num\tSet max length for result; buflen = num + 1\n");
393*5aa45fcbSEnji Cooper 	printf("\t\t  (NOTE: does not change expected result strings.)\n");
394*5aa45fcbSEnji Cooper 	printf("\t-n\tInclude negative scale tests, which cause older libutil\n");
395*5aa45fcbSEnji Cooper 	printf("\t\t  version of function to coredump with assertion failure\n");
396*5aa45fcbSEnji Cooper 	printf("\t-E\tInclude numbers > 1/2 Exa[byte] which currently fail\n");
397*5aa45fcbSEnji Cooper 	printf("\t-v\tVerbose - always print summary results\n");
398*5aa45fcbSEnji Cooper 	printf("\t-h, -?\tShow options\n");
399*5aa45fcbSEnji Cooper }
400*5aa45fcbSEnji Cooper 
401*5aa45fcbSEnji Cooper /* Parse command line options */
402*5aa45fcbSEnji Cooper static void
403*5aa45fcbSEnji Cooper read_options(int argc, char * const argv[], size_t *bufLength,
404*5aa45fcbSEnji Cooper     int *includeNegativeScale, int *includeExabytes, int *verbose) {
405*5aa45fcbSEnji Cooper 	int ch;
406*5aa45fcbSEnji Cooper 	size_t temp;
407*5aa45fcbSEnji Cooper 
408*5aa45fcbSEnji Cooper 	while ((ch = getopt(argc, argv, "nEh?vl:")) != -1) {
409*5aa45fcbSEnji Cooper 		switch (ch) {
410*5aa45fcbSEnji Cooper 			default:
411*5aa45fcbSEnji Cooper 				usage(argv[0]);
412*5aa45fcbSEnji Cooper 				exit(1);
413*5aa45fcbSEnji Cooper 				break;	/* UNREACHABLE */
414*5aa45fcbSEnji Cooper 			case 'h' :
415*5aa45fcbSEnji Cooper 			case '?' :
416*5aa45fcbSEnji Cooper 				usage(argv[0]);
417*5aa45fcbSEnji Cooper 				exit(0);
418*5aa45fcbSEnji Cooper 				break;	/* UNREACHABLE */
419*5aa45fcbSEnji Cooper 			case 'l' :
420*5aa45fcbSEnji Cooper 				sscanf(optarg, "%zu", &temp);
421*5aa45fcbSEnji Cooper 				*bufLength = temp + 1;
422*5aa45fcbSEnji Cooper 				break;
423*5aa45fcbSEnji Cooper 			case 'n' :
424*5aa45fcbSEnji Cooper 				*includeNegativeScale = 1;
425*5aa45fcbSEnji Cooper 				break;
426*5aa45fcbSEnji Cooper 			case 'E' :
427*5aa45fcbSEnji Cooper 				*includeExabytes = 1;
428*5aa45fcbSEnji Cooper 				break;
429*5aa45fcbSEnji Cooper 			case 'v' :
430*5aa45fcbSEnji Cooper 				*verbose = 1;
431*5aa45fcbSEnji Cooper 				break;
432*5aa45fcbSEnji Cooper 		}
433*5aa45fcbSEnji Cooper 	}
434*5aa45fcbSEnji Cooper }
435*5aa45fcbSEnji Cooper 
436*5aa45fcbSEnji Cooper static struct {
437*5aa45fcbSEnji Cooper 	int value;
438*5aa45fcbSEnji Cooper 	const char *name;
439*5aa45fcbSEnji Cooper  } flags[] = {
440*5aa45fcbSEnji Cooper 	{ HN_AUTOSCALE, "HN_AUTOSCALE" },
441*5aa45fcbSEnji Cooper 	{ HN_GETSCALE, "HN_GETSCALE" },
442*5aa45fcbSEnji Cooper 	{ HN_DIVISOR_1000, "HN_DIVISOR_1000"},
443*5aa45fcbSEnji Cooper 	{ HN_B, "HN_B"},
444*5aa45fcbSEnji Cooper 	{ HN_DECIMAL, "HN_DECIMAL"},
445*5aa45fcbSEnji Cooper };
446*5aa45fcbSEnji Cooper 
447*5aa45fcbSEnji Cooper static const char *separator = "|";
448*5aa45fcbSEnji Cooper 
449*5aa45fcbSEnji Cooper /* Format flags parameter for meaningful display */
450*5aa45fcbSEnji Cooper static char *
451*5aa45fcbSEnji Cooper str_flags(int hn_flags, char *noFlags) {
452*5aa45fcbSEnji Cooper 	size_t i;
453*5aa45fcbSEnji Cooper 	char * result;
454*5aa45fcbSEnji Cooper 
455*5aa45fcbSEnji Cooper 	result = malloc(MAX_STR_FLAGS_RESULT);
456*5aa45fcbSEnji Cooper 	result[0] = '\0';
457*5aa45fcbSEnji Cooper 
458*5aa45fcbSEnji Cooper 	for (i = 0; i < sizeof flags / sizeof *flags; i++) {
459*5aa45fcbSEnji Cooper 		if (hn_flags & flags[i].value) {
460*5aa45fcbSEnji Cooper 			if (*result != 0)
461*5aa45fcbSEnji Cooper 				strlcat(result, separator,
462*5aa45fcbSEnji Cooper 				    MAX_STR_FLAGS_RESULT);
463*5aa45fcbSEnji Cooper 			strlcat(result, flags[i].name, MAX_STR_FLAGS_RESULT);
464*5aa45fcbSEnji Cooper 		}
465*5aa45fcbSEnji Cooper 	}
466*5aa45fcbSEnji Cooper 
467*5aa45fcbSEnji Cooper 	if (strlen(result) == 0)
468*5aa45fcbSEnji Cooper 		strlcat(result, noFlags, MAX_STR_FLAGS_RESULT);
469*5aa45fcbSEnji Cooper 	return result;
470*5aa45fcbSEnji Cooper }
471*5aa45fcbSEnji Cooper 
472*5aa45fcbSEnji Cooper 
473*5aa45fcbSEnji Cooper /* Format scale parameter for meaningful display */
474*5aa45fcbSEnji Cooper static char *
475*5aa45fcbSEnji Cooper str_scale(int scale) {
476*5aa45fcbSEnji Cooper 	char *result;
477*5aa45fcbSEnji Cooper 
478*5aa45fcbSEnji Cooper 	if (scale == HN_AUTOSCALE || scale == HN_GETSCALE)
479*5aa45fcbSEnji Cooper 		return str_flags(scale, "");
480*5aa45fcbSEnji Cooper 
481*5aa45fcbSEnji Cooper 	result = malloc(MAX_INT_STR_DIGITS);
482*5aa45fcbSEnji Cooper 	result[0] = '\0';
483*5aa45fcbSEnji Cooper 	snprintf(result, MAX_INT_STR_DIGITS, "%d", scale);
484*5aa45fcbSEnji Cooper 	return result;
485*5aa45fcbSEnji Cooper }
486*5aa45fcbSEnji Cooper 
487*5aa45fcbSEnji Cooper static void
488*5aa45fcbSEnji Cooper testskipped(size_t i)
489*5aa45fcbSEnji Cooper {
490*5aa45fcbSEnji Cooper 
491*5aa45fcbSEnji Cooper 	printf("ok %zu # skip - not turned on\n", i);
492*5aa45fcbSEnji Cooper }
493*5aa45fcbSEnji Cooper 
494*5aa45fcbSEnji Cooper int
495*5aa45fcbSEnji Cooper main(int argc, char * const argv[])
496*5aa45fcbSEnji Cooper {
497*5aa45fcbSEnji Cooper 	char *buf;
498*5aa45fcbSEnji Cooper 	char *flag_str, *scale_str;
499*5aa45fcbSEnji Cooper 	size_t buflen, errcnt, i, skipped, tested;
500*5aa45fcbSEnji Cooper 	int r;
501*5aa45fcbSEnji Cooper 	int includeNegScale;
502*5aa45fcbSEnji Cooper 	int includeExabyteTests;
503*5aa45fcbSEnji Cooper 	int verbose;
504*5aa45fcbSEnji Cooper 
505*5aa45fcbSEnji Cooper 	buflen = 4;
506*5aa45fcbSEnji Cooper 	includeNegScale = 0;
507*5aa45fcbSEnji Cooper 	includeExabyteTests = 0;
508*5aa45fcbSEnji Cooper 	verbose = 0;
509*5aa45fcbSEnji Cooper 
510*5aa45fcbSEnji Cooper 	read_options(argc, argv, &buflen, &includeNegScale,
511*5aa45fcbSEnji Cooper 	    &includeExabyteTests, &verbose);
512*5aa45fcbSEnji Cooper 
513*5aa45fcbSEnji Cooper 	buf = malloc(buflen);
514*5aa45fcbSEnji Cooper 	errcnt = 0;
515*5aa45fcbSEnji Cooper 	tested = 0;
516*5aa45fcbSEnji Cooper 	skipped = 0;
517*5aa45fcbSEnji Cooper 
518*5aa45fcbSEnji Cooper 	if (buflen != 4)
519*5aa45fcbSEnji Cooper 		printf("Warning: buffer size %zu != 4, expect some results to differ.\n", buflen);
520*5aa45fcbSEnji Cooper 
521*5aa45fcbSEnji Cooper 	printf("1..%zu\n", nitems(test_args));
522*5aa45fcbSEnji Cooper 	for (i = 0; i < nitems(test_args); i++) {
523*5aa45fcbSEnji Cooper 		/* KLUDGE */
524*5aa45fcbSEnji Cooper 		if (test_args[i].num == INT64_MAX && buflen == 4) {
525*5aa45fcbSEnji Cooper 		        /* Start final tests which require buffer of 6 */
526*5aa45fcbSEnji Cooper 		        free(buf);
527*5aa45fcbSEnji Cooper 		        buflen = 6;
528*5aa45fcbSEnji Cooper                         buf = malloc(buflen);
529*5aa45fcbSEnji Cooper                         if (verbose)
530*5aa45fcbSEnji Cooper                                 printf("Buffer length increased to %zu\n",
531*5aa45fcbSEnji Cooper 				    buflen);
532*5aa45fcbSEnji Cooper 		}
533*5aa45fcbSEnji Cooper 
534*5aa45fcbSEnji Cooper 		if (test_args[i].scale < 0 && ! includeNegScale) {
535*5aa45fcbSEnji Cooper 			skipped++;
536*5aa45fcbSEnji Cooper 			testskipped(i + 1);
537*5aa45fcbSEnji Cooper 			continue;
538*5aa45fcbSEnji Cooper 		}
539*5aa45fcbSEnji Cooper 		if (test_args[i].num >= halfExabyte && ! includeExabyteTests) {
540*5aa45fcbSEnji Cooper 			skipped++;
541*5aa45fcbSEnji Cooper 			testskipped(i + 1);
542*5aa45fcbSEnji Cooper 			continue;
543*5aa45fcbSEnji Cooper 		}
544*5aa45fcbSEnji Cooper 
545*5aa45fcbSEnji Cooper 		r = humanize_number(buf, buflen, test_args[i].num, "",
546*5aa45fcbSEnji Cooper 		    test_args[i].scale, test_args[i].flags);
547*5aa45fcbSEnji Cooper 		flag_str = str_flags(test_args[i].flags, "[no flags]");
548*5aa45fcbSEnji Cooper 		scale_str = str_scale(test_args[i].scale);
549*5aa45fcbSEnji Cooper 
550*5aa45fcbSEnji Cooper 		if (r != test_args[i].retval) {
551*5aa45fcbSEnji Cooper 			if (verbose)
552*5aa45fcbSEnji Cooper 				printf("wrong return value on index %zu, "
553*5aa45fcbSEnji Cooper 				    "buflen: %zu, got: %d + \"%s\", "
554*5aa45fcbSEnji Cooper 				    "expected %d + \"%s\"; num = %jd, "
555*5aa45fcbSEnji Cooper 				    "scale = %s, flags= %s.\n",
556*5aa45fcbSEnji Cooper 				    i, buflen, r, buf, test_args[i].retval,
557*5aa45fcbSEnji Cooper 				    test_args[i].res,
558*5aa45fcbSEnji Cooper 				    (intmax_t)test_args[i].num,
559*5aa45fcbSEnji Cooper 				    scale_str, flag_str);
560*5aa45fcbSEnji Cooper 			else
561*5aa45fcbSEnji Cooper 				printf("not ok %zu # return %d != %d\n",
562*5aa45fcbSEnji Cooper 				    i + 1, r, test_args[i].retval);
563*5aa45fcbSEnji Cooper 			errcnt++;
564*5aa45fcbSEnji Cooper 		} else if (strcmp(buf, test_args[i].res) != 0) {
565*5aa45fcbSEnji Cooper 			if (verbose)
566*5aa45fcbSEnji Cooper 				printf("result mismatch on index %zu, got: "
567*5aa45fcbSEnji Cooper 				    "\"%s\", expected \"%s\"; num = %jd, "
568*5aa45fcbSEnji Cooper 				    "scale = %s, flags= %s.\n",
569*5aa45fcbSEnji Cooper 				    i, buf, test_args[i].res,
570*5aa45fcbSEnji Cooper 				    (intmax_t)test_args[i].num,
571*5aa45fcbSEnji Cooper 				    scale_str, flag_str);
572*5aa45fcbSEnji Cooper 			else
573*5aa45fcbSEnji Cooper 				printf("not ok %zu # buf \"%s\" != \"%s\"\n",
574*5aa45fcbSEnji Cooper 				    i + 1, buf, test_args[i].res);
575*5aa45fcbSEnji Cooper 			errcnt++;
576*5aa45fcbSEnji Cooper 		} else {
577*5aa45fcbSEnji Cooper 			if (verbose)
578*5aa45fcbSEnji Cooper 				printf("successful result on index %zu, "
579*5aa45fcbSEnji Cooper 				    "returned %d, got: \"%s\"; num = %jd, "
580*5aa45fcbSEnji Cooper 				    "scale = %s, flags= %s.\n",
581*5aa45fcbSEnji Cooper 				    i, r, buf,
582*5aa45fcbSEnji Cooper 				    (intmax_t)test_args[i].num,
583*5aa45fcbSEnji Cooper 				    scale_str, flag_str);
584*5aa45fcbSEnji Cooper 			else
585*5aa45fcbSEnji Cooper 				printf("ok %zu\n", i + 1);
586*5aa45fcbSEnji Cooper 		}
587*5aa45fcbSEnji Cooper 		tested++;
588*5aa45fcbSEnji Cooper 	}
589*5aa45fcbSEnji Cooper 
590*5aa45fcbSEnji Cooper 	if (verbose)
591*5aa45fcbSEnji Cooper 		printf("total errors: %zu/%zu tests, %zu skipped\n", errcnt,
592*5aa45fcbSEnji Cooper 		    tested, skipped);
593*5aa45fcbSEnji Cooper 
594*5aa45fcbSEnji Cooper 	if (errcnt)
595*5aa45fcbSEnji Cooper 		return 1;
596*5aa45fcbSEnji Cooper 
597*5aa45fcbSEnji Cooper 	return 0;
598*5aa45fcbSEnji Cooper }
599