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