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