control character expansion in wwwrite()
[unix-history] / usr / src / usr.bin / window / wwwrite.c
CommitLineData
fe3db729 1#ifndef lint
0e64e422 2static char *sccsid = "@(#)wwwrite.c 3.19 84/04/08";
fe3db729
EW
3#endif
4
5#include "ww.h"
b1189050 6#include "tt.h"
0e64e422 7#include "char.h"
fe3db729 8
0e64e422
EW
9/*
10 * To support control character expansion, we save the old
11 * p and q values in r and s, and point p at the beginning
12 * of the expanded string, and q at some safe place beyond it
13 * (p + 10). At strategic points in the loops, we check
14 * for (r && !*p) and restore the saved values back into
15 * p and q. Essentially, we implement a stack of depth 2,
16 * to avoid recursion, which might be a better idea.
17 */
fe3db729
EW
18wwwrite(w, p, n)
19register struct ww *w;
20register char *p;
2b269ee7 21int n;
fe3db729 22{
19f9784c 23 char hascursor;
b1189050
EW
24 char *savep = p;
25 char *q = p + n;
0e64e422
EW
26 char *r = 0;
27 char *s;
fe3db729 28
73218728
EW
29 if (hascursor = w->ww_hascursor)
30 wwcursor(w, 0);
b1189050 31 while (p < q && !w->ww_stopped && (!wwinterrupt() || w->ww_nointr)) {
0e64e422
EW
32 if (r && !*p) {
33 p = r;
34 q = s;
35 r = 0;
36 continue;
37 }
38 if (w->ww_wstate == 0 && (isprt(*p)
39 || w->ww_unctrl && isunctrl(*p))) {
19f9784c 40 register i;
19f9784c 41 register union ww_char *bp;
04d70db4 42 int col, col1;
19f9784c 43
04d70db4 44 if (w->ww_insert) { /* this is very slow */
b1189050
EW
45 if (*p == '\t') {
46 p++;
47 w->ww_cur.c += 8 -
48 (w->ww_cur.c - w->ww_w.l & 7);
49 goto chklf;
50 }
0e64e422
EW
51 if (!isprt(*p)) {
52 r = p + 1;
53 s = q;
54 p = unctrl(*p);
55 q = p + 10;
56 }
f2a77fe1 57 wwinschar(w, w->ww_cur.r, w->ww_cur.c,
19f9784c
EW
58 *p++ | w->ww_modes << WWC_MSHIFT);
59 goto right;
60 }
61
b1189050
EW
62 bp = &w->ww_buf[w->ww_cur.r][w->ww_cur.c];
63 i = w->ww_cur.c;
0e64e422
EW
64 while (i < w->ww_w.r && p < q)
65 if (!*p && r) {
66 p = r;
67 q = s;
68 r = 0;
69 } else if (*p == '\t') {
b1189050
EW
70 register tmp = 8 - (i - w->ww_w.l & 7);
71 p++;
72 i += tmp;
73 bp += tmp;
0e64e422 74 } else if (isprt(*p)) {
b1189050
EW
75 bp++->c_w = *p++
76 | w->ww_modes << WWC_MSHIFT;
77 i++;
0e64e422
EW
78 } else if (w->ww_unctrl && isunctrl(*p)) {
79 r = p + 1;
80 s = q;
81 p = unctrl(*p);
82 q = p + 10;
83 } else
84 break;
04d70db4 85 col = MAX(w->ww_cur.c, w->ww_i.l);
b1189050
EW
86 col1 = MIN(i, w->ww_i.r);
87 w->ww_cur.c = i;
0e64e422
EW
88 if (w->ww_cur.r >= w->ww_i.t
89 && w->ww_cur.r < w->ww_i.b) {
04d70db4
EW
90 register union ww_char *ns = wwns[w->ww_cur.r];
91 register char *smap = &wwsmap[w->ww_cur.r][col];
92 register char *win = w->ww_win[w->ww_cur.r];
b1189050 93 int nchanged = 0;
bb05dfb5 94
04d70db4
EW
95 bp = w->ww_buf[w->ww_cur.r];
96 for (i = col; i < col1; i++)
2b269ee7 97 if (*smap++ == w->ww_index) {
b1189050 98 nchanged++;
04d70db4
EW
99 ns[i].c_w = bp[i].c_w
100 ^ win[i] << WWC_MSHIFT;
30647f51 101 }
b1189050
EW
102 if (nchanged > 0) {
103 wwtouched[w->ww_cur.r] |= WWU_TOUCHED;
0e64e422
EW
104 if (!w->ww_noupdate)
105 wwupdate1(w->ww_cur.r,
106 w->ww_cur.r + 1);
b1189050 107 }
19f9784c 108 }
b1189050
EW
109
110 chklf:
111 if (w->ww_cur.c >= w->ww_w.r)
112 goto crlf;
113 } else switch (w->ww_wstate) {
19f9784c
EW
114 case 0:
115 switch (*p++) {
fe3db729 116 case '\n':
bb05dfb5 117 if (w->ww_mapnl)
b1189050 118 crlf:
f2a77fe1 119 w->ww_cur.c = w->ww_w.l;
bb05dfb5 120 lf:
f2a77fe1
EW
121 if (++w->ww_cur.r >= w->ww_w.b) {
122 w->ww_cur.r = w->ww_w.b - 1;
86697c44
EW
123 if (w->ww_w.b < w->ww_b.b) {
124 (void) wwscroll1(w, w->ww_i.t,
125 w->ww_i.b, 1, 0);
126 w->ww_buf++;
127 w->ww_b.t--;
128 w->ww_b.b--;
129 } else
f2a77fe1 130 wwdelline(w, w->ww_b.t);
bb05dfb5 131 }
fe3db729 132 break;
fe3db729 133 case '\b':
f2a77fe1
EW
134 if (--w->ww_cur.c < w->ww_w.l) {
135 w->ww_cur.c = w->ww_w.r - 1;
b0d4d9e2
EW
136 goto up;
137 }
bb05dfb5 138 break;
fe3db729 139 case '\r':
f2a77fe1 140 w->ww_cur.c = w->ww_w.l;
bb05dfb5 141 break;
0e64e422
EW
142 case ctrl(g):
143 ttputc(ctrl(g));
fe3db729 144 break;
0e64e422 145 case ctrl([):
fe3db729
EW
146 w->ww_wstate = 1;
147 break;
148 }
149 break;
150 case 1:
151 w->ww_wstate = 0;
19f9784c 152 switch (*p++) {
fe3db729
EW
153 case '@':
154 w->ww_insert = 1;
155 break;
156 case 'A':
b0d4d9e2 157 up:
f2a77fe1
EW
158 if (--w->ww_cur.r < w->ww_w.t) {
159 w->ww_cur.r = w->ww_w.t;
86697c44
EW
160 if (w->ww_w.t > w->ww_b.t) {
161 (void) wwscroll1(w, w->ww_i.t,
162 w->ww_i.b, -1, 0);
163 w->ww_buf--;
164 w->ww_b.t++;
165 w->ww_b.b++;
166 } else
f2a77fe1 167 wwinsline(w, w->ww_b.t);
b0d4d9e2 168 }
fe3db729
EW
169 break;
170 case 'B':
bb05dfb5 171 goto lf;
fe3db729 172 case 'C':
f2a77fe1 173 right:
b1189050
EW
174 w->ww_cur.c++;
175 goto chklf;
fe3db729 176 case 'E':
215eb00f 177 w->ww_buf -= w->ww_w.t - w->ww_b.t;
f2a77fe1
EW
178 w->ww_b.t = w->ww_w.t;
179 w->ww_b.b = w->ww_b.t + w->ww_b.nr;
180 w->ww_cur.r = w->ww_w.t;
181 w->ww_cur.c = w->ww_w.l;
182 wwclreos(w, w->ww_w.t, w->ww_w.l);
fe3db729
EW
183 break;
184 case 'H':
f2a77fe1
EW
185 w->ww_cur.r = w->ww_w.t;
186 w->ww_cur.c = w->ww_w.l;
fe3db729
EW
187 break;
188 case 'J':
f2a77fe1 189 wwclreos(w, w->ww_cur.r, w->ww_cur.c);
fe3db729
EW
190 break;
191 case 'K':
f2a77fe1 192 wwclreol(w, w->ww_cur.r, w->ww_cur.c);
fe3db729
EW
193 break;
194 case 'L':
f2a77fe1 195 wwinsline(w, w->ww_cur.r);
fe3db729
EW
196 break;
197 case 'M':
f2a77fe1 198 wwdelline(w, w->ww_cur.r);
fe3db729
EW
199 break;
200 case 'N':
f2a77fe1 201 wwdelchar(w, w->ww_cur.r, w->ww_cur.c);
fe3db729
EW
202 break;
203 case 'O':
204 w->ww_insert = 0;
205 break;
206 case 'Y':
207 w->ww_wstate = 2;
208 break;
7d77e730
EW
209 case 'p':
210 w->ww_modes |= WWM_REV;
211 break;
212 case 'q':
213 w->ww_modes &= ~WWM_REV;
214 break;
215 case 'r':
216 w->ww_modes |= WWM_UL;
217 break;
218 case 's':
219 w->ww_modes &= ~WWM_UL;
220 break;
78be6843
EW
221 case 'F':
222 w->ww_modes |= WWM_GRP;
223 break;
224 case 'G':
225 w->ww_modes &= ~WWM_GRP;
226 break;
fe3db729
EW
227 }
228 break;
229 case 2:
4c1c1e83
EW
230 w->ww_cur.r = w->ww_w.t +
231 (unsigned)(*p++ - ' ') % w->ww_w.nr;
f2a77fe1 232 w->ww_wstate = 3;
fe3db729
EW
233 break;
234 case 3:
4c1c1e83
EW
235 w->ww_cur.c = w->ww_w.l +
236 (unsigned)(*p++ - ' ') % w->ww_w.nc;
fe3db729
EW
237 w->ww_wstate = 0;
238 break;
239 }
240 }
73218728
EW
241 if (hascursor)
242 wwcursor(w, 1);
b1189050
EW
243 wwnwwr++;
244 wwnwwra += n;
245 n = p - savep;
246 wwnwwrc += n;
247 return n;
fe3db729 248}