testfmt.c (5339B)
1 #include <u.h> 2 #include <libc.h> 3 #include <stdio.h> 4 5 int failed; 6 7 /* Consume argument and ignore it */ 8 int 9 Zflag(Fmt* f) 10 { 11 if(va_arg(f->args, int)) 12 ; 13 return 1; /* it's a flag */ 14 } 15 16 void 17 verify(char *s, char *t) 18 { 19 if(strcmp(s, t) != 0){ 20 failed = 1; 21 fprintf(stderr, "error: (%s) != (%s)\n", s, t); 22 } 23 free(s); 24 } 25 26 Rune lightsmiley = 0x263a; 27 Rune darksmiley = 0x263b; 28 29 /* Test printer that loads unusual decimal point and separator */ 30 char* 31 mysmprint(char *fmt, ...) 32 { 33 Fmt f; 34 35 if(fmtstrinit(&f) < 0) 36 return 0; 37 va_start(f.args, fmt); 38 f.decimal = smprint("%C", lightsmiley); 39 f.thousands = smprint("%C", darksmiley); 40 f.grouping = "\1\2\3\4"; 41 if(dofmt(&f, fmt) < 0) 42 return 0; 43 va_end(f.args); 44 return fmtstrflush(&f); 45 } 46 47 double near1[] = { 48 0.5, 49 0.95, 50 0.995, 51 0.9995, 52 0.99995, 53 0.999995, 54 0.9999995, 55 0.99999995, 56 0.999999995, 57 }; 58 59 void 60 main(int argc, char **argv) 61 { 62 int i, j; 63 64 quotefmtinstall(); 65 fmtinstall('Z', Zflag); 66 fmtinstall(L'\x263a', Zflag); 67 #ifdef PLAN9PORT 68 { extern int __ifmt(Fmt*); 69 fmtinstall('i', __ifmt); 70 } 71 #endif 72 73 verify(smprint("hello world"), "hello world"); 74 #ifdef PLAN9PORT 75 verify(smprint("x: %ux", 0x87654321), "x: 87654321"); 76 #else 77 verify(smprint("x: %x", 0x87654321), "x: 87654321"); 78 #endif 79 verify(smprint("d: %d", 0x87654321), "d: -2023406815"); 80 verify(smprint("s: %s", "hi there"), "s: hi there"); 81 verify(smprint("q: %q", "hi i'm here"), "q: 'hi i''m here'"); 82 verify(smprint("c: %c", '!'), "c: !"); 83 verify(smprint("g: %g %g %g", 3.14159, 3.14159e10, 3.14159e-10), "g: 3.14159 3.14159e+10 3.14159e-10"); 84 verify(smprint("e: %e %e %e", 3.14159, 3.14159e10, 3.14159e-10), "e: 3.141590e+00 3.141590e+10 3.141590e-10"); 85 verify(smprint("f: %f %f %f", 3.14159, 3.14159e10, 3.14159e-10), "f: 3.141590 31415900000.000000 0.000000"); 86 verify(smprint("smiley: %C", (Rune)0x263a), "smiley: \xe2\x98\xba"); 87 verify(smprint("%g %.18g", 2e25, 2e25), "2e+25 2e+25"); 88 verify(smprint("%2.18g", 1.0), " 1"); 89 verify(smprint("%f", 3.1415927/4), "0.785398"); 90 verify(smprint("%d", 23), "23"); 91 verify(smprint("%i", 23), "23"); 92 verify(smprint("%Zi", 1234, 23), "23"); 93 94 /* ANSI and their wacky corner cases */ 95 verify(smprint("%.0d", 0), ""); 96 verify(smprint("%.0o", 0), ""); 97 verify(smprint("%.0x", 0), ""); 98 verify(smprint("%#.0o", 0), "0"); 99 verify(smprint("%#.0x", 0), ""); 100 101 /* difficult floating point tests that many libraries get wrong */ 102 verify(smprint("%.100f", 1.0), "1.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"); 103 verify(smprint("%.100g", 1.0), "1"); 104 verify(smprint("%0100f", 1.0), "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.000000"); 105 for(i=1; i<9; i++) 106 for(j=0; j<=i; j++) 107 verify(smprint("%.*g", j, near1[i]), "1"); 108 109 /* test $ reorderings */ 110 verify(smprint("%3$d %4$06d %2$d %1$d", 444, 333, 111, 222), "111 000222 333 444"); 111 verify(smprint("%3$Zd %5$06d %2$d %1$d", 444, 333, 555, 111, 222), "111 000222 333 444"); 112 verify(smprint("%3$d %4$*5$06d %2$d %1$d", 444, 333, 111, 222, 20), "111 000222 333 444"); 113 verify(smprint("%3$hd %4$*5$06d %2$d %1$d", 444, 333, (short)111, 222, 20), "111 000222 333 444"); 114 verify(smprint("%3$\xe2\x98\xba""d %5$06d %2$d %1$d", 444, 333, 555, 111, 222), "111 000222 333 444"); 115 116 /* test %'d formats */ 117 verify(smprint("%'d %'d %'d", 1, 2222, 33333333), "1 2,222 33,333,333"); 118 verify(smprint("%'019d", 0), "000,000,000,000,000"); 119 verify(smprint("%'08d %'08d %'08d", 1, 2222, 33333333), "0,000,001 0,002,222 33,333,333"); 120 #ifdef PLAN9PORT 121 verify(smprint("%'ux %'uX %'ub", 0x11111111, 0xabcd1234, 12345), "1111:1111 ABCD:1234 11:0000:0011:1001"); 122 #else 123 verify(smprint("%'x %'X %'b", 0x11111111, 0xabcd1234, 12345), "1111:1111 ABCD:1234 11:0000:0011:1001"); 124 #endif 125 verify(smprint("%'lld %'lld %'lld", 1LL, 222222222LL, 3333333333333LL), "1 222,222,222 3,333,333,333,333"); 126 verify(smprint("%'019lld %'019lld %'019lld", 1LL, 222222222LL, 3333333333333LL), "000,000,000,000,001 000,000,222,222,222 003,333,333,333,333"); 127 #ifdef PLAN9PORT 128 verify(smprint("%'llux %'lluX %'llub", 0x111111111111LL, 0xabcd12345678LL, 112342345LL), "1111:1111:1111 ABCD:1234:5678 110:1011:0010:0011:0101:0100:1001"); 129 #else 130 verify(smprint("%'llx %'llX %'llb", 0x111111111111LL, 0xabcd12345678LL, 112342345LL), "1111:1111:1111 ABCD:1234:5678 110:1011:0010:0011:0101:0100:1001"); 131 #endif 132 133 /* test %'d with custom (utf-8!) separators */ 134 /* x and b still use : */ 135 verify(mysmprint("%'d %'d %'d", 1, 2222, 33333333), "1 2\xe2\x98\xbb""22\xe2\x98\xbb""2 33\xe2\x98\xbb""333\xe2\x98\xbb""33\xe2\x98\xbb""3"); 136 #ifdef PLAN9PORT 137 verify(mysmprint("%'ux %'uX %'ub", 0x11111111, 0xabcd1234, 12345), "1111:1111 ABCD:1234 11:0000:0011:1001"); 138 #else 139 verify(mysmprint("%'x %'X %'b", 0x11111111, 0xabcd1234, 12345), "1111:1111 ABCD:1234 11:0000:0011:1001"); 140 #endif 141 verify(mysmprint("%'lld %'lld %'lld", 1LL, 222222222LL, 3333333333333LL), "1 222\xe2\x98\xbb""222\xe2\x98\xbb""22\xe2\x98\xbb""2 333\xe2\x98\xbb""3333\xe2\x98\xbb""333\xe2\x98\xbb""33\xe2\x98\xbb""3"); 142 verify(mysmprint("%'llx %'llX %'llb", 0x111111111111LL, 0xabcd12345678LL, 112342345LL), "1111:1111:1111 ABCD:1234:5678 110:1011:0010:0011:0101:0100:1001"); 143 verify(mysmprint("%.4f", 3.14159), "3\xe2\x98\xba""1416"); 144 145 if(failed) 146 sysfatal("tests failed"); 147 exits(0); 148 }