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