LC_COLLATE.
[p5sagit/p5-mst-13.2.git] / pp.c
CommitLineData
a0d0e21e 1/* pp.c
79072805 2 *
a0d0e21e 3 * Copyright (c) 1991-1994, Larry Wall
79072805 4 *
a0d0e21e 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 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 14
15#include "EXTERN.h"
16#include "perl.h"
17
a0d0e21e 18static void doencodes _((SV *sv, char *s, I32 len));
79072805 19
a0d0e21e 20/* variations on pp_null */
79072805 21
93a17b20 22PP(pp_stub)
23{
24 dSP;
25 if (GIMME != G_ARRAY) {
26 XPUSHs(&sv_undef);
27 }
28 RETURN;
29}
30
79072805 31PP(pp_scalar)
32{
33 return NORMAL;
34}
35
36/* Pushy stuff. */
37
93a17b20 38PP(pp_padav)
39{
40 dSP; dTARGET;
a0d0e21e 41 if (op->op_private & OPpLVAL_INTRO)
8990e307 42 SAVECLEARSV(curpad[op->op_targ]);
85e6fe83 43 EXTEND(SP, 1);
a0d0e21e 44 if (op->op_flags & OPf_REF) {
85e6fe83 45 PUSHs(TARG);
93a17b20 46 RETURN;
85e6fe83 47 }
48 if (GIMME == G_ARRAY) {
49 I32 maxarg = AvFILL((AV*)TARG) + 1;
50 EXTEND(SP, maxarg);
51 Copy(AvARRAY((AV*)TARG), SP+1, maxarg, SV*);
52 SP += maxarg;
53 }
54 else {
55 SV* sv = sv_newmortal();
56 I32 maxarg = AvFILL((AV*)TARG) + 1;
57 sv_setiv(sv, maxarg);
58 PUSHs(sv);
59 }
60 RETURN;
93a17b20 61}
62
63PP(pp_padhv)
64{
65 dSP; dTARGET;
66 XPUSHs(TARG);
a0d0e21e 67 if (op->op_private & OPpLVAL_INTRO)
8990e307 68 SAVECLEARSV(curpad[op->op_targ]);
a0d0e21e 69 if (op->op_flags & OPf_REF)
93a17b20 70 RETURN;
85e6fe83 71 if (GIMME == G_ARRAY) { /* array wanted */
a0d0e21e 72 RETURNOP(do_kv(ARGS));
85e6fe83 73 }
74 else {
75 SV* sv = sv_newmortal();
76 if (HvFILL((HV*)TARG)) {
77 sprintf(buf, "%d/%d", HvFILL((HV*)TARG), HvMAX((HV*)TARG)+1);
78 sv_setpv(sv, buf);
79 }
80 else
81 sv_setiv(sv, 0);
82 SETs(sv);
83 RETURN;
84 }
93a17b20 85}
86
ed6116ce 87PP(pp_padany)
88{
89 DIE("NOT IMPL LINE %d",__LINE__);
90}
91
79072805 92/* Translations. */
93
94PP(pp_rv2gv)
95{
96 dSP; dTOPss;
a0d0e21e 97
ed6116ce 98 if (SvROK(sv)) {
a0d0e21e 99 wasref:
ed6116ce 100 sv = SvRV(sv);
b1dadf13 101 if (SvTYPE(sv) == SVt_PVIO) {
102 GV *gv = (GV*) sv_newmortal();
103 gv_init(gv, 0, "", 0, 0);
104 GvIOp(gv) = (IO *)sv;
105 SvREFCNT_inc(sv);
106 sv = (SV*) gv;
107 } else if (SvTYPE(sv) != SVt_PVGV)
a0d0e21e 108 DIE("Not a GLOB reference");
79072805 109 }
110 else {
93a17b20 111 if (SvTYPE(sv) != SVt_PVGV) {
748a9306 112 char *sym;
113
a0d0e21e 114 if (SvGMAGICAL(sv)) {
115 mg_get(sv);
116 if (SvROK(sv))
117 goto wasref;
118 }
119 if (!SvOK(sv)) {
120 if (op->op_flags & OPf_REF ||
121 op->op_private & HINT_STRICT_REFS)
122 DIE(no_usym, "a symbol");
123 RETSETUNDEF;
124 }
748a9306 125 sym = SvPV(sv, na);
85e6fe83 126 if (op->op_private & HINT_STRICT_REFS)
748a9306 127 DIE(no_symref, sym, "a symbol");
128 sv = (SV*)gv_fetchpv(sym, TRUE, SVt_PVGV);
93a17b20 129 }
79072805 130 }
a0d0e21e 131 if (op->op_private & OPpLVAL_INTRO) {
79072805 132 GP *ogp = GvGP(sv);
133
134 SSCHECK(3);
4633a7c4 135 SSPUSHPTR(SvREFCNT_inc(sv));
79072805 136 SSPUSHPTR(ogp);
137 SSPUSHINT(SAVEt_GP);
138
a0d0e21e 139 if (op->op_flags & OPf_SPECIAL) {
79072805 140 GvGP(sv)->gp_refcnt++; /* will soon be assigned */
a5f75d66 141 GvINTRO_on(sv);
a0d0e21e 142 }
79072805 143 else {
144 GP *gp;
145 Newz(602,gp, 1, GP);
146 GvGP(sv) = gp;
147 GvREFCNT(sv) = 1;
148 GvSV(sv) = NEWSV(72,0);
149 GvLINE(sv) = curcop->cop_line;
f12c7020 150 GvEGV(sv) = (GV*)sv;
79072805 151 }
152 }
153 SETs(sv);
154 RETURN;
155}
156
79072805 157PP(pp_rv2sv)
158{
159 dSP; dTOPss;
160
ed6116ce 161 if (SvROK(sv)) {
a0d0e21e 162 wasref:
ed6116ce 163 sv = SvRV(sv);
79072805 164 switch (SvTYPE(sv)) {
165 case SVt_PVAV:
166 case SVt_PVHV:
167 case SVt_PVCV:
a0d0e21e 168 DIE("Not a SCALAR reference");
79072805 169 }
170 }
171 else {
f12c7020 172 GV *gv = (GV*)sv;
748a9306 173 char *sym;
174
463ee0b2 175 if (SvTYPE(gv) != SVt_PVGV) {
a0d0e21e 176 if (SvGMAGICAL(sv)) {
177 mg_get(sv);
178 if (SvROK(sv))
179 goto wasref;
180 }
181 if (!SvOK(sv)) {
182 if (op->op_flags & OPf_REF ||
183 op->op_private & HINT_STRICT_REFS)
184 DIE(no_usym, "a SCALAR");
185 RETSETUNDEF;
186 }
748a9306 187 sym = SvPV(sv, na);
85e6fe83 188 if (op->op_private & HINT_STRICT_REFS)
748a9306 189 DIE(no_symref, sym, "a SCALAR");
f12c7020 190 gv = (GV*)gv_fetchpv(sym, TRUE, SVt_PV);
463ee0b2 191 }
192 sv = GvSV(gv);
a0d0e21e 193 }
194 if (op->op_flags & OPf_MOD) {
195 if (op->op_private & OPpLVAL_INTRO)
196 sv = save_scalar((GV*)TOPs);
464e2e8a 197 else if (op->op_private & (OPpDEREF_HV|OPpDEREF_AV))
198 provide_ref(op, sv);
79072805 199 }
a0d0e21e 200 SETs(sv);
79072805 201 RETURN;
202}
203
204PP(pp_av2arylen)
205{
206 dSP;
207 AV *av = (AV*)TOPs;
208 SV *sv = AvARYLEN(av);
209 if (!sv) {
210 AvARYLEN(av) = sv = NEWSV(0,0);
211 sv_upgrade(sv, SVt_IV);
212 sv_magic(sv, (SV*)av, '#', Nullch, 0);
213 }
214 SETs(sv);
215 RETURN;
216}
217
a0d0e21e 218PP(pp_pos)
219{
220 dSP; dTARGET; dPOPss;
221
222 if (op->op_flags & OPf_MOD) {
223 LvTYPE(TARG) = '<';
224 LvTARG(TARG) = sv;
225 PUSHs(TARG); /* no SvSETMAGIC */
226 RETURN;
227 }
228 else {
229 MAGIC* mg;
230
231 if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv)) {
232 mg = mg_find(sv, 'g');
233 if (mg && mg->mg_len >= 0) {
234 PUSHi(mg->mg_len + curcop->cop_arybase);
235 RETURN;
236 }
237 }
238 RETPUSHUNDEF;
239 }
240}
241
79072805 242PP(pp_rv2cv)
243{
244 dSP;
79072805 245 GV *gv;
246 HV *stash;
8990e307 247
4633a7c4 248 /* We usually try to add a non-existent subroutine in case of AUTOLOAD. */
249 /* (But not in defined().) */
250 CV *cv = sv_2cv(TOPs, &stash, &gv, !(op->op_flags & OPf_SPECIAL));
79072805 251
4633a7c4 252 if (!cv)
253 cv = (CV*)&sv_undef;
79072805 254 SETs((SV*)cv);
255 RETURN;
256}
257
c07a80fd 258PP(pp_prototype)
259{
260 dSP;
261 CV *cv;
262 HV *stash;
263 GV *gv;
264 SV *ret;
265
266 ret = &sv_undef;
267 cv = sv_2cv(TOPs, &stash, &gv, FALSE);
268 if (cv && SvPOK(cv)) {
269 char *p = SvPVX(cv);
270 ret = sv_2mortal(newSVpv(p ? p : "", SvLEN(cv)));
271 }
272 SETs(ret);
273 RETURN;
274}
275
a0d0e21e 276PP(pp_anoncode)
277{
278 dSP;
748a9306 279 CV* cv = (CV*)cSVOP->op_sv;
280 EXTEND(SP,1);
281
a5f75d66 282 if (CvCLONE(cv))
b355b4e0 283 cv = (CV*)sv_2mortal((SV*)cv_clone(cv));
748a9306 284
285 PUSHs((SV*)cv);
a0d0e21e 286 RETURN;
287}
288
289PP(pp_srefgen)
79072805 290{
291 dSP; dTOPss;
292 SV* rv;
8990e307 293 rv = sv_newmortal();
ed6116ce 294 sv_upgrade(rv, SVt_RV);
a0d0e21e 295 if (SvPADTMP(sv))
296 sv = newSVsv(sv);
297 else {
298 SvTEMP_off(sv);
299 (void)SvREFCNT_inc(sv);
300 }
301 SvRV(rv) = sv;
ed6116ce 302 SvROK_on(rv);
79072805 303 SETs(rv);
304 RETURN;
a0d0e21e 305}
306
307PP(pp_refgen)
308{
309 dSP; dMARK;
310 SV* sv;
311 SV* rv;
312 if (GIMME != G_ARRAY) {
313 MARK[1] = *SP;
314 SP = MARK + 1;
315 }
316 while (MARK < SP) {
317 sv = *++MARK;
318 rv = sv_newmortal();
319 sv_upgrade(rv, SVt_RV);
320 if (SvPADTMP(sv))
321 sv = newSVsv(sv);
322 else {
323 SvTEMP_off(sv);
324 (void)SvREFCNT_inc(sv);
325 }
326 SvRV(rv) = sv;
327 SvROK_on(rv);
328 *MARK = rv;
329 }
330 RETURN;
79072805 331}
332
333PP(pp_ref)
334{
463ee0b2 335 dSP; dTARGET;
336 SV *sv;
79072805 337 char *pv;
338
a0d0e21e 339 sv = POPs;
f12c7020 340
341 if (sv && SvGMAGICAL(sv))
342 mg_get(sv);
343
a0d0e21e 344 if (!sv || !SvROK(sv))
4633a7c4 345 RETPUSHNO;
79072805 346
ed6116ce 347 sv = SvRV(sv);
a0d0e21e 348 pv = sv_reftype(sv,TRUE);
463ee0b2 349 PUSHp(pv, strlen(pv));
79072805 350 RETURN;
351}
352
353PP(pp_bless)
354{
463ee0b2 355 dSP;
463ee0b2 356 HV *stash;
79072805 357
463ee0b2 358 if (MAXARG == 1)
359 stash = curcop->cop_stash;
360 else
a0d0e21e 361 stash = gv_stashsv(POPs, TRUE);
362
363 (void)sv_bless(TOPs, stash);
79072805 364 RETURN;
365}
366
a0d0e21e 367/* Pattern matching */
79072805 368
a0d0e21e 369PP(pp_study)
79072805 370{
c07a80fd 371 dSP; dPOPss;
a0d0e21e 372 register unsigned char *s;
373 register I32 pos;
374 register I32 ch;
375 register I32 *sfirst;
376 register I32 *snext;
377 I32 retval;
378 STRLEN len;
379
c07a80fd 380 s = (unsigned char*)(SvPV(sv, len));
a0d0e21e 381 pos = len;
c07a80fd 382 if (sv == lastscream)
383 SvSCREAM_off(sv);
384 else {
385 if (lastscream) {
386 SvSCREAM_off(lastscream);
387 SvREFCNT_dec(lastscream);
388 }
389 lastscream = SvREFCNT_inc(sv);
390 }
a0d0e21e 391 if (pos <= 0) {
392 retval = 0;
393 goto ret;
394 }
395 if (pos > maxscream) {
396 if (maxscream < 0) {
397 maxscream = pos + 80;
398 New(301, screamfirst, 256, I32);
399 New(302, screamnext, maxscream, I32);
79072805 400 }
401 else {
a0d0e21e 402 maxscream = pos + pos / 4;
403 Renew(screamnext, maxscream, I32);
79072805 404 }
79072805 405 }
a0d0e21e 406
407 sfirst = screamfirst;
408 snext = screamnext;
409
410 if (!sfirst || !snext)
411 DIE("do_study: out of memory");
412
413 for (ch = 256; ch; --ch)
414 *sfirst++ = -1;
415 sfirst -= 256;
416
417 while (--pos >= 0) {
418 ch = s[pos];
419 if (sfirst[ch] >= 0)
420 snext[pos] = sfirst[ch] - pos;
421 else
422 snext[pos] = -pos;
423 sfirst[ch] = pos;
424
425 /* If there were any case insensitive searches, we must assume they
426 * all are. This speeds up insensitive searches much more than
427 * it slows down sensitive ones.
428 */
429 if (sawi)
430 sfirst[fold[ch]] = pos;
79072805 431 }
432
c07a80fd 433 SvSCREAM_on(sv);
464e2e8a 434 sv_magic(sv, Nullsv, 'g', Nullch, 0); /* piggyback on m//g magic */
a0d0e21e 435 retval = 1;
436 ret:
437 XPUSHs(sv_2mortal(newSViv((I32)retval)));
79072805 438 RETURN;
439}
440
a0d0e21e 441PP(pp_trans)
79072805 442{
a0d0e21e 443 dSP; dTARG;
444 SV *sv;
445
446 if (op->op_flags & OPf_STACKED)
447 sv = POPs;
79072805 448 else {
a0d0e21e 449 sv = GvSV(defgv);
450 EXTEND(SP,1);
79072805 451 }
adbc6bb1 452 TARG = sv_newmortal();
a0d0e21e 453 PUSHi(do_trans(sv, op));
454 RETURN;
79072805 455}
456
a0d0e21e 457/* Lvalue operators. */
79072805 458
a0d0e21e 459PP(pp_schop)
460{
461 dSP; dTARGET;
462 do_chop(TARG, TOPs);
463 SETTARG;
464 RETURN;
79072805 465}
466
a0d0e21e 467PP(pp_chop)
79072805 468{
a0d0e21e 469 dSP; dMARK; dTARGET;
470 while (SP > MARK)
471 do_chop(TARG, POPs);
472 PUSHTARG;
473 RETURN;
79072805 474}
475
a0d0e21e 476PP(pp_schomp)
79072805 477{
a0d0e21e 478 dSP; dTARGET;
479 SETi(do_chomp(TOPs));
480 RETURN;
79072805 481}
482
a0d0e21e 483PP(pp_chomp)
79072805 484{
a0d0e21e 485 dSP; dMARK; dTARGET;
486 register I32 count = 0;
487
488 while (SP > MARK)
489 count += do_chomp(POPs);
490 PUSHi(count);
491 RETURN;
79072805 492}
493
a0d0e21e 494PP(pp_defined)
463ee0b2 495{
a0d0e21e 496 dSP;
497 register SV* sv;
498
499 sv = POPs;
500 if (!sv || !SvANY(sv))
501 RETPUSHNO;
502 switch (SvTYPE(sv)) {
503 case SVt_PVAV:
8e07c86e 504 if (AvMAX(sv) >= 0 || SvRMAGICAL(sv))
a0d0e21e 505 RETPUSHYES;
506 break;
507 case SVt_PVHV:
8e07c86e 508 if (HvARRAY(sv) || SvRMAGICAL(sv))
a0d0e21e 509 RETPUSHYES;
510 break;
511 case SVt_PVCV:
512 if (CvROOT(sv) || CvXSUB(sv))
513 RETPUSHYES;
514 break;
515 default:
516 if (SvGMAGICAL(sv))
517 mg_get(sv);
518 if (SvOK(sv))
519 RETPUSHYES;
520 }
521 RETPUSHNO;
463ee0b2 522}
523
a0d0e21e 524PP(pp_undef)
525{
79072805 526 dSP;
a0d0e21e 527 SV *sv;
528
529 if (!op->op_private)
530 RETPUSHUNDEF;
79072805 531
a0d0e21e 532 sv = POPs;
533 if (!sv)
534 RETPUSHUNDEF;
85e6fe83 535
a0d0e21e 536 if (SvTHINKFIRST(sv)) {
537 if (SvREADONLY(sv))
538 RETPUSHUNDEF;
539 if (SvROK(sv))
540 sv_unref(sv);
85e6fe83 541 }
542
a0d0e21e 543 switch (SvTYPE(sv)) {
544 case SVt_NULL:
545 break;
546 case SVt_PVAV:
547 av_undef((AV*)sv);
548 break;
549 case SVt_PVHV:
550 hv_undef((HV*)sv);
551 break;
552 case SVt_PVCV:
553 cv_undef((CV*)sv);
554 sub_generation++;
555 break;
8e07c86e 556 case SVt_PVGV:
557 if (SvFAKE(sv)) {
558 sv_setsv(sv, &sv_undef);
559 break;
560 }
a0d0e21e 561 default:
4633a7c4 562 if (SvPOK(sv) && SvLEN(sv)) {
563 (void)SvOOK_off(sv);
564 Safefree(SvPVX(sv));
565 SvPV_set(sv, Nullch);
566 SvLEN_set(sv, 0);
a0d0e21e 567 }
4633a7c4 568 (void)SvOK_off(sv);
569 SvSETMAGIC(sv);
79072805 570 }
a0d0e21e 571
572 RETPUSHUNDEF;
79072805 573}
574
a0d0e21e 575PP(pp_predec)
79072805 576{
a0d0e21e 577 dSP;
748a9306 578 if (SvIOK(TOPs)) {
dedeecda 579 if (SvIVX(TOPs) == IV_MIN) {
760ac839 580 sv_setnv(TOPs, (double)SvIVX(TOPs) - 1.0);
581 }
582 else {
583 --SvIVX(TOPs);
584 SvFLAGS(TOPs) &= ~(SVf_NOK|SVf_POK|SVp_NOK|SVp_POK);
585 }
748a9306 586 }
587 else
588 sv_dec(TOPs);
a0d0e21e 589 SvSETMAGIC(TOPs);
590 return NORMAL;
591}
79072805 592
a0d0e21e 593PP(pp_postinc)
594{
595 dSP; dTARGET;
596 sv_setsv(TARG, TOPs);
748a9306 597 if (SvIOK(TOPs)) {
dedeecda 598 if (SvIVX(TOPs) == IV_MAX) {
760ac839 599 sv_setnv(TOPs, (double)SvIVX(TOPs) + 1.0);
600 }
601 else {
602 ++SvIVX(TOPs);
603 SvFLAGS(TOPs) &= ~(SVf_NOK|SVf_POK|SVp_NOK|SVp_POK);
604 }
748a9306 605 }
606 else
607 sv_inc(TOPs);
a0d0e21e 608 SvSETMAGIC(TOPs);
609 if (!SvOK(TARG))
610 sv_setiv(TARG, 0);
611 SETs(TARG);
612 return NORMAL;
613}
79072805 614
a0d0e21e 615PP(pp_postdec)
616{
617 dSP; dTARGET;
618 sv_setsv(TARG, TOPs);
748a9306 619 if (SvIOK(TOPs)) {
dedeecda 620 if (SvIVX(TOPs) == IV_MIN) {
760ac839 621 sv_setnv(TOPs, (double)SvIVX(TOPs) - 1.0);
622 }
623 else {
624 --SvIVX(TOPs);
625 SvFLAGS(TOPs) &= ~(SVf_NOK|SVf_POK|SVp_NOK|SVp_POK);
626 }
748a9306 627 }
628 else
629 sv_dec(TOPs);
a0d0e21e 630 SvSETMAGIC(TOPs);
631 SETs(TARG);
632 return NORMAL;
633}
79072805 634
a0d0e21e 635/* Ordinary operators. */
636
637PP(pp_pow)
638{
639 dSP; dATARGET; tryAMAGICbin(pow,opASSIGN);
640 {
641 dPOPTOPnnrl;
642 SETn( pow( left, right) );
643 RETURN;
93a17b20 644 }
a0d0e21e 645}
646
647PP(pp_multiply)
648{
649 dSP; dATARGET; tryAMAGICbin(mult,opASSIGN);
650 {
651 dPOPTOPnnrl;
652 SETn( left * right );
653 RETURN;
79072805 654 }
a0d0e21e 655}
656
657PP(pp_divide)
658{
659 dSP; dATARGET; tryAMAGICbin(div,opASSIGN);
660 {
661 dPOPnv;
662 if (value == 0.0)
663 DIE("Illegal division by zero");
664#ifdef SLOPPYDIVIDE
665 /* insure that 20./5. == 4. */
666 {
667 double x;
668 I32 k;
669 x = POPn;
670 if ((double)I_32(x) == x &&
671 (double)I_32(value) == value &&
672 (k = I_32(x)/I_32(value))*I_32(value) == I_32(x)) {
673 value = k;
674 } else {
675 value = x/value;
79072805 676 }
a0d0e21e 677 }
678#else
679 value = POPn / value;
680#endif
681 PUSHn( value );
682 RETURN;
79072805 683 }
a0d0e21e 684}
685
686PP(pp_modulo)
687{
688 dSP; dATARGET; tryAMAGICbin(mod,opASSIGN);
689 {
1e11cddc 690 register IV value;
691 register UV uval;
a0d0e21e 692
1e11cddc 693 uval = POPn;
694 if (!uval)
a0d0e21e 695 DIE("Illegal modulus zero");
696 value = TOPn;
1e11cddc 697 if (value >= 0)
698 value = (UV)value % uval;
a0d0e21e 699 else {
1e11cddc 700 value = (uval - ((UV)(-value - 1) % uval)) - 1;
a0d0e21e 701 }
702 SETi(value);
703 RETURN;
79072805 704 }
a0d0e21e 705}
79072805 706
a0d0e21e 707PP(pp_repeat)
708{
748a9306 709 dSP; dATARGET; tryAMAGICbin(repeat,opASSIGN);
710 {
a0d0e21e 711 register I32 count = POPi;
712 if (GIMME == G_ARRAY && op->op_private & OPpREPEAT_DOLIST) {
713 dMARK;
714 I32 items = SP - MARK;
715 I32 max;
79072805 716
a0d0e21e 717 max = items * count;
718 MEXTEND(MARK, max);
719 if (count > 1) {
720 while (SP > MARK) {
721 if (*SP)
722 SvTEMP_off((*SP));
723 SP--;
79072805 724 }
a0d0e21e 725 MARK++;
726 repeatcpy((char*)(MARK + items), (char*)MARK,
727 items * sizeof(SV*), count - 1);
728 SP += max;
79072805 729 }
a0d0e21e 730 else if (count <= 0)
731 SP -= items;
79072805 732 }
a0d0e21e 733 else { /* Note: mark already snarfed by pp_list */
734 SV *tmpstr;
735 STRLEN len;
736
737 tmpstr = POPs;
738 if (TARG == tmpstr && SvTHINKFIRST(tmpstr)) {
739 if (SvREADONLY(tmpstr) && curcop != &compiling)
740 DIE("Can't x= to readonly value");
741 if (SvROK(tmpstr))
742 sv_unref(tmpstr);
93a17b20 743 }
a0d0e21e 744 SvSetSV(TARG, tmpstr);
745 SvPV_force(TARG, len);
746 if (count >= 1) {
747 SvGROW(TARG, (count * len) + 1);
748 if (count > 1)
749 repeatcpy(SvPVX(TARG) + len, SvPVX(TARG), len, count - 1);
750 SvCUR(TARG) *= count;
751 *SvEND(TARG) = '\0';
752 (void)SvPOK_only(TARG);
753 }
754 else
755 sv_setsv(TARG, &sv_no);
756 PUSHTARG;
79072805 757 }
a0d0e21e 758 RETURN;
748a9306 759 }
a0d0e21e 760}
79072805 761
a0d0e21e 762PP(pp_subtract)
763{
764 dSP; dATARGET; tryAMAGICbin(subtr,opASSIGN);
765 {
766 dPOPTOPnnrl;
767 SETn( left - right );
768 RETURN;
79072805 769 }
a0d0e21e 770}
79072805 771
a0d0e21e 772PP(pp_left_shift)
773{
774 dSP; dATARGET; tryAMAGICbin(lshift,opASSIGN);
775 {
748a9306 776 dPOPTOPiirl;
777 SETi( left << right );
778 RETURN;
79072805 779 }
a0d0e21e 780}
79072805 781
a0d0e21e 782PP(pp_right_shift)
783{
784 dSP; dATARGET; tryAMAGICbin(rshift,opASSIGN);
785 {
786 dPOPTOPiirl;
787 SETi( left >> right );
788 RETURN;
93a17b20 789 }
79072805 790}
791
a0d0e21e 792PP(pp_lt)
79072805 793{
a0d0e21e 794 dSP; tryAMAGICbinSET(lt,0);
795 {
796 dPOPnv;
797 SETs((TOPn < value) ? &sv_yes : &sv_no);
798 RETURN;
79072805 799 }
a0d0e21e 800}
79072805 801
a0d0e21e 802PP(pp_gt)
803{
804 dSP; tryAMAGICbinSET(gt,0);
805 {
806 dPOPnv;
807 SETs((TOPn > value) ? &sv_yes : &sv_no);
808 RETURN;
79072805 809 }
a0d0e21e 810}
811
812PP(pp_le)
813{
814 dSP; tryAMAGICbinSET(le,0);
815 {
816 dPOPnv;
817 SETs((TOPn <= value) ? &sv_yes : &sv_no);
818 RETURN;
79072805 819 }
a0d0e21e 820}
821
822PP(pp_ge)
823{
824 dSP; tryAMAGICbinSET(ge,0);
825 {
826 dPOPnv;
827 SETs((TOPn >= value) ? &sv_yes : &sv_no);
828 RETURN;
79072805 829 }
a0d0e21e 830}
79072805 831
a0d0e21e 832PP(pp_ne)
833{
834 dSP; tryAMAGICbinSET(ne,0);
835 {
836 dPOPnv;
837 SETs((TOPn != value) ? &sv_yes : &sv_no);
838 RETURN;
839 }
79072805 840}
841
a0d0e21e 842PP(pp_ncmp)
79072805 843{
a0d0e21e 844 dSP; dTARGET; tryAMAGICbin(ncmp,0);
845 {
846 dPOPTOPnnrl;
847 I32 value;
79072805 848
a0d0e21e 849 if (left > right)
850 value = 1;
851 else if (left < right)
852 value = -1;
853 else
854 value = 0;
855 SETi(value);
856 RETURN;
79072805 857 }
a0d0e21e 858}
79072805 859
a0d0e21e 860PP(pp_slt)
861{
862 dSP; tryAMAGICbinSET(slt,0);
863 {
864 dPOPTOPssrl;
865 SETs( sv_cmp(left, right) < 0 ? &sv_yes : &sv_no );
866 RETURN;
867 }
79072805 868}
869
a0d0e21e 870PP(pp_sgt)
79072805 871{
a0d0e21e 872 dSP; tryAMAGICbinSET(sgt,0);
873 {
874 dPOPTOPssrl;
875 SETs( sv_cmp(left, right) > 0 ? &sv_yes : &sv_no );
876 RETURN;
877 }
878}
79072805 879
a0d0e21e 880PP(pp_sle)
881{
882 dSP; tryAMAGICbinSET(sle,0);
883 {
884 dPOPTOPssrl;
885 SETs( sv_cmp(left, right) <= 0 ? &sv_yes : &sv_no );
886 RETURN;
79072805 887 }
79072805 888}
889
a0d0e21e 890PP(pp_sge)
891{
892 dSP; tryAMAGICbinSET(sge,0);
893 {
894 dPOPTOPssrl;
895 SETs( sv_cmp(left, right) >= 0 ? &sv_yes : &sv_no );
896 RETURN;
897 }
898}
79072805 899
a0d0e21e 900PP(pp_sne)
79072805 901{
a0d0e21e 902 dSP; tryAMAGICbinSET(sne,0);
903 {
904 dPOPTOPssrl;
905 SETs( !sv_eq(left, right) ? &sv_yes : &sv_no );
906 RETURN;
463ee0b2 907 }
79072805 908}
909
a0d0e21e 910PP(pp_scmp)
79072805 911{
a0d0e21e 912 dSP; dTARGET; tryAMAGICbin(scmp,0);
913 {
914 dPOPTOPssrl;
915 SETi( sv_cmp(left, right) );
916 RETURN;
917 }
918}
79072805 919
a0d0e21e 920PP(pp_bit_and) {
921 dSP; dATARGET; tryAMAGICbin(band,opASSIGN);
922 {
923 dPOPTOPssrl;
4633a7c4 924 if (SvNIOKp(left) || SvNIOKp(right)) {
a0d0e21e 925 unsigned long value = U_L(SvNV(left));
926 value = value & U_L(SvNV(right));
1e11cddc 927 if ((IV)value == value)
928 SETi(value);
929 else
930 SETn((double)value);
a0d0e21e 931 }
932 else {
933 do_vop(op->op_type, TARG, left, right);
934 SETTARG;
935 }
936 RETURN;
937 }
938}
79072805 939
a0d0e21e 940PP(pp_bit_xor)
941{
942 dSP; dATARGET; tryAMAGICbin(bxor,opASSIGN);
943 {
944 dPOPTOPssrl;
4633a7c4 945 if (SvNIOKp(left) || SvNIOKp(right)) {
a0d0e21e 946 unsigned long value = U_L(SvNV(left));
947 value = value ^ U_L(SvNV(right));
1e11cddc 948 if ((IV)value == value)
949 SETi(value);
950 else
951 SETn((double)value);
a0d0e21e 952 }
953 else {
954 do_vop(op->op_type, TARG, left, right);
955 SETTARG;
956 }
957 RETURN;
958 }
959}
79072805 960
a0d0e21e 961PP(pp_bit_or)
962{
963 dSP; dATARGET; tryAMAGICbin(bor,opASSIGN);
964 {
965 dPOPTOPssrl;
4633a7c4 966 if (SvNIOKp(left) || SvNIOKp(right)) {
a0d0e21e 967 unsigned long value = U_L(SvNV(left));
968 value = value | U_L(SvNV(right));
1e11cddc 969 if ((IV)value == value)
970 SETi(value);
971 else
972 SETn((double)value);
a0d0e21e 973 }
974 else {
975 do_vop(op->op_type, TARG, left, right);
976 SETTARG;
977 }
978 RETURN;
79072805 979 }
a0d0e21e 980}
79072805 981
a0d0e21e 982PP(pp_negate)
983{
984 dSP; dTARGET; tryAMAGICun(neg);
985 {
986 dTOPss;
4633a7c4 987 if (SvGMAGICAL(sv))
988 mg_get(sv);
989 if (SvNIOKp(sv))
a0d0e21e 990 SETn(-SvNV(sv));
4633a7c4 991 else if (SvPOKp(sv)) {
a0d0e21e 992 STRLEN len;
993 char *s = SvPV(sv, len);
994 if (isALPHA(*s) || *s == '_') {
995 sv_setpvn(TARG, "-", 1);
996 sv_catsv(TARG, sv);
79072805 997 }
a0d0e21e 998 else if (*s == '+' || *s == '-') {
999 sv_setsv(TARG, sv);
1000 *SvPV_force(TARG, len) = *s == '-' ? '+' : '-';
79072805 1001 }
1002 else
a0d0e21e 1003 sv_setnv(TARG, -SvNV(sv));
1004 SETTARG;
79072805 1005 }
4633a7c4 1006 else
1007 SETn(-SvNV(sv));
79072805 1008 }
a0d0e21e 1009 RETURN;
79072805 1010}
1011
a0d0e21e 1012PP(pp_not)
79072805 1013{
a0d0e21e 1014#ifdef OVERLOAD
1015 dSP; tryAMAGICunSET(not);
1016#endif /* OVERLOAD */
1017 *stack_sp = SvTRUE(*stack_sp) ? &sv_no : &sv_yes;
1018 return NORMAL;
79072805 1019}
1020
a0d0e21e 1021PP(pp_complement)
79072805 1022{
a0d0e21e 1023 dSP; dTARGET; tryAMAGICun(compl);
1024 {
1025 dTOPss;
1026 register I32 anum;
1027
4633a7c4 1028 if (SvNIOKp(sv)) {
1e11cddc 1029 UV value = ~SvIV(sv);
1030 if ((IV)value == value)
1031 SETi(value);
748a9306 1032 else
1e11cddc 1033 SETn((double)value);
a0d0e21e 1034 }
1035 else {
1036 register char *tmps;
1037 register long *tmpl;
1038 STRLEN len;
1039
1040 SvSetSV(TARG, sv);
1041 tmps = SvPV_force(TARG, len);
1042 anum = len;
1043#ifdef LIBERAL
1044 for ( ; anum && (unsigned long)tmps % sizeof(long); anum--, tmps++)
1045 *tmps = ~*tmps;
1046 tmpl = (long*)tmps;
1047 for ( ; anum >= sizeof(long); anum -= sizeof(long), tmpl++)
1048 *tmpl = ~*tmpl;
1049 tmps = (char*)tmpl;
1050#endif
1051 for ( ; anum > 0; anum--, tmps++)
1052 *tmps = ~*tmps;
1053
1054 SETs(TARG);
1055 }
1056 RETURN;
1057 }
79072805 1058}
1059
a0d0e21e 1060/* integer versions of some of the above */
1061
a0d0e21e 1062PP(pp_i_multiply)
79072805 1063{
a0d0e21e 1064 dSP; dATARGET; tryAMAGICbin(mult,opASSIGN);
1065 {
1066 dPOPTOPiirl;
1067 SETi( left * right );
1068 RETURN;
1069 }
79072805 1070}
1071
a0d0e21e 1072PP(pp_i_divide)
79072805 1073{
a0d0e21e 1074 dSP; dATARGET; tryAMAGICbin(div,opASSIGN);
1075 {
1076 dPOPiv;
1077 if (value == 0)
1078 DIE("Illegal division by zero");
1079 value = POPi / value;
1080 PUSHi( value );
1081 RETURN;
1082 }
79072805 1083}
1084
a0d0e21e 1085PP(pp_i_modulo)
79072805 1086{
a0d0e21e 1087 dSP; dATARGET; tryAMAGICbin(mod,opASSIGN);
79072805 1088 {
a0d0e21e 1089 dPOPTOPiirl;
1090 SETi( left % right );
1091 RETURN;
79072805 1092 }
79072805 1093}
1094
a0d0e21e 1095PP(pp_i_add)
79072805 1096{
a0d0e21e 1097 dSP; dATARGET; tryAMAGICbin(add,opASSIGN);
1098 {
1099 dPOPTOPiirl;
1100 SETi( left + right );
1101 RETURN;
79072805 1102 }
79072805 1103}
1104
a0d0e21e 1105PP(pp_i_subtract)
79072805 1106{
a0d0e21e 1107 dSP; dATARGET; tryAMAGICbin(subtr,opASSIGN);
1108 {
1109 dPOPTOPiirl;
1110 SETi( left - right );
1111 RETURN;
79072805 1112 }
79072805 1113}
1114
a0d0e21e 1115PP(pp_i_lt)
79072805 1116{
a0d0e21e 1117 dSP; tryAMAGICbinSET(lt,0);
1118 {
1119 dPOPTOPiirl;
1120 SETs((left < right) ? &sv_yes : &sv_no);
1121 RETURN;
1122 }
79072805 1123}
1124
a0d0e21e 1125PP(pp_i_gt)
79072805 1126{
a0d0e21e 1127 dSP; tryAMAGICbinSET(gt,0);
1128 {
1129 dPOPTOPiirl;
1130 SETs((left > right) ? &sv_yes : &sv_no);
1131 RETURN;
1132 }
79072805 1133}
1134
a0d0e21e 1135PP(pp_i_le)
79072805 1136{
a0d0e21e 1137 dSP; tryAMAGICbinSET(le,0);
1138 {
1139 dPOPTOPiirl;
1140 SETs((left <= right) ? &sv_yes : &sv_no);
1141 RETURN;
85e6fe83 1142 }
79072805 1143}
1144
a0d0e21e 1145PP(pp_i_ge)
79072805 1146{
a0d0e21e 1147 dSP; tryAMAGICbinSET(ge,0);
1148 {
1149 dPOPTOPiirl;
1150 SETs((left >= right) ? &sv_yes : &sv_no);
1151 RETURN;
1152 }
79072805 1153}
1154
a0d0e21e 1155PP(pp_i_eq)
79072805 1156{
a0d0e21e 1157 dSP; tryAMAGICbinSET(eq,0);
1158 {
1159 dPOPTOPiirl;
1160 SETs((left == right) ? &sv_yes : &sv_no);
1161 RETURN;
1162 }
79072805 1163}
1164
a0d0e21e 1165PP(pp_i_ne)
79072805 1166{
a0d0e21e 1167 dSP; tryAMAGICbinSET(ne,0);
1168 {
1169 dPOPTOPiirl;
1170 SETs((left != right) ? &sv_yes : &sv_no);
1171 RETURN;
1172 }
79072805 1173}
1174
a0d0e21e 1175PP(pp_i_ncmp)
79072805 1176{
a0d0e21e 1177 dSP; dTARGET; tryAMAGICbin(ncmp,0);
1178 {
1179 dPOPTOPiirl;
1180 I32 value;
79072805 1181
a0d0e21e 1182 if (left > right)
79072805 1183 value = 1;
a0d0e21e 1184 else if (left < right)
79072805 1185 value = -1;
a0d0e21e 1186 else
79072805 1187 value = 0;
a0d0e21e 1188 SETi(value);
1189 RETURN;
79072805 1190 }
85e6fe83 1191}
1192
1193PP(pp_i_negate)
1194{
a0d0e21e 1195 dSP; dTARGET; tryAMAGICun(neg);
85e6fe83 1196 SETi(-TOPi);
1197 RETURN;
1198}
1199
79072805 1200/* High falutin' math. */
1201
1202PP(pp_atan2)
1203{
a0d0e21e 1204 dSP; dTARGET; tryAMAGICbin(atan2,0);
1205 {
1206 dPOPTOPnnrl;
1207 SETn(atan2(left, right));
1208 RETURN;
1209 }
79072805 1210}
1211
1212PP(pp_sin)
1213{
a0d0e21e 1214 dSP; dTARGET; tryAMAGICun(sin);
1215 {
1216 double value;
1217 value = POPn;
1218 value = sin(value);
1219 XPUSHn(value);
1220 RETURN;
1221 }
79072805 1222}
1223
1224PP(pp_cos)
1225{
a0d0e21e 1226 dSP; dTARGET; tryAMAGICun(cos);
1227 {
1228 double value;
1229 value = POPn;
1230 value = cos(value);
1231 XPUSHn(value);
1232 RETURN;
1233 }
79072805 1234}
1235
1236PP(pp_rand)
1237{
1238 dSP; dTARGET;
1239 double value;
1240 if (MAXARG < 1)
1241 value = 1.0;
1242 else
1243 value = POPn;
1244 if (value == 0.0)
1245 value = 1.0;
1246#if RANDBITS == 31
1247 value = rand() * value / 2147483648.0;
1248#else
1249#if RANDBITS == 16
1250 value = rand() * value / 65536.0;
1251#else
1252#if RANDBITS == 15
1253 value = rand() * value / 32768.0;
1254#else
1255 value = rand() * value / (double)(((unsigned long)1) << RANDBITS);
1256#endif
1257#endif
1258#endif
1259 XPUSHn(value);
1260 RETURN;
1261}
1262
1263PP(pp_srand)
1264{
1265 dSP;
1266 I32 anum;
79072805 1267
1268 if (MAXARG < 1) {
f12c7020 1269#ifdef VMS
1270# include <starlet.h>
1271 unsigned int when[2];
1272 _ckvmssts(sys$gettim(when));
1273 anum = when[0] ^ when[1];
1274#else
1275# if defined(I_SYS_TIME) && !defined(PLAN9)
1276 struct timeval when;
1277 gettimeofday(&when,(struct timezone *) 0);
1278 anum = when.tv_sec ^ when.tv_usec;
1279# else
1280 Time_t when;
79072805 1281 (void)time(&when);
1282 anum = when;
f12c7020 1283# endif
1284#endif
1285#if !defined(PLAN9) /* XXX Plan9 assembler chokes on this; fix coming soon */
1286 /* 17-Jul-1996 bailey@genetics.upenn.edu */
1287 /* What is a good hashing algorithm here? */
1288 anum ^= ( ( 269 * (U32)getpid())
1289 ^ (26107 * (U32)&when)
1290 ^ (73819 * (U32)stack_sp));
1291#endif
79072805 1292 }
1293 else
1294 anum = POPi;
1295 (void)srand(anum);
1296 EXTEND(SP, 1);
1297 RETPUSHYES;
1298}
1299
1300PP(pp_exp)
1301{
a0d0e21e 1302 dSP; dTARGET; tryAMAGICun(exp);
1303 {
1304 double value;
1305 value = POPn;
1306 value = exp(value);
1307 XPUSHn(value);
1308 RETURN;
1309 }
79072805 1310}
1311
1312PP(pp_log)
1313{
a0d0e21e 1314 dSP; dTARGET; tryAMAGICun(log);
1315 {
1316 double value;
1317 value = POPn;
1318 if (value <= 0.0)
2304df62 1319 DIE("Can't take log of %g", value);
a0d0e21e 1320 value = log(value);
1321 XPUSHn(value);
1322 RETURN;
1323 }
79072805 1324}
1325
1326PP(pp_sqrt)
1327{
a0d0e21e 1328 dSP; dTARGET; tryAMAGICun(sqrt);
1329 {
1330 double value;
1331 value = POPn;
1332 if (value < 0.0)
2304df62 1333 DIE("Can't take sqrt of %g", value);
a0d0e21e 1334 value = sqrt(value);
1335 XPUSHn(value);
1336 RETURN;
1337 }
79072805 1338}
1339
1340PP(pp_int)
1341{
1342 dSP; dTARGET;
1343 double value;
a0d0e21e 1344 value = POPn;
79072805 1345 if (value >= 0.0)
1346 (void)modf(value, &value);
1347 else {
1348 (void)modf(-value, &value);
1349 value = -value;
1350 }
1351 XPUSHn(value);
1352 RETURN;
1353}
1354
463ee0b2 1355PP(pp_abs)
1356{
a0d0e21e 1357 dSP; dTARGET; tryAMAGICun(abs);
1358 {
1359 double value;
1360 value = POPn;
463ee0b2 1361
a0d0e21e 1362 if (value < 0.0)
463ee0b2 1363 value = -value;
1364
a0d0e21e 1365 XPUSHn(value);
1366 RETURN;
1367 }
463ee0b2 1368}
1369
79072805 1370PP(pp_hex)
1371{
1372 dSP; dTARGET;
1373 char *tmps;
464e2e8a 1374 unsigned long value;
79072805 1375 I32 argtype;
1376
a0d0e21e 1377 tmps = POPp;
464e2e8a 1378 value = scan_hex(tmps, 99, &argtype);
1379 if ((IV)value >= 0)
1380 XPUSHi(value);
1381 else
1382 XPUSHn(U_V(value));
79072805 1383 RETURN;
1384}
1385
1386PP(pp_oct)
1387{
1388 dSP; dTARGET;
464e2e8a 1389 unsigned long value;
79072805 1390 I32 argtype;
1391 char *tmps;
1392
a0d0e21e 1393 tmps = POPp;
464e2e8a 1394 while (*tmps && isSPACE(*tmps))
1395 tmps++;
1396 if (*tmps == '0')
79072805 1397 tmps++;
1398 if (*tmps == 'x')
464e2e8a 1399 value = scan_hex(++tmps, 99, &argtype);
1400 else
1401 value = scan_oct(tmps, 99, &argtype);
1402 if ((IV)value >= 0)
1403 XPUSHi(value);
79072805 1404 else
464e2e8a 1405 XPUSHn(U_V(value));
79072805 1406 RETURN;
1407}
1408
1409/* String stuff. */
1410
1411PP(pp_length)
1412{
1413 dSP; dTARGET;
a0d0e21e 1414 SETi( sv_len(TOPs) );
79072805 1415 RETURN;
1416}
1417
1418PP(pp_substr)
1419{
1420 dSP; dTARGET;
1421 SV *sv;
1422 I32 len;
463ee0b2 1423 STRLEN curlen;
79072805 1424 I32 pos;
1425 I32 rem;
a0d0e21e 1426 I32 lvalue = op->op_flags & OPf_MOD;
79072805 1427 char *tmps;
a0d0e21e 1428 I32 arybase = curcop->cop_arybase;
79072805 1429
1430 if (MAXARG > 2)
1431 len = POPi;
1432 pos = POPi - arybase;
1433 sv = POPs;
a0d0e21e 1434 tmps = SvPV(sv, curlen);
79072805 1435 if (pos < 0)
1436 pos += curlen + arybase;
2304df62 1437 if (pos < 0 || pos > curlen) {
a0d0e21e 1438 if (dowarn || lvalue)
2304df62 1439 warn("substr outside of string");
1440 RETPUSHUNDEF;
1441 }
79072805 1442 else {
1443 if (MAXARG < 3)
1444 len = curlen;
a0d0e21e 1445 else if (len < 0) {
748a9306 1446 len += curlen - pos;
a0d0e21e 1447 if (len < 0)
1448 len = 0;
1449 }
79072805 1450 tmps += pos;
1451 rem = curlen - pos; /* rem=how many bytes left*/
1452 if (rem > len)
1453 rem = len;
1454 sv_setpvn(TARG, tmps, rem);
1455 if (lvalue) { /* it's an lvalue! */
dedeecda 1456 if (!SvGMAGICAL(sv)) {
1457 if (SvROK(sv)) {
1458 SvPV_force(sv,na);
1459 if (dowarn)
1460 warn("Attempt to use reference as lvalue in substr");
1461 }
1462 if (SvOK(sv)) /* is it defined ? */
1463 (void)SvPOK_only(sv);
1464 else
1465 sv_setpvn(sv,"",0); /* avoid lexical reincarnation */
1466 }
a0d0e21e 1467 if (SvTYPE(TARG) < SVt_PVLV) {
1468 sv_upgrade(TARG, SVt_PVLV);
1469 sv_magic(TARG, Nullsv, 'x', Nullch, 0);
ed6116ce 1470 }
a0d0e21e 1471
79072805 1472 LvTYPE(TARG) = 's';
1473 LvTARG(TARG) = sv;
a0d0e21e 1474 LvTARGOFF(TARG) = pos;
79072805 1475 LvTARGLEN(TARG) = rem;
1476 }
1477 }
1478 PUSHs(TARG); /* avoid SvSETMAGIC here */
1479 RETURN;
1480}
1481
1482PP(pp_vec)
1483{
1484 dSP; dTARGET;
1485 register I32 size = POPi;
1486 register I32 offset = POPi;
1487 register SV *src = POPs;
a0d0e21e 1488 I32 lvalue = op->op_flags & OPf_MOD;
463ee0b2 1489 STRLEN srclen;
1490 unsigned char *s = (unsigned char*)SvPV(src, srclen);
79072805 1491 unsigned long retnum;
1492 I32 len;
1493
1494 offset *= size; /* turn into bit offset */
1495 len = (offset + size + 7) / 8;
1496 if (offset < 0 || size < 1)
1497 retnum = 0;
79072805 1498 else {
a0d0e21e 1499 if (lvalue) { /* it's an lvalue! */
1500 if (SvTYPE(TARG) < SVt_PVLV) {
1501 sv_upgrade(TARG, SVt_PVLV);
1502 sv_magic(TARG, Nullsv, 'v', Nullch, 0);
1503 }
1504
1505 LvTYPE(TARG) = 'v';
1506 LvTARG(TARG) = src;
1507 LvTARGOFF(TARG) = offset;
1508 LvTARGLEN(TARG) = size;
1509 }
93a17b20 1510 if (len > srclen) {
a0d0e21e 1511 if (size <= 8)
1512 retnum = 0;
1513 else {
1514 offset >>= 3;
748a9306 1515 if (size == 16) {
1516 if (offset >= srclen)
1517 retnum = 0;
a0d0e21e 1518 else
748a9306 1519 retnum = (unsigned long) s[offset] << 8;
1520 }
1521 else if (size == 32) {
1522 if (offset >= srclen)
1523 retnum = 0;
1524 else if (offset + 1 >= srclen)
a0d0e21e 1525 retnum = (unsigned long) s[offset] << 24;
748a9306 1526 else if (offset + 2 >= srclen)
1527 retnum = ((unsigned long) s[offset] << 24) +
1528 ((unsigned long) s[offset + 1] << 16);
1529 else
1530 retnum = ((unsigned long) s[offset] << 24) +
1531 ((unsigned long) s[offset + 1] << 16) +
1532 (s[offset + 2] << 8);
a0d0e21e 1533 }
1534 }
79072805 1535 }
a0d0e21e 1536 else if (size < 8)
79072805 1537 retnum = (s[offset >> 3] >> (offset & 7)) & ((1 << size) - 1);
1538 else {
1539 offset >>= 3;
1540 if (size == 8)
1541 retnum = s[offset];
1542 else if (size == 16)
1543 retnum = ((unsigned long) s[offset] << 8) + s[offset+1];
1544 else if (size == 32)
1545 retnum = ((unsigned long) s[offset] << 24) +
1546 ((unsigned long) s[offset + 1] << 16) +
1547 (s[offset + 2] << 8) + s[offset+3];
1548 }
79072805 1549 }
1550
1551 sv_setiv(TARG, (I32)retnum);
1552 PUSHs(TARG);
1553 RETURN;
1554}
1555
1556PP(pp_index)
1557{
1558 dSP; dTARGET;
1559 SV *big;
1560 SV *little;
1561 I32 offset;
1562 I32 retval;
1563 char *tmps;
1564 char *tmps2;
463ee0b2 1565 STRLEN biglen;
a0d0e21e 1566 I32 arybase = curcop->cop_arybase;
79072805 1567
1568 if (MAXARG < 3)
1569 offset = 0;
1570 else
1571 offset = POPi - arybase;
1572 little = POPs;
1573 big = POPs;
463ee0b2 1574 tmps = SvPV(big, biglen);
79072805 1575 if (offset < 0)
1576 offset = 0;
93a17b20 1577 else if (offset > biglen)
1578 offset = biglen;
79072805 1579 if (!(tmps2 = fbm_instr((unsigned char*)tmps + offset,
93a17b20 1580 (unsigned char*)tmps + biglen, little)))
79072805 1581 retval = -1 + arybase;
1582 else
1583 retval = tmps2 - tmps + arybase;
1584 PUSHi(retval);
1585 RETURN;
1586}
1587
1588PP(pp_rindex)
1589{
1590 dSP; dTARGET;
1591 SV *big;
1592 SV *little;
463ee0b2 1593 STRLEN blen;
1594 STRLEN llen;
79072805 1595 SV *offstr;
1596 I32 offset;
1597 I32 retval;
1598 char *tmps;
1599 char *tmps2;
a0d0e21e 1600 I32 arybase = curcop->cop_arybase;
79072805 1601
a0d0e21e 1602 if (MAXARG >= 3)
79072805 1603 offstr = POPs;
1604 little = POPs;
1605 big = POPs;
463ee0b2 1606 tmps2 = SvPV(little, llen);
1607 tmps = SvPV(big, blen);
79072805 1608 if (MAXARG < 3)
463ee0b2 1609 offset = blen;
79072805 1610 else
463ee0b2 1611 offset = SvIV(offstr) - arybase + llen;
79072805 1612 if (offset < 0)
1613 offset = 0;
463ee0b2 1614 else if (offset > blen)
1615 offset = blen;
79072805 1616 if (!(tmps2 = rninstr(tmps, tmps + offset,
463ee0b2 1617 tmps2, tmps2 + llen)))
79072805 1618 retval = -1 + arybase;
1619 else
1620 retval = tmps2 - tmps + arybase;
1621 PUSHi(retval);
1622 RETURN;
1623}
1624
1625PP(pp_sprintf)
1626{
1627 dSP; dMARK; dORIGMARK; dTARGET;
1628 do_sprintf(TARG, SP-MARK, MARK+1);
1629 SP = ORIGMARK;
1630 PUSHTARG;
1631 RETURN;
1632}
1633
79072805 1634PP(pp_ord)
1635{
1636 dSP; dTARGET;
1637 I32 value;
1638 char *tmps;
79072805 1639
79072805 1640#ifndef I286
a0d0e21e 1641 tmps = POPp;
79072805 1642 value = (I32) (*tmps & 255);
1643#else
a0d0e21e 1644 I32 anum;
1645 tmps = POPp;
79072805 1646 anum = (I32) *tmps;
1647 value = (I32) (anum & 255);
1648#endif
1649 XPUSHi(value);
1650 RETURN;
1651}
1652
463ee0b2 1653PP(pp_chr)
1654{
1655 dSP; dTARGET;
1656 char *tmps;
1657
748a9306 1658 (void)SvUPGRADE(TARG,SVt_PV);
1659 SvGROW(TARG,2);
463ee0b2 1660 SvCUR_set(TARG, 1);
1661 tmps = SvPVX(TARG);
748a9306 1662 *tmps++ = POPi;
1663 *tmps = '\0';
a0d0e21e 1664 (void)SvPOK_only(TARG);
463ee0b2 1665 XPUSHs(TARG);
1666 RETURN;
1667}
1668
79072805 1669PP(pp_crypt)
1670{
1671 dSP; dTARGET; dPOPTOPssrl;
1672#ifdef HAS_CRYPT
a0d0e21e 1673 char *tmps = SvPV(left, na);
79072805 1674#ifdef FCRYPT
a0d0e21e 1675 sv_setpv(TARG, fcrypt(tmps, SvPV(right, na)));
79072805 1676#else
a0d0e21e 1677 sv_setpv(TARG, crypt(tmps, SvPV(right, na)));
79072805 1678#endif
1679#else
1680 DIE(
1681 "The crypt() function is unimplemented due to excessive paranoia.");
1682#endif
1683 SETs(TARG);
1684 RETURN;
1685}
1686
1687PP(pp_ucfirst)
1688{
1689 dSP;
1690 SV *sv = TOPs;
1691 register char *s;
1692
ed6116ce 1693 if (!SvPADTMP(sv)) {
79072805 1694 dTARGET;
1695 sv_setsv(TARG, sv);
1696 sv = TARG;
1697 SETs(sv);
1698 }
a0d0e21e 1699 s = SvPV_force(sv, na);
1700 if (isLOWER(*s))
1701 *s = toUPPER(*s);
79072805 1702
1703 RETURN;
1704}
1705
1706PP(pp_lcfirst)
1707{
1708 dSP;
1709 SV *sv = TOPs;
1710 register char *s;
1711
ed6116ce 1712 if (!SvPADTMP(sv)) {
79072805 1713 dTARGET;
1714 sv_setsv(TARG, sv);
1715 sv = TARG;
1716 SETs(sv);
1717 }
a0d0e21e 1718 s = SvPV_force(sv, na);
1719 if (isUPPER(*s))
1720 *s = toLOWER(*s);
79072805 1721
1722 SETs(sv);
1723 RETURN;
1724}
1725
1726PP(pp_uc)
1727{
1728 dSP;
1729 SV *sv = TOPs;
1730 register char *s;
1731 register char *send;
463ee0b2 1732 STRLEN len;
79072805 1733
ed6116ce 1734 if (!SvPADTMP(sv)) {
79072805 1735 dTARGET;
1736 sv_setsv(TARG, sv);
1737 sv = TARG;
1738 SETs(sv);
1739 }
a0d0e21e 1740 s = SvPV_force(sv, len);
463ee0b2 1741 send = s + len;
79072805 1742 while (s < send) {
a0d0e21e 1743 if (isLOWER(*s))
1744 *s = toUPPER(*s);
79072805 1745 s++;
1746 }
1747 RETURN;
1748}
1749
1750PP(pp_lc)
1751{
1752 dSP;
1753 SV *sv = TOPs;
1754 register char *s;
1755 register char *send;
463ee0b2 1756 STRLEN len;
79072805 1757
ed6116ce 1758 if (!SvPADTMP(sv)) {
79072805 1759 dTARGET;
1760 sv_setsv(TARG, sv);
1761 sv = TARG;
1762 SETs(sv);
1763 }
a0d0e21e 1764 s = SvPV_force(sv, len);
463ee0b2 1765 send = s + len;
79072805 1766 while (s < send) {
a0d0e21e 1767 if (isUPPER(*s))
1768 *s = toLOWER(*s);
79072805 1769 s++;
1770 }
1771 RETURN;
1772}
1773
a0d0e21e 1774PP(pp_quotemeta)
79072805 1775{
a0d0e21e 1776 dSP; dTARGET;
1777 SV *sv = TOPs;
1778 STRLEN len;
1779 register char *s = SvPV(sv,len);
1780 register char *d;
79072805 1781
a0d0e21e 1782 if (len) {
1783 (void)SvUPGRADE(TARG, SVt_PV);
c07a80fd 1784 SvGROW(TARG, (len * 2) + 1);
a0d0e21e 1785 d = SvPVX(TARG);
1786 while (len--) {
1787 if (!isALNUM(*s))
1788 *d++ = '\\';
1789 *d++ = *s++;
79072805 1790 }
a0d0e21e 1791 *d = '\0';
1792 SvCUR_set(TARG, d - SvPVX(TARG));
1793 (void)SvPOK_only(TARG);
79072805 1794 }
a0d0e21e 1795 else
1796 sv_setpvn(TARG, s, len);
1797 SETs(TARG);
79072805 1798 RETURN;
1799}
1800
a0d0e21e 1801/* Arrays. */
79072805 1802
a0d0e21e 1803PP(pp_aslice)
79072805 1804{
a0d0e21e 1805 dSP; dMARK; dORIGMARK;
1806 register SV** svp;
1807 register AV* av = (AV*)POPs;
1808 register I32 lval = op->op_flags & OPf_MOD;
748a9306 1809 I32 arybase = curcop->cop_arybase;
1810 I32 elem;
79072805 1811
a0d0e21e 1812 if (SvTYPE(av) == SVt_PVAV) {
748a9306 1813 if (lval && op->op_private & OPpLVAL_INTRO) {
1814 I32 max = -1;
1815 for (svp = mark + 1; svp <= sp; svp++) {
1816 elem = SvIVx(*svp);
1817 if (elem > max)
1818 max = elem;
1819 }
1820 if (max > AvMAX(av))
1821 av_extend(av, max);
1822 }
a0d0e21e 1823 while (++MARK <= SP) {
748a9306 1824 elem = SvIVx(*MARK);
a0d0e21e 1825
748a9306 1826 if (elem > 0)
1827 elem -= arybase;
a0d0e21e 1828 svp = av_fetch(av, elem, lval);
1829 if (lval) {
1830 if (!svp || *svp == &sv_undef)
1831 DIE(no_aelem, elem);
1832 if (op->op_private & OPpLVAL_INTRO)
1833 save_svref(svp);
79072805 1834 }
a0d0e21e 1835 *MARK = svp ? *svp : &sv_undef;
79072805 1836 }
1837 }
748a9306 1838 if (GIMME != G_ARRAY) {
a0d0e21e 1839 MARK = ORIGMARK;
1840 *++MARK = *SP;
1841 SP = MARK;
1842 }
79072805 1843 RETURN;
1844}
1845
1846/* Associative arrays. */
1847
1848PP(pp_each)
1849{
1850 dSP; dTARGET;
1851 HV *hash = (HV*)POPs;
c07a80fd 1852 HE *entry;
c07a80fd 1853
1854 PUTBACK;
1855 entry = hv_iternext(hash); /* might clobber stack_sp */
1856 SPAGAIN;
79072805 1857
79072805 1858 EXTEND(SP, 2);
1859 if (entry) {
f12c7020 1860 PUSHs(hv_iterkeysv(entry)); /* won't clobber stack_sp */
79072805 1861 if (GIMME == G_ARRAY) {
c07a80fd 1862 PUTBACK;
1863 sv_setsv(TARG, hv_iterval(hash, entry)); /* might clobber stack_sp */
1864 SPAGAIN;
8990e307 1865 PUSHs(TARG);
79072805 1866 }
79072805 1867 }
1868 else if (GIMME == G_SCALAR)
1869 RETPUSHUNDEF;
1870
1871 RETURN;
1872}
1873
1874PP(pp_values)
1875{
1876 return do_kv(ARGS);
1877}
1878
1879PP(pp_keys)
1880{
1881 return do_kv(ARGS);
1882}
1883
1884PP(pp_delete)
1885{
1886 dSP;
1887 SV *sv;
1888 SV *tmpsv = POPs;
1889 HV *hv = (HV*)POPs;
463ee0b2 1890 STRLEN len;
a0d0e21e 1891 if (SvTYPE(hv) != SVt_PVHV) {
1892 DIE("Not a HASH reference");
79072805 1893 }
f12c7020 1894 sv = hv_delete_ent(hv, tmpsv,
1895 (op->op_private & OPpLEAVE_VOID ? G_DISCARD : 0), 0);
79072805 1896 if (!sv)
1897 RETPUSHUNDEF;
1898 PUSHs(sv);
1899 RETURN;
1900}
1901
a0d0e21e 1902PP(pp_exists)
79072805 1903{
a0d0e21e 1904 dSP;
1905 SV *tmpsv = POPs;
1906 HV *hv = (HV*)POPs;
a0d0e21e 1907 STRLEN len;
1908 if (SvTYPE(hv) != SVt_PVHV) {
1909 DIE("Not a HASH reference");
1910 }
f12c7020 1911 if (hv_exists_ent(hv, tmpsv, 0))
a0d0e21e 1912 RETPUSHYES;
1913 RETPUSHNO;
1914}
79072805 1915
a0d0e21e 1916PP(pp_hslice)
1917{
1918 dSP; dMARK; dORIGMARK;
f12c7020 1919 register HE *he;
a0d0e21e 1920 register HV *hv = (HV*)POPs;
1921 register I32 lval = op->op_flags & OPf_MOD;
79072805 1922
a0d0e21e 1923 if (SvTYPE(hv) == SVt_PVHV) {
1924 while (++MARK <= SP) {
f12c7020 1925 SV *keysv = *MARK;
79072805 1926
f12c7020 1927 he = hv_fetch_ent(hv, keysv, lval, 0);
a0d0e21e 1928 if (lval) {
f12c7020 1929 if (!he || HeVAL(he) == &sv_undef)
1930 DIE(no_helem, SvPV(keysv, na));
a0d0e21e 1931 if (op->op_private & OPpLVAL_INTRO)
f12c7020 1932 save_svref(&HeVAL(he));
93a17b20 1933 }
f12c7020 1934 *MARK = he ? HeVAL(he) : &sv_undef;
79072805 1935 }
1936 }
a0d0e21e 1937 if (GIMME != G_ARRAY) {
1938 MARK = ORIGMARK;
1939 *++MARK = *SP;
1940 SP = MARK;
79072805 1941 }
a0d0e21e 1942 RETURN;
1943}
1944
1945/* List operators. */
1946
1947PP(pp_list)
1948{
1949 dSP; dMARK;
1950 if (GIMME != G_ARRAY) {
1951 if (++MARK <= SP)
1952 *MARK = *SP; /* unwanted list, return last item */
8990e307 1953 else
a0d0e21e 1954 *MARK = &sv_undef;
1955 SP = MARK;
79072805 1956 }
a0d0e21e 1957 RETURN;
79072805 1958}
1959
a0d0e21e 1960PP(pp_lslice)
79072805 1961{
1962 dSP;
a0d0e21e 1963 SV **lastrelem = stack_sp;
1964 SV **lastlelem = stack_base + POPMARK;
1965 SV **firstlelem = stack_base + POPMARK + 1;
1966 register SV **firstrelem = lastlelem + 1;
1967 I32 arybase = curcop->cop_arybase;
4633a7c4 1968 I32 lval = op->op_flags & OPf_MOD;
1969 I32 is_something_there = lval;
79072805 1970
a0d0e21e 1971 register I32 max = lastrelem - lastlelem;
1972 register SV **lelem;
1973 register I32 ix;
1974
1975 if (GIMME != G_ARRAY) {
748a9306 1976 ix = SvIVx(*lastlelem);
1977 if (ix < 0)
1978 ix += max;
1979 else
1980 ix -= arybase;
a0d0e21e 1981 if (ix < 0 || ix >= max)
1982 *firstlelem = &sv_undef;
1983 else
1984 *firstlelem = firstrelem[ix];
1985 SP = firstlelem;
1986 RETURN;
1987 }
1988
1989 if (max == 0) {
1990 SP = firstlelem - 1;
1991 RETURN;
1992 }
1993
1994 for (lelem = firstlelem; lelem <= lastlelem; lelem++) {
748a9306 1995 ix = SvIVx(*lelem);
a0d0e21e 1996 if (ix < 0) {
1997 ix += max;
1998 if (ix < 0)
1999 *lelem = &sv_undef;
2000 else if (!(*lelem = firstrelem[ix]))
2001 *lelem = &sv_undef;
79072805 2002 }
748a9306 2003 else {
2004 ix -= arybase;
2005 if (ix >= max || !(*lelem = firstrelem[ix]))
2006 *lelem = &sv_undef;
2007 }
4633a7c4 2008 if (!is_something_there && (SvOKp(*lelem) || SvGMAGICAL(*lelem)))
2009 is_something_there = TRUE;
79072805 2010 }
4633a7c4 2011 if (is_something_there)
2012 SP = lastlelem;
2013 else
2014 SP = firstlelem - 1;
79072805 2015 RETURN;
2016}
2017
a0d0e21e 2018PP(pp_anonlist)
2019{
2020 dSP; dMARK;
2021 I32 items = SP - MARK;
2022 SP = MARK;
2023 XPUSHs((SV*)sv_2mortal((SV*)av_make(items, MARK+1)));
2024 RETURN;
2025}
2026
2027PP(pp_anonhash)
79072805 2028{
2029 dSP; dMARK; dORIGMARK;
a0d0e21e 2030 STRLEN len;
2031 HV* hv = (HV*)sv_2mortal((SV*)newHV());
2032
2033 while (MARK < SP) {
2034 SV* key = *++MARK;
a0d0e21e 2035 SV *val = NEWSV(46, 0);
2036 if (MARK < SP)
2037 sv_setsv(val, *++MARK);
2038 else
2039 warn("Odd number of elements in hash list");
f12c7020 2040 (void)hv_store_ent(hv,key,val,0);
79072805 2041 }
a0d0e21e 2042 SP = ORIGMARK;
2043 XPUSHs((SV*)hv);
79072805 2044 RETURN;
2045}
2046
a0d0e21e 2047PP(pp_splice)
79072805 2048{
a0d0e21e 2049 dSP; dMARK; dORIGMARK;
2050 register AV *ary = (AV*)*++MARK;
2051 register SV **src;
2052 register SV **dst;
2053 register I32 i;
2054 register I32 offset;
2055 register I32 length;
2056 I32 newlen;
2057 I32 after;
2058 I32 diff;
2059 SV **tmparyval = 0;
79072805 2060
a0d0e21e 2061 SP++;
79072805 2062
a0d0e21e 2063 if (++MARK < SP) {
2064 offset = SvIVx(*MARK);
2065 if (offset < 0)
2066 offset += AvFILL(ary) + 1;
2067 else
2068 offset -= curcop->cop_arybase;
2069 if (++MARK < SP) {
2070 length = SvIVx(*MARK++);
2071 if (length < 0)
2072 length = 0;
79072805 2073 }
2074 else
a0d0e21e 2075 length = AvMAX(ary) + 1; /* close enough to infinity */
79072805 2076 }
a0d0e21e 2077 else {
2078 offset = 0;
2079 length = AvMAX(ary) + 1;
2080 }
2081 if (offset < 0) {
2082 length += offset;
2083 offset = 0;
2084 if (length < 0)
2085 length = 0;
2086 }
2087 if (offset > AvFILL(ary) + 1)
2088 offset = AvFILL(ary) + 1;
2089 after = AvFILL(ary) + 1 - (offset + length);
2090 if (after < 0) { /* not that much array */
2091 length += after; /* offset+length now in array */
2092 after = 0;
2093 if (!AvALLOC(ary))
2094 av_extend(ary, 0);
2095 }
2096
2097 /* At this point, MARK .. SP-1 is our new LIST */
2098
2099 newlen = SP - MARK;
2100 diff = newlen - length;
2101
2102 if (diff < 0) { /* shrinking the area */
2103 if (newlen) {
2104 New(451, tmparyval, newlen, SV*); /* so remember insertion */
2105 Copy(MARK, tmparyval, newlen, SV*);
79072805 2106 }
a0d0e21e 2107
2108 MARK = ORIGMARK + 1;
2109 if (GIMME == G_ARRAY) { /* copy return vals to stack */
2110 MEXTEND(MARK, length);
2111 Copy(AvARRAY(ary)+offset, MARK, length, SV*);
2112 if (AvREAL(ary)) {
2113 for (i = length, dst = MARK; i; i--)
2114 sv_2mortal(*dst++); /* free them eventualy */
2115 }
2116 MARK += length - 1;
79072805 2117 }
a0d0e21e 2118 else {
2119 *MARK = AvARRAY(ary)[offset+length-1];
2120 if (AvREAL(ary)) {
2121 sv_2mortal(*MARK);
2122 for (i = length - 1, dst = &AvARRAY(ary)[offset]; i > 0; i--)
2123 SvREFCNT_dec(*dst++); /* free them now */
79072805 2124 }
a0d0e21e 2125 }
2126 AvFILL(ary) += diff;
2127
2128 /* pull up or down? */
2129
2130 if (offset < after) { /* easier to pull up */
2131 if (offset) { /* esp. if nothing to pull */
2132 src = &AvARRAY(ary)[offset-1];
2133 dst = src - diff; /* diff is negative */
2134 for (i = offset; i > 0; i--) /* can't trust Copy */
2135 *dst-- = *src--;
79072805 2136 }
a0d0e21e 2137 dst = AvARRAY(ary);
2138 SvPVX(ary) = (char*)(AvARRAY(ary) - diff); /* diff is negative */
2139 AvMAX(ary) += diff;
2140 }
2141 else {
2142 if (after) { /* anything to pull down? */
2143 src = AvARRAY(ary) + offset + length;
2144 dst = src + diff; /* diff is negative */
2145 Move(src, dst, after, SV*);
79072805 2146 }
a0d0e21e 2147 dst = &AvARRAY(ary)[AvFILL(ary)+1];
2148 /* avoid later double free */
2149 }
2150 i = -diff;
2151 while (i)
2152 dst[--i] = &sv_undef;
2153
2154 if (newlen) {
2155 for (src = tmparyval, dst = AvARRAY(ary) + offset;
2156 newlen; newlen--) {
2157 *dst = NEWSV(46, 0);
2158 sv_setsv(*dst++, *src++);
79072805 2159 }
a0d0e21e 2160 Safefree(tmparyval);
2161 }
2162 }
2163 else { /* no, expanding (or same) */
2164 if (length) {
2165 New(452, tmparyval, length, SV*); /* so remember deletion */
2166 Copy(AvARRAY(ary)+offset, tmparyval, length, SV*);
2167 }
2168
2169 if (diff > 0) { /* expanding */
2170
2171 /* push up or down? */
2172
2173 if (offset < after && diff <= AvARRAY(ary) - AvALLOC(ary)) {
2174 if (offset) {
2175 src = AvARRAY(ary);
2176 dst = src - diff;
2177 Move(src, dst, offset, SV*);
79072805 2178 }
a0d0e21e 2179 SvPVX(ary) = (char*)(AvARRAY(ary) - diff);/* diff is positive */
2180 AvMAX(ary) += diff;
2181 AvFILL(ary) += diff;
79072805 2182 }
2183 else {
a0d0e21e 2184 if (AvFILL(ary) + diff >= AvMAX(ary)) /* oh, well */
2185 av_extend(ary, AvFILL(ary) + diff);
2186 AvFILL(ary) += diff;
2187
2188 if (after) {
2189 dst = AvARRAY(ary) + AvFILL(ary);
2190 src = dst - diff;
2191 for (i = after; i; i--) {
2192 *dst-- = *src--;
2193 }
79072805 2194 }
2195 }
a0d0e21e 2196 }
2197
2198 for (src = MARK, dst = AvARRAY(ary) + offset; newlen; newlen--) {
2199 *dst = NEWSV(46, 0);
2200 sv_setsv(*dst++, *src++);
2201 }
2202 MARK = ORIGMARK + 1;
2203 if (GIMME == G_ARRAY) { /* copy return vals to stack */
2204 if (length) {
2205 Copy(tmparyval, MARK, length, SV*);
2206 if (AvREAL(ary)) {
2207 for (i = length, dst = MARK; i; i--)
2208 sv_2mortal(*dst++); /* free them eventualy */
79072805 2209 }
a0d0e21e 2210 Safefree(tmparyval);
79072805 2211 }
a0d0e21e 2212 MARK += length - 1;
2213 }
2214 else if (length--) {
2215 *MARK = tmparyval[length];
2216 if (AvREAL(ary)) {
2217 sv_2mortal(*MARK);
2218 while (length-- > 0)
2219 SvREFCNT_dec(tmparyval[length]);
79072805 2220 }
a0d0e21e 2221 Safefree(tmparyval);
79072805 2222 }
a0d0e21e 2223 else
2224 *MARK = &sv_undef;
79072805 2225 }
a0d0e21e 2226 SP = MARK;
79072805 2227 RETURN;
2228}
2229
a0d0e21e 2230PP(pp_push)
79072805 2231{
2232 dSP; dMARK; dORIGMARK; dTARGET;
a0d0e21e 2233 register AV *ary = (AV*)*++MARK;
2234 register SV *sv = &sv_undef;
79072805 2235
a0d0e21e 2236 for (++MARK; MARK <= SP; MARK++) {
2237 sv = NEWSV(51, 0);
2238 if (*MARK)
2239 sv_setsv(sv, *MARK);
2240 av_push(ary, sv);
79072805 2241 }
2242 SP = ORIGMARK;
a0d0e21e 2243 PUSHi( AvFILL(ary) + 1 );
79072805 2244 RETURN;
2245}
2246
a0d0e21e 2247PP(pp_pop)
79072805 2248{
2249 dSP;
a0d0e21e 2250 AV *av = (AV*)POPs;
2251 SV *sv = av_pop(av);
2252 if (sv != &sv_undef && AvREAL(av))
2253 (void)sv_2mortal(sv);
2254 PUSHs(sv);
79072805 2255 RETURN;
79072805 2256}
2257
a0d0e21e 2258PP(pp_shift)
79072805 2259{
2260 dSP;
a0d0e21e 2261 AV *av = (AV*)POPs;
2262 SV *sv = av_shift(av);
79072805 2263 EXTEND(SP, 1);
a0d0e21e 2264 if (!sv)
79072805 2265 RETPUSHUNDEF;
a0d0e21e 2266 if (sv != &sv_undef && AvREAL(av))
2267 (void)sv_2mortal(sv);
2268 PUSHs(sv);
79072805 2269 RETURN;
79072805 2270}
2271
a0d0e21e 2272PP(pp_unshift)
79072805 2273{
a0d0e21e 2274 dSP; dMARK; dORIGMARK; dTARGET;
2275 register AV *ary = (AV*)*++MARK;
2276 register SV *sv;
2277 register I32 i = 0;
79072805 2278
a0d0e21e 2279 av_unshift(ary, SP - MARK);
2280 while (MARK < SP) {
2281 sv = NEWSV(27, 0);
2282 sv_setsv(sv, *++MARK);
2283 (void)av_store(ary, i++, sv);
79072805 2284 }
79072805 2285
a0d0e21e 2286 SP = ORIGMARK;
2287 PUSHi( AvFILL(ary) + 1 );
79072805 2288 RETURN;
79072805 2289}
2290
a0d0e21e 2291PP(pp_reverse)
79072805 2292{
a0d0e21e 2293 dSP; dMARK;
2294 register SV *tmp;
2295 SV **oldsp = SP;
79072805 2296
a0d0e21e 2297 if (GIMME == G_ARRAY) {
2298 MARK++;
2299 while (MARK < SP) {
2300 tmp = *MARK;
2301 *MARK++ = *SP;
2302 *SP-- = tmp;
2303 }
2304 SP = oldsp;
79072805 2305 }
2306 else {
a0d0e21e 2307 register char *up;
2308 register char *down;
2309 register I32 tmp;
2310 dTARGET;
2311 STRLEN len;
79072805 2312
a0d0e21e 2313 if (SP - MARK > 1)
2314 do_join(TARG, &sv_no, MARK, SP);
2315 else
2316 sv_setsv(TARG, *SP);
2317 up = SvPV_force(TARG, len);
2318 if (len > 1) {
2319 down = SvPVX(TARG) + len - 1;
2320 while (down > up) {
2321 tmp = *up;
2322 *up++ = *down;
2323 *down-- = tmp;
2324 }
2325 (void)SvPOK_only(TARG);
79072805 2326 }
a0d0e21e 2327 SP = MARK + 1;
2328 SETTARG;
79072805 2329 }
a0d0e21e 2330 RETURN;
79072805 2331}
2332
a0d0e21e 2333/* Explosives and implosives. */
2334
2335PP(pp_unpack)
79072805 2336{
2337 dSP;
a0d0e21e 2338 dPOPPOPssrl;
ed6116ce 2339 SV *sv;
a0d0e21e 2340 STRLEN llen;
2341 STRLEN rlen;
2342 register char *pat = SvPV(left, llen);
2343 register char *s = SvPV(right, rlen);
2344 char *strend = s + rlen;
2345 char *strbeg = s;
2346 register char *patend = pat + llen;
2347 I32 datumtype;
2348 register I32 len;
2349 register I32 bits;
79072805 2350
a0d0e21e 2351 /* These must not be in registers: */
2352 I16 ashort;
2353 int aint;
2354 I32 along;
ecfc5424 2355#ifdef HAS_QUAD
2356 Quad_t aquad;
a0d0e21e 2357#endif
2358 U16 aushort;
2359 unsigned int auint;
2360 U32 aulong;
ecfc5424 2361#ifdef HAS_QUAD
2362 unsigned Quad_t auquad;
a0d0e21e 2363#endif
2364 char *aptr;
2365 float afloat;
2366 double adouble;
2367 I32 checksum = 0;
2368 register U32 culong;
2369 double cdouble;
2370 static char* bitcount = 0;
79072805 2371
a0d0e21e 2372 if (GIMME != G_ARRAY) { /* arrange to do first one only */
2373 /*SUPPRESS 530*/
2374 for (patend = pat; !isALPHA(*patend) || *patend == 'x'; patend++) ;
748a9306 2375 if (strchr("aAbBhHP", *patend) || *pat == '%') {
a0d0e21e 2376 patend++;
2377 while (isDIGIT(*patend) || *patend == '*')
2378 patend++;
2379 }
2380 else
2381 patend++;
79072805 2382 }
a0d0e21e 2383 while (pat < patend) {
2384 reparse:
2385 datumtype = *pat++;
2386 if (pat >= patend)
2387 len = 1;
2388 else if (*pat == '*') {
2389 len = strend - strbeg; /* long enough */
2390 pat++;
2391 }
2392 else if (isDIGIT(*pat)) {
2393 len = *pat++ - '0';
2394 while (isDIGIT(*pat))
2395 len = (len * 10) + (*pat++ - '0');
2396 }
2397 else
2398 len = (datumtype != '@');
2399 switch(datumtype) {
2400 default:
2401 break;
2402 case '%':
2403 if (len == 1 && pat[-1] != '1')
2404 len = 16;
2405 checksum = len;
2406 culong = 0;
2407 cdouble = 0;
2408 if (pat < patend)
2409 goto reparse;
2410 break;
2411 case '@':
2412 if (len > strend - strbeg)
2413 DIE("@ outside of string");
2414 s = strbeg + len;
2415 break;
2416 case 'X':
2417 if (len > s - strbeg)
2418 DIE("X outside of string");
2419 s -= len;
2420 break;
2421 case 'x':
2422 if (len > strend - s)
2423 DIE("x outside of string");
2424 s += len;
2425 break;
2426 case 'A':
2427 case 'a':
2428 if (len > strend - s)
2429 len = strend - s;
2430 if (checksum)
2431 goto uchar_checksum;
2432 sv = NEWSV(35, len);
2433 sv_setpvn(sv, s, len);
2434 s += len;
2435 if (datumtype == 'A') {
2436 aptr = s; /* borrow register */
2437 s = SvPVX(sv) + len - 1;
2438 while (s >= SvPVX(sv) && (!*s || isSPACE(*s)))
2439 s--;
2440 *++s = '\0';
2441 SvCUR_set(sv, s - SvPVX(sv));
2442 s = aptr; /* unborrow register */
2443 }
2444 XPUSHs(sv_2mortal(sv));
2445 break;
2446 case 'B':
2447 case 'b':
2448 if (pat[-1] == '*' || len > (strend - s) * 8)
2449 len = (strend - s) * 8;
2450 if (checksum) {
2451 if (!bitcount) {
2452 Newz(601, bitcount, 256, char);
2453 for (bits = 1; bits < 256; bits++) {
2454 if (bits & 1) bitcount[bits]++;
2455 if (bits & 2) bitcount[bits]++;
2456 if (bits & 4) bitcount[bits]++;
2457 if (bits & 8) bitcount[bits]++;
2458 if (bits & 16) bitcount[bits]++;
2459 if (bits & 32) bitcount[bits]++;
2460 if (bits & 64) bitcount[bits]++;
2461 if (bits & 128) bitcount[bits]++;
2462 }
2463 }
2464 while (len >= 8) {
2465 culong += bitcount[*(unsigned char*)s++];
2466 len -= 8;
2467 }
2468 if (len) {
2469 bits = *s;
2470 if (datumtype == 'b') {
2471 while (len-- > 0) {
2472 if (bits & 1) culong++;
2473 bits >>= 1;
2474 }
2475 }
2476 else {
2477 while (len-- > 0) {
2478 if (bits & 128) culong++;
2479 bits <<= 1;
2480 }
2481 }
2482 }
79072805 2483 break;
2484 }
a0d0e21e 2485 sv = NEWSV(35, len + 1);
2486 SvCUR_set(sv, len);
2487 SvPOK_on(sv);
2488 aptr = pat; /* borrow register */
2489 pat = SvPVX(sv);
2490 if (datumtype == 'b') {
2491 aint = len;
2492 for (len = 0; len < aint; len++) {
2493 if (len & 7) /*SUPPRESS 595*/
2494 bits >>= 1;
2495 else
2496 bits = *s++;
2497 *pat++ = '0' + (bits & 1);
2498 }
2499 }
2500 else {
2501 aint = len;
2502 for (len = 0; len < aint; len++) {
2503 if (len & 7)
2504 bits <<= 1;
2505 else
2506 bits = *s++;
2507 *pat++ = '0' + ((bits & 128) != 0);
2508 }
2509 }
2510 *pat = '\0';
2511 pat = aptr; /* unborrow register */
2512 XPUSHs(sv_2mortal(sv));
2513 break;
2514 case 'H':
2515 case 'h':
2516 if (pat[-1] == '*' || len > (strend - s) * 2)
2517 len = (strend - s) * 2;
2518 sv = NEWSV(35, len + 1);
2519 SvCUR_set(sv, len);
2520 SvPOK_on(sv);
2521 aptr = pat; /* borrow register */
2522 pat = SvPVX(sv);
2523 if (datumtype == 'h') {
2524 aint = len;
2525 for (len = 0; len < aint; len++) {
2526 if (len & 1)
2527 bits >>= 4;
2528 else
2529 bits = *s++;
2530 *pat++ = hexdigit[bits & 15];
2531 }
2532 }
2533 else {
2534 aint = len;
2535 for (len = 0; len < aint; len++) {
2536 if (len & 1)
2537 bits <<= 4;
2538 else
2539 bits = *s++;
2540 *pat++ = hexdigit[(bits >> 4) & 15];
2541 }
2542 }
2543 *pat = '\0';
2544 pat = aptr; /* unborrow register */
2545 XPUSHs(sv_2mortal(sv));
2546 break;
2547 case 'c':
2548 if (len > strend - s)
2549 len = strend - s;
2550 if (checksum) {
2551 while (len-- > 0) {
2552 aint = *s++;
2553 if (aint >= 128) /* fake up signed chars */
2554 aint -= 256;
2555 culong += aint;
2556 }
2557 }
2558 else {
2559 EXTEND(SP, len);
2560 while (len-- > 0) {
2561 aint = *s++;
2562 if (aint >= 128) /* fake up signed chars */
2563 aint -= 256;
2564 sv = NEWSV(36, 0);
2565 sv_setiv(sv, (I32)aint);
2566 PUSHs(sv_2mortal(sv));
2567 }
2568 }
2569 break;
2570 case 'C':
2571 if (len > strend - s)
2572 len = strend - s;
2573 if (checksum) {
2574 uchar_checksum:
2575 while (len-- > 0) {
2576 auint = *s++ & 255;
2577 culong += auint;
2578 }
2579 }
2580 else {
2581 EXTEND(SP, len);
2582 while (len-- > 0) {
2583 auint = *s++ & 255;
2584 sv = NEWSV(37, 0);
2585 sv_setiv(sv, (I32)auint);
2586 PUSHs(sv_2mortal(sv));
2587 }
2588 }
2589 break;
2590 case 's':
2591 along = (strend - s) / sizeof(I16);
2592 if (len > along)
2593 len = along;
2594 if (checksum) {
2595 while (len-- > 0) {
2596 Copy(s, &ashort, 1, I16);
2597 s += sizeof(I16);
2598 culong += ashort;
2599 }
2600 }
2601 else {
2602 EXTEND(SP, len);
2603 while (len-- > 0) {
2604 Copy(s, &ashort, 1, I16);
2605 s += sizeof(I16);
2606 sv = NEWSV(38, 0);
2607 sv_setiv(sv, (I32)ashort);
2608 PUSHs(sv_2mortal(sv));
2609 }
2610 }
2611 break;
2612 case 'v':
2613 case 'n':
2614 case 'S':
2615 along = (strend - s) / sizeof(U16);
2616 if (len > along)
2617 len = along;
2618 if (checksum) {
2619 while (len-- > 0) {
2620 Copy(s, &aushort, 1, U16);
2621 s += sizeof(U16);
2622#ifdef HAS_NTOHS
2623 if (datumtype == 'n')
2624 aushort = ntohs(aushort);
79072805 2625#endif
a0d0e21e 2626#ifdef HAS_VTOHS
2627 if (datumtype == 'v')
2628 aushort = vtohs(aushort);
79072805 2629#endif
a0d0e21e 2630 culong += aushort;
2631 }
2632 }
2633 else {
2634 EXTEND(SP, len);
2635 while (len-- > 0) {
2636 Copy(s, &aushort, 1, U16);
2637 s += sizeof(U16);
2638 sv = NEWSV(39, 0);
2639#ifdef HAS_NTOHS
2640 if (datumtype == 'n')
2641 aushort = ntohs(aushort);
79072805 2642#endif
a0d0e21e 2643#ifdef HAS_VTOHS
2644 if (datumtype == 'v')
2645 aushort = vtohs(aushort);
79072805 2646#endif
a0d0e21e 2647 sv_setiv(sv, (I32)aushort);
2648 PUSHs(sv_2mortal(sv));
2649 }
2650 }
2651 break;
2652 case 'i':
2653 along = (strend - s) / sizeof(int);
2654 if (len > along)
2655 len = along;
2656 if (checksum) {
2657 while (len-- > 0) {
2658 Copy(s, &aint, 1, int);
2659 s += sizeof(int);
2660 if (checksum > 32)
2661 cdouble += (double)aint;
2662 else
2663 culong += aint;
2664 }
2665 }
2666 else {
2667 EXTEND(SP, len);
2668 while (len-- > 0) {
2669 Copy(s, &aint, 1, int);
2670 s += sizeof(int);
2671 sv = NEWSV(40, 0);
2672 sv_setiv(sv, (I32)aint);
2673 PUSHs(sv_2mortal(sv));
2674 }
2675 }
2676 break;
2677 case 'I':
2678 along = (strend - s) / sizeof(unsigned int);
2679 if (len > along)
2680 len = along;
2681 if (checksum) {
2682 while (len-- > 0) {
2683 Copy(s, &auint, 1, unsigned int);
2684 s += sizeof(unsigned int);
2685 if (checksum > 32)
2686 cdouble += (double)auint;
2687 else
2688 culong += auint;
2689 }
2690 }
2691 else {
2692 EXTEND(SP, len);
2693 while (len-- > 0) {
2694 Copy(s, &auint, 1, unsigned int);
2695 s += sizeof(unsigned int);
2696 sv = NEWSV(41, 0);
1e11cddc 2697 if (auint <= I32_MAX)
2698 sv_setiv(sv, (I32)auint);
2699 else
2700 sv_setnv(sv, (double)auint);
a0d0e21e 2701 PUSHs(sv_2mortal(sv));
2702 }
2703 }
2704 break;
2705 case 'l':
2706 along = (strend - s) / sizeof(I32);
2707 if (len > along)
2708 len = along;
2709 if (checksum) {
2710 while (len-- > 0) {
2711 Copy(s, &along, 1, I32);
2712 s += sizeof(I32);
2713 if (checksum > 32)
2714 cdouble += (double)along;
2715 else
2716 culong += along;
2717 }
2718 }
2719 else {
2720 EXTEND(SP, len);
2721 while (len-- > 0) {
2722 Copy(s, &along, 1, I32);
2723 s += sizeof(I32);
2724 sv = NEWSV(42, 0);
2725 sv_setiv(sv, (I32)along);
2726 PUSHs(sv_2mortal(sv));
2727 }
79072805 2728 }
a0d0e21e 2729 break;
2730 case 'V':
2731 case 'N':
2732 case 'L':
2733 along = (strend - s) / sizeof(U32);
2734 if (len > along)
2735 len = along;
2736 if (checksum) {
2737 while (len-- > 0) {
2738 Copy(s, &aulong, 1, U32);
2739 s += sizeof(U32);
2740#ifdef HAS_NTOHL
2741 if (datumtype == 'N')
2742 aulong = ntohl(aulong);
79072805 2743#endif
a0d0e21e 2744#ifdef HAS_VTOHL
2745 if (datumtype == 'V')
2746 aulong = vtohl(aulong);
79072805 2747#endif
a0d0e21e 2748 if (checksum > 32)
2749 cdouble += (double)aulong;
2750 else
2751 culong += aulong;
2752 }
2753 }
2754 else {
2755 EXTEND(SP, len);
2756 while (len-- > 0) {
2757 Copy(s, &aulong, 1, U32);
2758 s += sizeof(U32);
2759 sv = NEWSV(43, 0);
2760#ifdef HAS_NTOHL
2761 if (datumtype == 'N')
2762 aulong = ntohl(aulong);
79072805 2763#endif
a0d0e21e 2764#ifdef HAS_VTOHL
2765 if (datumtype == 'V')
2766 aulong = vtohl(aulong);
79072805 2767#endif
a0d0e21e 2768 sv_setnv(sv, (double)aulong);
2769 PUSHs(sv_2mortal(sv));
2770 }
2771 }
2772 break;
2773 case 'p':
2774 along = (strend - s) / sizeof(char*);
2775 if (len > along)
2776 len = along;
2777 EXTEND(SP, len);
2778 while (len-- > 0) {
2779 if (sizeof(char*) > strend - s)
2780 break;
2781 else {
2782 Copy(s, &aptr, 1, char*);
2783 s += sizeof(char*);
2784 }
2785 sv = NEWSV(44, 0);
2786 if (aptr)
2787 sv_setpv(sv, aptr);
2788 PUSHs(sv_2mortal(sv));
2789 }
2790 break;
2791 case 'P':
2792 EXTEND(SP, 1);
2793 if (sizeof(char*) > strend - s)
2794 break;
2795 else {
2796 Copy(s, &aptr, 1, char*);
2797 s += sizeof(char*);
2798 }
2799 sv = NEWSV(44, 0);
2800 if (aptr)
2801 sv_setpvn(sv, aptr, len);
2802 PUSHs(sv_2mortal(sv));
2803 break;
ecfc5424 2804#ifdef HAS_QUAD
a0d0e21e 2805 case 'q':
2806 EXTEND(SP, len);
2807 while (len-- > 0) {
ecfc5424 2808 if (s + sizeof(Quad_t) > strend)
a0d0e21e 2809 aquad = 0;
2810 else {
ecfc5424 2811 Copy(s, &aquad, 1, Quad_t);
2812 s += sizeof(Quad_t);
a0d0e21e 2813 }
2814 sv = NEWSV(42, 0);
2815 sv_setiv(sv, (IV)aquad);
2816 PUSHs(sv_2mortal(sv));
2817 }
2818 break;
2819 case 'Q':
2820 EXTEND(SP, len);
2821 while (len-- > 0) {
ecfc5424 2822 if (s + sizeof(unsigned Quad_t) > strend)
a0d0e21e 2823 auquad = 0;
2824 else {
ecfc5424 2825 Copy(s, &auquad, 1, unsigned Quad_t);
2826 s += sizeof(unsigned Quad_t);
a0d0e21e 2827 }
2828 sv = NEWSV(43, 0);
2829 sv_setiv(sv, (IV)auquad);
2830 PUSHs(sv_2mortal(sv));
2831 }
2832 break;
79072805 2833#endif
a0d0e21e 2834 /* float and double added gnb@melba.bby.oz.au 22/11/89 */
2835 case 'f':
2836 case 'F':
2837 along = (strend - s) / sizeof(float);
2838 if (len > along)
2839 len = along;
2840 if (checksum) {
2841 while (len-- > 0) {
2842 Copy(s, &afloat, 1, float);
2843 s += sizeof(float);
2844 cdouble += afloat;
2845 }
2846 }
2847 else {
2848 EXTEND(SP, len);
2849 while (len-- > 0) {
2850 Copy(s, &afloat, 1, float);
2851 s += sizeof(float);
2852 sv = NEWSV(47, 0);
2853 sv_setnv(sv, (double)afloat);
2854 PUSHs(sv_2mortal(sv));
2855 }
2856 }
2857 break;
2858 case 'd':
2859 case 'D':
2860 along = (strend - s) / sizeof(double);
2861 if (len > along)
2862 len = along;
2863 if (checksum) {
2864 while (len-- > 0) {
2865 Copy(s, &adouble, 1, double);
2866 s += sizeof(double);
2867 cdouble += adouble;
2868 }
2869 }
2870 else {
2871 EXTEND(SP, len);
2872 while (len-- > 0) {
2873 Copy(s, &adouble, 1, double);
2874 s += sizeof(double);
2875 sv = NEWSV(48, 0);
2876 sv_setnv(sv, (double)adouble);
2877 PUSHs(sv_2mortal(sv));
2878 }
2879 }
2880 break;
2881 case 'u':
2882 along = (strend - s) * 3 / 4;
2883 sv = NEWSV(42, along);
f12c7020 2884 if (along)
2885 SvPOK_on(sv);
a0d0e21e 2886 while (s < strend && *s > ' ' && *s < 'a') {
2887 I32 a, b, c, d;
2888 char hunk[4];
79072805 2889
a0d0e21e 2890 hunk[3] = '\0';
2891 len = (*s++ - ' ') & 077;
2892 while (len > 0) {
2893 if (s < strend && *s >= ' ')
2894 a = (*s++ - ' ') & 077;
2895 else
2896 a = 0;
2897 if (s < strend && *s >= ' ')
2898 b = (*s++ - ' ') & 077;
2899 else
2900 b = 0;
2901 if (s < strend && *s >= ' ')
2902 c = (*s++ - ' ') & 077;
2903 else
2904 c = 0;
2905 if (s < strend && *s >= ' ')
2906 d = (*s++ - ' ') & 077;
2907 else
2908 d = 0;
2909 hunk[0] = a << 2 | b >> 4;
2910 hunk[1] = b << 4 | c >> 2;
2911 hunk[2] = c << 6 | d;
2912 sv_catpvn(sv, hunk, len > 3 ? 3 : len);
2913 len -= 3;
2914 }
2915 if (*s == '\n')
2916 s++;
2917 else if (s[1] == '\n') /* possible checksum byte */
2918 s += 2;
79072805 2919 }
a0d0e21e 2920 XPUSHs(sv_2mortal(sv));
2921 break;
79072805 2922 }
a0d0e21e 2923 if (checksum) {
2924 sv = NEWSV(42, 0);
2925 if (strchr("fFdD", datumtype) ||
2926 (checksum > 32 && strchr("iIlLN", datumtype)) ) {
2927 double trouble;
79072805 2928
a0d0e21e 2929 adouble = 1.0;
2930 while (checksum >= 16) {
2931 checksum -= 16;
2932 adouble *= 65536.0;
2933 }
2934 while (checksum >= 4) {
2935 checksum -= 4;
2936 adouble *= 16.0;
2937 }
2938 while (checksum--)
2939 adouble *= 2.0;
2940 along = (1 << checksum) - 1;
2941 while (cdouble < 0.0)
2942 cdouble += adouble;
2943 cdouble = modf(cdouble / adouble, &trouble) * adouble;
2944 sv_setnv(sv, cdouble);
2945 }
2946 else {
2947 if (checksum < 32) {
2948 along = (1 << checksum) - 1;
2949 culong &= (U32)along;
2950 }
2951 sv_setnv(sv, (double)culong);
2952 }
2953 XPUSHs(sv_2mortal(sv));
2954 checksum = 0;
79072805 2955 }
79072805 2956 }
79072805 2957 RETURN;
79072805 2958}
2959
a0d0e21e 2960static void
2961doencodes(sv, s, len)
2962register SV *sv;
2963register char *s;
2964register I32 len;
79072805 2965{
a0d0e21e 2966 char hunk[5];
79072805 2967
a0d0e21e 2968 *hunk = len + ' ';
2969 sv_catpvn(sv, hunk, 1);
2970 hunk[4] = '\0';
2971 while (len > 0) {
2972 hunk[0] = ' ' + (077 & (*s >> 2));
2973 hunk[1] = ' ' + (077 & ((*s << 4) & 060 | (s[1] >> 4) & 017));
2974 hunk[2] = ' ' + (077 & ((s[1] << 2) & 074 | (s[2] >> 6) & 03));
2975 hunk[3] = ' ' + (077 & (s[2] & 077));
2976 sv_catpvn(sv, hunk, 4);
2977 s += 3;
2978 len -= 3;
2979 }
2980 for (s = SvPVX(sv); *s; s++) {
2981 if (*s == ' ')
2982 *s = '`';
2983 }
2984 sv_catpvn(sv, "\n", 1);
79072805 2985}
2986
a0d0e21e 2987PP(pp_pack)
79072805 2988{
a0d0e21e 2989 dSP; dMARK; dORIGMARK; dTARGET;
2990 register SV *cat = TARG;
2991 register I32 items;
2992 STRLEN fromlen;
2993 register char *pat = SvPVx(*++MARK, fromlen);
2994 register char *patend = pat + fromlen;
2995 register I32 len;
2996 I32 datumtype;
2997 SV *fromstr;
2998 /*SUPPRESS 442*/
2999 static char null10[] = {0,0,0,0,0,0,0,0,0,0};
3000 static char *space10 = " ";
79072805 3001
a0d0e21e 3002 /* These must not be in registers: */
3003 char achar;
3004 I16 ashort;
3005 int aint;
3006 unsigned int auint;
3007 I32 along;
3008 U32 aulong;
ecfc5424 3009#ifdef HAS_QUAD
3010 Quad_t aquad;
3011 unsigned Quad_t auquad;
79072805 3012#endif
a0d0e21e 3013 char *aptr;
3014 float afloat;
3015 double adouble;
79072805 3016
a0d0e21e 3017 items = SP - MARK;
3018 MARK++;
3019 sv_setpvn(cat, "", 0);
3020 while (pat < patend) {
3021#define NEXTFROM (items-- > 0 ? *MARK++ : &sv_no)
3022 datumtype = *pat++;
3023 if (*pat == '*') {
3024 len = strchr("@Xxu", datumtype) ? 0 : items;
3025 pat++;
3026 }
3027 else if (isDIGIT(*pat)) {
3028 len = *pat++ - '0';
3029 while (isDIGIT(*pat))
3030 len = (len * 10) + (*pat++ - '0');
3031 }
3032 else
3033 len = 1;
3034 switch(datumtype) {
3035 default:
3036 break;
3037 case '%':
3038 DIE("%% may only be used in unpack");
3039 case '@':
3040 len -= SvCUR(cat);
3041 if (len > 0)
3042 goto grow;
3043 len = -len;
3044 if (len > 0)
3045 goto shrink;
3046 break;
3047 case 'X':
3048 shrink:
3049 if (SvCUR(cat) < len)
3050 DIE("X outside of string");
3051 SvCUR(cat) -= len;
3052 *SvEND(cat) = '\0';
3053 break;
3054 case 'x':
3055 grow:
3056 while (len >= 10) {
3057 sv_catpvn(cat, null10, 10);
3058 len -= 10;
3059 }
3060 sv_catpvn(cat, null10, len);
3061 break;
3062 case 'A':
3063 case 'a':
3064 fromstr = NEXTFROM;
3065 aptr = SvPV(fromstr, fromlen);
3066 if (pat[-1] == '*')
3067 len = fromlen;
3068 if (fromlen > len)
3069 sv_catpvn(cat, aptr, len);
3070 else {
3071 sv_catpvn(cat, aptr, fromlen);
3072 len -= fromlen;
3073 if (datumtype == 'A') {
3074 while (len >= 10) {
3075 sv_catpvn(cat, space10, 10);
3076 len -= 10;
3077 }
3078 sv_catpvn(cat, space10, len);
3079 }
3080 else {
3081 while (len >= 10) {
3082 sv_catpvn(cat, null10, 10);
3083 len -= 10;
3084 }
3085 sv_catpvn(cat, null10, len);
3086 }
3087 }
3088 break;
3089 case 'B':
3090 case 'b':
3091 {
3092 char *savepat = pat;
3093 I32 saveitems;
79072805 3094
a0d0e21e 3095 fromstr = NEXTFROM;
3096 saveitems = items;
3097 aptr = SvPV(fromstr, fromlen);
3098 if (pat[-1] == '*')
3099 len = fromlen;
3100 pat = aptr;
3101 aint = SvCUR(cat);
3102 SvCUR(cat) += (len+7)/8;
3103 SvGROW(cat, SvCUR(cat) + 1);
3104 aptr = SvPVX(cat) + aint;
3105 if (len > fromlen)
3106 len = fromlen;
3107 aint = len;
3108 items = 0;
3109 if (datumtype == 'B') {
3110 for (len = 0; len++ < aint;) {
3111 items |= *pat++ & 1;
3112 if (len & 7)
3113 items <<= 1;
3114 else {
3115 *aptr++ = items & 0xff;
3116 items = 0;
3117 }
3118 }
3119 }
3120 else {
3121 for (len = 0; len++ < aint;) {
3122 if (*pat++ & 1)
3123 items |= 128;
3124 if (len & 7)
3125 items >>= 1;
3126 else {
3127 *aptr++ = items & 0xff;
3128 items = 0;
3129 }
3130 }
3131 }
3132 if (aint & 7) {
3133 if (datumtype == 'B')
3134 items <<= 7 - (aint & 7);
3135 else
3136 items >>= 7 - (aint & 7);
3137 *aptr++ = items & 0xff;
3138 }
3139 pat = SvPVX(cat) + SvCUR(cat);
3140 while (aptr <= pat)
3141 *aptr++ = '\0';
79072805 3142
a0d0e21e 3143 pat = savepat;
3144 items = saveitems;
3145 }
3146 break;
3147 case 'H':
3148 case 'h':
3149 {
3150 char *savepat = pat;
3151 I32 saveitems;
79072805 3152
a0d0e21e 3153 fromstr = NEXTFROM;
3154 saveitems = items;
3155 aptr = SvPV(fromstr, fromlen);
3156 if (pat[-1] == '*')
3157 len = fromlen;
3158 pat = aptr;
3159 aint = SvCUR(cat);
3160 SvCUR(cat) += (len+1)/2;
3161 SvGROW(cat, SvCUR(cat) + 1);
3162 aptr = SvPVX(cat) + aint;
3163 if (len > fromlen)
3164 len = fromlen;
3165 aint = len;
3166 items = 0;
3167 if (datumtype == 'H') {
3168 for (len = 0; len++ < aint;) {
3169 if (isALPHA(*pat))
3170 items |= ((*pat++ & 15) + 9) & 15;
3171 else
3172 items |= *pat++ & 15;
3173 if (len & 1)
3174 items <<= 4;
3175 else {
3176 *aptr++ = items & 0xff;
3177 items = 0;
3178 }
3179 }
3180 }
3181 else {
3182 for (len = 0; len++ < aint;) {
3183 if (isALPHA(*pat))
3184 items |= (((*pat++ & 15) + 9) & 15) << 4;
3185 else
3186 items |= (*pat++ & 15) << 4;
3187 if (len & 1)
3188 items >>= 4;
3189 else {
3190 *aptr++ = items & 0xff;
3191 items = 0;
3192 }
3193 }
3194 }
3195 if (aint & 1)
3196 *aptr++ = items & 0xff;
3197 pat = SvPVX(cat) + SvCUR(cat);
3198 while (aptr <= pat)
3199 *aptr++ = '\0';
79072805 3200
a0d0e21e 3201 pat = savepat;
3202 items = saveitems;
3203 }
3204 break;
3205 case 'C':
3206 case 'c':
3207 while (len-- > 0) {
3208 fromstr = NEXTFROM;
3209 aint = SvIV(fromstr);
3210 achar = aint;
3211 sv_catpvn(cat, &achar, sizeof(char));
3212 }
3213 break;
3214 /* Float and double added by gnb@melba.bby.oz.au 22/11/89 */
3215 case 'f':
3216 case 'F':
3217 while (len-- > 0) {
3218 fromstr = NEXTFROM;
3219 afloat = (float)SvNV(fromstr);
3220 sv_catpvn(cat, (char *)&afloat, sizeof (float));
3221 }
3222 break;
3223 case 'd':
3224 case 'D':
3225 while (len-- > 0) {
3226 fromstr = NEXTFROM;
3227 adouble = (double)SvNV(fromstr);
3228 sv_catpvn(cat, (char *)&adouble, sizeof (double));
3229 }
3230 break;
3231 case 'n':
3232 while (len-- > 0) {
3233 fromstr = NEXTFROM;
3234 ashort = (I16)SvIV(fromstr);
3235#ifdef HAS_HTONS
3236 ashort = htons(ashort);
79072805 3237#endif
a0d0e21e 3238 sv_catpvn(cat, (char*)&ashort, sizeof(I16));
3239 }
3240 break;
3241 case 'v':
3242 while (len-- > 0) {
3243 fromstr = NEXTFROM;
3244 ashort = (I16)SvIV(fromstr);
3245#ifdef HAS_HTOVS
3246 ashort = htovs(ashort);
79072805 3247#endif
a0d0e21e 3248 sv_catpvn(cat, (char*)&ashort, sizeof(I16));
3249 }
3250 break;
3251 case 'S':
3252 case 's':
3253 while (len-- > 0) {
3254 fromstr = NEXTFROM;
3255 ashort = (I16)SvIV(fromstr);
3256 sv_catpvn(cat, (char*)&ashort, sizeof(I16));
3257 }
3258 break;
3259 case 'I':
3260 while (len-- > 0) {
3261 fromstr = NEXTFROM;
3262 auint = U_I(SvNV(fromstr));
3263 sv_catpvn(cat, (char*)&auint, sizeof(unsigned int));
3264 }
3265 break;
3266 case 'i':
3267 while (len-- > 0) {
3268 fromstr = NEXTFROM;
3269 aint = SvIV(fromstr);
3270 sv_catpvn(cat, (char*)&aint, sizeof(int));
3271 }
3272 break;
3273 case 'N':
3274 while (len-- > 0) {
3275 fromstr = NEXTFROM;
3276 aulong = U_L(SvNV(fromstr));
3277#ifdef HAS_HTONL
3278 aulong = htonl(aulong);
79072805 3279#endif
a0d0e21e 3280 sv_catpvn(cat, (char*)&aulong, sizeof(U32));
3281 }
3282 break;
3283 case 'V':
3284 while (len-- > 0) {
3285 fromstr = NEXTFROM;
3286 aulong = U_L(SvNV(fromstr));
3287#ifdef HAS_HTOVL
3288 aulong = htovl(aulong);
79072805 3289#endif
a0d0e21e 3290 sv_catpvn(cat, (char*)&aulong, sizeof(U32));
3291 }
3292 break;
3293 case 'L':
3294 while (len-- > 0) {
3295 fromstr = NEXTFROM;
3296 aulong = U_L(SvNV(fromstr));
3297 sv_catpvn(cat, (char*)&aulong, sizeof(U32));
3298 }
3299 break;
3300 case 'l':
3301 while (len-- > 0) {
3302 fromstr = NEXTFROM;
3303 along = SvIV(fromstr);
3304 sv_catpvn(cat, (char*)&along, sizeof(I32));
3305 }
3306 break;
ecfc5424 3307#ifdef HAS_QUAD
a0d0e21e 3308 case 'Q':
3309 while (len-- > 0) {
3310 fromstr = NEXTFROM;
ecfc5424 3311 auquad = (unsigned Quad_t)SvIV(fromstr);
3312 sv_catpvn(cat, (char*)&auquad, sizeof(unsigned Quad_t));
a0d0e21e 3313 }
3314 break;
3315 case 'q':
3316 while (len-- > 0) {
3317 fromstr = NEXTFROM;
ecfc5424 3318 aquad = (Quad_t)SvIV(fromstr);
3319 sv_catpvn(cat, (char*)&aquad, sizeof(Quad_t));
a0d0e21e 3320 }
3321 break;
ecfc5424 3322#endif /* HAS_QUAD */
a0d0e21e 3323 case 'P':
3324 len = 1; /* assume SV is correct length */
3325 /* FALL THROUGH */
3326 case 'p':
3327 while (len-- > 0) {
3328 fromstr = NEXTFROM;
3329 aptr = SvPV_force(fromstr, na); /* XXX Error if TEMP? */
3330 sv_catpvn(cat, (char*)&aptr, sizeof(char*));
3331 }
3332 break;
3333 case 'u':
3334 fromstr = NEXTFROM;
3335 aptr = SvPV(fromstr, fromlen);
3336 SvGROW(cat, fromlen * 4 / 3);
3337 if (len <= 1)
3338 len = 45;
3339 else
3340 len = len / 3 * 3;
3341 while (fromlen > 0) {
3342 I32 todo;
79072805 3343
a0d0e21e 3344 if (fromlen > len)
3345 todo = len;
3346 else
3347 todo = fromlen;
3348 doencodes(cat, aptr, todo);
3349 fromlen -= todo;
3350 aptr += todo;
3351 }
3352 break;
3353 }
3354 }
3355 SvSETMAGIC(cat);
3356 SP = ORIGMARK;
3357 PUSHs(cat);
3358 RETURN;
79072805 3359}
a0d0e21e 3360#undef NEXTFROM
79072805 3361
a0d0e21e 3362PP(pp_split)
79072805 3363{
a0d0e21e 3364 dSP; dTARG;
3365 AV *ary;
3366 register I32 limit = POPi; /* note, negative is forever */
3367 SV *sv = POPs;
3368 STRLEN len;
3369 register char *s = SvPV(sv, len);
3370 char *strend = s + len;
3371 register PMOP *pm = (PMOP*)POPs;
3372 register SV *dstr;
3373 register char *m;
3374 I32 iters = 0;
3375 I32 maxiters = (strend - s) + 10;
3376 I32 i;
3377 char *orig;
3378 I32 origlimit = limit;
3379 I32 realarray = 0;
3380 I32 base;
f12c7020 3381 AV *oldstack = curstack;
a0d0e21e 3382 register REGEXP *rx = pm->op_pmregexp;
3383 I32 gimme = GIMME;
c07a80fd 3384 I32 oldsave = savestack_ix;
79072805 3385
a0d0e21e 3386 if (!pm || !s)
3387 DIE("panic: do_split");
3388 if (pm->op_pmreplroot)
3389 ary = GvAVn((GV*)pm->op_pmreplroot);
3390 else if (gimme != G_ARRAY)
3391 ary = GvAVn(defgv);
79072805 3392 else
a0d0e21e 3393 ary = Nullav;
3394 if (ary && (gimme != G_ARRAY || (pm->op_pmflags & PMf_ONCE))) {
3395 realarray = 1;
3396 if (!AvREAL(ary)) {
3397 AvREAL_on(ary);
3398 for (i = AvFILL(ary); i >= 0; i--)
3399 AvARRAY(ary)[i] = &sv_undef; /* don't free mere refs */
79072805 3400 }
a0d0e21e 3401 av_extend(ary,0);
3402 av_clear(ary);
3403 /* temporarily switch stacks */
f12c7020 3404 SWITCHSTACK(curstack, ary);
79072805 3405 }
a0d0e21e 3406 base = SP - stack_base;
3407 orig = s;
3408 if (pm->op_pmflags & PMf_SKIPWHITE) {
3409 while (isSPACE(*s))
3410 s++;
3411 }
c07a80fd 3412 if (pm->op_pmflags & (PMf_MULTILINE|PMf_SINGLELINE)) {
3413 SAVEINT(multiline);
3414 multiline = pm->op_pmflags & PMf_MULTILINE;
3415 }
3416
a0d0e21e 3417 if (!limit)
3418 limit = maxiters + 2;
3419 if (pm->op_pmflags & PMf_WHITE) {
3420 while (--limit) {
3421 /*SUPPRESS 530*/
3422 for (m = s; m < strend && !isSPACE(*m); m++) ;
3423 if (m >= strend)
3424 break;
3425 dstr = NEWSV(30, m-s);
3426 sv_setpvn(dstr, s, m-s);
3427 if (!realarray)
3428 sv_2mortal(dstr);
3429 XPUSHs(dstr);
3430 /*SUPPRESS 530*/
3431 for (s = m + 1; s < strend && isSPACE(*s); s++) ;
79072805 3432 }
3433 }
a0d0e21e 3434 else if (strEQ("^", rx->precomp)) {
3435 while (--limit) {
3436 /*SUPPRESS 530*/
3437 for (m = s; m < strend && *m != '\n'; m++) ;
3438 m++;
3439 if (m >= strend)
3440 break;
3441 dstr = NEWSV(30, m-s);
3442 sv_setpvn(dstr, s, m-s);
3443 if (!realarray)
3444 sv_2mortal(dstr);
3445 XPUSHs(dstr);
3446 s = m;
3447 }
3448 }
3449 else if (pm->op_pmshort) {
3450 i = SvCUR(pm->op_pmshort);
3451 if (i == 1) {
3452 I32 fold = (pm->op_pmflags & PMf_FOLD);
3453 i = *SvPVX(pm->op_pmshort);
3454 if (fold && isUPPER(i))
3455 i = toLOWER(i);
3456 while (--limit) {
3457 if (fold) {
3458 for ( m = s;
3459 m < strend && *m != i &&
3460 (!isUPPER(*m) || toLOWER(*m) != i);
3461 m++) /*SUPPRESS 530*/
3462 ;
3463 }
3464 else /*SUPPRESS 530*/
3465 for (m = s; m < strend && *m != i; m++) ;
3466 if (m >= strend)
3467 break;
3468 dstr = NEWSV(30, m-s);
3469 sv_setpvn(dstr, s, m-s);
3470 if (!realarray)
3471 sv_2mortal(dstr);
3472 XPUSHs(dstr);
3473 s = m + 1;
3474 }
3475 }
3476 else {
3477#ifndef lint
3478 while (s < strend && --limit &&
3479 (m=fbm_instr((unsigned char*)s, (unsigned char*)strend,
3480 pm->op_pmshort)) )
79072805 3481#endif
a0d0e21e 3482 {
3483 dstr = NEWSV(31, m-s);
3484 sv_setpvn(dstr, s, m-s);
3485 if (!realarray)
3486 sv_2mortal(dstr);
3487 XPUSHs(dstr);
3488 s = m + i;
3489 }
463ee0b2 3490 }
463ee0b2 3491 }
a0d0e21e 3492 else {
3493 maxiters += (strend - s) * rx->nparens;
3494 while (s < strend && --limit &&
e50aee73 3495 pregexec(rx, s, strend, orig, 1, Nullsv, TRUE) ) {
a0d0e21e 3496 if (rx->subbase
3497 && rx->subbase != orig) {
3498 m = s;
3499 s = orig;
3500 orig = rx->subbase;
3501 s = orig + (m - s);
3502 strend = s + (strend - m);
3503 }
3504 m = rx->startp[0];
3505 dstr = NEWSV(32, m-s);
3506 sv_setpvn(dstr, s, m-s);
3507 if (!realarray)
3508 sv_2mortal(dstr);
3509 XPUSHs(dstr);
3510 if (rx->nparens) {
3511 for (i = 1; i <= rx->nparens; i++) {
3512 s = rx->startp[i];
3513 m = rx->endp[i];
748a9306 3514 if (m && s) {
3515 dstr = NEWSV(33, m-s);
3516 sv_setpvn(dstr, s, m-s);
3517 }
3518 else
3519 dstr = NEWSV(33, 0);
a0d0e21e 3520 if (!realarray)
3521 sv_2mortal(dstr);
3522 XPUSHs(dstr);
3523 }
3524 }
3525 s = rx->endp[0];
3526 }
79072805 3527 }
c07a80fd 3528 LEAVE_SCOPE(oldsave);
a0d0e21e 3529 iters = (SP - stack_base) - base;
3530 if (iters > maxiters)
3531 DIE("Split loop");
3532
3533 /* keep field after final delim? */
3534 if (s < strend || (iters && origlimit)) {
3535 dstr = NEWSV(34, strend-s);
3536 sv_setpvn(dstr, s, strend-s);
3537 if (!realarray)
3538 sv_2mortal(dstr);
3539 XPUSHs(dstr);
3540 iters++;
79072805 3541 }
a0d0e21e 3542 else if (!origlimit) {
b1dadf13 3543 while (iters > 0 && (!TOPs || !SvANY(TOPs) || SvCUR(TOPs) == 0))
a0d0e21e 3544 iters--, SP--;
3545 }
3546 if (realarray) {
3547 SWITCHSTACK(ary, oldstack);
3548 if (gimme == G_ARRAY) {
3549 EXTEND(SP, iters);
3550 Copy(AvARRAY(ary), SP + 1, iters, SV*);
3551 SP += iters;
3552 RETURN;
3553 }
3554 }
3555 else {
3556 if (gimme == G_ARRAY)
3557 RETURN;
3558 }
3559 if (iters || !pm->op_pmreplroot) {
3560 GETTARGET;
3561 PUSHi(iters);
3562 RETURN;
3563 }
3564 RETPUSHUNDEF;
79072805 3565}
85e6fe83 3566