Annotation of src/usr.bin/window/wwwrite.c, Revision 1.3
1.3 ! deraadt 1: /* $OpenBSD: wwwrite.c,v 1.5 1996/02/08 21:49:19 mycroft Exp $ */
1.2 niklas 2: /* $NetBSD: wwwrite.c,v 1.5 1996/02/08 21:49:19 mycroft Exp $ */
1.1 deraadt 3:
4: /*
5: * Copyright (c) 1983, 1993
6: * The Regents of the University of California. All rights reserved.
7: *
8: * This code is derived from software contributed to Berkeley by
9: * Edward Wang at The University of California, Berkeley.
10: *
11: * Redistribution and use in source and binary forms, with or without
12: * modification, are permitted provided that the following conditions
13: * are met:
14: * 1. Redistributions of source code must retain the above copyright
15: * notice, this list of conditions and the following disclaimer.
16: * 2. Redistributions in binary form must reproduce the above copyright
17: * notice, this list of conditions and the following disclaimer in the
18: * documentation and/or other materials provided with the distribution.
19: * 3. All advertising materials mentioning features or use of this software
20: * must display the following acknowledgement:
21: * This product includes software developed by the University of
22: * California, Berkeley and its contributors.
23: * 4. Neither the name of the University nor the names of its contributors
24: * may be used to endorse or promote products derived from this software
25: * without specific prior written permission.
26: *
27: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37: * SUCH DAMAGE.
38: */
39:
40: #ifndef lint
41: #if 0
42: static char sccsid[] = "@(#)wwwrite.c 8.1 (Berkeley) 6/6/93";
43: #else
1.3 ! deraadt 44: static char rcsid[] = "$OpenBSD: wwwrite.c,v 1.5 1996/02/08 21:49:19 mycroft Exp $";
1.1 deraadt 45: #endif
46: #endif /* not lint */
47:
48: #include "ww.h"
49: #include "tt.h"
50: #include "char.h"
51:
52: #define UPDATE() \
1.2 niklas 53: if (!ISSET(w->ww_wflags, WWW_NOUPDATE) && w->ww_cur.r >= 0 && \
54: w->ww_cur.r < wwnrow && wwtouched[w->ww_cur.r]) \
1.1 deraadt 55: wwupdate1(w->ww_cur.r, w->ww_cur.r + 1)
56:
57: /*
58: * To support control character expansion, we save the old
59: * p and q values in r and s, and point p at the beginning
60: * of the expanded string, and q at some safe place beyond it
61: * (p + 10). At strategic points in the loops, we check
62: * for (r && !*p) and restore the saved values back into
63: * p and q. Essentially, we implement a stack of depth 2,
64: * to avoid recursion, which might be a better idea.
65: */
66: wwwrite(w, p, n)
67: register struct ww *w;
68: register char *p;
69: int n;
70: {
1.2 niklas 71: int hascursor;
1.1 deraadt 72: char *savep = p;
73: char *q = p + n;
74: char *r = 0;
75: char *s;
76:
77: #ifdef lint
78: s = 0; /* define it before possible use */
79: #endif
1.2 niklas 80: hascursor = ISSET(w->ww_wflags, WWW_HASCURSOR);
81: if (hascursor)
1.1 deraadt 82: wwcursor(w, 0);
1.2 niklas 83: while (p < q && !ISSET(w->ww_pflags, WWP_STOPPED) &&
84: (!wwinterrupt() || ISSET(w->ww_wflags, WWW_NOINTR))) {
1.1 deraadt 85: if (r && !*p) {
86: p = r;
87: q = s;
88: r = 0;
89: continue;
90: }
91: if (w->ww_wstate == 0 &&
1.2 niklas 92: (isprt(*p) || ISSET(w->ww_wflags, WWW_UNCTRL) &&
93: isunctrl(*p))) {
1.1 deraadt 94: register i;
95: register union ww_char *bp;
96: int col, col1;
97:
1.2 niklas 98: if (ISSET(w->ww_wflags, WWW_INSERT)) {
99: /* this is very slow */
1.1 deraadt 100: if (*p == '\t') {
101: p++;
102: w->ww_cur.c += 8 -
103: (w->ww_cur.c - w->ww_w.l & 7);
104: goto chklf;
105: }
106: if (!isprt(*p)) {
107: r = p + 1;
108: s = q;
109: p = unctrl(*p);
110: q = p + 10;
111: }
112: wwinschar(w, w->ww_cur.r, w->ww_cur.c,
113: *p++, w->ww_modes);
114: goto right;
115: }
116:
117: bp = &w->ww_buf[w->ww_cur.r][w->ww_cur.c];
118: i = w->ww_cur.c;
119: while (i < w->ww_w.r && p < q)
120: if (!*p && r) {
121: p = r;
122: q = s;
123: r = 0;
124: } else if (*p == '\t') {
125: register tmp = 8 - (i - w->ww_w.l & 7);
126: p++;
127: i += tmp;
128: bp += tmp;
129: } else if (isprt(*p)) {
130: bp++->c_w = *p++
131: | w->ww_modes << WWC_MSHIFT;
132: i++;
1.2 niklas 133: } else if (ISSET(w->ww_wflags, WWW_UNCTRL) &&
134: isunctrl(*p)) {
1.1 deraadt 135: r = p + 1;
136: s = q;
137: p = unctrl(*p);
138: q = p + 10;
139: } else
140: break;
141: col = MAX(w->ww_cur.c, w->ww_i.l);
142: col1 = MIN(i, w->ww_i.r);
143: w->ww_cur.c = i;
144: if (w->ww_cur.r >= w->ww_i.t
145: && w->ww_cur.r < w->ww_i.b) {
146: register union ww_char *ns = wwns[w->ww_cur.r];
1.2 niklas 147: register unsigned char *smap =
148: &wwsmap[w->ww_cur.r][col];
1.1 deraadt 149: register char *win = w->ww_win[w->ww_cur.r];
150: int nchanged = 0;
151:
152: bp = w->ww_buf[w->ww_cur.r];
153: for (i = col; i < col1; i++)
154: if (*smap++ == w->ww_index) {
155: nchanged++;
156: ns[i].c_w = bp[i].c_w
157: ^ win[i] << WWC_MSHIFT;
158: }
159: if (nchanged > 0)
160: wwtouched[w->ww_cur.r] |= WWU_TOUCHED;
161: }
162: chklf:
163: if (w->ww_cur.c >= w->ww_w.r)
164: goto crlf;
165: } else switch (w->ww_wstate) {
166: case 0:
167: switch (*p++) {
168: case '\n':
1.2 niklas 169: if (ISSET(w->ww_wflags, WWW_MAPNL))
1.1 deraadt 170: crlf:
171: w->ww_cur.c = w->ww_w.l;
172: lf:
173: UPDATE();
174: if (++w->ww_cur.r >= w->ww_w.b) {
175: w->ww_cur.r = w->ww_w.b - 1;
176: if (w->ww_w.b < w->ww_b.b) {
177: (void) wwscroll1(w, w->ww_i.t,
178: w->ww_i.b, 1, 0);
179: w->ww_buf++;
180: w->ww_b.t--;
181: w->ww_b.b--;
182: } else
183: wwdelline(w, w->ww_b.t);
184: }
185: break;
186: case '\b':
187: if (--w->ww_cur.c < w->ww_w.l) {
188: w->ww_cur.c = w->ww_w.r - 1;
189: goto up;
190: }
191: break;
192: case '\r':
193: w->ww_cur.c = w->ww_w.l;
194: break;
195: case ctrl('g'):
196: ttputc(ctrl('g'));
197: break;
198: case ctrl('['):
199: w->ww_wstate = 1;
200: break;
201: }
202: break;
203: case 1:
204: w->ww_wstate = 0;
205: switch (*p++) {
206: case '@':
1.2 niklas 207: SET(w->ww_wflags, WWW_INSERT);
1.1 deraadt 208: break;
209: case 'A':
210: up:
211: UPDATE();
212: if (--w->ww_cur.r < w->ww_w.t) {
213: w->ww_cur.r = w->ww_w.t;
214: if (w->ww_w.t > w->ww_b.t) {
215: (void) wwscroll1(w, w->ww_i.t,
216: w->ww_i.b, -1, 0);
217: w->ww_buf--;
218: w->ww_b.t++;
219: w->ww_b.b++;
220: } else
221: wwinsline(w, w->ww_b.t);
222: }
223: break;
224: case 'B':
225: goto lf;
226: case 'C':
227: right:
228: w->ww_cur.c++;
229: goto chklf;
230: case 'E':
231: w->ww_buf -= w->ww_w.t - w->ww_b.t;
232: w->ww_b.t = w->ww_w.t;
233: w->ww_b.b = w->ww_b.t + w->ww_b.nr;
234: w->ww_cur.r = w->ww_w.t;
235: w->ww_cur.c = w->ww_w.l;
236: wwclreos(w, w->ww_w.t, w->ww_w.l);
237: break;
238: case 'H':
239: UPDATE();
240: w->ww_cur.r = w->ww_w.t;
241: w->ww_cur.c = w->ww_w.l;
242: break;
243: case 'J':
244: wwclreos(w, w->ww_cur.r, w->ww_cur.c);
245: break;
246: case 'K':
247: wwclreol(w, w->ww_cur.r, w->ww_cur.c);
248: break;
249: case 'L':
250: UPDATE();
251: wwinsline(w, w->ww_cur.r);
252: break;
253: case 'M':
254: wwdelline(w, w->ww_cur.r);
255: break;
256: case 'N':
257: wwdelchar(w, w->ww_cur.r, w->ww_cur.c);
258: break;
259: case 'O':
1.2 niklas 260: CLR(w->ww_wflags, WWW_INSERT);
1.1 deraadt 261: break;
262: case 'P':
263: wwinschar(w, w->ww_cur.r, w->ww_cur.c, ' ', 0);
264: break;
265: case 'X':
266: wwupdate();
267: break;
268: case 'Y':
269: UPDATE();
270: w->ww_wstate = 2;
271: break;
272: case 'Z':
273: wwupdate();
274: xxflush(0);
275: break;
276: case 's':
277: w->ww_wstate = 4;
278: break;
279: case 'r':
280: w->ww_wstate = 5;
281: break;
282: }
283: break;
284: case 2:
285: w->ww_cur.r = w->ww_w.t +
286: (unsigned)(*p++ - ' ') % w->ww_w.nr;
287: w->ww_wstate = 3;
288: break;
289: case 3:
290: w->ww_cur.c = w->ww_w.l +
291: (unsigned)(*p++ - ' ') % w->ww_w.nc;
292: w->ww_wstate = 0;
293: break;
294: case 4:
295: w->ww_modes |= *p++ & wwavailmodes;
296: w->ww_wstate = 0;
297: break;
298: case 5:
299: w->ww_modes &= ~*p++;
300: w->ww_wstate = 0;
301: break;
302: }
303: }
304: if (hascursor)
305: wwcursor(w, 1);
306: wwnwwr++;
307: wwnwwra += n;
308: n = p - savep;
309: wwnwwrc += n;
310: return n;
311: }