summaryrefslogtreecommitdiff
path: root/do/trans
diff options
context:
space:
mode:
Diffstat (limited to 'do/trans')
-rw-r--r--do/trans58
1 files changed, 58 insertions, 0 deletions
diff --git a/do/trans b/do/trans
new file mode 100644
index 0000000000..f4c5503b43
--- /dev/null
+++ b/do/trans
@@ -0,0 +1,58 @@
+int
+do_trans(TARG,arg)
+STR *TARG;
+ARG *arg;
+{
+ register short *tbl;
+ register char *s;
+ register int matches = 0;
+ register int ch;
+ register char *send;
+ register char *d;
+ register int squash = arg[2].arg_len & 1;
+
+ tbl = (short*) arg[2].arg_ptr.arg_cval;
+ s = str_get(TARG);
+ send = s + TARG->str_cur;
+ if (!tbl || !s)
+ fatal("panic: do_trans");
+#ifdef DEBUGGING
+ if (debug & 8) {
+ deb("2.TBL\n");
+ }
+#endif
+ if (!arg[2].arg_len) {
+ while (s < send) {
+ if ((ch = tbl[*s & 0377]) >= 0) {
+ matches++;
+ *s = ch;
+ }
+ s++;
+ }
+ }
+ else {
+ d = s;
+ while (s < send) {
+ if ((ch = tbl[*s & 0377]) >= 0) {
+ *d = ch;
+ if (matches++ && squash) {
+ if (d[-1] == *d)
+ matches--;
+ else
+ d++;
+ }
+ else
+ d++;
+ }
+ else if (ch == -1) /* -1 is unmapped character */
+ *d++ = *s; /* -2 is delete character */
+ s++;
+ }
+ matches += send - d; /* account for disappeared chars */
+ *d = '\0';
+ TARG->str_cur = d - TARG->str_ptr;
+ }
+ STABSET(TARG);
+ return matches;
+}
+