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