f4c5503b43f5fe05f1993e87c26a44d29686660f
[perl.git] / do / trans
1 int
2 do_trans(TARG,arg)
3 STR *TARG;
4 ARG *arg;
5 {
6     register short *tbl;
7     register char *s;
8     register int matches = 0;
9     register int ch;
10     register char *send;
11     register char *d;
12     register int squash = arg[2].arg_len & 1;
13
14     tbl = (short*) arg[2].arg_ptr.arg_cval;
15     s = str_get(TARG);
16     send = s + TARG->str_cur;
17     if (!tbl || !s)
18         fatal("panic: do_trans");
19 #ifdef DEBUGGING
20     if (debug & 8) {
21         deb("2.TBL\n");
22     }
23 #endif
24     if (!arg[2].arg_len) {
25         while (s < send) {
26             if ((ch = tbl[*s & 0377]) >= 0) {
27                 matches++;
28                 *s = ch;
29             }
30             s++;
31         }
32     }
33     else {
34         d = s;
35         while (s < send) {
36             if ((ch = tbl[*s & 0377]) >= 0) {
37                 *d = ch;
38                 if (matches++ && squash) {
39                     if (d[-1] == *d)
40                         matches--;
41                     else
42                         d++;
43                 }
44                 else
45                     d++;
46             }
47             else if (ch == -1)          /* -1 is unmapped character */
48                 *d++ = *s;              /* -2 is delete character */
49             s++;
50         }
51         matches += send - d;    /* account for disappeared chars */
52         *d = '\0';
53         TARG->str_cur = d - TARG->str_ptr;
54     }
55     STABSET(TARG);
56     return matches;
57 }
58