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 * $FreeBSD$ 285aa45fcbSEnji Cooper * 295aa45fcbSEnji Cooper */ 305aa45fcbSEnji Cooper 315aa45fcbSEnji Cooper #include <sys/param.h> 325aa45fcbSEnji Cooper #include <inttypes.h> 335aa45fcbSEnji Cooper #include <libutil.h> 345aa45fcbSEnji Cooper #include <limits.h> 355aa45fcbSEnji Cooper #include <math.h> 365aa45fcbSEnji Cooper #include <stdio.h> 375aa45fcbSEnji Cooper #include <stdlib.h> 385aa45fcbSEnji Cooper #include <string.h> 395aa45fcbSEnji Cooper #include <unistd.h> 405aa45fcbSEnji Cooper 415aa45fcbSEnji Cooper #define MAX_STR_FLAGS_RESULT 80 425aa45fcbSEnji Cooper #define MAX_INT_STR_DIGITS 12 435aa45fcbSEnji Cooper 445aa45fcbSEnji Cooper static const int64_t halfExabyte = (int64_t)500*1000*1000*1000*1000*1000L; 455aa45fcbSEnji Cooper 465aa45fcbSEnji Cooper static struct { 475aa45fcbSEnji Cooper int retval; 485aa45fcbSEnji Cooper const char *res; 495aa45fcbSEnji Cooper int64_t num; 505aa45fcbSEnji Cooper int flags; 515aa45fcbSEnji Cooper int scale; 52*e285e32eSBartek Rutkowski size_t buflen; 535aa45fcbSEnji Cooper } test_args[] = { 545aa45fcbSEnji Cooper /* tests 0-13 test 1000 suffixes */ 55*e285e32eSBartek Rutkowski { 2, "0 ", (int64_t)0L, HN_DIVISOR_1000, HN_AUTOSCALE, 4 }, 56*e285e32eSBartek Rutkowski { 3, "1 k", (int64_t)500L, HN_DIVISOR_1000, HN_AUTOSCALE, 4 }, 57*e285e32eSBartek Rutkowski { 3, "1 M", (int64_t)500*1000L, HN_DIVISOR_1000, HN_AUTOSCALE, 4 }, 58*e285e32eSBartek Rutkowski { 3, "1 G", (int64_t)500*1000*1000L, HN_DIVISOR_1000, HN_AUTOSCALE, 4 }, 59*e285e32eSBartek Rutkowski { 3, "1 T", (int64_t)500*1000*1000*1000L, HN_DIVISOR_1000, HN_AUTOSCALE, 4 }, 60*e285e32eSBartek Rutkowski { 3, "1 P", (int64_t)500*1000*1000*1000*1000L, HN_DIVISOR_1000, HN_AUTOSCALE, 4 }, 61*e285e32eSBartek Rutkowski { 3, "1 E", (int64_t)500*1000*1000*1000*1000*1000L, HN_DIVISOR_1000, HN_AUTOSCALE, 4 }, 62*e285e32eSBartek Rutkowski { 2, "1 ", (int64_t)1L, HN_DIVISOR_1000, HN_AUTOSCALE, 4 }, 63*e285e32eSBartek Rutkowski { 3, "2 k", (int64_t)1500L, HN_DIVISOR_1000, HN_AUTOSCALE, 4 }, 64*e285e32eSBartek Rutkowski { 3, "2 M", (int64_t)1500*1000L, HN_DIVISOR_1000, HN_AUTOSCALE, 4 }, 65*e285e32eSBartek Rutkowski { 3, "2 G", (int64_t)1500*1000*1000L, HN_DIVISOR_1000, HN_AUTOSCALE, 4 }, 66*e285e32eSBartek Rutkowski { 3, "2 T", (int64_t)1500*1000*1000*1000L, HN_DIVISOR_1000, HN_AUTOSCALE, 4 }, 67*e285e32eSBartek Rutkowski { 3, "2 P", (int64_t)1500*1000*1000*1000*1000L, HN_DIVISOR_1000, HN_AUTOSCALE, 4 }, 68*e285e32eSBartek Rutkowski { 3, "2 E", (int64_t)1500*1000*1000*1000*1000*1000L, HN_DIVISOR_1000, HN_AUTOSCALE, 4 }, 695aa45fcbSEnji Cooper 705aa45fcbSEnji Cooper /* tests 14-27 test 1024 suffixes */ 71*e285e32eSBartek Rutkowski { 2, "0 ", (int64_t)0L, 0, HN_AUTOSCALE, 4 }, 72*e285e32eSBartek Rutkowski { 3, "1 K", (int64_t)512L, 0, HN_AUTOSCALE, 4 }, 73*e285e32eSBartek Rutkowski { 3, "1 M", (int64_t)512*1024L, 0, HN_AUTOSCALE, 4 }, 74*e285e32eSBartek Rutkowski { 3, "1 G", (int64_t)512*1024*1024L, 0, HN_AUTOSCALE, 4 }, 75*e285e32eSBartek Rutkowski { 3, "1 T", (int64_t)512*1024*1024*1024L, 0, HN_AUTOSCALE, 4 }, 76*e285e32eSBartek Rutkowski { 3, "1 P", (int64_t)512*1024*1024*1024*1024L, 0, HN_AUTOSCALE, 4 }, 77*e285e32eSBartek Rutkowski { 3, "1 E", (int64_t)512*1024*1024*1024*1024*1024L, 0, HN_AUTOSCALE, 4 }, 78*e285e32eSBartek Rutkowski { 2, "1 ", (int64_t)1L, 0, HN_AUTOSCALE, 4 }, 79*e285e32eSBartek Rutkowski { 3, "2 K", (int64_t)1536L, 0, HN_AUTOSCALE, 4 }, 80*e285e32eSBartek Rutkowski { 3, "2 M", (int64_t)1536*1024L, 0, HN_AUTOSCALE, 4 }, 81*e285e32eSBartek Rutkowski { 3, "2 G", (int64_t)1536*1024*1024L, 0, HN_AUTOSCALE, 4 }, 82*e285e32eSBartek Rutkowski { 3, "2 T", (int64_t)1536*1024*1024*1024L, 0, HN_AUTOSCALE, 4 }, 83*e285e32eSBartek Rutkowski { 3, "2 P", (int64_t)1536*1024*1024*1024*1024L, 0, HN_AUTOSCALE, 4 }, 84*e285e32eSBartek Rutkowski { 3, "2 E", (int64_t)1536*1024*1024*1024*1024*1024L, 0, HN_AUTOSCALE, 4 }, 855aa45fcbSEnji Cooper 865aa45fcbSEnji Cooper /* tests 28-37 test rounding */ 87*e285e32eSBartek Rutkowski { 3, "0 M", (int64_t)500*1000L-1, HN_DIVISOR_1000, HN_AUTOSCALE, 4 }, 88*e285e32eSBartek Rutkowski { 3, "1 M", (int64_t)500*1000L, HN_DIVISOR_1000, HN_AUTOSCALE, 4 }, 89*e285e32eSBartek Rutkowski { 3, "1 M", (int64_t)1000*1000L + 500*1000L-1, HN_DIVISOR_1000, HN_AUTOSCALE, 4 }, 90*e285e32eSBartek Rutkowski { 3, "2 M", (int64_t)1000*1000L + 500*1000L, HN_DIVISOR_1000, HN_AUTOSCALE, 4 }, 91*e285e32eSBartek Rutkowski { 3, "0 K", (int64_t)512L-1, 0, HN_AUTOSCALE, 4 }, 92*e285e32eSBartek Rutkowski { 3, "1 K", (int64_t)512L, 0, HN_AUTOSCALE, 4 }, 93*e285e32eSBartek Rutkowski { 3, "0 M", (int64_t)512*1024L-1, 0, HN_AUTOSCALE, 4 }, 94*e285e32eSBartek Rutkowski { 3, "1 M", (int64_t)512*1024L, 0, HN_AUTOSCALE, 4 }, 95*e285e32eSBartek Rutkowski { 3, "1 M", (int64_t)1024*1024L + 512*1024L-1, 0, HN_AUTOSCALE, 4 }, 96*e285e32eSBartek Rutkowski { 3, "2 M", (int64_t)1024*1024L + 512*1024L, 0, HN_AUTOSCALE, 4 }, 975aa45fcbSEnji Cooper 985aa45fcbSEnji Cooper /* tests 38-61 test specific scale factors with 1000 divisor */ 99*e285e32eSBartek Rutkowski { 3, "0 k", (int64_t)0L, HN_DIVISOR_1000, 1, 4 }, 100*e285e32eSBartek Rutkowski { 3, "1 k", (int64_t)500L, HN_DIVISOR_1000, 1, 4 }, 101*e285e32eSBartek Rutkowski { 3, "0 M", (int64_t)500L, HN_DIVISOR_1000, 2, 4 }, 102*e285e32eSBartek Rutkowski { 3, "1 M", (int64_t)500*1000L, HN_DIVISOR_1000, 2, 4 }, 103*e285e32eSBartek Rutkowski { 3, "0 G", (int64_t)500*1000L, HN_DIVISOR_1000, 3, 4 }, 104*e285e32eSBartek Rutkowski { 3, "1 G", (int64_t)500*1000*1000L, HN_DIVISOR_1000, 3, 4 }, 105*e285e32eSBartek Rutkowski { 3, "0 T", (int64_t)500*1000*1000L, HN_DIVISOR_1000, 4, 4 }, 106*e285e32eSBartek Rutkowski { 3, "1 T", (int64_t)500*1000*1000*1000L, HN_DIVISOR_1000, 4, 4 }, 107*e285e32eSBartek Rutkowski { 3, "0 P", (int64_t)500*1000*1000*1000L, HN_DIVISOR_1000, 5, 4 }, 108*e285e32eSBartek Rutkowski { 3, "1 P", (int64_t)500*1000*1000*1000*1000L, HN_DIVISOR_1000, 5, 4 }, 109*e285e32eSBartek Rutkowski { 3, "0 E", (int64_t)500*1000*1000*1000*1000L, HN_DIVISOR_1000, 6, 4 }, 110*e285e32eSBartek Rutkowski { 3, "1 E", (int64_t)500*1000*1000*1000*1000*1000L, HN_DIVISOR_1000, 6, 4 }, 111*e285e32eSBartek Rutkowski { 3, "0 k", (int64_t)1L, HN_DIVISOR_1000, 1, 4 }, 112*e285e32eSBartek Rutkowski { 3, "2 k", (int64_t)1500L, HN_DIVISOR_1000, 1, 4 }, 113*e285e32eSBartek Rutkowski { 3, "0 M", (int64_t)1500L, HN_DIVISOR_1000, 2, 4 }, 114*e285e32eSBartek Rutkowski { 3, "2 M", (int64_t)1500*1000L, HN_DIVISOR_1000, 2, 4 }, 115*e285e32eSBartek Rutkowski { 3, "0 G", (int64_t)1500*1000L, HN_DIVISOR_1000, 3, 4 }, 116*e285e32eSBartek Rutkowski { 3, "2 G", (int64_t)1500*1000*1000L, HN_DIVISOR_1000, 3, 4 }, 117*e285e32eSBartek Rutkowski { 3, "0 T", (int64_t)1500*1000*1000L, HN_DIVISOR_1000, 4, 4 }, 118*e285e32eSBartek Rutkowski { 3, "2 T", (int64_t)1500*1000*1000*1000L, HN_DIVISOR_1000, 4, 4 }, 119*e285e32eSBartek Rutkowski { 3, "0 P", (int64_t)1500*1000*1000*1000L, HN_DIVISOR_1000, 5, 4 }, 120*e285e32eSBartek Rutkowski { 3, "2 P", (int64_t)1500*1000*1000*1000*1000L, HN_DIVISOR_1000, 5, 4 }, 121*e285e32eSBartek Rutkowski { 3, "0 E", (int64_t)1500*1000*1000*1000*1000L, HN_DIVISOR_1000, 6, 4 }, 122*e285e32eSBartek Rutkowski { 3, "2 E", (int64_t)1500*1000*1000*1000*1000*1000L, HN_DIVISOR_1000, 6, 4 }, 1235aa45fcbSEnji Cooper 1245aa45fcbSEnji Cooper /* tests 62-85 test specific scale factors with 1024 divisor */ 125*e285e32eSBartek Rutkowski { 3, "0 K", (int64_t)0L, 0, 1, 4 }, 126*e285e32eSBartek Rutkowski { 3, "1 K", (int64_t)512L, 0, 1, 4 }, 127*e285e32eSBartek Rutkowski { 3, "0 M", (int64_t)512L, 0, 2, 4 }, 128*e285e32eSBartek Rutkowski { 3, "1 M", (int64_t)512*1024L, 0, 2, 4 }, 129*e285e32eSBartek Rutkowski { 3, "0 G", (int64_t)512*1024L, 0, 3, 4 }, 130*e285e32eSBartek Rutkowski { 3, "1 G", (int64_t)512*1024*1024L, 0, 3, 4 }, 131*e285e32eSBartek Rutkowski { 3, "0 T", (int64_t)512*1024*1024L, 0, 4, 4 }, 132*e285e32eSBartek Rutkowski { 3, "1 T", (int64_t)512*1024*1024*1024L, 0, 4, 4 }, 133*e285e32eSBartek Rutkowski { 3, "0 P", (int64_t)512*1024*1024*1024L, 0, 5, 4 }, 134*e285e32eSBartek Rutkowski { 3, "1 P", (int64_t)512*1024*1024*1024*1024L, 0, 5, 4 }, 135*e285e32eSBartek Rutkowski { 3, "0 E", (int64_t)512*1024*1024*1024*1024L, 0, 6, 4 }, 136*e285e32eSBartek Rutkowski { 3, "1 E", (int64_t)512*1024*1024*1024*1024*1024L, 0, 6, 4 }, 137*e285e32eSBartek Rutkowski { 3, "0 K", (int64_t)1L, 0, 1, 4 }, 138*e285e32eSBartek Rutkowski { 3, "2 K", (int64_t)1536L, 0, 1, 4 }, 139*e285e32eSBartek Rutkowski { 3, "0 M", (int64_t)1536L, 0, 2, 4 }, 140*e285e32eSBartek Rutkowski { 3, "2 M", (int64_t)1536*1024L, 0, 2, 4 }, 141*e285e32eSBartek Rutkowski { 3, "0 G", (int64_t)1536*1024L, 0, 3, 4 }, 142*e285e32eSBartek Rutkowski { 3, "2 G", (int64_t)1536*1024*1024L, 0, 3, 4 }, 143*e285e32eSBartek Rutkowski { 3, "0 T", (int64_t)1536*1024*1024L, 0, 4, 4 }, 144*e285e32eSBartek Rutkowski { 3, "2 T", (int64_t)1536*1024*1024*1024L, 0, 4, 4 }, 145*e285e32eSBartek Rutkowski { 3, "0 P", (int64_t)1536*1024*1024*1024L, 0, 5, 4 }, 146*e285e32eSBartek Rutkowski { 3, "2 P", (int64_t)1536*1024*1024*1024*1024L, 0, 5, 4 }, 147*e285e32eSBartek Rutkowski { 3, "0 E", (int64_t)1536*1024*1024*1024*1024L, 0, 6, 4 }, 148*e285e32eSBartek Rutkowski { 3, "2 E", (int64_t)1536*1024*1024*1024*1024*1024L, 0, 6, 4 }, 1495aa45fcbSEnji Cooper 1505aa45fcbSEnji Cooper /* tests 86-99 test invalid specific scale values of < 0 or >= 7 with 1515aa45fcbSEnji Cooper and without HN_DIVISOR_1000 set */ 1525aa45fcbSEnji Cooper /* all should return errors with new code; with old, the latter 3 1535aa45fcbSEnji Cooper are instead processed as if having AUTOSCALE and/or GETSCALE set */ 154*e285e32eSBartek Rutkowski { -1, "", (int64_t)1L, 0, 7, 4 }, 155*e285e32eSBartek Rutkowski { -1, "", (int64_t)1L, HN_DIVISOR_1000, 7, 4 }, 156*e285e32eSBartek Rutkowski { -1, "", (int64_t)1L, 0, 1000, 4 }, 157*e285e32eSBartek Rutkowski { -1, "", (int64_t)1L, HN_DIVISOR_1000, 1000, 4 }, 158*e285e32eSBartek Rutkowski { -1, "", (int64_t)0L, 0, 1000*1000, 4 }, 159*e285e32eSBartek Rutkowski { -1, "", (int64_t)0L, HN_DIVISOR_1000, 1000*1000, 4 }, 160*e285e32eSBartek Rutkowski { -1, "", (int64_t)0L, 0, INT_MAX, 4 }, 161*e285e32eSBartek Rutkowski { -1, "", (int64_t)0L, HN_DIVISOR_1000, INT_MAX, 4 }, 1625aa45fcbSEnji Cooper 1635aa45fcbSEnji Cooper /* Negative scale values are not handled well 1645aa45fcbSEnji Cooper by the existing library routine - should report as error */ 1655aa45fcbSEnji Cooper /* all should return errors with new code, fail assertion with old */ 1665aa45fcbSEnji Cooper 167*e285e32eSBartek Rutkowski { -1, "", (int64_t)1L, 0, -1, 4 }, 168*e285e32eSBartek Rutkowski { -1, "", (int64_t)1L, HN_DIVISOR_1000, -1, 4 }, 169*e285e32eSBartek Rutkowski { -1, "", (int64_t)1L, 0, -1000, 4 }, 170*e285e32eSBartek Rutkowski { -1, "", (int64_t)1L, HN_DIVISOR_1000, -1000, 4 }, 1715aa45fcbSEnji Cooper 1725aa45fcbSEnji Cooper /* __INT_MIN doesn't print properly, skipped. */ 1735aa45fcbSEnji Cooper 174*e285e32eSBartek Rutkowski { -1, "", (int64_t)1L, 0, -__INT_MAX, 4 }, 175*e285e32eSBartek Rutkowski { -1, "", (int64_t)1L, HN_DIVISOR_1000, -__INT_MAX, 4 }, 1765aa45fcbSEnji Cooper 1775aa45fcbSEnji Cooper 1785aa45fcbSEnji Cooper /* tests for scale == 0, without autoscale */ 1795aa45fcbSEnji Cooper /* tests 100-114 test scale 0 with 1000 divisor - print first N digits */ 180*e285e32eSBartek Rutkowski { 2, "0 ", (int64_t)0L, HN_DIVISOR_1000, 0, 4 }, 181*e285e32eSBartek Rutkowski { 2, "1 ", (int64_t)1L, HN_DIVISOR_1000, 0, 4 }, 182*e285e32eSBartek Rutkowski { 3, "10 ", (int64_t)10L, HN_DIVISOR_1000, 0, 4 }, 183*e285e32eSBartek Rutkowski { 3, "0 M", (int64_t)150L, HN_DIVISOR_1000, HN_NOSPACE, 4 }, 184*e285e32eSBartek Rutkowski { 3, "0 M", (int64_t)500L, HN_DIVISOR_1000, HN_NOSPACE, 4 }, 185*e285e32eSBartek Rutkowski { 3, "0 M", (int64_t)999L, HN_DIVISOR_1000, HN_NOSPACE, 4 }, 186*e285e32eSBartek Rutkowski { 4, "150", (int64_t)150L, HN_DIVISOR_1000, 0, 4 }, 187*e285e32eSBartek Rutkowski { 4, "500", (int64_t)500L, HN_DIVISOR_1000, 0, 4 }, 188*e285e32eSBartek Rutkowski { 4, "999", (int64_t)999L, HN_DIVISOR_1000, 0, 4 }, 189*e285e32eSBartek Rutkowski { 5, "100", (int64_t)1000L, HN_DIVISOR_1000, 0, 4 }, 190*e285e32eSBartek Rutkowski { 5, "150", (int64_t)1500L, HN_DIVISOR_1000, 0, 4 }, 191*e285e32eSBartek Rutkowski { 7, "500", (int64_t)500*1000L, HN_DIVISOR_1000, 0, 4 }, 192*e285e32eSBartek Rutkowski { 8, "150", (int64_t)1500*1000L, HN_DIVISOR_1000, 0, 4 }, 193*e285e32eSBartek Rutkowski { 10, "500", (int64_t)500*1000*1000L, HN_DIVISOR_1000, 0, 4 }, 194*e285e32eSBartek Rutkowski { 11, "150", (int64_t)1500*1000*1000L, HN_DIVISOR_1000, 0, 4 }, 1955aa45fcbSEnji Cooper 1965aa45fcbSEnji Cooper /* tests 115-126 test scale 0 with 1024 divisor - print first N digits */ 197*e285e32eSBartek Rutkowski { 2, "0 ", (int64_t)0L, 0, 0, 4 }, 198*e285e32eSBartek Rutkowski { 2, "1 ", (int64_t)1L, 0, 0, 4 }, 199*e285e32eSBartek Rutkowski { 3, "10 ", (int64_t)10L, 0, 0, 4 }, 200*e285e32eSBartek Rutkowski { 4, "150", (int64_t)150L, 0, 0, 4 }, 201*e285e32eSBartek Rutkowski { 4, "500", (int64_t)500L, 0, 0, 4 }, 202*e285e32eSBartek Rutkowski { 4, "999", (int64_t)999L, 0, 0, 4 }, 203*e285e32eSBartek Rutkowski { 5, "100", (int64_t)1000L, 0, 0, 4 }, 204*e285e32eSBartek Rutkowski { 5, "150", (int64_t)1500L, 0, 0, 4 }, 205*e285e32eSBartek Rutkowski { 7, "500", (int64_t)500*1000L, 0, 0, 4 }, 206*e285e32eSBartek Rutkowski { 8, "150", (int64_t)1500*1000L, 0, 0, 4 }, 207*e285e32eSBartek Rutkowski { 10, "500", (int64_t)500*1000*1000L, 0, 0, 4 }, 208*e285e32eSBartek Rutkowski { 11, "150", (int64_t)1500*1000*1000L, 0, 0, 4 }, 209*e285e32eSBartek Rutkowski 210*e285e32eSBartek Rutkowski /* Test case for rounding of edge numbers around 999.5+, see PR224498. 211*e285e32eSBartek Rutkowski * Require buflen >= 5 */ 212*e285e32eSBartek Rutkowski { 4, "1.0M", (int64_t)1023500, HN_DECIMAL|HN_B|HN_NOSPACE, HN_AUTOSCALE, 5 }, 2135aa45fcbSEnji Cooper 2145aa45fcbSEnji Cooper /* Test boundary cases for very large positive/negative number formatting */ 2155aa45fcbSEnji Cooper /* Explicit scale, divisor 1024 */ 2165aa45fcbSEnji Cooper 217*e285e32eSBartek Rutkowski /* Requires buflen >= 6 */ 218*e285e32eSBartek Rutkowski { 3, "8 E", INT64_MAX, 0, 6, 6 }, 219*e285e32eSBartek Rutkowski { 4, "-8 E", -INT64_MAX, 0, 6, 6 }, 220*e285e32eSBartek Rutkowski { 3, "0 E", (int64_t)92*1024*1024*1024*1024*1024L, 0, 6, 6 }, 221*e285e32eSBartek Rutkowski { 3, "0 E", -(int64_t)92*1024*1024*1024*1024*1024L, 0, 6, 6 }, 222*e285e32eSBartek Rutkowski { 3, "0 E", (int64_t)82*1024*1024*1024*1024*1024L, 0, 6, 6 }, 223*e285e32eSBartek Rutkowski { 3, "0 E", -(int64_t)82*1024*1024*1024*1024*1024L, 0, 6, 6 }, 224*e285e32eSBartek Rutkowski { 3, "0 E", (int64_t)81*1024*1024*1024*1024*1024L, 0, 6, 6 }, 225*e285e32eSBartek Rutkowski { 3, "0 E", -(int64_t)81*1024*1024*1024*1024*1024L, 0, 6, 6 }, 226*e285e32eSBartek Rutkowski { 4, "92 P", (int64_t)92*1024*1024*1024*1024*1024L, 0, 5, 6 }, 227*e285e32eSBartek Rutkowski { 5, "-92 P", -(int64_t)92*1024*1024*1024*1024*1024L, 0, 5, 6 }, 228*e285e32eSBartek Rutkowski { 4, "82 P", (int64_t)82*1024*1024*1024*1024*1024L, 0, 5, 6 }, 229*e285e32eSBartek Rutkowski { 5, "-82 P", -(int64_t)82*1024*1024*1024*1024*1024L, 0, 5, 6 }, 230*e285e32eSBartek Rutkowski { 4, "81 P", (int64_t)81*1024*1024*1024*1024*1024L, 0, 5, 6 }, 231*e285e32eSBartek Rutkowski { 5, "-81 P", -(int64_t)81*1024*1024*1024*1024*1024L, 0, 5, 6 }, 2325aa45fcbSEnji Cooper 2335aa45fcbSEnji Cooper /* Explicit scale, divisor 1000 */ 234*e285e32eSBartek Rutkowski { 3, "9 E", INT64_MAX, HN_DIVISOR_1000, 6, 6 }, 235*e285e32eSBartek Rutkowski { 4, "-9 E", -INT64_MAX, 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 { 3, "0 E", (int64_t)82*1024*1024*1024*1024*1024L, HN_DIVISOR_1000, 6, 6 }, 239*e285e32eSBartek Rutkowski { 3, "0 E", -(int64_t)82*1024*1024*1024*1024*1024L, HN_DIVISOR_1000, 6, 6 }, 240*e285e32eSBartek Rutkowski { 4, "92 P", (int64_t)82*1024*1024*1024*1024*1024L, HN_DIVISOR_1000, 5, 6 }, 241*e285e32eSBartek Rutkowski { 5, "-92 P", -(int64_t)82*1024*1024*1024*1024*1024L, HN_DIVISOR_1000, 5, 6 }, 242*e285e32eSBartek Rutkowski { 4, "91 P", (int64_t)81*1024*1024*1024*1024*1024L, HN_DIVISOR_1000, 5, 6 }, 243*e285e32eSBartek Rutkowski { 5, "-91 P", -(int64_t)81*1024*1024*1024*1024*1024L, HN_DIVISOR_1000, 5, 6 }, 2445aa45fcbSEnji Cooper 2455aa45fcbSEnji Cooper /* Autoscale, divisor 1024 */ 246*e285e32eSBartek Rutkowski { 3, "8 E", INT64_MAX, 0, HN_AUTOSCALE, 6 }, 247*e285e32eSBartek Rutkowski { 4, "-8 E", -INT64_MAX, 0, HN_AUTOSCALE, 6 }, 248*e285e32eSBartek Rutkowski { 4, "92 P", (int64_t)92*1024*1024*1024*1024*1024L, 0, HN_AUTOSCALE, 6 }, 249*e285e32eSBartek Rutkowski { 5, "-92 P", -(int64_t)92*1024*1024*1024*1024*1024L, 0, HN_AUTOSCALE, 6 }, 250*e285e32eSBartek Rutkowski { 4, "82 P", (int64_t)82*1024*1024*1024*1024*1024L, 0, HN_AUTOSCALE, 6 }, 251*e285e32eSBartek Rutkowski { 5, "-82 P", -(int64_t)82*1024*1024*1024*1024*1024L, 0, HN_AUTOSCALE, 6 }, 252*e285e32eSBartek Rutkowski { 4, "81 P", (int64_t)81*1024*1024*1024*1024*1024L, 0, HN_AUTOSCALE, 6 }, 253*e285e32eSBartek Rutkowski { 5, "-81 P", -(int64_t)81*1024*1024*1024*1024*1024L, 0, HN_AUTOSCALE, 6 }, 2545aa45fcbSEnji Cooper /* Autoscale, divisor 1000 */ 255*e285e32eSBartek Rutkowski { 3, "9 E", INT64_MAX, HN_DIVISOR_1000, HN_AUTOSCALE, 6 }, 256*e285e32eSBartek Rutkowski { 4, "-9 E", -INT64_MAX, HN_DIVISOR_1000, HN_AUTOSCALE, 6 }, 257*e285e32eSBartek Rutkowski { 4, "92 P", (int64_t)82*1024*1024*1024*1024*1024L, HN_DIVISOR_1000, HN_AUTOSCALE, 6 }, 258*e285e32eSBartek Rutkowski { 5, "-92 P", -(int64_t)82*1024*1024*1024*1024*1024L, HN_DIVISOR_1000, HN_AUTOSCALE, 6 }, 259*e285e32eSBartek Rutkowski { 4, "91 P", (int64_t)81*1024*1024*1024*1024*1024L, HN_DIVISOR_1000, HN_AUTOSCALE, 6 }, 260*e285e32eSBartek Rutkowski { 5, "-91 P", -(int64_t)81*1024*1024*1024*1024*1024L, HN_DIVISOR_1000, HN_AUTOSCALE, 6 }, 2615aa45fcbSEnji Cooper 2625aa45fcbSEnji Cooper /* 0 scale, divisor 1024 */ 263*e285e32eSBartek Rutkowski { 12, "skdj", INT64_MAX, 0, 0, 6 }, 264*e285e32eSBartek Rutkowski { 21, "-9223", -INT64_MAX, 0, 0, 6 }, 265*e285e32eSBartek Rutkowski { 19, "10358", (int64_t)92*1024*1024*1024*1024*1024L, 0, 0, 6 }, 266*e285e32eSBartek Rutkowski { 20, "-1035", -(int64_t)92*1024*1024*1024*1024*1024L, 0, 0, 6 }, 267*e285e32eSBartek Rutkowski { 18, "92323", (int64_t)82*1024*1024*1024*1024*1024L, 0, 0, 6 }, 268*e285e32eSBartek Rutkowski { 19, "-9232", -(int64_t)82*1024*1024*1024*1024*1024L, 0, 0, 6 }, 269*e285e32eSBartek Rutkowski { 18, "91197", (int64_t)81*1024*1024*1024*1024*1024L, 0, 0, 6 }, 270*e285e32eSBartek Rutkowski { 19, "-9119", -(int64_t)81*1024*1024*1024*1024*1024L, 0, 0, 6 }, 2715aa45fcbSEnji Cooper 2725aa45fcbSEnji Cooper /* 0 scale, divisor 1000 */ 2735aa45fcbSEnji Cooper /* XXX - why does this fail? */ 274*e285e32eSBartek Rutkowski { -1, "", INT64_MAX, HN_DIVISOR_1000, 0, 6 }, 275*e285e32eSBartek Rutkowski { 21, "-9223", -INT64_MAX, HN_DIVISOR_1000, 0, 6 }, 276*e285e32eSBartek Rutkowski { 19, "10358", (int64_t)92*1024*1024*1024*1024*1024L, HN_DIVISOR_1000, 0, 6 }, 277*e285e32eSBartek Rutkowski { 20, "-1035", -(int64_t)92*1024*1024*1024*1024*1024L, HN_DIVISOR_1000, 0, 6 }, 278*e285e32eSBartek Rutkowski { 18, "92323", (int64_t)82*1024*1024*1024*1024*1024L, HN_DIVISOR_1000, 0, 6 }, 279*e285e32eSBartek Rutkowski { 19, "-9232", -(int64_t)82*1024*1024*1024*1024*1024L, HN_DIVISOR_1000, 0, 6 }, 2805aa45fcbSEnji Cooper /* Expected to pass */ 281*e285e32eSBartek Rutkowski { 18, "91197", (int64_t)81*1024*1024*1024*1024*1024L, HN_DIVISOR_1000, 0, 6 }, 282*e285e32eSBartek Rutkowski { 19, "-9119", -(int64_t)81*1024*1024*1024*1024*1024L, HN_DIVISOR_1000, 0, 6 }, 2835aa45fcbSEnji Cooper 2845aa45fcbSEnji Cooper 2855aa45fcbSEnji Cooper 2865aa45fcbSEnji Cooper /* Need to implement tests for GETSCALE */ 287*e285e32eSBartek Rutkowski /* { ?, "", (int64_t)0L, HN_DIVISOR_1000, HN_GETSCALE, 6 }, 2885aa45fcbSEnji Cooper ... 2895aa45fcbSEnji Cooper */ 2905aa45fcbSEnji Cooper /* Tests for HN_DECIMAL */ 2915aa45fcbSEnji Cooper /* Positive, Autoscale */ 292*e285e32eSBartek Rutkowski { 5, "500 k", (int64_t)500*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE, 6 }, 293*e285e32eSBartek Rutkowski { 5, "994 k", (int64_t)994*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE, 6 }, 294*e285e32eSBartek Rutkowski { 5, "995 k", (int64_t)995*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE, 6 }, 295*e285e32eSBartek Rutkowski { 5, "999 k", (int64_t)999*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE, 6 }, 296*e285e32eSBartek Rutkowski { 5, "1.0 M", (int64_t)1000*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE, 6 }, 297*e285e32eSBartek Rutkowski { 5, "1.5 M", (int64_t)1500*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE, 6 }, 298*e285e32eSBartek Rutkowski { 5, "1.9 M", (int64_t)1949*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE, 6 }, 299*e285e32eSBartek Rutkowski { 5, "2.0 M", (int64_t)1950*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE, 6 }, 300*e285e32eSBartek Rutkowski { 5, "9.9 M", (int64_t)9949*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE, 6 }, 301*e285e32eSBartek Rutkowski { 4, "10 M", (int64_t)9950*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE, 6 }, 302*e285e32eSBartek Rutkowski { 5, "500 M", (int64_t)500*1000*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE, 6 }, 303*e285e32eSBartek Rutkowski { 5, "994 M", (int64_t)994*1000*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE, 6 }, 304*e285e32eSBartek Rutkowski { 5, "995 M", (int64_t)995*1000*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE, 6 }, 305*e285e32eSBartek Rutkowski { 5, "999 M", (int64_t)999*1000*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE, 6 }, 3065aa45fcbSEnji Cooper 307*e285e32eSBartek Rutkowski { 5, "500 K", (int64_t)500*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 }, 308*e285e32eSBartek Rutkowski { 5, "994 K", (int64_t)994*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 }, 309*e285e32eSBartek Rutkowski { 5, "995 K", (int64_t)995*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 }, 310*e285e32eSBartek Rutkowski { 5, "999 K", (int64_t)999*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 }, 311*e285e32eSBartek Rutkowski { 5, "1.0 M", (int64_t)1000*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 }, 312*e285e32eSBartek Rutkowski { 5, "1.0 M", (int64_t)1018*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 }, 313*e285e32eSBartek Rutkowski { 5, "1.0 M", (int64_t)1019*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 }, 314*e285e32eSBartek Rutkowski { 5, "1.5 M", (int64_t)1536*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 }, 315*e285e32eSBartek Rutkowski { 5, "1.9 M", (int64_t)1996*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 }, 316*e285e32eSBartek Rutkowski { 5, "2.0 M", (int64_t)1997*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 }, 317*e285e32eSBartek Rutkowski { 5, "2.0 M", (int64_t)2047*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 }, 318*e285e32eSBartek Rutkowski { 5, "2.0 M", (int64_t)2048*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 }, 319*e285e32eSBartek Rutkowski { 5, "2.0 M", (int64_t)2099*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 }, 320*e285e32eSBartek Rutkowski { 5, "2.1 M", (int64_t)2100*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 }, 321*e285e32eSBartek Rutkowski { 5, "9.9 M", (int64_t)10188*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 }, 3225aa45fcbSEnji Cooper /* XXX - shouldn't the following two be "10. M"? */ 323*e285e32eSBartek Rutkowski { 4, "10 M", (int64_t)10189*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 }, 324*e285e32eSBartek Rutkowski { 4, "10 M", (int64_t)10240*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 }, 325*e285e32eSBartek Rutkowski { 5, "500 M", (int64_t)500*1024*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 }, 326*e285e32eSBartek Rutkowski { 5, "994 M", (int64_t)994*1024*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 }, 327*e285e32eSBartek Rutkowski { 5, "995 M", (int64_t)995*1024*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 }, 328*e285e32eSBartek Rutkowski { 5, "999 M", (int64_t)999*1024*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 }, 329*e285e32eSBartek Rutkowski { 5, "1.0 G", (int64_t)1000*1024*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 }, 330*e285e32eSBartek Rutkowski { 5, "1.0 G", (int64_t)1023*1024*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 }, 3315aa45fcbSEnji Cooper 3325aa45fcbSEnji Cooper /* Negative, Autoscale - should pass */ 333*e285e32eSBartek Rutkowski { 6, "-1.5 ", -(int64_t)1500*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE, 6 }, 334*e285e32eSBartek Rutkowski { 6, "-1.9 ", -(int64_t)1949*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE, 6 }, 335*e285e32eSBartek Rutkowski { 6, "-9.9 ", -(int64_t)9949*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE, 6 }, 3365aa45fcbSEnji Cooper 337*e285e32eSBartek Rutkowski { 6, "-1.5 ", -(int64_t)1536*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 }, 338*e285e32eSBartek Rutkowski { 6, "-1.9 ", -(int64_t)1949*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 }, 339*e285e32eSBartek Rutkowski { 6, "-9.7 ", -(int64_t)9949*1024L, HN_DECIMAL, HN_AUTOSCALE, 6 }, 3405aa45fcbSEnji Cooper 3415aa45fcbSEnji Cooper /* Positive/negative, at maximum scale */ 342*e285e32eSBartek Rutkowski { 5, "500 P", (int64_t)500*1000*1000*1000*1000*1000L, HN_DIVISOR_1000, HN_AUTOSCALE, 6 }, 343*e285e32eSBartek Rutkowski { 5, "1.9 E", (int64_t)1949*1000*1000*1000*1000*1000L, HN_DIVISOR_1000, HN_AUTOSCALE, 6 }, 344*e285e32eSBartek Rutkowski { 5, "8.9 E", (int64_t)8949*1000*1000*1000*1000*1000L, HN_DIVISOR_1000, HN_AUTOSCALE, 6 }, 345*e285e32eSBartek Rutkowski { 5, "9.2 E", INT64_MAX, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE, 6 }, 3465aa45fcbSEnji Cooper /* Negatives work with latest rev only: */ 347*e285e32eSBartek Rutkowski { 6, "-9.2 ", -INT64_MAX, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE, 6 }, 348*e285e32eSBartek Rutkowski { 6, "-8.9 ", -(int64_t)8949*1000*1000*1000*1000*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE, 6 }, 3495aa45fcbSEnji Cooper 350*e285e32eSBartek Rutkowski { 5, "8.0 E", INT64_MAX, HN_DECIMAL, HN_AUTOSCALE, 6 }, 351*e285e32eSBartek Rutkowski { 5, "7.9 E", INT64_MAX-(int64_t)100*1024*1024*1024*1024*1024LL, HN_DECIMAL, HN_AUTOSCALE, 6 }, 352*e285e32eSBartek Rutkowski { 6, "-8.0 ", -INT64_MAX, HN_DECIMAL, HN_AUTOSCALE, 6 }, 353*e285e32eSBartek Rutkowski { 6, "-7.9 ", -INT64_MAX+(int64_t)100*1024*1024*1024*1024*1024LL, HN_DECIMAL, HN_AUTOSCALE, 6 }, 3545aa45fcbSEnji Cooper 3555aa45fcbSEnji Cooper /* Positive, Fixed scales */ 356*e285e32eSBartek Rutkowski { 5, "500 k", (int64_t)500*1000L, HN_DECIMAL|HN_DIVISOR_1000, 1, 6 }, 357*e285e32eSBartek Rutkowski { 5, "0.5 M", (int64_t)500*1000L, HN_DECIMAL|HN_DIVISOR_1000, 2, 6 }, 358*e285e32eSBartek Rutkowski { 5, "949 k", (int64_t)949*1000L, HN_DECIMAL|HN_DIVISOR_1000, 1, 6 }, 359*e285e32eSBartek Rutkowski { 5, "0.9 M", (int64_t)949*1000L, HN_DECIMAL|HN_DIVISOR_1000, 2, 6 }, 360*e285e32eSBartek Rutkowski { 5, "950 k", (int64_t)950*1000L, HN_DECIMAL|HN_DIVISOR_1000, 1, 6 }, 361*e285e32eSBartek Rutkowski { 5, "1.0 M", (int64_t)950*1000L, HN_DECIMAL|HN_DIVISOR_1000, 2, 6 }, 362*e285e32eSBartek Rutkowski { 5, "999 k", (int64_t)999*1000L, HN_DECIMAL|HN_DIVISOR_1000, 1, 6 }, 363*e285e32eSBartek Rutkowski { 5, "1.0 M", (int64_t)999*1000L, HN_DECIMAL|HN_DIVISOR_1000, 2, 6 }, 364*e285e32eSBartek Rutkowski { 5, "1.5 M", (int64_t)1500*1000L, HN_DECIMAL|HN_DIVISOR_1000, 2, 6 }, 365*e285e32eSBartek Rutkowski { 5, "1.9 M", (int64_t)1949*1000L, HN_DECIMAL|HN_DIVISOR_1000, 2, 6 }, 366*e285e32eSBartek Rutkowski { 5, "2.0 M", (int64_t)1950*1000L, HN_DECIMAL|HN_DIVISOR_1000, 2, 6 }, 367*e285e32eSBartek Rutkowski { 5, "9.9 M", (int64_t)9949*1000L, HN_DECIMAL|HN_DIVISOR_1000, 2, 6 }, 368*e285e32eSBartek Rutkowski { 4, "10 M", (int64_t)9950*1000L, HN_DECIMAL|HN_DIVISOR_1000, 2, 6 }, 369*e285e32eSBartek Rutkowski { 5, "500 M", (int64_t)500*1000*1000L, HN_DECIMAL|HN_DIVISOR_1000, 2, 6 }, 370*e285e32eSBartek Rutkowski { 5, "0.5 G", (int64_t)500*1000*1000L, HN_DECIMAL|HN_DIVISOR_1000, 3, 6 }, 371*e285e32eSBartek Rutkowski { 5, "999 M", (int64_t)999*1000*1000L, HN_DECIMAL|HN_DIVISOR_1000, 2, 6 }, 372*e285e32eSBartek Rutkowski { 5, "1.0 G", (int64_t)999*1000*1000L, HN_DECIMAL|HN_DIVISOR_1000, 3, 6 }, 3735aa45fcbSEnji Cooper /* Positive/negative, at maximum scale */ 374*e285e32eSBartek Rutkowski { 5, "500 P", (int64_t)500*1000*1000*1000*1000*1000L, HN_DIVISOR_1000, 5, 6 }, 375*e285e32eSBartek Rutkowski { 5, "1.0 E", (int64_t)500*1000*1000*1000*1000*1000L, HN_DIVISOR_1000, 6, 6 }, 376*e285e32eSBartek Rutkowski { 5, "1.9 E", (int64_t)1949*1000*1000*1000*1000*1000L, HN_DIVISOR_1000, 6, 6 }, 377*e285e32eSBartek Rutkowski { 5, "8.9 E", (int64_t)8949*1000*1000*1000*1000*1000L, HN_DIVISOR_1000, 6, 6 }, 378*e285e32eSBartek Rutkowski { 5, "9.2 E", INT64_MAX, HN_DECIMAL|HN_DIVISOR_1000, 6, 6 }, 3795aa45fcbSEnji Cooper 3805aa45fcbSEnji Cooper /* HN_DECIMAL + binary + fixed scale cases not completed */ 381*e285e32eSBartek Rutkowski { 5, "512 K", (int64_t)512*1024L, HN_DECIMAL, 1, 6 }, 382*e285e32eSBartek Rutkowski { 5, "0.5 M", (int64_t)512*1024L, HN_DECIMAL, 2, 6 }, 3835aa45fcbSEnji Cooper 3845aa45fcbSEnji Cooper /* Negative, Fixed scales */ 3855aa45fcbSEnji Cooper /* Not yet added, but should work with latest rev */ 3865aa45fcbSEnji Cooper 3875aa45fcbSEnji Cooper }; 3885aa45fcbSEnji Cooper 3895aa45fcbSEnji Cooper 3905aa45fcbSEnji Cooper /* Command line options usage */ 3915aa45fcbSEnji Cooper static void 3925aa45fcbSEnji Cooper usage(char * progname) { 3935aa45fcbSEnji Cooper printf("%s: tests libutil humanize_number function\n", progname); 3945aa45fcbSEnji Cooper printf("Usage: %s [-nE] [-l num] [-v]\n\n", progname); 3955aa45fcbSEnji Cooper printf("Options:\n"); 3965aa45fcbSEnji Cooper printf("\t-l num\tSet max length for result; buflen = num + 1\n"); 3975aa45fcbSEnji Cooper printf("\t\t (NOTE: does not change expected result strings.)\n"); 3985aa45fcbSEnji Cooper printf("\t-n\tInclude negative scale tests, which cause older libutil\n"); 3995aa45fcbSEnji Cooper printf("\t\t version of function to coredump with assertion failure\n"); 4005aa45fcbSEnji Cooper printf("\t-E\tInclude numbers > 1/2 Exa[byte] which currently fail\n"); 4015aa45fcbSEnji Cooper printf("\t-v\tVerbose - always print summary results\n"); 4025aa45fcbSEnji Cooper printf("\t-h, -?\tShow options\n"); 4035aa45fcbSEnji Cooper } 4045aa45fcbSEnji Cooper 4055aa45fcbSEnji Cooper /* Parse command line options */ 4065aa45fcbSEnji Cooper static void 4075aa45fcbSEnji Cooper read_options(int argc, char * const argv[], size_t *bufLength, 4085aa45fcbSEnji Cooper int *includeNegativeScale, int *includeExabytes, int *verbose) { 4095aa45fcbSEnji Cooper int ch; 4105aa45fcbSEnji Cooper size_t temp; 4115aa45fcbSEnji Cooper 4125aa45fcbSEnji Cooper while ((ch = getopt(argc, argv, "nEh?vl:")) != -1) { 4135aa45fcbSEnji Cooper switch (ch) { 4145aa45fcbSEnji Cooper default: 4155aa45fcbSEnji Cooper usage(argv[0]); 4165aa45fcbSEnji Cooper exit(1); 4175aa45fcbSEnji Cooper break; /* UNREACHABLE */ 4185aa45fcbSEnji Cooper case 'h' : 4195aa45fcbSEnji Cooper case '?' : 4205aa45fcbSEnji Cooper usage(argv[0]); 4215aa45fcbSEnji Cooper exit(0); 4225aa45fcbSEnji Cooper break; /* UNREACHABLE */ 4235aa45fcbSEnji Cooper case 'l' : 4245aa45fcbSEnji Cooper sscanf(optarg, "%zu", &temp); 4255aa45fcbSEnji Cooper *bufLength = temp + 1; 4265aa45fcbSEnji Cooper break; 4275aa45fcbSEnji Cooper case 'n' : 4285aa45fcbSEnji Cooper *includeNegativeScale = 1; 4295aa45fcbSEnji Cooper break; 4305aa45fcbSEnji Cooper case 'E' : 4315aa45fcbSEnji Cooper *includeExabytes = 1; 4325aa45fcbSEnji Cooper break; 4335aa45fcbSEnji Cooper case 'v' : 4345aa45fcbSEnji Cooper *verbose = 1; 4355aa45fcbSEnji Cooper break; 4365aa45fcbSEnji Cooper } 4375aa45fcbSEnji Cooper } 4385aa45fcbSEnji Cooper } 4395aa45fcbSEnji Cooper 4405aa45fcbSEnji Cooper static struct { 4415aa45fcbSEnji Cooper int value; 4425aa45fcbSEnji Cooper const char *name; 4435aa45fcbSEnji Cooper } flags[] = { 4445aa45fcbSEnji Cooper { HN_AUTOSCALE, "HN_AUTOSCALE" }, 4455aa45fcbSEnji Cooper { HN_GETSCALE, "HN_GETSCALE" }, 4465aa45fcbSEnji Cooper { HN_DIVISOR_1000, "HN_DIVISOR_1000" }, 4475aa45fcbSEnji Cooper { HN_B, "HN_B" }, 4485aa45fcbSEnji Cooper { HN_DECIMAL, "HN_DECIMAL" }, 4495aa45fcbSEnji Cooper }; 4505aa45fcbSEnji Cooper 4515aa45fcbSEnji Cooper static const char *separator = "|"; 4525aa45fcbSEnji Cooper 4535aa45fcbSEnji Cooper /* Format flags parameter for meaningful display */ 4545aa45fcbSEnji Cooper static char * 4555aa45fcbSEnji Cooper str_flags(int hn_flags, char *noFlags) { 4565aa45fcbSEnji Cooper size_t i; 4575aa45fcbSEnji Cooper char * result; 4585aa45fcbSEnji Cooper 4595aa45fcbSEnji Cooper result = malloc(MAX_STR_FLAGS_RESULT); 4605aa45fcbSEnji Cooper result[0] = '\0'; 4615aa45fcbSEnji Cooper 4625aa45fcbSEnji Cooper for (i = 0; i < sizeof flags / sizeof *flags; i++) { 4635aa45fcbSEnji Cooper if (hn_flags & flags[i].value) { 4645aa45fcbSEnji Cooper if (*result != 0) 4655aa45fcbSEnji Cooper strlcat(result, separator, 4665aa45fcbSEnji Cooper MAX_STR_FLAGS_RESULT); 4675aa45fcbSEnji Cooper strlcat(result, flags[i].name, MAX_STR_FLAGS_RESULT); 4685aa45fcbSEnji Cooper } 4695aa45fcbSEnji Cooper } 4705aa45fcbSEnji Cooper 4715aa45fcbSEnji Cooper if (strlen(result) == 0) 4725aa45fcbSEnji Cooper strlcat(result, noFlags, MAX_STR_FLAGS_RESULT); 4735aa45fcbSEnji Cooper return result; 4745aa45fcbSEnji Cooper } 4755aa45fcbSEnji Cooper 4765aa45fcbSEnji Cooper 4775aa45fcbSEnji Cooper /* Format scale parameter for meaningful display */ 4785aa45fcbSEnji Cooper static char * 4795aa45fcbSEnji Cooper str_scale(int scale) { 4805aa45fcbSEnji Cooper char *result; 4815aa45fcbSEnji Cooper 4825aa45fcbSEnji Cooper if (scale == HN_AUTOSCALE || scale == HN_GETSCALE) 4835aa45fcbSEnji Cooper return str_flags(scale, ""); 4845aa45fcbSEnji Cooper 4855aa45fcbSEnji Cooper result = malloc(MAX_INT_STR_DIGITS); 4865aa45fcbSEnji Cooper result[0] = '\0'; 4875aa45fcbSEnji Cooper snprintf(result, MAX_INT_STR_DIGITS, "%d", scale); 4885aa45fcbSEnji Cooper return result; 4895aa45fcbSEnji Cooper } 4905aa45fcbSEnji Cooper 4915aa45fcbSEnji Cooper static void 4925aa45fcbSEnji Cooper testskipped(size_t i) 4935aa45fcbSEnji Cooper { 4945aa45fcbSEnji Cooper 4955aa45fcbSEnji Cooper printf("ok %zu # skip - not turned on\n", i); 4965aa45fcbSEnji Cooper } 4975aa45fcbSEnji Cooper 4985aa45fcbSEnji Cooper int 4995aa45fcbSEnji Cooper main(int argc, char * const argv[]) 5005aa45fcbSEnji Cooper { 5015aa45fcbSEnji Cooper char *buf; 5025aa45fcbSEnji Cooper char *flag_str, *scale_str; 503*e285e32eSBartek Rutkowski size_t blen, buflen, errcnt, i, skipped, tested; 5045aa45fcbSEnji Cooper int r; 5055aa45fcbSEnji Cooper int includeNegScale; 5065aa45fcbSEnji Cooper int includeExabyteTests; 5075aa45fcbSEnji Cooper int verbose; 5085aa45fcbSEnji Cooper 509*e285e32eSBartek Rutkowski buf = NULL; 510*e285e32eSBartek Rutkowski buflen = 0; 5115aa45fcbSEnji Cooper includeNegScale = 0; 5125aa45fcbSEnji Cooper includeExabyteTests = 0; 5135aa45fcbSEnji Cooper verbose = 0; 5145aa45fcbSEnji Cooper 5155aa45fcbSEnji Cooper read_options(argc, argv, &buflen, &includeNegScale, 5165aa45fcbSEnji Cooper &includeExabyteTests, &verbose); 5175aa45fcbSEnji Cooper 5185aa45fcbSEnji Cooper errcnt = 0; 5195aa45fcbSEnji Cooper tested = 0; 5205aa45fcbSEnji Cooper skipped = 0; 5215aa45fcbSEnji Cooper 5225aa45fcbSEnji Cooper if (buflen != 4) 5235aa45fcbSEnji Cooper printf("Warning: buffer size %zu != 4, expect some results to differ.\n", buflen); 5245aa45fcbSEnji Cooper 5255aa45fcbSEnji Cooper printf("1..%zu\n", nitems(test_args)); 5265aa45fcbSEnji Cooper for (i = 0; i < nitems(test_args); i++) { 527*e285e32eSBartek Rutkowski blen = (buflen > 0) ? buflen : test_args[i].buflen; 528*e285e32eSBartek Rutkowski buf = realloc(buf, blen); 5295aa45fcbSEnji Cooper 5305aa45fcbSEnji Cooper if (test_args[i].scale < 0 && ! includeNegScale) { 5315aa45fcbSEnji Cooper skipped++; 5325aa45fcbSEnji Cooper testskipped(i + 1); 5335aa45fcbSEnji Cooper continue; 5345aa45fcbSEnji Cooper } 5355aa45fcbSEnji Cooper if (test_args[i].num >= halfExabyte && ! includeExabyteTests) { 5365aa45fcbSEnji Cooper skipped++; 5375aa45fcbSEnji Cooper testskipped(i + 1); 5385aa45fcbSEnji Cooper continue; 5395aa45fcbSEnji Cooper } 5405aa45fcbSEnji Cooper 541*e285e32eSBartek Rutkowski r = humanize_number(buf, blen, test_args[i].num, "", 5425aa45fcbSEnji Cooper test_args[i].scale, test_args[i].flags); 5435aa45fcbSEnji Cooper flag_str = str_flags(test_args[i].flags, "[no flags]"); 5445aa45fcbSEnji Cooper scale_str = str_scale(test_args[i].scale); 5455aa45fcbSEnji Cooper 5465aa45fcbSEnji Cooper if (r != test_args[i].retval) { 5475aa45fcbSEnji Cooper if (verbose) 5485aa45fcbSEnji Cooper printf("wrong return value on index %zu, " 5495aa45fcbSEnji Cooper "buflen: %zu, got: %d + \"%s\", " 5505aa45fcbSEnji Cooper "expected %d + \"%s\"; num = %jd, " 5515aa45fcbSEnji Cooper "scale = %s, flags= %s.\n", 552*e285e32eSBartek Rutkowski i, blen, r, buf, test_args[i].retval, 5535aa45fcbSEnji Cooper test_args[i].res, 5545aa45fcbSEnji Cooper (intmax_t)test_args[i].num, 5555aa45fcbSEnji Cooper scale_str, flag_str); 5565aa45fcbSEnji Cooper else 5575aa45fcbSEnji Cooper printf("not ok %zu # return %d != %d\n", 5585aa45fcbSEnji Cooper i + 1, r, test_args[i].retval); 5595aa45fcbSEnji Cooper errcnt++; 5605aa45fcbSEnji Cooper } else if (strcmp(buf, test_args[i].res) != 0) { 5615aa45fcbSEnji Cooper if (verbose) 5625aa45fcbSEnji Cooper printf("result mismatch on index %zu, got: " 5635aa45fcbSEnji Cooper "\"%s\", expected \"%s\"; num = %jd, " 564*e285e32eSBartek Rutkowski "buflen: %zu, scale = %s, flags= %s.\n", 5655aa45fcbSEnji Cooper i, buf, test_args[i].res, 5665aa45fcbSEnji Cooper (intmax_t)test_args[i].num, 567*e285e32eSBartek Rutkowski blen, scale_str, flag_str); 5685aa45fcbSEnji Cooper else 5695aa45fcbSEnji Cooper printf("not ok %zu # buf \"%s\" != \"%s\"\n", 5705aa45fcbSEnji Cooper i + 1, buf, test_args[i].res); 5715aa45fcbSEnji Cooper errcnt++; 5725aa45fcbSEnji Cooper } else { 5735aa45fcbSEnji Cooper if (verbose) 5745aa45fcbSEnji Cooper printf("successful result on index %zu, " 5755aa45fcbSEnji Cooper "returned %d, got: \"%s\"; num = %jd, " 576*e285e32eSBartek Rutkowski "buflen = %zd, scale = %s, flags= %s.\n", 577*e285e32eSBartek Rutkowski i, r, buf, (intmax_t)test_args[i].num, 578*e285e32eSBartek Rutkowski blen, scale_str, flag_str); 5795aa45fcbSEnji Cooper else 5805aa45fcbSEnji Cooper printf("ok %zu\n", i + 1); 5815aa45fcbSEnji Cooper } 5825aa45fcbSEnji Cooper tested++; 5835aa45fcbSEnji Cooper } 584*e285e32eSBartek Rutkowski free(buf); 5855aa45fcbSEnji Cooper 5865aa45fcbSEnji Cooper if (verbose) 5875aa45fcbSEnji Cooper printf("total errors: %zu/%zu tests, %zu skipped\n", errcnt, 5885aa45fcbSEnji Cooper tested, skipped); 5895aa45fcbSEnji Cooper 5905aa45fcbSEnji Cooper if (errcnt) 5915aa45fcbSEnji Cooper return 1; 5925aa45fcbSEnji Cooper 5935aa45fcbSEnji Cooper return 0; 5945aa45fcbSEnji Cooper } 595