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