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