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