xref: /openbsd/gnu/usr.bin/perl/t/opbasic/cmp.t (revision 9f11ffb7)
191f110e0Safresh1#!./perl
291f110e0Safresh1
391f110e0Safresh1# This file has been placed in t/opbasic to indicate that it should not use
491f110e0Safresh1# functions imported from t/test.pl or Test::More, as those programs/libraries
591f110e0Safresh1# use operators which are what is being tested in this file.
691f110e0Safresh1
791f110e0Safresh1# 2s complement assumption. Will not break test, just makes the internals of
891f110e0Safresh1# the SVs less interesting if were not on 2s complement system.
991f110e0Safresh1my $uv_max = ~0;
1091f110e0Safresh1my $uv_maxm1 = ~0 ^ 1;
1191f110e0Safresh1my $uv_big = $uv_max;
1291f110e0Safresh1$uv_big = ($uv_big - 20000) | 1;
1391f110e0Safresh1my ($iv0, $iv1, $ivm1, $iv_min, $iv_max, $iv_big, $iv_small);
1491f110e0Safresh1$iv_max = $uv_max; # Do copy, *then* divide
1591f110e0Safresh1$iv_max /= 2;
1691f110e0Safresh1$iv_min = $iv_max;
1791f110e0Safresh1{
1891f110e0Safresh1  use integer;
1991f110e0Safresh1  $iv0 = 2 - 2;
2091f110e0Safresh1  $iv1 = 3 - 2;
2191f110e0Safresh1  $ivm1 = 2 - 3;
2291f110e0Safresh1  $iv_max -= 1;
2391f110e0Safresh1  $iv_min += 0;
2491f110e0Safresh1  $iv_big = $iv_max - 3;
2591f110e0Safresh1  $iv_small = $iv_min + 2;
2691f110e0Safresh1}
2791f110e0Safresh1my $uv_bigi = $iv_big;
2891f110e0Safresh1$uv_bigi |= 0x0;
2991f110e0Safresh1
3091f110e0Safresh1my @array = qw(perl rules);
3191f110e0Safresh1
3291f110e0Safresh1my @raw, @upgraded, @utf8;
33*b8851fccSafresh1foreach ("\0", "\x{1F4A9}", chr(163), 'N') {
3491f110e0Safresh1    push @raw, $_;
3591f110e0Safresh1    my $temp = $_ . chr 256;
3691f110e0Safresh1    chop $temp;
3791f110e0Safresh1    push @upgraded, $temp;
3891f110e0Safresh1    my $utf8 = $_;
3991f110e0Safresh1    next if utf8::upgrade($utf8) == length $_;
4091f110e0Safresh1    utf8::encode($utf8);
4191f110e0Safresh1    push @utf8, $utf8;
4291f110e0Safresh1}
4391f110e0Safresh1
4491f110e0Safresh1# Seems one needs to perform the maths on 'Inf' to get the NV correctly primed.
4591f110e0Safresh1@FOO = ('s', 'N/A', 'a', 'NaN', -1, undef, 0, 1, 3.14, 1e37, 0.632120558, -.5,
4691f110e0Safresh1	'Inf'+1, '-Inf'-1, 0x0, 0x1, 0x5, 0xFFFFFFFF, $uv_max, $uv_maxm1,
4791f110e0Safresh1	$uv_big, $uv_bigi, $iv0, $iv1, $ivm1, $iv_min, $iv_max, $iv_big,
4891f110e0Safresh1	$iv_small, \$array[0], \$array[0], \$array[1], \$^X, @raw, @upgraded,
4991f110e0Safresh1	@utf8);
5091f110e0Safresh1
5191f110e0Safresh1$expect = 7 * ($#FOO+2) * ($#FOO+1) + 6 * @raw + 6 * @utf8;
5291f110e0Safresh1print "1..$expect\n";
5391f110e0Safresh1
5491f110e0Safresh1my $bad_NaN = 0;
5591f110e0Safresh1
5691f110e0Safresh1{
5791f110e0Safresh1    # gcc -ffast-math option may stop NaNs working correctly
5891f110e0Safresh1    use Config;
5991f110e0Safresh1    my $ccflags = $Config{ccflags} // '';
6091f110e0Safresh1    $bad_NaN = 1 if $ccflags =~ /-ffast-math\b/;
6191f110e0Safresh1}
6291f110e0Safresh1
6391f110e0Safresh1sub nok ($$$$$$$$) {
6491f110e0Safresh1  my ($test, $left, $threeway, $right, $result, $i, $j, $boolean) = @_;
6591f110e0Safresh1  $result = defined $result ? "'$result'" : 'undef';
6691f110e0Safresh1  if ($bad_NaN && ($left eq 'NaN' || $right eq 'NaN')) {
6791f110e0Safresh1    print "ok $test # skipping failed NaN test under -ffast-math\n";
6891f110e0Safresh1  }
6991f110e0Safresh1  else {
7091f110e0Safresh1    print "not ok $test # ($left $threeway $right) gives: $result \$i=$i \$j=$j, $boolean disagrees\n";
7191f110e0Safresh1  }
7291f110e0Safresh1}
7391f110e0Safresh1
7491f110e0Safresh1my $ok = 0;
7591f110e0Safresh1for my $i (0..$#FOO) {
7691f110e0Safresh1    for my $j ($i..$#FOO) {
7791f110e0Safresh1	$ok++;
7891f110e0Safresh1	# Comparison routines may convert these internally, which would change
7991f110e0Safresh1	# what is used to determine the comparison on later runs. Hence copy
8091f110e0Safresh1	my ($i1, $i2, $i3, $i4, $i5, $i6, $i7, $i8, $i9, $i10,
8191f110e0Safresh1	    $i11, $i12, $i13, $i14, $i15, $i16, $i17) =
8291f110e0Safresh1	  ($FOO[$i], $FOO[$i], $FOO[$i], $FOO[$i], $FOO[$i], $FOO[$i],
8391f110e0Safresh1	   $FOO[$i], $FOO[$i], $FOO[$i], $FOO[$i], $FOO[$i], $FOO[$i],
8491f110e0Safresh1	   $FOO[$i], $FOO[$i], $FOO[$i], $FOO[$i], $FOO[$i]);
8591f110e0Safresh1	my ($j1, $j2, $j3, $j4, $j5, $j6, $j7, $j8, $j9, $j10,
8691f110e0Safresh1	    $j11, $j12, $j13, $j14, $j15, $j16, $j17) =
8791f110e0Safresh1	  ($FOO[$j], $FOO[$j], $FOO[$j], $FOO[$j], $FOO[$j], $FOO[$j],
8891f110e0Safresh1	   $FOO[$j], $FOO[$j], $FOO[$j], $FOO[$j], $FOO[$j], $FOO[$j],
8991f110e0Safresh1	   $FOO[$j], $FOO[$j], $FOO[$j], $FOO[$j], $FOO[$j]);
9091f110e0Safresh1	my $cmp = $i1 <=> $j1;
9191f110e0Safresh1	if (!defined($cmp) ? !($i2 < $j2)
9291f110e0Safresh1	    : ($cmp == -1 && $i2 < $j2 ||
9391f110e0Safresh1	       $cmp == 0  && !($i2 < $j2) ||
9491f110e0Safresh1	       $cmp == 1  && !($i2 < $j2)))
9591f110e0Safresh1	{
9691f110e0Safresh1	    print "ok $ok\n";
9791f110e0Safresh1	}
9891f110e0Safresh1	else {
9991f110e0Safresh1	    nok ($ok, $i3, '<=>', $j3, $cmp, $i, $j, '<');
10091f110e0Safresh1	}
10191f110e0Safresh1	$ok++;
10291f110e0Safresh1	if (!defined($cmp) ? !($i4 == $j4)
10391f110e0Safresh1	    : ($cmp == -1 && !($i4 == $j4) ||
10491f110e0Safresh1	       $cmp == 0  && $i4 == $j4 ||
10591f110e0Safresh1	       $cmp == 1  && !($i4 == $j4)))
10691f110e0Safresh1	{
10791f110e0Safresh1	    print "ok $ok\n";
10891f110e0Safresh1	}
10991f110e0Safresh1	else {
11091f110e0Safresh1	    nok ($ok, $i3, '<=>', $j3, $cmp, $i, $j, '==');
11191f110e0Safresh1	}
11291f110e0Safresh1	$ok++;
11391f110e0Safresh1	if (!defined($cmp) ? !($i5 > $j5)
11491f110e0Safresh1	    : ($cmp == -1 && !($i5 > $j5) ||
11591f110e0Safresh1	       $cmp == 0  && !($i5 > $j5) ||
11691f110e0Safresh1	       $cmp == 1  && ($i5 > $j5)))
11791f110e0Safresh1	{
11891f110e0Safresh1	    print "ok $ok\n";
11991f110e0Safresh1	}
12091f110e0Safresh1	else {
12191f110e0Safresh1	    nok ($ok, $i3, '<=>', $j3, $cmp, $i, $j, '>');
12291f110e0Safresh1	}
12391f110e0Safresh1	$ok++;
12491f110e0Safresh1	if (!defined($cmp) ? !($i6 >= $j6)
12591f110e0Safresh1	    : ($cmp == -1 && !($i6 >= $j6) ||
12691f110e0Safresh1	       $cmp == 0  && $i6 >= $j6 ||
12791f110e0Safresh1	       $cmp == 1  && $i6 >= $j6))
12891f110e0Safresh1	{
12991f110e0Safresh1	    print "ok $ok\n";
13091f110e0Safresh1	}
13191f110e0Safresh1	else {
13291f110e0Safresh1	    nok ($ok, $i3, '<=>', $j3, $cmp, $i, $j, '>=');
13391f110e0Safresh1	}
13491f110e0Safresh1	$ok++;
13591f110e0Safresh1	# OK, so the docs are wrong it seems. NaN != NaN
13691f110e0Safresh1	if (!defined($cmp) ? ($i7 != $j7)
13791f110e0Safresh1	    : ($cmp == -1 && $i7 != $j7 ||
13891f110e0Safresh1	       $cmp == 0  && !($i7 != $j7) ||
13991f110e0Safresh1	       $cmp == 1  && $i7 != $j7))
14091f110e0Safresh1	{
14191f110e0Safresh1	    print "ok $ok\n";
14291f110e0Safresh1	}
14391f110e0Safresh1	else {
14491f110e0Safresh1	    nok ($ok, $i3, '<=>', $j3, $cmp, $i, $j, '!=');
14591f110e0Safresh1	}
14691f110e0Safresh1	$ok++;
14791f110e0Safresh1	if (!defined($cmp) ? !($i8 <= $j8)
14891f110e0Safresh1	    : ($cmp == -1 && $i8 <= $j8 ||
14991f110e0Safresh1	       $cmp == 0  && $i8 <= $j8 ||
15091f110e0Safresh1	       $cmp == 1  && !($i8 <= $j8)))
15191f110e0Safresh1	{
15291f110e0Safresh1	    print "ok $ok\n";
15391f110e0Safresh1	}
15491f110e0Safresh1	else {
15591f110e0Safresh1	    nok ($ok, $i3, '<=>', $j3, $cmp, $i, $j, '<=');
15691f110e0Safresh1	}
15791f110e0Safresh1	$ok++;
15891f110e0Safresh1        my $pmc =  $j16 <=> $i16; # cmp it in reverse
15991f110e0Safresh1        # Should give -ve of other answer, or undef for NaNs
16091f110e0Safresh1        # a + -a should be zero. not zero is truth. which avoids using ==
16191f110e0Safresh1	if (defined($cmp) ? !($cmp + $pmc) : !defined $pmc)
16291f110e0Safresh1	{
16391f110e0Safresh1	    print "ok $ok\n";
16491f110e0Safresh1	}
16591f110e0Safresh1	else {
16691f110e0Safresh1	    nok ($ok, $i3, '<=>', $j3, $cmp, $i, $j, '<=> transposed');
16791f110e0Safresh1	}
16891f110e0Safresh1
16991f110e0Safresh1
17091f110e0Safresh1	# String comparisons
17191f110e0Safresh1	$ok++;
17291f110e0Safresh1	$cmp = $i9 cmp $j9;
17391f110e0Safresh1	if ($cmp == -1 && $i10 lt $j10 ||
17491f110e0Safresh1	    $cmp == 0  && !($i10 lt $j10) ||
17591f110e0Safresh1	    $cmp == 1  && !($i10 lt $j10))
17691f110e0Safresh1	{
17791f110e0Safresh1	    print "ok $ok\n";
17891f110e0Safresh1	}
17991f110e0Safresh1	else {
18091f110e0Safresh1	    nok ($ok, $i3, 'cmp', $j3, $cmp, $i, $j, 'lt');
18191f110e0Safresh1	}
18291f110e0Safresh1	$ok++;
18391f110e0Safresh1	if ($cmp == -1 && !($i11 eq $j11) ||
18491f110e0Safresh1	    $cmp == 0  && ($i11 eq $j11) ||
18591f110e0Safresh1	    $cmp == 1  && !($i11 eq $j11))
18691f110e0Safresh1	{
18791f110e0Safresh1	    print "ok $ok\n";
18891f110e0Safresh1	}
18991f110e0Safresh1	else {
19091f110e0Safresh1	    nok ($ok, $i3, 'cmp', $j3, $cmp, $i, $j, 'eq');
19191f110e0Safresh1	}
19291f110e0Safresh1	$ok++;
19391f110e0Safresh1	if ($cmp == -1 && !($i12 gt $j12) ||
19491f110e0Safresh1	    $cmp == 0  && !($i12 gt $j12) ||
19591f110e0Safresh1	    $cmp == 1  && ($i12 gt $j12))
19691f110e0Safresh1	{
19791f110e0Safresh1	    print "ok $ok\n";
19891f110e0Safresh1	}
19991f110e0Safresh1	else {
20091f110e0Safresh1	    nok ($ok, $i3, 'cmp', $j3, $cmp, $i, $j, 'gt');
20191f110e0Safresh1	}
20291f110e0Safresh1	$ok++;
20391f110e0Safresh1	if ($cmp == -1 && $i13 le $j13 ||
20491f110e0Safresh1	    $cmp == 0  && ($i13 le $j13) ||
20591f110e0Safresh1	    $cmp == 1  && !($i13 le $j13))
20691f110e0Safresh1	{
20791f110e0Safresh1	    print "ok $ok\n";
20891f110e0Safresh1	}
20991f110e0Safresh1	else {
21091f110e0Safresh1	    nok ($ok, $i3, 'cmp', $j3, $cmp, $i, $j, 'le');
21191f110e0Safresh1	}
21291f110e0Safresh1	$ok++;
21391f110e0Safresh1	if ($cmp == -1 && ($i14 ne $j14) ||
21491f110e0Safresh1	    $cmp == 0  && !($i14 ne $j14) ||
21591f110e0Safresh1	    $cmp == 1  && ($i14 ne $j14))
21691f110e0Safresh1	{
21791f110e0Safresh1	    print "ok $ok\n";
21891f110e0Safresh1	}
21991f110e0Safresh1	else {
22091f110e0Safresh1	    nok ($ok, $i3, 'cmp', $j3, $cmp, $i, $j, 'ne');
22191f110e0Safresh1	}
22291f110e0Safresh1	$ok++;
22391f110e0Safresh1	if ($cmp == -1 && !($i15 ge $j15) ||
22491f110e0Safresh1	    $cmp == 0  && ($i15 ge $j15) ||
22591f110e0Safresh1	    $cmp == 1  && ($i15 ge $j15))
22691f110e0Safresh1	{
22791f110e0Safresh1	    print "ok $ok\n";
22891f110e0Safresh1	}
22991f110e0Safresh1	else {
23091f110e0Safresh1	    nok ($ok, $i3, 'cmp', $j3, $cmp, $i, $j, 'ge');
23191f110e0Safresh1	}
23291f110e0Safresh1	$ok++;
23391f110e0Safresh1        $pmc =  $j17 cmp $i17; # cmp it in reverse
23491f110e0Safresh1        # Should give -ve of other answer
23591f110e0Safresh1        # a + -a should be zero. not zero is truth. which avoids using ==
23691f110e0Safresh1	if (!($cmp + $pmc))
23791f110e0Safresh1	{
23891f110e0Safresh1	    print "ok $ok\n";
23991f110e0Safresh1	}
24091f110e0Safresh1	else {
24191f110e0Safresh1	    nok ($ok, $i3, 'cmp', $j3, $cmp, $i, $j, 'cmp transposed');
24291f110e0Safresh1	}
24391f110e0Safresh1    }
24491f110e0Safresh1}
24591f110e0Safresh1
24691f110e0Safresh1# We know the answers for these. We can rely on the consistency checks above
24791f110e0Safresh1# to test the other string comparisons.
24891f110e0Safresh1
24991f110e0Safresh1while (my ($i, $v) = each @raw) {
25091f110e0Safresh1    # Copy, to avoid any inadvertent conversion
25191f110e0Safresh1    my ($raw, $cooked, $not);
25291f110e0Safresh1    $raw = $v;
25391f110e0Safresh1    $cooked = $upgraded[$i];
25491f110e0Safresh1    $not = $raw eq $cooked ? '' : 'not ';
25591f110e0Safresh1    printf "%sok %d # eq, chr %d\n", $not, ++$ok, ord $raw;
25691f110e0Safresh1
25791f110e0Safresh1    $raw = $v;
25891f110e0Safresh1    $cooked = $upgraded[$i];
25991f110e0Safresh1    $not = $raw ne $cooked ? 'not ' : '';
26091f110e0Safresh1    printf "%sok %d # ne, chr %d\n", $not, ++$ok, ord $raw;
26191f110e0Safresh1
26291f110e0Safresh1    $raw = $v;
26391f110e0Safresh1    $cooked = $upgraded[$i];
26491f110e0Safresh1    $not = (($raw cmp $cooked) == 0) ? '' : 'not ';
26591f110e0Safresh1    printf "%sok %d # cmp, chr %d\n", $not, ++$ok, ord $raw;
26691f110e0Safresh1
26791f110e0Safresh1    # And now, transposed.
26891f110e0Safresh1    $raw = $v;
26991f110e0Safresh1    $cooked = $upgraded[$i];
27091f110e0Safresh1    $not = $cooked eq $raw ? '' : 'not ';
27191f110e0Safresh1    printf "%sok %d # eq, chr %d\n", $not, ++$ok, ord $raw;
27291f110e0Safresh1
27391f110e0Safresh1    $raw = $v;
27491f110e0Safresh1    $cooked = $upgraded[$i];
27591f110e0Safresh1    $not = $cooked ne $raw ? 'not ' : '';
27691f110e0Safresh1    printf "%sok %d # ne, chr %d\n", $not, ++$ok, ord $raw;
27791f110e0Safresh1
27891f110e0Safresh1    $raw = $v;
27991f110e0Safresh1    $cooked = $upgraded[$i];
28091f110e0Safresh1    $not = (($cooked cmp $raw) == 0) ? '' : 'not ';
28191f110e0Safresh1    printf "%sok %d # cmp, chr %d\n", $not, ++$ok, ord $raw;
28291f110e0Safresh1}
28391f110e0Safresh1
28491f110e0Safresh1while (my ($i, $v) = each @utf8) {
28591f110e0Safresh1    # Copy, to avoid any inadvertent conversion
28691f110e0Safresh1    my ($raw, $cooked, $not);
28791f110e0Safresh1    $raw = $raw[$i];
28891f110e0Safresh1    $cooked = $v;
28991f110e0Safresh1    $not = $raw eq $cooked ? 'not ' : '';
29091f110e0Safresh1    printf "%sok %d # eq vs octets, chr %d\n", $not, ++$ok, ord $raw;
29191f110e0Safresh1
29291f110e0Safresh1    $raw = $raw[$i];
29391f110e0Safresh1    $cooked = $v;
29491f110e0Safresh1    $not = $raw ne $cooked ? '' : 'not ';
29591f110e0Safresh1    printf "%sok %d # ne vs octets, chr %d\n", $not, ++$ok, ord $raw;
29691f110e0Safresh1
29791f110e0Safresh1    $raw = $raw[$i];
29891f110e0Safresh1    $cooked = $v;
29991f110e0Safresh1    $not = (($raw cmp $cooked) == 0) ? 'not ' : '';
30091f110e0Safresh1    printf "%sok %d # cmp vs octects, chr %d\n", $not, ++$ok, ord $raw;
30191f110e0Safresh1
30291f110e0Safresh1    # And now, transposed.
30391f110e0Safresh1    $raw = $raw[$i];
30491f110e0Safresh1    $cooked = $v;
30591f110e0Safresh1    $not = $cooked eq $raw ? 'not ' : '';
30691f110e0Safresh1    printf "%sok %d # eq vs octets, chr %d\n", $not, ++$ok, ord $raw;
30791f110e0Safresh1
30891f110e0Safresh1    $raw = $raw[$i];
30991f110e0Safresh1    $cooked = $v;
31091f110e0Safresh1    $not = $cooked ne $raw? '' : 'not ';
31191f110e0Safresh1    printf "%sok %d # ne vs octets, chr %d\n", $not, ++$ok, ord $raw;
31291f110e0Safresh1
31391f110e0Safresh1    $raw = $raw[$i];
31491f110e0Safresh1    $cooked = $v;
31591f110e0Safresh1    $not = (($cooked cmp $raw) == 0) ? 'not ' : '';
31691f110e0Safresh1    printf "%sok %d # cmp vs octects, chr %d\n", $not, ++$ok, ord $raw;
31791f110e0Safresh1}
318