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