Commit | Line | Data |
---|---|---|
fe3db729 | 1 | #ifndef lint |
0e64e422 | 2 | static 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 |
18 | wwwrite(w, p, n) |
19 | register struct ww *w; | |
20 | register char *p; | |
2b269ee7 | 21 | int 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 | } |