This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Make some panic messages a bit more logical.
[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;
bdeef251 2945 UV value;
7e2040f0 2946 SV *tmpsv = POPs;
ba210ebe
JH
2947 STRLEN len;
2948 U8 *tmps = (U8*)SvPVx(tmpsv, len);
2949 STRLEN retlen;
79072805 2950
7e2040f0 2951 if ((*tmps & 0x80) && DO_UTF8(tmpsv))
dcad2880 2952 value = utf8_to_uv(tmps, len, &retlen, 0);
a0ed51b3 2953 else
bdeef251
GA
2954 value = (UV)(*tmps & 255);
2955 XPUSHu(value);
79072805
LW
2956 RETURN;
2957}
2958
463ee0b2
LW
2959PP(pp_chr)
2960{
4e35701f 2961 djSP; dTARGET;
463ee0b2 2962 char *tmps;
467f0320 2963 UV value = POPu;
463ee0b2 2964
748a9306 2965 (void)SvUPGRADE(TARG,SVt_PV);
a0ed51b3 2966
aaa68c4a 2967 if ((value > 255 && !IN_BYTE) || (value & 0x80 && PL_hints & HINT_UTF8) ) {
aa6ffa16 2968 SvGROW(TARG, UTF8_MAXLEN+1);
a0ed51b3 2969 tmps = SvPVX(TARG);
dfe13c55 2970 tmps = (char*)uv_to_utf8((U8*)tmps, (UV)value);
a0ed51b3
LW
2971 SvCUR_set(TARG, tmps - SvPVX(TARG));
2972 *tmps = '\0';
2973 (void)SvPOK_only(TARG);
aa6ffa16 2974 SvUTF8_on(TARG);
a0ed51b3
LW
2975 XPUSHs(TARG);
2976 RETURN;
2977 }
2978
748a9306 2979 SvGROW(TARG,2);
463ee0b2
LW
2980 SvCUR_set(TARG, 1);
2981 tmps = SvPVX(TARG);
a0ed51b3 2982 *tmps++ = value;
748a9306 2983 *tmps = '\0';
a0d0e21e 2984 (void)SvPOK_only(TARG);
463ee0b2
LW
2985 XPUSHs(TARG);
2986 RETURN;
2987}
2988
79072805
LW
2989PP(pp_crypt)
2990{
4e35701f 2991 djSP; dTARGET; dPOPTOPssrl;
2d8e6c8d 2992 STRLEN n_a;
79072805 2993#ifdef HAS_CRYPT
2d8e6c8d 2994 char *tmps = SvPV(left, n_a);
79072805 2995#ifdef FCRYPT
2d8e6c8d 2996 sv_setpv(TARG, fcrypt(tmps, SvPV(right, n_a)));
79072805 2997#else
2d8e6c8d 2998 sv_setpv(TARG, PerlProc_crypt(tmps, SvPV(right, n_a)));
79072805
LW
2999#endif
3000#else
b13b2135 3001 DIE(aTHX_
79072805
LW
3002 "The crypt() function is unimplemented due to excessive paranoia.");
3003#endif
3004 SETs(TARG);
3005 RETURN;
3006}
3007
3008PP(pp_ucfirst)
3009{
4e35701f 3010 djSP;
79072805 3011 SV *sv = TOPs;
a0ed51b3
LW
3012 register U8 *s;
3013 STRLEN slen;
3014
7e2040f0 3015 if (DO_UTF8(sv) && (s = (U8*)SvPV(sv, slen)) && slen && (*s & 0xc0) == 0xc0) {
ba210ebe 3016 STRLEN ulen;
ad391ad9 3017 U8 tmpbuf[UTF8_MAXLEN+1];
a0ed51b3 3018 U8 *tend;
dcad2880 3019 UV uv = utf8_to_uv(s, slen, &ulen, 0);
a0ed51b3
LW
3020
3021 if (PL_op->op_private & OPpLOCALE) {
3022 TAINT;
3023 SvTAINTED_on(sv);
3024 uv = toTITLE_LC_uni(uv);
3025 }
3026 else
3027 uv = toTITLE_utf8(s);
3028
3029 tend = uv_to_utf8(tmpbuf, uv);
3030
014822e4 3031 if (!SvPADTMP(sv) || tend - tmpbuf != ulen || SvREADONLY(sv)) {
a0ed51b3 3032 dTARGET;
dfe13c55
GS
3033 sv_setpvn(TARG, (char*)tmpbuf, tend - tmpbuf);
3034 sv_catpvn(TARG, (char*)(s + ulen), slen - ulen);
7e2040f0 3035 SvUTF8_on(TARG);
a0ed51b3
LW
3036 SETs(TARG);
3037 }
3038 else {
dfe13c55 3039 s = (U8*)SvPV_force(sv, slen);
a0ed51b3
LW
3040 Copy(tmpbuf, s, ulen, U8);
3041 }
a0ed51b3 3042 }
626727d5 3043 else {
014822e4 3044 if (!SvPADTMP(sv) || SvREADONLY(sv)) {
31351b04 3045 dTARGET;
7e2040f0 3046 SvUTF8_off(TARG); /* decontaminate */
31351b04
JS
3047 sv_setsv(TARG, sv);
3048 sv = TARG;
3049 SETs(sv);
3050 }
3051 s = (U8*)SvPV_force(sv, slen);
3052 if (*s) {
3053 if (PL_op->op_private & OPpLOCALE) {
3054 TAINT;
3055 SvTAINTED_on(sv);
3056 *s = toUPPER_LC(*s);
3057 }
3058 else
3059 *s = toUPPER(*s);
bbce6d69 3060 }
bbce6d69 3061 }
31351b04
JS
3062 if (SvSMAGICAL(sv))
3063 mg_set(sv);
79072805
LW
3064 RETURN;
3065}
3066
3067PP(pp_lcfirst)
3068{
4e35701f 3069 djSP;
79072805 3070 SV *sv = TOPs;
a0ed51b3
LW
3071 register U8 *s;
3072 STRLEN slen;
3073
7e2040f0 3074 if (DO_UTF8(sv) && (s = (U8*)SvPV(sv, slen)) && slen && (*s & 0xc0) == 0xc0) {
ba210ebe 3075 STRLEN ulen;
ad391ad9 3076 U8 tmpbuf[UTF8_MAXLEN+1];
a0ed51b3 3077 U8 *tend;
dcad2880 3078 UV uv = utf8_to_uv(s, slen, &ulen, 0);
a0ed51b3
LW
3079
3080 if (PL_op->op_private & OPpLOCALE) {
3081 TAINT;
3082 SvTAINTED_on(sv);
3083 uv = toLOWER_LC_uni(uv);
3084 }
3085 else
3086 uv = toLOWER_utf8(s);
3087
3088 tend = uv_to_utf8(tmpbuf, uv);
3089
014822e4 3090 if (!SvPADTMP(sv) || tend - tmpbuf != ulen || SvREADONLY(sv)) {
a0ed51b3 3091 dTARGET;
dfe13c55
GS
3092 sv_setpvn(TARG, (char*)tmpbuf, tend - tmpbuf);
3093 sv_catpvn(TARG, (char*)(s + ulen), slen - ulen);
7e2040f0 3094 SvUTF8_on(TARG);
a0ed51b3
LW
3095 SETs(TARG);
3096 }
3097 else {
dfe13c55 3098 s = (U8*)SvPV_force(sv, slen);
a0ed51b3
LW
3099 Copy(tmpbuf, s, ulen, U8);
3100 }
a0ed51b3 3101 }
626727d5 3102 else {
014822e4 3103 if (!SvPADTMP(sv) || SvREADONLY(sv)) {
31351b04 3104 dTARGET;
7e2040f0 3105 SvUTF8_off(TARG); /* decontaminate */
31351b04
JS
3106 sv_setsv(TARG, sv);
3107 sv = TARG;
3108 SETs(sv);
3109 }
3110 s = (U8*)SvPV_force(sv, slen);
3111 if (*s) {
3112 if (PL_op->op_private & OPpLOCALE) {
3113 TAINT;
3114 SvTAINTED_on(sv);
3115 *s = toLOWER_LC(*s);
3116 }
3117 else
3118 *s = toLOWER(*s);
bbce6d69 3119 }
bbce6d69 3120 }
31351b04
JS
3121 if (SvSMAGICAL(sv))
3122 mg_set(sv);
79072805
LW
3123 RETURN;
3124}
3125
3126PP(pp_uc)
3127{
4e35701f 3128 djSP;
79072805 3129 SV *sv = TOPs;
a0ed51b3 3130 register U8 *s;
463ee0b2 3131 STRLEN len;
79072805 3132
7e2040f0 3133 if (DO_UTF8(sv)) {
a0ed51b3 3134 dTARGET;
ba210ebe 3135 STRLEN ulen;
a0ed51b3
LW
3136 register U8 *d;
3137 U8 *send;
3138
dfe13c55 3139 s = (U8*)SvPV(sv,len);
a5a20234 3140 if (!len) {
7e2040f0 3141 SvUTF8_off(TARG); /* decontaminate */
a5a20234
LW
3142 sv_setpvn(TARG, "", 0);
3143 SETs(TARG);
a0ed51b3
LW
3144 }
3145 else {
31351b04
JS
3146 (void)SvUPGRADE(TARG, SVt_PV);
3147 SvGROW(TARG, (len * 2) + 1);
3148 (void)SvPOK_only(TARG);
3149 d = (U8*)SvPVX(TARG);
3150 send = s + len;
3151 if (PL_op->op_private & OPpLOCALE) {
3152 TAINT;
3153 SvTAINTED_on(TARG);
3154 while (s < send) {
dcad2880 3155 d = uv_to_utf8(d, toUPPER_LC_uni( utf8_to_uv(s, len, &ulen, 0)));
31351b04
JS
3156 s += ulen;
3157 }
a0ed51b3 3158 }
31351b04
JS
3159 else {
3160 while (s < send) {
3161 d = uv_to_utf8(d, toUPPER_utf8( s ));
3162 s += UTF8SKIP(s);
3163 }
a0ed51b3 3164 }
31351b04 3165 *d = '\0';
7e2040f0 3166 SvUTF8_on(TARG);
31351b04
JS
3167 SvCUR_set(TARG, d - (U8*)SvPVX(TARG));
3168 SETs(TARG);
a0ed51b3 3169 }
a0ed51b3 3170 }
626727d5 3171 else {
014822e4 3172 if (!SvPADTMP(sv) || SvREADONLY(sv)) {
31351b04 3173 dTARGET;
7e2040f0 3174 SvUTF8_off(TARG); /* decontaminate */
31351b04
JS
3175 sv_setsv(TARG, sv);
3176 sv = TARG;
3177 SETs(sv);
3178 }
3179 s = (U8*)SvPV_force(sv, len);
3180 if (len) {
3181 register U8 *send = s + len;
3182
3183 if (PL_op->op_private & OPpLOCALE) {
3184 TAINT;
3185 SvTAINTED_on(sv);
3186 for (; s < send; s++)
3187 *s = toUPPER_LC(*s);
3188 }
3189 else {
3190 for (; s < send; s++)
3191 *s = toUPPER(*s);
3192 }
bbce6d69 3193 }
79072805 3194 }
31351b04
JS
3195 if (SvSMAGICAL(sv))
3196 mg_set(sv);
79072805
LW
3197 RETURN;
3198}
3199
3200PP(pp_lc)
3201{
4e35701f 3202 djSP;
79072805 3203 SV *sv = TOPs;
a0ed51b3 3204 register U8 *s;
463ee0b2 3205 STRLEN len;
79072805 3206
7e2040f0 3207 if (DO_UTF8(sv)) {
a0ed51b3 3208 dTARGET;
ba210ebe 3209 STRLEN ulen;
a0ed51b3
LW
3210 register U8 *d;
3211 U8 *send;
3212
dfe13c55 3213 s = (U8*)SvPV(sv,len);
a5a20234 3214 if (!len) {
7e2040f0 3215 SvUTF8_off(TARG); /* decontaminate */
a5a20234
LW
3216 sv_setpvn(TARG, "", 0);
3217 SETs(TARG);
a0ed51b3
LW
3218 }
3219 else {
31351b04
JS
3220 (void)SvUPGRADE(TARG, SVt_PV);
3221 SvGROW(TARG, (len * 2) + 1);
3222 (void)SvPOK_only(TARG);
3223 d = (U8*)SvPVX(TARG);
3224 send = s + len;
3225 if (PL_op->op_private & OPpLOCALE) {
3226 TAINT;
3227 SvTAINTED_on(TARG);
3228 while (s < send) {
dcad2880 3229 d = uv_to_utf8(d, toLOWER_LC_uni( utf8_to_uv(s, len, &ulen, 0)));
31351b04
JS
3230 s += ulen;
3231 }
a0ed51b3 3232 }
31351b04
JS
3233 else {
3234 while (s < send) {
3235 d = uv_to_utf8(d, toLOWER_utf8(s));
3236 s += UTF8SKIP(s);
3237 }
a0ed51b3 3238 }
31351b04 3239 *d = '\0';
7e2040f0 3240 SvUTF8_on(TARG);
31351b04
JS
3241 SvCUR_set(TARG, d - (U8*)SvPVX(TARG));
3242 SETs(TARG);
a0ed51b3 3243 }
79072805 3244 }
626727d5 3245 else {
014822e4 3246 if (!SvPADTMP(sv) || SvREADONLY(sv)) {
31351b04 3247 dTARGET;
7e2040f0 3248 SvUTF8_off(TARG); /* decontaminate */
31351b04
JS
3249 sv_setsv(TARG, sv);
3250 sv = TARG;
3251 SETs(sv);
a0ed51b3 3252 }
bbce6d69 3253
31351b04
JS
3254 s = (U8*)SvPV_force(sv, len);
3255 if (len) {
3256 register U8 *send = s + len;
bbce6d69 3257
31351b04
JS
3258 if (PL_op->op_private & OPpLOCALE) {
3259 TAINT;
3260 SvTAINTED_on(sv);
3261 for (; s < send; s++)
3262 *s = toLOWER_LC(*s);
3263 }
3264 else {
3265 for (; s < send; s++)
3266 *s = toLOWER(*s);
3267 }
bbce6d69 3268 }
79072805 3269 }
31351b04
JS
3270 if (SvSMAGICAL(sv))
3271 mg_set(sv);
79072805
LW
3272 RETURN;
3273}
3274
a0d0e21e 3275PP(pp_quotemeta)
79072805 3276{
4e35701f 3277 djSP; dTARGET;
a0d0e21e
LW
3278 SV *sv = TOPs;
3279 STRLEN len;
3280 register char *s = SvPV(sv,len);
3281 register char *d;
79072805 3282
7e2040f0 3283 SvUTF8_off(TARG); /* decontaminate */
a0d0e21e
LW
3284 if (len) {
3285 (void)SvUPGRADE(TARG, SVt_PV);
c07a80fd 3286 SvGROW(TARG, (len * 2) + 1);
a0d0e21e 3287 d = SvPVX(TARG);
7e2040f0 3288 if (DO_UTF8(sv)) {
0dd2cdef
LW
3289 while (len) {
3290 if (*s & 0x80) {
3291 STRLEN ulen = UTF8SKIP(s);
3292 if (ulen > len)
3293 ulen = len;
3294 len -= ulen;
3295 while (ulen--)
3296 *d++ = *s++;
3297 }
3298 else {
3299 if (!isALNUM(*s))
3300 *d++ = '\\';
3301 *d++ = *s++;
3302 len--;
3303 }
3304 }
7e2040f0 3305 SvUTF8_on(TARG);
0dd2cdef
LW
3306 }
3307 else {
3308 while (len--) {
3309 if (!isALNUM(*s))
3310 *d++ = '\\';
3311 *d++ = *s++;
3312 }
79072805 3313 }
a0d0e21e
LW
3314 *d = '\0';
3315 SvCUR_set(TARG, d - SvPVX(TARG));
3aa33fe5 3316 (void)SvPOK_only_UTF8(TARG);
79072805 3317 }
a0d0e21e
LW
3318 else
3319 sv_setpvn(TARG, s, len);
3320 SETs(TARG);
31351b04
JS
3321 if (SvSMAGICAL(TARG))
3322 mg_set(TARG);
79072805
LW
3323 RETURN;
3324}
3325
a0d0e21e 3326/* Arrays. */
79072805 3327
a0d0e21e 3328PP(pp_aslice)
79072805 3329{
4e35701f 3330 djSP; dMARK; dORIGMARK;
a0d0e21e
LW
3331 register SV** svp;
3332 register AV* av = (AV*)POPs;
533c011a 3333 register I32 lval = PL_op->op_flags & OPf_MOD;
3280af22 3334 I32 arybase = PL_curcop->cop_arybase;
748a9306 3335 I32 elem;
79072805 3336
a0d0e21e 3337 if (SvTYPE(av) == SVt_PVAV) {
533c011a 3338 if (lval && PL_op->op_private & OPpLVAL_INTRO) {
748a9306 3339 I32 max = -1;
924508f0 3340 for (svp = MARK + 1; svp <= SP; svp++) {
748a9306
LW
3341 elem = SvIVx(*svp);
3342 if (elem > max)
3343 max = elem;
3344 }
3345 if (max > AvMAX(av))
3346 av_extend(av, max);
3347 }
a0d0e21e 3348 while (++MARK <= SP) {
748a9306 3349 elem = SvIVx(*MARK);
a0d0e21e 3350
748a9306
LW
3351 if (elem > 0)
3352 elem -= arybase;
a0d0e21e
LW
3353 svp = av_fetch(av, elem, lval);
3354 if (lval) {
3280af22 3355 if (!svp || *svp == &PL_sv_undef)
cea2e8a9 3356 DIE(aTHX_ PL_no_aelem, elem);
533c011a 3357 if (PL_op->op_private & OPpLVAL_INTRO)
161b7d16 3358 save_aelem(av, elem, svp);
79072805 3359 }
3280af22 3360 *MARK = svp ? *svp : &PL_sv_undef;
79072805
LW
3361 }
3362 }
748a9306 3363 if (GIMME != G_ARRAY) {
a0d0e21e
LW
3364 MARK = ORIGMARK;
3365 *++MARK = *SP;
3366 SP = MARK;
3367 }
79072805
LW
3368 RETURN;
3369}
3370
3371/* Associative arrays. */
3372
3373PP(pp_each)
3374{
59af0135 3375 djSP;
79072805 3376 HV *hash = (HV*)POPs;
c07a80fd 3377 HE *entry;
54310121 3378 I32 gimme = GIMME_V;
c750a3ec 3379 I32 realhv = (SvTYPE(hash) == SVt_PVHV);
8ec5e241 3380
c07a80fd 3381 PUTBACK;
c750a3ec
MB
3382 /* might clobber stack_sp */
3383 entry = realhv ? hv_iternext(hash) : avhv_iternext((AV*)hash);
c07a80fd 3384 SPAGAIN;
79072805 3385
79072805
LW
3386 EXTEND(SP, 2);
3387 if (entry) {
54310121 3388 PUSHs(hv_iterkeysv(entry)); /* won't clobber stack_sp */
3389 if (gimme == G_ARRAY) {
59af0135 3390 SV *val;
c07a80fd 3391 PUTBACK;
c750a3ec 3392 /* might clobber stack_sp */
59af0135
GS
3393 val = realhv ?
3394 hv_iterval(hash, entry) : avhv_iterval((AV*)hash, entry);
c07a80fd 3395 SPAGAIN;
59af0135 3396 PUSHs(val);
79072805 3397 }
79072805 3398 }
54310121 3399 else if (gimme == G_SCALAR)
79072805
LW
3400 RETPUSHUNDEF;
3401
3402 RETURN;
3403}
3404
3405PP(pp_values)
3406{
cea2e8a9 3407 return do_kv();
79072805
LW
3408}
3409
3410PP(pp_keys)
3411{
cea2e8a9 3412 return do_kv();
79072805
LW
3413}
3414
3415PP(pp_delete)
3416{
4e35701f 3417 djSP;
54310121 3418 I32 gimme = GIMME_V;
3419 I32 discard = (gimme == G_VOID) ? G_DISCARD : 0;
79072805 3420 SV *sv;
5f05dabc 3421 HV *hv;
3422
533c011a 3423 if (PL_op->op_private & OPpSLICE) {
5f05dabc 3424 dMARK; dORIGMARK;
97fcbf96 3425 U32 hvtype;
5f05dabc 3426 hv = (HV*)POPs;
97fcbf96 3427 hvtype = SvTYPE(hv);
01020589
GS
3428 if (hvtype == SVt_PVHV) { /* hash element */
3429 while (++MARK <= SP) {
ae77835f 3430 sv = hv_delete_ent(hv, *MARK, discard, 0);
01020589
GS
3431 *MARK = sv ? sv : &PL_sv_undef;
3432 }
5f05dabc 3433 }
01020589
GS
3434 else if (hvtype == SVt_PVAV) {
3435 if (PL_op->op_flags & OPf_SPECIAL) { /* array element */
3436 while (++MARK <= SP) {
3437 sv = av_delete((AV*)hv, SvIV(*MARK), discard);
3438 *MARK = sv ? sv : &PL_sv_undef;
3439 }
3440 }
3441 else { /* pseudo-hash element */
3442 while (++MARK <= SP) {
3443 sv = avhv_delete_ent((AV*)hv, *MARK, discard, 0);
3444 *MARK = sv ? sv : &PL_sv_undef;
3445 }
3446 }
3447 }
3448 else
3449 DIE(aTHX_ "Not a HASH reference");
54310121 3450 if (discard)
3451 SP = ORIGMARK;
3452 else if (gimme == G_SCALAR) {
5f05dabc 3453 MARK = ORIGMARK;
3454 *++MARK = *SP;
3455 SP = MARK;
3456 }
3457 }
3458 else {
3459 SV *keysv = POPs;
3460 hv = (HV*)POPs;
97fcbf96
MB
3461 if (SvTYPE(hv) == SVt_PVHV)
3462 sv = hv_delete_ent(hv, keysv, discard, 0);
01020589
GS
3463 else if (SvTYPE(hv) == SVt_PVAV) {
3464 if (PL_op->op_flags & OPf_SPECIAL)
3465 sv = av_delete((AV*)hv, SvIV(keysv), discard);
3466 else
3467 sv = avhv_delete_ent((AV*)hv, keysv, discard, 0);
3468 }
97fcbf96 3469 else
cea2e8a9 3470 DIE(aTHX_ "Not a HASH reference");
5f05dabc 3471 if (!sv)
3280af22 3472 sv = &PL_sv_undef;
54310121 3473 if (!discard)
3474 PUSHs(sv);
79072805 3475 }
79072805
LW
3476 RETURN;
3477}
3478
a0d0e21e 3479PP(pp_exists)
79072805 3480{
4e35701f 3481 djSP;
afebc493
GS
3482 SV *tmpsv;
3483 HV *hv;
3484
3485 if (PL_op->op_private & OPpEXISTS_SUB) {
3486 GV *gv;
3487 CV *cv;
3488 SV *sv = POPs;
3489 cv = sv_2cv(sv, &hv, &gv, FALSE);
3490 if (cv)
3491 RETPUSHYES;
3492 if (gv && isGV(gv) && GvCV(gv) && !GvCVGEN(gv))
3493 RETPUSHYES;
3494 RETPUSHNO;
3495 }
3496 tmpsv = POPs;
3497 hv = (HV*)POPs;
c750a3ec 3498 if (SvTYPE(hv) == SVt_PVHV) {
ae77835f 3499 if (hv_exists_ent(hv, tmpsv, 0))
c750a3ec 3500 RETPUSHYES;
ef54e1a4
JH
3501 }
3502 else if (SvTYPE(hv) == SVt_PVAV) {
01020589
GS
3503 if (PL_op->op_flags & OPf_SPECIAL) { /* array element */
3504 if (av_exists((AV*)hv, SvIV(tmpsv)))
3505 RETPUSHYES;
3506 }
3507 else if (avhv_exists_ent((AV*)hv, tmpsv, 0)) /* pseudo-hash element */
c750a3ec 3508 RETPUSHYES;
ef54e1a4
JH
3509 }
3510 else {
cea2e8a9 3511 DIE(aTHX_ "Not a HASH reference");
a0d0e21e 3512 }
a0d0e21e
LW
3513 RETPUSHNO;
3514}
79072805 3515
a0d0e21e
LW
3516PP(pp_hslice)
3517{
4e35701f 3518 djSP; dMARK; dORIGMARK;
a0d0e21e 3519 register HV *hv = (HV*)POPs;
533c011a 3520 register I32 lval = PL_op->op_flags & OPf_MOD;
c750a3ec 3521 I32 realhv = (SvTYPE(hv) == SVt_PVHV);
79072805 3522
0ebe0038 3523 if (!realhv && PL_op->op_private & OPpLVAL_INTRO)
cea2e8a9 3524 DIE(aTHX_ "Can't localize pseudo-hash element");
0ebe0038 3525
c750a3ec 3526 if (realhv || SvTYPE(hv) == SVt_PVAV) {
a0d0e21e 3527 while (++MARK <= SP) {
f12c7020 3528 SV *keysv = *MARK;
ae77835f 3529 SV **svp;
1f5346dc 3530 I32 preeminent = SvRMAGICAL(hv) ? 1 : hv_exists_ent(hv, keysv, 0);
ae77835f 3531 if (realhv) {
800e9ae0 3532 HE *he = hv_fetch_ent(hv, keysv, lval, 0);
ae77835f 3533 svp = he ? &HeVAL(he) : 0;
ef54e1a4
JH
3534 }
3535 else {
97fcbf96 3536 svp = avhv_fetch_ent((AV*)hv, keysv, lval, 0);
ae77835f 3537 }
a0d0e21e 3538 if (lval) {
2d8e6c8d
GS
3539 if (!svp || *svp == &PL_sv_undef) {
3540 STRLEN n_a;
cea2e8a9 3541 DIE(aTHX_ PL_no_helem, SvPV(keysv, n_a));
2d8e6c8d 3542 }
1f5346dc
SC
3543 if (PL_op->op_private & OPpLVAL_INTRO) {
3544 if (preeminent)
3545 save_helem(hv, keysv, svp);
3546 else {
3547 STRLEN keylen;
3548 char *key = SvPV(keysv, keylen);
3549 save_delete(hv, key, keylen);
3550 }
3551 }
93a17b20 3552 }
3280af22 3553 *MARK = svp ? *svp : &PL_sv_undef;
79072805
LW
3554 }
3555 }
a0d0e21e
LW
3556 if (GIMME != G_ARRAY) {
3557 MARK = ORIGMARK;
3558 *++MARK = *SP;
3559 SP = MARK;
79072805 3560 }
a0d0e21e
LW
3561 RETURN;
3562}
3563
3564/* List operators. */
3565
3566PP(pp_list)
3567{
4e35701f 3568 djSP; dMARK;
a0d0e21e
LW
3569 if (GIMME != G_ARRAY) {
3570 if (++MARK <= SP)
3571 *MARK = *SP; /* unwanted list, return last item */
8990e307 3572 else
3280af22 3573 *MARK = &PL_sv_undef;
a0d0e21e 3574 SP = MARK;
79072805 3575 }
a0d0e21e 3576 RETURN;
79072805
LW
3577}
3578
a0d0e21e 3579PP(pp_lslice)
79072805 3580{
4e35701f 3581 djSP;
3280af22
NIS
3582 SV **lastrelem = PL_stack_sp;
3583 SV **lastlelem = PL_stack_base + POPMARK;
3584 SV **firstlelem = PL_stack_base + POPMARK + 1;
a0d0e21e 3585 register SV **firstrelem = lastlelem + 1;
3280af22 3586 I32 arybase = PL_curcop->cop_arybase;
533c011a 3587 I32 lval = PL_op->op_flags & OPf_MOD;
4633a7c4 3588 I32 is_something_there = lval;
79072805 3589
a0d0e21e
LW
3590 register I32 max = lastrelem - lastlelem;
3591 register SV **lelem;
3592 register I32 ix;
3593
3594 if (GIMME != G_ARRAY) {
748a9306
LW
3595 ix = SvIVx(*lastlelem);
3596 if (ix < 0)
3597 ix += max;
3598 else
3599 ix -= arybase;
a0d0e21e 3600 if (ix < 0 || ix >= max)
3280af22 3601 *firstlelem = &PL_sv_undef;
a0d0e21e
LW
3602 else
3603 *firstlelem = firstrelem[ix];
3604 SP = firstlelem;
3605 RETURN;
3606 }
3607
3608 if (max == 0) {
3609 SP = firstlelem - 1;
3610 RETURN;
3611 }
3612
3613 for (lelem = firstlelem; lelem <= lastlelem; lelem++) {
748a9306 3614 ix = SvIVx(*lelem);
c73bf8e3 3615 if (ix < 0)
a0d0e21e 3616 ix += max;
b13b2135 3617 else
748a9306 3618 ix -= arybase;
c73bf8e3
HS
3619 if (ix < 0 || ix >= max)
3620 *lelem = &PL_sv_undef;
3621 else {
3622 is_something_there = TRUE;
3623 if (!(*lelem = firstrelem[ix]))
3280af22 3624 *lelem = &PL_sv_undef;
748a9306 3625 }
79072805 3626 }
4633a7c4
LW
3627 if (is_something_there)
3628 SP = lastlelem;
3629 else
3630 SP = firstlelem - 1;
79072805
LW
3631 RETURN;
3632}
3633
a0d0e21e
LW
3634PP(pp_anonlist)
3635{
4e35701f 3636 djSP; dMARK; dORIGMARK;
a0d0e21e 3637 I32 items = SP - MARK;
44a8e56a 3638 SV *av = sv_2mortal((SV*)av_make(items, MARK+1));
3639 SP = ORIGMARK; /* av_make() might realloc stack_sp */
3640 XPUSHs(av);
a0d0e21e
LW
3641 RETURN;
3642}
3643
3644PP(pp_anonhash)
79072805 3645{
4e35701f 3646 djSP; dMARK; dORIGMARK;
a0d0e21e
LW
3647 HV* hv = (HV*)sv_2mortal((SV*)newHV());
3648
3649 while (MARK < SP) {
3650 SV* key = *++MARK;
a0d0e21e
LW
3651 SV *val = NEWSV(46, 0);
3652 if (MARK < SP)
3653 sv_setsv(val, *++MARK);
e476b1b5
GS
3654 else if (ckWARN(WARN_MISC))
3655 Perl_warner(aTHX_ WARN_MISC, "Odd number of elements in hash assignment");
f12c7020 3656 (void)hv_store_ent(hv,key,val,0);
79072805 3657 }
a0d0e21e
LW
3658 SP = ORIGMARK;
3659 XPUSHs((SV*)hv);
79072805
LW
3660 RETURN;
3661}
3662
a0d0e21e 3663PP(pp_splice)
79072805 3664{
4e35701f 3665 djSP; dMARK; dORIGMARK;
a0d0e21e
LW
3666 register AV *ary = (AV*)*++MARK;
3667 register SV **src;
3668 register SV **dst;
3669 register I32 i;
3670 register I32 offset;
3671 register I32 length;
3672 I32 newlen;
3673 I32 after;
3674 I32 diff;
3675 SV **tmparyval = 0;
93965878
NIS
3676 MAGIC *mg;
3677
155aba94 3678 if ((mg = SvTIED_mg((SV*)ary, 'P'))) {
33c27489 3679 *MARK-- = SvTIED_obj((SV*)ary, mg);
93965878 3680 PUSHMARK(MARK);
8ec5e241 3681 PUTBACK;
a60c0954 3682 ENTER;
864dbfa3 3683 call_method("SPLICE",GIMME_V);
a60c0954 3684 LEAVE;
93965878
NIS
3685 SPAGAIN;
3686 RETURN;
3687 }
79072805 3688
a0d0e21e 3689 SP++;
79072805 3690
a0d0e21e 3691 if (++MARK < SP) {
84902520 3692 offset = i = SvIVx(*MARK);
a0d0e21e 3693 if (offset < 0)
93965878 3694 offset += AvFILLp(ary) + 1;
a0d0e21e 3695 else
3280af22 3696 offset -= PL_curcop->cop_arybase;
84902520 3697 if (offset < 0)
cea2e8a9 3698 DIE(aTHX_ PL_no_aelem, i);
a0d0e21e
LW
3699 if (++MARK < SP) {
3700 length = SvIVx(*MARK++);
48cdf507
GA
3701 if (length < 0) {
3702 length += AvFILLp(ary) - offset + 1;
3703 if (length < 0)
3704 length = 0;
3705 }
79072805
LW
3706 }
3707 else
a0d0e21e 3708 length = AvMAX(ary) + 1; /* close enough to infinity */
79072805 3709 }
a0d0e21e
LW
3710 else {
3711 offset = 0;
3712 length = AvMAX(ary) + 1;
3713 }
93965878
NIS
3714 if (offset > AvFILLp(ary) + 1)
3715 offset = AvFILLp(ary) + 1;
3716 after = AvFILLp(ary) + 1 - (offset + length);
a0d0e21e
LW
3717 if (after < 0) { /* not that much array */
3718 length += after; /* offset+length now in array */
3719 after = 0;
3720 if (!AvALLOC(ary))
3721 av_extend(ary, 0);
3722 }
3723
3724 /* At this point, MARK .. SP-1 is our new LIST */
3725
3726 newlen = SP - MARK;
3727 diff = newlen - length;
13d7cbc1
GS
3728 if (newlen && !AvREAL(ary) && AvREIFY(ary))
3729 av_reify(ary);
a0d0e21e
LW
3730
3731 if (diff < 0) { /* shrinking the area */
3732 if (newlen) {
3733 New(451, tmparyval, newlen, SV*); /* so remember insertion */
3734 Copy(MARK, tmparyval, newlen, SV*);
79072805 3735 }
a0d0e21e
LW
3736
3737 MARK = ORIGMARK + 1;
3738 if (GIMME == G_ARRAY) { /* copy return vals to stack */
3739 MEXTEND(MARK, length);
3740 Copy(AvARRAY(ary)+offset, MARK, length, SV*);
3741 if (AvREAL(ary)) {
bbce6d69 3742 EXTEND_MORTAL(length);
36477c24 3743 for (i = length, dst = MARK; i; i--) {
d689ffdd 3744 sv_2mortal(*dst); /* free them eventualy */
36477c24 3745 dst++;
3746 }
a0d0e21e
LW
3747 }
3748 MARK += length - 1;
79072805 3749 }
a0d0e21e
LW
3750 else {
3751 *MARK = AvARRAY(ary)[offset+length-1];
3752 if (AvREAL(ary)) {
d689ffdd 3753 sv_2mortal(*MARK);
a0d0e21e
LW
3754 for (i = length - 1, dst = &AvARRAY(ary)[offset]; i > 0; i--)
3755 SvREFCNT_dec(*dst++); /* free them now */
79072805 3756 }
a0d0e21e 3757 }
93965878 3758 AvFILLp(ary) += diff;
a0d0e21e
LW
3759
3760 /* pull up or down? */
3761
3762 if (offset < after) { /* easier to pull up */
3763 if (offset) { /* esp. if nothing to pull */
3764 src = &AvARRAY(ary)[offset-1];
3765 dst = src - diff; /* diff is negative */
3766 for (i = offset; i > 0; i--) /* can't trust Copy */
3767 *dst-- = *src--;
79072805 3768 }
a0d0e21e
LW
3769 dst = AvARRAY(ary);
3770 SvPVX(ary) = (char*)(AvARRAY(ary) - diff); /* diff is negative */
3771 AvMAX(ary) += diff;
3772 }
3773 else {
3774 if (after) { /* anything to pull down? */
3775 src = AvARRAY(ary) + offset + length;
3776 dst = src + diff; /* diff is negative */
3777 Move(src, dst, after, SV*);
79072805 3778 }
93965878 3779 dst = &AvARRAY(ary)[AvFILLp(ary)+1];
a0d0e21e
LW
3780 /* avoid later double free */
3781 }
3782 i = -diff;
3783 while (i)
3280af22 3784 dst[--i] = &PL_sv_undef;
a0d0e21e
LW
3785
3786 if (newlen) {
3787 for (src = tmparyval, dst = AvARRAY(ary) + offset;
3788 newlen; newlen--) {
3789 *dst = NEWSV(46, 0);
3790 sv_setsv(*dst++, *src++);
79072805 3791 }
a0d0e21e
LW
3792 Safefree(tmparyval);
3793 }
3794 }
3795 else { /* no, expanding (or same) */
3796 if (length) {
3797 New(452, tmparyval, length, SV*); /* so remember deletion */
3798 Copy(AvARRAY(ary)+offset, tmparyval, length, SV*);
3799 }
3800
3801 if (diff > 0) { /* expanding */
3802
3803 /* push up or down? */
3804
3805 if (offset < after && diff <= AvARRAY(ary) - AvALLOC(ary)) {
3806 if (offset) {
3807 src = AvARRAY(ary);
3808 dst = src - diff;
3809 Move(src, dst, offset, SV*);
79072805 3810 }
a0d0e21e
LW
3811 SvPVX(ary) = (char*)(AvARRAY(ary) - diff);/* diff is positive */
3812 AvMAX(ary) += diff;
93965878 3813 AvFILLp(ary) += diff;
79072805
LW
3814 }
3815 else {
93965878
NIS
3816 if (AvFILLp(ary) + diff >= AvMAX(ary)) /* oh, well */
3817 av_extend(ary, AvFILLp(ary) + diff);
3818 AvFILLp(ary) += diff;
a0d0e21e
LW
3819
3820 if (after) {
93965878 3821 dst = AvARRAY(ary) + AvFILLp(ary);
a0d0e21e
LW
3822 src = dst - diff;
3823 for (i = after; i; i--) {
3824 *dst-- = *src--;
3825 }
79072805
LW
3826 }
3827 }
a0d0e21e
LW
3828 }
3829
3830 for (src = MARK, dst = AvARRAY(ary) + offset; newlen; newlen--) {
3831 *dst = NEWSV(46, 0);
3832 sv_setsv(*dst++, *src++);
3833 }
3834 MARK = ORIGMARK + 1;
3835 if (GIMME == G_ARRAY) { /* copy return vals to stack */
3836 if (length) {
3837 Copy(tmparyval, MARK, length, SV*);
3838 if (AvREAL(ary)) {
bbce6d69 3839 EXTEND_MORTAL(length);
36477c24 3840 for (i = length, dst = MARK; i; i--) {
d689ffdd 3841 sv_2mortal(*dst); /* free them eventualy */
36477c24 3842 dst++;
3843 }
79072805 3844 }
a0d0e21e 3845 Safefree(tmparyval);
79072805 3846 }
a0d0e21e
LW
3847 MARK += length - 1;
3848 }
3849 else if (length--) {
3850 *MARK = tmparyval[length];
3851 if (AvREAL(ary)) {
d689ffdd 3852 sv_2mortal(*MARK);
a0d0e21e
LW
3853 while (length-- > 0)
3854 SvREFCNT_dec(tmparyval[length]);
79072805 3855 }
a0d0e21e 3856 Safefree(tmparyval);
79072805 3857 }
a0d0e21e 3858 else
3280af22 3859 *MARK = &PL_sv_undef;
79072805 3860 }
a0d0e21e 3861 SP = MARK;
79072805
LW
3862 RETURN;
3863}
3864
a0d0e21e 3865PP(pp_push)
79072805 3866{
4e35701f 3867 djSP; dMARK; dORIGMARK; dTARGET;
a0d0e21e 3868 register AV *ary = (AV*)*++MARK;
3280af22 3869 register SV *sv = &PL_sv_undef;
93965878 3870 MAGIC *mg;
79072805 3871
155aba94 3872 if ((mg = SvTIED_mg((SV*)ary, 'P'))) {
33c27489 3873 *MARK-- = SvTIED_obj((SV*)ary, mg);
93965878
NIS
3874 PUSHMARK(MARK);
3875 PUTBACK;
a60c0954 3876 ENTER;
864dbfa3 3877 call_method("PUSH",G_SCALAR|G_DISCARD);
a60c0954 3878 LEAVE;
93965878 3879 SPAGAIN;
93965878 3880 }
a60c0954
NIS
3881 else {
3882 /* Why no pre-extend of ary here ? */
3883 for (++MARK; MARK <= SP; MARK++) {
3884 sv = NEWSV(51, 0);
3885 if (*MARK)
3886 sv_setsv(sv, *MARK);
3887 av_push(ary, sv);
3888 }
79072805
LW
3889 }
3890 SP = ORIGMARK;
a0d0e21e 3891 PUSHi( AvFILL(ary) + 1 );
79072805
LW
3892 RETURN;
3893}
3894
a0d0e21e 3895PP(pp_pop)
79072805 3896{
4e35701f 3897 djSP;
a0d0e21e
LW
3898 AV *av = (AV*)POPs;
3899 SV *sv = av_pop(av);
d689ffdd 3900 if (AvREAL(av))
a0d0e21e
LW
3901 (void)sv_2mortal(sv);
3902 PUSHs(sv);
79072805 3903 RETURN;
79072805
LW
3904}
3905
a0d0e21e 3906PP(pp_shift)
79072805 3907{
4e35701f 3908 djSP;
a0d0e21e
LW
3909 AV *av = (AV*)POPs;
3910 SV *sv = av_shift(av);
79072805 3911 EXTEND(SP, 1);
a0d0e21e 3912 if (!sv)
79072805 3913 RETPUSHUNDEF;
d689ffdd 3914 if (AvREAL(av))
a0d0e21e
LW
3915 (void)sv_2mortal(sv);
3916 PUSHs(sv);
79072805 3917 RETURN;
79072805
LW
3918}
3919
a0d0e21e 3920PP(pp_unshift)
79072805 3921{
4e35701f 3922 djSP; dMARK; dORIGMARK; dTARGET;
a0d0e21e
LW
3923 register AV *ary = (AV*)*++MARK;
3924 register SV *sv;
3925 register I32 i = 0;
93965878
NIS
3926 MAGIC *mg;
3927
155aba94 3928 if ((mg = SvTIED_mg((SV*)ary, 'P'))) {
33c27489 3929 *MARK-- = SvTIED_obj((SV*)ary, mg);
7fd66d9d 3930 PUSHMARK(MARK);
93965878 3931 PUTBACK;
a60c0954 3932 ENTER;
864dbfa3 3933 call_method("UNSHIFT",G_SCALAR|G_DISCARD);
a60c0954 3934 LEAVE;
93965878 3935 SPAGAIN;
93965878 3936 }
a60c0954
NIS
3937 else {
3938 av_unshift(ary, SP - MARK);
3939 while (MARK < SP) {
3940 sv = NEWSV(27, 0);
3941 sv_setsv(sv, *++MARK);
3942 (void)av_store(ary, i++, sv);
3943 }
79072805 3944 }
a0d0e21e
LW
3945 SP = ORIGMARK;
3946 PUSHi( AvFILL(ary) + 1 );
79072805 3947 RETURN;
79072805
LW
3948}
3949
a0d0e21e 3950PP(pp_reverse)
79072805 3951{
4e35701f 3952 djSP; dMARK;
a0d0e21e
LW
3953 register SV *tmp;
3954 SV **oldsp = SP;
79072805 3955
a0d0e21e
LW
3956 if (GIMME == G_ARRAY) {
3957 MARK++;
3958 while (MARK < SP) {
3959 tmp = *MARK;
3960 *MARK++ = *SP;
3961 *SP-- = tmp;
3962 }
dd58a1ab 3963 /* safe as long as stack cannot get extended in the above */
a0d0e21e 3964 SP = oldsp;
79072805
LW
3965 }
3966 else {
a0d0e21e
LW
3967 register char *up;
3968 register char *down;
3969 register I32 tmp;
3970 dTARGET;
3971 STRLEN len;
79072805 3972
7e2040f0 3973 SvUTF8_off(TARG); /* decontaminate */
a0d0e21e 3974 if (SP - MARK > 1)
3280af22 3975 do_join(TARG, &PL_sv_no, MARK, SP);
a0d0e21e 3976 else
54b9620d 3977 sv_setsv(TARG, (SP > MARK) ? *SP : DEFSV);
a0d0e21e
LW
3978 up = SvPV_force(TARG, len);
3979 if (len > 1) {
7e2040f0 3980 if (DO_UTF8(TARG)) { /* first reverse each character */
dfe13c55
GS
3981 U8* s = (U8*)SvPVX(TARG);
3982 U8* send = (U8*)(s + len);
a0ed51b3
LW
3983 while (s < send) {
3984 if (*s < 0x80) {
3985 s++;
3986 continue;
3987 }
3988 else {
dfe13c55 3989 up = (char*)s;
a0ed51b3 3990 s += UTF8SKIP(s);
dfe13c55 3991 down = (char*)(s - 1);
f248d071
GS
3992 if (s > send || !((*down & 0xc0) == 0x80)) {
3993 if (ckWARN_d(WARN_UTF8))
3994 Perl_warner(aTHX_ WARN_UTF8,
3995 "Malformed UTF-8 character");
a0ed51b3
LW
3996 break;
3997 }
3998 while (down > up) {
3999 tmp = *up;
4000 *up++ = *down;
4001 *down-- = tmp;
4002 }
4003 }
4004 }
4005 up = SvPVX(TARG);
4006 }
a0d0e21e
LW
4007 down = SvPVX(TARG) + len - 1;
4008 while (down > up) {
4009 tmp = *up;
4010 *up++ = *down;
4011 *down-- = tmp;
4012 }
3aa33fe5 4013 (void)SvPOK_only_UTF8(TARG);
79072805 4014 }
a0d0e21e
LW
4015 SP = MARK + 1;
4016 SETTARG;
79072805 4017 }
a0d0e21e 4018 RETURN;
79072805
LW
4019}
4020
864dbfa3 4021STATIC SV *
cea2e8a9 4022S_mul128(pTHX_ SV *sv, U8 m)
55497cff 4023{
4024 STRLEN len;
4025 char *s = SvPV(sv, len);
4026 char *t;
4027 U32 i = 0;
4028
4029 if (!strnEQ(s, "0000", 4)) { /* need to grow sv */
79cb57f6 4030 SV *tmpNew = newSVpvn("0000000000", 10);
55497cff 4031
09b7f37c 4032 sv_catsv(tmpNew, sv);
55497cff 4033 SvREFCNT_dec(sv); /* free old sv */
09b7f37c 4034 sv = tmpNew;
55497cff 4035 s = SvPV(sv, len);
4036 }
4037 t = s + len - 1;
4038 while (!*t) /* trailing '\0'? */
4039 t--;
4040 while (t > s) {
4041 i = ((*t - '0') << 7) + m;
4042 *(t--) = '0' + (i % 10);
4043 m = i / 10;
4044 }
4045 return (sv);
4046}
4047
a0d0e21e
LW
4048/* Explosives and implosives. */
4049
9d116dd7
JH
4050#if 'I' == 73 && 'J' == 74
4051/* On an ASCII/ISO kind of system */
ba1ac976 4052#define ISUUCHAR(ch) ((ch) >= ' ' && (ch) < 'a')
9d116dd7
JH
4053#else
4054/*
4055 Some other sort of character set - use memchr() so we don't match
4056 the null byte.
4057 */
80252599 4058#define ISUUCHAR(ch) (memchr(PL_uuemap, (ch), sizeof(PL_uuemap)-1) || (ch) == ' ')
9d116dd7
JH
4059#endif
4060
a0d0e21e 4061PP(pp_unpack)
79072805 4062{
4e35701f 4063 djSP;
a0d0e21e 4064 dPOPPOPssrl;
dd58a1ab 4065 I32 start_sp_offset = SP - PL_stack_base;
54310121 4066 I32 gimme = GIMME_V;
ed6116ce 4067 SV *sv;
a0d0e21e
LW
4068 STRLEN llen;
4069 STRLEN rlen;
4070 register char *pat = SvPV(left, llen);
4071 register char *s = SvPV(right, rlen);
4072 char *strend = s + rlen;
4073 char *strbeg = s;
4074 register char *patend = pat + llen;
4075 I32 datumtype;
4076 register I32 len;
4077 register I32 bits;
abdc5761 4078 register char *str;
79072805 4079
a0d0e21e 4080 /* These must not be in registers: */
43ea6eee 4081 short ashort;
a0d0e21e 4082 int aint;
43ea6eee 4083 long along;
6b8eaf93 4084#ifdef HAS_QUAD
ecfc5424 4085 Quad_t aquad;
a0d0e21e
LW
4086#endif
4087 U16 aushort;
4088 unsigned int auint;
4089 U32 aulong;
6b8eaf93 4090#ifdef HAS_QUAD
e862df63 4091 Uquad_t auquad;
a0d0e21e
LW
4092#endif
4093 char *aptr;
4094 float afloat;
4095 double adouble;
4096 I32 checksum = 0;
4097 register U32 culong;
65202027 4098 NV cdouble;
fb73857a 4099 int commas = 0;
4b5b2118 4100 int star;
726ea183 4101#ifdef PERL_NATINT_PACK
ef54e1a4
JH
4102 int natint; /* native integer */
4103 int unatint; /* unsigned native integer */
726ea183 4104#endif
79072805 4105
54310121 4106 if (gimme != G_ARRAY) { /* arrange to do first one only */
a0d0e21e
LW
4107 /*SUPPRESS 530*/
4108 for (patend = pat; !isALPHA(*patend) || *patend == 'x'; patend++) ;
5a929a98 4109 if (strchr("aAZbBhHP", *patend) || *pat == '%') {
a0d0e21e
LW
4110 patend++;
4111 while (isDIGIT(*patend) || *patend == '*')
4112 patend++;
4113 }
4114 else
4115 patend++;
79072805 4116 }
a0d0e21e
LW
4117 while (pat < patend) {
4118 reparse:
bbdab043 4119 datumtype = *pat++ & 0xFF;
726ea183 4120#ifdef PERL_NATINT_PACK
ef54e1a4 4121 natint = 0;
726ea183 4122#endif
bbdab043
CS
4123 if (isSPACE(datumtype))
4124 continue;
17f4a12d
IZ
4125 if (datumtype == '#') {
4126 while (pat < patend && *pat != '\n')
4127 pat++;
4128 continue;
4129 }
f61d411c 4130 if (*pat == '!') {
ef54e1a4
JH
4131 char *natstr = "sSiIlL";
4132
4133 if (strchr(natstr, datumtype)) {
726ea183 4134#ifdef PERL_NATINT_PACK
ef54e1a4 4135 natint = 1;
726ea183 4136#endif
ef54e1a4
JH
4137 pat++;
4138 }
4139 else
d470f89e 4140 DIE(aTHX_ "'!' allowed only after types %s", natstr);
ef54e1a4 4141 }
4b5b2118 4142 star = 0;
a0d0e21e
LW
4143 if (pat >= patend)
4144 len = 1;
4145 else if (*pat == '*') {
4146 len = strend - strbeg; /* long enough */
4147 pat++;
4b5b2118 4148 star = 1;
a0d0e21e
LW
4149 }
4150 else if (isDIGIT(*pat)) {
4151 len = *pat++ - '0';
06387354 4152 while (isDIGIT(*pat)) {
a0d0e21e 4153 len = (len * 10) + (*pat++ - '0');
06387354 4154 if (len < 0)
d470f89e 4155 DIE(aTHX_ "Repeat count in unpack overflows");
06387354 4156 }
a0d0e21e
LW
4157 }
4158 else
4159 len = (datumtype != '@');
4b5b2118 4160 redo_switch:
a0d0e21e
LW
4161 switch(datumtype) {
4162 default:
d470f89e 4163 DIE(aTHX_ "Invalid type in unpack: '%c'", (int)datumtype);
fb73857a 4164 case ',': /* grandfather in commas but with a warning */
e476b1b5
GS
4165 if (commas++ == 0 && ckWARN(WARN_UNPACK))
4166 Perl_warner(aTHX_ WARN_UNPACK,
d470f89e 4167 "Invalid type in unpack: '%c'", (int)datumtype);
fb73857a 4168 break;
a0d0e21e
LW
4169 case '%':
4170 if (len == 1 && pat[-1] != '1')
4171 len = 16;
4172 checksum = len;
4173 culong = 0;
4174 cdouble = 0;
4175 if (pat < patend)
4176 goto reparse;
4177 break;
4178 case '@':
4179 if (len > strend - strbeg)
cea2e8a9 4180 DIE(aTHX_ "@ outside of string");
a0d0e21e
LW
4181 s = strbeg + len;
4182 break;
4183 case 'X':
4184 if (len > s - strbeg)
cea2e8a9 4185 DIE(aTHX_ "X outside of string");
a0d0e21e
LW
4186 s -= len;
4187 break;
4188 case 'x':
4189 if (len > strend - s)
cea2e8a9 4190 DIE(aTHX_ "x outside of string");
a0d0e21e
LW
4191 s += len;
4192 break;
17f4a12d 4193 case '/':
dd58a1ab 4194 if (start_sp_offset >= SP - PL_stack_base)
17f4a12d 4195 DIE(aTHX_ "/ must follow a numeric type");
43192e07
IP
4196 datumtype = *pat++;
4197 if (*pat == '*')
4198 pat++; /* ignore '*' for compatibility with pack */
4199 if (isDIGIT(*pat))
17f4a12d 4200 DIE(aTHX_ "/ cannot take a count" );
43192e07 4201 len = POPi;
4b5b2118
GS
4202 star = 0;
4203 goto redo_switch;
a0d0e21e 4204 case 'A':
5a929a98 4205 case 'Z':
a0d0e21e
LW
4206 case 'a':
4207 if (len > strend - s)
4208 len = strend - s;
4209 if (checksum)
4210 goto uchar_checksum;
4211 sv = NEWSV(35, len);
4212 sv_setpvn(sv, s, len);
4213 s += len;
5a929a98 4214 if (datumtype == 'A' || datumtype == 'Z') {
a0d0e21e 4215 aptr = s; /* borrow register */
5a929a98
VU
4216 if (datumtype == 'Z') { /* 'Z' strips stuff after first null */
4217 s = SvPVX(sv);
4218 while (*s)
4219 s++;
4220 }
4221 else { /* 'A' strips both nulls and spaces */
4222 s = SvPVX(sv) + len - 1;
4223 while (s >= SvPVX(sv) && (!*s || isSPACE(*s)))
4224 s--;
4225 *++s = '\0';
4226 }
a0d0e21e
LW
4227 SvCUR_set(sv, s - SvPVX(sv));
4228 s = aptr; /* unborrow register */
4229 }
4230 XPUSHs(sv_2mortal(sv));
4231 break;
4232 case 'B':
4233 case 'b':
4b5b2118 4234 if (star || len > (strend - s) * 8)
a0d0e21e
LW
4235 len = (strend - s) * 8;
4236 if (checksum) {
80252599
GS
4237 if (!PL_bitcount) {
4238 Newz(601, PL_bitcount, 256, char);
a0d0e21e 4239 for (bits = 1; bits < 256; bits++) {
80252599
GS
4240 if (bits & 1) PL_bitcount[bits]++;
4241 if (bits & 2) PL_bitcount[bits]++;
4242 if (bits & 4) PL_bitcount[bits]++;
4243 if (bits & 8) PL_bitcount[bits]++;
4244 if (bits & 16) PL_bitcount[bits]++;
4245 if (bits & 32) PL_bitcount[bits]++;
4246 if (bits & 64) PL_bitcount[bits]++;
4247 if (bits & 128) PL_bitcount[bits]++;
a0d0e21e
LW
4248 }
4249 }
4250 while (len >= 8) {
80252599 4251 culong += PL_bitcount[*(unsigned char*)s++];
a0d0e21e
LW
4252 len -= 8;
4253 }
4254 if (len) {
4255 bits = *s;
4256 if (datumtype == 'b') {
4257 while (len-- > 0) {
4258 if (bits & 1) culong++;
4259 bits >>= 1;
4260 }
4261 }
4262 else {
4263 while (len-- > 0) {
4264 if (bits & 128) culong++;
4265 bits <<= 1;
4266 }
4267 }
4268 }
79072805
LW
4269 break;
4270 }
a0d0e21e
LW
4271 sv = NEWSV(35, len + 1);
4272 SvCUR_set(sv, len);
4273 SvPOK_on(sv);
abdc5761 4274 str = SvPVX(sv);
a0d0e21e
LW
4275 if (datumtype == 'b') {
4276 aint = len;
4277 for (len = 0; len < aint; len++) {
4278 if (len & 7) /*SUPPRESS 595*/
4279 bits >>= 1;
4280 else
4281 bits = *s++;
abdc5761 4282 *str++ = '0' + (bits & 1);
a0d0e21e
LW
4283 }
4284 }
4285 else {
4286 aint = len;
4287 for (len = 0; len < aint; len++) {
4288 if (len & 7)
4289 bits <<= 1;
4290 else
4291 bits = *s++;
abdc5761 4292 *str++ = '0' + ((bits & 128) != 0);
a0d0e21e
LW
4293 }
4294 }
abdc5761 4295 *str = '\0';
a0d0e21e
LW
4296 XPUSHs(sv_2mortal(sv));
4297 break;
4298 case 'H':
4299 case 'h':
4b5b2118 4300 if (star || len > (strend - s) * 2)
a0d0e21e
LW
4301 len = (strend - s) * 2;
4302 sv = NEWSV(35, len + 1);
4303 SvCUR_set(sv, len);
4304 SvPOK_on(sv);
abdc5761 4305 str = SvPVX(sv);
a0d0e21e
LW
4306 if (datumtype == 'h') {
4307 aint = len;
4308 for (len = 0; len < aint; len++) {
4309 if (len & 1)
4310 bits >>= 4;
4311 else
4312 bits = *s++;
abdc5761 4313 *str++ = PL_hexdigit[bits & 15];
a0d0e21e
LW
4314 }
4315 }
4316 else {
4317 aint = len;
4318 for (len = 0; len < aint; len++) {
4319 if (len & 1)
4320 bits <<= 4;
4321 else
4322 bits = *s++;
abdc5761 4323 *str++ = PL_hexdigit[(bits >> 4) & 15];
a0d0e21e
LW
4324 }
4325 }
abdc5761 4326 *str = '\0';
a0d0e21e
LW
4327 XPUSHs(sv_2mortal(sv));
4328 break;
4329 case 'c':
4330 if (len > strend - s)
4331 len = strend - s;
4332 if (checksum) {
4333 while (len-- > 0) {
4334 aint = *s++;
4335 if (aint >= 128) /* fake up signed chars */
4336 aint -= 256;
4337 culong += aint;
4338 }
4339 }
4340 else {
4341 EXTEND(SP, len);
bbce6d69 4342 EXTEND_MORTAL(len);
a0d0e21e
LW
4343 while (len-- > 0) {
4344 aint = *s++;
4345 if (aint >= 128) /* fake up signed chars */
4346 aint -= 256;
4347 sv = NEWSV(36, 0);
1e422769 4348 sv_setiv(sv, (IV)aint);
a0d0e21e
LW
4349 PUSHs(sv_2mortal(sv));
4350 }
4351 }
4352 break;
4353 case 'C':
4354 if (len > strend - s)
4355 len = strend - s;
4356 if (checksum) {
4357 uchar_checksum:
4358 while (len-- > 0) {
4359 auint = *s++ & 255;
4360 culong += auint;
4361 }
4362 }
4363 else {
4364 EXTEND(SP, len);
bbce6d69 4365 EXTEND_MORTAL(len);
a0d0e21e
LW
4366 while (len-- > 0) {
4367 auint = *s++ & 255;
4368 sv = NEWSV(37, 0);
1e422769 4369 sv_setiv(sv, (IV)auint);
a0d0e21e
LW
4370 PUSHs(sv_2mortal(sv));
4371 }
4372 }
4373 break;
a0ed51b3
LW
4374 case 'U':
4375 if (len > strend - s)
4376 len = strend - s;
4377 if (checksum) {
4378 while (len-- > 0 && s < strend) {
43ea6eee 4379 STRLEN alen;
dcad2880 4380 auint = utf8_to_uv((U8*)s, strend - s, &alen, 0);
43ea6eee 4381 along = alen;
a0ed51b3 4382 s += along;
32d8b6e5 4383 if (checksum > 32)
65202027 4384 cdouble += (NV)auint;
32d8b6e5
GA
4385 else
4386 culong += auint;
a0ed51b3
LW
4387 }
4388 }
4389 else {
4390 EXTEND(SP, len);
4391 EXTEND_MORTAL(len);
4392 while (len-- > 0 && s < strend) {
43ea6eee 4393 STRLEN alen;
dcad2880 4394 auint = utf8_to_uv((U8*)s, strend - s, &alen, 0);
43ea6eee 4395 along = alen;
a0ed51b3
LW
4396 s += along;
4397 sv = NEWSV(37, 0);
bdeef251 4398 sv_setuv(sv, (UV)auint);
a0ed51b3
LW
4399 PUSHs(sv_2mortal(sv));
4400 }
4401 }
4402 break;
a0d0e21e 4403 case 's':
726ea183
JH
4404#if SHORTSIZE == SIZE16
4405 along = (strend - s) / SIZE16;
4406#else
ef54e1a4 4407 along = (strend - s) / (natint ? sizeof(short) : SIZE16);
726ea183 4408#endif
a0d0e21e
LW
4409 if (len > along)
4410 len = along;
4411 if (checksum) {
726ea183 4412#if SHORTSIZE != SIZE16
ef54e1a4 4413 if (natint) {
bf9315bb 4414 short ashort;
ef54e1a4
JH
4415 while (len-- > 0) {
4416 COPYNN(s, &ashort, sizeof(short));
4417 s += sizeof(short);
4418 culong += ashort;
4419
4420 }
4421 }
726ea183
JH
4422 else
4423#endif
4424 {
ef54e1a4
JH
4425 while (len-- > 0) {
4426 COPY16(s, &ashort);
c67712b2
JH
4427#if SHORTSIZE > SIZE16
4428 if (ashort > 32767)
4429 ashort -= 65536;
4430#endif
ef54e1a4
JH
4431 s += SIZE16;
4432 culong += ashort;
4433 }
a0d0e21e
LW
4434 }
4435 }
4436 else {
4437 EXTEND(SP, len);
bbce6d69 4438 EXTEND_MORTAL(len);
726ea183 4439#if SHORTSIZE != SIZE16
ef54e1a4 4440 if (natint) {
bf9315bb 4441 short ashort;
ef54e1a4
JH
4442 while (len-- > 0) {
4443 COPYNN(s, &ashort, sizeof(short));
4444 s += sizeof(short);
4445 sv = NEWSV(38, 0);
4446 sv_setiv(sv, (IV)ashort);
4447 PUSHs(sv_2mortal(sv));
4448 }
4449 }
726ea183
JH
4450 else
4451#endif
4452 {
ef54e1a4
JH
4453 while (len-- > 0) {
4454 COPY16(s, &ashort);
c67712b2
JH
4455#if SHORTSIZE > SIZE16
4456 if (ashort > 32767)
4457 ashort -= 65536;
4458#endif
ef54e1a4
JH
4459 s += SIZE16;
4460 sv = NEWSV(38, 0);
4461 sv_setiv(sv, (IV)ashort);
4462 PUSHs(sv_2mortal(sv));
4463 }
a0d0e21e
LW
4464 }
4465 }
4466 break;
4467 case 'v':
4468 case 'n':
4469 case 'S':
726ea183
JH
4470#if SHORTSIZE == SIZE16
4471 along = (strend - s) / SIZE16;
4472#else
ef54e1a4
JH
4473 unatint = natint && datumtype == 'S';
4474 along = (strend - s) / (unatint ? sizeof(unsigned short) : SIZE16);
726ea183 4475#endif
a0d0e21e
LW
4476 if (len > along)
4477 len = along;
4478 if (checksum) {
726ea183 4479#if SHORTSIZE != SIZE16
ef54e1a4 4480 if (unatint) {
bf9315bb 4481 unsigned short aushort;
ef54e1a4
JH
4482 while (len-- > 0) {
4483 COPYNN(s, &aushort, sizeof(unsigned short));
4484 s += sizeof(unsigned short);
4485 culong += aushort;
4486 }
4487 }
726ea183
JH
4488 else
4489#endif
4490 {
ef54e1a4
JH
4491 while (len-- > 0) {
4492 COPY16(s, &aushort);
4493 s += SIZE16;
a0d0e21e 4494#ifdef HAS_NTOHS
ef54e1a4
JH
4495 if (datumtype == 'n')
4496 aushort = PerlSock_ntohs(aushort);
79072805 4497#endif
a0d0e21e 4498#ifdef HAS_VTOHS
ef54e1a4
JH
4499 if (datumtype == 'v')
4500 aushort = vtohs(aushort);
79072805 4501#endif
ef54e1a4
JH
4502 culong += aushort;
4503 }
a0d0e21e
LW
4504 }
4505 }
4506 else {
4507 EXTEND(SP, len);
bbce6d69 4508 EXTEND_MORTAL(len);
726ea183 4509#if SHORTSIZE != SIZE16
ef54e1a4 4510 if (unatint) {
bf9315bb 4511 unsigned short aushort;
ef54e1a4
JH
4512 while (len-- > 0) {
4513 COPYNN(s, &aushort, sizeof(unsigned short));
4514 s += sizeof(unsigned short);
4515 sv = NEWSV(39, 0);
726ea183 4516 sv_setiv(sv, (UV)aushort);
ef54e1a4
JH
4517 PUSHs(sv_2mortal(sv));
4518 }
4519 }
726ea183
JH
4520 else
4521#endif
4522 {
ef54e1a4
JH
4523 while (len-- > 0) {
4524 COPY16(s, &aushort);
4525 s += SIZE16;
4526 sv = NEWSV(39, 0);
a0d0e21e 4527#ifdef HAS_NTOHS
ef54e1a4
JH
4528 if (datumtype == 'n')
4529 aushort = PerlSock_ntohs(aushort);
79072805 4530#endif
a0d0e21e 4531#ifdef HAS_VTOHS
ef54e1a4
JH
4532 if (datumtype == 'v')
4533 aushort = vtohs(aushort);
79072805 4534#endif
726ea183 4535 sv_setiv(sv, (UV)aushort);
ef54e1a4
JH
4536 PUSHs(sv_2mortal(sv));
4537 }
a0d0e21e
LW
4538 }
4539 }
4540 break;
4541 case 'i':
4542 along = (strend - s) / sizeof(int);
4543 if (len > along)
4544 len = along;
4545 if (checksum) {
4546 while (len-- > 0) {
4547 Copy(s, &aint, 1, int);
4548 s += sizeof(int);
4549 if (checksum > 32)
65202027 4550 cdouble += (NV)aint;
a0d0e21e
LW
4551 else
4552 culong += aint;
4553 }
4554 }
4555 else {
4556 EXTEND(SP, len);
bbce6d69 4557 EXTEND_MORTAL(len);
a0d0e21e
LW
4558 while (len-- > 0) {
4559 Copy(s, &aint, 1, int);
4560 s += sizeof(int);
4561 sv = NEWSV(40, 0);
20408e3c
GS
4562#ifdef __osf__
4563 /* Without the dummy below unpack("i", pack("i",-1))
4564 * return 0xFFffFFff instead of -1 for Digital Unix V4.0
13476c87
JH
4565 * cc with optimization turned on.
4566 *
4567 * The bug was detected in
4568 * DEC C V5.8-009 on Digital UNIX V4.0 (Rev. 1091) (V4.0E)
4569 * with optimization (-O4) turned on.
4570 * DEC C V5.2-040 on Digital UNIX V4.0 (Rev. 564) (V4.0B)
4571 * does not have this problem even with -O4.
4572 *
4573 * This bug was reported as DECC_BUGS 1431
4574 * and tracked internally as GEM_BUGS 7775.
4575 *
4576 * The bug is fixed in
4577 * Tru64 UNIX V5.0: Compaq C V6.1-006 or later
4578 * UNIX V4.0F support: DEC C V5.9-006 or later
4579 * UNIX V4.0E support: DEC C V5.8-011 or later
4580 * and also in DTK.
4581 *
4582 * See also few lines later for the same bug.
4583 */
20408e3c
GS
4584 (aint) ?
4585 sv_setiv(sv, (IV)aint) :
4586#endif
1e422769 4587 sv_setiv(sv, (IV)aint);
a0d0e21e
LW
4588 PUSHs(sv_2mortal(sv));
4589 }
4590 }
4591 break;
4592 case 'I':
4593 along = (strend - s) / sizeof(unsigned int);
4594 if (len > along)
4595 len = along;
4596 if (checksum) {
4597 while (len-- > 0) {
4598 Copy(s, &auint, 1, unsigned int);
4599 s += sizeof(unsigned int);
4600 if (checksum > 32)
65202027 4601 cdouble += (NV)auint;
a0d0e21e
LW
4602 else
4603 culong += auint;
4604 }
4605 }
4606 else {
4607 EXTEND(SP, len);
bbce6d69 4608 EXTEND_MORTAL(len);
a0d0e21e
LW
4609 while (len-- > 0) {
4610 Copy(s, &auint, 1, unsigned int);
4611 s += sizeof(unsigned int);
4612 sv = NEWSV(41, 0);
9d645a59
AB
4613#ifdef __osf__
4614 /* Without the dummy below unpack("I", pack("I",0xFFFFFFFF))
13476c87
JH
4615 * returns 1.84467440737096e+19 instead of 0xFFFFFFFF.
4616 * See details few lines earlier. */
9d645a59
AB
4617 (auint) ?
4618 sv_setuv(sv, (UV)auint) :
4619#endif
1e422769 4620 sv_setuv(sv, (UV)auint);
a0d0e21e
LW
4621 PUSHs(sv_2mortal(sv));
4622 }
4623 }
4624 break;
4625 case 'l':
726ea183
JH
4626#if LONGSIZE == SIZE32
4627 along = (strend - s) / SIZE32;
4628#else
ef54e1a4 4629 along = (strend - s) / (natint ? sizeof(long) : SIZE32);
726ea183 4630#endif
a0d0e21e
LW
4631 if (len > along)
4632 len = along;
4633 if (checksum) {
726ea183 4634#if LONGSIZE != SIZE32
ef54e1a4
JH
4635 if (natint) {
4636 while (len-- > 0) {
4637 COPYNN(s, &along, sizeof(long));
4638 s += sizeof(long);
4639 if (checksum > 32)
65202027 4640 cdouble += (NV)along;
ef54e1a4
JH
4641 else
4642 culong += along;
4643 }
4644 }
726ea183
JH
4645 else
4646#endif
4647 {
ef54e1a4 4648 while (len-- > 0) {
2f3a5373
JH
4649#if LONGSIZE > SIZE32 && INTSIZE == SIZE32
4650 I32 along;
4651#endif
ef54e1a4 4652 COPY32(s, &along);
c67712b2
JH
4653#if LONGSIZE > SIZE32
4654 if (along > 2147483647)
4655 along -= 4294967296;
4656#endif
ef54e1a4
JH
4657 s += SIZE32;
4658 if (checksum > 32)
65202027 4659 cdouble += (NV)along;
ef54e1a4
JH
4660 else
4661 culong += along;
4662 }
a0d0e21e
LW
4663 }
4664 }
4665 else {
4666 EXTEND(SP, len);
bbce6d69 4667 EXTEND_MORTAL(len);
726ea183 4668#if LONGSIZE != SIZE32
ef54e1a4
JH
4669 if (natint) {
4670 while (len-- > 0) {
4671 COPYNN(s, &along, sizeof(long));
4672 s += sizeof(long);
4673 sv = NEWSV(42, 0);
4674 sv_setiv(sv, (IV)along);
4675 PUSHs(sv_2mortal(sv));
4676 }
4677 }
726ea183
JH
4678 else
4679#endif
4680 {
ef54e1a4 4681 while (len-- > 0) {
2f3a5373
JH
4682#if LONGSIZE > SIZE32 && INTSIZE == SIZE32
4683 I32 along;
4684#endif
ef54e1a4 4685 COPY32(s, &along);
c67712b2
JH
4686#if LONGSIZE > SIZE32
4687 if (along > 2147483647)
4688 along -= 4294967296;
4689#endif
ef54e1a4
JH
4690 s += SIZE32;
4691 sv = NEWSV(42, 0);
4692 sv_setiv(sv, (IV)along);
4693 PUSHs(sv_2mortal(sv));
4694 }
a0d0e21e 4695 }
79072805 4696 }
a0d0e21e
LW
4697 break;
4698 case 'V':
4699 case 'N':
4700 case 'L':
726ea183
JH
4701#if LONGSIZE == SIZE32
4702 along = (strend - s) / SIZE32;
4703#else
4704 unatint = natint && datumtype == 'L';
ef54e1a4 4705 along = (strend - s) / (unatint ? sizeof(unsigned long) : SIZE32);
726ea183 4706#endif
a0d0e21e
LW
4707 if (len > along)
4708 len = along;
4709 if (checksum) {
726ea183 4710#if LONGSIZE != SIZE32
ef54e1a4 4711 if (unatint) {
bf9315bb 4712 unsigned long aulong;
ef54e1a4
JH
4713 while (len-- > 0) {
4714 COPYNN(s, &aulong, sizeof(unsigned long));
4715 s += sizeof(unsigned long);
4716 if (checksum > 32)
65202027 4717 cdouble += (NV)aulong;
ef54e1a4
JH
4718 else
4719 culong += aulong;
4720 }
4721 }
726ea183
JH
4722 else
4723#endif
4724 {
ef54e1a4
JH
4725 while (len-- > 0) {
4726 COPY32(s, &aulong);
4727 s += SIZE32;
a0d0e21e 4728#ifdef HAS_NTOHL
ef54e1a4
JH
4729 if (datumtype == 'N')
4730 aulong = PerlSock_ntohl(aulong);
79072805 4731#endif
a0d0e21e 4732#ifdef HAS_VTOHL
ef54e1a4
JH
4733 if (datumtype == 'V')
4734 aulong = vtohl(aulong);
79072805 4735#endif
ef54e1a4 4736 if (checksum > 32)
65202027 4737 cdouble += (NV)aulong;
ef54e1a4
JH
4738 else
4739 culong += aulong;
4740 }
a0d0e21e
LW
4741 }
4742 }
4743 else {
4744 EXTEND(SP, len);
bbce6d69 4745 EXTEND_MORTAL(len);
726ea183 4746#if LONGSIZE != SIZE32
ef54e1a4 4747 if (unatint) {
bf9315bb 4748 unsigned long aulong;
ef54e1a4
JH
4749 while (len-- > 0) {
4750 COPYNN(s, &aulong, sizeof(unsigned long));
4751 s += sizeof(unsigned long);
4752 sv = NEWSV(43, 0);
4753 sv_setuv(sv, (UV)aulong);
4754 PUSHs(sv_2mortal(sv));
4755 }
4756 }
726ea183
JH
4757 else
4758#endif
4759 {
ef54e1a4
JH
4760 while (len-- > 0) {
4761 COPY32(s, &aulong);
4762 s += SIZE32;
a0d0e21e 4763#ifdef HAS_NTOHL
ef54e1a4
JH
4764 if (datumtype == 'N')
4765 aulong = PerlSock_ntohl(aulong);
79072805 4766#endif
a0d0e21e 4767#ifdef HAS_VTOHL
ef54e1a4
JH
4768 if (datumtype == 'V')
4769 aulong = vtohl(aulong);
79072805 4770#endif
ef54e1a4
JH
4771 sv = NEWSV(43, 0);
4772 sv_setuv(sv, (UV)aulong);
4773 PUSHs(sv_2mortal(sv));
4774 }
a0d0e21e
LW
4775 }
4776 }
4777 break;
4778 case 'p':
4779 along = (strend - s) / sizeof(char*);
4780 if (len > along)
4781 len = along;
4782 EXTEND(SP, len);
bbce6d69 4783 EXTEND_MORTAL(len);
a0d0e21e
LW
4784 while (len-- > 0) {
4785 if (sizeof(char*) > strend - s)
4786 break;
4787 else {
4788 Copy(s, &aptr, 1, char*);
4789 s += sizeof(char*);
4790 }
4791 sv = NEWSV(44, 0);
4792 if (aptr)
4793 sv_setpv(sv, aptr);
4794 PUSHs(sv_2mortal(sv));
4795 }
4796 break;
def98dd4 4797 case 'w':
def98dd4 4798 EXTEND(SP, len);
bbce6d69 4799 EXTEND_MORTAL(len);
8ec5e241 4800 {
bbce6d69 4801 UV auv = 0;
4802 U32 bytes = 0;
4803
4804 while ((len > 0) && (s < strend)) {
4805 auv = (auv << 7) | (*s & 0x7f);
4806 if (!(*s++ & 0x80)) {
4807 bytes = 0;
4808 sv = NEWSV(40, 0);
4809 sv_setuv(sv, auv);
4810 PUSHs(sv_2mortal(sv));
4811 len--;
4812 auv = 0;
4813 }
4814 else if (++bytes >= sizeof(UV)) { /* promote to string */
bbce6d69 4815 char *t;
2d8e6c8d 4816 STRLEN n_a;
bbce6d69 4817
d2560b70 4818 sv = Perl_newSVpvf(aTHX_ "%.*"UVf, (int)TYPE_DIGITS(UV), auv);
bbce6d69 4819 while (s < strend) {
4820 sv = mul128(sv, *s & 0x7f);
4821 if (!(*s++ & 0x80)) {
4822 bytes = 0;
4823 break;
4824 }
4825 }
2d8e6c8d 4826 t = SvPV(sv, n_a);
bbce6d69 4827 while (*t == '0')
4828 t++;
4829 sv_chop(sv, t);
4830 PUSHs(sv_2mortal(sv));
4831 len--;
4832 auv = 0;
4833 }
4834 }
4835 if ((s >= strend) && bytes)
d470f89e 4836 DIE(aTHX_ "Unterminated compressed integer");
bbce6d69 4837 }
def98dd4 4838 break;
a0d0e21e
LW
4839 case 'P':
4840 EXTEND(SP, 1);
4841 if (sizeof(char*) > strend - s)
4842 break;
4843 else {
4844 Copy(s, &aptr, 1, char*);
4845 s += sizeof(char*);
4846 }
4847 sv = NEWSV(44, 0);
4848 if (aptr)
4849 sv_setpvn(sv, aptr, len);
4850 PUSHs(sv_2mortal(sv));
4851 break;
6b8eaf93 4852#ifdef HAS_QUAD
a0d0e21e 4853 case 'q':
d4217c7e
JH
4854 along = (strend - s) / sizeof(Quad_t);
4855 if (len > along)
4856 len = along;
a0d0e21e 4857 EXTEND(SP, len);
bbce6d69 4858 EXTEND_MORTAL(len);
a0d0e21e 4859 while (len-- > 0) {
ecfc5424 4860 if (s + sizeof(Quad_t) > strend)
a0d0e21e
LW
4861 aquad = 0;
4862 else {
ecfc5424
AD
4863 Copy(s, &aquad, 1, Quad_t);
4864 s += sizeof(Quad_t);
a0d0e21e
LW
4865 }
4866 sv = NEWSV(42, 0);
96e4d5b1 4867 if (aquad >= IV_MIN && aquad <= IV_MAX)
4868 sv_setiv(sv, (IV)aquad);
4869 else
65202027 4870 sv_setnv(sv, (NV)aquad);
a0d0e21e
LW
4871 PUSHs(sv_2mortal(sv));
4872 }
4873 break;
4874 case 'Q':
d4217c7e
JH
4875 along = (strend - s) / sizeof(Quad_t);
4876 if (len > along)
4877 len = along;
a0d0e21e 4878 EXTEND(SP, len);
bbce6d69 4879 EXTEND_MORTAL(len);
a0d0e21e 4880 while (len-- > 0) {
e862df63 4881 if (s + sizeof(Uquad_t) > strend)
a0d0e21e
LW
4882 auquad = 0;
4883 else {
e862df63
HB
4884 Copy(s, &auquad, 1, Uquad_t);
4885 s += sizeof(Uquad_t);
a0d0e21e
LW
4886 }
4887 sv = NEWSV(43, 0);
27612d38 4888 if (auquad <= UV_MAX)
96e4d5b1 4889 sv_setuv(sv, (UV)auquad);
4890 else
65202027 4891 sv_setnv(sv, (NV)auquad);
a0d0e21e
LW
4892 PUSHs(sv_2mortal(sv));
4893 }
4894 break;
79072805 4895#endif
a0d0e21e
LW
4896 /* float and double added gnb@melba.bby.oz.au 22/11/89 */
4897 case 'f':
4898 case 'F':
4899 along = (strend - s) / sizeof(float);
4900 if (len > along)
4901 len = along;
4902 if (checksum) {
4903 while (len-- > 0) {
4904 Copy(s, &afloat, 1, float);
4905 s += sizeof(float);
4906 cdouble += afloat;
4907 }
4908 }
4909 else {
4910 EXTEND(SP, len);
bbce6d69 4911 EXTEND_MORTAL(len);
a0d0e21e
LW
4912 while (len-- > 0) {
4913 Copy(s, &afloat, 1, float);
4914 s += sizeof(float);
4915 sv = NEWSV(47, 0);
65202027 4916 sv_setnv(sv, (NV)afloat);
a0d0e21e
LW
4917 PUSHs(sv_2mortal(sv));
4918 }
4919 }
4920 break;
4921 case 'd':
4922 case 'D':
4923 along = (strend - s) / sizeof(double);
4924 if (len > along)
4925 len = along;
4926 if (checksum) {
4927 while (len-- > 0) {
4928 Copy(s, &adouble, 1, double);
4929 s += sizeof(double);
4930 cdouble += adouble;
4931 }
4932 }
4933 else {
4934 EXTEND(SP, len);
bbce6d69 4935 EXTEND_MORTAL(len);
a0d0e21e
LW
4936 while (len-- > 0) {
4937 Copy(s, &adouble, 1, double);
4938 s += sizeof(double);
4939 sv = NEWSV(48, 0);
65202027 4940 sv_setnv(sv, (NV)adouble);
a0d0e21e
LW
4941 PUSHs(sv_2mortal(sv));
4942 }
4943 }
4944 break;
4945 case 'u':
9d116dd7
JH
4946 /* MKS:
4947 * Initialise the decode mapping. By using a table driven
4948 * algorithm, the code will be character-set independent
4949 * (and just as fast as doing character arithmetic)
4950 */
80252599 4951 if (PL_uudmap['M'] == 0) {
9d116dd7 4952 int i;
b13b2135 4953
80252599 4954 for (i = 0; i < sizeof(PL_uuemap); i += 1)
155aba94 4955 PL_uudmap[(U8)PL_uuemap[i]] = i;
9d116dd7
JH
4956 /*
4957 * Because ' ' and '`' map to the same value,
4958 * we need to decode them both the same.
4959 */
80252599 4960 PL_uudmap[' '] = 0;
9d116dd7
JH
4961 }
4962
a0d0e21e
LW
4963 along = (strend - s) * 3 / 4;
4964 sv = NEWSV(42, along);
f12c7020 4965 if (along)
4966 SvPOK_on(sv);
9d116dd7 4967 while (s < strend && *s > ' ' && ISUUCHAR(*s)) {
a0d0e21e
LW
4968 I32 a, b, c, d;
4969 char hunk[4];
79072805 4970
a0d0e21e 4971 hunk[3] = '\0';
155aba94 4972 len = PL_uudmap[*(U8*)s++] & 077;
a0d0e21e 4973 while (len > 0) {
9d116dd7 4974 if (s < strend && ISUUCHAR(*s))
155aba94 4975 a = PL_uudmap[*(U8*)s++] & 077;
9d116dd7
JH
4976 else
4977 a = 0;
4978 if (s < strend && ISUUCHAR(*s))
155aba94 4979 b = PL_uudmap[*(U8*)s++] & 077;
9d116dd7
JH
4980 else
4981 b = 0;
4982 if (s < strend && ISUUCHAR(*s))
155aba94 4983 c = PL_uudmap[*(U8*)s++] & 077;
9d116dd7
JH
4984 else
4985 c = 0;
4986 if (s < strend && ISUUCHAR(*s))
155aba94 4987 d = PL_uudmap[*(U8*)s++] & 077;
a0d0e21e
LW
4988 else
4989 d = 0;
4e35701f
NIS
4990 hunk[0] = (a << 2) | (b >> 4);
4991 hunk[1] = (b << 4) | (c >> 2);
4992 hunk[2] = (c << 6) | d;
4993 sv_catpvn(sv, hunk, (len > 3) ? 3 : len);
a0d0e21e
LW
4994 len -= 3;
4995 }
4996 if (*s == '\n')
4997 s++;
4998 else if (s[1] == '\n') /* possible checksum byte */
4999 s += 2;
79072805 5000 }
a0d0e21e
LW
5001 XPUSHs(sv_2mortal(sv));
5002 break;
79072805 5003 }
a0d0e21e
LW
5004 if (checksum) {
5005 sv = NEWSV(42, 0);
5006 if (strchr("fFdD", datumtype) ||
32d8b6e5 5007 (checksum > 32 && strchr("iIlLNU", datumtype)) ) {
65202027 5008 NV trouble;
79072805 5009
a0d0e21e
LW
5010 adouble = 1.0;
5011 while (checksum >= 16) {
5012 checksum -= 16;
5013 adouble *= 65536.0;
5014 }
5015 while (checksum >= 4) {
5016 checksum -= 4;
5017 adouble *= 16.0;
5018 }
5019 while (checksum--)
5020 adouble *= 2.0;
5021 along = (1 << checksum) - 1;
5022 while (cdouble < 0.0)
5023 cdouble += adouble;
65202027 5024 cdouble = Perl_modf(cdouble / adouble, &trouble) * adouble;
a0d0e21e
LW
5025 sv_setnv(sv, cdouble);
5026 }
5027 else {
5028 if (checksum < 32) {
96e4d5b1 5029 aulong = (1 << checksum) - 1;
5030 culong &= aulong;
a0d0e21e 5031 }
96e4d5b1 5032 sv_setuv(sv, (UV)culong);
a0d0e21e
LW
5033 }
5034 XPUSHs(sv_2mortal(sv));
5035 checksum = 0;
79072805 5036 }
79072805 5037 }
dd58a1ab 5038 if (SP - PL_stack_base == start_sp_offset && gimme == G_SCALAR)
3280af22 5039 PUSHs(&PL_sv_undef);
79072805 5040 RETURN;
79072805
LW
5041}
5042
76e3520e 5043STATIC void
cea2e8a9 5044S_doencodes(pTHX_ register SV *sv, register char *s, register I32 len)
79072805 5045{
a0d0e21e 5046 char hunk[5];
79072805 5047
80252599 5048 *hunk = PL_uuemap[len];
a0d0e21e
LW
5049 sv_catpvn(sv, hunk, 1);
5050 hunk[4] = '\0';
f264d472 5051 while (len > 2) {
80252599
GS
5052 hunk[0] = PL_uuemap[(077 & (*s >> 2))];
5053 hunk[1] = PL_uuemap[(077 & (((*s << 4) & 060) | ((s[1] >> 4) & 017)))];
5054 hunk[2] = PL_uuemap[(077 & (((s[1] << 2) & 074) | ((s[2] >> 6) & 03)))];
5055 hunk[3] = PL_uuemap[(077 & (s[2] & 077))];
a0d0e21e
LW
5056 sv_catpvn(sv, hunk, 4);
5057 s += 3;
5058 len -= 3;
5059 }
f264d472
GS
5060 if (len > 0) {
5061 char r = (len > 1 ? s[1] : '\0');
80252599
GS
5062 hunk[0] = PL_uuemap[(077 & (*s >> 2))];
5063 hunk[1] = PL_uuemap[(077 & (((*s << 4) & 060) | ((r >> 4) & 017)))];
5064 hunk[2] = PL_uuemap[(077 & ((r << 2) & 074))];
5065 hunk[3] = PL_uuemap[0];
f264d472 5066 sv_catpvn(sv, hunk, 4);
a0d0e21e
LW
5067 }
5068 sv_catpvn(sv, "\n", 1);
79072805
LW
5069}
5070
79cb57f6 5071STATIC SV *
cea2e8a9 5072S_is_an_int(pTHX_ char *s, STRLEN l)
55497cff 5073{
2d8e6c8d 5074 STRLEN n_a;
79cb57f6 5075 SV *result = newSVpvn(s, l);
2d8e6c8d 5076 char *result_c = SvPV(result, n_a); /* convenience */
55497cff 5077 char *out = result_c;
5078 bool skip = 1;
5079 bool ignore = 0;
5080
5081 while (*s) {
5082 switch (*s) {
5083 case ' ':
5084 break;
5085 case '+':
5086 if (!skip) {
5087 SvREFCNT_dec(result);
5088 return (NULL);
5089 }
5090 break;
5091 case '0':
5092 case '1':
5093 case '2':
5094 case '3':
5095 case '4':
5096 case '5':
5097 case '6':
5098 case '7':
5099 case '8':
5100 case '9':
5101 skip = 0;
5102 if (!ignore) {
5103 *(out++) = *s;
5104 }
5105 break;
5106 case '.':
5107 ignore = 1;
5108 break;
5109 default:
5110 SvREFCNT_dec(result);
5111 return (NULL);
5112 }
5113 s++;
5114 }
5115 *(out++) = '\0';
5116 SvCUR_set(result, out - result_c);
5117 return (result);
5118}
5119
864dbfa3 5120/* pnum must be '\0' terminated */
76e3520e 5121STATIC int
cea2e8a9 5122S_div128(pTHX_ SV *pnum, bool *done)
55497cff 5123{
5124 STRLEN len;
5125 char *s = SvPV(pnum, len);
5126 int m = 0;
5127 int r = 0;
5128 char *t = s;
5129
5130 *done = 1;
5131 while (*t) {
5132 int i;
5133
5134 i = m * 10 + (*t - '0');
5135 m = i & 0x7F;
5136 r = (i >> 7); /* r < 10 */
5137 if (r) {
5138 *done = 0;
5139 }
5140 *(t++) = '0' + r;
5141 }
5142 *(t++) = '\0';
5143 SvCUR_set(pnum, (STRLEN) (t - s));
5144 return (m);
5145}
5146
5147
a0d0e21e 5148PP(pp_pack)
79072805 5149{
4e35701f 5150 djSP; dMARK; dORIGMARK; dTARGET;
a0d0e21e
LW
5151 register SV *cat = TARG;
5152 register I32 items;
5153 STRLEN fromlen;
5154 register char *pat = SvPVx(*++MARK, fromlen);
036b4402 5155 char *patcopy;
a0d0e21e
LW
5156 register char *patend = pat + fromlen;
5157 register I32 len;
5158 I32 datumtype;
5159 SV *fromstr;
5160 /*SUPPRESS 442*/
5161 static char null10[] = {0,0,0,0,0,0,0,0,0,0};
5162 static char *space10 = " ";
79072805 5163
a0d0e21e
LW
5164 /* These must not be in registers: */
5165 char achar;
5166 I16 ashort;
5167 int aint;
5168 unsigned int auint;
5169 I32 along;
5170 U32 aulong;
6b8eaf93 5171#ifdef HAS_QUAD
ecfc5424 5172 Quad_t aquad;
e862df63 5173 Uquad_t auquad;
79072805 5174#endif
a0d0e21e
LW
5175 char *aptr;
5176 float afloat;
5177 double adouble;
fb73857a 5178 int commas = 0;
726ea183 5179#ifdef PERL_NATINT_PACK
ef54e1a4 5180 int natint; /* native integer */
726ea183 5181#endif
79072805 5182
a0d0e21e
LW
5183 items = SP - MARK;
5184 MARK++;
5185 sv_setpvn(cat, "", 0);
036b4402 5186 patcopy = pat;
a0d0e21e 5187 while (pat < patend) {
43192e07
IP
5188 SV *lengthcode = Nullsv;
5189#define NEXTFROM ( lengthcode ? lengthcode : items-- > 0 ? *MARK++ : &PL_sv_no)
bbdab043 5190 datumtype = *pat++ & 0xFF;
726ea183 5191#ifdef PERL_NATINT_PACK
ef54e1a4 5192 natint = 0;
726ea183 5193#endif
036b4402
GS
5194 if (isSPACE(datumtype)) {
5195 patcopy++;
bbdab043 5196 continue;
036b4402 5197 }
b13b2135 5198 if (datumtype == 'U' && pat == patcopy+1)
036b4402 5199 SvUTF8_on(cat);
17f4a12d
IZ
5200 if (datumtype == '#') {
5201 while (pat < patend && *pat != '\n')
5202 pat++;
5203 continue;
5204 }
f61d411c 5205 if (*pat == '!') {
ef54e1a4
JH
5206 char *natstr = "sSiIlL";
5207
5208 if (strchr(natstr, datumtype)) {
726ea183 5209#ifdef PERL_NATINT_PACK
ef54e1a4 5210 natint = 1;
726ea183 5211#endif
ef54e1a4
JH
5212 pat++;
5213 }
5214 else
d470f89e 5215 DIE(aTHX_ "'!' allowed only after types %s", natstr);
ef54e1a4 5216 }
a0d0e21e
LW
5217 if (*pat == '*') {
5218 len = strchr("@Xxu", datumtype) ? 0 : items;
5219 pat++;
5220 }
5221 else if (isDIGIT(*pat)) {
5222 len = *pat++ - '0';
06387354 5223 while (isDIGIT(*pat)) {
a0d0e21e 5224 len = (len * 10) + (*pat++ - '0');
06387354 5225 if (len < 0)
d470f89e 5226 DIE(aTHX_ "Repeat count in pack overflows");
06387354 5227 }
a0d0e21e
LW
5228 }
5229 else
5230 len = 1;
17f4a12d 5231 if (*pat == '/') {
43192e07 5232 ++pat;
155aba94 5233 if ((*pat != 'a' && *pat != 'A' && *pat != 'Z') || pat[1] != '*')
17f4a12d 5234 DIE(aTHX_ "/ must be followed by a*, A* or Z*");
43192e07 5235 lengthcode = sv_2mortal(newSViv(sv_len(items > 0
3399f041
GS
5236 ? *MARK : &PL_sv_no)
5237 + (*pat == 'Z' ? 1 : 0)));
43192e07 5238 }
a0d0e21e
LW
5239 switch(datumtype) {
5240 default:
d470f89e 5241 DIE(aTHX_ "Invalid type in pack: '%c'", (int)datumtype);
fb73857a 5242 case ',': /* grandfather in commas but with a warning */
e476b1b5
GS
5243 if (commas++ == 0 && ckWARN(WARN_PACK))
5244 Perl_warner(aTHX_ WARN_PACK,
43192e07 5245 "Invalid type in pack: '%c'", (int)datumtype);
fb73857a 5246 break;
a0d0e21e 5247 case '%':
cea2e8a9 5248 DIE(aTHX_ "%% may only be used in unpack");
a0d0e21e
LW
5249 case '@':
5250 len -= SvCUR(cat);
5251 if (len > 0)
5252 goto grow;
5253 len = -len;
5254 if (len > 0)
5255 goto shrink;
5256 break;
5257 case 'X':
5258 shrink:
5259 if (SvCUR(cat) < len)
cea2e8a9 5260 DIE(aTHX_ "X outside of string");
a0d0e21e
LW
5261 SvCUR(cat) -= len;
5262 *SvEND(cat) = '\0';
5263 break;
5264 case 'x':
5265 grow:
5266 while (len >= 10) {
5267 sv_catpvn(cat, null10, 10);
5268 len -= 10;
5269 }
5270 sv_catpvn(cat, null10, len);
5271 break;
5272 case 'A':
5a929a98 5273 case 'Z':
a0d0e21e
LW
5274 case 'a':
5275 fromstr = NEXTFROM;
5276 aptr = SvPV(fromstr, fromlen);
2b6c5635 5277 if (pat[-1] == '*') {
a0d0e21e 5278 len = fromlen;
2b6c5635
GS
5279 if (datumtype == 'Z')
5280 ++len;
5281 }
5282 if (fromlen >= len) {
a0d0e21e 5283 sv_catpvn(cat, aptr, len);
2b6c5635
GS
5284 if (datumtype == 'Z')
5285 *(SvEND(cat)-1) = '\0';
5286 }
a0d0e21e
LW
5287 else {
5288 sv_catpvn(cat, aptr, fromlen);
5289 len -= fromlen;
5290 if (datumtype == 'A') {
5291 while (len >= 10) {
5292 sv_catpvn(cat, space10, 10);
5293 len -= 10;
5294 }
5295 sv_catpvn(cat, space10, len);
5296 }
5297 else {
5298 while (len >= 10) {
5299 sv_catpvn(cat, null10, 10);
5300 len -= 10;
5301 }
5302 sv_catpvn(cat, null10, len);
5303 }
5304 }
5305 break;
5306 case 'B':
5307 case 'b':
5308 {
abdc5761 5309 register char *str;
a0d0e21e 5310 I32 saveitems;
79072805 5311
a0d0e21e
LW
5312 fromstr = NEXTFROM;
5313 saveitems = items;
abdc5761 5314 str = SvPV(fromstr, fromlen);
a0d0e21e
LW
5315 if (pat[-1] == '*')
5316 len = fromlen;
a0d0e21e
LW
5317 aint = SvCUR(cat);
5318 SvCUR(cat) += (len+7)/8;
5319 SvGROW(cat, SvCUR(cat) + 1);
5320 aptr = SvPVX(cat) + aint;
5321 if (len > fromlen)
5322 len = fromlen;
5323 aint = len;
5324 items = 0;
5325 if (datumtype == 'B') {
5326 for (len = 0; len++ < aint;) {
abdc5761 5327 items |= *str++ & 1;
a0d0e21e
LW
5328 if (len & 7)
5329 items <<= 1;
5330 else {
5331 *aptr++ = items & 0xff;
5332 items = 0;
5333 }
5334 }
5335 }
5336 else {
5337 for (len = 0; len++ < aint;) {
abdc5761 5338 if (*str++ & 1)
a0d0e21e
LW
5339 items |= 128;
5340 if (len & 7)
5341 items >>= 1;
5342 else {
5343 *aptr++ = items & 0xff;
5344 items = 0;
5345 }
5346 }
5347 }
5348 if (aint & 7) {
5349 if (datumtype == 'B')
5350 items <<= 7 - (aint & 7);
5351 else
5352 items >>= 7 - (aint & 7);
5353 *aptr++ = items & 0xff;
5354 }
abdc5761
GS
5355 str = SvPVX(cat) + SvCUR(cat);
5356 while (aptr <= str)
a0d0e21e 5357 *aptr++ = '\0';
79072805 5358
a0d0e21e
LW
5359 items = saveitems;
5360 }
5361 break;
5362 case 'H':
5363 case 'h':
5364 {
abdc5761 5365 register char *str;
a0d0e21e 5366 I32 saveitems;
79072805 5367
a0d0e21e
LW
5368 fromstr = NEXTFROM;
5369 saveitems = items;
abdc5761 5370 str = SvPV(fromstr, fromlen);
a0d0e21e
LW
5371 if (pat[-1] == '*')
5372 len = fromlen;
a0d0e21e
LW
5373 aint = SvCUR(cat);
5374 SvCUR(cat) += (len+1)/2;
5375 SvGROW(cat, SvCUR(cat) + 1);
5376 aptr = SvPVX(cat) + aint;
5377 if (len > fromlen)
5378 len = fromlen;
5379 aint = len;
5380 items = 0;
5381 if (datumtype == 'H') {
5382 for (len = 0; len++ < aint;) {
abdc5761
GS
5383 if (isALPHA(*str))
5384 items |= ((*str++ & 15) + 9) & 15;
a0d0e21e 5385 else
abdc5761 5386 items |= *str++ & 15;
a0d0e21e
LW
5387 if (len & 1)
5388 items <<= 4;
5389 else {
5390 *aptr++ = items & 0xff;
5391 items = 0;
5392 }
5393 }
5394 }
5395 else {
5396 for (len = 0; len++ < aint;) {
abdc5761
GS
5397 if (isALPHA(*str))
5398 items |= (((*str++ & 15) + 9) & 15) << 4;
a0d0e21e 5399 else
abdc5761 5400 items |= (*str++ & 15) << 4;
a0d0e21e
LW
5401 if (len & 1)
5402 items >>= 4;
5403 else {
5404 *aptr++ = items & 0xff;
5405 items = 0;
5406 }
5407 }
5408 }
5409 if (aint & 1)
5410 *aptr++ = items & 0xff;
abdc5761
GS
5411 str = SvPVX(cat) + SvCUR(cat);
5412 while (aptr <= str)
a0d0e21e 5413 *aptr++ = '\0';
79072805 5414
a0d0e21e
LW
5415 items = saveitems;
5416 }
5417 break;
5418 case 'C':
5419 case 'c':
5420 while (len-- > 0) {
5421 fromstr = NEXTFROM;
5422 aint = SvIV(fromstr);
5423 achar = aint;
5424 sv_catpvn(cat, &achar, sizeof(char));
5425 }
5426 break;
a0ed51b3
LW
5427 case 'U':
5428 while (len-- > 0) {
5429 fromstr = NEXTFROM;
5430 auint = SvUV(fromstr);
ad391ad9 5431 SvGROW(cat, SvCUR(cat) + UTF8_MAXLEN + 1);
dfe13c55
GS
5432 SvCUR_set(cat, (char*)uv_to_utf8((U8*)SvEND(cat),auint)
5433 - SvPVX(cat));
a0ed51b3
LW
5434 }
5435 *SvEND(cat) = '\0';
5436 break;
a0d0e21e
LW
5437 /* Float and double added by gnb@melba.bby.oz.au 22/11/89 */
5438 case 'f':
5439 case 'F':
5440 while (len-- > 0) {
5441 fromstr = NEXTFROM;
5442 afloat = (float)SvNV(fromstr);
5443 sv_catpvn(cat, (char *)&afloat, sizeof (float));
5444 }
5445 break;
5446 case 'd':
5447 case 'D':
5448 while (len-- > 0) {
5449 fromstr = NEXTFROM;
5450 adouble = (double)SvNV(fromstr);
5451 sv_catpvn(cat, (char *)&adouble, sizeof (double));
5452 }
5453 break;
5454 case 'n':
5455 while (len-- > 0) {
5456 fromstr = NEXTFROM;
5457 ashort = (I16)SvIV(fromstr);
5458#ifdef HAS_HTONS
6ad3d225 5459 ashort = PerlSock_htons(ashort);
79072805 5460#endif
96e4d5b1 5461 CAT16(cat, &ashort);
a0d0e21e
LW
5462 }
5463 break;
5464 case 'v':
5465 while (len-- > 0) {
5466 fromstr = NEXTFROM;
5467 ashort = (I16)SvIV(fromstr);
5468#ifdef HAS_HTOVS
5469 ashort = htovs(ashort);
79072805 5470#endif
96e4d5b1 5471 CAT16(cat, &ashort);
a0d0e21e
LW
5472 }
5473 break;
5474 case 'S':
726ea183 5475#if SHORTSIZE != SIZE16
ef54e1a4
JH
5476 if (natint) {
5477 unsigned short aushort;
5478
5479 while (len-- > 0) {
5480 fromstr = NEXTFROM;
5481 aushort = SvUV(fromstr);
5482 sv_catpvn(cat, (char *)&aushort, sizeof(unsigned short));
5483 }
5484 }
726ea183
JH
5485 else
5486#endif
5487 {
ef54e1a4
JH
5488 U16 aushort;
5489
5490 while (len-- > 0) {
5491 fromstr = NEXTFROM;
726ea183 5492 aushort = (U16)SvUV(fromstr);
ef54e1a4
JH
5493 CAT16(cat, &aushort);
5494 }
726ea183 5495
ef54e1a4
JH
5496 }
5497 break;
a0d0e21e 5498 case 's':
c67712b2 5499#if SHORTSIZE != SIZE16
ef54e1a4 5500 if (natint) {
bf9315bb
GS
5501 short ashort;
5502
ef54e1a4
JH
5503 while (len-- > 0) {
5504 fromstr = NEXTFROM;
5505 ashort = SvIV(fromstr);
5506 sv_catpvn(cat, (char *)&ashort, sizeof(short));
5507 }
5508 }
726ea183
JH
5509 else
5510#endif
5511 {
ef54e1a4
JH
5512 while (len-- > 0) {
5513 fromstr = NEXTFROM;
5514 ashort = (I16)SvIV(fromstr);
5515 CAT16(cat, &ashort);
5516 }
a0d0e21e
LW
5517 }
5518 break;
5519 case 'I':
5520 while (len-- > 0) {
5521 fromstr = NEXTFROM;
96e4d5b1 5522 auint = SvUV(fromstr);
a0d0e21e
LW
5523 sv_catpvn(cat, (char*)&auint, sizeof(unsigned int));
5524 }
5525 break;
def98dd4
UP
5526 case 'w':
5527 while (len-- > 0) {
bbce6d69 5528 fromstr = NEXTFROM;
65202027 5529 adouble = Perl_floor(SvNV(fromstr));
bbce6d69 5530
5531 if (adouble < 0)
d470f89e 5532 DIE(aTHX_ "Cannot compress negative numbers");
bbce6d69 5533
46fc3d4c 5534 if (
8bda1795
ML
5535#if UVSIZE > 4 && UVSIZE >= NVSIZE
5536 adouble <= 0xffffffff
ef2d312d 5537#else
8bda1795
ML
5538# ifdef CXUX_BROKEN_CONSTANT_CONVERT
5539 adouble <= UV_MAX_cxux
5540# else
46fc3d4c 5541 adouble <= UV_MAX
8bda1795 5542# endif
46fc3d4c 5543#endif
5544 )
5545 {
bbce6d69 5546 char buf[1 + sizeof(UV)];
5547 char *in = buf + sizeof(buf);
db7c17d7 5548 UV auv = U_V(adouble);
bbce6d69 5549
5550 do {
5551 *--in = (auv & 0x7f) | 0x80;
5552 auv >>= 7;
5553 } while (auv);
5554 buf[sizeof(buf) - 1] &= 0x7f; /* clear continue bit */
5555 sv_catpvn(cat, in, (buf + sizeof(buf)) - in);
5556 }
5557 else if (SvPOKp(fromstr)) { /* decimal string arithmetics */
5558 char *from, *result, *in;
5559 SV *norm;
5560 STRLEN len;
5561 bool done;
8ec5e241 5562
bbce6d69 5563 /* Copy string and check for compliance */
5564 from = SvPV(fromstr, len);
5565 if ((norm = is_an_int(from, len)) == NULL)
d470f89e 5566 DIE(aTHX_ "can compress only unsigned integer");
bbce6d69 5567
5568 New('w', result, len, char);
5569 in = result + len;
5570 done = FALSE;
5571 while (!done)
5572 *--in = div128(norm, &done) | 0x80;
5573 result[len - 1] &= 0x7F; /* clear continue bit */
5574 sv_catpvn(cat, in, (result + len) - in);
5f05dabc 5575 Safefree(result);
bbce6d69 5576 SvREFCNT_dec(norm); /* free norm */
def98dd4 5577 }
bbce6d69 5578 else if (SvNOKp(fromstr)) {
5579 char buf[sizeof(double) * 2]; /* 8/7 <= 2 */
5580 char *in = buf + sizeof(buf);
5581
5582 do {
5583 double next = floor(adouble / 128);
5584 *--in = (unsigned char)(adouble - (next * 128)) | 0x80;
acae6be1 5585 if (in <= buf) /* this cannot happen ;-) */
d470f89e 5586 DIE(aTHX_ "Cannot compress integer");
acae6be1 5587 in--;
bbce6d69 5588 adouble = next;
5589 } while (adouble > 0);
5590 buf[sizeof(buf) - 1] &= 0x7f; /* clear continue bit */
5591 sv_catpvn(cat, in, (buf + sizeof(buf)) - in);
5592 }
5593 else
d470f89e 5594 DIE(aTHX_ "Cannot compress non integer");
bbce6d69 5595 }
def98dd4 5596 break;
a0d0e21e
LW
5597 case 'i':
5598 while (len-- > 0) {
5599 fromstr = NEXTFROM;
5600 aint = SvIV(fromstr);
5601 sv_catpvn(cat, (char*)&aint, sizeof(int));
5602 }
5603 break;
5604 case 'N':
5605 while (len-- > 0) {
5606 fromstr = NEXTFROM;
96e4d5b1 5607 aulong = SvUV(fromstr);
a0d0e21e 5608#ifdef HAS_HTONL
6ad3d225 5609 aulong = PerlSock_htonl(aulong);
79072805 5610#endif
96e4d5b1 5611 CAT32(cat, &aulong);
a0d0e21e
LW
5612 }
5613 break;
5614 case 'V':
5615 while (len-- > 0) {
5616 fromstr = NEXTFROM;
96e4d5b1 5617 aulong = SvUV(fromstr);
a0d0e21e
LW
5618#ifdef HAS_HTOVL
5619 aulong = htovl(aulong);
79072805 5620#endif
96e4d5b1 5621 CAT32(cat, &aulong);
a0d0e21e
LW
5622 }
5623 break;
5624 case 'L':
726ea183 5625#if LONGSIZE != SIZE32
ef54e1a4 5626 if (natint) {
bf9315bb
GS
5627 unsigned long aulong;
5628
ef54e1a4
JH
5629 while (len-- > 0) {
5630 fromstr = NEXTFROM;
5631 aulong = SvUV(fromstr);
5632 sv_catpvn(cat, (char *)&aulong, sizeof(unsigned long));
5633 }
5634 }
726ea183
JH
5635 else
5636#endif
5637 {
ef54e1a4
JH
5638 while (len-- > 0) {
5639 fromstr = NEXTFROM;
5640 aulong = SvUV(fromstr);
5641 CAT32(cat, &aulong);
5642 }
a0d0e21e
LW
5643 }
5644 break;
5645 case 'l':
726ea183 5646#if LONGSIZE != SIZE32
ef54e1a4 5647 if (natint) {
bf9315bb
GS
5648 long along;
5649
ef54e1a4
JH
5650 while (len-- > 0) {
5651 fromstr = NEXTFROM;
5652 along = SvIV(fromstr);
5653 sv_catpvn(cat, (char *)&along, sizeof(long));
5654 }
5655 }
726ea183
JH
5656 else
5657#endif
5658 {
ef54e1a4
JH
5659 while (len-- > 0) {
5660 fromstr = NEXTFROM;
5661 along = SvIV(fromstr);
5662 CAT32(cat, &along);
5663 }
a0d0e21e
LW
5664 }
5665 break;
6b8eaf93 5666#ifdef HAS_QUAD
a0d0e21e
LW
5667 case 'Q':
5668 while (len-- > 0) {
5669 fromstr = NEXTFROM;
bf9315bb 5670 auquad = (Uquad_t)SvUV(fromstr);
e862df63 5671 sv_catpvn(cat, (char*)&auquad, sizeof(Uquad_t));
a0d0e21e
LW
5672 }
5673 break;
5674 case 'q':
5675 while (len-- > 0) {
5676 fromstr = NEXTFROM;
ecfc5424
AD
5677 aquad = (Quad_t)SvIV(fromstr);
5678 sv_catpvn(cat, (char*)&aquad, sizeof(Quad_t));
a0d0e21e
LW
5679 }
5680 break;
1b8cd678 5681#endif
a0d0e21e
LW
5682 case 'P':
5683 len = 1; /* assume SV is correct length */
5684 /* FALL THROUGH */
5685 case 'p':
5686 while (len-- > 0) {
5687 fromstr = NEXTFROM;
3280af22 5688 if (fromstr == &PL_sv_undef)
84902520 5689 aptr = NULL;
72dbcb4b 5690 else {
2d8e6c8d 5691 STRLEN n_a;
84902520
TB
5692 /* XXX better yet, could spirit away the string to
5693 * a safe spot and hang on to it until the result
5694 * of pack() (and all copies of the result) are
5695 * gone.
5696 */
e476b1b5 5697 if (ckWARN(WARN_PACK) && (SvTEMP(fromstr)
014822e4
GS
5698 || (SvPADTMP(fromstr)
5699 && !SvREADONLY(fromstr))))
5700 {
e476b1b5 5701 Perl_warner(aTHX_ WARN_PACK,
599cee73 5702 "Attempt to pack pointer to temporary value");
014822e4 5703 }
84902520 5704 if (SvPOK(fromstr) || SvNIOK(fromstr))
2d8e6c8d 5705 aptr = SvPV(fromstr,n_a);
84902520 5706 else
2d8e6c8d 5707 aptr = SvPV_force(fromstr,n_a);
72dbcb4b 5708 }
a0d0e21e
LW
5709 sv_catpvn(cat, (char*)&aptr, sizeof(char*));
5710 }
5711 break;
5712 case 'u':
5713 fromstr = NEXTFROM;
5714 aptr = SvPV(fromstr, fromlen);
5715 SvGROW(cat, fromlen * 4 / 3);
5716 if (len <= 1)
5717 len = 45;
5718 else
5719 len = len / 3 * 3;
5720 while (fromlen > 0) {
5721 I32 todo;
79072805 5722
a0d0e21e
LW
5723 if (fromlen > len)
5724 todo = len;
5725 else
5726 todo = fromlen;
5727 doencodes(cat, aptr, todo);
5728 fromlen -= todo;
5729 aptr += todo;
5730 }
5731 break;
5732 }
5733 }
5734 SvSETMAGIC(cat);
5735 SP = ORIGMARK;
5736 PUSHs(cat);
5737 RETURN;
79072805 5738}
a0d0e21e 5739#undef NEXTFROM
79072805 5740
8ec5e241 5741
a0d0e21e 5742PP(pp_split)
79072805 5743{
4e35701f 5744 djSP; dTARG;
a0d0e21e 5745 AV *ary;
467f0320 5746 register IV limit = POPi; /* note, negative is forever */
a0d0e21e 5747 SV *sv = POPs;
93f04dac 5748 bool doutf8 = DO_UTF8(sv);
a0d0e21e
LW
5749 STRLEN len;
5750 register char *s = SvPV(sv, len);
5751 char *strend = s + len;
44a8e56a 5752 register PMOP *pm;
d9f97599 5753 register REGEXP *rx;
a0d0e21e
LW
5754 register SV *dstr;
5755 register char *m;
5756 I32 iters = 0;
5757 I32 maxiters = (strend - s) + 10;
5758 I32 i;
5759 char *orig;
5760 I32 origlimit = limit;
5761 I32 realarray = 0;
5762 I32 base;
3280af22 5763 AV *oldstack = PL_curstack;
54310121 5764 I32 gimme = GIMME_V;
3280af22 5765 I32 oldsave = PL_savestack_ix;
8ec5e241
NIS
5766 I32 make_mortal = 1;
5767 MAGIC *mg = (MAGIC *) NULL;
79072805 5768
44a8e56a 5769#ifdef DEBUGGING
5770 Copy(&LvTARGOFF(POPs), &pm, 1, PMOP*);
5771#else
5772 pm = (PMOP*)POPs;
5773#endif
a0d0e21e 5774 if (!pm || !s)
2269b42e 5775 DIE(aTHX_ "panic: pp_split");
d9f97599 5776 rx = pm->op_pmregexp;
bbce6d69 5777
5778 TAINT_IF((pm->op_pmflags & PMf_LOCALE) &&
5779 (pm->op_pmflags & (PMf_WHITE | PMf_SKIPWHITE)));
5780
971a9dd3
GS
5781 if (pm->op_pmreplroot) {
5782#ifdef USE_ITHREADS
5783 ary = GvAVn((GV*)PL_curpad[(PADOFFSET)pm->op_pmreplroot]);
5784#else
a0d0e21e 5785 ary = GvAVn((GV*)pm->op_pmreplroot);
971a9dd3
GS
5786#endif
5787 }
a0d0e21e 5788 else if (gimme != G_ARRAY)
6d4ff0d2 5789#ifdef USE_THREADS
533c011a 5790 ary = (AV*)PL_curpad[0];
6d4ff0d2 5791#else
3280af22 5792 ary = GvAVn(PL_defgv);
6d4ff0d2 5793#endif /* USE_THREADS */
79072805 5794 else
a0d0e21e
LW
5795 ary = Nullav;
5796 if (ary && (gimme != G_ARRAY || (pm->op_pmflags & PMf_ONCE))) {
5797 realarray = 1;
8ec5e241 5798 PUTBACK;
a0d0e21e
LW
5799 av_extend(ary,0);
5800 av_clear(ary);
8ec5e241 5801 SPAGAIN;
155aba94 5802 if ((mg = SvTIED_mg((SV*)ary, 'P'))) {
8ec5e241 5803 PUSHMARK(SP);
33c27489 5804 XPUSHs(SvTIED_obj((SV*)ary, mg));
8ec5e241
NIS
5805 }
5806 else {
1c0b011c
NIS
5807 if (!AvREAL(ary)) {
5808 AvREAL_on(ary);
abff13bb 5809 AvREIFY_off(ary);
1c0b011c 5810 for (i = AvFILLp(ary); i >= 0; i--)
3280af22 5811 AvARRAY(ary)[i] = &PL_sv_undef; /* don't free mere refs */
1c0b011c
NIS
5812 }
5813 /* temporarily switch stacks */
3280af22 5814 SWITCHSTACK(PL_curstack, ary);
8ec5e241 5815 make_mortal = 0;
1c0b011c 5816 }
79072805 5817 }
3280af22 5818 base = SP - PL_stack_base;
a0d0e21e
LW
5819 orig = s;
5820 if (pm->op_pmflags & PMf_SKIPWHITE) {
bbce6d69 5821 if (pm->op_pmflags & PMf_LOCALE) {
5822 while (isSPACE_LC(*s))
5823 s++;
5824 }
5825 else {
5826 while (isSPACE(*s))
5827 s++;
5828 }
a0d0e21e 5829 }
c07a80fd 5830 if (pm->op_pmflags & (PMf_MULTILINE|PMf_SINGLELINE)) {
3280af22
NIS
5831 SAVEINT(PL_multiline);
5832 PL_multiline = pm->op_pmflags & PMf_MULTILINE;
c07a80fd 5833 }
5834
a0d0e21e
LW
5835 if (!limit)
5836 limit = maxiters + 2;
5837 if (pm->op_pmflags & PMf_WHITE) {
5838 while (--limit) {
bbce6d69 5839 m = s;
5840 while (m < strend &&
5841 !((pm->op_pmflags & PMf_LOCALE)
5842 ? isSPACE_LC(*m) : isSPACE(*m)))
5843 ++m;
a0d0e21e
LW
5844 if (m >= strend)
5845 break;
bbce6d69 5846
a0d0e21e
LW
5847 dstr = NEWSV(30, m-s);
5848 sv_setpvn(dstr, s, m-s);
8ec5e241 5849 if (make_mortal)
a0d0e21e 5850 sv_2mortal(dstr);
93f04dac 5851 if (doutf8)
28cb3359 5852 (void)SvUTF8_on(dstr);
a0d0e21e 5853 XPUSHs(dstr);
bbce6d69 5854
5855 s = m + 1;
5856 while (s < strend &&
5857 ((pm->op_pmflags & PMf_LOCALE)
5858 ? isSPACE_LC(*s) : isSPACE(*s)))
5859 ++s;
79072805
LW
5860 }
5861 }
f4091fba 5862 else if (strEQ("^", rx->precomp)) {
a0d0e21e
LW
5863 while (--limit) {
5864 /*SUPPRESS 530*/
5865 for (m = s; m < strend && *m != '\n'; m++) ;
5866 m++;
5867 if (m >= strend)
5868 break;
5869 dstr = NEWSV(30, m-s);
5870 sv_setpvn(dstr, s, m-s);
8ec5e241 5871 if (make_mortal)
a0d0e21e 5872 sv_2mortal(dstr);
93f04dac 5873 if (doutf8)
28cb3359 5874 (void)SvUTF8_on(dstr);
a0d0e21e
LW
5875 XPUSHs(dstr);
5876 s = m;
5877 }
5878 }
f722798b 5879 else if ((rx->reganch & RE_USE_INTUIT) && !rx->nparens
d9f97599
GS
5880 && (rx->reganch & ROPT_CHECK_ALL)
5881 && !(rx->reganch & ROPT_ANCH)) {
f722798b
IZ
5882 int tail = (rx->reganch & RE_INTUIT_TAIL);
5883 SV *csv = CALLREG_INTUIT_STRING(aTHX_ rx);
cf93c79d 5884
ca5b42cb
GS
5885 len = rx->minlen;
5886 if (len == 1 && !tail) {
93f04dac
JH
5887 STRLEN n_a;
5888 char c = *SvPV(csv, n_a);
a0d0e21e 5889 while (--limit) {
bbce6d69 5890 /*SUPPRESS 530*/
f722798b 5891 for (m = s; m < strend && *m != c; m++) ;
a0d0e21e
LW
5892 if (m >= strend)
5893 break;
5894 dstr = NEWSV(30, m-s);
5895 sv_setpvn(dstr, s, m-s);
8ec5e241 5896 if (make_mortal)
a0d0e21e 5897 sv_2mortal(dstr);
93f04dac 5898 if (doutf8)
28cb3359 5899 (void)SvUTF8_on(dstr);
a0d0e21e 5900 XPUSHs(dstr);
93f04dac
JH
5901 /* The rx->minlen is in characters but we want to step
5902 * s ahead by bytes. */
5903 s = m + (doutf8 ? SvCUR(csv) : len);
a0d0e21e
LW
5904 }
5905 }
5906 else {
5907#ifndef lint
5908 while (s < strend && --limit &&
f722798b
IZ
5909 (m = fbm_instr((unsigned char*)s, (unsigned char*)strend,
5910 csv, PL_multiline ? FBMrf_MULTILINE : 0)) )
79072805 5911#endif
a0d0e21e
LW
5912 {
5913 dstr = NEWSV(31, m-s);
5914 sv_setpvn(dstr, s, m-s);
8ec5e241 5915 if (make_mortal)
a0d0e21e 5916 sv_2mortal(dstr);
93f04dac 5917 if (doutf8)
28cb3359 5918 (void)SvUTF8_on(dstr);
a0d0e21e 5919 XPUSHs(dstr);
93f04dac
JH
5920 /* The rx->minlen is in characters but we want to step
5921 * s ahead by bytes. */
5922 s = m + (doutf8 ? SvCUR(csv) : len); /* Fake \n at the end */
a0d0e21e 5923 }
463ee0b2 5924 }
463ee0b2 5925 }
a0d0e21e 5926 else {
d9f97599 5927 maxiters += (strend - s) * rx->nparens;
f722798b 5928 while (s < strend && --limit
b13b2135 5929/* && (!rx->check_substr
f722798b
IZ
5930 || ((s = CALLREG_INTUIT_START(aTHX_ rx, sv, s, strend,
5931 0, NULL))))
5932*/ && CALLREGEXEC(aTHX_ rx, s, strend, orig,
5933 1 /* minend */, sv, NULL, 0))
bbce6d69 5934 {
d9f97599 5935 TAINT_IF(RX_MATCH_TAINTED(rx));
cf93c79d 5936 if (RX_MATCH_COPIED(rx) && rx->subbeg != orig) {
a0d0e21e
LW
5937 m = s;
5938 s = orig;
cf93c79d 5939 orig = rx->subbeg;
a0d0e21e
LW
5940 s = orig + (m - s);
5941 strend = s + (strend - m);
5942 }
cf93c79d 5943 m = rx->startp[0] + orig;
a0d0e21e
LW
5944 dstr = NEWSV(32, m-s);
5945 sv_setpvn(dstr, s, m-s);
8ec5e241 5946 if (make_mortal)
a0d0e21e 5947 sv_2mortal(dstr);
93f04dac 5948 if (doutf8)
28cb3359 5949 (void)SvUTF8_on(dstr);
a0d0e21e 5950 XPUSHs(dstr);
d9f97599
GS
5951 if (rx->nparens) {
5952 for (i = 1; i <= rx->nparens; i++) {
cf93c79d
IZ
5953 s = rx->startp[i] + orig;
5954 m = rx->endp[i] + orig;
748a9306
LW
5955 if (m && s) {
5956 dstr = NEWSV(33, m-s);
5957 sv_setpvn(dstr, s, m-s);
5958 }
5959 else
5960 dstr = NEWSV(33, 0);
8ec5e241 5961 if (make_mortal)
a0d0e21e 5962 sv_2mortal(dstr);
93f04dac 5963 if (doutf8)
28cb3359 5964 (void)SvUTF8_on(dstr);
a0d0e21e
LW
5965 XPUSHs(dstr);
5966 }
5967 }
cf93c79d 5968 s = rx->endp[0] + orig;
a0d0e21e 5969 }
79072805 5970 }
8ec5e241 5971
c07a80fd 5972 LEAVE_SCOPE(oldsave);
3280af22 5973 iters = (SP - PL_stack_base) - base;
a0d0e21e 5974 if (iters > maxiters)
cea2e8a9 5975 DIE(aTHX_ "Split loop");
8ec5e241 5976
a0d0e21e
LW
5977 /* keep field after final delim? */
5978 if (s < strend || (iters && origlimit)) {
93f04dac
JH
5979 STRLEN l = strend - s;
5980 dstr = NEWSV(34, l);
5981 sv_setpvn(dstr, s, l);
8ec5e241 5982 if (make_mortal)
a0d0e21e 5983 sv_2mortal(dstr);
93f04dac 5984 if (doutf8)
28cb3359 5985 (void)SvUTF8_on(dstr);
a0d0e21e
LW
5986 XPUSHs(dstr);
5987 iters++;
79072805 5988 }
a0d0e21e 5989 else if (!origlimit) {
b1dadf13 5990 while (iters > 0 && (!TOPs || !SvANY(TOPs) || SvCUR(TOPs) == 0))
a0d0e21e
LW
5991 iters--, SP--;
5992 }
8ec5e241 5993
a0d0e21e 5994 if (realarray) {
8ec5e241 5995 if (!mg) {
1c0b011c
NIS
5996 SWITCHSTACK(ary, oldstack);
5997 if (SvSMAGICAL(ary)) {
5998 PUTBACK;
5999 mg_set((SV*)ary);
6000 SPAGAIN;
6001 }
6002 if (gimme == G_ARRAY) {
6003 EXTEND(SP, iters);
6004 Copy(AvARRAY(ary), SP + 1, iters, SV*);
6005 SP += iters;
6006 RETURN;
6007 }
8ec5e241 6008 }
1c0b011c 6009 else {
fb73857a 6010 PUTBACK;
8ec5e241 6011 ENTER;
864dbfa3 6012 call_method("PUSH",G_SCALAR|G_DISCARD);
8ec5e241 6013 LEAVE;
fb73857a 6014 SPAGAIN;
8ec5e241
NIS
6015 if (gimme == G_ARRAY) {
6016 /* EXTEND should not be needed - we just popped them */
6017 EXTEND(SP, iters);
6018 for (i=0; i < iters; i++) {
6019 SV **svp = av_fetch(ary, i, FALSE);
3280af22 6020 PUSHs((svp) ? *svp : &PL_sv_undef);
8ec5e241 6021 }
1c0b011c
NIS
6022 RETURN;
6023 }
a0d0e21e
LW
6024 }
6025 }
6026 else {
6027 if (gimme == G_ARRAY)
6028 RETURN;
6029 }
6030 if (iters || !pm->op_pmreplroot) {
6031 GETTARGET;
6032 PUSHi(iters);
6033 RETURN;
6034 }
6035 RETPUSHUNDEF;
79072805 6036}
85e6fe83 6037
c0329465 6038#ifdef USE_THREADS
77a005ab 6039void
864dbfa3 6040Perl_unlock_condpair(pTHX_ void *svv)
c0329465 6041{
c0329465 6042 MAGIC *mg = mg_find((SV*)svv, 'm');
8ec5e241 6043
c0329465 6044 if (!mg)
cea2e8a9 6045 Perl_croak(aTHX_ "panic: unlock_condpair unlocking non-mutex");
c0329465
MB
6046 MUTEX_LOCK(MgMUTEXP(mg));
6047 if (MgOWNER(mg) != thr)
cea2e8a9 6048 Perl_croak(aTHX_ "panic: unlock_condpair unlocking mutex that we don't own");
c0329465
MB
6049 MgOWNER(mg) = 0;
6050 COND_SIGNAL(MgOWNERCONDP(mg));
b900a521
JH
6051 DEBUG_S(PerlIO_printf(Perl_debug_log, "0x%"UVxf": unlock 0x%"UVxf"\n",
6052 PTR2UV(thr), PTR2UV(svv));)
c0329465
MB
6053 MUTEX_UNLOCK(MgMUTEXP(mg));
6054}
6055#endif /* USE_THREADS */
6056
6057PP(pp_lock)
6058{
4e35701f 6059 djSP;
c0329465 6060 dTOPss;
e55aaa0e
MB
6061 SV *retsv = sv;
6062#ifdef USE_THREADS
4755096e 6063 sv_lock(sv);
c0329465 6064#endif /* USE_THREADS */
e55aaa0e
MB
6065 if (SvTYPE(retsv) == SVt_PVAV || SvTYPE(retsv) == SVt_PVHV
6066 || SvTYPE(retsv) == SVt_PVCV) {
6067 retsv = refto(retsv);
6068 }
6069 SETs(retsv);
c0329465
MB
6070 RETURN;
6071}
a863c7d1 6072
2faa37cc 6073PP(pp_threadsv)
a863c7d1 6074{
57d3b86d 6075#ifdef USE_THREADS
155aba94 6076 djSP;
924508f0 6077 EXTEND(SP, 1);
533c011a
NIS
6078 if (PL_op->op_private & OPpLVAL_INTRO)
6079 PUSHs(*save_threadsv(PL_op->op_targ));
554b3eca 6080 else
533c011a 6081 PUSHs(THREADSV(PL_op->op_targ));
fdb47d66 6082 RETURN;
a863c7d1 6083#else
cea2e8a9 6084 DIE(aTHX_ "tried to access per-thread data in non-threaded perl");
a863c7d1 6085#endif /* USE_THREADS */
a863c7d1 6086}