This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
utf8.c: EBCDIC fix
[perl5.git] / ext / XS-APItest / t / grok.t
CommitLineData
ffe53d21
NC
1#!perl -w
2use strict;
3
4use Test::More;
5use Config;
6use XS::APItest;
7use feature 'switch';
0f539b13 8no warnings 'experimental::smartmatch';
ffe53d21
NC
9use constant TRUTH => '0 but true';
10
11# Tests for grok_number. Not yet comprehensive.
12foreach my $leader ('', ' ', ' ') {
13 foreach my $trailer ('', ' ', ' ') {
14 foreach ((map {"0" x $_} 1 .. 12),
15 (map {("0" x $_) . "1"} 0 .. 12),
16 (map {"1" . ("0" x $_)} 1 .. 9),
17 (map {1 << $_} 0 .. 31),
18 (map {1 << $_} 0 .. 31),
19 (map {0xFFFFFFFF >> $_} reverse (0 .. 31)),
20 ) {
21 foreach my $sign ('', '-', '+') {
22 my $string = $leader . $sign . $_ . $trailer;
23 my ($flags, $value) = grok_number($string);
24 is($flags & IS_NUMBER_IN_UV, IS_NUMBER_IN_UV,
25 "'$string' is a UV");
26 is($flags & IS_NUMBER_NEG, $sign eq '-' ? IS_NUMBER_NEG : 0,
27 "'$string' sign");
28 is($value, abs $string, "value is correct");
29 }
30 }
31
32 {
33 my (@UV, @NV);
34 given ($Config{ivsize}) {
35 when (4) {
36 @UV = qw(429496729 4294967290 4294967294 4294967295);
37 @NV = qw(4294967296 4294967297 4294967300 4294967304);
38 }
39 when (8) {
40 @UV = qw(1844674407370955161 18446744073709551610
41 18446744073709551614 18446744073709551615);
42 @NV = qw(18446744073709551616 18446744073709551617
43 18446744073709551620 18446744073709551624);
44 }
45 default {
46 die "Unknown IV size $_";
47 }
48 }
49 foreach (@UV) {
50 my $string = $leader . $_ . $trailer;
51 my ($flags, $value) = grok_number($string);
52 is($flags & IS_NUMBER_IN_UV, IS_NUMBER_IN_UV,
53 "'$string' is a UV");
54 is($value, abs $string, "value is correct");
55 }
56 foreach (@NV) {
57 my $string = $leader . $_ . $trailer;
58 my ($flags, $value) = grok_number($string);
59 is($flags & IS_NUMBER_IN_UV, 0, "'$string' is an NV");
60 is($value, undef, "value is correct");
61 }
62 }
63
64 my $string = $leader . TRUTH . $trailer;
65 my ($flags, $value) = grok_number($string);
66
67 if ($string eq TRUTH) {
68 is($flags & IS_NUMBER_IN_UV, IS_NUMBER_IN_UV, "'$string' is a UV");
69 is($value, 0);
70 } else {
71 is($flags, 0, "'$string' is not a number");
72 is($value, undef);
73 }
74 }
75}
76
e222d7e2
TC
77# format tests
78my @groks =
79 (
80 # input, in flags, out uv, out flags
81 [ "1", 0, 1, IS_NUMBER_IN_UV ],
82 [ "1x", 0, undef, 0 ],
83 [ "1x", PERL_SCAN_TRAILING, 1, IS_NUMBER_IN_UV | IS_NUMBER_TRAILING ],
84 [ "3.1", 0, 3, IS_NUMBER_IN_UV | IS_NUMBER_NOT_INT ],
85 [ "3.1a", 0, undef, 0 ],
86 [ "3.1a", PERL_SCAN_TRAILING, 3,
87 IS_NUMBER_IN_UV | IS_NUMBER_NOT_INT | IS_NUMBER_TRAILING ],
88 [ "3e5", 0, undef, IS_NUMBER_NOT_INT ],
89 [ "3e", 0, undef, 0 ],
90 [ "3e", PERL_SCAN_TRAILING, 3, IS_NUMBER_IN_UV | IS_NUMBER_TRAILING ],
91 [ "3e+", 0, undef, 0 ],
92 [ "3e+", PERL_SCAN_TRAILING, 3, IS_NUMBER_IN_UV | IS_NUMBER_TRAILING ],
93 [ "Inf", 0, undef,
94 IS_NUMBER_INFINITY | IS_NUMBER_NOT_INT ],
95 [ "In", 0, undef, 0 ],
a3c662ac 96 [ "Infin",0, undef, IS_NUMBER_INFINITY | IS_NUMBER_NOT_INT | IS_NUMBER_TRAILING ],
e222d7e2
TC
97 # this doesn't work and hasn't been needed yet
98 #[ "Infin",PERL_SCAN_TRAILING, undef,
99 # IS_NUMBER_INFINITY | IS_NUMBER_NOT_INT | IS_NUMBER_TRAILING ],
100 [ "nan", 0, undef, IS_NUMBER_NAN | IS_NUMBER_NOT_INT ],
ae776a2c 101 # even without PERL_SCAN_TRAILING nan can have weird stuff trailing
a3c662ac
JH
102 [ "nanx", 0, undef, IS_NUMBER_NAN | IS_NUMBER_NOT_INT | IS_NUMBER_TRAILING ],
103 [ "nanx", PERL_SCAN_TRAILING, undef, IS_NUMBER_NAN | IS_NUMBER_NOT_INT | IS_NUMBER_TRAILING ],
e222d7e2
TC
104 );
105
c6303df5
JH
106my $non_ieee_fp = ($Config{doublekind} == 9 ||
107 $Config{doublekind} == 10 ||
108 $Config{doublekind} == 11);
109
110if ($non_ieee_fp) {
111 @groks = grep { $_->[0] !~ /^(?:inf|nan)/i } @groks;
112}
113
e222d7e2
TC
114for my $grok (@groks) {
115 my ($out_flags, $out_uv) = grok_number_flags($grok->[0], $grok->[1]);
116 is($out_uv, $grok->[2], "'$grok->[0]' flags $grok->[1] - check number");
117 is($out_flags, $grok->[3], "'$grok->[0]' flags $grok->[1] - check flags");
118}
119
dd52de80
JH
120my $ATOU_MAX = ~0;
121
122# atou tests
123my @atous =
124 (
125 # [ input, endsv, out uv, out len ]
126
127 # Basic cases.
128 [ "0", "", 0, 1 ],
129 [ "1", "", 1, 1 ],
130 [ "2", "", 2, 1 ],
131 [ "9", "", 9, 1 ],
132 [ "12", "", 12, 2 ],
133 [ "123", "", 123, 3 ],
134
135 # Trailing whitespace is accepted or rejected, depending on endptr.
136 [ "0 ", " ", 0, 1 ],
137 [ "1 ", " ", 1, 1 ],
138 [ "2 ", " ", 2, 1 ],
139 [ "12 ", " ", 12, 2 ],
140
141 # Trailing garbage is accepted or rejected, depending on endptr.
142 [ "0x", "x", 0, 1 ],
143 [ "1x", "x", 1, 1 ],
144 [ "2x", "x", 2, 1 ],
145 [ "12x", "x", 12, 2 ],
146
147 # Leading whitespace is failure.
22ff3130
HS
148 [ " 0", undef, 0, 0 ],
149 [ " 1", undef, 0, 0 ],
150 [ " 12", undef, 0, 0 ],
dd52de80
JH
151
152 # Leading garbage is outright failure.
22ff3130
HS
153 [ "x0", undef, 0, 0 ],
154 [ "x1", undef, 0, 0 ],
155 [ "x12", undef, 0, 0 ],
dd52de80
JH
156
157 # We do not parse decimal point.
22ff3130 158 [ "12.3", ".3", 12, 2 ],
dd52de80
JH
159
160 # Leading pluses or minuses are no good.
22ff3130
HS
161 [ "+12", undef, 0, 0 ],
162 [ "-12", undef, 0, 0 ],
dd52de80 163
22ff3130
HS
164 # Extra leading zeros are no good.
165 [ "00", undef, $ATOU_MAX, 0 ],
166 [ "01", undef, $ATOU_MAX, 0 ],
167 [ "012", undef, $ATOU_MAX, 0 ],
dd52de80
JH
168 );
169
75feedba
JH
170# Values near overflow point.
171if ($Config{uvsize} == 8) {
dd52de80
JH
172 push @atous,
173 (
75feedba
JH
174 # 32-bit values no problem for 64-bit.
175 [ "4294967293", "", 4294967293, 10, ],
dd52de80
JH
176 [ "4294967294", "", 4294967294, 10, ],
177 [ "4294967295", "", 4294967295, 10, ],
178 [ "4294967296", "", 4294967296, 10, ],
75feedba 179 [ "4294967297", "", 4294967297, 10, ],
dd52de80 180
75feedba 181 # This is well within 64-bit.
dd52de80
JH
182 [ "9999999999", "", 9999999999, 10, ],
183
22ff3130 184 # Values valid up to 64-bit, failing beyond.
75feedba 185 [ "18446744073709551613", "", 18446744073709551613, 20, ],
dd52de80
JH
186 [ "18446744073709551614", "", 18446744073709551614, 20, ],
187 [ "18446744073709551615", "", $ATOU_MAX, 20, ],
22ff3130
HS
188 [ "18446744073709551616", undef, $ATOU_MAX, 0, ],
189 [ "18446744073709551617", undef, $ATOU_MAX, 0, ],
dd52de80 190 );
75feedba 191} elsif ($Config{uvsize} == 4) {
dd52de80
JH
192 push @atous,
193 (
22ff3130 194 # Values valid up to 32-bit, failing beyond.
75feedba 195 [ "4294967293", "", 4294967293, 10, ],
dd52de80
JH
196 [ "4294967294", "", 4294967294, 10, ],
197 [ "4294967295", "", $ATOU_MAX, 10, ],
22ff3130
HS
198 [ "4294967296", undef, $ATOU_MAX, 0, ],
199 [ "4294967297", undef, $ATOU_MAX, 0, ],
dd52de80 200
75feedba 201 # Still beyond 32-bit.
22ff3130
HS
202 [ "4999999999", undef, $ATOU_MAX, 0, ],
203 [ "5678901234", undef, $ATOU_MAX, 0, ],
204 [ "6789012345", undef, $ATOU_MAX, 0, ],
205 [ "7890123456", undef, $ATOU_MAX, 0, ],
206 [ "8901234567", undef, $ATOU_MAX, 0, ],
207 [ "9012345678", undef, $ATOU_MAX, 0, ],
208 [ "9999999999", undef, $ATOU_MAX, 0, ],
209 [ "10000000000", undef, $ATOU_MAX, 0, ],
210 [ "12345678901", undef, $ATOU_MAX, 0, ],
dd52de80 211
75feedba 212 # 64-bit values are way beyond.
22ff3130
HS
213 [ "18446744073709551613", undef, $ATOU_MAX, 0, ],
214 [ "18446744073709551614", undef, $ATOU_MAX, 0, ],
215 [ "18446744073709551615", undef, $ATOU_MAX, 0, ],
216 [ "18446744073709551616", undef, $ATOU_MAX, 0, ],
217 [ "18446744073709551617", undef, $ATOU_MAX, 0, ],
dd52de80
JH
218 );
219}
220
75feedba 221# These will fail to fail once 128/256-bit systems arrive.
dd52de80
JH
222push @atous,
223 (
22ff3130
HS
224 [ "23456789012345678901", undef, $ATOU_MAX, 0 ],
225 [ "34567890123456789012", undef, $ATOU_MAX, 0 ],
226 [ "98765432109876543210", undef, $ATOU_MAX, 0 ],
227 [ "98765432109876543211", undef, $ATOU_MAX, 0 ],
228 [ "99999999999999999999", undef, $ATOU_MAX, 0 ],
dd52de80
JH
229 );
230
231for my $grok (@atous) {
232 my $input = $grok->[0];
233 my $endsv = $grok->[1];
22ff3130
HS
234 my $expect_ok = defined $endsv;
235 my $strict_ok = $expect_ok && $endsv eq '';
dd52de80 236
22ff3130 237 my ($ok, $out_uv, $out_len);
dd52de80
JH
238
239 # First with endsv.
22ff3130
HS
240 ($ok, $out_uv, $out_len) = grok_atoUV($input, $endsv);
241 is($expect_ok, $ok, sprintf "'$input' expected %s, got %s",
242 ($expect_ok ? 'success' : 'failure'),
243 ($ok ? 'success' : 'failure'),
244 );
245 if ($expect_ok) {
246 is($expect_ok, $ok, "'$input' expect success");
247 is($out_uv, $grok->[2],
248 "'$input' $endsv - number success (got $out_uv cf $grok->[2])");
249 ok($grok->[3] <= length $input, "'$input' $endsv - length sanity 1");
250 unless (length $grok->[1]) {
251 is($out_len, $grok->[3], "'$input' $endsv - length sanity 2");
252 } # else { ... } ?
253 if ($out_len) {
254 is($endsv, substr($input, $out_len),
255 "'$input' $endsv - length sanity 3");
256 }
257 } else {
258 is($expect_ok, $ok, "'$input' expect failure");
259 is(0xdeadbeef, $out_uv, "'$input' on failure expect value unchanged");
75feedba 260 }
dd52de80
JH
261
262 # Then without endsv (undef == NULL).
22ff3130
HS
263 ($ok, $out_uv, $out_len) = grok_atoUV($input, undef);
264 if ($strict_ok) {
265 is($strict_ok, $ok, "'$input' expect strict success");
dd52de80 266 is($out_uv, $grok->[2],
22ff3130
HS
267 "'$input' $endsv - strict number success (got $out_uv cf $grok->[2])");
268 } else {
269 is($strict_ok, $ok, "'$input' expect strict failure");
270 is(0xdeadbeef, $out_uv, "'$input' on strict failure expect value unchanged");
dd52de80
JH
271 }
272}
273
ffe53d21 274done_testing();