ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/staticperl/perl/doop.c
Revision: 1.1
Committed: Thu Jun 30 14:26:41 2005 UTC (21 years, 3 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: PERL-5-8-7, HEAD
Branch point for: PERL
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 /* doop.c
2     *
3     * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
4     * 2000, 2001, 2002, 2004, 2005, 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    
15     /* This file contains some common functions needed to carry out certain
16     * ops. For example both pp_schomp() and pp_chomp() - scalar and array
17     * chomp operations - call the function do_chomp() found in this file.
18     */
19    
20     #include "EXTERN.h"
21     #define PERL_IN_DOOP_C
22     #include "perl.h"
23    
24     #ifndef PERL_MICRO
25     #include <signal.h>
26     #endif
27    
28     STATIC I32
29     S_do_trans_simple(pTHX_ SV *sv)
30     {
31     U8 *s;
32     U8 *d;
33     U8 *send;
34     U8 *dstart;
35     I32 matches = 0;
36     I32 grows = PL_op->op_private & OPpTRANS_GROWS;
37     STRLEN len;
38     short *tbl;
39     I32 ch;
40    
41     tbl = (short*)cPVOP->op_pv;
42     if (!tbl)
43     Perl_croak(aTHX_ "panic: do_trans_simple line %d",__LINE__);
44    
45     s = (U8*)SvPV(sv, len);
46     send = s + len;
47    
48     /* First, take care of non-UTF-8 input strings, because they're easy */
49     if (!SvUTF8(sv)) {
50     while (s < send) {
51     if ((ch = tbl[*s]) >= 0) {
52     matches++;
53     *s++ = (U8)ch;
54     }
55     else
56     s++;
57     }
58     SvSETMAGIC(sv);
59     return matches;
60     }
61    
62     /* Allow for expansion: $_="a".chr(400); tr/a/\xFE/, FE needs encoding */
63     if (grows)
64     New(0, d, len*2+1, U8);
65     else
66     d = s;
67     dstart = d;
68     while (s < send) {
69     STRLEN ulen;
70     UV c;
71    
72     /* Need to check this, otherwise 128..255 won't match */
73     c = utf8n_to_uvchr(s, send - s, &ulen, 0);
74     if (c < 0x100 && (ch = tbl[c]) >= 0) {
75     matches++;
76     d = uvchr_to_utf8(d, ch);
77     s += ulen;
78     }
79     else { /* No match -> copy */
80     Move(s, d, ulen, U8);
81     d += ulen;
82     s += ulen;
83     }
84     }
85     if (grows) {
86     sv_setpvn(sv, (char*)dstart, d - dstart);
87     Safefree(dstart);
88     }
89     else {
90     *d = '\0';
91     SvCUR_set(sv, d - dstart);
92     }
93     SvUTF8_on(sv);
94     SvSETMAGIC(sv);
95     return matches;
96     }
97    
98     STATIC I32
99     S_do_trans_count(pTHX_ SV *sv)
100     {
101     U8 *s;
102     U8 *send;
103     I32 matches = 0;
104     STRLEN len;
105     short *tbl;
106     I32 complement = PL_op->op_private & OPpTRANS_COMPLEMENT;
107    
108     tbl = (short*)cPVOP->op_pv;
109     if (!tbl)
110     Perl_croak(aTHX_ "panic: do_trans_count line %d",__LINE__);
111    
112     s = (U8*)SvPV(sv, len);
113     send = s + len;
114    
115     if (!SvUTF8(sv))
116     while (s < send) {
117     if (tbl[*s++] >= 0)
118     matches++;
119     }
120     else
121     while (s < send) {
122     UV c;
123     STRLEN ulen;
124     c = utf8n_to_uvchr(s, send - s, &ulen, 0);
125     if (c < 0x100) {
126     if (tbl[c] >= 0)
127     matches++;
128     } else if (complement)
129     matches++;
130     s += ulen;
131     }
132    
133     return matches;
134     }
135    
136     STATIC I32
137     S_do_trans_complex(pTHX_ SV *sv)
138     {
139     U8 *s;
140     U8 *send;
141     U8 *d;
142     U8 *dstart;
143     I32 isutf8;
144     I32 matches = 0;
145     I32 grows = PL_op->op_private & OPpTRANS_GROWS;
146     I32 complement = PL_op->op_private & OPpTRANS_COMPLEMENT;
147     I32 del = PL_op->op_private & OPpTRANS_DELETE;
148     STRLEN len, rlen = 0;
149     short *tbl;
150     I32 ch;
151    
152     tbl = (short*)cPVOP->op_pv;
153     if (!tbl)
154     Perl_croak(aTHX_ "panic: do_trans_complex line %d",__LINE__);
155    
156     s = (U8*)SvPV(sv, len);
157     isutf8 = SvUTF8(sv);
158     send = s + len;
159    
160     if (!isutf8) {
161     dstart = d = s;
162     if (PL_op->op_private & OPpTRANS_SQUASH) {
163     U8* p = send;
164     while (s < send) {
165     if ((ch = tbl[*s]) >= 0) {
166     *d = (U8)ch;
167     matches++;
168     if (p != d - 1 || *p != *d)
169     p = d++;
170     }
171     else if (ch == -1) /* -1 is unmapped character */
172     *d++ = *s;
173     else if (ch == -2) /* -2 is delete character */
174     matches++;
175     s++;
176     }
177     }
178     else {
179     while (s < send) {
180     if ((ch = tbl[*s]) >= 0) {
181     matches++;
182     *d++ = (U8)ch;
183     }
184     else if (ch == -1) /* -1 is unmapped character */
185     *d++ = *s;
186     else if (ch == -2) /* -2 is delete character */
187     matches++;
188     s++;
189     }
190     }
191     *d = '\0';
192     SvCUR_set(sv, d - dstart);
193     }
194     else { /* isutf8 */
195     if (grows)
196     New(0, d, len*2+1, U8);
197     else
198     d = s;
199     dstart = d;
200     if (complement && !del)
201     rlen = tbl[0x100];
202    
203     #ifdef MACOS_TRADITIONAL
204     #define comp CoMP /* "comp" is a keyword in some compilers ... */
205     #endif
206    
207     if (PL_op->op_private & OPpTRANS_SQUASH) {
208     UV pch = 0xfeedface;
209     while (s < send) {
210     STRLEN len;
211     UV comp = utf8_to_uvchr(s, &len);
212    
213     if (comp > 0xff) {
214     if (!complement) {
215     Copy(s, d, len, U8);
216     d += len;
217     }
218     else {
219     matches++;
220     if (!del) {
221     ch = (rlen == 0) ? comp :
222     (comp - 0x100 < rlen) ?
223     tbl[comp+1] : tbl[0x100+rlen];
224     if ((UV)ch != pch) {
225     d = uvchr_to_utf8(d, ch);
226     pch = (UV)ch;
227     }
228     s += len;
229     continue;
230     }
231     }
232     }
233     else if ((ch = tbl[comp]) >= 0) {
234     matches++;
235     if ((UV)ch != pch) {
236     d = uvchr_to_utf8(d, ch);
237     pch = (UV)ch;
238     }
239     s += len;
240     continue;
241     }
242     else if (ch == -1) { /* -1 is unmapped character */
243     Copy(s, d, len, U8);
244     d += len;
245     }
246     else if (ch == -2) /* -2 is delete character */
247     matches++;
248     s += len;
249     pch = 0xfeedface;
250     }
251     }
252     else {
253     while (s < send) {
254     STRLEN len;
255     UV comp = utf8_to_uvchr(s, &len);
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     Copy(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 *sv)
300     {
301     U8 *s;
302     U8 *send;
303     U8 *d;
304     U8 *start;
305     U8 *dstart, *dend;
306     I32 matches = 0;
307     I32 grows = PL_op->op_private & OPpTRANS_GROWS;
308     STRLEN len;
309    
310     SV* rv = (SV*)cSVOP->op_sv;
311     HV* hv = (HV*)SvRV(rv);
312     SV** svp = hv_fetch(hv, "NONE", 4, FALSE);
313     UV none = svp ? SvUV(*svp) : 0x7fffffff;
314     UV extra = none + 1;
315     UV final = 0;
316     UV uv;
317     I32 isutf8;
318     U8 hibit = 0;
319    
320     s = (U8*)SvPV(sv, len);
321     isutf8 = SvUTF8(sv);
322     if (!isutf8) {
323     U8 *t = s, *e = s + len;
324     while (t < e) {
325     U8 ch = *t++;
326     if ((hibit = !NATIVE_IS_INVARIANT(ch)))
327     break;
328     }
329     if (hibit)
330     s = bytes_to_utf8(s, &len);
331     }
332     send = s + len;
333     start = s;
334    
335     svp = hv_fetch(hv, "FINAL", 5, FALSE);
336     if (svp)
337     final = SvUV(*svp);
338    
339     if (grows) {
340     /* d needs to be bigger than s, in case e.g. upgrading is required */
341     New(0, d, len * 3 + UTF8_MAXBYTES, U8);
342     dend = d + len * 3;
343     dstart = d;
344     }
345     else {
346     dstart = d = s;
347     dend = d + len;
348     }
349    
350     while (s < send) {
351     if ((uv = swash_fetch(rv, s, TRUE)) < none) {
352     s += UTF8SKIP(s);
353     matches++;
354     d = uvuni_to_utf8(d, uv);
355     }
356     else if (uv == none) {
357     int i = UTF8SKIP(s);
358     Move(s, d, i, U8);
359     d += i;
360     s += i;
361     }
362     else if (uv == extra) {
363     int i = UTF8SKIP(s);
364     s += i;
365     matches++;
366     d = uvuni_to_utf8(d, final);
367     }
368     else
369     s += UTF8SKIP(s);
370    
371     if (d > dend) {
372     STRLEN clen = d - dstart;
373     STRLEN nlen = dend - dstart + len + UTF8_MAXBYTES;
374     if (!grows)
375     Perl_croak(aTHX_ "panic: do_trans_simple_utf8 line %d",__LINE__);
376     Renew(dstart, nlen + UTF8_MAXBYTES, U8);
377     d = dstart + clen;
378     dend = dstart + nlen;
379     }
380     }
381     if (grows || hibit) {
382     sv_setpvn(sv, (char*)dstart, d - dstart);
383     Safefree(dstart);
384     if (grows && hibit)
385     Safefree(start);
386     }
387     else {
388     *d = '\0';
389     SvCUR_set(sv, d - dstart);
390     }
391     SvSETMAGIC(sv);
392     SvUTF8_on(sv);
393    
394     return matches;
395     }
396    
397     STATIC I32
398     S_do_trans_count_utf8(pTHX_ SV *sv)
399     {
400     U8 *s;
401     U8 *start = 0, *send;
402     I32 matches = 0;
403     STRLEN len;
404    
405     SV* rv = (SV*)cSVOP->op_sv;
406     HV* hv = (HV*)SvRV(rv);
407     SV** svp = hv_fetch(hv, "NONE", 4, FALSE);
408     UV none = svp ? SvUV(*svp) : 0x7fffffff;
409     UV extra = none + 1;
410     UV uv;
411     U8 hibit = 0;
412    
413     s = (U8*)SvPV(sv, len);
414     if (!SvUTF8(sv)) {
415     U8 *t = s, *e = s + len;
416     while (t < e) {
417     U8 ch = *t++;
418     if ((hibit = !NATIVE_IS_INVARIANT(ch)))
419     break;
420     }
421     if (hibit)
422     start = s = bytes_to_utf8(s, &len);
423     }
424     send = s + len;
425    
426     while (s < send) {
427     if ((uv = swash_fetch(rv, s, TRUE)) < none || uv == extra)
428     matches++;
429     s += UTF8SKIP(s);
430     }
431     if (hibit)
432     Safefree(start);
433    
434     return matches;
435     }
436    
437     STATIC I32
438     S_do_trans_complex_utf8(pTHX_ SV *sv)
439     {
440     U8 *s;
441     U8 *start, *send;
442     U8 *d;
443     I32 matches = 0;
444     I32 squash = PL_op->op_private & OPpTRANS_SQUASH;
445     I32 del = PL_op->op_private & OPpTRANS_DELETE;
446     I32 grows = PL_op->op_private & OPpTRANS_GROWS;
447     SV* rv = (SV*)cSVOP->op_sv;
448     HV* hv = (HV*)SvRV(rv);
449     SV** svp = hv_fetch(hv, "NONE", 4, FALSE);
450     UV none = svp ? SvUV(*svp) : 0x7fffffff;
451     UV extra = none + 1;
452     UV final = 0;
453     bool havefinal = FALSE;
454     UV uv;
455     STRLEN len;
456     U8 *dstart, *dend;
457     I32 isutf8;
458     U8 hibit = 0;
459    
460     s = (U8*)SvPV(sv, len);
461     isutf8 = SvUTF8(sv);
462     if (!isutf8) {
463     U8 *t = s, *e = s + len;
464     while (t < e) {
465     U8 ch = *t++;
466     if ((hibit = !NATIVE_IS_INVARIANT(ch)))
467     break;
468     }
469     if (hibit)
470     s = bytes_to_utf8(s, &len);
471     }
472     send = s + len;
473     start = s;
474    
475     svp = hv_fetch(hv, "FINAL", 5, FALSE);
476     if (svp) {
477     final = SvUV(*svp);
478     havefinal = TRUE;
479     }
480    
481     if (grows) {
482     /* d needs to be bigger than s, in case e.g. upgrading is required */
483     New(0, d, len * 3 + UTF8_MAXBYTES, U8);
484     dend = d + len * 3;
485     dstart = d;
486     }
487     else {
488     dstart = d = s;
489     dend = d + len;
490     }
491    
492     if (squash) {
493     UV puv = 0xfeedface;
494     while (s < send) {
495     uv = swash_fetch(rv, s, TRUE);
496    
497     if (d > dend) {
498     STRLEN clen = d - dstart;
499     STRLEN nlen = dend - dstart + len + UTF8_MAXBYTES;
500     if (!grows)
501     Perl_croak(aTHX_ "panic: do_trans_complex_utf8 line %d",__LINE__);
502     Renew(dstart, nlen + UTF8_MAXBYTES, U8);
503     d = dstart + clen;
504     dend = dstart + nlen;
505     }
506     if (uv < none) {
507     matches++;
508     s += UTF8SKIP(s);
509     if (uv != puv) {
510     d = uvuni_to_utf8(d, uv);
511     puv = uv;
512     }
513     continue;
514     }
515     else if (uv == none) { /* "none" is unmapped character */
516     int i = UTF8SKIP(s);
517     Move(s, d, i, U8);
518     d += i;
519     s += i;
520     puv = 0xfeedface;
521     continue;
522     }
523     else if (uv == extra && !del) {
524     matches++;
525     if (havefinal) {
526     s += UTF8SKIP(s);
527     if (puv != final) {
528     d = uvuni_to_utf8(d, final);
529     puv = final;
530     }
531     }
532     else {
533     STRLEN len;
534     uv = utf8_to_uvuni(s, &len);
535     if (uv != puv) {
536     Move(s, d, len, U8);
537     d += len;
538     puv = uv;
539     }
540     s += len;
541     }
542     continue;
543     }
544     matches++; /* "none+1" is delete character */
545     s += UTF8SKIP(s);
546     }
547     }
548     else {
549     while (s < send) {
550     uv = swash_fetch(rv, s, TRUE);
551     if (d > dend) {
552     STRLEN clen = d - dstart;
553     STRLEN nlen = dend - dstart + len + UTF8_MAXBYTES;
554     if (!grows)
555     Perl_croak(aTHX_ "panic: do_trans_complex_utf8 line %d",__LINE__);
556     Renew(dstart, nlen + UTF8_MAXBYTES, U8);
557     d = dstart + clen;
558     dend = dstart + nlen;
559     }
560     if (uv < none) {
561     matches++;
562     s += UTF8SKIP(s);
563     d = uvuni_to_utf8(d, uv);
564     continue;
565     }
566     else if (uv == none) { /* "none" is unmapped character */
567     int i = UTF8SKIP(s);
568     Move(s, d, i, U8);
569     d += i;
570     s += i;
571     continue;
572     }
573     else if (uv == extra && !del) {
574     matches++;
575     s += UTF8SKIP(s);
576     d = uvuni_to_utf8(d, final);
577     continue;
578     }
579     matches++; /* "none+1" is delete character */
580     s += UTF8SKIP(s);
581     }
582     }
583     if (grows || hibit) {
584     sv_setpvn(sv, (char*)dstart, d - dstart);
585     Safefree(dstart);
586     if (grows && hibit)
587     Safefree(start);
588     }
589     else {
590     *d = '\0';
591     SvCUR_set(sv, d - dstart);
592     }
593     SvUTF8_on(sv);
594     SvSETMAGIC(sv);
595    
596     return matches;
597     }
598    
599     I32
600     Perl_do_trans(pTHX_ SV *sv)
601     {
602     STRLEN len;
603     I32 hasutf = (PL_op->op_private &
604     (OPpTRANS_FROM_UTF|OPpTRANS_TO_UTF));
605    
606     if (SvREADONLY(sv)) {
607     if (SvFAKE(sv))
608     sv_force_normal(sv);
609     if (SvREADONLY(sv) && !(PL_op->op_private & OPpTRANS_IDENTICAL))
610     Perl_croak(aTHX_ PL_no_modify);
611     }
612     (void)SvPV(sv, len);
613     if (!len)
614     return 0;
615     if (!(PL_op->op_private & OPpTRANS_IDENTICAL)) {
616     if (!SvPOKp(sv))
617     (void)SvPV_force(sv, len);
618     (void)SvPOK_only_UTF8(sv);
619     }
620    
621     DEBUG_t( Perl_deb(aTHX_ "2.TBL\n"));
622    
623     switch (PL_op->op_private & ~hasutf & (
624     OPpTRANS_FROM_UTF|OPpTRANS_TO_UTF|OPpTRANS_IDENTICAL|
625     OPpTRANS_SQUASH|OPpTRANS_DELETE|OPpTRANS_COMPLEMENT)) {
626     case 0:
627     if (hasutf)
628     return do_trans_simple_utf8(sv);
629     else
630     return do_trans_simple(sv);
631    
632     case OPpTRANS_IDENTICAL:
633     case OPpTRANS_IDENTICAL|OPpTRANS_COMPLEMENT:
634     if (hasutf)
635     return do_trans_count_utf8(sv);
636     else
637     return do_trans_count(sv);
638    
639     default:
640     if (hasutf)
641     return do_trans_complex_utf8(sv);
642     else
643     return do_trans_complex(sv);
644     }
645     }
646    
647     void
648     Perl_do_join(pTHX_ register SV *sv, SV *del, register SV **mark, register SV **sp)
649     {
650     SV **oldmark = mark;
651     register I32 items = sp - mark;
652     register STRLEN len;
653     STRLEN delimlen;
654     STRLEN tmplen;
655    
656     (void) SvPV(del, delimlen); /* stringify and get the delimlen */
657     /* SvCUR assumes it's SvPOK() and woe betide you if it's not. */
658    
659     mark++;
660     len = (items > 0 ? (delimlen * (items - 1) ) : 0);
661     (void)SvUPGRADE(sv, SVt_PV);
662     if (SvLEN(sv) < len + items) { /* current length is way too short */
663     while (items-- > 0) {
664     if (*mark && !SvGAMAGIC(*mark) && SvOK(*mark)) {
665     SvPV(*mark, tmplen);
666     len += tmplen;
667     }
668     mark++;
669     }
670     SvGROW(sv, len + 1); /* so try to pre-extend */
671    
672     mark = oldmark;
673     items = sp - mark;
674     ++mark;
675     }
676    
677     sv_setpvn(sv, "", 0);
678     /* sv_setpv retains old UTF8ness [perl #24846] */
679     SvUTF8_off(sv);
680    
681     if (PL_tainting && SvMAGICAL(sv))
682     SvTAINTED_off(sv);
683    
684     if (items-- > 0) {
685     if (*mark)
686     sv_catsv(sv, *mark);
687     mark++;
688     }
689    
690     if (delimlen) {
691     for (; items > 0; items--,mark++) {
692     sv_catsv(sv,del);
693     sv_catsv(sv,*mark);
694     }
695     }
696     else {
697     for (; items > 0; items--,mark++)
698     sv_catsv(sv,*mark);
699     }
700     SvSETMAGIC(sv);
701     }
702    
703     void
704     Perl_do_sprintf(pTHX_ SV *sv, I32 len, SV **sarg)
705     {
706     STRLEN patlen;
707     char *pat = SvPV(*sarg, patlen);
708     bool do_taint = FALSE;
709    
710     SvUTF8_off(sv);
711     if (DO_UTF8(*sarg))
712     SvUTF8_on(sv);
713     sv_vsetpvfn(sv, pat, patlen, Null(va_list*), sarg + 1, len - 1, &do_taint);
714     SvSETMAGIC(sv);
715     if (do_taint)
716     SvTAINTED_on(sv);
717     }
718    
719     /* currently converts input to bytes if possible, but doesn't sweat failure */
720     UV
721     Perl_do_vecget(pTHX_ SV *sv, I32 offset, I32 size)
722     {
723     STRLEN srclen, len;
724     unsigned char *s = (unsigned char *) SvPV(sv, srclen);
725     UV retnum = 0;
726    
727     if (offset < 0)
728     return retnum;
729     if (size < 1 || (size & (size-1))) /* size < 1 or not a power of two */
730     Perl_croak(aTHX_ "Illegal number of bits in vec");
731    
732     if (SvUTF8(sv))
733     (void) Perl_sv_utf8_downgrade(aTHX_ sv, TRUE);
734    
735     offset *= size; /* turn into bit offset */
736     len = (offset + size + 7) / 8; /* required number of bytes */
737     if (len > srclen) {
738     if (size <= 8)
739     retnum = 0;
740     else {
741     offset >>= 3; /* turn into byte offset */
742     if (size == 16) {
743     if ((STRLEN)offset >= srclen)
744     retnum = 0;
745     else
746     retnum = (UV) s[offset] << 8;
747     }
748     else if (size == 32) {
749     if ((STRLEN)offset >= srclen)
750     retnum = 0;
751     else if ((STRLEN)(offset + 1) >= srclen)
752     retnum =
753     ((UV) s[offset ] << 24);
754     else if ((STRLEN)(offset + 2) >= srclen)
755     retnum =
756     ((UV) s[offset ] << 24) +
757     ((UV) s[offset + 1] << 16);
758     else
759     retnum =
760     ((UV) s[offset ] << 24) +
761     ((UV) s[offset + 1] << 16) +
762     ( s[offset + 2] << 8);
763     }
764     #ifdef UV_IS_QUAD
765     else if (size == 64) {
766     if (ckWARN(WARN_PORTABLE))
767     Perl_warner(aTHX_ packWARN(WARN_PORTABLE),
768     "Bit vector size > 32 non-portable");
769     if (offset >= srclen)
770     retnum = 0;
771     else if (offset + 1 >= srclen)
772     retnum =
773     (UV) s[offset ] << 56;
774     else if (offset + 2 >= srclen)
775     retnum =
776     ((UV) s[offset ] << 56) +
777     ((UV) s[offset + 1] << 48);
778     else if (offset + 3 >= srclen)
779     retnum =
780     ((UV) s[offset ] << 56) +
781     ((UV) s[offset + 1] << 48) +
782     ((UV) s[offset + 2] << 40);
783     else if (offset + 4 >= srclen)
784     retnum =
785     ((UV) s[offset ] << 56) +
786     ((UV) s[offset + 1] << 48) +
787     ((UV) s[offset + 2] << 40) +
788     ((UV) s[offset + 3] << 32);
789     else if (offset + 5 >= srclen)
790     retnum =
791     ((UV) s[offset ] << 56) +
792     ((UV) s[offset + 1] << 48) +
793     ((UV) s[offset + 2] << 40) +
794     ((UV) s[offset + 3] << 32) +
795     ( s[offset + 4] << 24);
796     else if (offset + 6 >= srclen)
797     retnum =
798     ((UV) s[offset ] << 56) +
799     ((UV) s[offset + 1] << 48) +
800     ((UV) s[offset + 2] << 40) +
801     ((UV) s[offset + 3] << 32) +
802     ((UV) s[offset + 4] << 24) +
803     ((UV) s[offset + 5] << 16);
804     else
805     retnum =
806     ((UV) s[offset ] << 56) +
807     ((UV) s[offset + 1] << 48) +
808     ((UV) s[offset + 2] << 40) +
809     ((UV) s[offset + 3] << 32) +
810     ((UV) s[offset + 4] << 24) +
811     ((UV) s[offset + 5] << 16) +
812     ( s[offset + 6] << 8);
813     }
814     #endif
815     }
816     }
817     else if (size < 8)
818     retnum = (s[offset >> 3] >> (offset & 7)) & ((1 << size) - 1);
819     else {
820     offset >>= 3; /* turn into byte offset */
821     if (size == 8)
822     retnum = s[offset];
823     else if (size == 16)
824     retnum =
825     ((UV) s[offset] << 8) +
826     s[offset + 1];
827     else if (size == 32)
828     retnum =
829     ((UV) s[offset ] << 24) +
830     ((UV) s[offset + 1] << 16) +
831     ( s[offset + 2] << 8) +
832     s[offset + 3];
833     #ifdef UV_IS_QUAD
834     else if (size == 64) {
835     if (ckWARN(WARN_PORTABLE))
836     Perl_warner(aTHX_ packWARN(WARN_PORTABLE),
837     "Bit vector size > 32 non-portable");
838     retnum =
839     ((UV) s[offset ] << 56) +
840     ((UV) s[offset + 1] << 48) +
841     ((UV) s[offset + 2] << 40) +
842     ((UV) s[offset + 3] << 32) +
843     ((UV) s[offset + 4] << 24) +
844     ((UV) s[offset + 5] << 16) +
845     ( s[offset + 6] << 8) +
846     s[offset + 7];
847     }
848     #endif
849     }
850    
851     return retnum;
852     }
853    
854     /* currently converts input to bytes if possible but doesn't sweat failures,
855     * although it does ensure that the string it clobbers is not marked as
856     * utf8-valid any more
857     */
858     void
859     Perl_do_vecset(pTHX_ SV *sv)
860     {
861     SV *targ = LvTARG(sv);
862     register I32 offset;
863     register I32 size;
864     register unsigned char *s;
865     register UV lval;
866     I32 mask;
867     STRLEN targlen;
868     STRLEN len;
869    
870     if (!targ)
871     return;
872     s = (unsigned char*)SvPV_force(targ, targlen);
873     if (SvUTF8(targ)) {
874     /* This is handled by the SvPOK_only below...
875     if (!Perl_sv_utf8_downgrade(aTHX_ targ, TRUE))
876     SvUTF8_off(targ);
877     */
878     (void) Perl_sv_utf8_downgrade(aTHX_ targ, TRUE);
879     }
880    
881     (void)SvPOK_only(targ);
882     lval = SvUV(sv);
883     offset = LvTARGOFF(sv);
884     if (offset < 0)
885     Perl_croak(aTHX_ "Negative offset to vec in lvalue context");
886     size = LvTARGLEN(sv);
887     if (size < 1 || (size & (size-1))) /* size < 1 or not a power of two */
888     Perl_croak(aTHX_ "Illegal number of bits in vec");
889    
890     offset *= size; /* turn into bit offset */
891     len = (offset + size + 7) / 8; /* required number of bytes */
892     if (len > targlen) {
893     s = (unsigned char*)SvGROW(targ, len + 1);
894     (void)memzero((char *)(s + targlen), len - targlen + 1);
895     SvCUR_set(targ, len);
896     }
897    
898     if (size < 8) {
899     mask = (1 << size) - 1;
900     size = offset & 7;
901     lval &= mask;
902     offset >>= 3; /* turn into byte offset */
903     s[offset] &= ~(mask << size);
904     s[offset] |= lval << size;
905     }
906     else {
907     offset >>= 3; /* turn into byte offset */
908     if (size == 8)
909     s[offset ] = (U8)( lval & 0xff);
910     else if (size == 16) {
911     s[offset ] = (U8)((lval >> 8) & 0xff);
912     s[offset+1] = (U8)( lval & 0xff);
913     }
914     else if (size == 32) {
915     s[offset ] = (U8)((lval >> 24) & 0xff);
916     s[offset+1] = (U8)((lval >> 16) & 0xff);
917     s[offset+2] = (U8)((lval >> 8) & 0xff);
918     s[offset+3] = (U8)( lval & 0xff);
919     }
920     #ifdef UV_IS_QUAD
921     else if (size == 64) {
922     if (ckWARN(WARN_PORTABLE))
923     Perl_warner(aTHX_ packWARN(WARN_PORTABLE),
924     "Bit vector size > 32 non-portable");
925     s[offset ] = (U8)((lval >> 56) & 0xff);
926     s[offset+1] = (U8)((lval >> 48) & 0xff);
927     s[offset+2] = (U8)((lval >> 40) & 0xff);
928     s[offset+3] = (U8)((lval >> 32) & 0xff);
929     s[offset+4] = (U8)((lval >> 24) & 0xff);
930     s[offset+5] = (U8)((lval >> 16) & 0xff);
931     s[offset+6] = (U8)((lval >> 8) & 0xff);
932     s[offset+7] = (U8)( lval & 0xff);
933     }
934     #endif
935     }
936     SvSETMAGIC(targ);
937     }
938    
939     void
940     Perl_do_chop(pTHX_ register SV *astr, register SV *sv)
941     {
942     STRLEN len;
943     char *s;
944    
945     if (SvTYPE(sv) == SVt_PVAV) {
946     register I32 i;
947     I32 max;
948     AV* av = (AV*)sv;
949     max = AvFILL(av);
950     for (i = 0; i <= max; i++) {
951     sv = (SV*)av_fetch(av, i, FALSE);
952     if (sv && ((sv = *(SV**)sv), sv != &PL_sv_undef))
953     do_chop(astr, sv);
954     }
955     return;
956     }
957     else if (SvTYPE(sv) == SVt_PVHV) {
958     HV* hv = (HV*)sv;
959     HE* entry;
960     (void)hv_iterinit(hv);
961     /*SUPPRESS 560*/
962     while ((entry = hv_iternext(hv)))
963     do_chop(astr,hv_iterval(hv,entry));
964     return;
965     }
966     else if (SvREADONLY(sv)) {
967     if (SvFAKE(sv)) {
968     /* SV is copy-on-write */
969     sv_force_normal_flags(sv, 0);
970     }
971     if (SvREADONLY(sv))
972     Perl_croak(aTHX_ PL_no_modify);
973     }
974     s = SvPV(sv, len);
975     if (len && !SvPOK(sv))
976     s = SvPV_force(sv, len);
977     if (DO_UTF8(sv)) {
978     if (s && len) {
979     char *send = s + len;
980     char *start = s;
981     s = send - 1;
982     while (s > start && UTF8_IS_CONTINUATION(*s))
983     s--;
984     if (utf8_to_uvchr((U8*)s, 0)) {
985     sv_setpvn(astr, s, send - s);
986     *s = '\0';
987     SvCUR_set(sv, s - start);
988     SvNIOK_off(sv);
989     SvUTF8_on(astr);
990     }
991     }
992     else
993     sv_setpvn(astr, "", 0);
994     }
995     else if (s && len) {
996     s += --len;
997     sv_setpvn(astr, s, 1);
998     *s = '\0';
999     SvCUR_set(sv, len);
1000     SvUTF8_off(sv);
1001     SvNIOK_off(sv);
1002     }
1003     else
1004     sv_setpvn(astr, "", 0);
1005     SvSETMAGIC(sv);
1006     }
1007    
1008     I32
1009     Perl_do_chomp(pTHX_ register SV *sv)
1010     {
1011     register I32 count;
1012     STRLEN len;
1013     STRLEN n_a;
1014     char *s;
1015     char *temp_buffer = NULL;
1016     SV* svrecode = Nullsv;
1017    
1018     if (RsSNARF(PL_rs))
1019     return 0;
1020     if (RsRECORD(PL_rs))
1021     return 0;
1022     count = 0;
1023     if (SvTYPE(sv) == SVt_PVAV) {
1024     register I32 i;
1025     I32 max;
1026     AV* av = (AV*)sv;
1027     max = AvFILL(av);
1028     for (i = 0; i <= max; i++) {
1029     sv = (SV*)av_fetch(av, i, FALSE);
1030     if (sv && ((sv = *(SV**)sv), sv != &PL_sv_undef))
1031     count += do_chomp(sv);
1032     }
1033     return count;
1034     }
1035     else if (SvTYPE(sv) == SVt_PVHV) {
1036     HV* hv = (HV*)sv;
1037     HE* entry;
1038     (void)hv_iterinit(hv);
1039     /*SUPPRESS 560*/
1040     while ((entry = hv_iternext(hv)))
1041     count += do_chomp(hv_iterval(hv,entry));
1042     return count;
1043     }
1044     else if (SvREADONLY(sv)) {
1045     if (SvFAKE(sv)) {
1046     /* SV is copy-on-write */
1047     sv_force_normal_flags(sv, 0);
1048     }
1049     if (SvREADONLY(sv))
1050     Perl_croak(aTHX_ PL_no_modify);
1051     }
1052    
1053     if (PL_encoding) {
1054     if (!SvUTF8(sv)) {
1055     /* XXX, here sv is utf8-ized as a side-effect!
1056     If encoding.pm is used properly, almost string-generating
1057     operations, including literal strings, chr(), input data, etc.
1058     should have been utf8-ized already, right?
1059     */
1060     sv_recode_to_utf8(sv, PL_encoding);
1061     }
1062     }
1063    
1064     s = SvPV(sv, len);
1065     if (s && len) {
1066     s += --len;
1067     if (RsPARA(PL_rs)) {
1068     if (*s != '\n')
1069     goto nope;
1070     ++count;
1071     while (len && s[-1] == '\n') {
1072     --len;
1073     --s;
1074     ++count;
1075     }
1076     }
1077     else {
1078     STRLEN rslen, rs_charlen;
1079     char *rsptr = SvPV(PL_rs, rslen);
1080    
1081     rs_charlen = SvUTF8(PL_rs)
1082     ? sv_len_utf8(PL_rs)
1083     : rslen;
1084    
1085     if (SvUTF8(PL_rs) != SvUTF8(sv)) {
1086     /* Assumption is that rs is shorter than the scalar. */
1087     if (SvUTF8(PL_rs)) {
1088     /* RS is utf8, scalar is 8 bit. */
1089     bool is_utf8 = TRUE;
1090     temp_buffer = (char*)bytes_from_utf8((U8*)rsptr,
1091     &rslen, &is_utf8);
1092     if (is_utf8) {
1093     /* Cannot downgrade, therefore cannot possibly match
1094     */
1095     assert (temp_buffer == rsptr);
1096     temp_buffer = NULL;
1097     goto nope;
1098     }
1099     rsptr = temp_buffer;
1100     }
1101     else if (PL_encoding) {
1102     /* RS is 8 bit, encoding.pm is used.
1103     * Do not recode PL_rs as a side-effect. */
1104     svrecode = newSVpvn(rsptr, rslen);
1105     sv_recode_to_utf8(svrecode, PL_encoding);
1106     rsptr = SvPV(svrecode, rslen);
1107     rs_charlen = sv_len_utf8(svrecode);
1108     }
1109     else {
1110     /* RS is 8 bit, scalar is utf8. */
1111     temp_buffer = (char*)bytes_to_utf8((U8*)rsptr, &rslen);
1112     rsptr = temp_buffer;
1113     }
1114     }
1115     if (rslen == 1) {
1116     if (*s != *rsptr)
1117     goto nope;
1118     ++count;
1119     }
1120     else {
1121     if (len < rslen - 1)
1122     goto nope;
1123     len -= rslen - 1;
1124     s -= rslen - 1;
1125     if (memNE(s, rsptr, rslen))
1126     goto nope;
1127     count += rs_charlen;
1128     }
1129     }
1130     s = SvPV_force(sv, n_a);
1131     SvCUR_set(sv, len);
1132     *SvEND(sv) = '\0';
1133     SvNIOK_off(sv);
1134     SvSETMAGIC(sv);
1135     }
1136     nope:
1137    
1138     if (svrecode)
1139     SvREFCNT_dec(svrecode);
1140    
1141     Safefree(temp_buffer);
1142     return count;
1143     }
1144    
1145     void
1146     Perl_do_vop(pTHX_ I32 optype, SV *sv, SV *left, SV *right)
1147     {
1148     #ifdef LIBERAL
1149     register long *dl;
1150     register long *ll;
1151     register long *rl;
1152     #endif
1153     register char *dc;
1154     STRLEN leftlen;
1155     STRLEN rightlen;
1156     register char *lc;
1157     register char *rc;
1158     register I32 len;
1159     I32 lensave;
1160     char *lsave;
1161     char *rsave;
1162     bool left_utf = DO_UTF8(left);
1163     bool right_utf = DO_UTF8(right);
1164     I32 needlen = 0;
1165    
1166     if (left_utf && !right_utf)
1167     sv_utf8_upgrade(right);
1168     else if (!left_utf && right_utf)
1169     sv_utf8_upgrade(left);
1170    
1171     if (sv != left || (optype != OP_BIT_AND && !SvOK(sv) && !SvGMAGICAL(sv)))
1172     sv_setpvn(sv, "", 0); /* avoid undef warning on |= and ^= */
1173     lsave = lc = SvPV(left, leftlen);
1174     rsave = rc = SvPV(right, rightlen);
1175     len = leftlen < rightlen ? leftlen : rightlen;
1176     lensave = len;
1177     if ((left_utf || right_utf) && (sv == left || sv == right)) {
1178     needlen = optype == OP_BIT_AND ? len : leftlen + rightlen;
1179     Newz(801, dc, needlen + 1, char);
1180     }
1181     else if (SvOK(sv) || SvTYPE(sv) > SVt_PVMG) {
1182     STRLEN n_a;
1183     dc = SvPV_force(sv, n_a);
1184     if (SvCUR(sv) < (STRLEN)len) {
1185     dc = SvGROW(sv, (STRLEN)(len + 1));
1186     (void)memzero(dc + SvCUR(sv), len - SvCUR(sv) + 1);
1187     }
1188     if (optype != OP_BIT_AND && (left_utf || right_utf))
1189     dc = SvGROW(sv, leftlen + rightlen + 1);
1190     }
1191     else {
1192     needlen = ((optype == OP_BIT_AND)
1193     ? len : (leftlen > rightlen ? leftlen : rightlen));
1194     Newz(801, dc, needlen + 1, char);
1195     (void)sv_usepvn(sv, dc, needlen);
1196     dc = SvPVX(sv); /* sv_usepvn() calls Renew() */
1197     }
1198     SvCUR_set(sv, len);
1199     (void)SvPOK_only(sv);
1200     if (left_utf || right_utf) {
1201     UV duc, luc, ruc;
1202     char *dcsave = dc;
1203     STRLEN lulen = leftlen;
1204     STRLEN rulen = rightlen;
1205     STRLEN ulen;
1206    
1207     switch (optype) {
1208     case OP_BIT_AND:
1209     while (lulen && rulen) {
1210     luc = utf8n_to_uvchr((U8*)lc, lulen, &ulen, UTF8_ALLOW_ANYUV);
1211     lc += ulen;
1212     lulen -= ulen;
1213     ruc = utf8n_to_uvchr((U8*)rc, rulen, &ulen, UTF8_ALLOW_ANYUV);
1214     rc += ulen;
1215     rulen -= ulen;
1216     duc = luc & ruc;
1217     dc = (char*)uvchr_to_utf8((U8*)dc, duc);
1218     }
1219     if (sv == left || sv == right)
1220     (void)sv_usepvn(sv, dcsave, needlen);
1221     SvCUR_set(sv, dc - dcsave);
1222     break;
1223     case OP_BIT_XOR:
1224     while (lulen && rulen) {
1225     luc = utf8n_to_uvchr((U8*)lc, lulen, &ulen, UTF8_ALLOW_ANYUV);
1226     lc += ulen;
1227     lulen -= ulen;
1228     ruc = utf8n_to_uvchr((U8*)rc, rulen, &ulen, UTF8_ALLOW_ANYUV);
1229     rc += ulen;
1230     rulen -= ulen;
1231     duc = luc ^ ruc;
1232     dc = (char*)uvchr_to_utf8((U8*)dc, duc);
1233     }
1234     goto mop_up_utf;
1235     case OP_BIT_OR:
1236     while (lulen && rulen) {
1237     luc = utf8n_to_uvchr((U8*)lc, lulen, &ulen, UTF8_ALLOW_ANYUV);
1238     lc += ulen;
1239     lulen -= ulen;
1240     ruc = utf8n_to_uvchr((U8*)rc, rulen, &ulen, UTF8_ALLOW_ANYUV);
1241     rc += ulen;
1242     rulen -= ulen;
1243     duc = luc | ruc;
1244     dc = (char*)uvchr_to_utf8((U8*)dc, duc);
1245     }
1246     mop_up_utf:
1247     if (sv == left || sv == right)
1248     (void)sv_usepvn(sv, dcsave, needlen);
1249     SvCUR_set(sv, dc - dcsave);
1250     if (rulen)
1251     sv_catpvn(sv, rc, rulen);
1252     else if (lulen)
1253     sv_catpvn(sv, lc, lulen);
1254     else
1255     *SvEND(sv) = '\0';
1256     break;
1257     }
1258     SvUTF8_on(sv);
1259     goto finish;
1260     }
1261     else
1262     #ifdef LIBERAL
1263     if (len >= sizeof(long)*4 &&
1264     !((long)dc % sizeof(long)) &&
1265     !((long)lc % sizeof(long)) &&
1266     !((long)rc % sizeof(long))) /* It's almost always aligned... */
1267     {
1268     I32 remainder = len % (sizeof(long)*4);
1269     len /= (sizeof(long)*4);
1270    
1271     dl = (long*)dc;
1272     ll = (long*)lc;
1273     rl = (long*)rc;
1274    
1275     switch (optype) {
1276     case OP_BIT_AND:
1277     while (len--) {
1278     *dl++ = *ll++ & *rl++;
1279     *dl++ = *ll++ & *rl++;
1280     *dl++ = *ll++ & *rl++;
1281     *dl++ = *ll++ & *rl++;
1282     }
1283     break;
1284     case OP_BIT_XOR:
1285     while (len--) {
1286     *dl++ = *ll++ ^ *rl++;
1287     *dl++ = *ll++ ^ *rl++;
1288     *dl++ = *ll++ ^ *rl++;
1289     *dl++ = *ll++ ^ *rl++;
1290     }
1291     break;
1292     case OP_BIT_OR:
1293     while (len--) {
1294     *dl++ = *ll++ | *rl++;
1295     *dl++ = *ll++ | *rl++;
1296     *dl++ = *ll++ | *rl++;
1297     *dl++ = *ll++ | *rl++;
1298     }
1299     }
1300    
1301     dc = (char*)dl;
1302     lc = (char*)ll;
1303     rc = (char*)rl;
1304    
1305     len = remainder;
1306     }
1307     #endif
1308     {
1309     switch (optype) {
1310     case OP_BIT_AND:
1311     while (len--)
1312     *dc++ = *lc++ & *rc++;
1313     break;
1314     case OP_BIT_XOR:
1315     while (len--)
1316     *dc++ = *lc++ ^ *rc++;
1317     goto mop_up;
1318     case OP_BIT_OR:
1319     while (len--)
1320     *dc++ = *lc++ | *rc++;
1321     mop_up:
1322     len = lensave;
1323     if (rightlen > (STRLEN)len)
1324     sv_catpvn(sv, rsave + len, rightlen - len);
1325     else if (leftlen > (STRLEN)len)
1326     sv_catpvn(sv, lsave + len, leftlen - len);
1327     else
1328     *SvEND(sv) = '\0';
1329     break;
1330     }
1331     }
1332     finish:
1333     SvTAINT(sv);
1334     }
1335    
1336     OP *
1337     Perl_do_kv(pTHX)
1338     {
1339     dSP;
1340     HV *hv = (HV*)POPs;
1341     HV *keys;
1342     register HE *entry;
1343     SV *tmpstr;
1344     I32 gimme = GIMME_V;
1345     I32 dokeys = (PL_op->op_type == OP_KEYS);
1346     I32 dovalues = (PL_op->op_type == OP_VALUES);
1347     I32 realhv = (SvTYPE(hv) == SVt_PVHV);
1348    
1349     if (PL_op->op_type == OP_RV2HV || PL_op->op_type == OP_PADHV)
1350     dokeys = dovalues = TRUE;
1351    
1352     if (!hv) {
1353     if (PL_op->op_flags & OPf_MOD || LVRET) { /* lvalue */
1354     dTARGET; /* make sure to clear its target here */
1355     if (SvTYPE(TARG) == SVt_PVLV)
1356     LvTARG(TARG) = Nullsv;
1357     PUSHs(TARG);
1358     }
1359     RETURN;
1360     }
1361    
1362     keys = realhv ? hv : avhv_keys((AV*)hv);
1363     (void)hv_iterinit(keys); /* always reset iterator regardless */
1364    
1365     if (gimme == G_VOID)
1366     RETURN;
1367    
1368     if (gimme == G_SCALAR) {
1369     IV i;
1370     dTARGET;
1371    
1372     if (PL_op->op_flags & OPf_MOD || LVRET) { /* lvalue */
1373     if (SvTYPE(TARG) < SVt_PVLV) {
1374     sv_upgrade(TARG, SVt_PVLV);
1375     sv_magic(TARG, Nullsv, PERL_MAGIC_nkeys, Nullch, 0);
1376     }
1377     LvTYPE(TARG) = 'k';
1378     if (LvTARG(TARG) != (SV*)keys) {
1379     if (LvTARG(TARG))
1380     SvREFCNT_dec(LvTARG(TARG));
1381     LvTARG(TARG) = SvREFCNT_inc(keys);
1382     }
1383     PUSHs(TARG);
1384     RETURN;
1385     }
1386    
1387     if (! SvTIED_mg((SV*)keys, PERL_MAGIC_tied))
1388     i = HvKEYS(keys);
1389     else {
1390     i = 0;
1391     /*SUPPRESS 560*/
1392     while (hv_iternext(keys)) i++;
1393     }
1394     PUSHi( i );
1395     RETURN;
1396     }
1397    
1398     EXTEND(SP, HvKEYS(keys) * (dokeys + dovalues));
1399    
1400     PUTBACK; /* hv_iternext and hv_iterval might clobber stack_sp */
1401     while ((entry = hv_iternext(keys))) {
1402     SPAGAIN;
1403     if (dokeys) {
1404     SV* sv = hv_iterkeysv(entry);
1405     XPUSHs(sv); /* won't clobber stack_sp */
1406     }
1407     if (dovalues) {
1408     PUTBACK;
1409     tmpstr = realhv ?
1410     hv_iterval(hv,entry) : avhv_iterval((AV*)hv,entry);
1411     DEBUG_H(Perl_sv_setpvf(aTHX_ tmpstr, "%lu%%%d=%lu",
1412     (unsigned long)HeHASH(entry),
1413     HvMAX(keys)+1,
1414     (unsigned long)(HeHASH(entry) & HvMAX(keys))));
1415     SPAGAIN;
1416     XPUSHs(tmpstr);
1417     }
1418     PUTBACK;
1419     }
1420     return NORMAL;
1421     }
1422    
1423     /*
1424     * Local variables:
1425     * c-indentation-style: bsd
1426     * c-basic-offset: 4
1427     * indent-tabs-mode: t
1428     * End:
1429     *
1430     * vim: shiftwidth=4:
1431     */