This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Integrate Memoize 0.64. Few tweaks were required in
[perl5.git] / pp.c
CommitLineData
a0d0e21e 1/* pp.c
79072805 2 *
bc89e66f 3 * Copyright (c) 1991-2001, Larry Wall
79072805 4 *
a0d0e21e
LW
5 * You may distribute under the terms of either the GNU General Public
6 * License or the Artistic License, as specified in the README file.
79072805 7 *
a0d0e21e
LW
8 */
9
10/*
11 * "It's a big house this, and very peculiar. Always a bit more to discover,
12 * and no knowing what you'll find around a corner. And Elves, sir!" --Samwise
13 */
79072805
LW
14
15#include "EXTERN.h"
864dbfa3 16#define PERL_IN_PP_C
79072805
LW
17#include "perl.h"
18
36477c24 19/*
ef2d312d
TH
20 * The compiler on Concurrent CX/UX systems has a subtle bug which only
21 * seems to show up when compiling pp.c - it generates the wrong double
22 * precision constant value for (double)UV_MAX when used inline in the body
23 * of the code below, so this makes a static variable up front (which the
24 * compiler seems to get correct) and uses it in place of UV_MAX below.
25 */
26#ifdef CXUX_BROKEN_CONSTANT_CONVERT
27static double UV_MAX_cxux = ((double)UV_MAX);
8ec5e241 28#endif
ef2d312d
TH
29
30/*
96e4d5b1 31 * Offset for integer pack/unpack.
32 *
33 * On architectures where I16 and I32 aren't really 16 and 32 bits,
34 * which for now are all Crays, pack and unpack have to play games.
35 */
36
37/*
38 * These values are required for portability of pack() output.
39 * If they're not right on your machine, then pack() and unpack()
40 * wouldn't work right anyway; you'll need to apply the Cray hack.
41 * (I'd like to check them with #if, but you can't use sizeof() in
dc45a647
MB
42 * the preprocessor.) --???
43 */
44/*
45 The appropriate SHORTSIZE, INTSIZE, LONGSIZE, and LONGLONGSIZE
46 defines are now in config.h. --Andy Dougherty April 1998
96e4d5b1 47 */
48#define SIZE16 2
49#define SIZE32 4
50
9851f69c
JH
51/* CROSSCOMPILE and MULTIARCH are going to affect pp_pack() and pp_unpack().
52 --jhi Feb 1999 */
53
726ea183
JH
54#if SHORTSIZE != SIZE16 || LONGSIZE != SIZE32
55# define PERL_NATINT_PACK
56#endif
57
0f9dfb06 58#if LONGSIZE > 4 && defined(_CRAY)
96e4d5b1 59# if BYTEORDER == 0x12345678
60# define OFF16(p) (char*)(p)
61# define OFF32(p) (char*)(p)
62# else
63# if BYTEORDER == 0x87654321
64# define OFF16(p) ((char*)(p) + (sizeof(U16) - SIZE16))
65# define OFF32(p) ((char*)(p) + (sizeof(U32) - SIZE32))
66# else
67 }}}} bad cray byte order
68# endif
69# endif
70# define COPY16(s,p) (*(p) = 0, Copy(s, OFF16(p), SIZE16, char))
71# define COPY32(s,p) (*(p) = 0, Copy(s, OFF32(p), SIZE32, char))
ef54e1a4 72# define COPYNN(s,p,n) (*(p) = 0, Copy(s, (char *)(p), n, char))
96e4d5b1 73# define CAT16(sv,p) sv_catpvn(sv, OFF16(p), SIZE16)
74# define CAT32(sv,p) sv_catpvn(sv, OFF32(p), SIZE32)
75#else
76# define COPY16(s,p) Copy(s, p, SIZE16, char)
77# define COPY32(s,p) Copy(s, p, SIZE32, char)
ef54e1a4 78# define COPYNN(s,p,n) Copy(s, (char *)(p), n, char)
96e4d5b1 79# define CAT16(sv,p) sv_catpvn(sv, (char*)(p), SIZE16)
80# define CAT32(sv,p) sv_catpvn(sv, (char*)(p), SIZE32)
81#endif
82
a0d0e21e 83/* variations on pp_null */
79072805 84
dfe9444c
AD
85/* XXX I can't imagine anyone who doesn't have this actually _needs_
86 it, since pid_t is an integral type.
87 --AD 2/20/1998
88*/
89#ifdef NEED_GETPID_PROTO
90extern Pid_t getpid (void);
8ac85365
NIS
91#endif
92
93a17b20
LW
93PP(pp_stub)
94{
39644a26 95 dSP;
54310121 96 if (GIMME_V == G_SCALAR)
3280af22 97 XPUSHs(&PL_sv_undef);
93a17b20
LW
98 RETURN;
99}
100
79072805
LW
101PP(pp_scalar)
102{
103 return NORMAL;
104}
105
106/* Pushy stuff. */
107
93a17b20
LW
108PP(pp_padav)
109{
39644a26 110 dSP; dTARGET;
533c011a
NIS
111 if (PL_op->op_private & OPpLVAL_INTRO)
112 SAVECLEARSV(PL_curpad[PL_op->op_targ]);
85e6fe83 113 EXTEND(SP, 1);
533c011a 114 if (PL_op->op_flags & OPf_REF) {
85e6fe83 115 PUSHs(TARG);
93a17b20 116 RETURN;
78f9721b
SM
117 } else if (LVRET) {
118 if (GIMME == G_SCALAR)
119 Perl_croak(aTHX_ "Can't return array to lvalue scalar context");
120 PUSHs(TARG);
121 RETURN;
85e6fe83
LW
122 }
123 if (GIMME == G_ARRAY) {
124 I32 maxarg = AvFILL((AV*)TARG) + 1;
125 EXTEND(SP, maxarg);
93965878
NIS
126 if (SvMAGICAL(TARG)) {
127 U32 i;
128 for (i=0; i < maxarg; i++) {
129 SV **svp = av_fetch((AV*)TARG, i, FALSE);
3280af22 130 SP[i+1] = (svp) ? *svp : &PL_sv_undef;
93965878
NIS
131 }
132 }
133 else {
134 Copy(AvARRAY((AV*)TARG), SP+1, maxarg, SV*);
135 }
85e6fe83
LW
136 SP += maxarg;
137 }
138 else {
139 SV* sv = sv_newmortal();
140 I32 maxarg = AvFILL((AV*)TARG) + 1;
141 sv_setiv(sv, maxarg);
142 PUSHs(sv);
143 }
144 RETURN;
93a17b20
LW
145}
146
147PP(pp_padhv)
148{
39644a26 149 dSP; dTARGET;
54310121 150 I32 gimme;
151
93a17b20 152 XPUSHs(TARG);
533c011a
NIS
153 if (PL_op->op_private & OPpLVAL_INTRO)
154 SAVECLEARSV(PL_curpad[PL_op->op_targ]);
155 if (PL_op->op_flags & OPf_REF)
93a17b20 156 RETURN;
78f9721b
SM
157 else if (LVRET) {
158 if (GIMME == G_SCALAR)
159 Perl_croak(aTHX_ "Can't return hash to lvalue scalar context");
160 RETURN;
161 }
54310121 162 gimme = GIMME_V;
163 if (gimme == G_ARRAY) {
cea2e8a9 164 RETURNOP(do_kv());
85e6fe83 165 }
54310121 166 else if (gimme == G_SCALAR) {
85e6fe83 167 SV* sv = sv_newmortal();
46fc3d4c 168 if (HvFILL((HV*)TARG))
cea2e8a9 169 Perl_sv_setpvf(aTHX_ sv, "%ld/%ld",
46fc3d4c 170 (long)HvFILL((HV*)TARG), (long)HvMAX((HV*)TARG) + 1);
85e6fe83
LW
171 else
172 sv_setiv(sv, 0);
173 SETs(sv);
85e6fe83 174 }
54310121 175 RETURN;
93a17b20
LW
176}
177
ed6116ce
LW
178PP(pp_padany)
179{
cea2e8a9 180 DIE(aTHX_ "NOT IMPL LINE %d",__LINE__);
ed6116ce
LW
181}
182
79072805
LW
183/* Translations. */
184
185PP(pp_rv2gv)
186{
39644a26 187 dSP; dTOPss;
8ec5e241 188
ed6116ce 189 if (SvROK(sv)) {
a0d0e21e 190 wasref:
f5284f61
IZ
191 tryAMAGICunDEREF(to_gv);
192
ed6116ce 193 sv = SvRV(sv);
b1dadf13 194 if (SvTYPE(sv) == SVt_PVIO) {
195 GV *gv = (GV*) sv_newmortal();
196 gv_init(gv, 0, "", 0, 0);
197 GvIOp(gv) = (IO *)sv;
3e3baf6d 198 (void)SvREFCNT_inc(sv);
b1dadf13 199 sv = (SV*) gv;
ef54e1a4
JH
200 }
201 else if (SvTYPE(sv) != SVt_PVGV)
cea2e8a9 202 DIE(aTHX_ "Not a GLOB reference");
79072805
LW
203 }
204 else {
93a17b20 205 if (SvTYPE(sv) != SVt_PVGV) {
748a9306 206 char *sym;
c9d5ac95 207 STRLEN len;
748a9306 208
a0d0e21e
LW
209 if (SvGMAGICAL(sv)) {
210 mg_get(sv);
211 if (SvROK(sv))
212 goto wasref;
213 }
afd1915d 214 if (!SvOK(sv) && sv != &PL_sv_undef) {
b13b2135 215 /* If this is a 'my' scalar and flag is set then vivify
853846ea 216 * NI-S 1999/05/07
b13b2135 217 */
1d8d4d2a 218 if (PL_op->op_private & OPpDEREF) {
2c8ac474
GS
219 char *name;
220 GV *gv;
221 if (cUNOP->op_targ) {
222 STRLEN len;
223 SV *namesv = PL_curpad[cUNOP->op_targ];
224 name = SvPV(namesv, len);
2d6d9f7a 225 gv = (GV*)NEWSV(0,0);
2c8ac474
GS
226 gv_init(gv, CopSTASH(PL_curcop), name, len, 0);
227 }
228 else {
229 name = CopSTASHPV(PL_curcop);
230 gv = newGVgen(name);
1d8d4d2a 231 }
b13b2135
NIS
232 if (SvTYPE(sv) < SVt_RV)
233 sv_upgrade(sv, SVt_RV);
2c8ac474 234 SvRV(sv) = (SV*)gv;
853846ea 235 SvROK_on(sv);
1d8d4d2a 236 SvSETMAGIC(sv);
853846ea 237 goto wasref;
2c8ac474 238 }
533c011a
NIS
239 if (PL_op->op_flags & OPf_REF ||
240 PL_op->op_private & HINT_STRICT_REFS)
cea2e8a9 241 DIE(aTHX_ PL_no_usym, "a symbol");
599cee73 242 if (ckWARN(WARN_UNINITIALIZED))
b89fed5f 243 report_uninit();
a0d0e21e
LW
244 RETSETUNDEF;
245 }
c9d5ac95 246 sym = SvPV(sv,len);
35cd451c
GS
247 if ((PL_op->op_flags & OPf_SPECIAL) &&
248 !(PL_op->op_flags & OPf_MOD))
249 {
250 sv = (SV*)gv_fetchpv(sym, FALSE, SVt_PVGV);
c9d5ac95
GS
251 if (!sv
252 && (!is_gv_magical(sym,len,0)
253 || !(sv = (SV*)gv_fetchpv(sym, TRUE, SVt_PVGV))))
254 {
35cd451c 255 RETSETUNDEF;
c9d5ac95 256 }
35cd451c
GS
257 }
258 else {
259 if (PL_op->op_private & HINT_STRICT_REFS)
cea2e8a9 260 DIE(aTHX_ PL_no_symref, sym, "a symbol");
35cd451c
GS
261 sv = (SV*)gv_fetchpv(sym, TRUE, SVt_PVGV);
262 }
93a17b20 263 }
79072805 264 }
533c011a
NIS
265 if (PL_op->op_private & OPpLVAL_INTRO)
266 save_gp((GV*)sv, !(PL_op->op_flags & OPf_SPECIAL));
79072805
LW
267 SETs(sv);
268 RETURN;
269}
270
79072805
LW
271PP(pp_rv2sv)
272{
39644a26 273 dSP; dTOPss;
79072805 274
ed6116ce 275 if (SvROK(sv)) {
a0d0e21e 276 wasref:
f5284f61
IZ
277 tryAMAGICunDEREF(to_sv);
278
ed6116ce 279 sv = SvRV(sv);
79072805
LW
280 switch (SvTYPE(sv)) {
281 case SVt_PVAV:
282 case SVt_PVHV:
283 case SVt_PVCV:
cea2e8a9 284 DIE(aTHX_ "Not a SCALAR reference");
79072805
LW
285 }
286 }
287 else {
f12c7020 288 GV *gv = (GV*)sv;
748a9306 289 char *sym;
c9d5ac95 290 STRLEN len;
748a9306 291
463ee0b2 292 if (SvTYPE(gv) != SVt_PVGV) {
a0d0e21e
LW
293 if (SvGMAGICAL(sv)) {
294 mg_get(sv);
295 if (SvROK(sv))
296 goto wasref;
297 }
298 if (!SvOK(sv)) {
533c011a
NIS
299 if (PL_op->op_flags & OPf_REF ||
300 PL_op->op_private & HINT_STRICT_REFS)
cea2e8a9 301 DIE(aTHX_ PL_no_usym, "a SCALAR");
599cee73 302 if (ckWARN(WARN_UNINITIALIZED))
b89fed5f 303 report_uninit();
a0d0e21e
LW
304 RETSETUNDEF;
305 }
c9d5ac95 306 sym = SvPV(sv, len);
35cd451c
GS
307 if ((PL_op->op_flags & OPf_SPECIAL) &&
308 !(PL_op->op_flags & OPf_MOD))
309 {
310 gv = (GV*)gv_fetchpv(sym, FALSE, SVt_PV);
c9d5ac95
GS
311 if (!gv
312 && (!is_gv_magical(sym,len,0)
313 || !(gv = (GV*)gv_fetchpv(sym, TRUE, SVt_PV))))
314 {
35cd451c 315 RETSETUNDEF;
c9d5ac95 316 }
35cd451c
GS
317 }
318 else {
319 if (PL_op->op_private & HINT_STRICT_REFS)
cea2e8a9 320 DIE(aTHX_ PL_no_symref, sym, "a SCALAR");
35cd451c
GS
321 gv = (GV*)gv_fetchpv(sym, TRUE, SVt_PV);
322 }
463ee0b2
LW
323 }
324 sv = GvSV(gv);
a0d0e21e 325 }
533c011a
NIS
326 if (PL_op->op_flags & OPf_MOD) {
327 if (PL_op->op_private & OPpLVAL_INTRO)
a0d0e21e 328 sv = save_scalar((GV*)TOPs);
533c011a
NIS
329 else if (PL_op->op_private & OPpDEREF)
330 vivify_ref(sv, PL_op->op_private & OPpDEREF);
79072805 331 }
a0d0e21e 332 SETs(sv);
79072805
LW
333 RETURN;
334}
335
336PP(pp_av2arylen)
337{
39644a26 338 dSP;
79072805
LW
339 AV *av = (AV*)TOPs;
340 SV *sv = AvARYLEN(av);
341 if (!sv) {
342 AvARYLEN(av) = sv = NEWSV(0,0);
343 sv_upgrade(sv, SVt_IV);
14befaf4 344 sv_magic(sv, (SV*)av, PERL_MAGIC_arylen, Nullch, 0);
79072805
LW
345 }
346 SETs(sv);
347 RETURN;
348}
349
a0d0e21e
LW
350PP(pp_pos)
351{
39644a26 352 dSP; dTARGET; dPOPss;
8ec5e241 353
78f9721b 354 if (PL_op->op_flags & OPf_MOD || LVRET) {
5f05dabc 355 if (SvTYPE(TARG) < SVt_PVLV) {
356 sv_upgrade(TARG, SVt_PVLV);
14befaf4 357 sv_magic(TARG, Nullsv, PERL_MAGIC_pos, Nullch, 0);
5f05dabc 358 }
359
360 LvTYPE(TARG) = '.';
6ff81951
GS
361 if (LvTARG(TARG) != sv) {
362 if (LvTARG(TARG))
363 SvREFCNT_dec(LvTARG(TARG));
364 LvTARG(TARG) = SvREFCNT_inc(sv);
365 }
a0d0e21e
LW
366 PUSHs(TARG); /* no SvSETMAGIC */
367 RETURN;
368 }
369 else {
8ec5e241 370 MAGIC* mg;
a0d0e21e
LW
371
372 if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv)) {
14befaf4 373 mg = mg_find(sv, PERL_MAGIC_regex_global);
565764a8 374 if (mg && mg->mg_len >= 0) {
a0ed51b3 375 I32 i = mg->mg_len;
7e2040f0 376 if (DO_UTF8(sv))
a0ed51b3
LW
377 sv_pos_b2u(sv, &i);
378 PUSHi(i + PL_curcop->cop_arybase);
a0d0e21e
LW
379 RETURN;
380 }
381 }
382 RETPUSHUNDEF;
383 }
384}
385
79072805
LW
386PP(pp_rv2cv)
387{
39644a26 388 dSP;
79072805
LW
389 GV *gv;
390 HV *stash;
8990e307 391
4633a7c4
LW
392 /* We usually try to add a non-existent subroutine in case of AUTOLOAD. */
393 /* (But not in defined().) */
533c011a 394 CV *cv = sv_2cv(TOPs, &stash, &gv, !(PL_op->op_flags & OPf_SPECIAL));
07055b4c
CS
395 if (cv) {
396 if (CvCLONE(cv))
397 cv = (CV*)sv_2mortal((SV*)cv_clone(cv));
d32f2495
SC
398 if ((PL_op->op_private & OPpLVAL_INTRO)) {
399 if (gv && GvCV(gv) == cv && (gv = gv_autoload4(GvSTASH(gv), GvNAME(gv), GvNAMELEN(gv), FALSE)))
400 cv = GvCV(gv);
401 if (!CvLVALUE(cv))
402 DIE(aTHX_ "Can't modify non-lvalue subroutine call");
403 }
07055b4c
CS
404 }
405 else
3280af22 406 cv = (CV*)&PL_sv_undef;
79072805
LW
407 SETs((SV*)cv);
408 RETURN;
409}
410
c07a80fd 411PP(pp_prototype)
412{
39644a26 413 dSP;
c07a80fd 414 CV *cv;
415 HV *stash;
416 GV *gv;
417 SV *ret;
418
3280af22 419 ret = &PL_sv_undef;
b6c543e3
IZ
420 if (SvPOK(TOPs) && SvCUR(TOPs) >= 7) {
421 char *s = SvPVX(TOPs);
422 if (strnEQ(s, "CORE::", 6)) {
423 int code;
b13b2135 424
b6c543e3
IZ
425 code = keyword(s + 6, SvCUR(TOPs) - 6);
426 if (code < 0) { /* Overridable. */
427#define MAX_ARGS_OP ((sizeof(I32) - 1) * 2)
428 int i = 0, n = 0, seen_question = 0;
429 I32 oa;
430 char str[ MAX_ARGS_OP * 2 + 2 ]; /* One ';', one '\0' */
431
432 while (i < MAXO) { /* The slow way. */
22c35a8c
GS
433 if (strEQ(s + 6, PL_op_name[i])
434 || strEQ(s + 6, PL_op_desc[i]))
435 {
b6c543e3 436 goto found;
22c35a8c 437 }
b6c543e3
IZ
438 i++;
439 }
440 goto nonesuch; /* Should not happen... */
441 found:
22c35a8c 442 oa = PL_opargs[i] >> OASHIFT;
b6c543e3 443 while (oa) {
3012a639 444 if (oa & OA_OPTIONAL && !seen_question) {
b6c543e3
IZ
445 seen_question = 1;
446 str[n++] = ';';
ef54e1a4 447 }
b13b2135 448 else if (n && str[0] == ';' && seen_question)
b6c543e3 449 goto set; /* XXXX system, exec */
b13b2135 450 if ((oa & (OA_OPTIONAL - 1)) >= OA_AVREF
6e97e420
SC
451 && (oa & (OA_OPTIONAL - 1)) <= OA_SCALARREF
452 /* But globs are already references (kinda) */
453 && (oa & (OA_OPTIONAL - 1)) != OA_FILEREF
454 ) {
b6c543e3
IZ
455 str[n++] = '\\';
456 }
b6c543e3
IZ
457 str[n++] = ("?$@@%&*$")[oa & (OA_OPTIONAL - 1)];
458 oa = oa >> 4;
459 }
460 str[n++] = '\0';
79cb57f6 461 ret = sv_2mortal(newSVpvn(str, n - 1));
ef54e1a4
JH
462 }
463 else if (code) /* Non-Overridable */
b6c543e3
IZ
464 goto set;
465 else { /* None such */
466 nonesuch:
d470f89e 467 DIE(aTHX_ "Can't find an opnumber for \"%s\"", s+6);
b6c543e3
IZ
468 }
469 }
470 }
c07a80fd 471 cv = sv_2cv(TOPs, &stash, &gv, FALSE);
5f05dabc 472 if (cv && SvPOK(cv))
79cb57f6 473 ret = sv_2mortal(newSVpvn(SvPVX(cv), SvCUR(cv)));
b6c543e3 474 set:
c07a80fd 475 SETs(ret);
476 RETURN;
477}
478
a0d0e21e
LW
479PP(pp_anoncode)
480{
39644a26 481 dSP;
533c011a 482 CV* cv = (CV*)PL_curpad[PL_op->op_targ];
a5f75d66 483 if (CvCLONE(cv))
b355b4e0 484 cv = (CV*)sv_2mortal((SV*)cv_clone(cv));
5f05dabc 485 EXTEND(SP,1);
748a9306 486 PUSHs((SV*)cv);
a0d0e21e
LW
487 RETURN;
488}
489
490PP(pp_srefgen)
79072805 491{
39644a26 492 dSP;
71be2cbc 493 *SP = refto(*SP);
79072805 494 RETURN;
8ec5e241 495}
a0d0e21e
LW
496
497PP(pp_refgen)
498{
39644a26 499 dSP; dMARK;
a0d0e21e 500 if (GIMME != G_ARRAY) {
5f0b1d4e
GS
501 if (++MARK <= SP)
502 *MARK = *SP;
503 else
3280af22 504 *MARK = &PL_sv_undef;
5f0b1d4e
GS
505 *MARK = refto(*MARK);
506 SP = MARK;
507 RETURN;
a0d0e21e 508 }
bbce6d69 509 EXTEND_MORTAL(SP - MARK);
71be2cbc 510 while (++MARK <= SP)
511 *MARK = refto(*MARK);
a0d0e21e 512 RETURN;
79072805
LW
513}
514
76e3520e 515STATIC SV*
cea2e8a9 516S_refto(pTHX_ SV *sv)
71be2cbc 517{
518 SV* rv;
519
520 if (SvTYPE(sv) == SVt_PVLV && LvTYPE(sv) == 'y') {
521 if (LvTARGLEN(sv))
68dc0745 522 vivify_defelem(sv);
523 if (!(sv = LvTARG(sv)))
3280af22 524 sv = &PL_sv_undef;
0dd88869 525 else
a6c40364 526 (void)SvREFCNT_inc(sv);
71be2cbc 527 }
d8b46c1b
GS
528 else if (SvTYPE(sv) == SVt_PVAV) {
529 if (!AvREAL((AV*)sv) && AvREIFY((AV*)sv))
530 av_reify((AV*)sv);
531 SvTEMP_off(sv);
532 (void)SvREFCNT_inc(sv);
533 }
71be2cbc 534 else if (SvPADTMP(sv))
535 sv = newSVsv(sv);
536 else {
537 SvTEMP_off(sv);
538 (void)SvREFCNT_inc(sv);
539 }
540 rv = sv_newmortal();
541 sv_upgrade(rv, SVt_RV);
542 SvRV(rv) = sv;
543 SvROK_on(rv);
544 return rv;
545}
546
79072805
LW
547PP(pp_ref)
548{
39644a26 549 dSP; dTARGET;
463ee0b2 550 SV *sv;
79072805
LW
551 char *pv;
552
a0d0e21e 553 sv = POPs;
f12c7020 554
555 if (sv && SvGMAGICAL(sv))
8ec5e241 556 mg_get(sv);
f12c7020 557
a0d0e21e 558 if (!sv || !SvROK(sv))
4633a7c4 559 RETPUSHNO;
79072805 560
ed6116ce 561 sv = SvRV(sv);
a0d0e21e 562 pv = sv_reftype(sv,TRUE);
463ee0b2 563 PUSHp(pv, strlen(pv));
79072805
LW
564 RETURN;
565}
566
567PP(pp_bless)
568{
39644a26 569 dSP;
463ee0b2 570 HV *stash;
79072805 571
463ee0b2 572 if (MAXARG == 1)
11faa288 573 stash = CopSTASH(PL_curcop);
7b8d334a
GS
574 else {
575 SV *ssv = POPs;
576 STRLEN len;
81689caa
HS
577 char *ptr;
578
016a42f3 579 if (ssv && !SvGMAGICAL(ssv) && !SvAMAGIC(ssv) && SvROK(ssv))
81689caa
HS
580 Perl_croak(aTHX_ "Attempt to bless into a reference");
581 ptr = SvPV(ssv,len);
e476b1b5 582 if (ckWARN(WARN_MISC) && len == 0)
b13b2135 583 Perl_warner(aTHX_ WARN_MISC,
599cee73 584 "Explicit blessing to '' (assuming package main)");
7b8d334a
GS
585 stash = gv_stashpvn(ptr, len, TRUE);
586 }
a0d0e21e 587
5d3fdfeb 588 (void)sv_bless(TOPs, stash);
79072805
LW
589 RETURN;
590}
591
fb73857a 592PP(pp_gelem)
593{
594 GV *gv;
595 SV *sv;
76e3520e 596 SV *tmpRef;
fb73857a 597 char *elem;
39644a26 598 dSP;
2d8e6c8d 599 STRLEN n_a;
b13b2135 600
fb73857a 601 sv = POPs;
2d8e6c8d 602 elem = SvPV(sv, n_a);
fb73857a 603 gv = (GV*)POPs;
76e3520e 604 tmpRef = Nullsv;
fb73857a 605 sv = Nullsv;
606 switch (elem ? *elem : '\0')
607 {
608 case 'A':
609 if (strEQ(elem, "ARRAY"))
76e3520e 610 tmpRef = (SV*)GvAV(gv);
fb73857a 611 break;
612 case 'C':
613 if (strEQ(elem, "CODE"))
76e3520e 614 tmpRef = (SV*)GvCVu(gv);
fb73857a 615 break;
616 case 'F':
617 if (strEQ(elem, "FILEHANDLE")) /* XXX deprecate in 5.005 */
76e3520e 618 tmpRef = (SV*)GvIOp(gv);
f4d13ee9
JH
619 else
620 if (strEQ(elem, "FORMAT"))
621 tmpRef = (SV*)GvFORM(gv);
fb73857a 622 break;
623 case 'G':
624 if (strEQ(elem, "GLOB"))
76e3520e 625 tmpRef = (SV*)gv;
fb73857a 626 break;
627 case 'H':
628 if (strEQ(elem, "HASH"))
76e3520e 629 tmpRef = (SV*)GvHV(gv);
fb73857a 630 break;
631 case 'I':
632 if (strEQ(elem, "IO"))
76e3520e 633 tmpRef = (SV*)GvIOp(gv);
fb73857a 634 break;
635 case 'N':
636 if (strEQ(elem, "NAME"))
79cb57f6 637 sv = newSVpvn(GvNAME(gv), GvNAMELEN(gv));
fb73857a 638 break;
639 case 'P':
640 if (strEQ(elem, "PACKAGE"))
641 sv = newSVpv(HvNAME(GvSTASH(gv)), 0);
642 break;
643 case 'S':
644 if (strEQ(elem, "SCALAR"))
76e3520e 645 tmpRef = GvSV(gv);
fb73857a 646 break;
647 }
76e3520e
GS
648 if (tmpRef)
649 sv = newRV(tmpRef);
fb73857a 650 if (sv)
651 sv_2mortal(sv);
652 else
3280af22 653 sv = &PL_sv_undef;
fb73857a 654 XPUSHs(sv);
655 RETURN;
656}
657
a0d0e21e 658/* Pattern matching */
79072805 659
a0d0e21e 660PP(pp_study)
79072805 661{
39644a26 662 dSP; dPOPss;
a0d0e21e
LW
663 register unsigned char *s;
664 register I32 pos;
665 register I32 ch;
666 register I32 *sfirst;
667 register I32 *snext;
a0d0e21e
LW
668 STRLEN len;
669
3280af22 670 if (sv == PL_lastscream) {
1e422769 671 if (SvSCREAM(sv))
672 RETPUSHYES;
673 }
c07a80fd 674 else {
3280af22
NIS
675 if (PL_lastscream) {
676 SvSCREAM_off(PL_lastscream);
677 SvREFCNT_dec(PL_lastscream);
c07a80fd 678 }
3280af22 679 PL_lastscream = SvREFCNT_inc(sv);
c07a80fd 680 }
1e422769 681
682 s = (unsigned char*)(SvPV(sv, len));
683 pos = len;
684 if (pos <= 0)
685 RETPUSHNO;
3280af22
NIS
686 if (pos > PL_maxscream) {
687 if (PL_maxscream < 0) {
688 PL_maxscream = pos + 80;
689 New(301, PL_screamfirst, 256, I32);
690 New(302, PL_screamnext, PL_maxscream, I32);
79072805
LW
691 }
692 else {
3280af22
NIS
693 PL_maxscream = pos + pos / 4;
694 Renew(PL_screamnext, PL_maxscream, I32);
79072805 695 }
79072805 696 }
a0d0e21e 697
3280af22
NIS
698 sfirst = PL_screamfirst;
699 snext = PL_screamnext;
a0d0e21e
LW
700
701 if (!sfirst || !snext)
cea2e8a9 702 DIE(aTHX_ "do_study: out of memory");
a0d0e21e
LW
703
704 for (ch = 256; ch; --ch)
705 *sfirst++ = -1;
706 sfirst -= 256;
707
708 while (--pos >= 0) {
709 ch = s[pos];
710 if (sfirst[ch] >= 0)
711 snext[pos] = sfirst[ch] - pos;
712 else
713 snext[pos] = -pos;
714 sfirst[ch] = pos;
79072805
LW
715 }
716
c07a80fd 717 SvSCREAM_on(sv);
14befaf4
DM
718 /* piggyback on m//g magic */
719 sv_magic(sv, Nullsv, PERL_MAGIC_regex_global, Nullch, 0);
1e422769 720 RETPUSHYES;
79072805
LW
721}
722
a0d0e21e 723PP(pp_trans)
79072805 724{
39644a26 725 dSP; dTARG;
a0d0e21e
LW
726 SV *sv;
727
533c011a 728 if (PL_op->op_flags & OPf_STACKED)
a0d0e21e 729 sv = POPs;
79072805 730 else {
54b9620d 731 sv = DEFSV;
a0d0e21e 732 EXTEND(SP,1);
79072805 733 }
adbc6bb1 734 TARG = sv_newmortal();
4757a243 735 PUSHi(do_trans(sv));
a0d0e21e 736 RETURN;
79072805
LW
737}
738
a0d0e21e 739/* Lvalue operators. */
79072805 740
a0d0e21e
LW
741PP(pp_schop)
742{
39644a26 743 dSP; dTARGET;
a0d0e21e
LW
744 do_chop(TARG, TOPs);
745 SETTARG;
746 RETURN;
79072805
LW
747}
748
a0d0e21e 749PP(pp_chop)
79072805 750{
2ec6af5f
RG
751 dSP; dMARK; dTARGET; dORIGMARK;
752 while (MARK < SP)
753 do_chop(TARG, *++MARK);
754 SP = ORIGMARK;
a0d0e21e
LW
755 PUSHTARG;
756 RETURN;
79072805
LW
757}
758
a0d0e21e 759PP(pp_schomp)
79072805 760{
39644a26 761 dSP; dTARGET;
a0d0e21e
LW
762 SETi(do_chomp(TOPs));
763 RETURN;
79072805
LW
764}
765
a0d0e21e 766PP(pp_chomp)
79072805 767{
39644a26 768 dSP; dMARK; dTARGET;
a0d0e21e 769 register I32 count = 0;
8ec5e241 770
a0d0e21e
LW
771 while (SP > MARK)
772 count += do_chomp(POPs);
773 PUSHi(count);
774 RETURN;
79072805
LW
775}
776
a0d0e21e 777PP(pp_defined)
463ee0b2 778{
39644a26 779 dSP;
a0d0e21e
LW
780 register SV* sv;
781
782 sv = POPs;
783 if (!sv || !SvANY(sv))
784 RETPUSHNO;
785 switch (SvTYPE(sv)) {
786 case SVt_PVAV:
14befaf4
DM
787 if (AvMAX(sv) >= 0 || SvGMAGICAL(sv)
788 || (SvRMAGICAL(sv) && mg_find(sv, PERL_MAGIC_tied)))
a0d0e21e
LW
789 RETPUSHYES;
790 break;
791 case SVt_PVHV:
14befaf4
DM
792 if (HvARRAY(sv) || SvGMAGICAL(sv)
793 || (SvRMAGICAL(sv) && mg_find(sv, PERL_MAGIC_tied)))
a0d0e21e
LW
794 RETPUSHYES;
795 break;
796 case SVt_PVCV:
797 if (CvROOT(sv) || CvXSUB(sv))
798 RETPUSHYES;
799 break;
800 default:
801 if (SvGMAGICAL(sv))
802 mg_get(sv);
803 if (SvOK(sv))
804 RETPUSHYES;
805 }
806 RETPUSHNO;
463ee0b2
LW
807}
808
a0d0e21e
LW
809PP(pp_undef)
810{
39644a26 811 dSP;
a0d0e21e
LW
812 SV *sv;
813
533c011a 814 if (!PL_op->op_private) {
774d564b 815 EXTEND(SP, 1);
a0d0e21e 816 RETPUSHUNDEF;
774d564b 817 }
79072805 818
a0d0e21e
LW
819 sv = POPs;
820 if (!sv)
821 RETPUSHUNDEF;
85e6fe83 822
6fc92669
GS
823 if (SvTHINKFIRST(sv))
824 sv_force_normal(sv);
85e6fe83 825
a0d0e21e
LW
826 switch (SvTYPE(sv)) {
827 case SVt_NULL:
828 break;
829 case SVt_PVAV:
830 av_undef((AV*)sv);
831 break;
832 case SVt_PVHV:
833 hv_undef((HV*)sv);
834 break;
835 case SVt_PVCV:
e476b1b5
GS
836 if (ckWARN(WARN_MISC) && cv_const_sv((CV*)sv))
837 Perl_warner(aTHX_ WARN_MISC, "Constant subroutine %s undefined",
54310121 838 CvANON((CV*)sv) ? "(anonymous)" : GvENAME(CvGV((CV*)sv)));
9607fc9c 839 /* FALL THROUGH */
840 case SVt_PVFM:
6fc92669
GS
841 {
842 /* let user-undef'd sub keep its identity */
65c50114 843 GV* gv = CvGV((CV*)sv);
6fc92669
GS
844 cv_undef((CV*)sv);
845 CvGV((CV*)sv) = gv;
846 }
a0d0e21e 847 break;
8e07c86e 848 case SVt_PVGV:
44a8e56a 849 if (SvFAKE(sv))
3280af22 850 SvSetMagicSV(sv, &PL_sv_undef);
20408e3c
GS
851 else {
852 GP *gp;
853 gp_free((GV*)sv);
854 Newz(602, gp, 1, GP);
855 GvGP(sv) = gp_ref(gp);
856 GvSV(sv) = NEWSV(72,0);
57843af0 857 GvLINE(sv) = CopLINE(PL_curcop);
20408e3c
GS
858 GvEGV(sv) = (GV*)sv;
859 GvMULTI_on(sv);
860 }
44a8e56a 861 break;
a0d0e21e 862 default:
1e422769 863 if (SvTYPE(sv) >= SVt_PV && SvPVX(sv) && SvLEN(sv)) {
4633a7c4
LW
864 (void)SvOOK_off(sv);
865 Safefree(SvPVX(sv));
866 SvPV_set(sv, Nullch);
867 SvLEN_set(sv, 0);
a0d0e21e 868 }
4633a7c4
LW
869 (void)SvOK_off(sv);
870 SvSETMAGIC(sv);
79072805 871 }
a0d0e21e
LW
872
873 RETPUSHUNDEF;
79072805
LW
874}
875
a0d0e21e 876PP(pp_predec)
79072805 877{
39644a26 878 dSP;
68dc0745 879 if (SvREADONLY(TOPs) || SvTYPE(TOPs) > SVt_PVLV)
d470f89e 880 DIE(aTHX_ PL_no_modify);
25da4f38 881 if (SvIOK_notUV(TOPs) && !SvNOK(TOPs) && !SvPOK(TOPs) &&
55497cff 882 SvIVX(TOPs) != IV_MIN)
883 {
748a9306 884 --SvIVX(TOPs);
55497cff 885 SvFLAGS(TOPs) &= ~(SVp_NOK|SVp_POK);
748a9306
LW
886 }
887 else
888 sv_dec(TOPs);
a0d0e21e
LW
889 SvSETMAGIC(TOPs);
890 return NORMAL;
891}
79072805 892
a0d0e21e
LW
893PP(pp_postinc)
894{
39644a26 895 dSP; dTARGET;
68dc0745 896 if (SvREADONLY(TOPs) || SvTYPE(TOPs) > SVt_PVLV)
d470f89e 897 DIE(aTHX_ PL_no_modify);
a0d0e21e 898 sv_setsv(TARG, TOPs);
25da4f38 899 if (SvIOK_notUV(TOPs) && !SvNOK(TOPs) && !SvPOK(TOPs) &&
55497cff 900 SvIVX(TOPs) != IV_MAX)
901 {
748a9306 902 ++SvIVX(TOPs);
55497cff 903 SvFLAGS(TOPs) &= ~(SVp_NOK|SVp_POK);
748a9306
LW
904 }
905 else
906 sv_inc(TOPs);
a0d0e21e
LW
907 SvSETMAGIC(TOPs);
908 if (!SvOK(TARG))
909 sv_setiv(TARG, 0);
910 SETs(TARG);
911 return NORMAL;
912}
79072805 913
a0d0e21e
LW
914PP(pp_postdec)
915{
39644a26 916 dSP; dTARGET;
43192e07 917 if (SvREADONLY(TOPs) || SvTYPE(TOPs) > SVt_PVLV)
d470f89e 918 DIE(aTHX_ PL_no_modify);
a0d0e21e 919 sv_setsv(TARG, TOPs);
25da4f38 920 if (SvIOK_notUV(TOPs) && !SvNOK(TOPs) && !SvPOK(TOPs) &&
55497cff 921 SvIVX(TOPs) != IV_MIN)
922 {
748a9306 923 --SvIVX(TOPs);
55497cff 924 SvFLAGS(TOPs) &= ~(SVp_NOK|SVp_POK);
748a9306
LW
925 }
926 else
927 sv_dec(TOPs);
a0d0e21e
LW
928 SvSETMAGIC(TOPs);
929 SETs(TARG);
930 return NORMAL;
931}
79072805 932
a0d0e21e
LW
933/* Ordinary operators. */
934
935PP(pp_pow)
936{
39644a26 937 dSP; dATARGET; tryAMAGICbin(pow,opASSIGN);
a0d0e21e
LW
938 {
939 dPOPTOPnnrl;
73b309ea 940 SETn( Perl_pow( left, right) );
a0d0e21e 941 RETURN;
93a17b20 942 }
a0d0e21e
LW
943}
944
945PP(pp_multiply)
946{
39644a26 947 dSP; dATARGET; tryAMAGICbin(mult,opASSIGN);
28e5dec8
JH
948#ifdef PERL_PRESERVE_IVUV
949 SvIV_please(TOPs);
950 if (SvIOK(TOPs)) {
951 /* Unless the left argument is integer in range we are going to have to
952 use NV maths. Hence only attempt to coerce the right argument if
953 we know the left is integer. */
954 /* Left operand is defined, so is it IV? */
955 SvIV_please(TOPm1s);
956 if (SvIOK(TOPm1s)) {
957 bool auvok = SvUOK(TOPm1s);
958 bool buvok = SvUOK(TOPs);
959 const UV topmask = (~ (UV)0) << (4 * sizeof (UV));
960 const UV botmask = ~((~ (UV)0) << (4 * sizeof (UV)));
961 UV alow;
962 UV ahigh;
963 UV blow;
964 UV bhigh;
965
966 if (auvok) {
967 alow = SvUVX(TOPm1s);
968 } else {
969 IV aiv = SvIVX(TOPm1s);
970 if (aiv >= 0) {
971 alow = aiv;
972 auvok = TRUE; /* effectively it's a UV now */
973 } else {
974 alow = -aiv; /* abs, auvok == false records sign */
975 }
976 }
977 if (buvok) {
978 blow = SvUVX(TOPs);
979 } else {
980 IV biv = SvIVX(TOPs);
981 if (biv >= 0) {
982 blow = biv;
983 buvok = TRUE; /* effectively it's a UV now */
984 } else {
985 blow = -biv; /* abs, buvok == false records sign */
986 }
987 }
988
989 /* If this does sign extension on unsigned it's time for plan B */
990 ahigh = alow >> (4 * sizeof (UV));
991 alow &= botmask;
992 bhigh = blow >> (4 * sizeof (UV));
993 blow &= botmask;
994 if (ahigh && bhigh) {
995 /* eg 32 bit is at least 0x10000 * 0x10000 == 0x100000000
996 which is overflow. Drop to NVs below. */
997 } else if (!ahigh && !bhigh) {
998 /* eg 32 bit is at most 0xFFFF * 0xFFFF == 0xFFFE0001
999 so the unsigned multiply cannot overflow. */
1000 UV product = alow * blow;
1001 if (auvok == buvok) {
1002 /* -ve * -ve or +ve * +ve gives a +ve result. */
1003 SP--;
1004 SETu( product );
1005 RETURN;
1006 } else if (product <= (UV)IV_MIN) {
1007 /* 2s complement assumption that (UV)-IV_MIN is correct. */
1008 /* -ve result, which could overflow an IV */
1009 SP--;
1010 SETi( -product );
1011 RETURN;
1012 } /* else drop to NVs below. */
1013 } else {
1014 /* One operand is large, 1 small */
1015 UV product_middle;
1016 if (bhigh) {
1017 /* swap the operands */
1018 ahigh = bhigh;
1019 bhigh = blow; /* bhigh now the temp var for the swap */
1020 blow = alow;
1021 alow = bhigh;
1022 }
1023 /* now, ((ahigh * blow) << half_UV_len) + (alow * blow)
1024 multiplies can't overflow. shift can, add can, -ve can. */
1025 product_middle = ahigh * blow;
1026 if (!(product_middle & topmask)) {
1027 /* OK, (ahigh * blow) won't lose bits when we shift it. */
1028 UV product_low;
1029 product_middle <<= (4 * sizeof (UV));
1030 product_low = alow * blow;
1031
1032 /* as for pp_add, UV + something mustn't get smaller.
1033 IIRC ANSI mandates this wrapping *behaviour* for
1034 unsigned whatever the actual representation*/
1035 product_low += product_middle;
1036 if (product_low >= product_middle) {
1037 /* didn't overflow */
1038 if (auvok == buvok) {
1039 /* -ve * -ve or +ve * +ve gives a +ve result. */
1040 SP--;
1041 SETu( product_low );
1042 RETURN;
1043 } else if (product_low <= (UV)IV_MIN) {
1044 /* 2s complement assumption again */
1045 /* -ve result, which could overflow an IV */
1046 SP--;
1047 SETi( -product_low );
1048 RETURN;
1049 } /* else drop to NVs below. */
1050 }
1051 } /* product_middle too large */
1052 } /* ahigh && bhigh */
1053 } /* SvIOK(TOPm1s) */
1054 } /* SvIOK(TOPs) */
1055#endif
a0d0e21e
LW
1056 {
1057 dPOPTOPnnrl;
1058 SETn( left * right );
1059 RETURN;
79072805 1060 }
a0d0e21e
LW
1061}
1062
1063PP(pp_divide)
1064{
39644a26 1065 dSP; dATARGET; tryAMAGICbin(div,opASSIGN);
a0d0e21e 1066 {
77676ba1 1067 dPOPPOPnnrl;
65202027 1068 NV value;
7a4c00b4 1069 if (right == 0.0)
cea2e8a9 1070 DIE(aTHX_ "Illegal division by zero");
a0d0e21e
LW
1071#ifdef SLOPPYDIVIDE
1072 /* insure that 20./5. == 4. */
1073 {
7a4c00b4 1074 IV k;
65202027
DS
1075 if ((NV)I_V(left) == left &&
1076 (NV)I_V(right) == right &&
7a4c00b4 1077 (k = I_V(left)/I_V(right))*I_V(right) == I_V(left)) {
a0d0e21e 1078 value = k;
ef54e1a4
JH
1079 }
1080 else {
7a4c00b4 1081 value = left / right;
79072805 1082 }
a0d0e21e
LW
1083 }
1084#else
7a4c00b4 1085 value = left / right;
a0d0e21e
LW
1086#endif
1087 PUSHn( value );
1088 RETURN;
79072805 1089 }
a0d0e21e
LW
1090}
1091
1092PP(pp_modulo)
1093{
39644a26 1094 dSP; dATARGET; tryAMAGICbin(modulo,opASSIGN);
a0d0e21e 1095 {
9c5ffd7c
JH
1096 UV left = 0;
1097 UV right = 0;
787eafbd
IZ
1098 bool left_neg;
1099 bool right_neg;
1100 bool use_double = 0;
9c5ffd7c
JH
1101 NV dright = 0.0;
1102 NV dleft = 0.0;
787eafbd 1103
d658dc55 1104 if (SvIOK_notUV(TOPs) && !SvNOK(TOPs) && !SvPOK(TOPs)) {
787eafbd
IZ
1105 IV i = SvIVX(POPs);
1106 right = (right_neg = (i < 0)) ? -i : i;
1107 }
1108 else {
1109 dright = POPn;
1110 use_double = 1;
1111 right_neg = dright < 0;
1112 if (right_neg)
1113 dright = -dright;
1114 }
a0d0e21e 1115
d658dc55 1116 if (!use_double && SvIOK_notUV(TOPs) && !SvNOK(TOPs) && !SvPOK(TOPs)) {
787eafbd
IZ
1117 IV i = SvIVX(POPs);
1118 left = (left_neg = (i < 0)) ? -i : i;
1119 }
1120 else {
1121 dleft = POPn;
1122 if (!use_double) {
a1bd196e
GS
1123 use_double = 1;
1124 dright = right;
787eafbd
IZ
1125 }
1126 left_neg = dleft < 0;
1127 if (left_neg)
1128 dleft = -dleft;
1129 }
68dc0745 1130
787eafbd 1131 if (use_double) {
65202027 1132 NV dans;
787eafbd
IZ
1133
1134#if 1
787eafbd
IZ
1135/* Somehow U_V is pessimized even if CASTFLAGS is 0 */
1136# if CASTFLAGS & 2
1137# define CAST_D2UV(d) U_V(d)
1138# else
1139# define CAST_D2UV(d) ((UV)(d))
1140# endif
a1bd196e
GS
1141 /* Tried to do this only in the case DOUBLESIZE <= UV_SIZE,
1142 * or, in other words, precision of UV more than of NV.
1143 * But in fact the approach below turned out to be an
1144 * optimization - floor() may be slow */
787eafbd
IZ
1145 if (dright <= UV_MAX && dleft <= UV_MAX) {
1146 right = CAST_D2UV(dright);
1147 left = CAST_D2UV(dleft);
1148 goto do_uv;
1149 }
1150#endif
1151
1152 /* Backward-compatibility clause: */
73b309ea
JH
1153 dright = Perl_floor(dright + 0.5);
1154 dleft = Perl_floor(dleft + 0.5);
787eafbd
IZ
1155
1156 if (!dright)
cea2e8a9 1157 DIE(aTHX_ "Illegal modulus zero");
787eafbd 1158
65202027 1159 dans = Perl_fmod(dleft, dright);
787eafbd
IZ
1160 if ((left_neg != right_neg) && dans)
1161 dans = dright - dans;
1162 if (right_neg)
1163 dans = -dans;
1164 sv_setnv(TARG, dans);
1165 }
1166 else {
1167 UV ans;
1168
1169 do_uv:
1170 if (!right)
cea2e8a9 1171 DIE(aTHX_ "Illegal modulus zero");
787eafbd
IZ
1172
1173 ans = left % right;
1174 if ((left_neg != right_neg) && ans)
1175 ans = right - ans;
1176 if (right_neg) {
1177 /* XXX may warn: unary minus operator applied to unsigned type */
1178 /* could change -foo to be (~foo)+1 instead */
1179 if (ans <= ~((UV)IV_MAX)+1)
1180 sv_setiv(TARG, ~ans+1);
1181 else
65202027 1182 sv_setnv(TARG, -(NV)ans);
787eafbd
IZ
1183 }
1184 else
1185 sv_setuv(TARG, ans);
1186 }
1187 PUSHTARG;
1188 RETURN;
79072805 1189 }
a0d0e21e 1190}
79072805 1191
a0d0e21e
LW
1192PP(pp_repeat)
1193{
39644a26 1194 dSP; dATARGET; tryAMAGICbin(repeat,opASSIGN);
748a9306 1195 {
467f0320 1196 register IV count = POPi;
533c011a 1197 if (GIMME == G_ARRAY && PL_op->op_private & OPpREPEAT_DOLIST) {
a0d0e21e
LW
1198 dMARK;
1199 I32 items = SP - MARK;
1200 I32 max;
79072805 1201
a0d0e21e
LW
1202 max = items * count;
1203 MEXTEND(MARK, max);
1204 if (count > 1) {
1205 while (SP > MARK) {
1206 if (*SP)
1207 SvTEMP_off((*SP));
1208 SP--;
79072805 1209 }
a0d0e21e
LW
1210 MARK++;
1211 repeatcpy((char*)(MARK + items), (char*)MARK,
1212 items * sizeof(SV*), count - 1);
1213 SP += max;
79072805 1214 }
a0d0e21e
LW
1215 else if (count <= 0)
1216 SP -= items;
79072805 1217 }
a0d0e21e 1218 else { /* Note: mark already snarfed by pp_list */
dfcb284a 1219 SV *tmpstr = POPs;
a0d0e21e 1220 STRLEN len;
9b877dbb 1221 bool isutf;
a0d0e21e 1222
a0d0e21e
LW
1223 SvSetSV(TARG, tmpstr);
1224 SvPV_force(TARG, len);
9b877dbb 1225 isutf = DO_UTF8(TARG);
8ebc5c01 1226 if (count != 1) {
1227 if (count < 1)
1228 SvCUR_set(TARG, 0);
1229 else {
1230 SvGROW(TARG, (count * len) + 1);
a0d0e21e 1231 repeatcpy(SvPVX(TARG) + len, SvPVX(TARG), len, count - 1);
8ebc5c01 1232 SvCUR(TARG) *= count;
7a4c00b4 1233 }
a0d0e21e 1234 *SvEND(TARG) = '\0';
a0d0e21e 1235 }
dfcb284a
GS
1236 if (isutf)
1237 (void)SvPOK_only_UTF8(TARG);
1238 else
1239 (void)SvPOK_only(TARG);
b80b6069
RH
1240
1241 if (PL_op->op_private & OPpREPEAT_DOLIST) {
1242 /* The parser saw this as a list repeat, and there
1243 are probably several items on the stack. But we're
1244 in scalar context, and there's no pp_list to save us
1245 now. So drop the rest of the items -- robin@kitsite.com
1246 */
1247 dMARK;
1248 SP = MARK;
1249 }
a0d0e21e 1250 PUSHTARG;
79072805 1251 }
a0d0e21e 1252 RETURN;
748a9306 1253 }
a0d0e21e 1254}
79072805 1255
a0d0e21e
LW
1256PP(pp_subtract)
1257{
39644a26 1258 dSP; dATARGET; bool useleft; tryAMAGICbin(subtr,opASSIGN);
28e5dec8
JH
1259 useleft = USE_LEFT(TOPm1s);
1260#ifdef PERL_PRESERVE_IVUV
7dca457a
NC
1261 /* See comments in pp_add (in pp_hot.c) about Overflow, and how
1262 "bad things" happen if you rely on signed integers wrapping. */
28e5dec8
JH
1263 SvIV_please(TOPs);
1264 if (SvIOK(TOPs)) {
1265 /* Unless the left argument is integer in range we are going to have to
1266 use NV maths. Hence only attempt to coerce the right argument if
1267 we know the left is integer. */
9c5ffd7c
JH
1268 register UV auv = 0;
1269 bool auvok = FALSE;
7dca457a
NC
1270 bool a_valid = 0;
1271
28e5dec8 1272 if (!useleft) {
7dca457a
NC
1273 auv = 0;
1274 a_valid = auvok = 1;
1275 /* left operand is undef, treat as zero. */
28e5dec8
JH
1276 } else {
1277 /* Left operand is defined, so is it IV? */
1278 SvIV_please(TOPm1s);
1279 if (SvIOK(TOPm1s)) {
7dca457a
NC
1280 if ((auvok = SvUOK(TOPm1s)))
1281 auv = SvUVX(TOPm1s);
1282 else {
1283 register IV aiv = SvIVX(TOPm1s);
1284 if (aiv >= 0) {
1285 auv = aiv;
1286 auvok = 1; /* Now acting as a sign flag. */
1287 } else { /* 2s complement assumption for IV_MIN */
1288 auv = (UV)-aiv;
28e5dec8 1289 }
7dca457a
NC
1290 }
1291 a_valid = 1;
1292 }
1293 }
1294 if (a_valid) {
1295 bool result_good = 0;
1296 UV result;
1297 register UV buv;
1298 bool buvok = SvUOK(TOPs);
9041c2e3 1299
7dca457a
NC
1300 if (buvok)
1301 buv = SvUVX(TOPs);
1302 else {
1303 register IV biv = SvIVX(TOPs);
1304 if (biv >= 0) {
1305 buv = biv;
1306 buvok = 1;
1307 } else
1308 buv = (UV)-biv;
1309 }
1310 /* ?uvok if value is >= 0. basically, flagged as UV if it's +ve,
1311 else "IV" now, independant of how it came in.
1312 if a, b represents positive, A, B negative, a maps to -A etc
1313 a - b => (a - b)
1314 A - b => -(a + b)
1315 a - B => (a + b)
1316 A - B => -(a - b)
1317 all UV maths. negate result if A negative.
1318 subtract if signs same, add if signs differ. */
1319
1320 if (auvok ^ buvok) {
1321 /* Signs differ. */
1322 result = auv + buv;
1323 if (result >= auv)
1324 result_good = 1;
1325 } else {
1326 /* Signs same */
1327 if (auv >= buv) {
1328 result = auv - buv;
1329 /* Must get smaller */
1330 if (result <= auv)
1331 result_good = 1;
1332 } else {
1333 result = buv - auv;
1334 if (result <= buv) {
1335 /* result really should be -(auv-buv). as its negation
1336 of true value, need to swap our result flag */
1337 auvok = !auvok;
1338 result_good = 1;
28e5dec8 1339 }
28e5dec8
JH
1340 }
1341 }
7dca457a
NC
1342 if (result_good) {
1343 SP--;
1344 if (auvok)
1345 SETu( result );
1346 else {
1347 /* Negate result */
1348 if (result <= (UV)IV_MIN)
1349 SETi( -(IV)result );
1350 else {
1351 /* result valid, but out of range for IV. */
1352 SETn( -(NV)result );
1353 }
1354 }
1355 RETURN;
1356 } /* Overflow, drop through to NVs. */
28e5dec8
JH
1357 }
1358 }
1359#endif
7dca457a 1360 useleft = USE_LEFT(TOPm1s);
a0d0e21e 1361 {
28e5dec8
JH
1362 dPOPnv;
1363 if (!useleft) {
1364 /* left operand is undef, treat as zero - value */
1365 SETn(-value);
1366 RETURN;
1367 }
1368 SETn( TOPn - value );
1369 RETURN;
79072805 1370 }
a0d0e21e 1371}
79072805 1372
a0d0e21e
LW
1373PP(pp_left_shift)
1374{
39644a26 1375 dSP; dATARGET; tryAMAGICbin(lshift,opASSIGN);
a0d0e21e 1376 {
972b05a9 1377 IV shift = POPi;
d0ba1bd2 1378 if (PL_op->op_private & HINT_INTEGER) {
972b05a9
JH
1379 IV i = TOPi;
1380 SETi(i << shift);
d0ba1bd2
JH
1381 }
1382 else {
972b05a9
JH
1383 UV u = TOPu;
1384 SETu(u << shift);
d0ba1bd2 1385 }
55497cff 1386 RETURN;
79072805 1387 }
a0d0e21e 1388}
79072805 1389
a0d0e21e
LW
1390PP(pp_right_shift)
1391{
39644a26 1392 dSP; dATARGET; tryAMAGICbin(rshift,opASSIGN);
a0d0e21e 1393 {
972b05a9 1394 IV shift = POPi;
d0ba1bd2 1395 if (PL_op->op_private & HINT_INTEGER) {
972b05a9
JH
1396 IV i = TOPi;
1397 SETi(i >> shift);
d0ba1bd2
JH
1398 }
1399 else {
972b05a9
JH
1400 UV u = TOPu;
1401 SETu(u >> shift);
d0ba1bd2 1402 }
a0d0e21e 1403 RETURN;
93a17b20 1404 }
79072805
LW
1405}
1406
a0d0e21e 1407PP(pp_lt)
79072805 1408{
39644a26 1409 dSP; tryAMAGICbinSET(lt,0);
28e5dec8
JH
1410#ifdef PERL_PRESERVE_IVUV
1411 SvIV_please(TOPs);
1412 if (SvIOK(TOPs)) {
1413 SvIV_please(TOPm1s);
1414 if (SvIOK(TOPm1s)) {
1415 bool auvok = SvUOK(TOPm1s);
1416 bool buvok = SvUOK(TOPs);
a227d84d 1417
28e5dec8
JH
1418 if (!auvok && !buvok) { /* ## IV < IV ## */
1419 IV aiv = SvIVX(TOPm1s);
1420 IV biv = SvIVX(TOPs);
1421
1422 SP--;
1423 SETs(boolSV(aiv < biv));
1424 RETURN;
1425 }
1426 if (auvok && buvok) { /* ## UV < UV ## */
1427 UV auv = SvUVX(TOPm1s);
1428 UV buv = SvUVX(TOPs);
1429
1430 SP--;
1431 SETs(boolSV(auv < buv));
1432 RETURN;
1433 }
1434 if (auvok) { /* ## UV < IV ## */
1435 UV auv;
1436 IV biv;
1437
1438 biv = SvIVX(TOPs);
1439 SP--;
1440 if (biv < 0) {
1441 /* As (a) is a UV, it's >=0, so it cannot be < */
1442 SETs(&PL_sv_no);
1443 RETURN;
1444 }
1445 auv = SvUVX(TOPs);
1446 if (auv >= (UV) IV_MAX) {
1447 /* As (b) is an IV, it cannot be > IV_MAX */
1448 SETs(&PL_sv_no);
1449 RETURN;
1450 }
1451 SETs(boolSV(auv < (UV)biv));
1452 RETURN;
1453 }
1454 { /* ## IV < UV ## */
1455 IV aiv;
1456 UV buv;
1457
1458 aiv = SvIVX(TOPm1s);
1459 if (aiv < 0) {
1460 /* As (b) is a UV, it's >=0, so it must be < */
1461 SP--;
1462 SETs(&PL_sv_yes);
1463 RETURN;
1464 }
1465 buv = SvUVX(TOPs);
1466 SP--;
1467 if (buv > (UV) IV_MAX) {
1468 /* As (a) is an IV, it cannot be > IV_MAX */
1469 SETs(&PL_sv_yes);
1470 RETURN;
1471 }
1472 SETs(boolSV((UV)aiv < buv));
1473 RETURN;
1474 }
1475 }
1476 }
1477#endif
a0d0e21e
LW
1478 {
1479 dPOPnv;
54310121 1480 SETs(boolSV(TOPn < value));
a0d0e21e 1481 RETURN;
79072805 1482 }
a0d0e21e 1483}
79072805 1484
a0d0e21e
LW
1485PP(pp_gt)
1486{
39644a26 1487 dSP; tryAMAGICbinSET(gt,0);
28e5dec8
JH
1488#ifdef PERL_PRESERVE_IVUV
1489 SvIV_please(TOPs);
1490 if (SvIOK(TOPs)) {
1491 SvIV_please(TOPm1s);
1492 if (SvIOK(TOPm1s)) {
1493 bool auvok = SvUOK(TOPm1s);
1494 bool buvok = SvUOK(TOPs);
a227d84d 1495
28e5dec8
JH
1496 if (!auvok && !buvok) { /* ## IV > IV ## */
1497 IV aiv = SvIVX(TOPm1s);
1498 IV biv = SvIVX(TOPs);
1499
1500 SP--;
1501 SETs(boolSV(aiv > biv));
1502 RETURN;
1503 }
1504 if (auvok && buvok) { /* ## UV > UV ## */
1505 UV auv = SvUVX(TOPm1s);
1506 UV buv = SvUVX(TOPs);
1507
1508 SP--;
1509 SETs(boolSV(auv > buv));
1510 RETURN;
1511 }
1512 if (auvok) { /* ## UV > IV ## */
1513 UV auv;
1514 IV biv;
1515
1516 biv = SvIVX(TOPs);
1517 SP--;
1518 if (biv < 0) {
1519 /* As (a) is a UV, it's >=0, so it must be > */
1520 SETs(&PL_sv_yes);
1521 RETURN;
1522 }
1523 auv = SvUVX(TOPs);
1524 if (auv > (UV) IV_MAX) {
1525 /* As (b) is an IV, it cannot be > IV_MAX */
1526 SETs(&PL_sv_yes);
1527 RETURN;
1528 }
1529 SETs(boolSV(auv > (UV)biv));
1530 RETURN;
1531 }
1532 { /* ## IV > UV ## */
1533 IV aiv;
1534 UV buv;
1535
1536 aiv = SvIVX(TOPm1s);
1537 if (aiv < 0) {
1538 /* As (b) is a UV, it's >=0, so it cannot be > */
1539 SP--;
1540 SETs(&PL_sv_no);
1541 RETURN;
1542 }
1543 buv = SvUVX(TOPs);
1544 SP--;
1545 if (buv >= (UV) IV_MAX) {
1546 /* As (a) is an IV, it cannot be > IV_MAX */
1547 SETs(&PL_sv_no);
1548 RETURN;
1549 }
1550 SETs(boolSV((UV)aiv > buv));
1551 RETURN;
1552 }
1553 }
1554 }
1555#endif
a0d0e21e
LW
1556 {
1557 dPOPnv;
54310121 1558 SETs(boolSV(TOPn > value));
a0d0e21e 1559 RETURN;
79072805 1560 }
a0d0e21e
LW
1561}
1562
1563PP(pp_le)
1564{
39644a26 1565 dSP; tryAMAGICbinSET(le,0);
28e5dec8
JH
1566#ifdef PERL_PRESERVE_IVUV
1567 SvIV_please(TOPs);
1568 if (SvIOK(TOPs)) {
1569 SvIV_please(TOPm1s);
1570 if (SvIOK(TOPm1s)) {
1571 bool auvok = SvUOK(TOPm1s);
1572 bool buvok = SvUOK(TOPs);
a227d84d 1573
28e5dec8
JH
1574 if (!auvok && !buvok) { /* ## IV <= IV ## */
1575 IV aiv = SvIVX(TOPm1s);
1576 IV biv = SvIVX(TOPs);
1577
1578 SP--;
1579 SETs(boolSV(aiv <= biv));
1580 RETURN;
1581 }
1582 if (auvok && buvok) { /* ## UV <= UV ## */
1583 UV auv = SvUVX(TOPm1s);
1584 UV buv = SvUVX(TOPs);
1585
1586 SP--;
1587 SETs(boolSV(auv <= buv));
1588 RETURN;
1589 }
1590 if (auvok) { /* ## UV <= IV ## */
1591 UV auv;
1592 IV biv;
1593
1594 biv = SvIVX(TOPs);
1595 SP--;
1596 if (biv < 0) {
1597 /* As (a) is a UV, it's >=0, so a cannot be <= */
1598 SETs(&PL_sv_no);
1599 RETURN;
1600 }
1601 auv = SvUVX(TOPs);
1602 if (auv > (UV) IV_MAX) {
1603 /* As (b) is an IV, it cannot be > IV_MAX */
1604 SETs(&PL_sv_no);
1605 RETURN;
1606 }
1607 SETs(boolSV(auv <= (UV)biv));
1608 RETURN;
1609 }
1610 { /* ## IV <= UV ## */
1611 IV aiv;
1612 UV buv;
1613
1614 aiv = SvIVX(TOPm1s);
1615 if (aiv < 0) {
1616 /* As (b) is a UV, it's >=0, so a must be <= */
1617 SP--;
1618 SETs(&PL_sv_yes);
1619 RETURN;
1620 }
1621 buv = SvUVX(TOPs);
1622 SP--;
1623 if (buv >= (UV) IV_MAX) {
1624 /* As (a) is an IV, it cannot be > IV_MAX */
1625 SETs(&PL_sv_yes);
1626 RETURN;
1627 }
1628 SETs(boolSV((UV)aiv <= buv));
1629 RETURN;
1630 }
1631 }
1632 }
1633#endif
a0d0e21e
LW
1634 {
1635 dPOPnv;
54310121 1636 SETs(boolSV(TOPn <= value));
a0d0e21e 1637 RETURN;
79072805 1638 }
a0d0e21e
LW
1639}
1640
1641PP(pp_ge)
1642{
39644a26 1643 dSP; tryAMAGICbinSET(ge,0);
28e5dec8
JH
1644#ifdef PERL_PRESERVE_IVUV
1645 SvIV_please(TOPs);
1646 if (SvIOK(TOPs)) {
1647 SvIV_please(TOPm1s);
1648 if (SvIOK(TOPm1s)) {
1649 bool auvok = SvUOK(TOPm1s);
1650 bool buvok = SvUOK(TOPs);
a227d84d 1651
28e5dec8
JH
1652 if (!auvok && !buvok) { /* ## IV >= IV ## */
1653 IV aiv = SvIVX(TOPm1s);
1654 IV biv = SvIVX(TOPs);
1655
1656 SP--;
1657 SETs(boolSV(aiv >= biv));
1658 RETURN;
1659 }
1660 if (auvok && buvok) { /* ## UV >= UV ## */
1661 UV auv = SvUVX(TOPm1s);
1662 UV buv = SvUVX(TOPs);
1663
1664 SP--;
1665 SETs(boolSV(auv >= buv));
1666 RETURN;
1667 }
1668 if (auvok) { /* ## UV >= IV ## */
1669 UV auv;
1670 IV biv;
1671
1672 biv = SvIVX(TOPs);
1673 SP--;
1674 if (biv < 0) {
1675 /* As (a) is a UV, it's >=0, so it must be >= */
1676 SETs(&PL_sv_yes);
1677 RETURN;
1678 }
1679 auv = SvUVX(TOPs);
1680 if (auv >= (UV) IV_MAX) {
1681 /* As (b) is an IV, it cannot be > IV_MAX */
1682 SETs(&PL_sv_yes);
1683 RETURN;
1684 }
1685 SETs(boolSV(auv >= (UV)biv));
1686 RETURN;
1687 }
1688 { /* ## IV >= UV ## */
1689 IV aiv;
1690 UV buv;
1691
1692 aiv = SvIVX(TOPm1s);
1693 if (aiv < 0) {
1694 /* As (b) is a UV, it's >=0, so a cannot be >= */
1695 SP--;
1696 SETs(&PL_sv_no);
1697 RETURN;
1698 }
1699 buv = SvUVX(TOPs);
1700 SP--;
1701 if (buv > (UV) IV_MAX) {
1702 /* As (a) is an IV, it cannot be > IV_MAX */
1703 SETs(&PL_sv_no);
1704 RETURN;
1705 }
1706 SETs(boolSV((UV)aiv >= buv));
1707 RETURN;
1708 }
1709 }
1710 }
1711#endif
a0d0e21e
LW
1712 {
1713 dPOPnv;
54310121 1714 SETs(boolSV(TOPn >= value));
a0d0e21e 1715 RETURN;
79072805 1716 }
a0d0e21e 1717}
79072805 1718
a0d0e21e
LW
1719PP(pp_ne)
1720{
16303949 1721 dSP; tryAMAGICbinSET(ne,0);
3bb2c415
JH
1722#ifndef NV_PRESERVES_UV
1723 if (SvROK(TOPs) && SvROK(TOPm1s)) {
c3e03cdf 1724 SETs(boolSV(SvRV(TOPs) != SvRV(TOPm1s)));
3bb2c415
JH
1725 RETURN;
1726 }
1727#endif
28e5dec8
JH
1728#ifdef PERL_PRESERVE_IVUV
1729 SvIV_please(TOPs);
1730 if (SvIOK(TOPs)) {
1731 SvIV_please(TOPm1s);
1732 if (SvIOK(TOPm1s)) {
1733 bool auvok = SvUOK(TOPm1s);
1734 bool buvok = SvUOK(TOPs);
a227d84d 1735
28e5dec8
JH
1736 if (!auvok && !buvok) { /* ## IV <=> IV ## */
1737 IV aiv = SvIVX(TOPm1s);
1738 IV biv = SvIVX(TOPs);
1739
1740 SP--;
1741 SETs(boolSV(aiv != biv));
1742 RETURN;
1743 }
1744 if (auvok && buvok) { /* ## UV != UV ## */
1745 UV auv = SvUVX(TOPm1s);
1746 UV buv = SvUVX(TOPs);
1747
1748 SP--;
1749 SETs(boolSV(auv != buv));
1750 RETURN;
1751 }
1752 { /* ## Mixed IV,UV ## */
1753 IV iv;
1754 UV uv;
1755
1756 /* != is commutative so swap if needed (save code) */
1757 if (auvok) {
1758 /* swap. top of stack (b) is the iv */
1759 iv = SvIVX(TOPs);
1760 SP--;
1761 if (iv < 0) {
1762 /* As (a) is a UV, it's >0, so it cannot be == */
1763 SETs(&PL_sv_yes);
1764 RETURN;
1765 }
1766 uv = SvUVX(TOPs);
1767 } else {
1768 iv = SvIVX(TOPm1s);
1769 SP--;
1770 if (iv < 0) {
1771 /* As (b) is a UV, it's >0, so it cannot be == */
1772 SETs(&PL_sv_yes);
1773 RETURN;
1774 }
1775 uv = SvUVX(*(SP+1)); /* Do I want TOPp1s() ? */
1776 }
1777 /* we know iv is >= 0 */
1778 if (uv > (UV) IV_MAX) {
1779 SETs(&PL_sv_yes);
1780 RETURN;
1781 }
1782 SETs(boolSV((UV)iv != uv));
1783 RETURN;
1784 }
1785 }
1786 }
1787#endif
a0d0e21e
LW
1788 {
1789 dPOPnv;
54310121 1790 SETs(boolSV(TOPn != value));
a0d0e21e
LW
1791 RETURN;
1792 }
79072805
LW
1793}
1794
a0d0e21e 1795PP(pp_ncmp)
79072805 1796{
39644a26 1797 dSP; dTARGET; tryAMAGICbin(ncmp,0);
d8c7644e
JH
1798#ifndef NV_PRESERVES_UV
1799 if (SvROK(TOPs) && SvROK(TOPm1s)) {
34d3ce40 1800 SETi(PTR2UV(SvRV(TOPs)) - PTR2UV(SvRV(TOPm1s)));
d8c7644e
JH
1801 RETURN;
1802 }
1803#endif
28e5dec8
JH
1804#ifdef PERL_PRESERVE_IVUV
1805 /* Fortunately it seems NaN isn't IOK */
1806 SvIV_please(TOPs);
1807 if (SvIOK(TOPs)) {
1808 SvIV_please(TOPm1s);
1809 if (SvIOK(TOPm1s)) {
1810 bool leftuvok = SvUOK(TOPm1s);
1811 bool rightuvok = SvUOK(TOPs);
1812 I32 value;
1813 if (!leftuvok && !rightuvok) { /* ## IV <=> IV ## */
1814 IV leftiv = SvIVX(TOPm1s);
1815 IV rightiv = SvIVX(TOPs);
1816
1817 if (leftiv > rightiv)
1818 value = 1;
1819 else if (leftiv < rightiv)
1820 value = -1;
1821 else
1822 value = 0;
1823 } else if (leftuvok && rightuvok) { /* ## UV <=> UV ## */
1824 UV leftuv = SvUVX(TOPm1s);
1825 UV rightuv = SvUVX(TOPs);
1826
1827 if (leftuv > rightuv)
1828 value = 1;
1829 else if (leftuv < rightuv)
1830 value = -1;
1831 else
1832 value = 0;
1833 } else if (leftuvok) { /* ## UV <=> IV ## */
1834 UV leftuv;
1835 IV rightiv;
1836
1837 rightiv = SvIVX(TOPs);
1838 if (rightiv < 0) {
1839 /* As (a) is a UV, it's >=0, so it cannot be < */
1840 value = 1;
1841 } else {
1842 leftuv = SvUVX(TOPm1s);
1843 if (leftuv > (UV) IV_MAX) {
1844 /* As (b) is an IV, it cannot be > IV_MAX */
1845 value = 1;
1846 } else if (leftuv > (UV)rightiv) {
1847 value = 1;
1848 } else if (leftuv < (UV)rightiv) {
1849 value = -1;
1850 } else {
1851 value = 0;
1852 }
1853 }
1854 } else { /* ## IV <=> UV ## */
1855 IV leftiv;
1856 UV rightuv;
1857
1858 leftiv = SvIVX(TOPm1s);
1859 if (leftiv < 0) {
1860 /* As (b) is a UV, it's >=0, so it must be < */
1861 value = -1;
1862 } else {
1863 rightuv = SvUVX(TOPs);
1864 if (rightuv > (UV) IV_MAX) {
1865 /* As (a) is an IV, it cannot be > IV_MAX */
1866 value = -1;
1867 } else if (leftiv > (UV)rightuv) {
1868 value = 1;
1869 } else if (leftiv < (UV)rightuv) {
1870 value = -1;
1871 } else {
1872 value = 0;
1873 }
1874 }
1875 }
1876 SP--;
1877 SETi(value);
1878 RETURN;
1879 }
1880 }
1881#endif
a0d0e21e
LW
1882 {
1883 dPOPTOPnnrl;
1884 I32 value;
79072805 1885
a3540c92 1886#ifdef Perl_isnan
1ad04cfd
JH
1887 if (Perl_isnan(left) || Perl_isnan(right)) {
1888 SETs(&PL_sv_undef);
1889 RETURN;
1890 }
1891 value = (left > right) - (left < right);
1892#else
ff0cee69 1893 if (left == right)
a0d0e21e 1894 value = 0;
a0d0e21e
LW
1895 else if (left < right)
1896 value = -1;
44a8e56a 1897 else if (left > right)
1898 value = 1;
1899 else {
3280af22 1900 SETs(&PL_sv_undef);
44a8e56a 1901 RETURN;
1902 }
1ad04cfd 1903#endif
a0d0e21e
LW
1904 SETi(value);
1905 RETURN;
79072805 1906 }
a0d0e21e 1907}
79072805 1908
a0d0e21e
LW
1909PP(pp_slt)
1910{
39644a26 1911 dSP; tryAMAGICbinSET(slt,0);
a0d0e21e
LW
1912 {
1913 dPOPTOPssrl;
2de3dbcc 1914 int cmp = (IN_LOCALE_RUNTIME
bbce6d69 1915 ? sv_cmp_locale(left, right)
1916 : sv_cmp(left, right));
54310121 1917 SETs(boolSV(cmp < 0));
a0d0e21e
LW
1918 RETURN;
1919 }
79072805
LW
1920}
1921
a0d0e21e 1922PP(pp_sgt)
79072805 1923{
39644a26 1924 dSP; tryAMAGICbinSET(sgt,0);
a0d0e21e
LW
1925 {
1926 dPOPTOPssrl;
2de3dbcc 1927 int cmp = (IN_LOCALE_RUNTIME
bbce6d69 1928 ? sv_cmp_locale(left, right)
1929 : sv_cmp(left, right));
54310121 1930 SETs(boolSV(cmp > 0));
a0d0e21e
LW
1931 RETURN;
1932 }
1933}
79072805 1934
a0d0e21e
LW
1935PP(pp_sle)
1936{
39644a26 1937 dSP; tryAMAGICbinSET(sle,0);
a0d0e21e
LW
1938 {
1939 dPOPTOPssrl;
2de3dbcc 1940 int cmp = (IN_LOCALE_RUNTIME
bbce6d69 1941 ? sv_cmp_locale(left, right)
1942 : sv_cmp(left, right));
54310121 1943 SETs(boolSV(cmp <= 0));
a0d0e21e 1944 RETURN;
79072805 1945 }
79072805
LW
1946}
1947
a0d0e21e
LW
1948PP(pp_sge)
1949{
39644a26 1950 dSP; tryAMAGICbinSET(sge,0);
a0d0e21e
LW
1951 {
1952 dPOPTOPssrl;
2de3dbcc 1953 int cmp = (IN_LOCALE_RUNTIME
bbce6d69 1954 ? sv_cmp_locale(left, right)
1955 : sv_cmp(left, right));
54310121 1956 SETs(boolSV(cmp >= 0));
a0d0e21e
LW
1957 RETURN;
1958 }
1959}
79072805 1960
36477c24 1961PP(pp_seq)
1962{
39644a26 1963 dSP; tryAMAGICbinSET(seq,0);
36477c24 1964 {
1965 dPOPTOPssrl;
54310121 1966 SETs(boolSV(sv_eq(left, right)));
a0d0e21e
LW
1967 RETURN;
1968 }
1969}
79072805 1970
a0d0e21e 1971PP(pp_sne)
79072805 1972{
39644a26 1973 dSP; tryAMAGICbinSET(sne,0);
a0d0e21e
LW
1974 {
1975 dPOPTOPssrl;
54310121 1976 SETs(boolSV(!sv_eq(left, right)));
a0d0e21e 1977 RETURN;
463ee0b2 1978 }
79072805
LW
1979}
1980
a0d0e21e 1981PP(pp_scmp)
79072805 1982{
39644a26 1983 dSP; dTARGET; tryAMAGICbin(scmp,0);
a0d0e21e
LW
1984 {
1985 dPOPTOPssrl;
2de3dbcc 1986 int cmp = (IN_LOCALE_RUNTIME
bbce6d69 1987 ? sv_cmp_locale(left, right)
1988 : sv_cmp(left, right));
1989 SETi( cmp );
a0d0e21e
LW
1990 RETURN;
1991 }
1992}
79072805 1993
55497cff 1994PP(pp_bit_and)
1995{
39644a26 1996 dSP; dATARGET; tryAMAGICbin(band,opASSIGN);
a0d0e21e
LW
1997 {
1998 dPOPTOPssrl;
4633a7c4 1999 if (SvNIOKp(left) || SvNIOKp(right)) {
d0ba1bd2 2000 if (PL_op->op_private & HINT_INTEGER) {
972b05a9
JH
2001 IV i = SvIV(left) & SvIV(right);
2002 SETi(i);
d0ba1bd2
JH
2003 }
2004 else {
972b05a9
JH
2005 UV u = SvUV(left) & SvUV(right);
2006 SETu(u);
d0ba1bd2 2007 }
a0d0e21e
LW
2008 }
2009 else {
533c011a 2010 do_vop(PL_op->op_type, TARG, left, right);
a0d0e21e
LW
2011 SETTARG;
2012 }
2013 RETURN;
2014 }
2015}
79072805 2016
a0d0e21e
LW
2017PP(pp_bit_xor)
2018{
39644a26 2019 dSP; dATARGET; tryAMAGICbin(bxor,opASSIGN);
a0d0e21e
LW
2020 {
2021 dPOPTOPssrl;
4633a7c4 2022 if (SvNIOKp(left) || SvNIOKp(right)) {
d0ba1bd2 2023 if (PL_op->op_private & HINT_INTEGER) {
972b05a9
JH
2024 IV i = (USE_LEFT(left) ? SvIV(left) : 0) ^ SvIV(right);
2025 SETi(i);
d0ba1bd2
JH
2026 }
2027 else {
972b05a9
JH
2028 UV u = (USE_LEFT(left) ? SvUV(left) : 0) ^ SvUV(right);
2029 SETu(u);
d0ba1bd2 2030 }
a0d0e21e
LW
2031 }
2032 else {
533c011a 2033 do_vop(PL_op->op_type, TARG, left, right);
a0d0e21e
LW
2034 SETTARG;
2035 }
2036 RETURN;
2037 }
2038}
79072805 2039
a0d0e21e
LW
2040PP(pp_bit_or)
2041{
39644a26 2042 dSP; dATARGET; tryAMAGICbin(bor,opASSIGN);
a0d0e21e
LW
2043 {
2044 dPOPTOPssrl;
4633a7c4 2045 if (SvNIOKp(left) || SvNIOKp(right)) {
d0ba1bd2 2046 if (PL_op->op_private & HINT_INTEGER) {
972b05a9
JH
2047 IV i = (USE_LEFT(left) ? SvIV(left) : 0) | SvIV(right);
2048 SETi(i);
d0ba1bd2
JH
2049 }
2050 else {
972b05a9
JH
2051 UV u = (USE_LEFT(left) ? SvUV(left) : 0) | SvUV(right);
2052 SETu(u);
d0ba1bd2 2053 }
a0d0e21e
LW
2054 }
2055 else {
533c011a 2056 do_vop(PL_op->op_type, TARG, left, right);
a0d0e21e
LW
2057 SETTARG;
2058 }
2059 RETURN;
79072805 2060 }
a0d0e21e 2061}
79072805 2062
a0d0e21e
LW
2063PP(pp_negate)
2064{
39644a26 2065 dSP; dTARGET; tryAMAGICun(neg);
a0d0e21e
LW
2066 {
2067 dTOPss;
28e5dec8 2068 int flags = SvFLAGS(sv);
4633a7c4
LW
2069 if (SvGMAGICAL(sv))
2070 mg_get(sv);
28e5dec8
JH
2071 if ((flags & SVf_IOK) || ((flags & (SVp_IOK | SVp_NOK)) == SVp_IOK)) {
2072 /* It's publicly an integer, or privately an integer-not-float */
2073 oops_its_an_int:
9b0e499b
GS
2074 if (SvIsUV(sv)) {
2075 if (SvIVX(sv) == IV_MIN) {
28e5dec8 2076 /* 2s complement assumption. */
9b0e499b
GS
2077 SETi(SvIVX(sv)); /* special case: -((UV)IV_MAX+1) == IV_MIN */
2078 RETURN;
2079 }
2080 else if (SvUVX(sv) <= IV_MAX) {
beccb14c 2081 SETi(-SvIVX(sv));
9b0e499b
GS
2082 RETURN;
2083 }
2084 }
2085 else if (SvIVX(sv) != IV_MIN) {
2086 SETi(-SvIVX(sv));
2087 RETURN;
2088 }
28e5dec8
JH
2089#ifdef PERL_PRESERVE_IVUV
2090 else {
2091 SETu((UV)IV_MIN);
2092 RETURN;
2093 }
2094#endif
9b0e499b
GS
2095 }
2096 if (SvNIOKp(sv))
a0d0e21e 2097 SETn(-SvNV(sv));
4633a7c4 2098 else if (SvPOKp(sv)) {
a0d0e21e
LW
2099 STRLEN len;
2100 char *s = SvPV(sv, len);
bbce6d69 2101 if (isIDFIRST(*s)) {
a0d0e21e
LW
2102 sv_setpvn(TARG, "-", 1);
2103 sv_catsv(TARG, sv);
79072805 2104 }
a0d0e21e
LW
2105 else if (*s == '+' || *s == '-') {
2106 sv_setsv(TARG, sv);
2107 *SvPV_force(TARG, len) = *s == '-' ? '+' : '-';
79072805 2108 }
fd400ab9 2109 else if (DO_UTF8(sv) && UTF8_IS_START(*s) && isIDFIRST_utf8((U8*)s)) {
834a4ddd
LW
2110 sv_setpvn(TARG, "-", 1);
2111 sv_catsv(TARG, sv);
2112 }
28e5dec8
JH
2113 else {
2114 SvIV_please(sv);
2115 if (SvIOK(sv))
2116 goto oops_its_an_int;
2117 sv_setnv(TARG, -SvNV(sv));
2118 }
a0d0e21e 2119 SETTARG;
79072805 2120 }
4633a7c4
LW
2121 else
2122 SETn(-SvNV(sv));
79072805 2123 }
a0d0e21e 2124 RETURN;
79072805
LW
2125}
2126
a0d0e21e 2127PP(pp_not)
79072805 2128{
39644a26 2129 dSP; tryAMAGICunSET(not);
3280af22 2130 *PL_stack_sp = boolSV(!SvTRUE(*PL_stack_sp));
a0d0e21e 2131 return NORMAL;
79072805
LW
2132}
2133
a0d0e21e 2134PP(pp_complement)
79072805 2135{
39644a26 2136 dSP; dTARGET; tryAMAGICun(compl);
a0d0e21e
LW
2137 {
2138 dTOPss;
4633a7c4 2139 if (SvNIOKp(sv)) {
d0ba1bd2 2140 if (PL_op->op_private & HINT_INTEGER) {
972b05a9
JH
2141 IV i = ~SvIV(sv);
2142 SETi(i);
d0ba1bd2
JH
2143 }
2144 else {
972b05a9
JH
2145 UV u = ~SvUV(sv);
2146 SETu(u);
d0ba1bd2 2147 }
a0d0e21e
LW
2148 }
2149 else {
51723571 2150 register U8 *tmps;
55497cff 2151 register I32 anum;
a0d0e21e
LW
2152 STRLEN len;
2153
2154 SvSetSV(TARG, sv);
51723571 2155 tmps = (U8*)SvPV_force(TARG, len);
a0d0e21e 2156 anum = len;
1d68d6cd 2157 if (SvUTF8(TARG)) {
a1ca4561 2158 /* Calculate exact length, let's not estimate. */
1d68d6cd
SC
2159 STRLEN targlen = 0;
2160 U8 *result;
51723571 2161 U8 *send;
ba210ebe 2162 STRLEN l;
a1ca4561
YST
2163 UV nchar = 0;
2164 UV nwide = 0;
1d68d6cd
SC
2165
2166 send = tmps + len;
2167 while (tmps < send) {
9041c2e3 2168 UV c = utf8n_to_uvchr(tmps, send-tmps, &l, UTF8_ALLOW_ANYUV);
1d68d6cd 2169 tmps += UTF8SKIP(tmps);
5bbb0b5a 2170 targlen += UNISKIP(~c);
a1ca4561
YST
2171 nchar++;
2172 if (c > 0xff)
2173 nwide++;
1d68d6cd
SC
2174 }
2175
2176 /* Now rewind strings and write them. */
2177 tmps -= len;
a1ca4561
YST
2178
2179 if (nwide) {
2180 Newz(0, result, targlen + 1, U8);
2181 while (tmps < send) {
9041c2e3 2182 UV c = utf8n_to_uvchr(tmps, send-tmps, &l, UTF8_ALLOW_ANYUV);
a1ca4561 2183 tmps += UTF8SKIP(tmps);
9041c2e3 2184 result = uvchr_to_utf8(result, ~c);
a1ca4561
YST
2185 }
2186 *result = '\0';
2187 result -= targlen;
2188 sv_setpvn(TARG, (char*)result, targlen);
2189 SvUTF8_on(TARG);
2190 }
2191 else {
2192 Newz(0, result, nchar + 1, U8);
2193 while (tmps < send) {
9041c2e3 2194 U8 c = (U8)utf8n_to_uvchr(tmps, 0, &l, UTF8_ALLOW_ANY);
a1ca4561
YST
2195 tmps += UTF8SKIP(tmps);
2196 *result++ = ~c;
2197 }
2198 *result = '\0';
2199 result -= nchar;
2200 sv_setpvn(TARG, (char*)result, nchar);
1d68d6cd 2201 }
1d68d6cd
SC
2202 Safefree(result);
2203 SETs(TARG);
2204 RETURN;
2205 }
a0d0e21e 2206#ifdef LIBERAL
51723571
JH
2207 {
2208 register long *tmpl;
2209 for ( ; anum && (unsigned long)tmps % sizeof(long); anum--, tmps++)
2210 *tmps = ~*tmps;
2211 tmpl = (long*)tmps;
2212 for ( ; anum >= sizeof(long); anum -= sizeof(long), tmpl++)
2213 *tmpl = ~*tmpl;
2214 tmps = (U8*)tmpl;
2215 }
a0d0e21e
LW
2216#endif
2217 for ( ; anum > 0; anum--, tmps++)
2218 *tmps = ~*tmps;
2219
2220 SETs(TARG);
2221 }
2222 RETURN;
2223 }
79072805
LW
2224}
2225
a0d0e21e
LW
2226/* integer versions of some of the above */
2227
a0d0e21e 2228PP(pp_i_multiply)
79072805 2229{
39644a26 2230 dSP; dATARGET; tryAMAGICbin(mult,opASSIGN);
a0d0e21e
LW
2231 {
2232 dPOPTOPiirl;
2233 SETi( left * right );
2234 RETURN;
2235 }
79072805
LW
2236}
2237
a0d0e21e 2238PP(pp_i_divide)
79072805 2239{
39644a26 2240 dSP; dATARGET; tryAMAGICbin(div,opASSIGN);
a0d0e21e
LW
2241 {
2242 dPOPiv;
2243 if (value == 0)
cea2e8a9 2244 DIE(aTHX_ "Illegal division by zero");
a0d0e21e
LW
2245 value = POPi / value;
2246 PUSHi( value );
2247 RETURN;
2248 }
79072805
LW
2249}
2250
a0d0e21e 2251PP(pp_i_modulo)
79072805 2252{
39644a26 2253 dSP; dATARGET; tryAMAGICbin(modulo,opASSIGN);
79072805 2254 {
a0d0e21e 2255 dPOPTOPiirl;
aa306039 2256 if (!right)
cea2e8a9 2257 DIE(aTHX_ "Illegal modulus zero");
a0d0e21e
LW
2258 SETi( left % right );
2259 RETURN;
79072805 2260 }
79072805
LW
2261}
2262
a0d0e21e 2263PP(pp_i_add)
79072805 2264{
39644a26 2265 dSP; dATARGET; tryAMAGICbin(add,opASSIGN);
a0d0e21e 2266 {
5e66d4f1 2267 dPOPTOPiirl_ul;
a0d0e21e
LW
2268 SETi( left + right );
2269 RETURN;
79072805 2270 }
79072805
LW
2271}
2272
a0d0e21e 2273PP(pp_i_subtract)
79072805 2274{
39644a26 2275 dSP; dATARGET; tryAMAGICbin(subtr,opASSIGN);
a0d0e21e 2276 {
5e66d4f1 2277 dPOPTOPiirl_ul;
a0d0e21e
LW
2278 SETi( left - right );
2279 RETURN;
79072805 2280 }
79072805
LW
2281}
2282
a0d0e21e 2283PP(pp_i_lt)
79072805 2284{
39644a26 2285 dSP; tryAMAGICbinSET(lt,0);
a0d0e21e
LW
2286 {
2287 dPOPTOPiirl;
54310121 2288 SETs(boolSV(left < right));
a0d0e21e
LW
2289 RETURN;
2290 }
79072805
LW
2291}
2292
a0d0e21e 2293PP(pp_i_gt)
79072805 2294{
39644a26 2295 dSP; tryAMAGICbinSET(gt,0);
a0d0e21e
LW
2296 {
2297 dPOPTOPiirl;
54310121 2298 SETs(boolSV(left > right));
a0d0e21e
LW
2299 RETURN;
2300 }
79072805
LW
2301}
2302
a0d0e21e 2303PP(pp_i_le)
79072805 2304{
39644a26 2305 dSP; tryAMAGICbinSET(le,0);
a0d0e21e
LW
2306 {
2307 dPOPTOPiirl;
54310121 2308 SETs(boolSV(left <= right));
a0d0e21e 2309 RETURN;
85e6fe83 2310 }
79072805
LW
2311}
2312
a0d0e21e 2313PP(pp_i_ge)
79072805 2314{
39644a26 2315 dSP; tryAMAGICbinSET(ge,0);
a0d0e21e
LW
2316 {
2317 dPOPTOPiirl;
54310121 2318 SETs(boolSV(left >= right));
a0d0e21e
LW
2319 RETURN;
2320 }
79072805
LW
2321}
2322
a0d0e21e 2323PP(pp_i_eq)
79072805 2324{
39644a26 2325 dSP; tryAMAGICbinSET(eq,0);
a0d0e21e
LW
2326 {
2327 dPOPTOPiirl;
54310121 2328 SETs(boolSV(left == right));
a0d0e21e
LW
2329 RETURN;
2330 }
79072805
LW
2331}
2332
a0d0e21e 2333PP(pp_i_ne)
79072805 2334{
39644a26 2335 dSP; tryAMAGICbinSET(ne,0);
a0d0e21e
LW
2336 {
2337 dPOPTOPiirl;
54310121 2338 SETs(boolSV(left != right));
a0d0e21e
LW
2339 RETURN;
2340 }
79072805
LW
2341}
2342
a0d0e21e 2343PP(pp_i_ncmp)
79072805 2344{
39644a26 2345 dSP; dTARGET; tryAMAGICbin(ncmp,0);
a0d0e21e
LW
2346 {
2347 dPOPTOPiirl;
2348 I32 value;
79072805 2349
a0d0e21e 2350 if (left > right)
79072805 2351 value = 1;
a0d0e21e 2352 else if (left < right)
79072805 2353 value = -1;
a0d0e21e 2354 else
79072805 2355 value = 0;
a0d0e21e
LW
2356 SETi(value);
2357 RETURN;
79072805 2358 }
85e6fe83
LW
2359}
2360
2361PP(pp_i_negate)
2362{
39644a26 2363 dSP; dTARGET; tryAMAGICun(neg);
85e6fe83
LW
2364 SETi(-TOPi);
2365 RETURN;
2366}
2367
79072805
LW
2368/* High falutin' math. */
2369
2370PP(pp_atan2)
2371{
39644a26 2372 dSP; dTARGET; tryAMAGICbin(atan2,0);
a0d0e21e
LW
2373 {
2374 dPOPTOPnnrl;
65202027 2375 SETn(Perl_atan2(left, right));
a0d0e21e
LW
2376 RETURN;
2377 }
79072805
LW
2378}
2379
2380PP(pp_sin)
2381{
39644a26 2382 dSP; dTARGET; tryAMAGICun(sin);
a0d0e21e 2383 {
65202027 2384 NV value;
a0d0e21e 2385 value = POPn;
65202027 2386 value = Perl_sin(value);
a0d0e21e
LW
2387 XPUSHn(value);
2388 RETURN;
2389 }
79072805
LW
2390}
2391
2392PP(pp_cos)
2393{
39644a26 2394 dSP; dTARGET; tryAMAGICun(cos);
a0d0e21e 2395 {
65202027 2396 NV value;
a0d0e21e 2397 value = POPn;
65202027 2398 value = Perl_cos(value);
a0d0e21e
LW
2399 XPUSHn(value);
2400 RETURN;
2401 }
79072805
LW
2402}
2403
56cb0a1c
AD
2404/* Support Configure command-line overrides for rand() functions.
2405 After 5.005, perhaps we should replace this by Configure support
2406 for drand48(), random(), or rand(). For 5.005, though, maintain
2407 compatibility by calling rand() but allow the user to override it.
2408 See INSTALL for details. --Andy Dougherty 15 July 1998
2409*/
85ab1d1d
JH
2410/* Now it's after 5.005, and Configure supports drand48() and random(),
2411 in addition to rand(). So the overrides should not be needed any more.
2412 --Jarkko Hietaniemi 27 September 1998
2413 */
2414
2415#ifndef HAS_DRAND48_PROTO
20ce7b12 2416extern double drand48 (void);
56cb0a1c
AD
2417#endif
2418
79072805
LW
2419PP(pp_rand)
2420{
39644a26 2421 dSP; dTARGET;
65202027 2422 NV value;
79072805
LW
2423 if (MAXARG < 1)
2424 value = 1.0;
2425 else
2426 value = POPn;
2427 if (value == 0.0)
2428 value = 1.0;
80252599 2429 if (!PL_srand_called) {
85ab1d1d 2430 (void)seedDrand01((Rand_seed_t)seed());
80252599 2431 PL_srand_called = TRUE;
93dc8474 2432 }
85ab1d1d 2433 value *= Drand01();
79072805
LW
2434 XPUSHn(value);
2435 RETURN;
2436}
2437
2438PP(pp_srand)
2439{
39644a26 2440 dSP;
93dc8474
CS
2441 UV anum;
2442 if (MAXARG < 1)
2443 anum = seed();
79072805 2444 else
93dc8474 2445 anum = POPu;
85ab1d1d 2446 (void)seedDrand01((Rand_seed_t)anum);
80252599 2447 PL_srand_called = TRUE;
79072805
LW
2448 EXTEND(SP, 1);
2449 RETPUSHYES;
2450}
2451
76e3520e 2452STATIC U32
cea2e8a9 2453S_seed(pTHX)
93dc8474 2454{
54310121 2455 /*
2456 * This is really just a quick hack which grabs various garbage
2457 * values. It really should be a real hash algorithm which
2458 * spreads the effect of every input bit onto every output bit,
85ab1d1d 2459 * if someone who knows about such things would bother to write it.
54310121 2460 * Might be a good idea to add that function to CORE as well.
85ab1d1d 2461 * No numbers below come from careful analysis or anything here,
54310121 2462 * except they are primes and SEED_C1 > 1E6 to get a full-width
2463 * value from (tv_sec * SEED_C1 + tv_usec). The multipliers should
2464 * probably be bigger too.
2465 */
2466#if RANDBITS > 16
2467# define SEED_C1 1000003
2468#define SEED_C4 73819
2469#else
2470# define SEED_C1 25747
2471#define SEED_C4 20639
2472#endif
2473#define SEED_C2 3
2474#define SEED_C3 269
2475#define SEED_C5 26107
2476
73c60299
RS
2477#ifndef PERL_NO_DEV_RANDOM
2478 int fd;
2479#endif
93dc8474 2480 U32 u;
f12c7020 2481#ifdef VMS
2482# include <starlet.h>
43c92808
HF
2483 /* when[] = (low 32 bits, high 32 bits) of time since epoch
2484 * in 100-ns units, typically incremented ever 10 ms. */
93dc8474 2485 unsigned int when[2];
73c60299
RS
2486#else
2487# ifdef HAS_GETTIMEOFDAY
2488 struct timeval when;
2489# else
2490 Time_t when;
2491# endif
2492#endif
2493
2494/* This test is an escape hatch, this symbol isn't set by Configure. */
2495#ifndef PERL_NO_DEV_RANDOM
2496#ifndef PERL_RANDOM_DEVICE
2497 /* /dev/random isn't used by default because reads from it will block
2498 * if there isn't enough entropy available. You can compile with
2499 * PERL_RANDOM_DEVICE to it if you'd prefer Perl to block until there
2500 * is enough real entropy to fill the seed. */
2501# define PERL_RANDOM_DEVICE "/dev/urandom"
2502#endif
2503 fd = PerlLIO_open(PERL_RANDOM_DEVICE, 0);
2504 if (fd != -1) {
2505 if (PerlLIO_read(fd, &u, sizeof u) != sizeof u)
2506 u = 0;
2507 PerlLIO_close(fd);
2508 if (u)
2509 return u;
2510 }
2511#endif
2512
2513#ifdef VMS
93dc8474 2514 _ckvmssts(sys$gettim(when));
54310121 2515 u = (U32)SEED_C1 * when[0] + (U32)SEED_C2 * when[1];
f12c7020 2516#else
5f05dabc 2517# ifdef HAS_GETTIMEOFDAY
93dc8474 2518 gettimeofday(&when,(struct timezone *) 0);
54310121 2519 u = (U32)SEED_C1 * when.tv_sec + (U32)SEED_C2 * when.tv_usec;
f12c7020 2520# else
93dc8474 2521 (void)time(&when);
54310121 2522 u = (U32)SEED_C1 * when;
f12c7020 2523# endif
2524#endif
7766f137 2525 u += SEED_C3 * (U32)PerlProc_getpid();
56431972 2526 u += SEED_C4 * (U32)PTR2UV(PL_stack_sp);
54310121 2527#ifndef PLAN9 /* XXX Plan9 assembler chokes on this; fix needed */
56431972 2528 u += SEED_C5 * (U32)PTR2UV(&when);
f12c7020 2529#endif
93dc8474 2530 return u;
79072805
LW
2531}
2532
2533PP(pp_exp)
2534{
39644a26 2535 dSP; dTARGET; tryAMAGICun(exp);
a0d0e21e 2536 {
65202027 2537 NV value;
a0d0e21e 2538 value = POPn;
65202027 2539 value = Perl_exp(value);
a0d0e21e
LW
2540 XPUSHn(value);
2541 RETURN;
2542 }
79072805
LW
2543}
2544
2545PP(pp_log)
2546{
39644a26 2547 dSP; dTARGET; tryAMAGICun(log);
a0d0e21e 2548 {
65202027 2549 NV value;
a0d0e21e 2550 value = POPn;
bbce6d69 2551 if (value <= 0.0) {
f93f4e46 2552 SET_NUMERIC_STANDARD();
cea2e8a9 2553 DIE(aTHX_ "Can't take log of %g", value);
bbce6d69 2554 }
65202027 2555 value = Perl_log(value);
a0d0e21e
LW
2556 XPUSHn(value);
2557 RETURN;
2558 }
79072805
LW
2559}
2560
2561PP(pp_sqrt)
2562{
39644a26 2563 dSP; dTARGET; tryAMAGICun(sqrt);
a0d0e21e 2564 {
65202027 2565 NV value;
a0d0e21e 2566 value = POPn;
bbce6d69 2567 if (value < 0.0) {
f93f4e46 2568 SET_NUMERIC_STANDARD();
cea2e8a9 2569 DIE(aTHX_ "Can't take sqrt of %g", value);
bbce6d69 2570 }
65202027 2571 value = Perl_sqrt(value);
a0d0e21e
LW
2572 XPUSHn(value);
2573 RETURN;
2574 }
79072805
LW
2575}
2576
2577PP(pp_int)
2578{
39644a26 2579 dSP; dTARGET; tryAMAGICun(int);
774d564b 2580 {
28e5dec8
JH
2581 NV value;
2582 IV iv = TOPi; /* attempt to convert to IV if possible. */
2583 /* XXX it's arguable that compiler casting to IV might be subtly
2584 different from modf (for numbers inside (IV_MIN,UV_MAX)) in which
2585 else preferring IV has introduced a subtle behaviour change bug. OTOH
2586 relying on floating point to be accurate is a bug. */
2587
2588 if (SvIOK(TOPs)) {
2589 if (SvIsUV(TOPs)) {
2590 UV uv = TOPu;
2591 SETu(uv);
2592 } else
2593 SETi(iv);
2594 } else {
2595 value = TOPn;
1048ea30 2596 if (value >= 0.0) {
28e5dec8
JH
2597 if (value < (NV)UV_MAX + 0.5) {
2598 SETu(U_V(value));
2599 } else {
1048ea30 2600#if defined(HAS_MODFL) || defined(LONG_DOUBLE_EQUALS_DOUBLE)
e67aeab1
JH
2601# ifdef HAS_MODFL_POW32_BUG
2602/* some versions of glibc split (i + d) into (i-1, d+1) for 2^32 <= i < 2^64 */
2603 {
2604 NV offset = Perl_modf(value, &value);
2605 (void)Perl_modf(offset, &offset);
2606 value += offset;
2607 }
2608# else
28e5dec8 2609 (void)Perl_modf(value, &value);
e67aeab1 2610# endif
1048ea30 2611#else
28e5dec8
JH
2612 double tmp = (double)value;
2613 (void)Perl_modf(tmp, &tmp);
2614 value = (NV)tmp;
1048ea30 2615#endif
2d9af89d 2616 SETn(value);
28e5dec8 2617 }
1048ea30 2618 }
28e5dec8
JH
2619 else {
2620 if (value > (NV)IV_MIN - 0.5) {
2621 SETi(I_V(value));
2622 } else {
1048ea30 2623#if defined(HAS_MODFL) || defined(LONG_DOUBLE_EQUALS_DOUBLE)
e67aeab1
JH
2624# ifdef HAS_MODFL_POW32_BUG
2625/* some versions of glibc split (i + d) into (i-1, d+1) for 2^32 <= i < 2^64 */
2626 {
2627 NV offset = Perl_modf(-value, &value);
2628 (void)Perl_modf(offset, &offset);
2629 value += offset;
2630 }
2631# else
28e5dec8 2632 (void)Perl_modf(-value, &value);
e67aeab1 2633# endif
28e5dec8 2634 value = -value;
1048ea30 2635#else
28e5dec8
JH
2636 double tmp = (double)value;
2637 (void)Perl_modf(-tmp, &tmp);
2638 value = -(NV)tmp;
1048ea30 2639#endif
28e5dec8
JH
2640 SETn(value);
2641 }
2642 }
774d564b 2643 }
79072805 2644 }
79072805
LW
2645 RETURN;
2646}
2647
463ee0b2
LW
2648PP(pp_abs)
2649{
39644a26 2650 dSP; dTARGET; tryAMAGICun(abs);
a0d0e21e 2651 {
28e5dec8
JH
2652 /* This will cache the NV value if string isn't actually integer */
2653 IV iv = TOPi;
a227d84d 2654
28e5dec8
JH
2655 if (SvIOK(TOPs)) {
2656 /* IVX is precise */
2657 if (SvIsUV(TOPs)) {
2658 SETu(TOPu); /* force it to be numeric only */
2659 } else {
2660 if (iv >= 0) {
2661 SETi(iv);
2662 } else {
2663 if (iv != IV_MIN) {
2664 SETi(-iv);
2665 } else {
2666 /* 2s complement assumption. Also, not really needed as
2667 IV_MIN and -IV_MIN should both be %100...00 and NV-able */
2668 SETu(IV_MIN);
2669 }
a227d84d 2670 }
28e5dec8
JH
2671 }
2672 } else{
2673 NV value = TOPn;
774d564b 2674 if (value < 0.0)
28e5dec8 2675 value = -value;
774d564b 2676 SETn(value);
2677 }
a0d0e21e 2678 }
774d564b 2679 RETURN;
463ee0b2
LW
2680}
2681
79072805
LW
2682PP(pp_hex)
2683{
39644a26 2684 dSP; dTARGET;
79072805 2685 char *tmps;
ba210ebe 2686 STRLEN argtype;
6f894ead 2687 STRLEN len;
79072805 2688
6f894ead 2689 tmps = (SvPVx(POPs, len));
b21ed0a9 2690 argtype = 1; /* allow underscores */
6f894ead 2691 XPUSHn(scan_hex(tmps, len, &argtype));
79072805
LW
2692 RETURN;
2693}
2694
2695PP(pp_oct)
2696{
39644a26 2697 dSP; dTARGET;
9e24b6e2 2698 NV value;
ba210ebe 2699 STRLEN argtype;
79072805 2700 char *tmps;
6f894ead 2701 STRLEN len;
79072805 2702
6f894ead
DD
2703 tmps = (SvPVx(POPs, len));
2704 while (*tmps && len && isSPACE(*tmps))
2705 tmps++, len--;
9e24b6e2 2706 if (*tmps == '0')
6f894ead 2707 tmps++, len--;
b21ed0a9 2708 argtype = 1; /* allow underscores */
9e24b6e2 2709 if (*tmps == 'x')
6f894ead 2710 value = scan_hex(++tmps, --len, &argtype);
9e24b6e2 2711 else if (*tmps == 'b')
6f894ead 2712 value = scan_bin(++tmps, --len, &argtype);
464e2e8a 2713 else
6f894ead 2714 value = scan_oct(tmps, len, &argtype);
9e24b6e2 2715 XPUSHn(value);
79072805
LW
2716 RETURN;
2717}
2718
2719/* String stuff. */
2720
2721PP(pp_length)
2722{
39644a26 2723 dSP; dTARGET;
7e2040f0 2724 SV *sv = TOPs;
a0ed51b3 2725
7e2040f0
GS
2726 if (DO_UTF8(sv))
2727 SETi(sv_len_utf8(sv));
2728 else
2729 SETi(sv_len(sv));
79072805
LW
2730 RETURN;
2731}
2732
2733PP(pp_substr)
2734{
39644a26 2735 dSP; dTARGET;
79072805 2736 SV *sv;
9c5ffd7c 2737 I32 len = 0;
463ee0b2 2738 STRLEN curlen;
9402d6ed 2739 STRLEN utf8_curlen;
79072805
LW
2740 I32 pos;
2741 I32 rem;
84902520 2742 I32 fail;
78f9721b 2743 I32 lvalue = PL_op->op_flags & OPf_MOD || LVRET;
79072805 2744 char *tmps;
3280af22 2745 I32 arybase = PL_curcop->cop_arybase;
9402d6ed 2746 SV *repl_sv = NULL;
7b8d334a
GS
2747 char *repl = 0;
2748 STRLEN repl_len;
78f9721b 2749 int num_args = PL_op->op_private & 7;
13e30c65 2750 bool repl_need_utf8_upgrade = FALSE;
9402d6ed 2751 bool repl_is_utf8 = FALSE;
79072805 2752
20408e3c 2753 SvTAINTED_off(TARG); /* decontaminate */
7e2040f0 2754 SvUTF8_off(TARG); /* decontaminate */
78f9721b
SM
2755 if (num_args > 2) {
2756 if (num_args > 3) {
9402d6ed
JH
2757 repl_sv = POPs;
2758 repl = SvPV(repl_sv, repl_len);
2759 repl_is_utf8 = DO_UTF8(repl_sv) && SvCUR(repl_sv);
7b8d334a 2760 }
79072805 2761 len = POPi;
5d82c453 2762 }
84902520 2763 pos = POPi;
79072805 2764 sv = POPs;
849ca7ee 2765 PUTBACK;
9402d6ed
JH
2766 if (repl_sv) {
2767 if (repl_is_utf8) {
2768 if (!DO_UTF8(sv))
2769 sv_utf8_upgrade(sv);
2770 }
13e30c65
JH
2771 else if (DO_UTF8(sv))
2772 repl_need_utf8_upgrade = TRUE;
9402d6ed 2773 }
a0d0e21e 2774 tmps = SvPV(sv, curlen);
7e2040f0 2775 if (DO_UTF8(sv)) {
9402d6ed
JH
2776 utf8_curlen = sv_len_utf8(sv);
2777 if (utf8_curlen == curlen)
2778 utf8_curlen = 0;
a0ed51b3 2779 else
9402d6ed 2780 curlen = utf8_curlen;
a0ed51b3 2781 }
d1c2b58a 2782 else
9402d6ed 2783 utf8_curlen = 0;
a0ed51b3 2784
84902520
TB
2785 if (pos >= arybase) {
2786 pos -= arybase;
2787 rem = curlen-pos;
2788 fail = rem;
78f9721b 2789 if (num_args > 2) {
5d82c453
GA
2790 if (len < 0) {
2791 rem += len;
2792 if (rem < 0)
2793 rem = 0;
2794 }
2795 else if (rem > len)
2796 rem = len;
2797 }
68dc0745 2798 }
84902520 2799 else {
5d82c453 2800 pos += curlen;
78f9721b 2801 if (num_args < 3)
5d82c453
GA
2802 rem = curlen;
2803 else if (len >= 0) {
2804 rem = pos+len;
2805 if (rem > (I32)curlen)
2806 rem = curlen;
2807 }
2808 else {
2809 rem = curlen+len;
2810 if (rem < pos)
2811 rem = pos;
2812 }
2813 if (pos < 0)
2814 pos = 0;
2815 fail = rem;
2816 rem -= pos;
84902520
TB
2817 }
2818 if (fail < 0) {
e476b1b5
GS
2819 if (lvalue || repl)
2820 Perl_croak(aTHX_ "substr outside of string");
2821 if (ckWARN(WARN_SUBSTR))
cea2e8a9 2822 Perl_warner(aTHX_ WARN_SUBSTR, "substr outside of string");
2304df62
AD
2823 RETPUSHUNDEF;
2824 }
79072805 2825 else {
9aa983d2
JH
2826 I32 upos = pos;
2827 I32 urem = rem;
9402d6ed 2828 if (utf8_curlen)
a0ed51b3 2829 sv_pos_u2b(sv, &pos, &rem);
79072805 2830 tmps += pos;
79072805 2831 sv_setpvn(TARG, tmps, rem);
12aa1545 2832#ifdef USE_LOCALE_COLLATE
14befaf4 2833 sv_unmagic(TARG, PERL_MAGIC_collxfrm);
12aa1545 2834#endif
9402d6ed 2835 if (utf8_curlen)
7f66633b 2836 SvUTF8_on(TARG);
f7928d6c 2837 if (repl) {
13e30c65
JH
2838 SV* repl_sv_copy = NULL;
2839
2840 if (repl_need_utf8_upgrade) {
2841 repl_sv_copy = newSVsv(repl_sv);
2842 sv_utf8_upgrade(repl_sv_copy);
2843 repl = SvPV(repl_sv_copy, repl_len);
2844 repl_is_utf8 = DO_UTF8(repl_sv_copy) && SvCUR(sv);
2845 }
c8faf1c5 2846 sv_insert(sv, pos, rem, repl, repl_len);
9402d6ed 2847 if (repl_is_utf8)
f7928d6c 2848 SvUTF8_on(sv);
9402d6ed
JH
2849 if (repl_sv_copy)
2850 SvREFCNT_dec(repl_sv_copy);
f7928d6c 2851 }
c8faf1c5 2852 else if (lvalue) { /* it's an lvalue! */
dedeecda 2853 if (!SvGMAGICAL(sv)) {
2854 if (SvROK(sv)) {
2d8e6c8d
GS
2855 STRLEN n_a;
2856 SvPV_force(sv,n_a);
599cee73 2857 if (ckWARN(WARN_SUBSTR))
cea2e8a9 2858 Perl_warner(aTHX_ WARN_SUBSTR,
599cee73 2859 "Attempt to use reference as lvalue in substr");
dedeecda 2860 }
2861 if (SvOK(sv)) /* is it defined ? */
7f66633b 2862 (void)SvPOK_only_UTF8(sv);
dedeecda 2863 else
2864 sv_setpvn(sv,"",0); /* avoid lexical reincarnation */
2865 }
5f05dabc 2866
a0d0e21e
LW
2867 if (SvTYPE(TARG) < SVt_PVLV) {
2868 sv_upgrade(TARG, SVt_PVLV);
14befaf4 2869 sv_magic(TARG, Nullsv, PERL_MAGIC_substr, Nullch, 0);
ed6116ce 2870 }
a0d0e21e 2871
5f05dabc 2872 LvTYPE(TARG) = 'x';
6ff81951
GS
2873 if (LvTARG(TARG) != sv) {
2874 if (LvTARG(TARG))
2875 SvREFCNT_dec(LvTARG(TARG));
2876 LvTARG(TARG) = SvREFCNT_inc(sv);
2877 }
9aa983d2
JH
2878 LvTARGOFF(TARG) = upos;
2879 LvTARGLEN(TARG) = urem;
79072805
LW
2880 }
2881 }
849ca7ee 2882 SPAGAIN;
79072805
LW
2883 PUSHs(TARG); /* avoid SvSETMAGIC here */
2884 RETURN;
2885}
2886
2887PP(pp_vec)
2888{
39644a26 2889 dSP; dTARGET;
467f0320
JH
2890 register IV size = POPi;
2891 register IV offset = POPi;
79072805 2892 register SV *src = POPs;
78f9721b 2893 I32 lvalue = PL_op->op_flags & OPf_MOD || LVRET;
a0d0e21e 2894
81e118e0
JH
2895 SvTAINTED_off(TARG); /* decontaminate */
2896 if (lvalue) { /* it's an lvalue! */
2897 if (SvTYPE(TARG) < SVt_PVLV) {
2898 sv_upgrade(TARG, SVt_PVLV);
14befaf4 2899 sv_magic(TARG, Nullsv, PERL_MAGIC_vec, Nullch, 0);
79072805 2900 }
81e118e0
JH
2901 LvTYPE(TARG) = 'v';
2902 if (LvTARG(TARG) != src) {
2903 if (LvTARG(TARG))
2904 SvREFCNT_dec(LvTARG(TARG));
2905 LvTARG(TARG) = SvREFCNT_inc(src);
79072805 2906 }
81e118e0
JH
2907 LvTARGOFF(TARG) = offset;
2908 LvTARGLEN(TARG) = size;
79072805
LW
2909 }
2910
81e118e0 2911 sv_setuv(TARG, do_vecget(src, offset, size));
79072805
LW
2912 PUSHs(TARG);
2913 RETURN;
2914}
2915
2916PP(pp_index)
2917{
39644a26 2918 dSP; dTARGET;
79072805
LW
2919 SV *big;
2920 SV *little;
2921 I32 offset;
2922 I32 retval;
2923 char *tmps;
2924 char *tmps2;
463ee0b2 2925 STRLEN biglen;
3280af22 2926 I32 arybase = PL_curcop->cop_arybase;
79072805
LW
2927
2928 if (MAXARG < 3)
2929 offset = 0;
2930 else
2931 offset = POPi - arybase;
2932 little = POPs;
2933 big = POPs;
463ee0b2 2934 tmps = SvPV(big, biglen);
7e2040f0 2935 if (offset > 0 && DO_UTF8(big))
a0ed51b3 2936 sv_pos_u2b(big, &offset, 0);
79072805
LW
2937 if (offset < 0)
2938 offset = 0;
93a17b20
LW
2939 else if (offset > biglen)
2940 offset = biglen;
79072805 2941 if (!(tmps2 = fbm_instr((unsigned char*)tmps + offset,
411d5715 2942 (unsigned char*)tmps + biglen, little, 0)))
a0ed51b3 2943 retval = -1;
79072805 2944 else
a0ed51b3 2945 retval = tmps2 - tmps;
7e2040f0 2946 if (retval > 0 && DO_UTF8(big))
a0ed51b3
LW
2947 sv_pos_b2u(big, &retval);
2948 PUSHi(retval + arybase);
79072805
LW
2949 RETURN;
2950}
2951
2952PP(pp_rindex)
2953{
39644a26 2954 dSP; dTARGET;
79072805
LW
2955 SV *big;
2956 SV *little;
463ee0b2
LW
2957 STRLEN blen;
2958 STRLEN llen;
79072805
LW
2959 I32 offset;
2960 I32 retval;
2961 char *tmps;
2962 char *tmps2;
3280af22 2963 I32 arybase = PL_curcop->cop_arybase;
79072805 2964
a0d0e21e 2965 if (MAXARG >= 3)
a0ed51b3 2966 offset = POPi;
79072805
LW
2967 little = POPs;
2968 big = POPs;
463ee0b2
LW
2969 tmps2 = SvPV(little, llen);
2970 tmps = SvPV(big, blen);
79072805 2971 if (MAXARG < 3)
463ee0b2 2972 offset = blen;
a0ed51b3 2973 else {
7e2040f0 2974 if (offset > 0 && DO_UTF8(big))
a0ed51b3
LW
2975 sv_pos_u2b(big, &offset, 0);
2976 offset = offset - arybase + llen;
2977 }
79072805
LW
2978 if (offset < 0)
2979 offset = 0;
463ee0b2
LW
2980 else if (offset > blen)
2981 offset = blen;
79072805 2982 if (!(tmps2 = rninstr(tmps, tmps + offset,
463ee0b2 2983 tmps2, tmps2 + llen)))
a0ed51b3 2984 retval = -1;
79072805 2985 else
a0ed51b3 2986 retval = tmps2 - tmps;
7e2040f0 2987 if (retval > 0 && DO_UTF8(big))
a0ed51b3
LW
2988 sv_pos_b2u(big, &retval);
2989 PUSHi(retval + arybase);
79072805
LW
2990 RETURN;
2991}
2992
2993PP(pp_sprintf)
2994{
39644a26 2995 dSP; dMARK; dORIGMARK; dTARGET;
79072805 2996 do_sprintf(TARG, SP-MARK, MARK+1);
bbce6d69 2997 TAINT_IF(SvTAINTED(TARG));
79072805
LW
2998 SP = ORIGMARK;
2999 PUSHTARG;
3000 RETURN;
3001}
3002
79072805
LW
3003PP(pp_ord)
3004{
39644a26 3005 dSP; dTARGET;
7df053ec 3006 SV *argsv = POPs;
ba210ebe 3007 STRLEN len;
7df053ec 3008 U8 *s = (U8*)SvPVx(argsv, len);
79072805 3009
9041c2e3 3010 XPUSHu(DO_UTF8(argsv) ? utf8_to_uvchr(s, 0) : (*s & 0xff));
79072805
LW
3011 RETURN;
3012}
3013
463ee0b2
LW
3014PP(pp_chr)
3015{
39644a26 3016 dSP; dTARGET;
463ee0b2 3017 char *tmps;
467f0320 3018 UV value = POPu;
463ee0b2 3019
748a9306 3020 (void)SvUPGRADE(TARG,SVt_PV);
a0ed51b3 3021
0064a8a9 3022 if (value > 255 && !IN_BYTES) {
9aa983d2 3023 SvGROW(TARG, UNISKIP(value)+1);
9041c2e3 3024 tmps = (char*)uvchr_to_utf8((U8*)SvPVX(TARG), value);
a0ed51b3
LW
3025 SvCUR_set(TARG, tmps - SvPVX(TARG));
3026 *tmps = '\0';
3027 (void)SvPOK_only(TARG);
aa6ffa16 3028 SvUTF8_on(TARG);
a0ed51b3
LW
3029 XPUSHs(TARG);
3030 RETURN;
3031 }
3032
748a9306 3033 SvGROW(TARG,2);
463ee0b2
LW
3034 SvCUR_set(TARG, 1);
3035 tmps = SvPVX(TARG);
a0ed51b3 3036 *tmps++ = value;
748a9306 3037 *tmps = '\0';
a0d0e21e 3038 (void)SvPOK_only(TARG);
463ee0b2
LW
3039 XPUSHs(TARG);
3040 RETURN;
3041}
3042
79072805
LW
3043PP(pp_crypt)
3044{
39644a26 3045 dSP; dTARGET; dPOPTOPssrl;
2d8e6c8d 3046 STRLEN n_a;
79072805 3047#ifdef HAS_CRYPT
2d8e6c8d 3048 char *tmps = SvPV(left, n_a);
79072805 3049#ifdef FCRYPT
2d8e6c8d 3050 sv_setpv(TARG, fcrypt(tmps, SvPV(right, n_a)));
79072805 3051#else
2d8e6c8d 3052 sv_setpv(TARG, PerlProc_crypt(tmps, SvPV(right, n_a)));
79072805
LW
3053#endif
3054#else
b13b2135 3055 DIE(aTHX_
79072805
LW
3056 "The crypt() function is unimplemented due to excessive paranoia.");
3057#endif
3058 SETs(TARG);
3059 RETURN;
3060}
3061
3062PP(pp_ucfirst)
3063{
39644a26 3064 dSP;
79072805 3065 SV *sv = TOPs;
a0ed51b3
LW
3066 register U8 *s;
3067 STRLEN slen;
3068
fd400ab9 3069 if (DO_UTF8(sv) && (s = (U8*)SvPV(sv, slen)) && slen && UTF8_IS_START(*s)) {
ba210ebe 3070 STRLEN ulen;
ad391ad9 3071 U8 tmpbuf[UTF8_MAXLEN+1];
a0ed51b3 3072 U8 *tend;
9041c2e3 3073 UV uv;
a0ed51b3 3074
2de3dbcc 3075 if (IN_LOCALE_RUNTIME) {
a0ed51b3
LW
3076 TAINT;
3077 SvTAINTED_on(sv);
9041c2e3 3078 uv = toTITLE_LC_uvchr(utf8n_to_uvchr(s, slen, &ulen, 0));
a0ed51b3
LW
3079 }
3080 else
3081 uv = toTITLE_utf8(s);
3082
9041c2e3 3083 tend = uvchr_to_utf8(tmpbuf, uv);
a0ed51b3 3084
014822e4 3085 if (!SvPADTMP(sv) || tend - tmpbuf != ulen || SvREADONLY(sv)) {
a0ed51b3 3086 dTARGET;
dfe13c55
GS
3087 sv_setpvn(TARG, (char*)tmpbuf, tend - tmpbuf);
3088 sv_catpvn(TARG, (char*)(s + ulen), slen - ulen);
7e2040f0 3089 SvUTF8_on(TARG);
a0ed51b3
LW
3090 SETs(TARG);
3091 }
3092 else {
dfe13c55 3093 s = (U8*)SvPV_force(sv, slen);
a0ed51b3
LW
3094 Copy(tmpbuf, s, ulen, U8);
3095 }
a0ed51b3 3096 }
626727d5 3097 else {
014822e4 3098 if (!SvPADTMP(sv) || SvREADONLY(sv)) {
31351b04 3099 dTARGET;
7e2040f0 3100 SvUTF8_off(TARG); /* decontaminate */
31351b04
JS
3101 sv_setsv(TARG, sv);
3102 sv = TARG;
3103 SETs(sv);
3104 }
3105 s = (U8*)SvPV_force(sv, slen);
3106 if (*s) {
2de3dbcc 3107 if (IN_LOCALE_RUNTIME) {
31351b04
JS
3108 TAINT;
3109 SvTAINTED_on(sv);
3110 *s = toUPPER_LC(*s);
3111 }
3112 else
3113 *s = toUPPER(*s);
bbce6d69 3114 }
bbce6d69 3115 }
31351b04
JS
3116 if (SvSMAGICAL(sv))
3117 mg_set(sv);
79072805
LW
3118 RETURN;
3119}
3120
3121PP(pp_lcfirst)
3122{
39644a26 3123 dSP;
79072805 3124 SV *sv = TOPs;
a0ed51b3
LW
3125 register U8 *s;
3126 STRLEN slen;
3127
fd400ab9 3128 if (DO_UTF8(sv) && (s = (U8*)SvPV(sv, slen)) && slen && UTF8_IS_START(*s)) {
ba210ebe 3129 STRLEN ulen;
ad391ad9 3130 U8 tmpbuf[UTF8_MAXLEN+1];
a0ed51b3 3131 U8 *tend;
9041c2e3 3132 UV uv;
a0ed51b3 3133
2de3dbcc 3134 if (IN_LOCALE_RUNTIME) {
a0ed51b3
LW
3135 TAINT;
3136 SvTAINTED_on(sv);
9041c2e3 3137 uv = toLOWER_LC_uvchr(utf8n_to_uvchr(s, slen, &ulen, 0));
a0ed51b3
LW
3138 }
3139 else
3140 uv = toLOWER_utf8(s);
3141
9041c2e3 3142 tend = uvchr_to_utf8(tmpbuf, uv);
a0ed51b3 3143
014822e4 3144 if (!SvPADTMP(sv) || tend - tmpbuf != ulen || SvREADONLY(sv)) {
a0ed51b3 3145 dTARGET;
dfe13c55
GS
3146 sv_setpvn(TARG, (char*)tmpbuf, tend - tmpbuf);
3147 sv_catpvn(TARG, (char*)(s + ulen), slen - ulen);
7e2040f0 3148 SvUTF8_on(TARG);
a0ed51b3
LW
3149 SETs(TARG);
3150 }
3151 else {
dfe13c55 3152 s = (U8*)SvPV_force(sv, slen);
a0ed51b3
LW
3153 Copy(tmpbuf, s, ulen, U8);
3154 }
a0ed51b3 3155 }
626727d5 3156 else {
014822e4 3157 if (!SvPADTMP(sv) || SvREADONLY(sv)) {
31351b04 3158 dTARGET;
7e2040f0 3159 SvUTF8_off(TARG); /* decontaminate */
31351b04
JS
3160 sv_setsv(TARG, sv);
3161 sv = TARG;
3162 SETs(sv);
3163 }
3164 s = (U8*)SvPV_force(sv, slen);
3165 if (*s) {
2de3dbcc 3166 if (IN_LOCALE_RUNTIME) {
31351b04
JS
3167 TAINT;
3168 SvTAINTED_on(sv);
3169 *s = toLOWER_LC(*s);
3170 }
3171 else
3172 *s = toLOWER(*s);
bbce6d69 3173 }
bbce6d69 3174 }
31351b04
JS
3175 if (SvSMAGICAL(sv))
3176 mg_set(sv);
79072805
LW
3177 RETURN;
3178}
3179
3180PP(pp_uc)
3181{
39644a26 3182 dSP;
79072805 3183 SV *sv = TOPs;
a0ed51b3 3184 register U8 *s;
463ee0b2 3185 STRLEN len;
79072805 3186
7e2040f0 3187 if (DO_UTF8(sv)) {
a0ed51b3 3188 dTARGET;
ba210ebe 3189 STRLEN ulen;
a0ed51b3
LW
3190 register U8 *d;
3191 U8 *send;
3192
dfe13c55 3193 s = (U8*)SvPV(sv,len);
a5a20234 3194 if (!len) {
7e2040f0 3195 SvUTF8_off(TARG); /* decontaminate */
a5a20234
LW
3196 sv_setpvn(TARG, "", 0);
3197 SETs(TARG);
a0ed51b3
LW
3198 }
3199 else {
31351b04
JS
3200 (void)SvUPGRADE(TARG, SVt_PV);
3201 SvGROW(TARG, (len * 2) + 1);
3202 (void)SvPOK_only(TARG);
3203 d = (U8*)SvPVX(TARG);
3204 send = s + len;
2de3dbcc 3205 if (IN_LOCALE_RUNTIME) {
31351b04
JS
3206 TAINT;
3207 SvTAINTED_on(TARG);
3208 while (s < send) {
9041c2e3 3209 d = uvchr_to_utf8(d, toUPPER_LC_uvchr( utf8n_to_uvchr(s, len, &ulen, 0)));
31351b04
JS
3210 s += ulen;
3211 }
a0ed51b3 3212 }
31351b04
JS
3213 else {
3214 while (s < send) {
9041c2e3 3215 d = uvchr_to_utf8(d, toUPPER_utf8( s ));
31351b04
JS
3216 s += UTF8SKIP(s);
3217 }
a0ed51b3 3218 }
31351b04 3219 *d = '\0';
7e2040f0 3220 SvUTF8_on(TARG);
31351b04
JS
3221 SvCUR_set(TARG, d - (U8*)SvPVX(TARG));
3222 SETs(TARG);
a0ed51b3 3223 }
a0ed51b3 3224 }
626727d5 3225 else {
014822e4 3226 if (!SvPADTMP(sv) || SvREADONLY(sv)) {
31351b04 3227 dTARGET;
7e2040f0 3228 SvUTF8_off(TARG); /* decontaminate */
31351b04
JS
3229 sv_setsv(TARG, sv);
3230 sv = TARG;
3231 SETs(sv);
3232 }
3233 s = (U8*)SvPV_force(sv, len);
3234 if (len) {
3235 register U8 *send = s + len;
3236
2de3dbcc 3237 if (IN_LOCALE_RUNTIME) {
31351b04
JS
3238 TAINT;
3239 SvTAINTED_on(sv);
3240 for (; s < send; s++)
3241 *s = toUPPER_LC(*s);
3242 }
3243 else {
3244 for (; s < send; s++)
3245 *s = toUPPER(*s);
3246 }
bbce6d69 3247 }
79072805 3248 }
31351b04
JS
3249 if (SvSMAGICAL(sv))
3250 mg_set(sv);
79072805
LW
3251 RETURN;
3252}
3253
3254PP(pp_lc)
3255{
39644a26 3256 dSP;
79072805 3257 SV *sv = TOPs;
a0ed51b3 3258 register U8 *s;
463ee0b2 3259 STRLEN len;
79072805 3260
7e2040f0 3261 if (DO_UTF8(sv)) {
a0ed51b3 3262 dTARGET;
ba210ebe 3263 STRLEN ulen;
a0ed51b3
LW
3264 register U8 *d;
3265 U8 *send;
3266
dfe13c55 3267 s = (U8*)SvPV(sv,len);
a5a20234 3268 if (!len) {
7e2040f0 3269 SvUTF8_off(TARG); /* decontaminate */
a5a20234
LW
3270 sv_setpvn(TARG, "", 0);
3271 SETs(TARG);
a0ed51b3
LW
3272 }
3273 else {
31351b04
JS
3274 (void)SvUPGRADE(TARG, SVt_PV);
3275 SvGROW(TARG, (len * 2) + 1);
3276 (void)SvPOK_only(TARG);
3277 d = (U8*)SvPVX(TARG);
3278 send = s + len;
2de3dbcc 3279 if (IN_LOCALE_RUNTIME) {
31351b04
JS
3280 TAINT;
3281 SvTAINTED_on(TARG);
3282 while (s < send) {
9041c2e3 3283 d = uvchr_to_utf8(d, toLOWER_LC_uvchr( utf8n_to_uvchr(s, len, &ulen, 0)));
31351b04
JS
3284 s += ulen;
3285 }
a0ed51b3 3286 }
31351b04
JS
3287 else {
3288 while (s < send) {
9041c2e3 3289 d = uvchr_to_utf8(d, toLOWER_utf8(s));
31351b04
JS
3290 s += UTF8SKIP(s);
3291 }
a0ed51b3 3292 }
31351b04 3293 *d = '\0';
7e2040f0 3294 SvUTF8_on(TARG);
31351b04
JS
3295 SvCUR_set(TARG, d - (U8*)SvPVX(TARG));
3296 SETs(TARG);
a0ed51b3 3297 }
79072805 3298 }
626727d5 3299 else {
014822e4 3300 if (!SvPADTMP(sv) || SvREADONLY(sv)) {
31351b04 3301 dTARGET;
7e2040f0 3302 SvUTF8_off(TARG); /* decontaminate */
31351b04
JS
3303 sv_setsv(TARG, sv);
3304 sv = TARG;
3305 SETs(sv);
a0ed51b3 3306 }
bbce6d69 3307
31351b04
JS
3308 s = (U8*)SvPV_force(sv, len);
3309 if (len) {
3310 register U8 *send = s + len;
bbce6d69 3311
2de3dbcc 3312 if (IN_LOCALE_RUNTIME) {
31351b04
JS
3313 TAINT;
3314 SvTAINTED_on(sv);
3315 for (; s < send; s++)
3316 *s = toLOWER_LC(*s);
3317 }
3318 else {
3319 for (; s < send; s++)
3320 *s = toLOWER(*s);
3321 }
bbce6d69 3322 }
79072805 3323 }
31351b04
JS
3324 if (SvSMAGICAL(sv))
3325 mg_set(sv);
79072805
LW
3326 RETURN;
3327}
3328
a0d0e21e 3329PP(pp_quotemeta)
79072805 3330{
39644a26 3331 dSP; dTARGET;
a0d0e21e
LW
3332 SV *sv = TOPs;
3333 STRLEN len;
3334 register char *s = SvPV(sv,len);
3335 register char *d;
79072805 3336
7e2040f0 3337 SvUTF8_off(TARG); /* decontaminate */
a0d0e21e
LW
3338 if (len) {
3339 (void)SvUPGRADE(TARG, SVt_PV);
c07a80fd 3340 SvGROW(TARG, (len * 2) + 1);
a0d0e21e 3341 d = SvPVX(TARG);
7e2040f0 3342 if (DO_UTF8(sv)) {
0dd2cdef 3343 while (len) {
fd400ab9 3344 if (UTF8_IS_CONTINUED(*s)) {
0dd2cdef
LW
3345 STRLEN ulen = UTF8SKIP(s);
3346 if (ulen > len)
3347 ulen = len;
3348 len -= ulen;
3349 while (ulen--)
3350 *d++ = *s++;
3351 }
3352 else {
3353 if (!isALNUM(*s))
3354 *d++ = '\\';
3355 *d++ = *s++;
3356 len--;
3357 }
3358 }
7e2040f0 3359 SvUTF8_on(TARG);
0dd2cdef
LW
3360 }
3361 else {
3362 while (len--) {
3363 if (!isALNUM(*s))
3364 *d++ = '\\';
3365 *d++ = *s++;
3366 }
79072805 3367 }
a0d0e21e
LW
3368 *d = '\0';
3369 SvCUR_set(TARG, d - SvPVX(TARG));
3aa33fe5 3370 (void)SvPOK_only_UTF8(TARG);
79072805 3371 }
a0d0e21e
LW
3372 else
3373 sv_setpvn(TARG, s, len);
3374 SETs(TARG);
31351b04
JS
3375 if (SvSMAGICAL(TARG))
3376 mg_set(TARG);
79072805
LW
3377 RETURN;
3378}
3379
a0d0e21e 3380/* Arrays. */
79072805 3381
a0d0e21e 3382PP(pp_aslice)
79072805 3383{
39644a26 3384 dSP; dMARK; dORIGMARK;
a0d0e21e
LW
3385 register SV** svp;
3386 register AV* av = (AV*)POPs;
78f9721b 3387 register I32 lval = (PL_op->op_flags & OPf_MOD || LVRET);
3280af22 3388 I32 arybase = PL_curcop->cop_arybase;
748a9306 3389 I32 elem;
79072805 3390
a0d0e21e 3391 if (SvTYPE(av) == SVt_PVAV) {
533c011a 3392 if (lval && PL_op->op_private & OPpLVAL_INTRO) {
748a9306 3393 I32 max = -1;
924508f0 3394 for (svp = MARK + 1; svp <= SP; svp++) {
748a9306
LW
3395 elem = SvIVx(*svp);
3396 if (elem > max)
3397 max = elem;
3398 }
3399 if (max > AvMAX(av))
3400 av_extend(av, max);
3401 }
a0d0e21e 3402 while (++MARK <= SP) {
748a9306 3403 elem = SvIVx(*MARK);
a0d0e21e 3404
748a9306
LW
3405 if (elem > 0)
3406 elem -= arybase;
a0d0e21e
LW
3407 svp = av_fetch(av, elem, lval);
3408 if (lval) {
3280af22 3409 if (!svp || *svp == &PL_sv_undef)
cea2e8a9 3410 DIE(aTHX_ PL_no_aelem, elem);
533c011a 3411 if (PL_op->op_private & OPpLVAL_INTRO)
161b7d16 3412 save_aelem(av, elem, svp);
79072805 3413 }
3280af22 3414 *MARK = svp ? *svp : &PL_sv_undef;
79072805
LW
3415 }
3416 }
748a9306 3417 if (GIMME != G_ARRAY) {
a0d0e21e
LW
3418 MARK = ORIGMARK;
3419 *++MARK = *SP;
3420 SP = MARK;
3421 }
79072805
LW
3422 RETURN;
3423}
3424
3425/* Associative arrays. */
3426
3427PP(pp_each)
3428{
39644a26 3429 dSP;
79072805 3430 HV *hash = (HV*)POPs;
c07a80fd 3431 HE *entry;
54310121 3432 I32 gimme = GIMME_V;
c750a3ec 3433 I32 realhv = (SvTYPE(hash) == SVt_PVHV);
8ec5e241 3434
c07a80fd 3435 PUTBACK;
c750a3ec
MB
3436 /* might clobber stack_sp */
3437 entry = realhv ? hv_iternext(hash) : avhv_iternext((AV*)hash);
c07a80fd 3438 SPAGAIN;
79072805 3439
79072805
LW
3440 EXTEND(SP, 2);
3441 if (entry) {
54310121 3442 PUSHs(hv_iterkeysv(entry)); /* won't clobber stack_sp */
3443 if (gimme == G_ARRAY) {
59af0135 3444 SV *val;
c07a80fd 3445 PUTBACK;
c750a3ec 3446 /* might clobber stack_sp */
59af0135
GS
3447 val = realhv ?
3448 hv_iterval(hash, entry) : avhv_iterval((AV*)hash, entry);
c07a80fd 3449 SPAGAIN;
59af0135 3450 PUSHs(val);
79072805 3451 }
79072805 3452 }
54310121 3453 else if (gimme == G_SCALAR)
79072805
LW
3454 RETPUSHUNDEF;
3455
3456 RETURN;
3457}
3458
3459PP(pp_values)
3460{
cea2e8a9 3461 return do_kv();
79072805
LW
3462}
3463
3464PP(pp_keys)
3465{
cea2e8a9 3466 return do_kv();
79072805
LW
3467}
3468
3469PP(pp_delete)
3470{
39644a26 3471 dSP;
54310121 3472 I32 gimme = GIMME_V;
3473 I32 discard = (gimme == G_VOID) ? G_DISCARD : 0;
79072805 3474 SV *sv;
5f05dabc 3475 HV *hv;
3476
533c011a 3477 if (PL_op->op_private & OPpSLICE) {
5f05dabc 3478 dMARK; dORIGMARK;
97fcbf96 3479 U32 hvtype;
5f05dabc 3480 hv = (HV*)POPs;
97fcbf96 3481 hvtype = SvTYPE(hv);
01020589
GS
3482 if (hvtype == SVt_PVHV) { /* hash element */
3483 while (++MARK <= SP) {
ae77835f 3484 sv = hv_delete_ent(hv, *MARK, discard, 0);
01020589
GS
3485 *MARK = sv ? sv : &PL_sv_undef;
3486 }
5f05dabc 3487 }
01020589
GS
3488 else if (hvtype == SVt_PVAV) {
3489 if (PL_op->op_flags & OPf_SPECIAL) { /* array element */
3490 while (++MARK <= SP) {
3491 sv = av_delete((AV*)hv, SvIV(*MARK), discard);
3492 *MARK = sv ? sv : &PL_sv_undef;
3493 }
3494 }
3495 else { /* pseudo-hash element */
3496 while (++MARK <= SP) {
3497 sv = avhv_delete_ent((AV*)hv, *MARK, discard, 0);
3498 *MARK = sv ? sv : &PL_sv_undef;
3499 }
3500 }
3501 }
3502 else
3503 DIE(aTHX_ "Not a HASH reference");
54310121 3504 if (discard)
3505 SP = ORIGMARK;
3506 else if (gimme == G_SCALAR) {
5f05dabc 3507 MARK = ORIGMARK;
3508 *++MARK = *SP;
3509 SP = MARK;
3510 }
3511 }
3512 else {
3513 SV *keysv = POPs;
3514 hv = (HV*)POPs;
97fcbf96
MB
3515 if (SvTYPE(hv) == SVt_PVHV)
3516 sv = hv_delete_ent(hv, keysv, discard, 0);
01020589
GS
3517 else if (SvTYPE(hv) == SVt_PVAV) {
3518 if (PL_op->op_flags & OPf_SPECIAL)
3519 sv = av_delete((AV*)hv, SvIV(keysv), discard);
3520 else
3521 sv = avhv_delete_ent((AV*)hv, keysv, discard, 0);
3522 }
97fcbf96 3523 else
cea2e8a9 3524 DIE(aTHX_ "Not a HASH reference");
5f05dabc 3525 if (!sv)
3280af22 3526 sv = &PL_sv_undef;
54310121 3527 if (!discard)
3528 PUSHs(sv);
79072805 3529 }
79072805
LW
3530 RETURN;
3531}
3532
a0d0e21e 3533PP(pp_exists)
79072805 3534{
39644a26 3535 dSP;
afebc493
GS
3536 SV *tmpsv;
3537 HV *hv;
3538
3539 if (PL_op->op_private & OPpEXISTS_SUB) {
3540 GV *gv;
3541 CV *cv;
3542 SV *sv = POPs;
3543 cv = sv_2cv(sv, &hv, &gv, FALSE);
3544 if (cv)
3545 RETPUSHYES;
3546 if (gv && isGV(gv) && GvCV(gv) && !GvCVGEN(gv))
3547 RETPUSHYES;
3548 RETPUSHNO;
3549 }
3550 tmpsv = POPs;
3551 hv = (HV*)POPs;
c750a3ec 3552 if (SvTYPE(hv) == SVt_PVHV) {
ae77835f 3553 if (hv_exists_ent(hv, tmpsv, 0))
c750a3ec 3554 RETPUSHYES;
ef54e1a4
JH
3555 }
3556 else if (SvTYPE(hv) == SVt_PVAV) {
01020589
GS
3557 if (PL_op->op_flags & OPf_SPECIAL) { /* array element */
3558 if (av_exists((AV*)hv, SvIV(tmpsv)))
3559 RETPUSHYES;
3560 }
3561 else if (avhv_exists_ent((AV*)hv, tmpsv, 0)) /* pseudo-hash element */
c750a3ec 3562 RETPUSHYES;
ef54e1a4
JH
3563 }
3564 else {
cea2e8a9 3565 DIE(aTHX_ "Not a HASH reference");
a0d0e21e 3566 }
a0d0e21e
LW
3567 RETPUSHNO;
3568}
79072805 3569
a0d0e21e
LW
3570PP(pp_hslice)
3571{
39644a26 3572 dSP; dMARK; dORIGMARK;
a0d0e21e 3573 register HV *hv = (HV*)POPs;
78f9721b 3574 register I32 lval = (PL_op->op_flags & OPf_MOD || LVRET);
c750a3ec 3575 I32 realhv = (SvTYPE(hv) == SVt_PVHV);
79072805 3576
0ebe0038 3577 if (!realhv && PL_op->op_private & OPpLVAL_INTRO)
cea2e8a9 3578 DIE(aTHX_ "Can't localize pseudo-hash element");
0ebe0038 3579
c750a3ec 3580 if (realhv || SvTYPE(hv) == SVt_PVAV) {
a0d0e21e 3581 while (++MARK <= SP) {
f12c7020 3582 SV *keysv = *MARK;
ae77835f 3583 SV **svp;
d4fa047a
RH
3584 I32 preeminent = SvRMAGICAL(hv) ? 1 :
3585 realhv ? hv_exists_ent(hv, keysv, 0)
3586 : avhv_exists_ent((AV*)hv, keysv, 0);
ae77835f 3587 if (realhv) {
800e9ae0 3588 HE *he = hv_fetch_ent(hv, keysv, lval, 0);
ae77835f 3589 svp = he ? &HeVAL(he) : 0;
ef54e1a4
JH
3590 }
3591 else {
97fcbf96 3592 svp = avhv_fetch_ent((AV*)hv, keysv, lval, 0);
ae77835f 3593 }
a0d0e21e 3594 if (lval) {
2d8e6c8d
GS
3595 if (!svp || *svp == &PL_sv_undef) {
3596 STRLEN n_a;
cea2e8a9 3597 DIE(aTHX_ PL_no_helem, SvPV(keysv, n_a));
2d8e6c8d 3598 }
1f5346dc 3599 if (PL_op->op_private & OPpLVAL_INTRO) {
a227d84d 3600 if (preeminent)
1f5346dc
SC
3601 save_helem(hv, keysv, svp);
3602 else {
3603 STRLEN keylen;
3604 char *key = SvPV(keysv, keylen);
57813020 3605 SAVEDELETE(hv, savepvn(key,keylen), keylen);
1f5346dc
SC
3606 }
3607 }
93a17b20 3608 }
3280af22 3609 *MARK = svp ? *svp : &PL_sv_undef;
79072805
LW
3610 }
3611 }
a0d0e21e
LW
3612 if (GIMME != G_ARRAY) {
3613 MARK = ORIGMARK;
3614 *++MARK = *SP;
3615 SP = MARK;
79072805 3616 }
a0d0e21e
LW
3617 RETURN;
3618}
3619
3620/* List operators. */
3621
3622PP(pp_list)
3623{
39644a26 3624 dSP; dMARK;
a0d0e21e
LW
3625 if (GIMME != G_ARRAY) {
3626 if (++MARK <= SP)
3627 *MARK = *SP; /* unwanted list, return last item */
8990e307 3628 else
3280af22 3629 *MARK = &PL_sv_undef;
a0d0e21e 3630 SP = MARK;
79072805 3631 }
a0d0e21e 3632 RETURN;
79072805
LW
3633}
3634
a0d0e21e 3635PP(pp_lslice)
79072805 3636{
39644a26 3637 dSP;
3280af22
NIS
3638 SV **lastrelem = PL_stack_sp;
3639 SV **lastlelem = PL_stack_base + POPMARK;
3640 SV **firstlelem = PL_stack_base + POPMARK + 1;
a0d0e21e 3641 register SV **firstrelem = lastlelem + 1;
3280af22 3642 I32 arybase = PL_curcop->cop_arybase;
533c011a 3643 I32 lval = PL_op->op_flags & OPf_MOD;
4633a7c4 3644 I32 is_something_there = lval;
79072805 3645
a0d0e21e
LW
3646 register I32 max = lastrelem - lastlelem;
3647 register SV **lelem;
3648 register I32 ix;
3649
3650 if (GIMME != G_ARRAY) {
748a9306
LW
3651 ix = SvIVx(*lastlelem);
3652 if (ix < 0)
3653 ix += max;
3654 else
3655 ix -= arybase;
a0d0e21e 3656 if (ix < 0 || ix >= max)
3280af22 3657 *firstlelem = &PL_sv_undef;
a0d0e21e
LW
3658 else
3659 *firstlelem = firstrelem[ix];
3660 SP = firstlelem;
3661 RETURN;
3662 }
3663
3664 if (max == 0) {
3665 SP = firstlelem - 1;
3666 RETURN;
3667 }
3668
3669 for (lelem = firstlelem; lelem <= lastlelem; lelem++) {
748a9306 3670 ix = SvIVx(*lelem);
c73bf8e3 3671 if (ix < 0)
a0d0e21e 3672 ix += max;
b13b2135 3673 else
748a9306 3674 ix -= arybase;
c73bf8e3
HS
3675 if (ix < 0 || ix >= max)
3676 *lelem = &PL_sv_undef;
3677 else {
3678 is_something_there = TRUE;
3679 if (!(*lelem = firstrelem[ix]))
3280af22 3680 *lelem = &PL_sv_undef;
748a9306 3681 }
79072805 3682 }
4633a7c4
LW
3683 if (is_something_there)
3684 SP = lastlelem;
3685 else
3686 SP = firstlelem - 1;
79072805
LW
3687 RETURN;
3688}
3689
a0d0e21e
LW
3690PP(pp_anonlist)
3691{
39644a26 3692 dSP; dMARK; dORIGMARK;
a0d0e21e 3693 I32 items = SP - MARK;
44a8e56a 3694 SV *av = sv_2mortal((SV*)av_make(items, MARK+1));
3695 SP = ORIGMARK; /* av_make() might realloc stack_sp */
3696 XPUSHs(av);
a0d0e21e
LW
3697 RETURN;
3698}
3699
3700PP(pp_anonhash)
79072805 3701{
39644a26 3702 dSP; dMARK; dORIGMARK;
a0d0e21e
LW
3703 HV* hv = (HV*)sv_2mortal((SV*)newHV());
3704
3705 while (MARK < SP) {
3706 SV* key = *++MARK;
a0d0e21e
LW
3707 SV *val = NEWSV(46, 0);
3708 if (MARK < SP)
3709 sv_setsv(val, *++MARK);
e476b1b5
GS
3710 else if (ckWARN(WARN_MISC))
3711 Perl_warner(aTHX_ WARN_MISC, "Odd number of elements in hash assignment");
f12c7020 3712 (void)hv_store_ent(hv,key,val,0);
79072805 3713 }
a0d0e21e
LW
3714 SP = ORIGMARK;
3715 XPUSHs((SV*)hv);
79072805
LW
3716 RETURN;
3717}
3718
a0d0e21e 3719PP(pp_splice)
79072805 3720{
39644a26 3721 dSP; dMARK; dORIGMARK;
a0d0e21e
LW
3722 register AV *ary = (AV*)*++MARK;
3723 register SV **src;
3724 register SV **dst;
3725 register I32 i;
3726 register I32 offset;
3727 register I32 length;
3728 I32 newlen;
3729 I32 after;
3730 I32 diff;
3731 SV **tmparyval = 0;
93965878
NIS
3732 MAGIC *mg;
3733
14befaf4 3734 if ((mg = SvTIED_mg((SV*)ary, PERL_MAGIC_tied))) {
33c27489 3735 *MARK-- = SvTIED_obj((SV*)ary, mg);
93965878 3736 PUSHMARK(MARK);
8ec5e241 3737 PUTBACK;
a60c0954 3738 ENTER;
864dbfa3 3739 call_method("SPLICE",GIMME_V);
a60c0954 3740 LEAVE;
93965878
NIS
3741 SPAGAIN;
3742 RETURN;
3743 }
79072805 3744
a0d0e21e 3745 SP++;
79072805 3746
a0d0e21e 3747 if (++MARK < SP) {
84902520 3748 offset = i = SvIVx(*MARK);
a0d0e21e 3749 if (offset < 0)
93965878 3750 offset += AvFILLp(ary) + 1;
a0d0e21e 3751 else
3280af22 3752 offset -= PL_curcop->cop_arybase;
84902520 3753 if (offset < 0)
cea2e8a9 3754 DIE(aTHX_ PL_no_aelem, i);
a0d0e21e
LW
3755 if (++MARK < SP) {
3756 length = SvIVx(*MARK++);
48cdf507
GA
3757 if (length < 0) {
3758 length += AvFILLp(ary) - offset + 1;
3759 if (length < 0)
3760 length = 0;
3761 }
79072805
LW
3762 }
3763 else
a0d0e21e 3764 length = AvMAX(ary) + 1; /* close enough to infinity */
79072805 3765 }
a0d0e21e
LW
3766 else {
3767 offset = 0;
3768 length = AvMAX(ary) + 1;
3769 }
93965878
NIS
3770 if (offset > AvFILLp(ary) + 1)
3771 offset = AvFILLp(ary) + 1;
3772 after = AvFILLp(ary) + 1 - (offset + length);
a0d0e21e
LW
3773 if (after < 0) { /* not that much array */
3774 length += after; /* offset+length now in array */
3775 after = 0;
3776 if (!AvALLOC(ary))
3777 av_extend(ary, 0);
3778 }
3779
3780 /* At this point, MARK .. SP-1 is our new LIST */
3781
3782 newlen = SP - MARK;
3783 diff = newlen - length;
13d7cbc1
GS
3784 if (newlen && !AvREAL(ary) && AvREIFY(ary))
3785 av_reify(ary);
a0d0e21e
LW
3786
3787 if (diff < 0) { /* shrinking the area */
3788 if (newlen) {
3789 New(451, tmparyval, newlen, SV*); /* so remember insertion */
3790 Copy(MARK, tmparyval, newlen, SV*);
79072805 3791 }
a0d0e21e
LW
3792
3793 MARK = ORIGMARK + 1;
3794 if (GIMME == G_ARRAY) { /* copy return vals to stack */
3795 MEXTEND(MARK, length);
3796 Copy(AvARRAY(ary)+offset, MARK, length, SV*);
3797 if (AvREAL(ary)) {
bbce6d69 3798 EXTEND_MORTAL(length);
36477c24 3799 for (i = length, dst = MARK; i; i--) {
d689ffdd 3800 sv_2mortal(*dst); /* free them eventualy */
36477c24 3801 dst++;
3802 }
a0d0e21e
LW
3803 }
3804 MARK += length - 1;
79072805 3805 }
a0d0e21e
LW
3806 else {
3807 *MARK = AvARRAY(ary)[offset+length-1];
3808 if (AvREAL(ary)) {
d689ffdd 3809 sv_2mortal(*MARK);
a0d0e21e
LW
3810 for (i = length - 1, dst = &AvARRAY(ary)[offset]; i > 0; i--)
3811 SvREFCNT_dec(*dst++); /* free them now */
79072805 3812 }
a0d0e21e 3813 }
93965878 3814 AvFILLp(ary) += diff;
a0d0e21e
LW
3815
3816 /* pull up or down? */
3817
3818 if (offset < after) { /* easier to pull up */
3819 if (offset) { /* esp. if nothing to pull */
3820 src = &AvARRAY(ary)[offset-1];
3821 dst = src - diff; /* diff is negative */
3822 for (i = offset; i > 0; i--) /* can't trust Copy */
3823 *dst-- = *src--;
79072805 3824 }
a0d0e21e
LW
3825 dst = AvARRAY(ary);
3826 SvPVX(ary) = (char*)(AvARRAY(ary) - diff); /* diff is negative */
3827 AvMAX(ary) += diff;
3828 }
3829 else {
3830 if (after) { /* anything to pull down? */
3831 src = AvARRAY(ary) + offset + length;
3832 dst = src + diff; /* diff is negative */
3833 Move(src, dst, after, SV*);
79072805 3834 }
93965878 3835 dst = &AvARRAY(ary)[AvFILLp(ary)+1];
a0d0e21e
LW
3836 /* avoid later double free */
3837 }
3838 i = -diff;
3839 while (i)
3280af22 3840 dst[--i] = &PL_sv_undef;
a0d0e21e
LW
3841
3842 if (newlen) {
3843 for (src = tmparyval, dst = AvARRAY(ary) + offset;
3844 newlen; newlen--) {
3845 *dst = NEWSV(46, 0);
3846 sv_setsv(*dst++, *src++);
79072805 3847 }
a0d0e21e
LW
3848 Safefree(tmparyval);
3849 }
3850 }
3851 else { /* no, expanding (or same) */
3852 if (length) {
3853 New(452, tmparyval, length, SV*); /* so remember deletion */
3854 Copy(AvARRAY(ary)+offset, tmparyval, length, SV*);
3855 }
3856
3857 if (diff > 0) { /* expanding */
3858
3859 /* push up or down? */
3860
3861 if (offset < after && diff <= AvARRAY(ary) - AvALLOC(ary)) {
3862 if (offset) {
3863 src = AvARRAY(ary);
3864 dst = src - diff;
3865 Move(src, dst, offset, SV*);
79072805 3866 }
a0d0e21e
LW
3867 SvPVX(ary) = (char*)(AvARRAY(ary) - diff);/* diff is positive */
3868 AvMAX(ary) += diff;
93965878 3869 AvFILLp(ary) += diff;
79072805
LW
3870 }
3871 else {
93965878
NIS
3872 if (AvFILLp(ary) + diff >= AvMAX(ary)) /* oh, well */
3873 av_extend(ary, AvFILLp(ary) + diff);
3874 AvFILLp(ary) += diff;
a0d0e21e
LW
3875
3876 if (after) {
93965878 3877 dst = AvARRAY(ary) + AvFILLp(ary);
a0d0e21e
LW
3878 src = dst - diff;
3879 for (i = after; i; i--) {
3880 *dst-- = *src--;
3881 }
79072805
LW
3882 }
3883 }
a0d0e21e
LW
3884 }
3885
3886 for (src = MARK, dst = AvARRAY(ary) + offset; newlen; newlen--) {
3887 *dst = NEWSV(46, 0);
3888 sv_setsv(*dst++, *src++);
3889 }
3890 MARK = ORIGMARK + 1;
3891 if (GIMME == G_ARRAY) { /* copy return vals to stack */
3892 if (length) {
3893 Copy(tmparyval, MARK, length, SV*);
3894 if (AvREAL(ary)) {
bbce6d69 3895 EXTEND_MORTAL(length);
36477c24 3896 for (i = length, dst = MARK; i; i--) {
d689ffdd 3897 sv_2mortal(*dst); /* free them eventualy */
36477c24 3898 dst++;
3899 }
79072805 3900 }
a0d0e21e 3901 Safefree(tmparyval);
79072805 3902 }
a0d0e21e
LW
3903 MARK += length - 1;
3904 }
3905 else if (length--) {
3906 *MARK = tmparyval[length];
3907 if (AvREAL(ary)) {
d689ffdd 3908 sv_2mortal(*MARK);
a0d0e21e
LW
3909 while (length-- > 0)
3910 SvREFCNT_dec(tmparyval[length]);
79072805 3911 }
a0d0e21e 3912 Safefree(tmparyval);
79072805 3913 }
a0d0e21e 3914 else
3280af22 3915 *MARK = &PL_sv_undef;
79072805 3916 }
a0d0e21e 3917 SP = MARK;
79072805
LW
3918 RETURN;
3919}
3920
a0d0e21e 3921PP(pp_push)
79072805 3922{
39644a26 3923 dSP; dMARK; dORIGMARK; dTARGET;
a0d0e21e 3924 register AV *ary = (AV*)*++MARK;
3280af22 3925 register SV *sv = &PL_sv_undef;
93965878 3926 MAGIC *mg;
79072805 3927
14befaf4 3928 if ((mg = SvTIED_mg((SV*)ary, PERL_MAGIC_tied))) {
33c27489 3929 *MARK-- = SvTIED_obj((SV*)ary, mg);
93965878
NIS
3930 PUSHMARK(MARK);
3931 PUTBACK;
a60c0954 3932 ENTER;
864dbfa3 3933 call_method("PUSH",G_SCALAR|G_DISCARD);
a60c0954 3934 LEAVE;
93965878 3935 SPAGAIN;
93965878 3936 }
a60c0954
NIS
3937 else {
3938 /* Why no pre-extend of ary here ? */
3939 for (++MARK; MARK <= SP; MARK++) {
3940 sv = NEWSV(51, 0);
3941 if (*MARK)
3942 sv_setsv(sv, *MARK);
3943 av_push(ary, sv);
3944 }
79072805
LW
3945 }
3946 SP = ORIGMARK;
a0d0e21e 3947 PUSHi( AvFILL(ary) + 1 );
79072805
LW
3948 RETURN;
3949}
3950
a0d0e21e 3951PP(pp_pop)
79072805 3952{
39644a26 3953 dSP;
a0d0e21e
LW
3954 AV *av = (AV*)POPs;
3955 SV *sv = av_pop(av);
d689ffdd 3956 if (AvREAL(av))
a0d0e21e
LW
3957 (void)sv_2mortal(sv);
3958 PUSHs(sv);
79072805 3959 RETURN;
79072805
LW
3960}
3961
a0d0e21e 3962PP(pp_shift)
79072805 3963{
39644a26 3964 dSP;
a0d0e21e
LW
3965 AV *av = (AV*)POPs;
3966 SV *sv = av_shift(av);
79072805 3967 EXTEND(SP, 1);
a0d0e21e 3968 if (!sv)
79072805 3969 RETPUSHUNDEF;
d689ffdd 3970 if (AvREAL(av))
a0d0e21e
LW
3971 (void)sv_2mortal(sv);
3972 PUSHs(sv);
79072805 3973 RETURN;
79072805
LW
3974}
3975
a0d0e21e 3976PP(pp_unshift)
79072805 3977{
39644a26 3978 dSP; dMARK; dORIGMARK; dTARGET;
a0d0e21e
LW
3979 register AV *ary = (AV*)*++MARK;
3980 register SV *sv;
3981 register I32 i = 0;
93965878
NIS
3982 MAGIC *mg;
3983
14befaf4 3984 if ((mg = SvTIED_mg((SV*)ary, PERL_MAGIC_tied))) {
33c27489 3985 *MARK-- = SvTIED_obj((SV*)ary, mg);
7fd66d9d 3986 PUSHMARK(MARK);
93965878 3987 PUTBACK;
a60c0954 3988 ENTER;
864dbfa3 3989 call_method("UNSHIFT",G_SCALAR|G_DISCARD);
a60c0954 3990 LEAVE;
93965878 3991 SPAGAIN;
93965878 3992 }
a60c0954
NIS
3993 else {
3994 av_unshift(ary, SP - MARK);
3995 while (MARK < SP) {
3996 sv = NEWSV(27, 0);
3997 sv_setsv(sv, *++MARK);
3998 (void)av_store(ary, i++, sv);
3999 }
79072805 4000 }
a0d0e21e
LW
4001 SP = ORIGMARK;
4002 PUSHi( AvFILL(ary) + 1 );
79072805 4003 RETURN;
79072805
LW
4004}
4005
a0d0e21e 4006PP(pp_reverse)
79072805 4007{
39644a26 4008 dSP; dMARK;
a0d0e21e
LW
4009 register SV *tmp;
4010 SV **oldsp = SP;
79072805 4011
a0d0e21e
LW
4012 if (GIMME == G_ARRAY) {
4013 MARK++;
4014 while (MARK < SP) {
4015 tmp = *MARK;
4016 *MARK++ = *SP;
4017 *SP-- = tmp;
4018 }
dd58a1ab 4019 /* safe as long as stack cannot get extended in the above */
a0d0e21e 4020 SP = oldsp;
79072805
LW
4021 }
4022 else {
a0d0e21e
LW
4023 register char *up;
4024 register char *down;
4025 register I32 tmp;
4026 dTARGET;
4027 STRLEN len;
79072805 4028
7e2040f0 4029 SvUTF8_off(TARG); /* decontaminate */
a0d0e21e 4030 if (SP - MARK > 1)
3280af22 4031 do_join(TARG, &PL_sv_no, MARK, SP);
a0d0e21e 4032 else
54b9620d 4033 sv_setsv(TARG, (SP > MARK) ? *SP : DEFSV);
a0d0e21e
LW
4034 up = SvPV_force(TARG, len);
4035 if (len > 1) {
7e2040f0 4036 if (DO_UTF8(TARG)) { /* first reverse each character */
dfe13c55
GS
4037 U8* s = (U8*)SvPVX(TARG);
4038 U8* send = (U8*)(s + len);
a0ed51b3 4039 while (s < send) {
d742c382 4040 if (UTF8_IS_INVARIANT(*s)) {
a0ed51b3
LW
4041 s++;
4042 continue;
4043 }
4044 else {
9041c2e3 4045 if (!utf8_to_uvchr(s, 0))
a0dbb045 4046 break;
dfe13c55 4047 up = (char*)s;
a0ed51b3 4048 s += UTF8SKIP(s);
dfe13c55 4049 down = (char*)(s - 1);
a0dbb045 4050 /* reverse this character */
a0ed51b3
LW
4051 while (down > up) {
4052 tmp = *up;
4053 *up++ = *down;
4054 *down-- = tmp;
4055 }
4056 }
4057 }
4058 up = SvPVX(TARG);
4059 }
a0d0e21e
LW
4060 down = SvPVX(TARG) + len - 1;
4061 while (down > up) {
4062 tmp = *up;
4063 *up++ = *down;
4064 *down-- = tmp;
4065 }
3aa33fe5 4066 (void)SvPOK_only_UTF8(TARG);
79072805 4067 }
a0d0e21e
LW
4068 SP = MARK + 1;
4069 SETTARG;
79072805 4070 }
a0d0e21e 4071 RETURN;
79072805
LW
4072}
4073
864dbfa3 4074STATIC SV *
cea2e8a9 4075S_mul128(pTHX_ SV *sv, U8 m)
55497cff 4076{
4077 STRLEN len;
4078 char *s = SvPV(sv, len);
4079 char *t;
4080 U32 i = 0;
4081
4082 if (!strnEQ(s, "0000", 4)) { /* need to grow sv */
79cb57f6 4083 SV *tmpNew = newSVpvn("0000000000", 10);
55497cff 4084
09b7f37c 4085 sv_catsv(tmpNew, sv);
55497cff 4086 SvREFCNT_dec(sv); /* free old sv */
09b7f37c 4087 sv = tmpNew;
55497cff 4088 s = SvPV(sv, len);
4089 }
4090 t = s + len - 1;
4091 while (!*t) /* trailing '\0'? */
4092 t--;
4093 while (t > s) {
4094 i = ((*t - '0') << 7) + m;
4095 *(t--) = '0' + (i % 10);
4096 m = i / 10;
4097 }
4098 return (sv);
4099}
4100
a0d0e21e
LW
4101/* Explosives and implosives. */
4102
9d116dd7
JH
4103#if 'I' == 73 && 'J' == 74
4104/* On an ASCII/ISO kind of system */
ba1ac976 4105#define ISUUCHAR(ch) ((ch) >= ' ' && (ch) < 'a')
9d116dd7
JH
4106#else
4107/*
4108 Some other sort of character set - use memchr() so we don't match
4109 the null byte.
4110 */
80252599 4111#define ISUUCHAR(ch) (memchr(PL_uuemap, (ch), sizeof(PL_uuemap)-1) || (ch) == ' ')
9d116dd7
JH
4112#endif
4113
d815558d 4114
a0d0e21e 4115PP(pp_unpack)
79072805 4116{
39644a26 4117 dSP;
a0d0e21e 4118 dPOPPOPssrl;
dd58a1ab 4119 I32 start_sp_offset = SP - PL_stack_base;
54310121 4120 I32 gimme = GIMME_V;
ed6116ce 4121 SV *sv;
a0d0e21e
LW
4122 STRLEN llen;
4123 STRLEN rlen;
4124 register char *pat = SvPV(left, llen);
d815558d 4125#ifdef PACKED_IS_OCTETS
9041c2e3
NIS
4126 /* Packed side is assumed to be octets - so force downgrade if it
4127 has been UTF-8 encoded by accident
4128 */
4129 register char *s = SvPVbyte(right, rlen);
4130#else
a0d0e21e 4131 register char *s = SvPV(right, rlen);
9041c2e3 4132#endif
a0d0e21e
LW
4133 char *strend = s + rlen;
4134 char *strbeg = s;
4135 register char *patend = pat + llen;
4136 I32 datumtype;
4137 register I32 len;
9c5ffd7c 4138 register I32 bits = 0;
abdc5761 4139 register char *str;
79072805 4140
a0d0e21e 4141 /* These must not be in registers: */
43ea6eee 4142 short ashort;
a0d0e21e 4143 int aint;
43ea6eee 4144 long along;
6b8eaf93 4145#ifdef HAS_QUAD
ecfc5424 4146 Quad_t aquad;
a0d0e21e
LW
4147#endif
4148 U16 aushort;
4149 unsigned int auint;
4150 U32 aulong;
6b8eaf93 4151#ifdef HAS_QUAD
e862df63 4152 Uquad_t auquad;
a0d0e21e
LW
4153#endif
4154 char *aptr;
4155 float afloat;
4156 double adouble;
4157 I32 checksum = 0;
9c5ffd7c
JH
4158 register U32 culong = 0;
4159 NV cdouble = 0.0;
fb73857a 4160 int commas = 0;
4b5b2118 4161 int star;
726ea183 4162#ifdef PERL_NATINT_PACK
ef54e1a4
JH
4163 int natint; /* native integer */
4164 int unatint; /* unsigned native integer */
726ea183 4165#endif
79072805 4166
54310121 4167 if (gimme != G_ARRAY) { /* arrange to do first one only */
a0d0e21e
LW
4168 /*SUPPRESS 530*/
4169 for (patend = pat; !isALPHA(*patend) || *patend == 'x'; patend++) ;
5a929a98 4170 if (strchr("aAZbBhHP", *patend) || *pat == '%') {
a0d0e21e
LW
4171 patend++;
4172 while (isDIGIT(*patend) || *patend == '*')
4173 patend++;
4174 }
4175 else
4176 patend++;
79072805 4177 }
a0d0e21e
LW
4178 while (pat < patend) {
4179 reparse:
bbdab043 4180 datumtype = *pat++ & 0xFF;
726ea183 4181#ifdef PERL_NATINT_PACK
ef54e1a4 4182 natint = 0;
726ea183 4183#endif
bbdab043
CS
4184 if (isSPACE(datumtype))
4185 continue;
17f4a12d
IZ
4186 if (datumtype == '#') {
4187 while (pat < patend && *pat != '\n')
4188 pat++;
4189 continue;
4190 }
f61d411c 4191 if (*pat == '!') {
ef54e1a4
JH
4192 char *natstr = "sSiIlL";
4193
4194 if (strchr(natstr, datumtype)) {
726ea183 4195#ifdef PERL_NATINT_PACK
ef54e1a4 4196 natint = 1;
726ea183 4197#endif
ef54e1a4
JH
4198 pat++;
4199 }
4200 else
d470f89e 4201 DIE(aTHX_ "'!' allowed only after types %s", natstr);
ef54e1a4 4202 }
4b5b2118 4203 star = 0;
a0d0e21e
LW
4204 if (pat >= patend)
4205 len = 1;
4206 else if (*pat == '*') {
4207 len = strend - strbeg; /* long enough */
4208 pat++;
4b5b2118 4209 star = 1;
a0d0e21e
LW
4210 }
4211 else if (isDIGIT(*pat)) {
4212 len = *pat++ - '0';
06387354 4213 while (isDIGIT(*pat)) {
a0d0e21e 4214 len = (len * 10) + (*pat++ - '0');
06387354 4215 if (len < 0)
d470f89e 4216 DIE(aTHX_ "Repeat count in unpack overflows");
06387354 4217 }
a0d0e21e
LW
4218 }
4219 else
4220 len = (datumtype != '@');
4b5b2118 4221 redo_switch:
a0d0e21e
LW
4222 switch(datumtype) {
4223 default:
d470f89e 4224 DIE(aTHX_ "Invalid type in unpack: '%c'", (int)datumtype);
fb73857a 4225 case ',': /* grandfather in commas but with a warning */
e476b1b5
GS
4226 if (commas++ == 0 && ckWARN(WARN_UNPACK))
4227 Perl_warner(aTHX_ WARN_UNPACK,
d470f89e 4228 "Invalid type in unpack: '%c'", (int)datumtype);
fb73857a 4229 break;
a0d0e21e
LW
4230 case '%':
4231 if (len == 1 && pat[-1] != '1')
4232 len = 16;
4233 checksum = len;
4234 culong = 0;
4235 cdouble = 0;
4236 if (pat < patend)
4237 goto reparse;
4238 break;
4239 case '@':
4240 if (len > strend - strbeg)
cea2e8a9 4241 DIE(aTHX_ "@ outside of string");
a0d0e21e
LW
4242 s = strbeg + len;
4243 break;
4244 case 'X':
4245 if (len > s - strbeg)
cea2e8a9 4246 DIE(aTHX_ "X outside of string");
a0d0e21e
LW
4247 s -= len;
4248 break;
4249 case 'x':
4250 if (len > strend - s)
cea2e8a9 4251 DIE(aTHX_ "x outside of string");
a0d0e21e
LW
4252 s += len;
4253 break;
17f4a12d 4254 case '/':
dd58a1ab 4255 if (start_sp_offset >= SP - PL_stack_base)
17f4a12d 4256 DIE(aTHX_ "/ must follow a numeric type");
43192e07
IP
4257 datumtype = *pat++;
4258 if (*pat == '*')
4259 pat++; /* ignore '*' for compatibility with pack */
4260 if (isDIGIT(*pat))
17f4a12d 4261 DIE(aTHX_ "/ cannot take a count" );
43192e07 4262 len = POPi;
4b5b2118
GS
4263 star = 0;
4264 goto redo_switch;
a0d0e21e 4265 case 'A':
5a929a98 4266 case 'Z':
a0d0e21e
LW
4267 case 'a':
4268 if (len > strend - s)
4269 len = strend - s;
4270 if (checksum)
4271 goto uchar_checksum;
4272 sv = NEWSV(35, len);
4273 sv_setpvn(sv, s, len);
4274 s += len;
5a929a98 4275 if (datumtype == 'A' || datumtype == 'Z') {
a0d0e21e 4276 aptr = s; /* borrow register */
5a929a98
VU
4277 if (datumtype == 'Z') { /* 'Z' strips stuff after first null */
4278 s = SvPVX(sv);
4279 while (*s)
4280 s++;
4281 }
4282 else { /* 'A' strips both nulls and spaces */
4283 s = SvPVX(sv) + len - 1;
4284 while (s >= SvPVX(sv) && (!*s || isSPACE(*s)))
4285 s--;
4286 *++s = '\0';
4287 }
a0d0e21e
LW
4288 SvCUR_set(sv, s - SvPVX(sv));
4289 s = aptr; /* unborrow register */
4290 }
4291 XPUSHs(sv_2mortal(sv));
4292 break;
4293 case 'B':
4294 case 'b':
4b5b2118 4295 if (star || len > (strend - s) * 8)
a0d0e21e
LW
4296 len = (strend - s) * 8;
4297 if (checksum) {
80252599
GS
4298 if (!PL_bitcount) {
4299 Newz(601, PL_bitcount, 256, char);
a0d0e21e 4300 for (bits = 1; bits < 256; bits++) {
80252599
GS
4301 if (bits & 1) PL_bitcount[bits]++;
4302 if (bits & 2) PL_bitcount[bits]++;
4303 if (bits & 4) PL_bitcount[bits]++;
4304 if (bits & 8) PL_bitcount[bits]++;
4305 if (bits & 16) PL_bitcount[bits]++;
4306 if (bits & 32) PL_bitcount[bits]++;
4307 if (bits & 64) PL_bitcount[bits]++;
4308 if (bits & 128) PL_bitcount[bits]++;
a0d0e21e
LW
4309 }
4310 }
4311 while (len >= 8) {
80252599 4312 culong += PL_bitcount[*(unsigned char*)s++];
a0d0e21e
LW
4313 len -= 8;
4314 }
4315 if (len) {
4316 bits = *s;
4317 if (datumtype == 'b') {
4318 while (len-- > 0) {
4319 if (bits & 1) culong++;
4320 bits >>= 1;
4321 }
4322 }
4323 else {
4324 while (len-- > 0) {
4325 if (bits & 128) culong++;
4326 bits <<= 1;
4327 }
4328 }
4329 }
79072805
LW
4330 break;
4331 }
a0d0e21e
LW
4332 sv = NEWSV(35, len + 1);
4333 SvCUR_set(sv, len);
4334 SvPOK_on(sv);
abdc5761 4335 str = SvPVX(sv);
a0d0e21e
LW
4336 if (datumtype == 'b') {
4337 aint = len;
4338 for (len = 0; len < aint; len++) {
4339 if (len & 7) /*SUPPRESS 595*/
4340 bits >>= 1;
4341 else
4342 bits = *s++;
abdc5761 4343 *str++ = '0' + (bits & 1);
a0d0e21e
LW
4344 }
4345 }
4346 else {
4347 aint = len;
4348 for (len = 0; len < aint; len++) {
4349 if (len & 7)
4350 bits <<= 1;
4351 else
4352 bits = *s++;
abdc5761 4353 *str++ = '0' + ((bits & 128) != 0);
a0d0e21e
LW
4354 }
4355 }
abdc5761 4356 *str = '\0';
a0d0e21e
LW
4357 XPUSHs(sv_2mortal(sv));
4358 break;
4359 case 'H':
4360 case 'h':
4b5b2118 4361 if (star || len > (strend - s) * 2)
a0d0e21e
LW
4362 len = (strend - s) * 2;
4363 sv = NEWSV(35, len + 1);
4364 SvCUR_set(sv, len);
4365 SvPOK_on(sv);
abdc5761 4366 str = SvPVX(sv);
a0d0e21e
LW
4367 if (datumtype == 'h') {
4368 aint = len;
4369 for (len = 0; len < aint; len++) {
4370 if (len & 1)
4371 bits >>= 4;
4372 else
4373 bits = *s++;
abdc5761 4374 *str++ = PL_hexdigit[bits & 15];
a0d0e21e
LW
4375 }
4376 }
4377 else {
4378 aint = len;
4379 for (len = 0; len < aint; len++) {
4380 if (len & 1)
4381 bits <<= 4;
4382 else
4383 bits = *s++;
abdc5761 4384 *str++ = PL_hexdigit[(bits >> 4) & 15];
a0d0e21e
LW
4385 }
4386 }
abdc5761 4387 *str = '\0';
a0d0e21e
LW
4388 XPUSHs(sv_2mortal(sv));
4389 break;
4390 case 'c':
4391 if (len > strend - s)
4392 len = strend - s;
4393 if (checksum) {
4394 while (len-- > 0) {
4395 aint = *s++;
4396 if (aint >= 128) /* fake up signed chars */
4397 aint -= 256;
4398 culong += aint;
4399 }
4400 }
4401 else {
4402 EXTEND(SP, len);
bbce6d69 4403 EXTEND_MORTAL(len);
a0d0e21e
LW
4404 while (len-- > 0) {
4405 aint = *s++;
4406 if (aint >= 128) /* fake up signed chars */
4407 aint -= 256;
4408 sv = NEWSV(36, 0);
1e422769 4409 sv_setiv(sv, (IV)aint);
a0d0e21e
LW
4410 PUSHs(sv_2mortal(sv));
4411 }
4412 }
4413 break;
4414 case 'C':
4415 if (len > strend - s)
4416 len = strend - s;
4417 if (checksum) {
494f3023
JH
4418 uchar_checksum:
4419 while (len-- > 0) {
4420 auint = *s++ & 255;
4421 culong += auint;
a0d0e21e
LW
4422 }
4423 }
4424 else {
4425 EXTEND(SP, len);
bbce6d69 4426 EXTEND_MORTAL(len);
494f3023
JH
4427 while (len-- > 0) {
4428 auint = *s++ & 255;
4429 sv = NEWSV(37, 0);
4430 sv_setiv(sv, (IV)auint);
4431 PUSHs(sv_2mortal(sv));
a0d0e21e
LW
4432 }
4433 }
4434 break;
9e639032
JH
4435 case 'U':
4436 if (len > strend - s)
4437 len = strend - s;
4438 if (checksum) {
4439 while (len-- > 0 && s < strend) {
4440 STRLEN alen;
9041c2e3 4441 auint = utf8n_to_uvchr((U8*)s, strend - s, &alen, 0);
9e639032
JH
4442 along = alen;
4443 s += along;
4444 if (checksum > 32)
4445 cdouble += (NV)auint;
4446 else
4447 culong += auint;
4448 }
4449 }
4450 else {
4451 EXTEND(SP, len);
4452 EXTEND_MORTAL(len);
4453 while (len-- > 0 && s < strend) {
4454 STRLEN alen;
9041c2e3 4455 auint = utf8n_to_uvchr((U8*)s, strend - s, &alen, 0);
9e639032
JH
4456 along = alen;
4457 s += along;
4458 sv = NEWSV(37, 0);
4459 sv_setuv(sv, (UV)auint);
4460 PUSHs(sv_2mortal(sv));
4461 }
4462 }
4463 break;
a0d0e21e 4464 case 's':
726ea183
JH
4465#if SHORTSIZE == SIZE16
4466 along = (strend - s) / SIZE16;
4467#else
ef54e1a4 4468 along = (strend - s) / (natint ? sizeof(short) : SIZE16);
726ea183 4469#endif
a0d0e21e
LW
4470 if (len > along)
4471 len = along;
4472 if (checksum) {
726ea183 4473#if SHORTSIZE != SIZE16
ef54e1a4 4474 if (natint) {
bf9315bb 4475 short ashort;
ef54e1a4
JH
4476 while (len-- > 0) {
4477 COPYNN(s, &ashort, sizeof(short));
4478 s += sizeof(short);
4479 culong += ashort;
4480
4481 }
4482 }
726ea183
JH
4483 else
4484#endif
4485 {
ef54e1a4
JH
4486 while (len-- > 0) {
4487 COPY16(s, &ashort);
c67712b2
JH
4488#if SHORTSIZE > SIZE16
4489 if (ashort > 32767)
4490 ashort -= 65536;
4491#endif
ef54e1a4
JH
4492 s += SIZE16;
4493 culong += ashort;
4494 }
a0d0e21e
LW
4495 }
4496 }
4497 else {
4498 EXTEND(SP, len);
bbce6d69 4499 EXTEND_MORTAL(len);
726ea183 4500#if SHORTSIZE != SIZE16
ef54e1a4 4501 if (natint) {
bf9315bb 4502 short ashort;
ef54e1a4
JH
4503 while (len-- > 0) {
4504 COPYNN(s, &ashort, sizeof(short));
4505 s += sizeof(short);
4506 sv = NEWSV(38, 0);
4507 sv_setiv(sv, (IV)ashort);
4508 PUSHs(sv_2mortal(sv));
4509 }
4510 }
726ea183
JH
4511 else
4512#endif
4513 {
ef54e1a4
JH
4514 while (len-- > 0) {
4515 COPY16(s, &ashort);
c67712b2
JH
4516#if SHORTSIZE > SIZE16
4517 if (ashort > 32767)
4518 ashort -= 65536;
4519#endif
ef54e1a4
JH
4520 s += SIZE16;
4521 sv = NEWSV(38, 0);
4522 sv_setiv(sv, (IV)ashort);
4523 PUSHs(sv_2mortal(sv));
4524 }
a0d0e21e
LW
4525 }
4526 }
4527 break;
4528 case 'v':
4529 case 'n':
4530 case 'S':
726ea183
JH
4531#if SHORTSIZE == SIZE16
4532 along = (strend - s) / SIZE16;
4533#else
ef54e1a4
JH
4534 unatint = natint && datumtype == 'S';
4535 along = (strend - s) / (unatint ? sizeof(unsigned short) : SIZE16);
726ea183 4536#endif
a0d0e21e
LW
4537 if (len > along)
4538 len = along;
4539 if (checksum) {
726ea183 4540#if SHORTSIZE != SIZE16
ef54e1a4 4541 if (unatint) {
bf9315bb 4542 unsigned short aushort;
ef54e1a4
JH
4543 while (len-- > 0) {
4544 COPYNN(s, &aushort, sizeof(unsigned short));
4545 s += sizeof(unsigned short);
4546 culong += aushort;
4547 }
4548 }
726ea183
JH
4549 else
4550#endif
4551 {
ef54e1a4
JH
4552 while (len-- > 0) {
4553 COPY16(s, &aushort);
4554 s += SIZE16;
a0d0e21e 4555#ifdef HAS_NTOHS
ef54e1a4
JH
4556 if (datumtype == 'n')
4557 aushort = PerlSock_ntohs(aushort);
79072805 4558#endif
a0d0e21e 4559#ifdef HAS_VTOHS
ef54e1a4
JH
4560 if (datumtype == 'v')
4561 aushort = vtohs(aushort);
79072805 4562#endif
ef54e1a4
JH
4563 culong += aushort;
4564 }
a0d0e21e
LW
4565 }
4566 }
4567 else {
4568 EXTEND(SP, len);
bbce6d69 4569 EXTEND_MORTAL(len);
726ea183 4570#if SHORTSIZE != SIZE16
ef54e1a4 4571 if (unatint) {
bf9315bb 4572 unsigned short aushort;
ef54e1a4
JH
4573 while (len-- > 0) {
4574 COPYNN(s, &aushort, sizeof(unsigned short));
4575 s += sizeof(unsigned short);
4576 sv = NEWSV(39, 0);
726ea183 4577 sv_setiv(sv, (UV)aushort);
ef54e1a4
JH
4578 PUSHs(sv_2mortal(sv));
4579 }
4580 }
726ea183
JH
4581 else
4582#endif
4583 {
ef54e1a4
JH
4584 while (len-- > 0) {
4585 COPY16(s, &aushort);
4586 s += SIZE16;
4587 sv = NEWSV(39, 0);
a0d0e21e 4588#ifdef HAS_NTOHS
ef54e1a4
JH
4589 if (datumtype == 'n')
4590 aushort = PerlSock_ntohs(aushort);
79072805 4591#endif
a0d0e21e 4592#ifdef HAS_VTOHS
ef54e1a4
JH
4593 if (datumtype == 'v')
4594 aushort = vtohs(aushort);
79072805 4595#endif
726ea183 4596 sv_setiv(sv, (UV)aushort);
ef54e1a4
JH
4597 PUSHs(sv_2mortal(sv));
4598 }
a0d0e21e
LW
4599 }
4600 }
4601 break;
4602 case 'i':
4603 along = (strend - s) / sizeof(int);
4604 if (len > along)
4605 len = along;
4606 if (checksum) {
4607 while (len-- > 0) {
4608 Copy(s, &aint, 1, int);
4609 s += sizeof(int);
4610 if (checksum > 32)
65202027 4611 cdouble += (NV)aint;
a0d0e21e
LW
4612 else
4613 culong += aint;
4614 }
4615 }
4616 else {
4617 EXTEND(SP, len);
bbce6d69 4618 EXTEND_MORTAL(len);
a0d0e21e
LW
4619 while (len-- > 0) {
4620 Copy(s, &aint, 1, int);
4621 s += sizeof(int);
4622 sv = NEWSV(40, 0);
20408e3c
GS
4623#ifdef __osf__
4624 /* Without the dummy below unpack("i", pack("i",-1))
4625 * return 0xFFffFFff instead of -1 for Digital Unix V4.0
13476c87
JH
4626 * cc with optimization turned on.
4627 *
4628 * The bug was detected in
4629 * DEC C V5.8-009 on Digital UNIX V4.0 (Rev. 1091) (V4.0E)
4630 * with optimization (-O4) turned on.
4631 * DEC C V5.2-040 on Digital UNIX V4.0 (Rev. 564) (V4.0B)
4632 * does not have this problem even with -O4.
4633 *
4634 * This bug was reported as DECC_BUGS 1431
4635 * and tracked internally as GEM_BUGS 7775.
4636 *
4637 * The bug is fixed in
4638 * Tru64 UNIX V5.0: Compaq C V6.1-006 or later
4639 * UNIX V4.0F support: DEC C V5.9-006 or later
4640 * UNIX V4.0E support: DEC C V5.8-011 or later
4641 * and also in DTK.
4642 *
4643 * See also few lines later for the same bug.
4644 */
20408e3c
GS
4645 (aint) ?
4646 sv_setiv(sv, (IV)aint) :
4647#endif
1e422769 4648 sv_setiv(sv, (IV)aint);
a0d0e21e
LW
4649 PUSHs(sv_2mortal(sv));
4650 }
4651 }
4652 break;
4653 case 'I':
4654 along = (strend - s) / sizeof(unsigned int);
4655 if (len > along)
4656 len = along;
4657 if (checksum) {
4658 while (len-- > 0) {
4659 Copy(s, &auint, 1, unsigned int);
4660 s += sizeof(unsigned int);
4661 if (checksum > 32)
65202027 4662 cdouble += (NV)auint;
a0d0e21e
LW
4663 else
4664 culong += auint;
4665 }
4666 }
4667 else {
4668 EXTEND(SP, len);
bbce6d69 4669 EXTEND_MORTAL(len);
a0d0e21e
LW
4670 while (len-- > 0) {
4671 Copy(s, &auint, 1, unsigned int);
4672 s += sizeof(unsigned int);
4673 sv = NEWSV(41, 0);
9d645a59
AB
4674#ifdef __osf__
4675 /* Without the dummy below unpack("I", pack("I",0xFFFFFFFF))
13476c87
JH
4676 * returns 1.84467440737096e+19 instead of 0xFFFFFFFF.
4677 * See details few lines earlier. */
9d645a59
AB
4678 (auint) ?
4679 sv_setuv(sv, (UV)auint) :
4680#endif
1e422769 4681 sv_setuv(sv, (UV)auint);
a0d0e21e
LW
4682 PUSHs(sv_2mortal(sv));
4683 }
4684 }
4685 break;
4686 case 'l':
726ea183
JH
4687#if LONGSIZE == SIZE32
4688 along = (strend - s) / SIZE32;
4689#else
ef54e1a4 4690 along = (strend - s) / (natint ? sizeof(long) : SIZE32);
726ea183 4691#endif
a0d0e21e
LW
4692 if (len > along)
4693 len = along;
4694 if (checksum) {
726ea183 4695#if LONGSIZE != SIZE32
ef54e1a4
JH
4696 if (natint) {
4697 while (len-- > 0) {
4698 COPYNN(s, &along, sizeof(long));
4699 s += sizeof(long);
4700 if (checksum > 32)
65202027 4701 cdouble += (NV)along;
ef54e1a4
JH
4702 else
4703 culong += along;
4704 }
4705 }
726ea183
JH
4706 else
4707#endif
4708 {
ef54e1a4 4709 while (len-- > 0) {
2f3a5373
JH
4710#if LONGSIZE > SIZE32 && INTSIZE == SIZE32
4711 I32 along;
4712#endif
ef54e1a4 4713 COPY32(s, &along);
c67712b2
JH
4714#if LONGSIZE > SIZE32
4715 if (along > 2147483647)
4716 along -= 4294967296;
4717#endif
ef54e1a4
JH
4718 s += SIZE32;
4719 if (checksum > 32)
65202027 4720 cdouble += (NV)along;
ef54e1a4
JH
4721 else
4722 culong += along;
4723 }
a0d0e21e
LW
4724 }
4725 }
4726 else {
4727 EXTEND(SP, len);
bbce6d69 4728 EXTEND_MORTAL(len);
726ea183 4729#if LONGSIZE != SIZE32
ef54e1a4
JH
4730 if (natint) {
4731 while (len-- > 0) {
4732 COPYNN(s, &along, sizeof(long));
4733 s += sizeof(long);
4734 sv = NEWSV(42, 0);
4735 sv_setiv(sv, (IV)along);
4736 PUSHs(sv_2mortal(sv));
4737 }
4738 }
726ea183
JH
4739 else
4740#endif
4741 {
ef54e1a4 4742 while (len-- > 0) {
2f3a5373
JH
4743#if LONGSIZE > SIZE32 && INTSIZE == SIZE32
4744 I32 along;
4745#endif
ef54e1a4 4746 COPY32(s, &along);
c67712b2
JH
4747#if LONGSIZE > SIZE32
4748 if (along > 2147483647)
4749 along -= 4294967296;
4750#endif
ef54e1a4
JH
4751 s += SIZE32;
4752 sv = NEWSV(42, 0);
4753 sv_setiv(sv, (IV)along);
4754 PUSHs(sv_2mortal(sv));
4755 }
a0d0e21e 4756 }
79072805 4757 }
a0d0e21e
LW
4758 break;
4759 case 'V':
4760 case 'N':
4761 case 'L':
726ea183
JH
4762#if LONGSIZE == SIZE32
4763 along = (strend - s) / SIZE32;
4764#else
4765 unatint = natint && datumtype == 'L';
ef54e1a4 4766 along = (strend - s) / (unatint ? sizeof(unsigned long) : SIZE32);
726ea183 4767#endif
a0d0e21e
LW
4768 if (len > along)
4769 len = along;
4770 if (checksum) {
726ea183 4771#if LONGSIZE != SIZE32
ef54e1a4 4772 if (unatint) {
bf9315bb 4773 unsigned long aulong;
ef54e1a4
JH
4774 while (len-- > 0) {
4775 COPYNN(s, &aulong, sizeof(unsigned long));
4776 s += sizeof(unsigned long);
4777 if (checksum > 32)
65202027 4778 cdouble += (NV)aulong;
ef54e1a4
JH
4779 else
4780 culong += aulong;
4781 }
4782 }
726ea183
JH
4783 else
4784#endif
4785 {
ef54e1a4
JH
4786 while (len-- > 0) {
4787 COPY32(s, &aulong);
4788 s += SIZE32;
a0d0e21e 4789#ifdef HAS_NTOHL
ef54e1a4
JH
4790 if (datumtype == 'N')
4791 aulong = PerlSock_ntohl(aulong);
79072805 4792#endif
a0d0e21e 4793#ifdef HAS_VTOHL
ef54e1a4
JH
4794 if (datumtype == 'V')
4795 aulong = vtohl(aulong);
79072805 4796#endif
ef54e1a4 4797 if (checksum > 32)
65202027 4798 cdouble += (NV)aulong;
ef54e1a4
JH
4799 else
4800 culong += aulong;
4801 }
a0d0e21e
LW
4802 }
4803 }
4804 else {
4805 EXTEND(SP, len);
bbce6d69 4806 EXTEND_MORTAL(len);
726ea183 4807#if LONGSIZE != SIZE32
ef54e1a4 4808 if (unatint) {
bf9315bb 4809 unsigned long aulong;
ef54e1a4
JH
4810 while (len-- > 0) {
4811 COPYNN(s, &aulong, sizeof(unsigned long));
4812 s += sizeof(unsigned long);
4813 sv = NEWSV(43, 0);
4814 sv_setuv(sv, (UV)aulong);
4815 PUSHs(sv_2mortal(sv));
4816 }
4817 }
726ea183
JH
4818 else
4819#endif
4820 {
ef54e1a4
JH
4821 while (len-- > 0) {
4822 COPY32(s, &aulong);
4823 s += SIZE32;
a0d0e21e 4824#ifdef HAS_NTOHL
ef54e1a4
JH
4825 if (datumtype == 'N')
4826 aulong = PerlSock_ntohl(aulong);
79072805 4827#endif
a0d0e21e 4828#ifdef HAS_VTOHL
ef54e1a4
JH
4829 if (datumtype == 'V')
4830 aulong = vtohl(aulong);
79072805 4831#endif
ef54e1a4
JH
4832 sv = NEWSV(43, 0);
4833 sv_setuv(sv, (UV)aulong);
4834 PUSHs(sv_2mortal(sv));
4835 }
a0d0e21e
LW
4836 }
4837 }
4838 break;
4839 case 'p':
4840 along = (strend - s) / sizeof(char*);
4841 if (len > along)
4842 len = along;
4843 EXTEND(SP, len);
bbce6d69 4844 EXTEND_MORTAL(len);
a0d0e21e
LW
4845 while (len-- > 0) {
4846 if (sizeof(char*) > strend - s)
4847 break;
4848 else {
4849 Copy(s, &aptr, 1, char*);
4850 s += sizeof(char*);
4851 }
4852 sv = NEWSV(44, 0);
4853 if (aptr)
4854 sv_setpv(sv, aptr);
4855 PUSHs(sv_2mortal(sv));
4856 }
4857 break;
def98dd4 4858 case 'w':
def98dd4 4859 EXTEND(SP, len);
bbce6d69 4860 EXTEND_MORTAL(len);
8ec5e241 4861 {
bbce6d69 4862 UV auv = 0;
4863 U32 bytes = 0;
4864
4865 while ((len > 0) && (s < strend)) {
4866 auv = (auv << 7) | (*s & 0x7f);
d742c382
NIS
4867 /* UTF8_IS_XXXXX not right here - using constant 0x80 */
4868 if ((U8)(*s++) < 0x80) {
bbce6d69 4869 bytes = 0;
4870 sv = NEWSV(40, 0);
4871 sv_setuv(sv, auv);
4872 PUSHs(sv_2mortal(sv));
4873 len--;
4874 auv = 0;
4875 }
4876 else if (++bytes >= sizeof(UV)) { /* promote to string */
bbce6d69 4877 char *t;
2d8e6c8d 4878 STRLEN n_a;
bbce6d69 4879
d2560b70 4880 sv = Perl_newSVpvf(aTHX_ "%.*"UVf, (int)TYPE_DIGITS(UV), auv);
bbce6d69 4881 while (s < strend) {
4882 sv = mul128(sv, *s & 0x7f);
4883 if (!(*s++ & 0x80)) {
4884 bytes = 0;
4885 break;
4886 }
4887 }
2d8e6c8d 4888 t = SvPV(sv, n_a);
bbce6d69 4889 while (*t == '0')
4890 t++;
4891 sv_chop(sv, t);
4892 PUSHs(sv_2mortal(sv));
4893 len--;
4894 auv = 0;
4895 }
4896 }
4897 if ((s >= strend) && bytes)
d470f89e 4898 DIE(aTHX_ "Unterminated compressed integer");
bbce6d69 4899 }
def98dd4 4900 break;
a0d0e21e
LW
4901 case 'P':
4902 EXTEND(SP, 1);
4903 if (sizeof(char*) > strend - s)
4904 break;
4905 else {
4906 Copy(s, &aptr, 1, char*);
4907 s += sizeof(char*);
4908 }
4909 sv = NEWSV(44, 0);
4910 if (aptr)
4911 sv_setpvn(sv, aptr, len);
4912 PUSHs(sv_2mortal(sv));
4913 break;
6b8eaf93 4914#ifdef HAS_QUAD
a0d0e21e 4915 case 'q':
d4217c7e
JH
4916 along = (strend - s) / sizeof(Quad_t);
4917 if (len > along)
4918 len = along;
a0d0e21e 4919 EXTEND(SP, len);
bbce6d69 4920 EXTEND_MORTAL(len);
a0d0e21e 4921 while (len-- > 0) {
ecfc5424 4922 if (s + sizeof(Quad_t) > strend)
a0d0e21e
LW
4923 aquad = 0;
4924 else {
ecfc5424
AD
4925 Copy(s, &aquad, 1, Quad_t);
4926 s += sizeof(Quad_t);
a0d0e21e
LW
4927 }
4928 sv = NEWSV(42, 0);
96e4d5b1 4929 if (aquad >= IV_MIN && aquad <= IV_MAX)
4930 sv_setiv(sv, (IV)aquad);
4931 else
65202027 4932 sv_setnv(sv, (NV)aquad);
a0d0e21e
LW
4933 PUSHs(sv_2mortal(sv));
4934 }
4935 break;
4936 case 'Q':
d4217c7e
JH
4937 along = (strend - s) / sizeof(Quad_t);
4938 if (len > along)
4939 len = along;
a0d0e21e 4940 EXTEND(SP, len);
bbce6d69 4941 EXTEND_MORTAL(len);
a0d0e21e 4942 while (len-- > 0) {
e862df63 4943 if (s + sizeof(Uquad_t) > strend)
a0d0e21e
LW
4944 auquad = 0;
4945 else {
e862df63
HB
4946 Copy(s, &auquad, 1, Uquad_t);
4947 s += sizeof(Uquad_t);
a0d0e21e
LW
4948 }
4949 sv = NEWSV(43, 0);
27612d38 4950 if (auquad <= UV_MAX)
96e4d5b1 4951 sv_setuv(sv, (UV)auquad);
4952 else
65202027 4953 sv_setnv(sv, (NV)auquad);
a0d0e21e
LW
4954 PUSHs(sv_2mortal(sv));
4955 }
4956 break;
79072805 4957#endif
a0d0e21e
LW
4958 /* float and double added gnb@melba.bby.oz.au 22/11/89 */
4959 case 'f':
4960 case 'F':
4961 along = (strend - s) / sizeof(float);
4962 if (len > along)
4963 len = along;
4964 if (checksum) {
4965 while (len-- > 0) {
4966 Copy(s, &afloat, 1, float);
4967 s += sizeof(float);
4968 cdouble += afloat;
4969 }
4970 }
4971 else {
4972 EXTEND(SP, len);
bbce6d69 4973 EXTEND_MORTAL(len);
a0d0e21e
LW
4974 while (len-- > 0) {
4975 Copy(s, &afloat, 1, float);
4976 s += sizeof(float);
4977 sv = NEWSV(47, 0);
65202027 4978 sv_setnv(sv, (NV)afloat);
a0d0e21e
LW
4979 PUSHs(sv_2mortal(sv));
4980 }
4981 }
4982 break;
4983 case 'd':
4984 case 'D':
4985 along = (strend - s) / sizeof(double);
4986 if (len > along)
4987 len = along;
4988 if (checksum) {
4989 while (len-- > 0) {
4990 Copy(s, &adouble, 1, double);
4991 s += sizeof(double);
4992 cdouble += adouble;
4993 }
4994 }
4995 else {
4996 EXTEND(SP, len);
bbce6d69 4997 EXTEND_MORTAL(len);
a0d0e21e
LW
4998 while (len-- > 0) {
4999 Copy(s, &adouble, 1, double);
5000 s += sizeof(double);
5001 sv = NEWSV(48, 0);
65202027 5002 sv_setnv(sv, (NV)adouble);
a0d0e21e
LW
5003 PUSHs(sv_2mortal(sv));
5004 }
5005 }
5006 break;
5007 case 'u':
9d116dd7
JH
5008 /* MKS:
5009 * Initialise the decode mapping. By using a table driven
5010 * algorithm, the code will be character-set independent
5011 * (and just as fast as doing character arithmetic)
5012 */
80252599 5013 if (PL_uudmap['M'] == 0) {
9d116dd7 5014 int i;
b13b2135 5015
80252599 5016 for (i = 0; i < sizeof(PL_uuemap); i += 1)
155aba94 5017 PL_uudmap[(U8)PL_uuemap[i]] = i;
9d116dd7
JH
5018 /*
5019 * Because ' ' and '`' map to the same value,
5020 * we need to decode them both the same.
5021 */
80252599 5022 PL_uudmap[' '] = 0;
9d116dd7
JH
5023 }
5024
a0d0e21e
LW
5025 along = (strend - s) * 3 / 4;
5026 sv = NEWSV(42, along);
f12c7020 5027 if (along)
5028 SvPOK_on(sv);
9d116dd7 5029 while (s < strend && *s > ' ' && ISUUCHAR(*s)) {
a0d0e21e
LW
5030 I32 a, b, c, d;
5031 char hunk[4];
79072805 5032
a0d0e21e 5033 hunk[3] = '\0';
155aba94 5034 len = PL_uudmap[*(U8*)s++] & 077;
a0d0e21e 5035 while (len > 0) {
9d116dd7 5036 if (s < strend && ISUUCHAR(*s))
155aba94 5037 a = PL_uudmap[*(U8*)s++] & 077;
9d116dd7
JH
5038 else
5039 a = 0;
5040 if (s < strend && ISUUCHAR(*s))
155aba94 5041 b = PL_uudmap[*(U8*)s++] & 077;
9d116dd7
JH
5042 else
5043 b = 0;
5044 if (s < strend && ISUUCHAR(*s))
155aba94 5045 c = PL_uudmap[*(U8*)s++] & 077;
9d116dd7
JH
5046 else
5047 c = 0;
5048 if (s < strend && ISUUCHAR(*s))
155aba94 5049 d = PL_uudmap[*(U8*)s++] & 077;
a0d0e21e
LW
5050 else
5051 d = 0;
4e35701f
NIS
5052 hunk[0] = (a << 2) | (b >> 4);
5053 hunk[1] = (b << 4) | (c >> 2);
5054 hunk[2] = (c << 6) | d;
5055 sv_catpvn(sv, hunk, (len > 3) ? 3 : len);
a0d0e21e
LW
5056 len -= 3;
5057 }
5058 if (*s == '\n')
5059 s++;
5060 else if (s[1] == '\n') /* possible checksum byte */
5061 s += 2;
79072805 5062 }
a0d0e21e
LW
5063 XPUSHs(sv_2mortal(sv));
5064 break;
79072805 5065 }
a0d0e21e
LW
5066 if (checksum) {
5067 sv = NEWSV(42, 0);
5068 if (strchr("fFdD", datumtype) ||
32d8b6e5 5069 (checksum > 32 && strchr("iIlLNU", datumtype)) ) {
65202027 5070 NV trouble;
79072805 5071
a0d0e21e
LW
5072 adouble = 1.0;
5073 while (checksum >= 16) {
5074 checksum -= 16;
5075 adouble *= 65536.0;
5076 }
5077 while (checksum >= 4) {
5078 checksum -= 4;
5079 adouble *= 16.0;
5080 }
5081 while (checksum--)
5082 adouble *= 2.0;
5083 along = (1 << checksum) - 1;
5084 while (cdouble < 0.0)
5085 cdouble += adouble;
65202027 5086 cdouble = Perl_modf(cdouble / adouble, &trouble) * adouble;
a0d0e21e
LW
5087 sv_setnv(sv, cdouble);
5088 }
5089 else {
5090 if (checksum < 32) {
96e4d5b1 5091 aulong = (1 << checksum) - 1;
5092 culong &= aulong;
a0d0e21e 5093 }
96e4d5b1 5094 sv_setuv(sv, (UV)culong);
a0d0e21e
LW
5095 }
5096 XPUSHs(sv_2mortal(sv));
5097 checksum = 0;
79072805 5098 }
79072805 5099 }
dd58a1ab 5100 if (SP - PL_stack_base == start_sp_offset && gimme == G_SCALAR)
3280af22 5101 PUSHs(&PL_sv_undef);
79072805 5102 RETURN;
79072805
LW
5103}
5104
76e3520e 5105STATIC void
cea2e8a9 5106S_doencodes(pTHX_ register SV *sv, register char *s, register I32 len)
79072805 5107{
a0d0e21e 5108 char hunk[5];
79072805 5109
80252599 5110 *hunk = PL_uuemap[len];
a0d0e21e
LW
5111 sv_catpvn(sv, hunk, 1);
5112 hunk[4] = '\0';
f264d472 5113 while (len > 2) {
80252599
GS
5114 hunk[0] = PL_uuemap[(077 & (*s >> 2))];
5115 hunk[1] = PL_uuemap[(077 & (((*s << 4) & 060) | ((s[1] >> 4) & 017)))];
5116 hunk[2] = PL_uuemap[(077 & (((s[1] << 2) & 074) | ((s[2] >> 6) & 03)))];
5117 hunk[3] = PL_uuemap[(077 & (s[2] & 077))];
a0d0e21e
LW
5118 sv_catpvn(sv, hunk, 4);
5119 s += 3;
5120 len -= 3;
5121 }
f264d472
GS
5122 if (len > 0) {
5123 char r = (len > 1 ? s[1] : '\0');
80252599
GS
5124 hunk[0] = PL_uuemap[(077 & (*s >> 2))];
5125 hunk[1] = PL_uuemap[(077 & (((*s << 4) & 060) | ((r >> 4) & 017)))];
5126 hunk[2] = PL_uuemap[(077 & ((r << 2) & 074))];
5127 hunk[3] = PL_uuemap[0];
f264d472 5128 sv_catpvn(sv, hunk, 4);
a0d0e21e
LW
5129 }
5130 sv_catpvn(sv, "\n", 1);
79072805
LW
5131}
5132
79cb57f6 5133STATIC SV *
cea2e8a9 5134S_is_an_int(pTHX_ char *s, STRLEN l)
55497cff 5135{
2d8e6c8d 5136 STRLEN n_a;
79cb57f6 5137 SV *result = newSVpvn(s, l);
2d8e6c8d 5138 char *result_c = SvPV(result, n_a); /* convenience */
55497cff 5139 char *out = result_c;
5140 bool skip = 1;
5141 bool ignore = 0;
5142
5143 while (*s) {
5144 switch (*s) {
5145 case ' ':
5146 break;
5147 case '+':
5148 if (!skip) {
5149 SvREFCNT_dec(result);
5150 return (NULL);
5151 }
5152 break;
5153 case '0':
5154 case '1':
5155 case '2':
5156 case '3':
5157 case '4':
5158 case '5':
5159 case '6':
5160 case '7':
5161 case '8':
5162 case '9':
5163 skip = 0;
5164 if (!ignore) {
5165 *(out++) = *s;
5166 }
5167 break;
5168 case '.':
5169 ignore = 1;
5170 break;
5171 default:
5172 SvREFCNT_dec(result);
5173 return (NULL);
5174 }
5175 s++;
5176 }
5177 *(out++) = '\0';
5178 SvCUR_set(result, out - result_c);
5179 return (result);
5180}
5181
864dbfa3 5182/* pnum must be '\0' terminated */
76e3520e 5183STATIC int
cea2e8a9 5184S_div128(pTHX_ SV *pnum, bool *done)
55497cff 5185{
5186 STRLEN len;
5187 char *s = SvPV(pnum, len);
5188 int m = 0;
5189 int r = 0;
5190 char *t = s;
5191
5192 *done = 1;
5193 while (*t) {
5194 int i;
5195
5196 i = m * 10 + (*t - '0');
5197 m = i & 0x7F;
5198 r = (i >> 7); /* r < 10 */
5199 if (r) {
5200 *done = 0;
5201 }
5202 *(t++) = '0' + r;
5203 }
5204 *(t++) = '\0';
5205 SvCUR_set(pnum, (STRLEN) (t - s));
5206 return (m);
5207}
5208
5209
a0d0e21e 5210PP(pp_pack)
79072805 5211{
39644a26 5212 dSP; dMARK; dORIGMARK; dTARGET;
a0d0e21e
LW
5213 register SV *cat = TARG;
5214 register I32 items;
5215 STRLEN fromlen;
5216 register char *pat = SvPVx(*++MARK, fromlen);
036b4402 5217 char *patcopy;
a0d0e21e
LW
5218 register char *patend = pat + fromlen;
5219 register I32 len;
5220 I32 datumtype;
5221 SV *fromstr;
5222 /*SUPPRESS 442*/
5223 static char null10[] = {0,0,0,0,0,0,0,0,0,0};
5224 static char *space10 = " ";
79072805 5225
a0d0e21e
LW
5226 /* These must not be in registers: */
5227 char achar;
5228 I16 ashort;
5229 int aint;
5230 unsigned int auint;
5231 I32 along;
5232 U32 aulong;
6b8eaf93 5233#ifdef HAS_QUAD
ecfc5424 5234 Quad_t aquad;
e862df63 5235 Uquad_t auquad;
79072805 5236#endif
a0d0e21e
LW
5237 char *aptr;
5238 float afloat;
5239 double adouble;
fb73857a 5240 int commas = 0;
726ea183 5241#ifdef PERL_NATINT_PACK
ef54e1a4 5242 int natint; /* native integer */
726ea183 5243#endif
79072805 5244
a0d0e21e
LW
5245 items = SP - MARK;
5246 MARK++;
5247 sv_setpvn(cat, "", 0);
036b4402 5248 patcopy = pat;
a0d0e21e 5249 while (pat < patend) {
43192e07
IP
5250 SV *lengthcode = Nullsv;
5251#define NEXTFROM ( lengthcode ? lengthcode : items-- > 0 ? *MARK++ : &PL_sv_no)
bbdab043 5252 datumtype = *pat++ & 0xFF;
726ea183 5253#ifdef PERL_NATINT_PACK
ef54e1a4 5254 natint = 0;
726ea183 5255#endif
036b4402
GS
5256 if (isSPACE(datumtype)) {
5257 patcopy++;
bbdab043 5258 continue;
036b4402 5259 }
d815558d 5260#ifndef PACKED_IS_OCTETS
b13b2135 5261 if (datumtype == 'U' && pat == patcopy+1)
036b4402 5262 SvUTF8_on(cat);
d815558d 5263#endif
17f4a12d
IZ
5264 if (datumtype == '#') {
5265 while (pat < patend && *pat != '\n')
5266 pat++;
5267 continue;
5268 }
f61d411c 5269 if (*pat == '!') {
ef54e1a4
JH
5270 char *natstr = "sSiIlL";
5271
5272 if (strchr(natstr, datumtype)) {
726ea183 5273#ifdef PERL_NATINT_PACK
ef54e1a4 5274 natint = 1;
726ea183 5275#endif
ef54e1a4
JH
5276 pat++;
5277 }
5278 else
d470f89e 5279 DIE(aTHX_ "'!' allowed only after types %s", natstr);
ef54e1a4 5280 }
a0d0e21e
LW
5281 if (*pat == '*') {
5282 len = strchr("@Xxu", datumtype) ? 0 : items;
5283 pat++;
5284 }
5285 else if (isDIGIT(*pat)) {
5286 len = *pat++ - '0';
06387354 5287 while (isDIGIT(*pat)) {
a0d0e21e 5288 len = (len * 10) + (*pat++ - '0');
06387354 5289 if (len < 0)
d470f89e 5290 DIE(aTHX_ "Repeat count in pack overflows");
06387354 5291 }
a0d0e21e
LW
5292 }
5293 else
5294 len = 1;
17f4a12d 5295 if (*pat == '/') {
43192e07 5296 ++pat;
155aba94 5297 if ((*pat != 'a' && *pat != 'A' && *pat != 'Z') || pat[1] != '*')
17f4a12d 5298 DIE(aTHX_ "/ must be followed by a*, A* or Z*");
43192e07 5299 lengthcode = sv_2mortal(newSViv(sv_len(items > 0
3399f041
GS
5300 ? *MARK : &PL_sv_no)
5301 + (*pat == 'Z' ? 1 : 0)));
43192e07 5302 }
a0d0e21e
LW
5303 switch(datumtype) {
5304 default:
d470f89e 5305 DIE(aTHX_ "Invalid type in pack: '%c'", (int)datumtype);
fb73857a 5306 case ',': /* grandfather in commas but with a warning */
e476b1b5
GS
5307 if (commas++ == 0 && ckWARN(WARN_PACK))
5308 Perl_warner(aTHX_ WARN_PACK,
43192e07 5309 "Invalid type in pack: '%c'", (int)datumtype);
fb73857a 5310 break;
a0d0e21e 5311 case '%':
cea2e8a9 5312 DIE(aTHX_ "%% may only be used in unpack");
a0d0e21e
LW
5313 case '@':
5314 len -= SvCUR(cat);
5315 if (len > 0)
5316 goto grow;
5317 len = -len;
5318 if (len > 0)
5319 goto shrink;
5320 break;
5321 case 'X':
5322 shrink:
5323 if (SvCUR(cat) < len)
cea2e8a9 5324 DIE(aTHX_ "X outside of string");
a0d0e21e
LW
5325 SvCUR(cat) -= len;
5326 *SvEND(cat) = '\0';
5327 break;
5328 case 'x':
5329 grow:
5330 while (len >= 10) {
5331 sv_catpvn(cat, null10, 10);
5332 len -= 10;
5333 }
5334 sv_catpvn(cat, null10, len);
5335 break;
5336 case 'A':
5a929a98 5337 case 'Z':
a0d0e21e
LW
5338 case 'a':
5339 fromstr = NEXTFROM;
5340 aptr = SvPV(fromstr, fromlen);
2b6c5635 5341 if (pat[-1] == '*') {
a0d0e21e 5342 len = fromlen;
2b6c5635
GS
5343 if (datumtype == 'Z')
5344 ++len;
5345 }
5346 if (fromlen >= len) {
a0d0e21e 5347 sv_catpvn(cat, aptr, len);
2b6c5635
GS
5348 if (datumtype == 'Z')
5349 *(SvEND(cat)-1) = '\0';
5350 }
a0d0e21e
LW
5351 else {
5352 sv_catpvn(cat, aptr, fromlen);
5353 len -= fromlen;
5354 if (datumtype == 'A') {
5355 while (len >= 10) {
5356 sv_catpvn(cat, space10, 10);
5357 len -= 10;
5358 }
5359 sv_catpvn(cat, space10, len);
5360 }
5361 else {
5362 while (len >= 10) {
5363 sv_catpvn(cat, null10, 10);
5364 len -= 10;
5365 }
5366 sv_catpvn(cat, null10, len);
5367 }
5368 }
5369 break;
5370 case 'B':
5371 case 'b':
5372 {
abdc5761 5373 register char *str;
a0d0e21e 5374 I32 saveitems;
79072805 5375
a0d0e21e
LW
5376 fromstr = NEXTFROM;
5377 saveitems = items;
abdc5761 5378 str = SvPV(fromstr, fromlen);
a0d0e21e
LW
5379 if (pat[-1] == '*')
5380 len = fromlen;
a0d0e21e
LW
5381 aint = SvCUR(cat);
5382 SvCUR(cat) += (len+7)/8;
5383 SvGROW(cat, SvCUR(cat) + 1);
5384 aptr = SvPVX(cat) + aint;
5385 if (len > fromlen)
5386 len = fromlen;
5387 aint = len;
5388 items = 0;
5389 if (datumtype == 'B') {
5390 for (len = 0; len++ < aint;) {
abdc5761 5391 items |= *str++ & 1;
a0d0e21e
LW
5392 if (len & 7)
5393 items <<= 1;
5394 else {
5395 *aptr++ = items & 0xff;
5396 items = 0;
5397 }
5398 }
5399 }
5400 else {
5401 for (len = 0; len++ < aint;) {
abdc5761 5402 if (*str++ & 1)
a0d0e21e
LW
5403 items |= 128;
5404 if (len & 7)
5405 items >>= 1;
5406 else {
5407 *aptr++ = items & 0xff;
5408 items = 0;
5409 }
5410 }
5411 }
5412 if (aint & 7) {
5413 if (datumtype == 'B')
5414 items <<= 7 - (aint & 7);
5415 else
5416 items >>= 7 - (aint & 7);
5417 *aptr++ = items & 0xff;
5418 }
abdc5761
GS
5419 str = SvPVX(cat) + SvCUR(cat);
5420 while (aptr <= str)
a0d0e21e 5421 *aptr++ = '\0';
79072805 5422
a0d0e21e
LW
5423 items = saveitems;
5424 }
5425 break;
5426 case 'H':
5427 case 'h':
5428 {
abdc5761 5429 register char *str;
a0d0e21e 5430 I32 saveitems;
79072805 5431
a0d0e21e
LW
5432 fromstr = NEXTFROM;
5433 saveitems = items;
abdc5761 5434 str = SvPV(fromstr, fromlen);
a0d0e21e
LW
5435 if (pat[-1] == '*')
5436 len = fromlen;
a0d0e21e
LW
5437 aint = SvCUR(cat);
5438 SvCUR(cat) += (len+1)/2;
5439 SvGROW(cat, SvCUR(cat) + 1);
5440 aptr = SvPVX(cat) + aint;
5441 if (len > fromlen)
5442 len = fromlen;
5443 aint = len;
5444 items = 0;
5445 if (datumtype == 'H') {
5446 for (len = 0; len++ < aint;) {
abdc5761
GS
5447 if (isALPHA(*str))
5448 items |= ((*str++ & 15) + 9) & 15;
a0d0e21e 5449 else
abdc5761 5450 items |= *str++ & 15;
a0d0e21e
LW
5451 if (len & 1)
5452 items <<= 4;
5453 else {
5454 *aptr++ = items & 0xff;
5455 items = 0;
5456 }
5457 }
5458 }
5459 else {
5460 for (len = 0; len++ < aint;) {
abdc5761
GS
5461 if (isALPHA(*str))
5462 items |= (((*str++ & 15) + 9) & 15) << 4;
a0d0e21e 5463 else
abdc5761 5464 items |= (*str++ & 15) << 4;
a0d0e21e
LW
5465 if (len & 1)
5466 items >>= 4;
5467 else {
5468 *aptr++ = items & 0xff;
5469 items = 0;
5470 }
5471 }
5472 }
5473 if (aint & 1)
5474 *aptr++ = items & 0xff;
abdc5761
GS
5475 str = SvPVX(cat) + SvCUR(cat);
5476 while (aptr <= str)
a0d0e21e 5477 *aptr++ = '\0';
79072805 5478
a0d0e21e
LW
5479 items = saveitems;
5480 }
5481 break;
494f3023 5482 case 'C':
a0d0e21e
LW
5483 case 'c':
5484 while (len-- > 0) {
5485 fromstr = NEXTFROM;
ac7cd81a
SC
5486 switch (datumtype) {
5487 case 'C':
5488 aint = SvIV(fromstr);
5489 if ((aint < 0 || aint > 255) &&
5490 ckWARN(WARN_PACK))
5491 Perl_warner(aTHX_ WARN_PACK,
5492 "Character in \"C\" format wrapped");
5493 achar = aint & 255;
5494 sv_catpvn(cat, &achar, sizeof(char));
5495 break;
5496 case 'c':
5497 aint = SvIV(fromstr);
5498 if ((aint < -128 || aint > 127) &&
5499 ckWARN(WARN_PACK))
5500 Perl_warner(aTHX_ WARN_PACK,
5501 "Character in \"c\" format wrapped");
5502 achar = aint & 255;
5503 sv_catpvn(cat, &achar, sizeof(char));
5504 break;
5505 }
a0d0e21e
LW
5506 }
5507 break;
a0ed51b3
LW
5508 case 'U':
5509 while (len-- > 0) {
5510 fromstr = NEXTFROM;
494f3023
JH
5511 auint = SvUV(fromstr);
5512 SvGROW(cat, SvCUR(cat) + UTF8_MAXLEN + 1);
9041c2e3 5513 SvCUR_set(cat, (char*)uvchr_to_utf8((U8*)SvEND(cat),auint)
dfe13c55 5514 - SvPVX(cat));
a0ed51b3
LW
5515 }
5516 *SvEND(cat) = '\0';
5517 break;
a0d0e21e
LW
5518 /* Float and double added by gnb@melba.bby.oz.au 22/11/89 */
5519 case 'f':
5520 case 'F':
5521 while (len-- > 0) {
5522 fromstr = NEXTFROM;
5523 afloat = (float)SvNV(fromstr);
5524 sv_catpvn(cat, (char *)&afloat, sizeof (float));
5525 }
5526 break;
5527 case 'd':
5528 case 'D':
5529 while (len-- > 0) {
5530 fromstr = NEXTFROM;
5531 adouble = (double)SvNV(fromstr);
5532 sv_catpvn(cat, (char *)&adouble, sizeof (double));
5533 }
5534 break;
5535 case 'n':
5536 while (len-- > 0) {
5537 fromstr = NEXTFROM;
5538 ashort = (I16)SvIV(fromstr);
5539#ifdef HAS_HTONS
6ad3d225 5540 ashort = PerlSock_htons(ashort);
79072805 5541#endif
96e4d5b1 5542 CAT16(cat, &ashort);
a0d0e21e
LW
5543 }
5544 break;
5545 case 'v':
5546 while (len-- > 0) {
5547 fromstr = NEXTFROM;
5548 ashort = (I16)SvIV(fromstr);
5549#ifdef HAS_HTOVS
5550 ashort = htovs(ashort);
79072805 5551#endif
96e4d5b1 5552 CAT16(cat, &ashort);
a0d0e21e
LW
5553 }
5554 break;
5555 case 'S':
726ea183 5556#if SHORTSIZE != SIZE16
ef54e1a4
JH
5557 if (natint) {
5558 unsigned short aushort;
5559
5560 while (len-- > 0) {
5561 fromstr = NEXTFROM;
5562 aushort = SvUV(fromstr);
5563 sv_catpvn(cat, (char *)&aushort, sizeof(unsigned short));
5564 }
5565 }
726ea183
JH
5566 else
5567#endif
5568 {
ef54e1a4
JH
5569 U16 aushort;
5570
5571 while (len-- > 0) {
5572 fromstr = NEXTFROM;
726ea183 5573 aushort = (U16)SvUV(fromstr);
ef54e1a4
JH
5574 CAT16(cat, &aushort);
5575 }
726ea183 5576
ef54e1a4
JH
5577 }
5578 break;
a0d0e21e 5579 case 's':
c67712b2 5580#if SHORTSIZE != SIZE16
ef54e1a4 5581 if (natint) {
bf9315bb
GS
5582 short ashort;
5583
ef54e1a4
JH
5584 while (len-- > 0) {
5585 fromstr = NEXTFROM;
5586 ashort = SvIV(fromstr);
5587 sv_catpvn(cat, (char *)&ashort, sizeof(short));
5588 }
5589 }
726ea183
JH
5590 else
5591#endif
5592 {
ef54e1a4
JH
5593 while (len-- > 0) {
5594 fromstr = NEXTFROM;
5595 ashort = (I16)SvIV(fromstr);
5596 CAT16(cat, &ashort);
5597 }
a0d0e21e
LW
5598 }
5599 break;
5600 case 'I':
5601 while (len-- > 0) {
5602 fromstr = NEXTFROM;
96e4d5b1 5603 auint = SvUV(fromstr);
a0d0e21e
LW
5604 sv_catpvn(cat, (char*)&auint, sizeof(unsigned int));
5605 }
5606 break;
def98dd4
UP
5607 case 'w':
5608 while (len-- > 0) {
bbce6d69 5609 fromstr = NEXTFROM;
65202027 5610 adouble = Perl_floor(SvNV(fromstr));
bbce6d69 5611
5612 if (adouble < 0)
d470f89e 5613 DIE(aTHX_ "Cannot compress negative numbers");
bbce6d69 5614
46fc3d4c 5615 if (
8bda1795
ML
5616#if UVSIZE > 4 && UVSIZE >= NVSIZE
5617 adouble <= 0xffffffff
ef2d312d 5618#else
8bda1795
ML
5619# ifdef CXUX_BROKEN_CONSTANT_CONVERT
5620 adouble <= UV_MAX_cxux
5621# else
46fc3d4c 5622 adouble <= UV_MAX
8bda1795 5623# endif
46fc3d4c 5624#endif
5625 )
5626 {
bbce6d69 5627 char buf[1 + sizeof(UV)];
5628 char *in = buf + sizeof(buf);
db7c17d7 5629 UV auv = U_V(adouble);
bbce6d69 5630
5631 do {
5632 *--in = (auv & 0x7f) | 0x80;
5633 auv >>= 7;
5634 } while (auv);
5635 buf[sizeof(buf) - 1] &= 0x7f; /* clear continue bit */
5636 sv_catpvn(cat, in, (buf + sizeof(buf)) - in);
5637 }
5638 else if (SvPOKp(fromstr)) { /* decimal string arithmetics */
5639 char *from, *result, *in;
5640 SV *norm;
5641 STRLEN len;
5642 bool done;
8ec5e241 5643
bbce6d69 5644 /* Copy string and check for compliance */
5645 from = SvPV(fromstr, len);
5646 if ((norm = is_an_int(from, len)) == NULL)
d470f89e 5647 DIE(aTHX_ "can compress only unsigned integer");
bbce6d69 5648
5649 New('w', result, len, char);
5650 in = result + len;
5651 done = FALSE;
5652 while (!done)
5653 *--in = div128(norm, &done) | 0x80;
5654 result[len - 1] &= 0x7F; /* clear continue bit */
5655 sv_catpvn(cat, in, (result + len) - in);
5f05dabc 5656 Safefree(result);
bbce6d69 5657 SvREFCNT_dec(norm); /* free norm */
def98dd4 5658 }
bbce6d69 5659 else if (SvNOKp(fromstr)) {
5660 char buf[sizeof(double) * 2]; /* 8/7 <= 2 */
5661 char *in = buf + sizeof(buf);
5662
5663 do {
5664 double next = floor(adouble / 128);
5665 *--in = (unsigned char)(adouble - (next * 128)) | 0x80;
acae6be1 5666 if (in <= buf) /* this cannot happen ;-) */
d470f89e 5667 DIE(aTHX_ "Cannot compress integer");
acae6be1 5668 in--;
bbce6d69 5669 adouble = next;
5670 } while (adouble > 0);
5671 buf[sizeof(buf) - 1] &= 0x7f; /* clear continue bit */
5672 sv_catpvn(cat, in, (buf + sizeof(buf)) - in);
5673 }
5674 else
d470f89e 5675 DIE(aTHX_ "Cannot compress non integer");
bbce6d69 5676 }
def98dd4 5677 break;
a0d0e21e
LW
5678 case 'i':
5679 while (len-- > 0) {
5680 fromstr = NEXTFROM;
5681 aint = SvIV(fromstr);
5682 sv_catpvn(cat, (char*)&aint, sizeof(int));
5683 }
5684 break;
5685 case 'N':
5686 while (len-- > 0) {
5687 fromstr = NEXTFROM;
96e4d5b1 5688 aulong = SvUV(fromstr);
a0d0e21e 5689#ifdef HAS_HTONL
6ad3d225 5690 aulong = PerlSock_htonl(aulong);
79072805 5691#endif
96e4d5b1 5692 CAT32(cat, &aulong);
a0d0e21e
LW
5693 }
5694 break;
5695 case 'V':
5696 while (len-- > 0) {
5697 fromstr = NEXTFROM;
96e4d5b1 5698 aulong = SvUV(fromstr);
a0d0e21e
LW
5699#ifdef HAS_HTOVL
5700 aulong = htovl(aulong);
79072805 5701#endif
96e4d5b1 5702 CAT32(cat, &aulong);
a0d0e21e
LW
5703 }
5704 break;
5705 case 'L':
726ea183 5706#if LONGSIZE != SIZE32
ef54e1a4 5707 if (natint) {
bf9315bb
GS
5708 unsigned long aulong;
5709
ef54e1a4
JH
5710 while (len-- > 0) {
5711 fromstr = NEXTFROM;
5712 aulong = SvUV(fromstr);
5713 sv_catpvn(cat, (char *)&aulong, sizeof(unsigned long));
5714 }
5715 }
726ea183
JH
5716 else
5717#endif
5718 {
ef54e1a4
JH
5719 while (len-- > 0) {
5720 fromstr = NEXTFROM;
5721 aulong = SvUV(fromstr);
5722 CAT32(cat, &aulong);
5723 }
a0d0e21e
LW
5724 }
5725 break;
5726 case 'l':
726ea183 5727#if LONGSIZE != SIZE32
ef54e1a4 5728 if (natint) {
bf9315bb
GS
5729 long along;
5730
ef54e1a4
JH
5731 while (len-- > 0) {
5732 fromstr = NEXTFROM;
5733 along = SvIV(fromstr);
5734 sv_catpvn(cat, (char *)&along, sizeof(long));
5735 }
5736 }
726ea183
JH
5737 else
5738#endif
5739 {
ef54e1a4
JH
5740 while (len-- > 0) {
5741 fromstr = NEXTFROM;
5742 along = SvIV(fromstr);
5743 CAT32(cat, &along);
5744 }
a0d0e21e
LW
5745 }
5746 break;
6b8eaf93 5747#ifdef HAS_QUAD
a0d0e21e
LW
5748 case 'Q':
5749 while (len-- > 0) {
5750 fromstr = NEXTFROM;
bf9315bb 5751 auquad = (Uquad_t)SvUV(fromstr);
e862df63 5752 sv_catpvn(cat, (char*)&auquad, sizeof(Uquad_t));
a0d0e21e
LW
5753 }
5754 break;
5755 case 'q':
5756 while (len-- > 0) {
5757 fromstr = NEXTFROM;
ecfc5424
AD
5758 aquad = (Quad_t)SvIV(fromstr);
5759 sv_catpvn(cat, (char*)&aquad, sizeof(Quad_t));
a0d0e21e
LW
5760 }
5761 break;
1b8cd678 5762#endif
a0d0e21e
LW
5763 case 'P':
5764 len = 1; /* assume SV is correct length */
5765 /* FALL THROUGH */
5766 case 'p':
5767 while (len-- > 0) {
5768 fromstr = NEXTFROM;
3280af22 5769 if (fromstr == &PL_sv_undef)
84902520 5770 aptr = NULL;
72dbcb4b 5771 else {
2d8e6c8d 5772 STRLEN n_a;
84902520
TB
5773 /* XXX better yet, could spirit away the string to
5774 * a safe spot and hang on to it until the result
5775 * of pack() (and all copies of the result) are
5776 * gone.
5777 */
e476b1b5 5778 if (ckWARN(WARN_PACK) && (SvTEMP(fromstr)
014822e4
GS
5779 || (SvPADTMP(fromstr)
5780 && !SvREADONLY(fromstr))))
5781 {
e476b1b5 5782 Perl_warner(aTHX_ WARN_PACK,
599cee73 5783 "Attempt to pack pointer to temporary value");
014822e4 5784 }
84902520 5785 if (SvPOK(fromstr) || SvNIOK(fromstr))
2d8e6c8d 5786 aptr = SvPV(fromstr,n_a);
84902520 5787 else
2d8e6c8d 5788 aptr = SvPV_force(fromstr,n_a);
72dbcb4b 5789 }
a0d0e21e
LW
5790 sv_catpvn(cat, (char*)&aptr, sizeof(char*));
5791 }
5792 break;
5793 case 'u':
5794 fromstr = NEXTFROM;
5795 aptr = SvPV(fromstr, fromlen);
5796 SvGROW(cat, fromlen * 4 / 3);
5797 if (len <= 1)
5798 len = 45;
5799 else
5800 len = len / 3 * 3;
5801 while (fromlen > 0) {
5802 I32 todo;
79072805 5803
a0d0e21e
LW
5804 if (fromlen > len)
5805 todo = len;
5806 else
5807 todo = fromlen;
5808 doencodes(cat, aptr, todo);
5809 fromlen -= todo;
5810 aptr += todo;
5811 }
5812 break;
5813 }
5814 }
5815 SvSETMAGIC(cat);
5816 SP = ORIGMARK;
5817 PUSHs(cat);
5818 RETURN;
79072805 5819}
a0d0e21e 5820#undef NEXTFROM
79072805 5821
8ec5e241 5822
a0d0e21e 5823PP(pp_split)
79072805 5824{
39644a26 5825 dSP; dTARG;
a0d0e21e 5826 AV *ary;
467f0320 5827 register IV limit = POPi; /* note, negative is forever */
a0d0e21e
LW
5828 SV *sv = POPs;
5829 STRLEN len;
5830 register char *s = SvPV(sv, len);
1aa99e6b 5831 bool do_utf8 = DO_UTF8(sv);
a0d0e21e 5832 char *strend = s + len;
44a8e56a 5833 register PMOP *pm;
d9f97599 5834 register REGEXP *rx;
a0d0e21e
LW
5835 register SV *dstr;
5836 register char *m;
5837 I32 iters = 0;
792b2c16
JH
5838 STRLEN slen = do_utf8 ? utf8_length((U8*)s, (U8*)strend) : (strend - s);
5839 I32 maxiters = slen + 10;
a0d0e21e
LW
5840 I32 i;
5841 char *orig;
5842 I32 origlimit = limit;
5843 I32 realarray = 0;
5844 I32 base;
3280af22 5845 AV *oldstack = PL_curstack;
54310121 5846 I32 gimme = GIMME_V;
3280af22 5847 I32 oldsave = PL_savestack_ix;
8ec5e241
NIS
5848 I32 make_mortal = 1;
5849 MAGIC *mg = (MAGIC *) NULL;
79072805 5850
44a8e56a 5851#ifdef DEBUGGING
5852 Copy(&LvTARGOFF(POPs), &pm, 1, PMOP*);
5853#else
5854 pm = (PMOP*)POPs;
5855#endif
a0d0e21e 5856 if (!pm || !s)
2269b42e 5857 DIE(aTHX_ "panic: pp_split");
d9f97599 5858 rx = pm->op_pmregexp;
bbce6d69 5859
5860 TAINT_IF((pm->op_pmflags & PMf_LOCALE) &&
5861 (pm->op_pmflags & (PMf_WHITE | PMf_SKIPWHITE)));
5862
971a9dd3
GS
5863 if (pm->op_pmreplroot) {
5864#ifdef USE_ITHREADS
5865 ary = GvAVn((GV*)PL_curpad[(PADOFFSET)pm->op_pmreplroot]);
5866#else
a0d0e21e 5867 ary = GvAVn((GV*)pm->op_pmreplroot);
971a9dd3
GS
5868#endif
5869 }
a0d0e21e 5870 else if (gimme != G_ARRAY)
6d4ff0d2 5871#ifdef USE_THREADS
533c011a 5872 ary = (AV*)PL_curpad[0];
6d4ff0d2 5873#else
3280af22 5874 ary = GvAVn(PL_defgv);
6d4ff0d2 5875#endif /* USE_THREADS */
79072805 5876 else
a0d0e21e
LW
5877 ary = Nullav;
5878 if (ary && (gimme != G_ARRAY || (pm->op_pmflags & PMf_ONCE))) {
5879 realarray = 1;
8ec5e241 5880 PUTBACK;
a0d0e21e
LW
5881 av_extend(ary,0);
5882 av_clear(ary);
8ec5e241 5883 SPAGAIN;
14befaf4 5884 if ((mg = SvTIED_mg((SV*)ary, PERL_MAGIC_tied))) {
8ec5e241 5885 PUSHMARK(SP);
33c27489 5886 XPUSHs(SvTIED_obj((SV*)ary, mg));
8ec5e241
NIS
5887 }
5888 else {
1c0b011c
NIS
5889 if (!AvREAL(ary)) {
5890 AvREAL_on(ary);
abff13bb 5891 AvREIFY_off(ary);
1c0b011c 5892 for (i = AvFILLp(ary); i >= 0; i--)
3280af22 5893 AvARRAY(ary)[i] = &PL_sv_undef; /* don't free mere refs */
1c0b011c
NIS
5894 }
5895 /* temporarily switch stacks */
3280af22 5896 SWITCHSTACK(PL_curstack, ary);
8ec5e241 5897 make_mortal = 0;
1c0b011c 5898 }
79072805 5899 }
3280af22 5900 base = SP - PL_stack_base;
a0d0e21e
LW
5901 orig = s;
5902 if (pm->op_pmflags & PMf_SKIPWHITE) {
bbce6d69 5903 if (pm->op_pmflags & PMf_LOCALE) {
5904 while (isSPACE_LC(*s))
5905 s++;
5906 }
5907 else {
5908 while (isSPACE(*s))
5909 s++;
5910 }
a0d0e21e 5911 }
c07a80fd 5912 if (pm->op_pmflags & (PMf_MULTILINE|PMf_SINGLELINE)) {
3280af22
NIS
5913 SAVEINT(PL_multiline);
5914 PL_multiline = pm->op_pmflags & PMf_MULTILINE;
c07a80fd 5915 }
5916
a0d0e21e
LW
5917 if (!limit)
5918 limit = maxiters + 2;
5919 if (pm->op_pmflags & PMf_WHITE) {
5920 while (--limit) {
bbce6d69 5921 m = s;
5922 while (m < strend &&
5923 !((pm->op_pmflags & PMf_LOCALE)
5924 ? isSPACE_LC(*m) : isSPACE(*m)))
5925 ++m;
a0d0e21e
LW
5926 if (m >= strend)
5927 break;
bbce6d69 5928
a0d0e21e
LW
5929 dstr = NEWSV(30, m-s);
5930 sv_setpvn(dstr, s, m-s);
8ec5e241 5931 if (make_mortal)
a0d0e21e 5932 sv_2mortal(dstr);
792b2c16 5933 if (do_utf8)
28cb3359 5934 (void)SvUTF8_on(dstr);
a0d0e21e 5935 XPUSHs(dstr);
bbce6d69 5936
5937 s = m + 1;
5938 while (s < strend &&
5939 ((pm->op_pmflags & PMf_LOCALE)
5940 ? isSPACE_LC(*s) : isSPACE(*s)))
5941 ++s;
79072805
LW
5942 }
5943 }
f4091fba 5944 else if (strEQ("^", rx->precomp)) {
a0d0e21e
LW
5945 while (--limit) {
5946 /*SUPPRESS 530*/
5947 for (m = s; m < strend && *m != '\n'; m++) ;
5948 m++;
5949 if (m >= strend)
5950 break;
5951 dstr = NEWSV(30, m-s);
5952 sv_setpvn(dstr, s, m-s);
8ec5e241 5953 if (make_mortal)
a0d0e21e 5954 sv_2mortal(dstr);
792b2c16 5955 if (do_utf8)
28cb3359 5956 (void)SvUTF8_on(dstr);
a0d0e21e
LW
5957 XPUSHs(dstr);
5958 s = m;
5959 }
5960 }
699c3c34
JH
5961 else if (do_utf8 == ((rx->reganch & ROPT_UTF8) != 0) &&
5962 (rx->reganch & RE_USE_INTUIT) && !rx->nparens
d9f97599
GS
5963 && (rx->reganch & ROPT_CHECK_ALL)
5964 && !(rx->reganch & ROPT_ANCH)) {
f722798b
IZ
5965 int tail = (rx->reganch & RE_INTUIT_TAIL);
5966 SV *csv = CALLREG_INTUIT_STRING(aTHX_ rx);
cf93c79d 5967
ca5b42cb 5968 len = rx->minlen;
1aa99e6b 5969 if (len == 1 && !(rx->reganch & ROPT_UTF8) && !tail) {
93f04dac
JH
5970 STRLEN n_a;
5971 char c = *SvPV(csv, n_a);
a0d0e21e 5972 while (--limit) {
bbce6d69 5973 /*SUPPRESS 530*/
f722798b 5974 for (m = s; m < strend && *m != c; m++) ;
a0d0e21e
LW
5975 if (m >= strend)
5976 break;
5977 dstr = NEWSV(30, m-s);
5978 sv_setpvn(dstr, s, m-s);
8ec5e241 5979 if (make_mortal)
a0d0e21e 5980 sv_2mortal(dstr);
792b2c16 5981 if (do_utf8)
28cb3359 5982 (void)SvUTF8_on(dstr);
a0d0e21e 5983 XPUSHs(dstr);
93f04dac
JH
5984 /* The rx->minlen is in characters but we want to step
5985 * s ahead by bytes. */
1aa99e6b
IH
5986 if (do_utf8)
5987 s = (char*)utf8_hop((U8*)m, len);
5988 else
5989 s = m + len; /* Fake \n at the end */
a0d0e21e
LW
5990 }
5991 }
5992 else {
5993#ifndef lint
5994 while (s < strend && --limit &&
f722798b
IZ
5995 (m = fbm_instr((unsigned char*)s, (unsigned char*)strend,
5996 csv, PL_multiline ? FBMrf_MULTILINE : 0)) )
79072805 5997#endif
a0d0e21e
LW
5998 {
5999 dstr = NEWSV(31, m-s);
6000 sv_setpvn(dstr, s, m-s);
8ec5e241 6001 if (make_mortal)
a0d0e21e 6002 sv_2mortal(dstr);
792b2c16 6003 if (do_utf8)
28cb3359 6004 (void)SvUTF8_on(dstr);
a0d0e21e 6005 XPUSHs(dstr);
93f04dac
JH
6006 /* The rx->minlen is in characters but we want to step
6007 * s ahead by bytes. */
1aa99e6b
IH
6008 if (do_utf8)
6009 s = (char*)utf8_hop((U8*)m, len);
6010 else
6011 s = m + len; /* Fake \n at the end */
a0d0e21e 6012 }
463ee0b2 6013 }
463ee0b2 6014 }
a0d0e21e 6015 else {
792b2c16 6016 maxiters += slen * rx->nparens;
f722798b 6017 while (s < strend && --limit
b13b2135 6018/* && (!rx->check_substr
f722798b
IZ
6019 || ((s = CALLREG_INTUIT_START(aTHX_ rx, sv, s, strend,
6020 0, NULL))))
6021*/ && CALLREGEXEC(aTHX_ rx, s, strend, orig,
6022 1 /* minend */, sv, NULL, 0))
bbce6d69 6023 {
d9f97599 6024 TAINT_IF(RX_MATCH_TAINTED(rx));
cf93c79d 6025 if (RX_MATCH_COPIED(rx) && rx->subbeg != orig) {
a0d0e21e
LW
6026 m = s;
6027 s = orig;
cf93c79d 6028 orig = rx->subbeg;
a0d0e21e
LW
6029 s = orig + (m - s);
6030 strend = s + (strend - m);
6031 }
cf93c79d 6032 m = rx->startp[0] + orig;
a0d0e21e
LW
6033 dstr = NEWSV(32, m-s);
6034 sv_setpvn(dstr, s, m-s);
8ec5e241 6035 if (make_mortal)
a0d0e21e 6036 sv_2mortal(dstr);
792b2c16 6037 if (do_utf8)
28cb3359 6038 (void)SvUTF8_on(dstr);
a0d0e21e 6039 XPUSHs(dstr);
d9f97599
GS
6040 if (rx->nparens) {
6041 for (i = 1; i <= rx->nparens; i++) {
cf93c79d
IZ
6042 s = rx->startp[i] + orig;
6043 m = rx->endp[i] + orig;
748a9306
LW
6044 if (m && s) {
6045 dstr = NEWSV(33, m-s);
6046 sv_setpvn(dstr, s, m-s);
6047 }
6048 else
6049 dstr = NEWSV(33, 0);
8ec5e241 6050 if (make_mortal)
a0d0e21e 6051 sv_2mortal(dstr);
792b2c16 6052 if (do_utf8)
28cb3359 6053 (void)SvUTF8_on(dstr);
a0d0e21e
LW
6054 XPUSHs(dstr);
6055 }
6056 }
cf93c79d 6057 s = rx->endp[0] + orig;
a0d0e21e 6058 }
79072805 6059 }
8ec5e241 6060
c07a80fd 6061 LEAVE_SCOPE(oldsave);
3280af22 6062 iters = (SP - PL_stack_base) - base;
a0d0e21e 6063 if (iters > maxiters)
cea2e8a9 6064 DIE(aTHX_ "Split loop");
8ec5e241 6065
a0d0e21e
LW
6066 /* keep field after final delim? */
6067 if (s < strend || (iters && origlimit)) {
93f04dac
JH
6068 STRLEN l = strend - s;
6069 dstr = NEWSV(34, l);
6070 sv_setpvn(dstr, s, l);
8ec5e241 6071 if (make_mortal)
a0d0e21e 6072 sv_2mortal(dstr);
792b2c16 6073 if (do_utf8)
28cb3359 6074 (void)SvUTF8_on(dstr);
a0d0e21e
LW
6075 XPUSHs(dstr);
6076 iters++;
79072805 6077 }
a0d0e21e 6078 else if (!origlimit) {
b1dadf13 6079 while (iters > 0 && (!TOPs || !SvANY(TOPs) || SvCUR(TOPs) == 0))
a0d0e21e
LW
6080 iters--, SP--;
6081 }
8ec5e241 6082
a0d0e21e 6083 if (realarray) {
8ec5e241 6084 if (!mg) {
1c0b011c
NIS
6085 SWITCHSTACK(ary, oldstack);
6086 if (SvSMAGICAL(ary)) {
6087 PUTBACK;
6088 mg_set((SV*)ary);
6089 SPAGAIN;
6090 }
6091 if (gimme == G_ARRAY) {
6092 EXTEND(SP, iters);
6093 Copy(AvARRAY(ary), SP + 1, iters, SV*);
6094 SP += iters;
6095 RETURN;
6096 }
8ec5e241 6097 }
1c0b011c 6098 else {
fb73857a 6099 PUTBACK;
8ec5e241 6100 ENTER;
864dbfa3 6101 call_method("PUSH",G_SCALAR|G_DISCARD);
8ec5e241 6102 LEAVE;
fb73857a 6103 SPAGAIN;
8ec5e241
NIS
6104 if (gimme == G_ARRAY) {
6105 /* EXTEND should not be needed - we just popped them */
6106 EXTEND(SP, iters);
6107 for (i=0; i < iters; i++) {
6108 SV **svp = av_fetch(ary, i, FALSE);
3280af22 6109 PUSHs((svp) ? *svp : &PL_sv_undef);
8ec5e241 6110 }
1c0b011c
NIS
6111 RETURN;
6112 }
a0d0e21e
LW
6113 }
6114 }
6115 else {
6116 if (gimme == G_ARRAY)
6117 RETURN;
6118 }
6119 if (iters || !pm->op_pmreplroot) {
6120 GETTARGET;
6121 PUSHi(iters);
6122 RETURN;
6123 }
6124 RETPUSHUNDEF;
79072805 6125}
85e6fe83 6126
c0329465 6127#ifdef USE_THREADS
77a005ab 6128void
864dbfa3 6129Perl_unlock_condpair(pTHX_ void *svv)
c0329465 6130{
14befaf4 6131 MAGIC *mg = mg_find((SV*)svv, PERL_MAGIC_mutex);
8ec5e241 6132
c0329465 6133 if (!mg)
cea2e8a9 6134 Perl_croak(aTHX_ "panic: unlock_condpair unlocking non-mutex");
c0329465
MB
6135 MUTEX_LOCK(MgMUTEXP(mg));
6136 if (MgOWNER(mg) != thr)
cea2e8a9 6137 Perl_croak(aTHX_ "panic: unlock_condpair unlocking mutex that we don't own");
c0329465
MB
6138 MgOWNER(mg) = 0;
6139 COND_SIGNAL(MgOWNERCONDP(mg));
b900a521
JH
6140 DEBUG_S(PerlIO_printf(Perl_debug_log, "0x%"UVxf": unlock 0x%"UVxf"\n",
6141 PTR2UV(thr), PTR2UV(svv));)
c0329465
MB
6142 MUTEX_UNLOCK(MgMUTEXP(mg));
6143}
6144#endif /* USE_THREADS */
6145
6146PP(pp_lock)
6147{
39644a26 6148 dSP;
c0329465 6149 dTOPss;
e55aaa0e
MB
6150 SV *retsv = sv;
6151#ifdef USE_THREADS
4755096e 6152 sv_lock(sv);
c0329465 6153#endif /* USE_THREADS */
e55aaa0e
MB
6154 if (SvTYPE(retsv) == SVt_PVAV || SvTYPE(retsv) == SVt_PVHV
6155 || SvTYPE(retsv) == SVt_PVCV) {
6156 retsv = refto(retsv);
6157 }
6158 SETs(retsv);
c0329465
MB
6159 RETURN;
6160}
a863c7d1 6161
2faa37cc 6162PP(pp_threadsv)
a863c7d1 6163{
57d3b86d 6164#ifdef USE_THREADS
39644a26 6165 dSP;
924508f0 6166 EXTEND(SP, 1);
533c011a
NIS
6167 if (PL_op->op_private & OPpLVAL_INTRO)
6168 PUSHs(*save_threadsv(PL_op->op_targ));
554b3eca 6169 else
533c011a 6170 PUSHs(THREADSV(PL_op->op_targ));
fdb47d66 6171 RETURN;
a863c7d1 6172#else
cea2e8a9 6173 DIE(aTHX_ "tried to access per-thread data in non-threaded perl");
a863c7d1 6174#endif /* USE_THREADS */
a863c7d1 6175}