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