This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Remove xcv_condp CV field which is no longer used.
[perl5.git] / doop.c
1 /*    doop.c
2  *
3  *    Copyright (c) 1991-1997, Larry Wall
4  *
5  *    You may distribute under the terms of either the GNU General Public
6  *    License or the Artistic License, as specified in the README file.
7  *
8  */
9
10 /*
11  * "'So that was the job I felt I had to do when I started,' thought Sam."
12  */
13
14 #include "EXTERN.h"
15 #include "perl.h"
16
17 #if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX)
18 #include <signal.h>
19 #endif
20
21 I32
22 do_trans(sv,arg)
23 SV *sv;
24 OP *arg;
25 {
26     dTHR;
27     register short *tbl;
28     register U8 *s;
29     register U8 *send;
30     register U8 *d;
31     register I32 ch;
32     register I32 matches = 0;
33     register I32 squash = op->op_private & OPpTRANS_SQUASH;
34     STRLEN len;
35
36     if (SvREADONLY(sv))
37         croak(no_modify);
38     tbl = (short*)cPVOP->op_pv;
39     s = (U8*)SvPV(sv, len);
40     if (!len)
41         return 0;
42     if (!SvPOKp(sv))
43         s = (U8*)SvPV_force(sv, len);
44     (void)SvPOK_only(sv);
45     send = s + len;
46     if (!tbl || !s)
47         croak("panic: do_trans");
48     DEBUG_t( deb("2.TBL\n"));
49     if (!op->op_private) {
50         while (s < send) {
51             if ((ch = tbl[*s]) >= 0) {
52                 matches++;
53                 *s = ch;
54             }
55             s++;
56         }
57     }
58     else {
59         d = s;
60         while (s < send) {
61             if ((ch = tbl[*s]) >= 0) {
62                 *d = ch;
63                 if (matches++ && squash) {
64                     if (d[-1] == *d)
65                         matches--;
66                     else
67                         d++;
68                 }
69                 else
70                     d++;
71             }
72             else if (ch == -1)          /* -1 is unmapped character */
73                 *d++ = *s;              /* -2 is delete character */
74             s++;
75         }
76         matches += send - d;    /* account for disappeared chars */
77         *d = '\0';
78         SvCUR_set(sv, d - (U8*)SvPVX(sv));
79     }
80     SvSETMAGIC(sv);
81     return matches;
82 }
83
84 void
85 do_join(sv,del,mark,sp)
86 register SV *sv;
87 SV *del;
88 register SV **mark;
89 register SV **sp;
90 {
91     SV **oldmark = mark;
92     register I32 items = sp - mark;
93     register STRLEN len;
94     STRLEN delimlen;
95     register char *delim = SvPV(del, delimlen);
96     STRLEN tmplen;
97
98     mark++;
99     len = (items > 0 ? (delimlen * (items - 1) ) : 0);
100     if (SvTYPE(sv) < SVt_PV)
101         sv_upgrade(sv, SVt_PV);
102     if (SvLEN(sv) < len + items) {      /* current length is way too short */
103         while (items-- > 0) {
104             if (*mark) {
105                 SvPV(*mark, tmplen);
106                 len += tmplen;
107             }
108             mark++;
109         }
110         SvGROW(sv, len + 1);            /* so try to pre-extend */
111
112         mark = oldmark;
113         items = sp - mark;;
114         ++mark;
115     }
116
117     if (items-- > 0) {
118         char *s;
119
120         if (*mark) {
121             s = SvPV(*mark, tmplen);
122             sv_setpvn(sv, s, tmplen);
123         }
124         else
125             sv_setpv(sv, "");
126         mark++;
127     }
128     else
129         sv_setpv(sv,"");
130     len = delimlen;
131     if (len) {
132         for (; items > 0; items--,mark++) {
133             sv_catpvn(sv,delim,len);
134             sv_catsv(sv,*mark);
135         }
136     }
137     else {
138         for (; items > 0; items--,mark++)
139             sv_catsv(sv,*mark);
140     }
141     SvSETMAGIC(sv);
142 }
143
144 void
145 do_sprintf(sv,len,sarg)
146 SV *sv;
147 I32 len;
148 SV **sarg;
149 {
150     STRLEN patlen;
151     char *pat = SvPV(*sarg, patlen);
152     bool do_taint = FALSE;
153
154     sv_vsetpvfn(sv, pat, patlen, Null(va_list*), sarg + 1, len - 1, &do_taint);
155     SvSETMAGIC(sv);
156     if (do_taint)
157         SvTAINTED_on(sv);
158 }
159
160 void
161 do_vecset(sv)
162 SV *sv;
163 {
164     SV *targ = LvTARG(sv);
165     register I32 offset;
166     register I32 size;
167     register unsigned char *s;
168     register unsigned long lval;
169     I32 mask;
170     STRLEN targlen;
171     STRLEN len;
172
173     if (!targ)
174         return;
175     s = (unsigned char*)SvPV_force(targ, targlen);
176     lval = U_L(SvNV(sv));
177     offset = LvTARGOFF(sv);
178     size = LvTARGLEN(sv);
179     
180     len = (offset + size + 7) / 8;
181     if (len > targlen) {
182         s = (unsigned char*)SvGROW(targ, len + 1);
183         (void)memzero(s + targlen, len - targlen + 1);
184         SvCUR_set(targ, len);
185     }
186     
187     if (size < 8) {
188         mask = (1 << size) - 1;
189         size = offset & 7;
190         lval &= mask;
191         offset >>= 3;
192         s[offset] &= ~(mask << size);
193         s[offset] |= lval << size;
194     }
195     else {
196         offset >>= 3;
197         if (size == 8)
198             s[offset] = lval & 255;
199         else if (size == 16) {
200             s[offset] = (lval >> 8) & 255;
201             s[offset+1] = lval & 255;
202         }
203         else if (size == 32) {
204             s[offset] = (lval >> 24) & 255;
205             s[offset+1] = (lval >> 16) & 255;
206             s[offset+2] = (lval >> 8) & 255;
207             s[offset+3] = lval & 255;
208         }
209     }
210 }
211
212 void
213 do_chop(astr,sv)
214 register SV *astr;
215 register SV *sv;
216 {
217     STRLEN len;
218     char *s;
219     
220     if (SvTYPE(sv) == SVt_PVAV) {
221         register I32 i;
222         I32 max;
223         AV* av = (AV*)sv;
224         max = AvFILL(av);
225         for (i = 0; i <= max; i++) {
226             sv = (SV*)av_fetch(av, i, FALSE);
227             if (sv && ((sv = *(SV**)sv), sv != &sv_undef))
228                 do_chop(astr, sv);
229         }
230         return;
231     }
232     if (SvTYPE(sv) == SVt_PVHV) {
233         HV* hv = (HV*)sv;
234         HE* entry;
235         (void)hv_iterinit(hv);
236         /*SUPPRESS 560*/
237         while (entry = hv_iternext(hv))
238             do_chop(astr,hv_iterval(hv,entry));
239         return;
240     }
241     s = SvPV(sv, len);
242     if (len && !SvPOK(sv))
243         s = SvPV_force(sv, len);
244     if (s && len) {
245         s += --len;
246         sv_setpvn(astr, s, 1);
247         *s = '\0';
248         SvCUR_set(sv, len);
249         SvNIOK_off(sv);
250     }
251     else
252         sv_setpvn(astr, "", 0);
253     SvSETMAGIC(sv);
254
255
256 I32
257 do_chomp(sv)
258 register SV *sv;
259 {
260     register I32 count;
261     STRLEN len;
262     char *s;
263
264     if (RsSNARF(rs))
265         return 0;
266     count = 0;
267     if (SvTYPE(sv) == SVt_PVAV) {
268         register I32 i;
269         I32 max;
270         AV* av = (AV*)sv;
271         max = AvFILL(av);
272         for (i = 0; i <= max; i++) {
273             sv = (SV*)av_fetch(av, i, FALSE);
274             if (sv && ((sv = *(SV**)sv), sv != &sv_undef))
275                 count += do_chomp(sv);
276         }
277         return count;
278     }
279     if (SvTYPE(sv) == SVt_PVHV) {
280         HV* hv = (HV*)sv;
281         HE* entry;
282         (void)hv_iterinit(hv);
283         /*SUPPRESS 560*/
284         while (entry = hv_iternext(hv))
285             count += do_chomp(hv_iterval(hv,entry));
286         return count;
287     }
288     s = SvPV(sv, len);
289     if (len && !SvPOKp(sv))
290         s = SvPV_force(sv, len);
291     if (s && len) {
292         s += --len;
293         if (RsPARA(rs)) {
294             if (*s != '\n')
295                 goto nope;
296             ++count;
297             while (len && s[-1] == '\n') {
298                 --len;
299                 --s;
300                 ++count;
301             }
302         }
303         else {
304             STRLEN rslen;
305             char *rsptr = SvPV(rs, rslen);
306             if (rslen == 1) {
307                 if (*s != *rsptr)
308                     goto nope;
309                 ++count;
310             }
311             else {
312                 if (len < rslen - 1)
313                     goto nope;
314                 len -= rslen - 1;
315                 s -= rslen - 1;
316                 if (memNE(s, rsptr, rslen))
317                     goto nope;
318                 count += rslen;
319             }
320         }
321         *s = '\0';
322         SvCUR_set(sv, len);
323         SvNIOK_off(sv);
324     }
325   nope:
326     SvSETMAGIC(sv);
327     return count;
328
329
330 void
331 do_vop(optype,sv,left,right)
332 I32 optype;
333 SV *sv;
334 SV *left;
335 SV *right;
336 {
337 #ifdef LIBERAL
338     register long *dl;
339     register long *ll;
340     register long *rl;
341 #endif
342     register char *dc;
343     STRLEN leftlen;
344     STRLEN rightlen;
345     register char *lc;
346     register char *rc;
347     register I32 len;
348     I32 lensave;
349     char *lsave;
350     char *rsave;
351
352     if (sv != left || (optype != OP_BIT_AND && !SvOK(sv) && !SvGMAGICAL(sv)))
353         sv_setpvn(sv, "", 0);   /* avoid undef warning on |= and ^= */
354     lsave = lc = SvPV(left, leftlen);
355     rsave = rc = SvPV(right, rightlen);
356     len = leftlen < rightlen ? leftlen : rightlen;
357     lensave = len;
358     if (SvOK(sv) || SvTYPE(sv) > SVt_PVMG) {
359         dc = SvPV_force(sv, na);
360         if (SvCUR(sv) < len) {
361             dc = SvGROW(sv, len + 1);
362             (void)memzero(dc + SvCUR(sv), len - SvCUR(sv) + 1);
363         }
364     }
365     else {
366         I32 needlen = ((optype == OP_BIT_AND)
367                         ? len : (leftlen > rightlen ? leftlen : rightlen));
368         Newz(801, dc, needlen + 1, char);
369         (void)sv_usepvn(sv, dc, needlen);
370         dc = SvPVX(sv);         /* sv_usepvn() calls Renew() */
371     }
372     SvCUR_set(sv, len);
373     (void)SvPOK_only(sv);
374 #ifdef LIBERAL
375     if (len >= sizeof(long)*4 &&
376         !((long)dc % sizeof(long)) &&
377         !((long)lc % sizeof(long)) &&
378         !((long)rc % sizeof(long)))     /* It's almost always aligned... */
379     {
380         I32 remainder = len % (sizeof(long)*4);
381         len /= (sizeof(long)*4);
382
383         dl = (long*)dc;
384         ll = (long*)lc;
385         rl = (long*)rc;
386
387         switch (optype) {
388         case OP_BIT_AND:
389             while (len--) {
390                 *dl++ = *ll++ & *rl++;
391                 *dl++ = *ll++ & *rl++;
392                 *dl++ = *ll++ & *rl++;
393                 *dl++ = *ll++ & *rl++;
394             }
395             break;
396         case OP_BIT_XOR:
397             while (len--) {
398                 *dl++ = *ll++ ^ *rl++;
399                 *dl++ = *ll++ ^ *rl++;
400                 *dl++ = *ll++ ^ *rl++;
401                 *dl++ = *ll++ ^ *rl++;
402             }
403             break;
404         case OP_BIT_OR:
405             while (len--) {
406                 *dl++ = *ll++ | *rl++;
407                 *dl++ = *ll++ | *rl++;
408                 *dl++ = *ll++ | *rl++;
409                 *dl++ = *ll++ | *rl++;
410             }
411         }
412
413         dc = (char*)dl;
414         lc = (char*)ll;
415         rc = (char*)rl;
416
417         len = remainder;
418     }
419 #endif
420     {
421         switch (optype) {
422         case OP_BIT_AND:
423             while (len--)
424                 *dc++ = *lc++ & *rc++;
425             break;
426         case OP_BIT_XOR:
427             while (len--)
428                 *dc++ = *lc++ ^ *rc++;
429             goto mop_up;
430         case OP_BIT_OR:
431             while (len--)
432                 *dc++ = *lc++ | *rc++;
433           mop_up:
434             len = lensave;
435             if (rightlen > len)
436                 sv_catpvn(sv, rsave + len, rightlen - len);
437             else if (leftlen > len)
438                 sv_catpvn(sv, lsave + len, leftlen - len);
439             else
440                 *SvEND(sv) = '\0';
441             break;
442         }
443     }
444     SvTAINT(sv);
445 }
446
447 OP *
448 do_kv(ARGS)
449 dARGS
450 {
451     dSP;
452     HV *hv = (HV*)POPs;
453     register HE *entry;
454     SV *tmpstr;
455     I32 gimme = GIMME_V;
456     I32 dokeys =   (op->op_type == OP_KEYS);
457     I32 dovalues = (op->op_type == OP_VALUES);
458     I32 realhv = (SvTYPE(hv) == SVt_PVHV);
459     
460     if (op->op_type == OP_RV2HV || op->op_type == OP_PADHV) 
461         dokeys = dovalues = TRUE;
462
463     if (!hv) {
464         if (op->op_flags & OPf_MOD) {   /* lvalue */
465             dTARGET;            /* make sure to clear its target here */
466             if (SvTYPE(TARG) == SVt_PVLV)
467                 LvTARG(TARG) = Nullsv;
468             PUSHs(TARG);
469         }
470         RETURN;
471     }
472
473     if (realhv)
474         (void)hv_iterinit(hv);  /* always reset iterator regardless */
475     else
476         (void)avhv_iterinit((AV*)hv);
477
478     if (gimme == G_VOID)
479         RETURN;
480
481     if (gimme == G_SCALAR) {
482         I32 i;
483         dTARGET;
484
485         if (op->op_flags & OPf_MOD) {   /* lvalue */
486             if (SvTYPE(TARG) < SVt_PVLV) {
487                 sv_upgrade(TARG, SVt_PVLV);
488                 sv_magic(TARG, Nullsv, 'k', Nullch, 0);
489             }
490             LvTYPE(TARG) = 'k';
491             LvTARG(TARG) = (SV*)hv;
492             PUSHs(TARG);
493             RETURN;
494         }
495
496         if (!SvRMAGICAL(hv) || !mg_find((SV*)hv,'P'))
497             i = HvKEYS(hv);
498         else {
499             i = 0;
500             /*SUPPRESS 560*/
501             while (entry = realhv ? hv_iternext(hv) : avhv_iternext((AV*)hv)) {
502                 i++;
503             }
504         }
505         PUSHi( i );
506         RETURN;
507     }
508
509     /* Guess how much room we need.  hv_max may be a few too many.  Oh well. */
510     EXTEND(sp, HvMAX(hv) * (dokeys + dovalues));
511
512     PUTBACK;    /* hv_iternext and hv_iterval might clobber stack_sp */
513     while (entry = realhv ? hv_iternext(hv) : avhv_iternext((AV*)hv)) {
514         SPAGAIN;
515         if (dokeys)
516             XPUSHs(hv_iterkeysv(entry));        /* won't clobber stack_sp */
517         if (dovalues) {
518             tmpstr = sv_newmortal();
519             PUTBACK;
520             sv_setsv(tmpstr,realhv ?
521                      hv_iterval(hv,entry) : avhv_iterval((AV*)hv,entry));
522             DEBUG_H(sv_setpvf(tmpstr, "%lu%%%d=%lu",
523                             (unsigned long)HeHASH(entry),
524                             HvMAX(hv)+1,
525                             (unsigned long)(HeHASH(entry) & HvMAX(hv))));
526             SPAGAIN;
527             XPUSHs(tmpstr);
528         }
529         PUTBACK;
530     }
531     return NORMAL;
532 }