fmt_test.c revision 1.3
1/* $OpenBSD */ 2 3/* 4 * Combined tests for fmt_scaled and scan_scaled. 5 * Ian Darwin, January 2001. Public domain. 6 */ 7 8#include <stdio.h> 9#include <stdlib.h> 10#include <string.h> 11#include <sys/types.h> 12#include <errno.h> 13 14#include <util.h> 15 16static int fmt_test(void); 17static int scan_test(void); 18 19static void print_errno(int e); 20static int assert_int(int testnum, int checknum, int expect, int result); 21static int assert_errno(int testnum, int checknum, int expect, int result); 22static int assert_quad_t(int testnum, int checknum, quad_t expect, quad_t result); 23static int assert_str(int testnum, int checknum, char * expect, char * result); 24 25extern char *__progname; 26static int verbose = 0; 27 28__dead static void usage(int stat) 29{ 30 fprintf(stderr, "usage: %s [-v]\n", __progname); 31 exit(stat); 32} 33 34int 35main(int argc, char **argv) 36{ 37 extern char *optarg; 38 extern int optind; 39 int i, ch; 40 41 while ((ch = getopt(argc, argv, "hv")) != -1) { 42 switch (ch) { 43 case 'v': 44 verbose = 1; 45 break; 46 case 'h': 47 usage(0); 48 case '?': 49 default: 50 usage(1); 51 } 52 } 53 argc -= optind; 54 argv += optind; 55 56 if (verbose) 57 printf("Starting fmt_test\n"); 58 i = fmt_test(); 59 if (verbose) 60 printf("Starting scan_test\n"); 61 i += scan_test(); 62 if (i) { 63 printf("*** %d errors in libutil/fmt_scaled tests ***\n", i); 64 } else { 65 if (verbose) 66 printf("Tests done; no unexpected errors\n"); 67 } 68 return i; 69} 70 71/************** tests for fmt_scaled *******************/ 72 73static struct { /* the test cases */ 74 quad_t input; 75 char *expect; 76 int errno; 77} ddata[] = { 78 { 0, "0B", 0 }, 79 { 1, "1B", 0 }, 80 { -1, "-1B", 0 }, 81 { 100, "100B", 0}, 82 { -100, "-100B", 0}, 83 { 999, "999B", 0 }, 84 { 1000, "1000B", 0 }, 85 { 1023, "1023B", 0 }, 86 { -1023, "-1023B", 0 }, 87 { 1024, "1.0K", 0 }, 88 { 1025, "1.0K", 0 }, 89 { 1234, "1.2K", 0 }, 90 { -1234, "-1.2K", 0 }, 91 { 1484, "1.4K", 0 }, /* rouding boundary, down */ 92 { 1485, "1.5K", 0 }, /* rouding boundary, up */ 93 { -1484, "-1.4K", 0 }, /* rouding boundary, down */ 94 { -1485, "-1.5K", 0 }, /* rouding boundary, up */ 95 { 1536, "1.5K", 0 }, 96 { 1786, "1.7K", 0 }, 97 { 1800, "1.8K", 0 }, 98 { 2000, "2.0K", 0 }, 99 { 123456, "120K", 0 }, 100 { -102400, "-100K", 0}, 101 { -103423, "-101K", 0 }, 102 { 7299072, "7.0M", 0 }, 103 { 409478144L, "390M", 0 }, 104 { -409478144L, "-390M", 0 }, 105 { 999999999L, "953M", 0 }, 106 { 1499999999L, "1.4G", 0 }, 107 { 12475423744LL, "11.6G", 0}, 108 { 1LL<<61, "2.0E", 0 }, 109 { 1LL<<62, "4.0E", 0 }, 110 { 1LL<<63, "", ERANGE }, 111}; 112# define DDATA_LENGTH (sizeof ddata/sizeof *ddata) 113 114static int 115fmt_test(void) 116{ 117 unsigned int i, e, errs = 0; 118 int ret; 119 char buf[FMT_SCALED_STRSIZE]; 120 121 for (i = 0; i < DDATA_LENGTH; i++) { 122 strlcpy(buf, "UNSET", FMT_SCALED_STRSIZE); 123 ret = fmt_scaled(ddata[i].input, buf); 124 e = errno; 125 if (verbose) { 126 printf("%lld --> %s (%d)", ddata[i].input, buf, ret); 127 if (ret == -1) 128 print_errno(e); 129 printf("\n"); 130 } 131 if (ret == -1) 132 errs += assert_int(i, 1, ret, ddata[i].errno == 0 ? 0 : -1); 133 if (ddata[i].errno) 134 errs += assert_errno(i, 2, ddata[i].errno, errno); 135 else 136 errs += assert_str(i, 3, ddata[i].expect, buf); 137 } 138 139 return errs; 140} 141 142/************** tests for scan_scaled *******************/ 143 144 145#define IMPROBABLE (-42) 146 147extern int errno; 148 149struct { /* the test cases */ 150 char *input; 151 quad_t result; 152 int errno; 153} sdata[] = { 154 { "0", 0, 0 }, 155 { "123", 123, 0 }, 156 { "1k", 1024, 0 }, /* lower case */ 157 { "100.944", 100, 0 }, /* should --> 100 (truncates fraction) */ 158 { "10099", 10099LL, 0 }, 159 { "1M", 1048576LL, 0 }, 160 { "1.1M", 1153433LL, 0 }, /* fractions */ 161 { "1.111111111111111111M", 1165084LL, 0 }, /* fractions */ 162 { "1.55M", 1625292LL, 0 }, /* fractions */ 163 { "1.9M", 1992294LL, 0 }, /* fractions */ 164 { "-2K", -2048LL, 0 }, /* negatives */ 165 { "-2.2K", -2252LL, 0 }, /* neg with fract */ 166 { "4.5k", 4608, 0 }, 167 { "4.5555555555555555K", 4664, 0 }, 168 { "4.5555555555555555555K", 4664, 0 }, /* handle enough digits? */ 169 { "4.555555555555555555555555555555K", 4664, 0 }, /* ignores extra digits? */ 170 { "1G", 1073741824LL, 0 }, 171 { "G", 0, 0 }, /* should == 0G? */ 172 { "1234567890", 1234567890LL, 0 }, /* should work */ 173 { "1.5E", 1729382256910270464LL, 0 }, /* big */ 174 { "32948093840918378473209480483092", 0, ERANGE }, /* too big */ 175 { "329480938409.8378473209480483092", 0, ERANGE }, /* fraction too big */ 176 { "1.5Q", 0, ERANGE }, /* invalid multiplier (XXX ERANGE??) */ 177 { "1ab", 0, ERANGE }, /* ditto */ 178 { "5.0e3", 0, EINVAL }, /* digits after */ 179 { "5.0E3", 0, EINVAL }, /* ditto */ 180 { "1..0", 0, EINVAL }, /* bad format */ 181 { "", 0, 0 }, /* boundary */ 182 { "--1", -1, EINVAL }, 183 { "++42", -1, EINVAL }, 184 { NULL, 0, EFAULT } /* bad input */ 185 /* { "9223372036854775808", -9223372036854775808LL, 0 }, */ /* XXX */ 186}; 187# define SDATA_LENGTH (sizeof sdata/sizeof *sdata) 188 189static void 190print_errno(int e) 191{ 192 switch(e) { 193 case EINVAL: printf("EINVAL"); break; 194 case EFAULT: printf("EFAULT"); break; 195 case EDOM: printf("EDOM"); break; 196 case ERANGE: printf("ERANGE"); break; 197 default: printf("errno %d", errno); 198 } 199} 200 201/** Print one result */ 202static void 203print(char *input, quad_t result, int ret) 204{ 205 int e = errno; 206 printf("\"%10s\" --> %lld (%d)", input, result, ret); 207 if (ret == -1) { 208 printf(" -- "); 209 print_errno(e); 210 } 211 printf("\n"); 212} 213 214static int 215scan_test(void) 216{ 217 unsigned int i, errs = 0, e; 218 int ret; 219 quad_t result; 220 221 for (i = 0; i < SDATA_LENGTH; i++) { 222 result = IMPROBABLE; 223 /* printf("Calling scan_scaled(%s, ...)\n", sdata[i].input); */ 224 ret = scan_scaled(sdata[i].input, &result); 225 e = errno; /* protect across printfs &c. */ 226 if (verbose) 227 print(sdata[i].input, result, ret); 228 errno = e; 229 if (ret == -1) 230 errs += assert_int(i, 1, ret, sdata[i].errno == 0 ? 0 : -1); 231 errno = e; 232 if (sdata[i].errno) 233 errs += assert_errno(i, 2, sdata[i].errno, errno); 234 else 235 errs += assert_quad_t(i, 3, sdata[i].result, result); 236 } 237 return errs; 238} 239 240/************** common testing stuff *******************/ 241 242static int 243assert_int(int testnum, int check, int expect, int result) 244{ 245 if (expect == result) 246 return 0; 247 printf("** FAILURE: test %d check %d, expect %d, result %d **\n", 248 testnum, check, expect, result); 249 return 1; 250} 251 252static int 253assert_errno(int testnum, int check, int expect, int result) 254{ 255 if (expect == result) 256 return 0; 257 printf("** FAILURE: test %d check %d, expect ", 258 testnum, check); 259 print_errno(expect); 260 printf(", got "); 261 print_errno(result); 262 printf(" **\n"); 263 return 1; 264} 265 266static int 267assert_quad_t(int testnum, int check, quad_t expect, quad_t result) 268{ 269 if (expect == result) 270 return 0; 271 printf("** FAILURE: test %d check %d, expect %lld, result %lld **\n", 272 testnum, check, expect, result); 273 return 1; 274} 275 276static int 277assert_str(int testnum, int check, char * expect, char * result) 278{ 279 if (strcmp(expect, result) == 0) 280 return 0; 281 printf("** FAILURE: test %d check %d, expect %s, result %s **\n", 282 testnum, check, expect, result); 283 return 1; 284} 285