8 no warnings 'experimental::smartmatch';
9 use constant TRUTH => '0 but true';
11 # Tests for grok_number. Not yet comprehensive.
12 foreach 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)),
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,
26 is($flags & IS_NUMBER_NEG, $sign eq '-' ? IS_NUMBER_NEG : 0,
28 is($value, abs $string, "value is correct");
34 given ($Config{ivsize}) {
36 @UV = qw(429496729 4294967290 4294967294 4294967295);
37 @NV = qw(4294967296 4294967297 4294967300 4294967304);
40 @UV = qw(1844674407370955161 18446744073709551610
41 18446744073709551614 18446744073709551615);
42 @NV = qw(18446744073709551616 18446744073709551617
43 18446744073709551620 18446744073709551624);
46 die "Unknown IV size $_";
50 my $string = $leader . $_ . $trailer;
51 my ($flags, $value) = grok_number($string);
52 is($flags & IS_NUMBER_IN_UV, IS_NUMBER_IN_UV,
54 is($value, abs $string, "value is correct");
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");
64 my $string = $leader . TRUTH . $trailer;
65 my ($flags, $value) = grok_number($string);
67 if ($string eq TRUTH) {
68 is($flags & IS_NUMBER_IN_UV, IS_NUMBER_IN_UV, "'$string' is a UV");
71 is($flags, 0, "'$string' is not a number");
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 ],
94 IS_NUMBER_INFINITY | IS_NUMBER_NOT_INT ],
95 [ "In", 0, undef, 0 ],
96 [ "Infin",0, undef, 0 ],
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 ],
101 # even without PERL_SCAN_TRAILING nan can have weird stuff trailing
102 [ "nanx", 0, undef, IS_NUMBER_NAN | IS_NUMBER_NOT_INT ],
103 [ "nanx", PERL_SCAN_TRAILING, undef, IS_NUMBER_NAN | IS_NUMBER_NOT_INT ],
106 for my $grok (@groks) {
107 my ($out_flags, $out_uv) = grok_number_flags($grok->[0], $grok->[1]);
108 is($out_uv, $grok->[2], "'$grok->[0]' flags $grok->[1] - check number");
109 is($out_flags, $grok->[3], "'$grok->[0]' flags $grok->[1] - check flags");
117 # [ input, endsv, out uv, out len ]
125 [ "123", "", 123, 3 ],
127 # Trailing whitespace is accepted or rejected, depending on endptr.
131 [ "12 ", " ", 12, 2 ],
133 # Trailing garbage is accepted or rejected, depending on endptr.
137 [ "12x", "x", 12, 2 ],
139 # Leading whitespace is failure.
140 [ " 0", " 0", 0, 0 ],
141 [ " 1", " 1", 0, 0 ],
142 [ " 12", " 12", 0, 0 ],
144 # Leading garbage is outright failure.
145 [ "x0", "x0", 0, 0 ],
146 [ "x1", "x1", 0, 0 ],
147 [ "x12", "x12", 0, 0 ],
149 # We do not parse decimal point.
150 [ "12.3", ".3", 12, 2 ],
152 # Leading pluses or minuses are no good.
153 [ "+12", "+12", 0, 0 ],
154 [ "-12", "-12", 0, 0 ],
156 # Extra leading zeros cause overflow.
157 [ "00", "00", $ATOU_MAX, 0 ],
158 [ "01", "01", $ATOU_MAX, 0 ],
159 [ "012", "012", $ATOU_MAX, 0 ],
162 # Values near overflow point.
163 if ($Config{uvsize} == 8) {
166 # 32-bit values no problem for 64-bit.
167 [ "4294967293", "", 4294967293, 10, ],
168 [ "4294967294", "", 4294967294, 10, ],
169 [ "4294967295", "", 4294967295, 10, ],
170 [ "4294967296", "", 4294967296, 10, ],
171 [ "4294967297", "", 4294967297, 10, ],
173 # This is well within 64-bit.
174 [ "9999999999", "", 9999999999, 10, ],
176 # Values valid up to 64-bit and beyond.
177 [ "18446744073709551613", "", 18446744073709551613, 20, ],
178 [ "18446744073709551614", "", 18446744073709551614, 20, ],
179 [ "18446744073709551615", "", $ATOU_MAX, 20, ],
180 [ "18446744073709551616", "", $ATOU_MAX, 0, ],
181 [ "18446744073709551617", "", $ATOU_MAX, 0, ],
183 } elsif ($Config{uvsize} == 4) {
186 # Values valid up to 32-bit and beyond.
187 [ "4294967293", "", 4294967293, 10, ],
188 [ "4294967294", "", 4294967294, 10, ],
189 [ "4294967295", "", $ATOU_MAX, 10, ],
190 [ "4294967296", "", $ATOU_MAX, 0, ],
191 [ "4294967297", "", $ATOU_MAX, 0, ],
193 # Still beyond 32-bit.
194 [ "4999999999", "", $ATOU_MAX, 0, ],
195 [ "5678901234", "", $ATOU_MAX, 0, ],
196 [ "6789012345", "", $ATOU_MAX, 0, ],
197 [ "7890123456", "", $ATOU_MAX, 0, ],
198 [ "8901234567", "", $ATOU_MAX, 0, ],
199 [ "9012345678", "", $ATOU_MAX, 0, ],
200 [ "9999999999", "", $ATOU_MAX, 0, ],
201 [ "10000000000", "", $ATOU_MAX, 0, ],
202 [ "12345678901", "", $ATOU_MAX, 0, ],
204 # 64-bit values are way beyond.
205 [ "18446744073709551613", "", $ATOU_MAX, 0, ],
206 [ "18446744073709551614", "", $ATOU_MAX, 0, ],
207 [ "18446744073709551615", "", $ATOU_MAX, 0, ],
208 [ "18446744073709551616", "", $ATOU_MAX, 0, ],
209 [ "18446744073709551617", "", $ATOU_MAX, 0, ],
213 # These will fail to fail once 128/256-bit systems arrive.
216 [ "23456789012345678901", "", $ATOU_MAX, 0 ],
217 [ "34567890123456789012", "", $ATOU_MAX, 0 ],
218 [ "98765432109876543210", "", $ATOU_MAX, 0 ],
219 [ "98765432109876543211", "", $ATOU_MAX, 0 ],
220 [ "99999999999999999999", "", $ATOU_MAX, 0 ],
223 for my $grok (@atous) {
224 my $input = $grok->[0];
225 my $endsv = $grok->[1];
227 my ($out_uv, $out_len);
230 ($out_uv, $out_len) = grok_atou($input, $endsv);
231 is($out_uv, $grok->[2],
232 "'$input' $endsv - number success (got $out_uv cf $grok->[2])");
233 ok($grok->[3] <= length $input, "'$input' $endsv - length sanity 1");
234 unless (length $grok->[1]) {
235 is($out_len, $grok->[3], "'$input' $endsv - length sanity 2");
238 is($endsv, substr($input, $out_len),
239 "'$input' $endsv - length sanity 3");
242 # Then without endsv (undef == NULL).
243 ($out_uv, $out_len) = grok_atou($input, undef);
244 if (length $grok->[1]) {
245 if ($grok->[2] == $ATOU_MAX) {
246 is($out_uv, $ATOU_MAX, "'$input' undef - number overflow");
248 is($out_uv, 0, "'$input' undef - number zero");
251 is($out_uv, $grok->[2],
252 "'$input' undef - number success (got $out_uv cf $grok->[2])");