1#!./perl 2 3# Tests sprintf, excluding handling of 64-bit integers or long 4# doubles (if supported), of machine-specific short and long 5# integers, machine-specific floating point exceptions (infinity, 6# not-a-number ...), of the effects of locale, and of features 7# specific to multi-byte characters (under the utf8 pragma and such). 8 9BEGIN { 10 chdir 't' if -d 't'; 11 @INC = '../lib'; 12} 13use warnings; 14# we do not load %Config since this test resides in op and needs 15# to run under the minitest target even without Config.pm working. 16 17# strictness 18my @tests = (); 19my ($i, $template, $data, $result, $comment, $w, $x, $evalData, $n, $p); 20 21while (<DATA>) { 22 s/^\s*>//; s/<\s*$//; 23 push @tests, [split(/<\s*>/, $_, 4)]; 24} 25 26print '1..', scalar @tests, "\n"; 27 28$SIG{__WARN__} = sub { 29 if ($_[0] =~ /^Invalid conversion/) { 30 $w = ' INVALID'; 31 } elsif ($_[0] =~ /^Use of uninitialized value/) { 32 $w = ' UNINIT'; 33 } else { 34 warn @_; 35 } 36}; 37 38my $Is_VMS_VAX = 0; 39# We use HW_MODEL since ARCH_NAME was not in VMS V5.* 40if ($^O eq 'VMS') { 41 my $hw_model; 42 chomp($hw_model = `write sys\$output f\$getsyi("HW_MODEL")`); 43 $Is_VMS_VAX = $hw_model < 1024 ? 1 : 0; 44} 45 46# No %Config. 47my $Is_Ultrix_VAX = $^O eq 'ultrix' && `uname -m` =~ /^VAX$/; 48 49for ($i = 1; @tests; $i++) { 50 ($template, $data, $result, $comment) = @{shift @tests}; 51 if ($^O eq 'os390' || $^O eq 's390') { # non-IEEE (s390 is UTS) 52 $data =~ s/([eE])96$/${1}63/; # smaller exponents 53 $result =~ s/([eE]\+)102$/${1}69/; # " " 54 $data =~ s/([eE])\-101$/${1}-56/; # larger exponents 55 $result =~ s/([eE])\-102$/${1}-57/; # " " 56 } 57 if ($Is_VMS_VAX || $Is_Ultrix_VAX) { 58 # VAX DEC C 5.3 at least since there is no 59 # ccflags =~ /float=ieee/ on VAX. 60 # AXP is unaffected whether or not it's using ieee. 61 $data =~ s/([eE])96$/${1}26/; # smaller exponents 62 $result =~ s/([eE]\+)102$/${1}32/; # " " 63 $data =~ s/([eE])\-101$/${1}-24/; # larger exponents 64 $result =~ s/([eE])\-102$/${1}-25/; # " " 65 } 66 $evalData = eval $data; 67 $w = undef; 68 $x = sprintf(">$template<", 69 defined @$evalData ? @$evalData : $evalData); 70 substr($x, -1, 0) = $w if $w; 71 # $x may have 3 exponent digits, not 2 72 my $y = $x; 73 if ($y =~ s/([Ee][-+])0(\d)/$1$2/) { 74 # if result is left-adjusted, append extra space 75 if ($template =~ /%\+?\-/ and $result =~ / $/) { 76 $y =~ s/<$/ </; 77 } 78 # if result is zero-filled, add extra zero 79 elsif ($template =~ /%\+?0/ and $result =~ /^0/) { 80 $y =~ s/^>0/>00/; 81 } 82 # if result is right-adjusted, prepend extra space 83 elsif ($result =~ /^ /) { 84 $y =~ s/^>/> /; 85 } 86 } 87 88 if ($x eq ">$result<") { 89 print "ok $i\n"; 90 } 91 elsif ($y eq ">$result<") # Some C libraries always give 92 { # three-digit exponent 93 print("ok $i # >$result< $x three-digit exponent accepted\n"); 94 } 95 elsif ($result =~ /[-+]\d{3}$/ && 96 # Suppress tests with modulo of exponent >= 100 on platforms 97 # which can't handle such magnitudes (or where we can't tell). 98 ((!eval {require POSIX}) || # Costly: only do this if we must! 99 (length(&POSIX::DBL_MAX) - rindex(&POSIX::DBL_MAX, '+')) == 3)) 100 { 101 print("ok $i # >$template< >$data< >$result<", 102 " Suppressed: exponent out of range?\n") 103 } 104 else { 105 $y = ($x eq $y ? "" : " => $y"); 106 print("not ok $i >$template< >$data< >$result< $x$y", 107 $comment ? " # $comment\n" : "\n"); 108 } 109} 110 111# In each of the following lines, there are three required fields: 112# printf template, data to be formatted (as a Perl expression), and 113# expected result of formatting. An optional fourth field can contain 114# a comment. Each field is delimited by a starting '>' and a 115# finishing '<'; any whitespace outside these start and end marks is 116# not part of the field. If formatting requires more than one data 117# item (for example, if variable field widths are used), the Perl data 118# expression should return a reference to an array having the requisite 119# number of elements. Even so, subterfuge is sometimes required: see 120# tests for %n and %p. 121# 122# The following tests are not currently run, for the reasons stated: 123 124=pod 125 126=begin problematic 127 128>%.0f< >-0.1< >-0< >C library bug: no minus on VMS, HP-UX< 129>%.0f< >1.5< >2< >Standard vague: no rounding rules< 130>%.0f< >2.5< >2< >Standard vague: no rounding rules< 131>%G< >1234567e96< >1.23457E+102< >exponent too big for OS/390< 132>%G< >.1234567e-101< >1.23457E-102< >exponent too small for OS/390< 133>%e< >1234567E96< >1.234567e+102< >exponent too big for OS/390< 134>%e< >.1234567E-101< >1.234567e-102< >exponent too small for OS/390< 135>%g< >.1234567E-101< >1.23457e-102< >exponent too small for OS/390< 136>%g< >1234567E96< >1.23457e+102< >exponent too big for OS/390< 137 138=end problematic 139 140=cut 141 142# template data result 143__END__ 144>%6. 6s< >''< >%6. 6s INVALID< >(See use of $w in code above)< 145>%6 .6s< >''< >%6 .6s INVALID< 146>%6.6 s< >''< >%6.6 s INVALID< 147>%A< >''< >%A INVALID< 148>%B< >''< >%B INVALID< 149>%C< >''< >%C INVALID< 150>%D< >0x7fffffff< >2147483647< >Synonym for %ld< 151>%E< >123456.789< >1.234568E+05< >Like %e, but using upper-case "E"< 152>%F< >123456.789< >123456.789000< >Synonym for %f< 153>%G< >1234567.89< >1.23457E+06< >Like %g, but using upper-case "E"< 154>%G< >1234567e96< >1.23457E+102< 155>%G< >.1234567e-101< >1.23457E-102< 156>%G< >12345.6789< >12345.7< 157>%H< >''< >%H INVALID< 158>%I< >''< >%I INVALID< 159>%J< >''< >%J INVALID< 160>%K< >''< >%K INVALID< 161>%L< >''< >%L INVALID< 162>%M< >''< >%M INVALID< 163>%N< >''< >%N INVALID< 164>%O< >2**32-1< >37777777777< >Synonym for %lo< 165>%P< >''< >%P INVALID< 166>%Q< >''< >%Q INVALID< 167>%R< >''< >%R INVALID< 168>%S< >''< >%S INVALID< 169>%T< >''< >%T INVALID< 170>%U< >2**32-1< >4294967295< >Synonym for %lu< 171>%V< >''< >%V INVALID< 172>%W< >''< >%W INVALID< 173>%X< >2**32-1< >FFFFFFFF< >Like %x, but with u/c letters< 174>%#X< >2**32-1< >0XFFFFFFFF< 175>%Y< >''< >%Y INVALID< 176>%Z< >''< >%Z INVALID< 177>%a< >''< >%a INVALID< 178>%b< >2**32-1< >11111111111111111111111111111111< 179>%+b< >2**32-1< >11111111111111111111111111111111< 180>%#b< >2**32-1< >0b11111111111111111111111111111111< 181>%34b< >2**32-1< > 11111111111111111111111111111111< 182>%034b< >2**32-1< >0011111111111111111111111111111111< 183>%-34b< >2**32-1< >11111111111111111111111111111111 < 184>%-034b< >2**32-1< >11111111111111111111111111111111 < 185>%c< >ord('A')< >A< 186>%10c< >ord('A')< > A< 187>%#10c< >ord('A')< > A< ># modifier: no effect< 188>%010c< >ord('A')< >000000000A< 189>%10lc< >ord('A')< > A< >l modifier: no effect< 190>%10hc< >ord('A')< > A< >h modifier: no effect< 191>%10.5c< >ord('A')< > A< >precision: no effect< 192>%-10c< >ord('A')< >A < 193>%d< >123456.789< >123456< 194>%d< >-123456.789< >-123456< 195>%d< >0< >0< 196>%+d< >0< >+0< 197>%0d< >0< >0< 198>%.0d< >0< >< 199>%+.0d< >0< >+< 200>%.0d< >1< >1< 201>%d< >1< >1< 202>%+d< >1< >+1< 203>%#3.2d< >1< > 01< ># modifier: no effect< 204>%3.2d< >1< > 01< 205>%03.2d< >1< >001< 206>%-3.2d< >1< >01 < 207>%-03.2d< >1< >01 < >zero pad + left just.: no effect< 208>%d< >-1< >-1< 209>%+d< >-1< >-1< 210>%hd< >1< >1< >More extensive testing of< 211>%ld< >1< >1< >length modifiers would be< 212>%Vd< >1< >1< >platform-specific< 213>%vd< >chr(1)< >1< 214>%+vd< >chr(1)< >+1< 215>%#vd< >chr(1)< >1< 216>%vd< >"\01\02\03"< >1.2.3< 217>%v.3d< >"\01\02\03"< >001.002.003< 218>%0v3d< >"\01\02\03"< >001.002.003< 219>%-v3d< >"\01\02\03"< >1 .2 .3 < 220>%+-v3d< >"\01\02\03"< >+1 .2 .3 < 221>%v4.3d< >"\01\02\03"< > 001. 002. 003< 222>%0v4.3d< >"\01\02\03"< >0001.0002.0003< 223>%0*v2d< >['-', "\0\7\14"]< >00-07-12< 224>%v.*d< >["\01\02\03", 3]< >001.002.003< 225>%0v*d< >["\01\02\03", 3]< >001.002.003< 226>%-v*d< >["\01\02\03", 3]< >1 .2 .3 < 227>%+-v*d< >["\01\02\03", 3]< >+1 .2 .3 < 228>%v*.*d< >["\01\02\03", 4, 3]< > 001. 002. 003< 229>%0v*.*d< >["\01\02\03", 4, 3]< >0001.0002.0003< 230>%0*v*d< >['-', "\0\7\13", 2]< >00-07-11< 231>%e< >1234.875< >1.234875e+03< 232>%e< >0.000012345< >1.234500e-05< 233>%e< >1234567E96< >1.234567e+102< 234>%e< >0< >0.000000e+00< 235>%e< >.1234567E-101< >1.234567e-102< 236>%+e< >1234.875< >+1.234875e+03< 237>%#e< >1234.875< >1.234875e+03< 238>%e< >-1234.875< >-1.234875e+03< 239>%+e< >-1234.875< >-1.234875e+03< 240>%#e< >-1234.875< >-1.234875e+03< 241>%.0e< >1234.875< >1e+03< 242>%#.0e< >1234.875< >1.e+03< 243>%.0e< >1.875< >2e+00< 244>%.0e< >0.875< >9e-01< 245>%.*e< >[0, 1234.875]< >1e+03< 246>%.1e< >1234.875< >1.2e+03< 247>%-12.4e< >1234.875< >1.2349e+03 < 248>%12.4e< >1234.875< > 1.2349e+03< 249>%+-12.4e< >1234.875< >+1.2349e+03 < 250>%+12.4e< >1234.875< > +1.2349e+03< 251>%+-12.4e< >-1234.875< >-1.2349e+03 < 252>%+12.4e< >-1234.875< > -1.2349e+03< 253>%f< >1234.875< >1234.875000< 254>%+f< >1234.875< >+1234.875000< 255>%#f< >1234.875< >1234.875000< 256>%f< >-1234.875< >-1234.875000< 257>%+f< >-1234.875< >-1234.875000< 258>%#f< >-1234.875< >-1234.875000< 259>%6f< >1234.875< >1234.875000< 260>%*f< >[6, 1234.875]< >1234.875000< 261>%.0f< >1234.875< >1235< 262>%.1f< >1234.875< >1234.9< 263>%-8.1f< >1234.875< >1234.9 < 264>%8.1f< >1234.875< > 1234.9< 265>%+-8.1f< >1234.875< >+1234.9 < 266>%+8.1f< >1234.875< > +1234.9< 267>%+-8.1f< >-1234.875< >-1234.9 < 268>%+8.1f< >-1234.875< > -1234.9< 269>%*.*f< >[5, 2, 12.3456]< >12.35< 270>%f< >0< >0.000000< 271>%.0f< >0< >0< 272>%.0f< >2**38< >274877906944< >Should have exact int'l rep'n< 273>%.0f< >0.1< >0< 274>%.0f< >0.6< >1< >Known to fail with sfio, (irix|nonstop-ux|powerux); -DHAS_LDBL_SPRINTF_BUG may fix< 275>%.0f< >-0.6< >-1< >Known to fail with sfio, (irix|nonstop-ux|powerux); -DHAS_LDBL_SPRINTF_BUG may fix< 276>%.0f< >1.6< >2< 277>%.0f< >-1.6< >-2< 278>%.0f< >1< >1< 279>%#.0f< >1< >1.< 280>%.0lf< >1< >1< >'l' should have no effect< 281>%.0hf< >1< >%.0hf INVALID< >'h' should be rejected< 282>%g< >12345.6789< >12345.7< 283>%+g< >12345.6789< >+12345.7< 284>%#g< >12345.6789< >12345.7< 285>%.0g< >12345.6789< >1e+04< 286>%#.0g< >12345.6789< >1.e+04< 287>%.2g< >12345.6789< >1.2e+04< 288>%.*g< >[2, 12345.6789]< >1.2e+04< 289>%.9g< >12345.6789< >12345.6789< 290>%12.9g< >12345.6789< > 12345.6789< 291>%012.9g< >12345.6789< >0012345.6789< 292>%-12.9g< >12345.6789< >12345.6789 < 293>%*.*g< >[-12, 9, 12345.6789]< >12345.6789 < 294>%-012.9g< >12345.6789< >12345.6789 < 295>%g< >-12345.6789< >-12345.7< 296>%+g< >-12345.6789< >-12345.7< 297>%g< >1234567.89< >1.23457e+06< 298>%+g< >1234567.89< >+1.23457e+06< 299>%#g< >1234567.89< >1.23457e+06< 300>%g< >-1234567.89< >-1.23457e+06< 301>%+g< >-1234567.89< >-1.23457e+06< 302>%#g< >-1234567.89< >-1.23457e+06< 303>%g< >0.00012345< >0.00012345< 304>%g< >0.000012345< >1.2345e-05< 305>%g< >1234567E96< >1.23457e+102< 306>%g< >.1234567E-101< >1.23457e-102< 307>%g< >0< >0< 308>%13g< >1234567.89< > 1.23457e+06< 309>%+13g< >1234567.89< > +1.23457e+06< 310>%013g< >1234567.89< >001.23457e+06< 311>%-13g< >1234567.89< >1.23457e+06 < 312>%h< >''< >%h INVALID< 313>%i< >123456.789< >123456< >Synonym for %d< 314>%j< >''< >%j INVALID< 315>%k< >''< >%k INVALID< 316>%l< >''< >%l INVALID< 317>%m< >''< >%m INVALID< 318>%s< >sprintf('%%n%n %d', $n, $n)< >%n 2< >Slight sneakiness to test %n< 319>%o< >2**32-1< >37777777777< 320>%+o< >2**32-1< >37777777777< 321>%#o< >2**32-1< >037777777777< 322>%o< >642< >1202< >check smaller octals across platforms< 323>%+o< >642< >1202< 324>%#o< >642< >01202< 325>%d< >$p=sprintf('%p',$p);$p=~/^[0-9a-f]+$/< >1< >Coarse hack: hex from %p?< 326>%#p< >''< >%#p INVALID< 327>%q< >''< >%q INVALID< 328>%r< >''< >%r INVALID< 329>%s< >'string'< >string< 330>%10s< >'string'< > string< 331>%+10s< >'string'< > string< 332>%#10s< >'string'< > string< 333>%010s< >'string'< >0000string< 334>%0*s< >[10, 'string']< >0000string< 335>%-10s< >'string'< >string < 336>%3s< >'string'< >string< 337>%.3s< >'string'< >str< 338>%.*s< >[3, 'string']< >str< 339>%t< >''< >%t INVALID< 340>%u< >2**32-1< >4294967295< 341>%+u< >2**32-1< >4294967295< 342>%#u< >2**32-1< >4294967295< 343>%12u< >2**32-1< > 4294967295< 344>%012u< >2**32-1< >004294967295< 345>%-12u< >2**32-1< >4294967295 < 346>%-012u< >2**32-1< >4294967295 < 347>%v< >''< >%v INVALID< 348>%w< >''< >%w INVALID< 349>%x< >2**32-1< >ffffffff< 350>%+x< >2**32-1< >ffffffff< 351>%#x< >2**32-1< >0xffffffff< 352>%10x< >2**32-1< > ffffffff< 353>%010x< >2**32-1< >00ffffffff< 354>%-10x< >2**32-1< >ffffffff < 355>%-010x< >2**32-1< >ffffffff < 356>%0-10x< >2**32-1< >ffffffff < 357>%0*x< >[-10, ,2**32-1]< >ffffffff < 358>%y< >''< >%y INVALID< 359>%z< >''< >%z INVALID< 360>%2$d %1$d< >[12, 34]< >34 12< 361>%*2$d< >[12, 3]< > 12< 362>%2$d %d< >[12, 34]< >34 12< 363>%2$d %d %d< >[12, 34]< >34 12 34< 364>%3$d %d %d< >[12, 34, 56]< >56 12 34< 365>%2$*3$d %d< >[12, 34, 3]< > 34 12< 366>%*3$2$d %d< >[12, 34, 3]< >%*3$2$d 12 INVALID< 367>%2$d< >12< >0 UNINIT< 368>%0$d< >12< >%0$d INVALID< 369>%1$$d< >12< >%1$$d INVALID< 370>%1$1$d< >12< >%1$1$d INVALID< 371>%*2$*2$d< >[12, 3]< >%*2$*2$d INVALID< 372>%*2*2$d< >[12, 3]< >%*2*2$d INVALID< 373>%0v2.2d< >''< >< 374>%vc,%d< >[63, 64, 65]< >?,64< 375>%vd,%d< >[1, 2, 3]< >49,2< 376>%vf,%d< >[1, 2, 3]< >1.000000,2< 377>%vp< >''< >%vp INVALID< 378>%vs,%d< >[1, 2, 3]< >1,2< 379>%v_< >''< >%v_ INVALID< 380>%v#x< >''< >%v#x INVALID< 381>%v02x< >"foo\012"< >66.6f.6f.0a< 382>%V-%s< >["Hello"]< >%V-Hello INVALID< 383>%K %d %d< >[13, 29]< >%K 13 29 INVALID< 384>%*.*K %d< >[13, 29, 76]< >%*.*K 13 INVALID< 385>%4$K %d< >[45, 67]< >%4$K 45 INVALID< 386>%d %K %d< >[23, 45]< >23 %K 45 INVALID< 387>%*v*999\$d %d %d< >[11, 22, 33]< >%*v*999\$d 11 22 INVALID< 388>%#b< >0< >0< 389>%#o< >0< >0< 390>%#x< >0< >0< 391>%2918905856$v2d< >''< >< 392>%*2918905856$v2d< >''< > UNINIT< 393