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