skip integrate of problematic change#6251 from cfgperl into mainline
[p5sagit/p5-mst-13.2.git] / doop.c
CommitLineData
a0d0e21e 1/* doop.c
79072805 2 *
3818b22b 3 * Copyright (c) 1991-2000, Larry Wall
79072805 4 *
5 * You may distribute under the terms of either the GNU General Public
6 * License or the Artistic License, as specified in the README file.
7 *
a0d0e21e 8 */
9
10/*
11 * "'So that was the job I felt I had to do when I started,' thought Sam."
79072805 12 */
13
14#include "EXTERN.h"
864dbfa3 15#define PERL_IN_DOOP_C
79072805 16#include "perl.h"
17
64ca3a65 18#ifndef PERL_MICRO
79072805 19#if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX)
20#include <signal.h>
21#endif
64ca3a65 22#endif
79072805 23
942e002e 24STATIC I32
cea2e8a9 25S_do_trans_CC_simple(pTHX_ SV *sv)
79072805 26{
11343788 27 dTHR;
4757a243 28 U8 *s;
29 U8 *send;
30 I32 matches = 0;
463ee0b2 31 STRLEN len;
4757a243 32 short *tbl;
33 I32 ch;
79072805 34
4757a243 35 tbl = (short*)cPVOP->op_pv;
36 if (!tbl)
cea2e8a9 37 Perl_croak(aTHX_ "panic: do_trans");
a0ed51b3 38
4757a243 39 s = (U8*)SvPV(sv, len);
40 send = s + len;
41
42 while (s < send) {
43 if ((ch = tbl[*s]) >= 0) {
44 matches++;
45 *s = ch;
79072805 46 }
4757a243 47 s++;
48 }
49 SvSETMAGIC(sv);
50
51 return matches;
52}
53
942e002e 54STATIC I32
cea2e8a9 55S_do_trans_CC_count(pTHX_ SV *sv)
4757a243 56{
57 dTHR;
58 U8 *s;
59 U8 *send;
60 I32 matches = 0;
61 STRLEN len;
62 short *tbl;
63
64 tbl = (short*)cPVOP->op_pv;
65 if (!tbl)
cea2e8a9 66 Perl_croak(aTHX_ "panic: do_trans");
4757a243 67
68 s = (U8*)SvPV(sv, len);
69 send = s + len;
70
71 while (s < send) {
72 if (tbl[*s] >= 0)
73 matches++;
74 s++;
75 }
76
77 return matches;
78}
79
942e002e 80STATIC I32
cea2e8a9 81S_do_trans_CC_complex(pTHX_ SV *sv)
4757a243 82{
83 dTHR;
84 U8 *s;
85 U8 *send;
86 U8 *d;
87 I32 matches = 0;
88 STRLEN len;
89 short *tbl;
90 I32 ch;
91
92 tbl = (short*)cPVOP->op_pv;
93 if (!tbl)
cea2e8a9 94 Perl_croak(aTHX_ "panic: do_trans");
4757a243 95
96 s = (U8*)SvPV(sv, len);
97 send = s + len;
98
99 d = s;
100 if (PL_op->op_private & OPpTRANS_SQUASH) {
101 U8* p = send;
102
103 while (s < send) {
104 if ((ch = tbl[*s]) >= 0) {
105 *d = ch;
106 matches++;
107 if (p == d - 1 && *p == *d)
108 matches--;
a0ed51b3 109 else
4757a243 110 p = d++;
a0ed51b3 111 }
4757a243 112 else if (ch == -1) /* -1 is unmapped character */
113 *d++ = *s; /* -2 is delete character */
114 s++;
a0ed51b3 115 }
4757a243 116 }
117 else {
118 while (s < send) {
119 if ((ch = tbl[*s]) >= 0) {
120 *d = ch;
121 matches++;
122 d++;
a0ed51b3 123 }
4757a243 124 else if (ch == -1) /* -1 is unmapped character */
125 *d++ = *s; /* -2 is delete character */
126 s++;
5d06d08e 127 }
4757a243 128 }
129 matches += send - d; /* account for disappeared chars */
130 *d = '\0';
131 SvCUR_set(sv, d - (U8*)SvPVX(sv));
132 SvSETMAGIC(sv);
133
134 return matches;
135}
136
942e002e 137STATIC I32
cea2e8a9 138S_do_trans_UU_simple(pTHX_ SV *sv)
4757a243 139{
140 dTHR;
141 U8 *s;
142 U8 *send;
143 U8 *d;
144 I32 matches = 0;
145 STRLEN len;
146
147 SV* rv = (SV*)cSVOP->op_sv;
148 HV* hv = (HV*)SvRV(rv);
149 SV** svp = hv_fetch(hv, "NONE", 4, FALSE);
150 UV none = svp ? SvUV(*svp) : 0x7fffffff;
151 UV extra = none + 1;
152 UV final;
153 UV uv;
154
155 s = (U8*)SvPV(sv, len);
156 send = s + len;
157
158 svp = hv_fetch(hv, "FINAL", 5, FALSE);
159 if (svp)
160 final = SvUV(*svp);
161
162 d = s;
163 while (s < send) {
164 if ((uv = swash_fetch(rv, s)) < none) {
165 s += UTF8SKIP(s);
166 matches++;
167 d = uv_to_utf8(d, uv);
168 }
169 else if (uv == none) {
170 int i;
171 for (i = UTF8SKIP(s); i; i--)
172 *d++ = *s++;
173 }
174 else if (uv == extra) {
175 s += UTF8SKIP(s);
176 matches++;
177 d = uv_to_utf8(d, final);
178 }
179 else
180 s += UTF8SKIP(s);
181 }
182 *d = '\0';
183 SvCUR_set(sv, d - (U8*)SvPVX(sv));
184 SvSETMAGIC(sv);
185
186 return matches;
187}
188
942e002e 189STATIC I32
cea2e8a9 190S_do_trans_UU_count(pTHX_ SV *sv)
4757a243 191{
192 dTHR;
193 U8 *s;
194 U8 *send;
195 I32 matches = 0;
196 STRLEN len;
197
198 SV* rv = (SV*)cSVOP->op_sv;
199 HV* hv = (HV*)SvRV(rv);
200 SV** svp = hv_fetch(hv, "NONE", 4, FALSE);
201 UV none = svp ? SvUV(*svp) : 0x7fffffff;
202 UV uv;
203
204 s = (U8*)SvPV(sv, len);
205 send = s + len;
206
207 while (s < send) {
834a4ddd 208 if ((uv = swash_fetch(rv, s)) < none)
4757a243 209 matches++;
834a4ddd 210 s += UTF8SKIP(s);
4757a243 211 }
212
213 return matches;
214}
215
942e002e 216STATIC I32
cea2e8a9 217S_do_trans_UU_complex(pTHX_ SV *sv)
4757a243 218{
219 dTHR;
220 U8 *s;
221 U8 *send;
222 U8 *d;
223 I32 matches = 0;
224 I32 squash = PL_op->op_private & OPpTRANS_SQUASH;
225 I32 from_utf = PL_op->op_private & OPpTRANS_FROM_UTF;
226 I32 to_utf = PL_op->op_private & OPpTRANS_TO_UTF;
227 I32 del = PL_op->op_private & OPpTRANS_DELETE;
228 SV* rv = (SV*)cSVOP->op_sv;
229 HV* hv = (HV*)SvRV(rv);
230 SV** svp = hv_fetch(hv, "NONE", 4, FALSE);
231 UV none = svp ? SvUV(*svp) : 0x7fffffff;
232 UV extra = none + 1;
233 UV final;
234 UV uv;
235 STRLEN len;
236 U8 *dst;
237
238 s = (U8*)SvPV(sv, len);
239 send = s + len;
240
241 svp = hv_fetch(hv, "FINAL", 5, FALSE);
242 if (svp)
243 final = SvUV(*svp);
244
245 if (PL_op->op_private & OPpTRANS_GROWS) {
246 I32 bits = 16;
247
248 svp = hv_fetch(hv, "BITS", 4, FALSE);
249 if (svp)
250 bits = (I32)SvIV(*svp);
251
252 Newz(801, d, len * (bits >> 3) + 1, U8);
253 dst = d;
254 }
255 else {
256 d = s;
257 dst = 0;
258 }
259
260 if (squash) {
261 UV puv = 0xfeedface;
262 while (s < send) {
263 if (from_utf) {
264 uv = swash_fetch(rv, s);
a0ed51b3 265 }
266 else {
4757a243 267 U8 tmpbuf[2];
268 uv = *s++;
269 if (uv < 0x80)
270 tmpbuf[0] = uv;
271 else {
272 tmpbuf[0] = (( uv >> 6) | 0xc0);
273 tmpbuf[1] = (( uv & 0x3f) | 0x80);
274 }
275 uv = swash_fetch(rv, tmpbuf);
276 }
277 if (uv < none) {
278 matches++;
279 if (uv != puv) {
280 if (uv >= 0x80 && to_utf)
281 d = uv_to_utf8(d, uv);
282 else
283 *d++ = (U8)uv;
284 puv = uv;
285 }
286 if (from_utf)
287 s += UTF8SKIP(s);
288 continue;
289 }
290 else if (uv == none) { /* "none" is unmapped character */
291 if (from_utf) {
292 if (*s < 0x80)
293 *d++ = *s++;
294 else if (to_utf) {
a0ed51b3 295 int i;
4757a243 296 for (i = UTF8SKIP(s); i; --i)
297 *d++ = *s++;
a0ed51b3 298 }
4757a243 299 else {
300 I32 ulen;
301 *d++ = (U8)utf8_to_uv(s, &ulen);
302 s += ulen;
a0ed51b3 303 }
a0ed51b3 304 }
4757a243 305 else { /* must be to_utf only */
306 d = uv_to_utf8(d, s[-1]);
307 }
308 puv = 0xfeedface;
309 continue;
a0ed51b3 310 }
4757a243 311 else if (uv == extra && !del) {
312 matches++;
313 if (uv != puv) {
314 if (final >= 0x80 && to_utf)
315 d = uv_to_utf8(d, final);
316 else
317 *d++ = (U8)final;
318 puv = final;
319 }
320 if (from_utf)
321 s += UTF8SKIP(s);
322 continue;
323 }
324 matches++; /* "none+1" is delete character */
325 if (from_utf)
326 s += UTF8SKIP(s);
a0ed51b3 327 }
79072805 328 }
329 else {
4757a243 330 while (s < send) {
331 if (from_utf) {
332 uv = swash_fetch(rv, s);
333 }
334 else {
335 U8 tmpbuf[2];
336 uv = *s++;
337 if (uv < 0x80)
338 tmpbuf[0] = uv;
339 else {
340 tmpbuf[0] = (( uv >> 6) | 0xc0);
341 tmpbuf[1] = (( uv & 0x3f) | 0x80);
a0ed51b3 342 }
4757a243 343 uv = swash_fetch(rv, tmpbuf);
a0ed51b3 344 }
4757a243 345 if (uv < none) {
346 matches++;
347 if (uv >= 0x80 && to_utf)
348 d = uv_to_utf8(d, uv);
349 else
350 *d++ = (U8)uv;
351 if (from_utf)
352 s += UTF8SKIP(s);
353 continue;
a0ed51b3 354 }
4757a243 355 else if (uv == none) { /* "none" is unmapped character */
356 if (from_utf) {
357 if (*s < 0x80)
358 *d++ = *s++;
359 else if (to_utf) {
360 int i;
361 for (i = UTF8SKIP(s); i; --i)
362 *d++ = *s++;
363 }
364 else {
365 I32 ulen;
366 *d++ = (U8)utf8_to_uv(s, &ulen);
367 s += ulen;
a0ed51b3 368 }
79072805 369 }
4757a243 370 else { /* must be to_utf only */
371 d = uv_to_utf8(d, s[-1]);
372 }
373 continue;
79072805 374 }
4757a243 375 else if (uv == extra && !del) {
376 matches++;
377 if (final >= 0x80 && to_utf)
378 d = uv_to_utf8(d, final);
379 else
380 *d++ = (U8)final;
381 if (from_utf)
382 s += UTF8SKIP(s);
383 continue;
384 }
385 matches++; /* "none+1" is delete character */
386 if (from_utf)
387 s += UTF8SKIP(s);
79072805 388 }
4757a243 389 }
390 if (dst)
391 sv_usepvn(sv, (char*)dst, d - dst);
392 else {
393 *d = '\0';
394 SvCUR_set(sv, d - (U8*)SvPVX(sv));
395 }
396 SvSETMAGIC(sv);
397
398 return matches;
399}
400
401I32
864dbfa3 402Perl_do_trans(pTHX_ SV *sv)
4757a243 403{
46124e9e 404 dTHR;
4757a243 405 STRLEN len;
406
407 if (SvREADONLY(sv) && !(PL_op->op_private & OPpTRANS_IDENTICAL))
cea2e8a9 408 Perl_croak(aTHX_ PL_no_modify);
4757a243 409
410 (void)SvPV(sv, len);
411 if (!len)
412 return 0;
413 if (!SvPOKp(sv))
414 (void)SvPV_force(sv, len);
2de7b02f 415 if (!(PL_op->op_private & OPpTRANS_IDENTICAL))
416 (void)SvPOK_only_UTF8(sv);
4757a243 417
cea2e8a9 418 DEBUG_t( Perl_deb(aTHX_ "2.TBL\n"));
4757a243 419
420 switch (PL_op->op_private & 63) {
421 case 0:
6940069f 422 if (SvUTF8(sv))
423 return do_trans_UU_simple(sv);
424 else
425 return do_trans_CC_simple(sv);
4757a243 426
427 case OPpTRANS_IDENTICAL:
6940069f 428 if (SvUTF8(sv))
429 return do_trans_UU_count(sv);
430 else
431 return do_trans_CC_count(sv);
4757a243 432
433 default:
6940069f 434 if (SvUTF8(sv))
4757a243 435 return do_trans_UU_complex(sv); /* could be UC or CU too */
436 else
437 return do_trans_CC_complex(sv);
79072805 438 }
79072805 439}
440
441void
864dbfa3 442Perl_do_join(pTHX_ register SV *sv, SV *del, register SV **mark, register SV **sp)
79072805 443{
444 SV **oldmark = mark;
445 register I32 items = sp - mark;
79072805 446 register STRLEN len;
463ee0b2 447 STRLEN delimlen;
448 register char *delim = SvPV(del, delimlen);
449 STRLEN tmplen;
79072805 450
451 mark++;
452 len = (items > 0 ? (delimlen * (items - 1) ) : 0);
07f14f54 453 (void)SvUPGRADE(sv, SVt_PV);
79072805 454 if (SvLEN(sv) < len + items) { /* current length is way too short */
455 while (items-- > 0) {
48c036b1 456 if (*mark && !SvGMAGICAL(*mark) && SvOK(*mark)) {
463ee0b2 457 SvPV(*mark, tmplen);
458 len += tmplen;
79072805 459 }
460 mark++;
461 }
462 SvGROW(sv, len + 1); /* so try to pre-extend */
463
464 mark = oldmark;
db7c17d7 465 items = sp - mark;
79072805 466 ++mark;
467 }
468
463ee0b2 469 if (items-- > 0) {
8990e307 470 char *s;
471
92d29cee 472 sv_setpv(sv, "");
473 if (*mark)
474 sv_catsv(sv, *mark);
463ee0b2 475 mark++;
476 }
79072805 477 else
478 sv_setpv(sv,"");
479 len = delimlen;
480 if (len) {
481 for (; items > 0; items--,mark++) {
482 sv_catpvn(sv,delim,len);
483 sv_catsv(sv,*mark);
484 }
485 }
486 else {
487 for (; items > 0; items--,mark++)
488 sv_catsv(sv,*mark);
489 }
490 SvSETMAGIC(sv);
491}
492
493void
864dbfa3 494Perl_do_sprintf(pTHX_ SV *sv, I32 len, SV **sarg)
79072805 495{
46fc3d4c 496 STRLEN patlen;
497 char *pat = SvPV(*sarg, patlen);
498 bool do_taint = FALSE;
499
500 sv_vsetpvfn(sv, pat, patlen, Null(va_list*), sarg + 1, len - 1, &do_taint);
79072805 501 SvSETMAGIC(sv);
46fc3d4c 502 if (do_taint)
503 SvTAINTED_on(sv);
79072805 504}
505
4ebbc975 506/* XXX SvUTF8 support missing! */
81e118e0 507UV
508Perl_do_vecget(pTHX_ SV *sv, I32 offset, I32 size)
509{
510 STRLEN srclen, len;
511 unsigned char *s = (unsigned char *) SvPV(sv, srclen);
512 UV retnum = 0;
513
a50d7633 514 if (offset < 0)
81e118e0 515 return retnum;
a50d7633 516 if (size < 1 || (size & (size-1))) /* size < 1 or not a power of two */
517 Perl_croak(aTHX_ "Illegal number of bits in vec");
81e118e0 518 offset *= size; /* turn into bit offset */
519 len = (offset + size + 7) / 8; /* required number of bytes */
520 if (len > srclen) {
521 if (size <= 8)
522 retnum = 0;
523 else {
524 offset >>= 3; /* turn into byte offset */
525 if (size == 16) {
526 if (offset >= srclen)
527 retnum = 0;
528 else
628e1a40 529 retnum = (UV) s[offset] << 8;
81e118e0 530 }
531 else if (size == 32) {
532 if (offset >= srclen)
533 retnum = 0;
534 else if (offset + 1 >= srclen)
535 retnum =
536 ((UV) s[offset ] << 24);
537 else if (offset + 2 >= srclen)
538 retnum =
539 ((UV) s[offset ] << 24) +
540 ((UV) s[offset + 1] << 16);
541 else
542 retnum =
543 ((UV) s[offset ] << 24) +
544 ((UV) s[offset + 1] << 16) +
545 ( s[offset + 2] << 8);
546 }
d7d93a81 547#ifdef UV_IS_QUAD
c5a0f51a 548 else if (size == 64) {
549 dTHR;
550 if (ckWARN(WARN_PORTABLE))
551 Perl_warner(aTHX_ WARN_PORTABLE,
552 "Bit vector size > 32 non-portable");
553 if (offset >= srclen)
554 retnum = 0;
555 else if (offset + 1 >= srclen)
556 retnum =
557 (UV) s[offset ] << 56;
558 else if (offset + 2 >= srclen)
559 retnum =
560 ((UV) s[offset ] << 56) +
561 ((UV) s[offset + 1] << 48);
562 else if (offset + 3 >= srclen)
563 retnum =
564 ((UV) s[offset ] << 56) +
565 ((UV) s[offset + 1] << 48) +
566 ((UV) s[offset + 2] << 40);
567 else if (offset + 4 >= srclen)
568 retnum =
569 ((UV) s[offset ] << 56) +
570 ((UV) s[offset + 1] << 48) +
571 ((UV) s[offset + 2] << 40) +
572 ((UV) s[offset + 3] << 32);
573 else if (offset + 5 >= srclen)
574 retnum =
575 ((UV) s[offset ] << 56) +
576 ((UV) s[offset + 1] << 48) +
577 ((UV) s[offset + 2] << 40) +
578 ((UV) s[offset + 3] << 32) +
579 ( s[offset + 4] << 24);
580 else if (offset + 6 >= srclen)
581 retnum =
582 ((UV) s[offset ] << 56) +
583 ((UV) s[offset + 1] << 48) +
584 ((UV) s[offset + 2] << 40) +
585 ((UV) s[offset + 3] << 32) +
586 ((UV) s[offset + 4] << 24) +
587 ((UV) s[offset + 5] << 16);
588 else
589 retnum =
590 ((UV) s[offset ] << 56) +
591 ((UV) s[offset + 1] << 48) +
592 ((UV) s[offset + 2] << 40) +
593 ((UV) s[offset + 3] << 32) +
594 ((UV) s[offset + 4] << 24) +
595 ((UV) s[offset + 5] << 16) +
628e1a40 596 ( s[offset + 6] << 8);
c5a0f51a 597 }
598#endif
81e118e0 599 }
600 }
601 else if (size < 8)
602 retnum = (s[offset >> 3] >> (offset & 7)) & ((1 << size) - 1);
603 else {
604 offset >>= 3; /* turn into byte offset */
605 if (size == 8)
606 retnum = s[offset];
607 else if (size == 16)
608 retnum =
628e1a40 609 ((UV) s[offset] << 8) +
81e118e0 610 s[offset + 1];
611 else if (size == 32)
612 retnum =
613 ((UV) s[offset ] << 24) +
614 ((UV) s[offset + 1] << 16) +
615 ( s[offset + 2] << 8) +
616 s[offset + 3];
d7d93a81 617#ifdef UV_IS_QUAD
c5a0f51a 618 else if (size == 64) {
619 dTHR;
620 if (ckWARN(WARN_PORTABLE))
621 Perl_warner(aTHX_ WARN_PORTABLE,
622 "Bit vector size > 32 non-portable");
623 retnum =
624 ((UV) s[offset ] << 56) +
625 ((UV) s[offset + 1] << 48) +
626 ((UV) s[offset + 2] << 40) +
627 ((UV) s[offset + 3] << 32) +
628 ((UV) s[offset + 4] << 24) +
629 ((UV) s[offset + 5] << 16) +
628e1a40 630 ( s[offset + 6] << 8) +
c5a0f51a 631 s[offset + 7];
632 }
633#endif
81e118e0 634 }
635
636 return retnum;
637}
638
4ebbc975 639/* XXX SvUTF8 support missing! */
79072805 640void
864dbfa3 641Perl_do_vecset(pTHX_ SV *sv)
79072805 642{
643 SV *targ = LvTARG(sv);
644 register I32 offset;
645 register I32 size;
8990e307 646 register unsigned char *s;
81e118e0 647 register UV lval;
79072805 648 I32 mask;
a0d0e21e 649 STRLEN targlen;
650 STRLEN len;
79072805 651
8990e307 652 if (!targ)
653 return;
a0d0e21e 654 s = (unsigned char*)SvPV_force(targ, targlen);
4ebbc975 655 (void)SvPOK_only(targ);
81e118e0 656 lval = SvUV(sv);
79072805 657 offset = LvTARGOFF(sv);
658 size = LvTARGLEN(sv);
a50d7633 659 if (size < 1 || (size & (size-1))) /* size < 1 or not a power of two */
660 Perl_croak(aTHX_ "Illegal number of bits in vec");
a0d0e21e 661
81e118e0 662 offset *= size; /* turn into bit offset */
663 len = (offset + size + 7) / 8; /* required number of bytes */
a0d0e21e 664 if (len > targlen) {
665 s = (unsigned char*)SvGROW(targ, len + 1);
12ae5dfc 666 (void)memzero((char *)(s + targlen), len - targlen + 1);
a0d0e21e 667 SvCUR_set(targ, len);
668 }
669
79072805 670 if (size < 8) {
671 mask = (1 << size) - 1;
672 size = offset & 7;
673 lval &= mask;
81e118e0 674 offset >>= 3; /* turn into byte offset */
79072805 675 s[offset] &= ~(mask << size);
676 s[offset] |= lval << size;
677 }
678 else {
81e118e0 679 offset >>= 3; /* turn into byte offset */
79072805 680 if (size == 8)
c5a0f51a 681 s[offset ] = lval & 0xff;
79072805 682 else if (size == 16) {
c5a0f51a 683 s[offset ] = (lval >> 8) & 0xff;
684 s[offset+1] = lval & 0xff;
79072805 685 }
686 else if (size == 32) {
c5a0f51a 687 s[offset ] = (lval >> 24) & 0xff;
688 s[offset+1] = (lval >> 16) & 0xff;
689 s[offset+2] = (lval >> 8) & 0xff;
690 s[offset+3] = lval & 0xff;
691 }
d7d93a81 692#ifdef UV_IS_QUAD
c5a0f51a 693 else if (size == 64) {
694 dTHR;
695 if (ckWARN(WARN_PORTABLE))
696 Perl_warner(aTHX_ WARN_PORTABLE,
697 "Bit vector size > 32 non-portable");
698 s[offset ] = (lval >> 56) & 0xff;
699 s[offset+1] = (lval >> 48) & 0xff;
700 s[offset+2] = (lval >> 40) & 0xff;
701 s[offset+3] = (lval >> 32) & 0xff;
702 s[offset+4] = (lval >> 24) & 0xff;
703 s[offset+5] = (lval >> 16) & 0xff;
704 s[offset+6] = (lval >> 8) & 0xff;
705 s[offset+7] = lval & 0xff;
79072805 706 }
dc1e3f56 707#endif
79072805 708 }
7bb043c3 709 SvSETMAGIC(targ);
79072805 710}
711
712void
864dbfa3 713Perl_do_chop(pTHX_ register SV *astr, register SV *sv)
79072805 714{
463ee0b2 715 STRLEN len;
a0d0e21e 716 char *s;
c485e607 717 dTHR;
a0d0e21e 718
79072805 719 if (SvTYPE(sv) == SVt_PVAV) {
a0d0e21e 720 register I32 i;
721 I32 max;
722 AV* av = (AV*)sv;
723 max = AvFILL(av);
724 for (i = 0; i <= max; i++) {
725 sv = (SV*)av_fetch(av, i, FALSE);
3280af22 726 if (sv && ((sv = *(SV**)sv), sv != &PL_sv_undef))
a0d0e21e 727 do_chop(astr, sv);
728 }
729 return;
79072805 730 }
aa854799 731 else if (SvTYPE(sv) == SVt_PVHV) {
a0d0e21e 732 HV* hv = (HV*)sv;
733 HE* entry;
734 (void)hv_iterinit(hv);
735 /*SUPPRESS 560*/
155aba94 736 while ((entry = hv_iternext(hv)))
a0d0e21e 737 do_chop(astr,hv_iterval(hv,entry));
738 return;
79072805 739 }
aa854799 740 else if (SvREADONLY(sv))
cea2e8a9 741 Perl_croak(aTHX_ PL_no_modify);
a0d0e21e 742 s = SvPV(sv, len);
748a9306 743 if (len && !SvPOK(sv))
a0d0e21e 744 s = SvPV_force(sv, len);
7e2040f0 745 if (DO_UTF8(sv)) {
a0ed51b3 746 if (s && len) {
747 char *send = s + len;
748 char *start = s;
749 s = send - 1;
750 while ((*s & 0xc0) == 0x80)
751 --s;
0453d815 752 if (UTF8SKIP(s) != send - s && ckWARN_d(WARN_UTF8))
753 Perl_warner(aTHX_ WARN_UTF8, "Malformed UTF-8 character");
a0ed51b3 754 sv_setpvn(astr, s, send - s);
755 *s = '\0';
756 SvCUR_set(sv, s - start);
757 SvNIOK_off(sv);
7e2040f0 758 SvUTF8_on(astr);
a0ed51b3 759 }
760 else
761 sv_setpvn(astr, "", 0);
762 }
7e2040f0 763 else if (s && len) {
a0d0e21e 764 s += --len;
765 sv_setpvn(astr, s, 1);
766 *s = '\0';
767 SvCUR_set(sv, len);
2c19a612 768 SvUTF8_off(sv);
a0d0e21e 769 SvNIOK_off(sv);
79072805 770 }
771 else
a0d0e21e 772 sv_setpvn(astr, "", 0);
773 SvSETMAGIC(sv);
7e2040f0 774}
a0d0e21e 775
776I32
864dbfa3 777Perl_do_chomp(pTHX_ register SV *sv)
a0d0e21e 778{
aeea060c 779 dTHR;
c07a80fd 780 register I32 count;
a0d0e21e 781 STRLEN len;
782 char *s;
c07a80fd 783
3280af22 784 if (RsSNARF(PL_rs))
c07a80fd 785 return 0;
4c5a6083 786 if (RsRECORD(PL_rs))
787 return 0;
c07a80fd 788 count = 0;
a0d0e21e 789 if (SvTYPE(sv) == SVt_PVAV) {
790 register I32 i;
791 I32 max;
792 AV* av = (AV*)sv;
793 max = AvFILL(av);
794 for (i = 0; i <= max; i++) {
795 sv = (SV*)av_fetch(av, i, FALSE);
3280af22 796 if (sv && ((sv = *(SV**)sv), sv != &PL_sv_undef))
a0d0e21e 797 count += do_chomp(sv);
798 }
799 return count;
800 }
aa854799 801 else if (SvTYPE(sv) == SVt_PVHV) {
a0d0e21e 802 HV* hv = (HV*)sv;
803 HE* entry;
804 (void)hv_iterinit(hv);
805 /*SUPPRESS 560*/
155aba94 806 while ((entry = hv_iternext(hv)))
a0d0e21e 807 count += do_chomp(hv_iterval(hv,entry));
808 return count;
809 }
aa854799 810 else if (SvREADONLY(sv))
cea2e8a9 811 Perl_croak(aTHX_ PL_no_modify);
a0d0e21e 812 s = SvPV(sv, len);
813 if (len && !SvPOKp(sv))
814 s = SvPV_force(sv, len);
815 if (s && len) {
816 s += --len;
3280af22 817 if (RsPARA(PL_rs)) {
a0d0e21e 818 if (*s != '\n')
819 goto nope;
820 ++count;
821 while (len && s[-1] == '\n') {
822 --len;
823 --s;
824 ++count;
825 }
826 }
a0d0e21e 827 else {
c07a80fd 828 STRLEN rslen;
3280af22 829 char *rsptr = SvPV(PL_rs, rslen);
c07a80fd 830 if (rslen == 1) {
831 if (*s != *rsptr)
832 goto nope;
833 ++count;
834 }
835 else {
8c2cee6f 836 if (len < rslen - 1)
c07a80fd 837 goto nope;
838 len -= rslen - 1;
839 s -= rslen - 1;
36477c24 840 if (memNE(s, rsptr, rslen))
c07a80fd 841 goto nope;
842 count += rslen;
843 }
a0d0e21e 844 }
a0d0e21e 845 *s = '\0';
846 SvCUR_set(sv, len);
847 SvNIOK_off(sv);
848 }
849 nope:
850 SvSETMAGIC(sv);
851 return count;
852}
79072805 853
854void
864dbfa3 855Perl_do_vop(pTHX_ I32 optype, SV *sv, SV *left, SV *right)
79072805 856{
aeea060c 857 dTHR; /* just for taint */
79072805 858#ifdef LIBERAL
859 register long *dl;
860 register long *ll;
861 register long *rl;
862#endif
863 register char *dc;
463ee0b2 864 STRLEN leftlen;
865 STRLEN rightlen;
7a4c00b4 866 register char *lc;
867 register char *rc;
79072805 868 register I32 len;
a0d0e21e 869 I32 lensave;
7a4c00b4 870 char *lsave;
871 char *rsave;
0c57e439 872 bool left_utf = DO_UTF8(left);
873 bool right_utf = DO_UTF8(right);
874
875 if (left_utf && !right_utf)
876 sv_utf8_upgrade(right);
877 if (!left_utf && right_utf)
878 sv_utf8_upgrade(left);
79072805 879
1fbd88dc 880 if (sv != left || (optype != OP_BIT_AND && !SvOK(sv) && !SvGMAGICAL(sv)))
881 sv_setpvn(sv, "", 0); /* avoid undef warning on |= and ^= */
7a4c00b4 882 lsave = lc = SvPV(left, leftlen);
883 rsave = rc = SvPV(right, rightlen);
93a17b20 884 len = leftlen < rightlen ? leftlen : rightlen;
a0d0e21e 885 lensave = len;
7a4c00b4 886 if (SvOK(sv) || SvTYPE(sv) > SVt_PVMG) {
2d8e6c8d 887 STRLEN n_a;
888 dc = SvPV_force(sv, n_a);
ff68c719 889 if (SvCUR(sv) < len) {
890 dc = SvGROW(sv, len + 1);
891 (void)memzero(dc + SvCUR(sv), len - SvCUR(sv) + 1);
892 }
893 }
894 else {
895 I32 needlen = ((optype == OP_BIT_AND)
896 ? len : (leftlen > rightlen ? leftlen : rightlen));
897 Newz(801, dc, needlen + 1, char);
898 (void)sv_usepvn(sv, dc, needlen);
899 dc = SvPVX(sv); /* sv_usepvn() calls Renew() */
79072805 900 }
a0d0e21e 901 SvCUR_set(sv, len);
902 (void)SvPOK_only(sv);
0c57e439 903 if (left_utf || right_utf) {
904 UV duc, luc, ruc;
905 STRLEN lulen = leftlen;
906 STRLEN rulen = rightlen;
907 STRLEN dulen = 0;
908 I32 ulen;
909
6b7c0e6e 910 if (optype != OP_BIT_AND)
911 dc = SvGROW(sv, leftlen+rightlen+1);
912
0c57e439 913 switch (optype) {
914 case OP_BIT_AND:
915 while (lulen && rulen) {
916 luc = utf8_to_uv((U8*)lc, &ulen);
917 lc += ulen;
918 lulen -= ulen;
919 ruc = utf8_to_uv((U8*)rc, &ulen);
920 rc += ulen;
921 rulen -= ulen;
922 duc = luc & ruc;
923 dc = (char*)uv_to_utf8((U8*)dc, duc);
924 }
925 dulen = dc - SvPVX(sv);
926 SvCUR_set(sv, dulen);
927 break;
928 case OP_BIT_XOR:
929 while (lulen && rulen) {
930 luc = utf8_to_uv((U8*)lc, &ulen);
931 lc += ulen;
932 lulen -= ulen;
933 ruc = utf8_to_uv((U8*)rc, &ulen);
934 rc += ulen;
935 rulen -= ulen;
936 duc = luc ^ ruc;
937 dc = (char*)uv_to_utf8((U8*)dc, duc);
938 }
939 goto mop_up_utf;
940 case OP_BIT_OR:
941 while (lulen && rulen) {
942 luc = utf8_to_uv((U8*)lc, &ulen);
943 lc += ulen;
944 lulen -= ulen;
945 ruc = utf8_to_uv((U8*)rc, &ulen);
946 rc += ulen;
947 rulen -= ulen;
948 duc = luc | ruc;
949 dc = (char*)uv_to_utf8((U8*)dc, duc);
950 }
951 mop_up_utf:
952 dulen = dc - SvPVX(sv);
953 SvCUR_set(sv, dulen);
954 if (rulen)
955 sv_catpvn(sv, rc, rulen);
956 else if (lulen)
957 sv_catpvn(sv, lc, lulen);
958 else
959 *SvEND(sv) = '\0';
960 break;
961 }
962 SvUTF8_on(sv);
963 goto finish;
964 }
965 else
79072805 966#ifdef LIBERAL
967 if (len >= sizeof(long)*4 &&
968 !((long)dc % sizeof(long)) &&
969 !((long)lc % sizeof(long)) &&
970 !((long)rc % sizeof(long))) /* It's almost always aligned... */
971 {
972 I32 remainder = len % (sizeof(long)*4);
973 len /= (sizeof(long)*4);
974
975 dl = (long*)dc;
976 ll = (long*)lc;
977 rl = (long*)rc;
978
979 switch (optype) {
980 case OP_BIT_AND:
981 while (len--) {
982 *dl++ = *ll++ & *rl++;
983 *dl++ = *ll++ & *rl++;
984 *dl++ = *ll++ & *rl++;
985 *dl++ = *ll++ & *rl++;
986 }
987 break;
a0d0e21e 988 case OP_BIT_XOR:
79072805 989 while (len--) {
990 *dl++ = *ll++ ^ *rl++;
991 *dl++ = *ll++ ^ *rl++;
992 *dl++ = *ll++ ^ *rl++;
993 *dl++ = *ll++ ^ *rl++;
994 }
995 break;
996 case OP_BIT_OR:
997 while (len--) {
998 *dl++ = *ll++ | *rl++;
999 *dl++ = *ll++ | *rl++;
1000 *dl++ = *ll++ | *rl++;
1001 *dl++ = *ll++ | *rl++;
1002 }
1003 }
1004
1005 dc = (char*)dl;
1006 lc = (char*)ll;
1007 rc = (char*)rl;
1008
1009 len = remainder;
1010 }
1011#endif
a0d0e21e 1012 {
a0d0e21e 1013 switch (optype) {
1014 case OP_BIT_AND:
1015 while (len--)
1016 *dc++ = *lc++ & *rc++;
1017 break;
1018 case OP_BIT_XOR:
1019 while (len--)
1020 *dc++ = *lc++ ^ *rc++;
1021 goto mop_up;
1022 case OP_BIT_OR:
1023 while (len--)
1024 *dc++ = *lc++ | *rc++;
1025 mop_up:
1026 len = lensave;
1027 if (rightlen > len)
1028 sv_catpvn(sv, rsave + len, rightlen - len);
1029 else if (leftlen > len)
1030 sv_catpvn(sv, lsave + len, leftlen - len);
4633a7c4 1031 else
1032 *SvEND(sv) = '\0';
a0d0e21e 1033 break;
1034 }
79072805 1035 }
0c57e439 1036finish:
fb73857a 1037 SvTAINT(sv);
79072805 1038}
463ee0b2 1039
1040OP *
cea2e8a9 1041Perl_do_kv(pTHX)
463ee0b2 1042{
4e35701f 1043 djSP;
463ee0b2 1044 HV *hv = (HV*)POPs;
800e9ae0 1045 HV *keys;
463ee0b2 1046 register HE *entry;
463ee0b2 1047 SV *tmpstr;
54310121 1048 I32 gimme = GIMME_V;
533c011a 1049 I32 dokeys = (PL_op->op_type == OP_KEYS);
1050 I32 dovalues = (PL_op->op_type == OP_VALUES);
c750a3ec 1051 I32 realhv = (SvTYPE(hv) == SVt_PVHV);
1052
533c011a 1053 if (PL_op->op_type == OP_RV2HV || PL_op->op_type == OP_PADHV)
a0d0e21e 1054 dokeys = dovalues = TRUE;
463ee0b2 1055
85581909 1056 if (!hv) {
533c011a 1057 if (PL_op->op_flags & OPf_MOD) { /* lvalue */
85581909 1058 dTARGET; /* make sure to clear its target here */
1059 if (SvTYPE(TARG) == SVt_PVLV)
1060 LvTARG(TARG) = Nullsv;
1061 PUSHs(TARG);
1062 }
463ee0b2 1063 RETURN;
85581909 1064 }
748a9306 1065
800e9ae0 1066 keys = realhv ? hv : avhv_keys((AV*)hv);
1067 (void)hv_iterinit(keys); /* always reset iterator regardless */
748a9306 1068
54310121 1069 if (gimme == G_VOID)
aa689395 1070 RETURN;
1071
54310121 1072 if (gimme == G_SCALAR) {
6ee623d5 1073 IV i;
463ee0b2 1074 dTARGET;
1075
533c011a 1076 if (PL_op->op_flags & OPf_MOD) { /* lvalue */
85581909 1077 if (SvTYPE(TARG) < SVt_PVLV) {
1078 sv_upgrade(TARG, SVt_PVLV);
1079 sv_magic(TARG, Nullsv, 'k', Nullch, 0);
1080 }
1081 LvTYPE(TARG) = 'k';
800e9ae0 1082 if (LvTARG(TARG) != (SV*)keys) {
6ff81951 1083 if (LvTARG(TARG))
1084 SvREFCNT_dec(LvTARG(TARG));
800e9ae0 1085 LvTARG(TARG) = SvREFCNT_inc(keys);
6ff81951 1086 }
85581909 1087 PUSHs(TARG);
1088 RETURN;
1089 }
1090
33c27489 1091 if (! SvTIED_mg((SV*)keys, 'P'))
800e9ae0 1092 i = HvKEYS(keys);
463ee0b2 1093 else {
1094 i = 0;
463ee0b2 1095 /*SUPPRESS 560*/
800e9ae0 1096 while (hv_iternext(keys)) i++;
463ee0b2 1097 }
1098 PUSHi( i );
1099 RETURN;
1100 }
1101
8ed4b672 1102 EXTEND(SP, HvKEYS(keys) * (dokeys + dovalues));
463ee0b2 1103
463ee0b2 1104 PUTBACK; /* hv_iternext and hv_iterval might clobber stack_sp */
155aba94 1105 while ((entry = hv_iternext(keys))) {
463ee0b2 1106 SPAGAIN;
8c2cee6f 1107 if (dokeys)
1108 XPUSHs(hv_iterkeysv(entry)); /* won't clobber stack_sp */
463ee0b2 1109 if (dovalues) {
463ee0b2 1110 PUTBACK;
b6429b1b 1111 tmpstr = realhv ?
1112 hv_iterval(hv,entry) : avhv_iterval((AV*)hv,entry);
cea2e8a9 1113 DEBUG_H(Perl_sv_setpvf(aTHX_ tmpstr, "%lu%%%d=%lu",
46fc3d4c 1114 (unsigned long)HeHASH(entry),
800e9ae0 1115 HvMAX(keys)+1,
1116 (unsigned long)(HeHASH(entry) & HvMAX(keys))));
463ee0b2 1117 SPAGAIN;
46fc3d4c 1118 XPUSHs(tmpstr);
463ee0b2 1119 }
1120 PUTBACK;
1121 }
1122 return NORMAL;
1123}
4e35701f 1124