This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
4e9a8a3d172bdb6cbeda87742bdfbc9b5caefe6b
[perl5.git] / doop.c
1 /*    doop.c
2  *
3  *    Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
4  *    2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009 by Larry Wall and others
5  *
6  *    You may distribute under the terms of either the GNU General Public
7  *    License or the Artistic License, as specified in the README file.
8  *
9  */
10
11 /*
12  *  'So that was the job I felt I had to do when I started,' thought Sam.
13  *
14  *     [p.934 of _The Lord of the Rings_, VI/iii: "Mount Doom"]
15  */
16
17 /* This file contains some common functions needed to carry out certain
18  * ops. For example, both pp_sprintf() and pp_prtf() call the function
19  * do_sprintf() found in this file.
20  */
21
22 #include "EXTERN.h"
23 #define PERL_IN_DOOP_C
24 #include "perl.h"
25
26 #ifndef PERL_MICRO
27 #include <signal.h>
28 #endif
29
30
31 /* Helper function for do_trans().
32  * Handles non-utf8 cases(*) not involving the /c, /d, /s flags,
33  * and where search and replacement charlists aren't identical.
34  * (*) i.e. where the search and replacement charlists are non-utf8. sv may
35  * or may not be utf8.
36  */
37
38 STATIC Size_t
39 S_do_trans_simple(pTHX_ SV * const sv, const OPtrans_map * const tbl)
40 {
41     Size_t matches = 0;
42     STRLEN len;
43     U8 *s = (U8*)SvPV_nomg(sv,len);
44     U8 * const send = s+len;
45
46     PERL_ARGS_ASSERT_DO_TRANS_SIMPLE;
47
48     /* First, take care of non-UTF-8 input strings, because they're easy */
49     if (!SvUTF8(sv)) {
50         while (s < send) {
51             const short ch = tbl->map[*s];
52             if (ch >= 0) {
53                 matches++;
54                 *s = (U8)ch;
55             }
56             s++;
57         }
58         SvSETMAGIC(sv);
59     }
60     else {
61         const bool grows = cBOOL(PL_op->op_private & OPpTRANS_GROWS);
62         U8 *d;
63         U8 *dstart;
64
65         /* Allow for expansion: $_="a".chr(400); tr/a/\xFE/, FE needs encoding */
66         if (grows)
67             Newx(d, len*2+1, U8);
68         else
69             d = s;
70         dstart = d;
71         while (s < send) {
72             STRLEN ulen;
73             short ch;
74
75             /* Need to check this, otherwise 128..255 won't match */
76             const UV c = utf8n_to_uvchr(s, send - s, &ulen, UTF8_ALLOW_DEFAULT);
77             if (c < 0x100 && (ch = tbl->map[c]) >= 0) {
78                 matches++;
79                 d = uvchr_to_utf8(d, (UV)ch);
80                 s += ulen;
81             }
82             else { /* No match -> copy */
83                 Move(s, d, ulen, U8);
84                 d += ulen;
85                 s += ulen;
86             }
87         }
88         if (grows) {
89             sv_setpvn(sv, (char*)dstart, d - dstart);
90             Safefree(dstart);
91         }
92         else {
93             *d = '\0';
94             SvCUR_set(sv, d - dstart);
95         }
96         SvUTF8_on(sv);
97         SvSETMAGIC(sv);
98     }
99     return matches;
100 }
101
102
103 /* Helper function for do_trans().
104  * Handles non-utf8 cases(*) where search and replacement charlists are
105  * identical: so the string isn't modified, and only a count of modifiable
106  * chars is needed.
107  * Note that it doesn't handle /d or /s, since these modify the string
108  * even if the replacement list is empty.
109  * (*) i.e. where the search and replacement charlists are non-utf8. sv may
110  * or may not be utf8.
111  */
112
113 STATIC Size_t
114 S_do_trans_count(pTHX_ SV * const sv, const OPtrans_map * const tbl)
115 {
116     STRLEN len;
117     const U8 *s = (const U8*)SvPV_nomg_const(sv, len);
118     const U8 * const send = s + len;
119     Size_t matches = 0;
120
121     PERL_ARGS_ASSERT_DO_TRANS_COUNT;
122
123     if (!SvUTF8(sv)) {
124         while (s < send) {
125             if (tbl->map[*s++] >= 0)
126                 matches++;
127         }
128     }
129     else {
130         const bool complement = cBOOL(PL_op->op_private & OPpTRANS_COMPLEMENT);
131         while (s < send) {
132             STRLEN ulen;
133             const UV c = utf8n_to_uvchr(s, send - s, &ulen, UTF8_ALLOW_DEFAULT);
134             if (c < 0x100) {
135                 if (tbl->map[c] >= 0)
136                     matches++;
137             } else if (complement)
138                 matches++;
139             s += ulen;
140         }
141     }
142
143     return matches;
144 }
145
146
147 /* Helper function for do_trans().
148  * Handles non-utf8 cases(*) involving the /c, /d, /s flags,
149  * and where search and replacement charlists aren't identical.
150  * (*) i.e. where the search and replacement charlists are non-utf8. sv may
151  * or may not be utf8.
152  */
153
154 STATIC Size_t
155 S_do_trans_complex(pTHX_ SV * const sv, const OPtrans_map * const tbl)
156 {
157     STRLEN len;
158     U8 *s = (U8*)SvPV_nomg(sv, len);
159     U8 * const send = s+len;
160     Size_t matches = 0;
161
162     PERL_ARGS_ASSERT_DO_TRANS_COMPLEX;
163
164     if (!SvUTF8(sv)) {
165         U8 *d = s;
166         U8 * const dstart = d;
167
168         if (PL_op->op_private & OPpTRANS_SQUASH) {
169             const U8* p = send;
170             while (s < send) {
171                 const short ch = tbl->map[*s];
172                 if (ch >= 0) {
173                     *d = (U8)ch;
174                     matches++;
175                     if (p != d - 1 || *p != *d)
176                         p = d++;
177                 }
178                 else if (ch == (short) TR_UNMAPPED)
179                     *d++ = *s;
180                 else if (ch == (short) TR_DELETE)
181                     matches++;
182                 s++;
183             }
184         }
185         else {
186             while (s < send) {
187                 const short ch = tbl->map[*s];
188                 if (ch >= 0) {
189                     matches++;
190                     *d++ = (U8)ch;
191                 }
192                 else if (ch == (short) TR_UNMAPPED)
193                     *d++ = *s;
194                 else if (ch == (short) TR_DELETE)
195                     matches++;
196                 s++;
197             }
198         }
199         *d = '\0';
200         SvCUR_set(sv, d - dstart);
201     }
202     else { /* is utf8 */
203         const bool squash = cBOOL(PL_op->op_private & OPpTRANS_SQUASH);
204         const bool grows  = cBOOL(PL_op->op_private & OPpTRANS_GROWS);
205         U8 *d;
206         U8 *dstart;
207         Size_t size = tbl->size;
208         UV pch = 0xfeedface;
209
210         if (grows)
211             Newx(d, len*2+1, U8);
212         else
213             d = s;
214         dstart = d;
215
216         while (s < send) {
217             STRLEN len;
218             const UV comp = utf8n_to_uvchr(s, send - s, &len,
219                                            UTF8_ALLOW_DEFAULT);
220             UV     ch;
221             short sch;
222
223             sch = tbl->map[comp >= size ? size : comp];
224
225             if (sch >= 0) {
226                 ch = (UV)sch;
227               replace:
228                 matches++;
229                 if (LIKELY(!squash || ch != pch)) {
230                     d = uvchr_to_utf8(d, ch);
231                     pch = ch;
232                 }
233                 s += len;
234                 continue;
235             }
236             else if (sch == (short) TR_UNMAPPED) {
237                 Move(s, d, len, U8);
238                 d += len;
239             }
240             else if (sch == (short) TR_DELETE)
241                 matches++;
242             else {
243                 assert(sch == (short) TR_R_EMPTY);  /* empty replacement */
244                 ch = comp;
245                 goto replace;
246             }
247
248             s += len;
249             pch = 0xfeedface;
250         }
251
252         if (grows) {
253             sv_setpvn(sv, (char*)dstart, d - dstart);
254             Safefree(dstart);
255         }
256         else {
257             *d = '\0';
258             SvCUR_set(sv, d - dstart);
259         }
260         SvUTF8_on(sv);
261     }
262     SvSETMAGIC(sv);
263     return matches;
264 }
265
266
267 /* Helper function for do_trans().
268  * Handles utf8 cases(*) not involving the /c, /d, /s flags,
269  * and where search and replacement charlists aren't identical.
270  * (*) i.e. where the search or replacement charlists are utf8. sv may
271  * or may not be utf8.
272  */
273
274 STATIC Size_t
275 S_do_trans_simple_utf8(pTHX_ SV * const sv)
276 {
277     U8 *s;
278     U8 *send;
279     U8 *d;
280     U8 *start;
281     U8 *dstart, *dend;
282     Size_t matches = 0;
283     const bool grows = cBOOL(PL_op->op_private & OPpTRANS_GROWS);
284     STRLEN len;
285     SV* const  rv =
286 #ifdef USE_ITHREADS
287                     PAD_SVl(cPADOP->op_padix);
288 #else
289                     MUTABLE_SV(cSVOP->op_sv);
290 #endif
291     HV* const  hv = MUTABLE_HV(SvRV(rv));
292     SV* const * svp = hv_fetchs(hv, "NONE", FALSE);
293     const UV none = svp ? SvUV(*svp) : 0x7fffffff;
294     const UV extra = none + 1;
295     UV final = 0;
296     U8 hibit = 0;
297
298     PERL_ARGS_ASSERT_DO_TRANS_SIMPLE_UTF8;
299
300     s = (U8*)SvPV_nomg(sv, len);
301     if (!SvUTF8(sv)) {
302         hibit = ! is_utf8_invariant_string(s, len);
303         if (hibit) {
304             s = bytes_to_utf8(s, &len);
305         }
306     }
307     send = s + len;
308     start = s;
309
310     svp = hv_fetchs(hv, "FINAL", FALSE);
311     if (svp)
312         final = SvUV(*svp);
313
314     if (grows) {
315         /* d needs to be bigger than s, in case e.g. upgrading is required */
316         Newx(d, len * 3 + UTF8_MAXBYTES, U8);
317         dend = d + len * 3;
318         dstart = d;
319     }
320     else {
321         dstart = d = s;
322         dend = d + len;
323     }
324
325     while (s < send) {
326         const UV uv = swash_fetch(rv, s, TRUE);
327         if (uv < none) {
328             s += UTF8SKIP(s);
329             matches++;
330             d = uvchr_to_utf8(d, uv);
331         }
332         else if (uv == none) {
333             const int i = UTF8SKIP(s);
334             Move(s, d, i, U8);
335             d += i;
336             s += i;
337         }
338         else if (uv == extra) {
339             s += UTF8SKIP(s);
340             matches++;
341             d = uvchr_to_utf8(d, final);
342         }
343         else
344             s += UTF8SKIP(s);
345
346         if (d > dend) {
347             const STRLEN clen = d - dstart;
348             const STRLEN nlen = dend - dstart + len + UTF8_MAXBYTES;
349             if (!grows)
350                 Perl_croak(aTHX_ "panic: do_trans_simple_utf8 line %d",__LINE__);
351             Renew(dstart, nlen + UTF8_MAXBYTES, U8);
352             d = dstart + clen;
353             dend = dstart + nlen;
354         }
355     }
356     if (grows || hibit) {
357         sv_setpvn(sv, (char*)dstart, d - dstart);
358         Safefree(dstart);
359         if (grows && hibit)
360             Safefree(start);
361     }
362     else {
363         *d = '\0';
364         SvCUR_set(sv, d - dstart);
365     }
366     SvSETMAGIC(sv);
367     SvUTF8_on(sv);
368
369     return matches;
370 }
371
372
373 /* Helper function for do_trans().
374  * Handles utf8 cases(*) where search and replacement charlists are
375  * identical: so the string isn't modified, and only a count of modifiable
376  * chars is needed.
377  * Note that it doesn't handle /d or /s, since these modify the string
378  * even if the replacement charlist is empty.
379  * (*) i.e. where the search or replacement charlists are utf8. sv may
380  * or may not be utf8.
381  */
382
383 STATIC Size_t
384 S_do_trans_count_utf8(pTHX_ SV * const sv)
385 {
386     const U8 *s;
387     const U8 *start = NULL;
388     const U8 *send;
389     Size_t matches = 0;
390     STRLEN len;
391     SV* const  rv =
392 #ifdef USE_ITHREADS
393                     PAD_SVl(cPADOP->op_padix);
394 #else
395                     MUTABLE_SV(cSVOP->op_sv);
396 #endif
397     HV* const hv = MUTABLE_HV(SvRV(rv));
398     SV* const * const svp = hv_fetchs(hv, "NONE", FALSE);
399     const UV none = svp ? SvUV(*svp) : 0x7fffffff;
400     const UV extra = none + 1;
401     U8 hibit = 0;
402
403     PERL_ARGS_ASSERT_DO_TRANS_COUNT_UTF8;
404
405     s = (const U8*)SvPV_nomg_const(sv, len);
406     if (!SvUTF8(sv)) {
407         hibit = ! is_utf8_invariant_string(s, len);
408         if (hibit) {
409             start = s = bytes_to_utf8(s, &len);
410         }
411     }
412     send = s + len;
413
414     while (s < send) {
415         const UV uv = swash_fetch(rv, s, TRUE);
416         if (uv < none || uv == extra)
417             matches++;
418         s += UTF8SKIP(s);
419     }
420     if (hibit)
421         Safefree(start);
422
423     return matches;
424 }
425
426
427 /* Helper function for do_trans().
428  * Handles utf8 cases(*) involving the /c, /d, /s flags,
429  * and where search and replacement charlists aren't identical.
430  * (*) i.e. where the search or replacement charlists are utf8. sv may
431  * or may not be utf8.
432  */
433
434 STATIC Size_t
435 S_do_trans_complex_utf8(pTHX_ SV * const sv)
436 {
437     U8 *start, *send;
438     U8 *d;
439     Size_t matches = 0;
440     const bool squash   = cBOOL(PL_op->op_private & OPpTRANS_SQUASH);
441     const bool del      = cBOOL(PL_op->op_private & OPpTRANS_DELETE);
442     const bool grows    = cBOOL(PL_op->op_private & OPpTRANS_GROWS);
443     SV* const  rv =
444 #ifdef USE_ITHREADS
445                     PAD_SVl(cPADOP->op_padix);
446 #else
447                     MUTABLE_SV(cSVOP->op_sv);
448 #endif
449     HV * const hv = MUTABLE_HV(SvRV(rv));
450     SV * const *svp = hv_fetchs(hv, "NONE", FALSE);
451     const UV none = svp ? SvUV(*svp) : 0x7fffffff;
452     const UV extra = none + 1;
453     UV final = 0;
454     bool havefinal = FALSE;
455     STRLEN len;
456     U8 *dstart, *dend;
457     U8 hibit = 0;
458     U8 *s = (U8*)SvPV_nomg(sv, len);
459
460     PERL_ARGS_ASSERT_DO_TRANS_COMPLEX_UTF8;
461
462     if (!SvUTF8(sv)) {
463         hibit = ! is_utf8_invariant_string(s, len);
464         if (hibit) {
465             s = bytes_to_utf8(s, &len);
466         }
467     }
468     send = s + len;
469     start = s;
470
471     svp = hv_fetchs(hv, "FINAL", FALSE);
472     if (svp) {
473         final = SvUV(*svp);
474         havefinal = TRUE;
475     }
476
477     if (grows) {
478         /* d needs to be bigger than s, in case e.g. upgrading is required */
479         Newx(d, len * 3 + UTF8_MAXBYTES, U8);
480         dend = d + len * 3;
481         dstart = d;
482     }
483     else {
484         dstart = d = s;
485         dend = d + len;
486     }
487
488     if (squash) {
489         UV puv = 0xfeedface;
490         while (s < send) {
491             UV uv = swash_fetch(rv, s, TRUE);
492
493             if (d > dend) {
494                 const STRLEN clen = d - dstart;
495                 const STRLEN nlen = dend - dstart + len + UTF8_MAXBYTES;
496                 if (!grows)
497                     Perl_croak(aTHX_ "panic: do_trans_complex_utf8 line %d",__LINE__);
498                 Renew(dstart, nlen + UTF8_MAXBYTES, U8);
499                 d = dstart + clen;
500                 dend = dstart + nlen;
501             }
502             if (uv < none) {
503                 matches++;
504                 s += UTF8SKIP(s);
505                 if (uv != puv) {
506                     d = uvchr_to_utf8(d, uv);
507                     puv = uv;
508                 }
509                 continue;
510             }
511             else if (uv == none) {      /* "none" is unmapped character */
512                 const int i = UTF8SKIP(s);
513                 Move(s, d, i, U8);
514                 d += i;
515                 s += i;
516                 puv = 0xfeedface;
517                 continue;
518             }
519             else if (uv == extra && !del) {
520                 matches++;
521                 if (havefinal) {
522                     s += UTF8SKIP(s);
523                     if (puv != final) {
524                         d = uvchr_to_utf8(d, final);
525                         puv = final;
526                     }
527                 }
528                 else {
529                     STRLEN len;
530                     uv = utf8n_to_uvchr(s, send - s, &len, UTF8_ALLOW_DEFAULT);
531                     if (uv != puv) {
532                         Move(s, d, len, U8);
533                         d += len;
534                         puv = uv;
535                     }
536                     s += len;
537                 }
538                 continue;
539             }
540             matches++;                  /* "none+1" is delete character */
541             s += UTF8SKIP(s);
542         }
543     }
544     else {
545         while (s < send) {
546             const UV uv = swash_fetch(rv, s, TRUE);
547             if (d > dend) {
548                 const STRLEN clen = d - dstart;
549                 const STRLEN nlen = dend - dstart + len + UTF8_MAXBYTES;
550                 if (!grows)
551                     Perl_croak(aTHX_ "panic: do_trans_complex_utf8 line %d",__LINE__);
552                 Renew(dstart, nlen + UTF8_MAXBYTES, U8);
553                 d = dstart + clen;
554                 dend = dstart + nlen;
555             }
556             if (uv < none) {
557                 matches++;
558                 s += UTF8SKIP(s);
559                 d = uvchr_to_utf8(d, uv);
560                 continue;
561             }
562             else if (uv == none) {      /* "none" is unmapped character */
563                 const int i = UTF8SKIP(s);
564                 Move(s, d, i, U8);
565                 d += i;
566                 s += i;
567                 continue;
568             }
569             else if (uv == extra && !del) {
570                 matches++;
571                 s += UTF8SKIP(s);
572                 d = uvchr_to_utf8(d, final);
573                 continue;
574             }
575             matches++;                  /* "none+1" is delete character */
576             s += UTF8SKIP(s);
577         }
578     }
579     if (grows || hibit) {
580         sv_setpvn(sv, (char*)dstart, d - dstart);
581         Safefree(dstart);
582         if (grows && hibit)
583             Safefree(start);
584     }
585     else {
586         *d = '\0';
587         SvCUR_set(sv, d - dstart);
588     }
589     SvUTF8_on(sv);
590     SvSETMAGIC(sv);
591
592     return matches;
593 }
594
595
596 /* Execute a tr//. sv is the value to be translated, while PL_op
597  * should be an OP_TRANS or OP_TRANSR op, whose op_pv field contains a
598  * translation table or whose op_sv field contains a swash.
599  * Returns a count of number of characters translated
600  */
601
602 Size_t
603 Perl_do_trans(pTHX_ SV *sv)
604 {
605     STRLEN len;
606     const U8 flags = PL_op->op_private;
607     const U8 hasutf = flags & (OPpTRANS_FROM_UTF | OPpTRANS_TO_UTF);
608
609     PERL_ARGS_ASSERT_DO_TRANS;
610
611     if (SvREADONLY(sv) && !(flags & OPpTRANS_IDENTICAL)) {
612         Perl_croak_no_modify();
613     }
614     (void)SvPV_const(sv, len);
615     if (!len)
616         return 0;
617     if (!(flags & OPpTRANS_IDENTICAL)) {
618         if (!SvPOKp(sv) || SvTHINKFIRST(sv))
619             (void)SvPV_force_nomg(sv, len);
620         (void)SvPOK_only_UTF8(sv);
621     }
622
623     /* If we use only OPpTRANS_IDENTICAL to bypass the READONLY check,
624      * we must also rely on it to choose the readonly strategy.
625      */
626     if (flags & OPpTRANS_IDENTICAL) {
627         return hasutf ? do_trans_count_utf8(sv) : do_trans_count(sv, (OPtrans_map*)cPVOP->op_pv);
628     } else if (flags & (OPpTRANS_SQUASH|OPpTRANS_DELETE|OPpTRANS_COMPLEMENT)) {
629         return hasutf ? do_trans_complex_utf8(sv) : do_trans_complex(sv, (OPtrans_map*)cPVOP->op_pv);
630     } else {
631         return hasutf ? do_trans_simple_utf8(sv) : do_trans_simple(sv, (OPtrans_map*)cPVOP->op_pv);
632     }
633 }
634
635 void
636 Perl_do_join(pTHX_ SV *sv, SV *delim, SV **mark, SV **sp)
637 {
638     SV ** const oldmark = mark;
639     I32 items = sp - mark;
640     STRLEN len;
641     STRLEN delimlen;
642     const char * const delims = SvPV_const(delim, delimlen);
643
644     PERL_ARGS_ASSERT_DO_JOIN;
645
646     mark++;
647     len = (items > 0 ? (delimlen * (items - 1) ) : 0);
648     SvUPGRADE(sv, SVt_PV);
649     if (SvLEN(sv) < len + items) {      /* current length is way too short */
650         while (items-- > 0) {
651             if (*mark && !SvGAMAGIC(*mark) && SvOK(*mark)) {
652                 STRLEN tmplen;
653                 SvPV_const(*mark, tmplen);
654                 len += tmplen;
655             }
656             mark++;
657         }
658         SvGROW(sv, len + 1);            /* so try to pre-extend */
659
660         mark = oldmark;
661         items = sp - mark;
662         ++mark;
663     }
664
665     SvPVCLEAR(sv);
666     /* sv_setpv retains old UTF8ness [perl #24846] */
667     SvUTF8_off(sv);
668
669     if (TAINTING_get && SvMAGICAL(sv))
670         SvTAINTED_off(sv);
671
672     if (items-- > 0) {
673         if (*mark)
674             sv_catsv(sv, *mark);
675         mark++;
676     }
677
678     if (delimlen) {
679         const U32 delimflag = DO_UTF8(delim) ? SV_CATUTF8 : SV_CATBYTES;
680         for (; items > 0; items--,mark++) {
681             STRLEN len;
682             const char *s;
683             sv_catpvn_flags(sv,delims,delimlen,delimflag);
684             s = SvPV_const(*mark,len);
685             sv_catpvn_flags(sv,s,len,
686                             DO_UTF8(*mark) ? SV_CATUTF8 : SV_CATBYTES);
687         }
688     }
689     else {
690         for (; items > 0; items--,mark++)
691         {
692             STRLEN len;
693             const char *s = SvPV_const(*mark,len);
694             sv_catpvn_flags(sv,s,len,
695                             DO_UTF8(*mark) ? SV_CATUTF8 : SV_CATBYTES);
696         }
697     }
698     SvSETMAGIC(sv);
699 }
700
701 void
702 Perl_do_sprintf(pTHX_ SV *sv, SSize_t len, SV **sarg)
703 {
704     STRLEN patlen;
705     const char * const pat = SvPV_const(*sarg, patlen);
706     bool do_taint = FALSE;
707
708     PERL_ARGS_ASSERT_DO_SPRINTF;
709     assert(len >= 1);
710
711     if (SvTAINTED(*sarg))
712         TAINT_PROPER(
713                 (PL_op && PL_op->op_type < OP_max)
714                     ? (PL_op->op_type == OP_PRTF)
715                         ? "printf"
716                         : PL_op_name[PL_op->op_type]
717                     : "(unknown)"
718         );
719     SvUTF8_off(sv);
720     if (DO_UTF8(*sarg))
721         SvUTF8_on(sv);
722     sv_vsetpvfn(sv, pat, patlen, NULL, sarg + 1, (Size_t)(len - 1), &do_taint);
723     SvSETMAGIC(sv);
724     if (do_taint)
725         SvTAINTED_on(sv);
726 }
727
728 /* currently converts input to bytes if possible, but doesn't sweat failure */
729 UV
730 Perl_do_vecget(pTHX_ SV *sv, STRLEN offset, int size)
731 {
732     STRLEN srclen, len, avail, uoffset, bitoffs = 0;
733     const I32 svpv_flags = ((PL_op->op_flags & OPf_MOD || LVRET)
734                                           ? SV_UNDEF_RETURNS_NULL : 0);
735     unsigned char *s = (unsigned char *)
736                             SvPV_flags(sv, srclen, (svpv_flags|SV_GMAGIC));
737     UV retnum = 0;
738
739     if (!s) {
740       s = (unsigned char *)"";
741     }
742
743     PERL_ARGS_ASSERT_DO_VECGET;
744
745     if (size < 1 || (size & (size-1))) /* size < 1 or not a power of two */
746         Perl_croak(aTHX_ "Illegal number of bits in vec");
747
748     if (SvUTF8(sv)) {
749         if (Perl_sv_utf8_downgrade_flags(aTHX_ sv, TRUE, 0)) {
750             /* PVX may have changed */
751             s = (unsigned char *) SvPV_flags(sv, srclen, svpv_flags);
752         }
753         else {
754                 Perl_croak(aTHX_ "Use of strings with code points over 0xFF as arguments to vec is forbidden");
755         }
756     }
757
758     if (size < 8) {
759         bitoffs = ((offset%8)*size)%8;
760         uoffset = offset/(8/size);
761     }
762     else if (size > 8) {
763         int n = size/8;
764         if (offset > Size_t_MAX / n - 1) /* would overflow */
765             return 0;
766         uoffset = offset*n;
767     }
768     else
769         uoffset = offset;
770
771     if (uoffset >= srclen)
772         return 0;
773
774     len   = (bitoffs + size + 7)/8; /* required number of bytes */
775     avail = srclen - uoffset;       /* available number of bytes */
776
777     /* Does the byte range overlap the end of the string? If so,
778      * handle specially. */
779     if (avail < len) {
780         if (size <= 8)
781             retnum = 0;
782         else {
783             if (size == 16) {
784                 assert(avail == 1);
785                 retnum = (UV) s[uoffset] <<  8;
786             }
787             else if (size == 32) {
788                 assert(avail >= 1 && avail <= 3);
789                 if (avail == 1)
790                     retnum =
791                         ((UV) s[uoffset    ] << 24);
792                 else if (avail == 2)
793                     retnum =
794                         ((UV) s[uoffset    ] << 24) +
795                         ((UV) s[uoffset + 1] << 16);
796                 else
797                     retnum =
798                         ((UV) s[uoffset    ] << 24) +
799                         ((UV) s[uoffset + 1] << 16) +
800                         (     s[uoffset + 2] <<  8);
801             }
802 #ifdef UV_IS_QUAD
803             else if (size == 64) {
804                 Perl_ck_warner(aTHX_ packWARN(WARN_PORTABLE),
805                                "Bit vector size > 32 non-portable");
806                 assert(avail >= 1 && avail <= 7);
807                 if (avail == 1)
808                     retnum =
809                         (UV) s[uoffset     ] << 56;
810                 else if (avail == 2)
811                     retnum =
812                         ((UV) s[uoffset    ] << 56) +
813                         ((UV) s[uoffset + 1] << 48);
814                 else if (avail == 3)
815                     retnum =
816                         ((UV) s[uoffset    ] << 56) +
817                         ((UV) s[uoffset + 1] << 48) +
818                         ((UV) s[uoffset + 2] << 40);
819                 else if (avail == 4)
820                     retnum =
821                         ((UV) s[uoffset    ] << 56) +
822                         ((UV) s[uoffset + 1] << 48) +
823                         ((UV) s[uoffset + 2] << 40) +
824                         ((UV) s[uoffset + 3] << 32);
825                 else if (avail == 5)
826                     retnum =
827                         ((UV) s[uoffset    ] << 56) +
828                         ((UV) s[uoffset + 1] << 48) +
829                         ((UV) s[uoffset + 2] << 40) +
830                         ((UV) s[uoffset + 3] << 32) +
831                         ((UV) s[uoffset + 4] << 24);
832                 else if (avail == 6)
833                     retnum =
834                         ((UV) s[uoffset    ] << 56) +
835                         ((UV) s[uoffset + 1] << 48) +
836                         ((UV) s[uoffset + 2] << 40) +
837                         ((UV) s[uoffset + 3] << 32) +
838                         ((UV) s[uoffset + 4] << 24) +
839                         ((UV) s[uoffset + 5] << 16);
840                 else
841                     retnum =
842                         ((UV) s[uoffset    ] << 56) +
843                         ((UV) s[uoffset + 1] << 48) +
844                         ((UV) s[uoffset + 2] << 40) +
845                         ((UV) s[uoffset + 3] << 32) +
846                         ((UV) s[uoffset + 4] << 24) +
847                         ((UV) s[uoffset + 5] << 16) +
848                         ((UV) s[uoffset + 6] <<  8);
849             }
850 #endif
851         }
852     }
853     else if (size < 8)
854         retnum = (s[uoffset] >> bitoffs) & ((1 << size) - 1);
855     else {
856         if (size == 8)
857             retnum = s[uoffset];
858         else if (size == 16)
859             retnum =
860                 ((UV) s[uoffset] <<      8) +
861                       s[uoffset + 1];
862         else if (size == 32)
863             retnum =
864                 ((UV) s[uoffset    ] << 24) +
865                 ((UV) s[uoffset + 1] << 16) +
866                 (     s[uoffset + 2] <<  8) +
867                       s[uoffset + 3];
868 #ifdef UV_IS_QUAD
869         else if (size == 64) {
870             Perl_ck_warner(aTHX_ packWARN(WARN_PORTABLE),
871                            "Bit vector size > 32 non-portable");
872             retnum =
873                 ((UV) s[uoffset    ] << 56) +
874                 ((UV) s[uoffset + 1] << 48) +
875                 ((UV) s[uoffset + 2] << 40) +
876                 ((UV) s[uoffset + 3] << 32) +
877                 ((UV) s[uoffset + 4] << 24) +
878                 ((UV) s[uoffset + 5] << 16) +
879                 (     s[uoffset + 6] <<  8) +
880                       s[uoffset + 7];
881         }
882 #endif
883     }
884
885     return retnum;
886 }
887
888 /* currently converts input to bytes if possible but doesn't sweat failures,
889  * although it does ensure that the string it clobbers is not marked as
890  * utf8-valid any more
891  */
892 void
893 Perl_do_vecset(pTHX_ SV *sv)
894 {
895     STRLEN offset, bitoffs = 0;
896     int size;
897     unsigned char *s;
898     UV lval;
899     I32 mask;
900     STRLEN targlen;
901     STRLEN len;
902     SV * const targ = LvTARG(sv);
903     char errflags = LvFLAGS(sv);
904
905     PERL_ARGS_ASSERT_DO_VECSET;
906
907     /* some out-of-range errors have been deferred if/until the LV is
908      * actually written to: f(vec($s,-1,8)) is not always fatal */
909     if (errflags) {
910         assert(!(errflags & ~(LVf_NEG_OFF|LVf_OUT_OF_RANGE)));
911         if (errflags & LVf_NEG_OFF)
912             Perl_croak_nocontext("Negative offset to vec in lvalue context");
913         Perl_croak_nocontext("Out of memory!");
914     }
915
916     if (!targ)
917         return;
918     s = (unsigned char*)SvPV_force_flags(targ, targlen,
919                                          SV_GMAGIC | SV_UNDEF_RETURNS_NULL);
920     if (SvUTF8(targ)) {
921         /* This is handled by the SvPOK_only below...
922         if (!Perl_sv_utf8_downgrade_flags(aTHX_ targ, TRUE, 0))
923             SvUTF8_off(targ);
924          */
925         (void) Perl_sv_utf8_downgrade_flags(aTHX_ targ, TRUE, 0);
926     }
927
928     (void)SvPOK_only(targ);
929     lval = SvUV(sv);
930     offset = LvTARGOFF(sv);
931     size = LvTARGLEN(sv);
932
933     if (size < 1 || (size & (size-1))) /* size < 1 or not a power of two */
934         Perl_croak(aTHX_ "Illegal number of bits in vec");
935
936     if (size < 8) {
937         bitoffs = ((offset%8)*size)%8;
938         offset /= 8/size;
939     }
940     else if (size > 8) {
941         int n = size/8;
942         if (offset > Size_t_MAX / n - 1) /* would overflow */
943             Perl_croak_nocontext("Out of memory!");
944         offset *= n;
945     }
946
947     len = (bitoffs + size + 7)/8;       /* required number of bytes */
948     if (targlen < offset || targlen - offset < len) {
949         STRLEN newlen = offset > Size_t_MAX - len - 1 ? /* avoid overflow */
950                                         Size_t_MAX : offset + len + 1;
951         s = (unsigned char*)SvGROW(targ, newlen);
952         (void)memzero((char *)(s + targlen), newlen - targlen);
953         SvCUR_set(targ, newlen - 1);
954     }
955
956     if (size < 8) {
957         mask = (1 << size) - 1;
958         lval &= mask;
959         s[offset] &= ~(mask << bitoffs);
960         s[offset] |= lval << bitoffs;
961     }
962     else {
963         if (size == 8)
964             s[offset  ] = (U8)( lval        & 0xff);
965         else if (size == 16) {
966             s[offset  ] = (U8)((lval >>  8) & 0xff);
967             s[offset+1] = (U8)( lval        & 0xff);
968         }
969         else if (size == 32) {
970             s[offset  ] = (U8)((lval >> 24) & 0xff);
971             s[offset+1] = (U8)((lval >> 16) & 0xff);
972             s[offset+2] = (U8)((lval >>  8) & 0xff);
973             s[offset+3] = (U8)( lval        & 0xff);
974         }
975 #ifdef UV_IS_QUAD
976         else if (size == 64) {
977             Perl_ck_warner(aTHX_ packWARN(WARN_PORTABLE),
978                            "Bit vector size > 32 non-portable");
979             s[offset  ] = (U8)((lval >> 56) & 0xff);
980             s[offset+1] = (U8)((lval >> 48) & 0xff);
981             s[offset+2] = (U8)((lval >> 40) & 0xff);
982             s[offset+3] = (U8)((lval >> 32) & 0xff);
983             s[offset+4] = (U8)((lval >> 24) & 0xff);
984             s[offset+5] = (U8)((lval >> 16) & 0xff);
985             s[offset+6] = (U8)((lval >>  8) & 0xff);
986             s[offset+7] = (U8)( lval        & 0xff);
987         }
988 #endif
989     }
990     SvSETMAGIC(targ);
991 }
992
993 void
994 Perl_do_vop(pTHX_ I32 optype, SV *sv, SV *left, SV *right)
995 {
996     long *dl;
997     long *ll;
998     long *rl;
999     char *dc;
1000     STRLEN leftlen;
1001     STRLEN rightlen;
1002     const char *lc;
1003     const char *rc;
1004     STRLEN len = 0;
1005     STRLEN lensave;
1006     const char *lsave;
1007     const char *rsave;
1008     STRLEN needlen = 0;
1009     bool result_needs_to_be_utf8 = FALSE;
1010     bool left_utf8 = FALSE;
1011     bool right_utf8 = FALSE;
1012     U8 * left_non_downgraded = NULL;
1013     U8 * right_non_downgraded = NULL;
1014     Size_t left_non_downgraded_len = 0;
1015     Size_t right_non_downgraded_len = 0;
1016     char * non_downgraded = NULL;
1017     Size_t non_downgraded_len = 0;
1018
1019     PERL_ARGS_ASSERT_DO_VOP;
1020
1021     if (sv != left || (optype != OP_BIT_AND && !SvOK(sv)))
1022         SvPVCLEAR(sv);        /* avoid undef warning on |= and ^= */
1023     if (sv == left) {
1024         lc = SvPV_force_nomg(left, leftlen);
1025     }
1026     else {
1027         lc = SvPV_nomg_const(left, leftlen);
1028         SvPV_force_nomg_nolen(sv);
1029     }
1030     rc = SvPV_nomg_const(right, rightlen);
1031
1032     /* This needs to come after SvPV to ensure that string overloading has
1033        fired off.  */
1034
1035     /* Create downgraded temporaries of any UTF-8 encoded operands */
1036     if (DO_UTF8(left)) {
1037         const U8 * save_lc = (U8 *) lc;
1038
1039         left_utf8 = TRUE;
1040         result_needs_to_be_utf8 = TRUE;
1041
1042         left_non_downgraded_len = leftlen;
1043         lc = (char *) bytes_from_utf8_loc((const U8 *) lc, &leftlen,
1044                                           &left_utf8,
1045                                           (const U8 **) &left_non_downgraded);
1046         /* Calculate the number of trailing unconvertible bytes.  This quantity
1047          * is the original length minus the length of the converted portion. */
1048         left_non_downgraded_len -= left_non_downgraded - save_lc;
1049         SAVEFREEPV(lc);
1050     }
1051     if (DO_UTF8(right)) {
1052         const U8 * save_rc = (U8 *) rc;
1053
1054         right_utf8 = TRUE;
1055         result_needs_to_be_utf8 = TRUE;
1056
1057         right_non_downgraded_len = rightlen;
1058         rc = (char *) bytes_from_utf8_loc((const U8 *) rc, &rightlen,
1059                                           &right_utf8,
1060                                           (const U8 **) &right_non_downgraded);
1061         right_non_downgraded_len -= right_non_downgraded - save_rc;
1062         SAVEFREEPV(rc);
1063     }
1064
1065     /* We set 'len' to the length that the operation actually operates on.  The
1066      * dangling part of the longer operand doesn't actually participate in the
1067      * operation.  What happens is that we pretend that the shorter operand has
1068      * been extended to the right by enough imaginary zeros to match the length
1069      * of the longer one.  But we know in advance the result of the operation
1070      * on zeros without having to do it.  In the case of '&', the result is
1071      * zero, and the dangling portion is simply discarded.  For '|' and '^', the
1072      * result is the same as the other operand, so the dangling part is just
1073      * appended to the final result, unchanged.  As of perl-5.32, we no longer
1074      * accept above-FF code points in the dangling portion.
1075      */
1076     if (left_utf8 || right_utf8) {
1077         Perl_croak(aTHX_ FATAL_ABOVE_FF_MSG, PL_op_desc[optype]);
1078     }
1079     else {  /* Neither is UTF-8 */
1080         len = MIN(leftlen, rightlen);
1081     }
1082
1083     lensave = len;
1084     lsave = lc;
1085     rsave = rc;
1086
1087     SvCUR_set(sv, len);
1088     (void)SvPOK_only(sv);
1089     if (SvOK(sv) || SvTYPE(sv) > SVt_PVMG) {
1090         dc = SvPV_force_nomg_nolen(sv);
1091         if (SvLEN(sv) < len + 1) {
1092             dc = SvGROW(sv, len + 1);
1093             (void)memzero(dc + SvCUR(sv), len - SvCUR(sv) + 1);
1094         }
1095     }
1096     else {
1097         needlen = optype == OP_BIT_AND
1098                     ? len : (leftlen > rightlen ? leftlen : rightlen);
1099         Newxz(dc, needlen + 1, char);
1100         sv_usepvn_flags(sv, dc, needlen, SV_HAS_TRAILING_NUL);
1101         dc = SvPVX(sv);         /* sv_usepvn() calls Renew() */
1102     }
1103
1104     if (len >= sizeof(long)*4 &&
1105         !(PTR2nat(dc) % sizeof(long)) &&
1106         !(PTR2nat(lc) % sizeof(long)) &&
1107         !(PTR2nat(rc) % sizeof(long)))  /* It's almost always aligned... */
1108     {
1109         const STRLEN remainder = len % (sizeof(long)*4);
1110         len /= (sizeof(long)*4);
1111
1112         dl = (long*)dc;
1113         ll = (long*)lc;
1114         rl = (long*)rc;
1115
1116         switch (optype) {
1117         case OP_BIT_AND:
1118             while (len--) {
1119                 *dl++ = *ll++ & *rl++;
1120                 *dl++ = *ll++ & *rl++;
1121                 *dl++ = *ll++ & *rl++;
1122                 *dl++ = *ll++ & *rl++;
1123             }
1124             break;
1125         case OP_BIT_XOR:
1126             while (len--) {
1127                 *dl++ = *ll++ ^ *rl++;
1128                 *dl++ = *ll++ ^ *rl++;
1129                 *dl++ = *ll++ ^ *rl++;
1130                 *dl++ = *ll++ ^ *rl++;
1131             }
1132             break;
1133         case OP_BIT_OR:
1134             while (len--) {
1135                 *dl++ = *ll++ | *rl++;
1136                 *dl++ = *ll++ | *rl++;
1137                 *dl++ = *ll++ | *rl++;
1138                 *dl++ = *ll++ | *rl++;
1139             }
1140         }
1141
1142         dc = (char*)dl;
1143         lc = (char*)ll;
1144         rc = (char*)rl;
1145
1146         len = remainder;
1147     }
1148
1149     switch (optype) {
1150     case OP_BIT_AND:
1151         while (len--)
1152             *dc++ = *lc++ & *rc++;
1153         *dc = '\0';
1154         break;
1155     case OP_BIT_XOR:
1156         while (len--)
1157             *dc++ = *lc++ ^ *rc++;
1158         goto mop_up;
1159     case OP_BIT_OR:
1160         while (len--)
1161             *dc++ = *lc++ | *rc++;
1162       mop_up:
1163         len = lensave;
1164         if (rightlen > len) {
1165             if (dc == rc)
1166                 SvCUR_set(sv, rightlen);
1167             else
1168                 sv_catpvn_nomg(sv, rsave + len, rightlen - len);
1169         }
1170         else if (leftlen > len) {
1171             if (dc == lc)
1172                 SvCUR_set(sv, leftlen);
1173             else
1174                 sv_catpvn_nomg(sv, lsave + len, leftlen - len);
1175         }
1176         *SvEND(sv) = '\0';
1177
1178         /* If there is trailing stuff that couldn't be converted from UTF-8, it
1179          * is appended as-is for the ^ and | operators.  This preserves
1180          * backwards compatibility */
1181         if (right_non_downgraded) {
1182             non_downgraded = (char *) right_non_downgraded;
1183             non_downgraded_len = right_non_downgraded_len;
1184         }
1185         else if (left_non_downgraded) {
1186             non_downgraded = (char *) left_non_downgraded;
1187             non_downgraded_len = left_non_downgraded_len;
1188         }
1189
1190         break;
1191     }
1192
1193     if (result_needs_to_be_utf8) {
1194         sv_utf8_upgrade_nomg(sv);
1195
1196         /* Append any trailing UTF-8 as-is. */
1197         if (non_downgraded) {
1198             sv_catpvn_nomg(sv, non_downgraded, non_downgraded_len);
1199         }
1200     }
1201
1202     SvTAINT(sv);
1203 }
1204
1205
1206 /* Perl_do_kv() may be:
1207  *  * called directly as the pp function for pp_keys() and pp_values();
1208  *  * It may also be called directly when the op is OP_AVHVSWITCH, to
1209  *       implement CORE::keys(), CORE::values().
1210  *
1211  * In all cases it expects an HV on the stack and returns a list of keys,
1212  * values, or key-value pairs, depending on PL_op.
1213  */
1214
1215 OP *
1216 Perl_do_kv(pTHX)
1217 {
1218     dSP;
1219     HV * const keys = MUTABLE_HV(POPs);
1220     const U8 gimme = GIMME_V;
1221
1222     const I32 dokeys   =     (PL_op->op_type == OP_KEYS)
1223                           || (    PL_op->op_type == OP_AVHVSWITCH
1224                               && (PL_op->op_private & OPpAVHVSWITCH_MASK)
1225                                     + OP_EACH == OP_KEYS);
1226
1227     const I32 dovalues =     (PL_op->op_type == OP_VALUES)
1228                           || (    PL_op->op_type == OP_AVHVSWITCH
1229                               && (PL_op->op_private & OPpAVHVSWITCH_MASK)
1230                                      + OP_EACH == OP_VALUES);
1231
1232     assert(   PL_op->op_type == OP_KEYS
1233            || PL_op->op_type == OP_VALUES
1234            || PL_op->op_type == OP_AVHVSWITCH);
1235
1236     assert(!(    PL_op->op_type == OP_VALUES
1237              && (PL_op->op_private & OPpMAYBE_LVSUB)));
1238
1239     (void)hv_iterinit(keys);    /* always reset iterator regardless */
1240
1241     if (gimme == G_VOID)
1242         RETURN;
1243
1244     if (gimme == G_SCALAR) {
1245         if (PL_op->op_flags & OPf_MOD || LVRET) {       /* lvalue */
1246             SV * const ret = sv_2mortal(newSV_type(SVt_PVLV));  /* Not TARG RT#67838 */
1247             sv_magic(ret, NULL, PERL_MAGIC_nkeys, NULL, 0);
1248             LvTYPE(ret) = 'k';
1249             LvTARG(ret) = SvREFCNT_inc_simple(keys);
1250             PUSHs(ret);
1251         }
1252         else {
1253             IV i;
1254             dTARGET;
1255
1256             /* note that in 'scalar(keys %h)' the OP_KEYS is usually
1257              * optimised away and the action is performed directly by the
1258              * padhv or rv2hv op. We now only get here via OP_AVHVSWITCH
1259              * and \&CORE::keys
1260              */
1261             if (! SvTIED_mg((const SV *)keys, PERL_MAGIC_tied) ) {
1262                 i = HvUSEDKEYS(keys);
1263             }
1264             else {
1265                 i = 0;
1266                 while (hv_iternext(keys)) i++;
1267             }
1268             PUSHi( i );
1269         }
1270         RETURN;
1271     }
1272
1273     if (UNLIKELY(PL_op->op_private & OPpMAYBE_LVSUB)) {
1274         const I32 flags = is_lvalue_sub();
1275         if (flags && !(flags & OPpENTERSUB_INARGS))
1276             /* diag_listed_as: Can't modify %s in %s */
1277             Perl_croak(aTHX_ "Can't modify keys in list assignment");
1278     }
1279
1280     PUTBACK;
1281     hv_pushkv(keys, (dokeys | (dovalues << 1)));
1282     return NORMAL;
1283 }
1284
1285 /*
1286  * ex: set ts=8 sts=4 sw=4 et:
1287  */