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