Commit | Line | Data |
---|---|---|
a687059c LW |
1 | #!./perl |
2 | ||
4fe3f0fa MHM |
3 | BEGIN { |
4 | chdir 't' if -d 't'; | |
624c42e2 N |
5 | require './test.pl'; |
6 | set_up_inc('../lib', '.'); | |
4fe3f0fa | 7 | } |
4e086238 | 8 | # Avoid using eq_array below as it uses .. internally. |
4fe3f0fa MHM |
9 | |
10 | use Config; | |
11 | ||
d1bc97fe | 12 | plan (162); |
a687059c | 13 | |
4e086238 | 14 | is(join(':',1..5), '1:2:3:4:5'); |
a687059c LW |
15 | |
16 | @foo = (1,2,3,4,5,6,7,8,9); | |
17 | @foo[2..4] = ('c','d','e'); | |
18 | ||
4e086238 | 19 | is(join(':',@foo[$foo[0]..5]), '2:c:d:e:6'); |
a687059c LW |
20 | |
21 | @bar[2..4] = ('c','d','e'); | |
4e086238 | 22 | is(join(':',@bar[1..5]), ':c:d:e:'); |
a687059c LW |
23 | |
24 | ($a,@bcd[0..2],$e) = ('a','b','c','d','e'); | |
4e086238 | 25 | is(join(':',$a,@bcd[0..2],$e), 'a:b:c:d:e'); |
a687059c LW |
26 | |
27 | $x = 0; | |
28 | for (1..100) { | |
29 | $x += $_; | |
30 | } | |
4e086238 | 31 | is($x, 5050); |
a687059c LW |
32 | |
33 | $x = 0; | |
34 | for ((100,2..99,1)) { | |
35 | $x += $_; | |
36 | } | |
4e086238 | 37 | is($x, 5050); |
0f85fab0 LW |
38 | |
39 | $x = join('','a'..'z'); | |
4e086238 | 40 | is($x, 'abcdefghijklmnopqrstuvwxyz'); |
0f85fab0 LW |
41 | |
42 | @x = 'A'..'ZZ'; | |
4e086238 | 43 | is (scalar @x, 27 * 26); |
89ea2908 | 44 | |
d6c970c7 AC |
45 | foreach (0, 1) { |
46 | use feature 'unicode_strings'; | |
47 | $s = "a"; | |
48 | $e = "\xFF"; | |
49 | utf8::upgrade($e) if $_; | |
50 | @x = $s .. $e; | |
51 | is (scalar @x, 26, "list-context range with rhs 0xFF, utf8=$_"); | |
52 | @y = (); | |
53 | foreach ($s .. $e) { | |
54 | push @y, $_; | |
55 | } | |
56 | is(join(",", @y), join(",", @x), "foreach range with rhs 0xFF, utf8=$_"); | |
57 | } | |
58 | ||
89ea2908 | 59 | @x = '09' .. '08'; # should produce '09', '10',... '99' (strange but true) |
4e086238 | 60 | is(join(",", @x), join(",", map {sprintf "%02d",$_} 9..99)); |
89ea2908 GA |
61 | |
62 | # same test with foreach (which is a separate implementation) | |
63 | @y = (); | |
64 | foreach ('09'..'08') { | |
65 | push(@y, $_); | |
66 | } | |
4e086238 | 67 | is(join(",", @y), join(",", @x)); |
89ea2908 | 68 | |
c1ab3db2 | 69 | # check bounds |
4fe3f0fa MHM |
70 | if ($Config{ivsize} == 8) { |
71 | @a = eval "0x7ffffffffffffffe..0x7fffffffffffffff"; | |
72 | $a = "9223372036854775806 9223372036854775807"; | |
73 | @b = eval "-0x7fffffffffffffff..-0x7ffffffffffffffe"; | |
74 | $b = "-9223372036854775807 -9223372036854775806"; | |
75 | } | |
76 | else { | |
77 | @a = eval "0x7ffffffe..0x7fffffff"; | |
78 | $a = "2147483646 2147483647"; | |
79 | @b = eval "-0x7fffffff..-0x7ffffffe"; | |
80 | $b = "-2147483647 -2147483646"; | |
81 | } | |
82 | ||
4e086238 | 83 | is ("@a", $a); |
c1ab3db2 | 84 | |
4e086238 | 85 | is ("@b", $b); |
c1ab3db2 | 86 | |
86cb7173 HS |
87 | # check magic |
88 | { | |
89 | my $bad = 0; | |
90 | local $SIG{'__WARN__'} = sub { $bad = 1 }; | |
91 | my $x = 'a-e'; | |
92 | $x =~ s/(\w)-(\w)/join ':', $1 .. $2/e; | |
4e086238 | 93 | is ($x, 'a:b:c:d:e'); |
86cb7173 | 94 | } |
39eb4040 GS |
95 | |
96 | # Should use magical autoinc only when both are strings | |
4e086238 NC |
97 | { |
98 | my $scalar = (() = "0"..-1); | |
99 | is ($scalar, 0); | |
100 | } | |
101 | { | |
102 | my $fail = 0; | |
103 | for my $x ("0"..-1) { | |
104 | $fail++; | |
105 | } | |
106 | is ($fail, 0); | |
39eb4040 | 107 | } |
545956b7 MJD |
108 | |
109 | # [#18165] Should allow "-4".."0", broken by #4730. (AMS 20021031) | |
4e086238 NC |
110 | is(join(":","-4".."0") , "-4:-3:-2:-1:0"); |
111 | is(join(":","-4".."-0") , "-4:-3:-2:-1:0"); | |
112 | is(join(":","-4\n".."0\n") , "-4:-3:-2:-1:0"); | |
113 | is(join(":","-4\n".."-0\n"), "-4:-3:-2:-1:0"); | |
b0e74086 | 114 | |
d1bc97fe H |
115 | # [#133695] "0".."-1" should be the same as 0..-1 |
116 | is(join(":","-2".."-1") , "-2:-1"); | |
117 | is(join(":","-1".."-1") , "-1"); | |
118 | is(join(":","0".."-1") , ""); | |
119 | is(join(":","1".."-1") , ""); | |
120 | ||
121 | # these test the statements made in the documentation | |
122 | # regarding the rules of string ranges | |
123 | is(join(":","-2".."2"), join(":",-2..2)); | |
124 | is(join(":","2.18".."3.14"), "2:3"); | |
125 | is(join(":","01".."04"), "01:02:03:04"); | |
126 | is(join(":","00".."-1"), "00:01:02:03:04:05:06:07:08:09:10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56:57:58:59:60:61:62:63:64:65:66:67:68:69:70:71:72:73:74:75:76:77:78:79:80:81:82:83:84:85:86:87:88:89:90:91:92:93:94:95:96:97:98:99"); | |
127 | is(join(":","00".."31"), "00:01:02:03:04:05:06:07:08:09:10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25:26:27:28:29:30:31"); | |
128 | is(join(":","ax".."az"), "ax:ay:az"); | |
129 | is(join(":","*x".."az"), "*x"); | |
130 | is(join(":","A".."Z"), "A:B:C:D:E:F:G:H:I:J:K:L:M:N:O:P:Q:R:S:T:U:V:W:X:Y:Z"); | |
131 | is(join(":", 0..9,"a".."f"), "0:1:2:3:4:5:6:7:8:9:a:b:c:d:e:f"); | |
132 | is(join(":","a".."--"), join(":","a".."zz")); | |
133 | is(join(":","0".."xx"), "0:1:2:3:4:5:6:7:8:9:10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56:57:58:59:60:61:62:63:64:65:66:67:68:69:70:71:72:73:74:75:76:77:78:79:80:81:82:83:84:85:86:87:88:89:90:91:92:93:94:95:96:97:98:99"); | |
134 | is(join(":","aaa".."--"), ""); | |
135 | ||
b0e74086 | 136 | # undef should be treated as 0 for numerical range |
4e086238 NC |
137 | is(join(":",undef..2), '0:1:2'); |
138 | is(join(":",-2..undef), '-2:-1:0'); | |
139 | is(join(":",undef..'2'), '0:1:2'); | |
140 | is(join(":",'-2'..undef), '-2:-1:0'); | |
b0e74086 RGS |
141 | |
142 | # undef should be treated as "" for magical range | |
4e086238 NC |
143 | is(join(":", map "[$_]", "".."B"), '[]'); |
144 | is(join(":", map "[$_]", undef.."B"), '[]'); | |
145 | is(join(":", map "[$_]", "B"..""), ''); | |
146 | is(join(":", map "[$_]", "B"..undef), ''); | |
3f63a782 | 147 | |
076d9a11 | 148 | # undef..undef used to segfault |
4e086238 | 149 | is(join(":", map "[$_]", undef..undef), '[]'); |
3f63a782 MHM |
150 | |
151 | # also test undef in foreach loops | |
152 | @foo=(); push @foo, $_ for undef..2; | |
4e086238 | 153 | is(join(":", @foo), '0:1:2'); |
3f63a782 MHM |
154 | |
155 | @foo=(); push @foo, $_ for -2..undef; | |
4e086238 | 156 | is(join(":", @foo), '-2:-1:0'); |
076d9a11 MHM |
157 | |
158 | @foo=(); push @foo, $_ for undef..'2'; | |
4e086238 | 159 | is(join(":", @foo), '0:1:2'); |
076d9a11 MHM |
160 | |
161 | @foo=(); push @foo, $_ for '-2'..undef; | |
4e086238 | 162 | is(join(":", @foo), '-2:-1:0'); |
3f63a782 MHM |
163 | |
164 | @foo=(); push @foo, $_ for undef.."B"; | |
4e086238 | 165 | is(join(":", map "[$_]", @foo), '[]'); |
6b75d741 MHM |
166 | |
167 | @foo=(); push @foo, $_ for "".."B"; | |
4e086238 | 168 | is(join(":", map "[$_]", @foo), '[]'); |
3f63a782 MHM |
169 | |
170 | @foo=(); push @foo, $_ for "B"..undef; | |
4e086238 | 171 | is(join(":", map "[$_]", @foo), ''); |
6b75d741 MHM |
172 | |
173 | @foo=(); push @foo, $_ for "B"..""; | |
4e086238 | 174 | is(join(":", map "[$_]", @foo), ''); |
6b75d741 MHM |
175 | |
176 | @foo=(); push @foo, $_ for undef..undef; | |
4e086238 | 177 | is(join(":", map "[$_]", @foo), '[]'); |
984a4bea RD |
178 | |
179 | # again with magic | |
180 | { | |
181 | my @a = (1..3); | |
182 | @foo=(); push @foo, $_ for undef..$#a; | |
4e086238 | 183 | is(join(":", @foo), '0:1:2'); |
984a4bea RD |
184 | } |
185 | { | |
186 | my @a = (); | |
187 | @foo=(); push @foo, $_ for $#a..undef; | |
4e086238 | 188 | is(join(":", @foo), '-1:0'); |
984a4bea RD |
189 | } |
190 | { | |
191 | local $1; | |
192 | "2" =~ /(.+)/; | |
193 | @foo=(); push @foo, $_ for undef..$1; | |
4e086238 | 194 | is(join(":", @foo), '0:1:2'); |
984a4bea RD |
195 | } |
196 | { | |
197 | local $1; | |
198 | "-2" =~ /(.+)/; | |
199 | @foo=(); push @foo, $_ for $1..undef; | |
4e086238 | 200 | is(join(":", @foo), '-2:-1:0'); |
984a4bea RD |
201 | } |
202 | { | |
203 | local $1; | |
204 | "B" =~ /(.+)/; | |
205 | @foo=(); push @foo, $_ for undef..$1; | |
4e086238 | 206 | is(join(":", map "[$_]", @foo), '[]'); |
984a4bea RD |
207 | } |
208 | { | |
209 | local $1; | |
210 | "B" =~ /(.+)/; | |
211 | @foo=(); push @foo, $_ for ""..$1; | |
4e086238 | 212 | is(join(":", map "[$_]", @foo), '[]'); |
984a4bea RD |
213 | } |
214 | { | |
215 | local $1; | |
216 | "B" =~ /(.+)/; | |
217 | @foo=(); push @foo, $_ for $1..undef; | |
4e086238 | 218 | is(join(":", map "[$_]", @foo), ''); |
984a4bea RD |
219 | } |
220 | { | |
221 | local $1; | |
222 | "B" =~ /(.+)/; | |
223 | @foo=(); push @foo, $_ for $1..""; | |
4e086238 | 224 | is(join(":", map "[$_]", @foo), ''); |
984a4bea | 225 | } |
a2309040 JH |
226 | |
227 | # Test upper range limit | |
228 | my $MAX_INT = ~0>>1; | |
229 | ||
230 | foreach my $ii (-3 .. 3) { | |
231 | my ($first, $last); | |
232 | eval { | |
233 | my $lim=0; | |
234 | for ($MAX_INT-10 .. $MAX_INT+$ii) { | |
235 | if (! defined($first)) { | |
236 | $first = $_; | |
237 | } | |
238 | $last = $_; | |
239 | last if ($lim++ > 100); # Protect against integer wrap | |
240 | } | |
241 | }; | |
242 | if ($ii <= 0) { | |
243 | ok(! $@, 'Upper bound accepted: ' . ($MAX_INT+$ii)); | |
244 | is($first, $MAX_INT-10, 'Lower bound okay'); | |
245 | is($last, $MAX_INT+$ii, 'Upper bound okay'); | |
246 | } else { | |
247 | ok($@, 'Upper bound rejected: ' . ($MAX_INT+$ii)); | |
248 | } | |
249 | } | |
250 | ||
251 | foreach my $ii (-3 .. 3) { | |
252 | my ($first, $last); | |
253 | eval { | |
254 | my $lim=0; | |
255 | for ($MAX_INT+$ii .. $MAX_INT) { | |
256 | if (! defined($first)) { | |
257 | $first = $_; | |
258 | } | |
259 | $last = $_; | |
260 | last if ($lim++ > 100); | |
261 | } | |
262 | }; | |
263 | if ($ii <= 0) { | |
264 | ok(! $@, 'Lower bound accepted: ' . ($MAX_INT+$ii)); | |
265 | is($first, $MAX_INT+$ii, 'Lower bound okay'); | |
266 | is($last, $MAX_INT, 'Upper bound okay'); | |
267 | } else { | |
268 | ok($@, 'Lower bound rejected: ' . ($MAX_INT+$ii)); | |
269 | } | |
270 | } | |
271 | ||
272 | { | |
273 | my $first; | |
274 | eval { | |
275 | my $lim=0; | |
276 | for ($MAX_INT .. $MAX_INT-1) { | |
277 | if (! defined($first)) { | |
278 | $first = $_; | |
279 | } | |
280 | $last = $_; | |
281 | last if ($lim++ > 100); | |
282 | } | |
283 | }; | |
284 | ok(! $@, 'Range accepted'); | |
285 | ok(! defined($first), 'Range ineffectual'); | |
286 | } | |
287 | ||
288 | foreach my $ii (~0, ~0+1, ~0+(~0>>4)) { | |
289 | eval { | |
290 | my $lim=0; | |
291 | for ($MAX_INT-10 .. $ii) { | |
292 | last if ($lim++ > 100); | |
293 | } | |
294 | }; | |
295 | ok($@, 'Upper bound rejected: ' . $ii); | |
296 | } | |
297 | ||
298 | # Test lower range limit | |
299 | my $MIN_INT = -1-$MAX_INT; | |
300 | ||
301 | if (! $Config{d_nv_preserves_uv}) { | |
302 | # $MIN_INT needs adjustment when IV won't fit into an NV | |
303 | my $NV = $MIN_INT - 1; | |
304 | my $OFFSET = 1; | |
305 | while (($NV + $OFFSET) == $MIN_INT) { | |
306 | $OFFSET++ | |
307 | } | |
308 | $MIN_INT += $OFFSET; | |
309 | } | |
310 | ||
311 | foreach my $ii (-3 .. 3) { | |
312 | my ($first, $last); | |
313 | eval { | |
314 | my $lim=0; | |
315 | for ($MIN_INT+$ii .. $MIN_INT+10) { | |
316 | if (! defined($first)) { | |
317 | $first = $_; | |
318 | } | |
319 | $last = $_; | |
320 | last if ($lim++ > 100); | |
321 | } | |
322 | }; | |
323 | if ($ii >= 0) { | |
324 | ok(! $@, 'Lower bound accepted: ' . ($MIN_INT+$ii)); | |
325 | is($first, $MIN_INT+$ii, 'Lower bound okay'); | |
326 | is($last, $MIN_INT+10, 'Upper bound okay'); | |
327 | } else { | |
328 | ok($@, 'Lower bound rejected: ' . ($MIN_INT+$ii)); | |
329 | } | |
330 | } | |
331 | ||
332 | foreach my $ii (-3 .. 3) { | |
333 | my ($first, $last); | |
334 | eval { | |
335 | my $lim=0; | |
336 | for ($MIN_INT .. $MIN_INT+$ii) { | |
337 | if (! defined($first)) { | |
338 | $first = $_; | |
339 | } | |
340 | $last = $_; | |
341 | last if ($lim++ > 100); | |
342 | } | |
343 | }; | |
344 | if ($ii >= 0) { | |
345 | ok(! $@, 'Upper bound accepted: ' . ($MIN_INT+$ii)); | |
346 | is($first, $MIN_INT, 'Lower bound okay'); | |
347 | is($last, $MIN_INT+$ii, 'Upper bound okay'); | |
348 | } else { | |
349 | ok($@, 'Upper bound rejected: ' . ($MIN_INT+$ii)); | |
350 | } | |
351 | } | |
352 | ||
353 | { | |
354 | my $first; | |
355 | eval { | |
356 | my $lim=0; | |
357 | for ($MIN_INT+1 .. $MIN_INT) { | |
358 | if (! defined($first)) { | |
359 | $first = $_; | |
360 | } | |
361 | $last = $_; | |
362 | last if ($lim++ > 100); | |
363 | } | |
364 | }; | |
365 | ok(! $@, 'Range accepted'); | |
366 | ok(! defined($first), 'Range ineffectual'); | |
367 | } | |
368 | ||
369 | foreach my $ii (~0, ~0+1, ~0+(~0>>4)) { | |
370 | eval { | |
371 | my $lim=0; | |
372 | for (-$ii .. $MIN_INT+10) { | |
373 | last if ($lim++ > 100); | |
374 | } | |
375 | }; | |
376 | ok($@, 'Lower bound rejected: ' . -$ii); | |
377 | } | |
378 | ||
93f09d7b | 379 | # double/triple magic tests |
bd1c7bd2 B |
380 | sub TIESCALAR { bless { value => $_[1], orig => $_[1] } } |
381 | sub STORE { $_[0]{store}++; $_[0]{value} = $_[1] } | |
382 | sub FETCH { $_[0]{fetch}++; $_[0]{value} } | |
383 | sub stores { tied($_[0])->{value} = tied($_[0])->{orig}; | |
384 | delete(tied($_[0])->{store}) || 0 } | |
385 | sub fetches { delete(tied($_[0])->{fetch}) || 0 } | |
386 | ||
387 | tie $x, "main", 6; | |
388 | ||
389 | my @foo; | |
390 | @foo = 4 .. $x; | |
391 | is(scalar @foo, 3); | |
392 | is("@foo", "4 5 6"); | |
f52e41ad | 393 | is(fetches($x), 1); |
bd1c7bd2 B |
394 | is(stores($x), 0); |
395 | ||
396 | @foo = $x .. 8; | |
397 | is(scalar @foo, 3); | |
398 | is("@foo", "6 7 8"); | |
f52e41ad | 399 | is(fetches($x), 1); |
bd1c7bd2 B |
400 | is(stores($x), 0); |
401 | ||
402 | @foo = $x .. $x + 1; | |
403 | is(scalar @foo, 2); | |
404 | is("@foo", "6 7"); | |
f52e41ad | 405 | is(fetches($x), 2); |
bd1c7bd2 B |
406 | is(stores($x), 0); |
407 | ||
408 | @foo = (); | |
409 | for (4 .. $x) { | |
410 | push @foo, $_; | |
411 | } | |
412 | is(scalar @foo, 3); | |
413 | is("@foo", "4 5 6"); | |
f52e41ad | 414 | is(fetches($x), 1); |
bd1c7bd2 B |
415 | is(stores($x), 0); |
416 | ||
417 | @foo = (); | |
418 | for (reverse 4 .. $x) { | |
419 | push @foo, $_; | |
420 | } | |
421 | is(scalar @foo, 3); | |
422 | is("@foo", "6 5 4"); | |
f52e41ad | 423 | is(fetches($x), 1); |
bd1c7bd2 B |
424 | is(stores($x), 0); |
425 | ||
2e0a827f EB |
426 | is( ( join ' ', map { join '', map ++$_, ($x=1)..4 } 1..2 ), '2345 2345', |
427 | 'modifiable variable num range' ); | |
ce1bce73 | 428 | is( ( join ' ', map { join '', map ++$_, 1..4 } 1..2 ), '2345 2345', |
5608dcc6 | 429 | 'modifiable const num range' ); # RT#3105 |
2e0a827f EB |
430 | $s = ''; for (1..2) { for (1..4) { $s .= ++$_ } $s.=' ' if $_==1; } |
431 | is( $s, '2345 2345','modifiable num counting loop counter' ); | |
432 | ||
433 | ||
434 | is( ( join ' ', map { join '', map ++$_, ($x='a')..'d' } 1..2 ), 'bcde bcde', | |
435 | 'modifiable variable alpha range' ); | |
ce1bce73 | 436 | is( ( join ' ', map { join '', map ++$_, 'a'..'d' } 1..2 ), 'bcde bcde', |
5608dcc6 | 437 | 'modifiable const alpha range' ); # RT#3105 |
2e0a827f EB |
438 | $s = ''; for (1..2) { for ('a'..'d') { $s .= ++$_ } $s.=' ' if $_==1; } |
439 | is( $s, 'bcde bcde','modifiable alpha counting loop counter' ); | |
440 | ||
a7dd840b DM |
441 | # RT #130841 |
442 | # generating an extreme range triggered a croak, which if caught, | |
443 | # left the temps stack small but with a very large PL_tmps_max | |
444 | ||
2d5eff8a DM |
445 | SKIP: { |
446 | skip 'mem wrap check disabled' unless $Config{usemallocwrap}; | |
447 | fresh_perl_like(<<'EOF', qr/\Aok 1 ok 2\Z/, {}, "RT #130841"); | |
a7dd840b DM |
448 | my $max_iv = (~0 >> 1); |
449 | eval { | |
450 | my @range = 1..($max_iv - 1); | |
451 | }; | |
452 | if ($@ =~ /panic: memory wrap|Out of memory/) { | |
453 | print "ok 1"; | |
454 | } | |
455 | else { | |
456 | print "unexpected err status: [$@]"; | |
457 | } | |
458 | ||
459 | # create and push lots of temps | |
460 | my $max = 10_000; | |
461 | my @ints = map $_+1, 0..($max-1); | |
462 | my $sum = 0; | |
463 | $sum += $_ for @ints; | |
464 | my $exp = $max*($max+1)/2; | |
465 | if ($sum == $exp) { | |
466 | print " ok 2"; | |
467 | } | |
468 | else { | |
469 | print " unexpected sum: [$sum]; expected: [$exp]"; | |
470 | } | |
471 | EOF | |
2d5eff8a | 472 | } |