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