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