|
|
1.1 root 1: /*
2: * Copyright (c) 1983 Regents of the University of California.
3: * All rights reserved.
4: *
5: * This code is derived from software contributed to Berkeley by
6: * Edward Wang at The University of California, Berkeley.
7: *
8: * Redistribution and use in source and binary forms are permitted provided
9: * that: (1) source distributions retain this entire copyright notice and
10: * comment, and (2) distributions including binaries display the following
11: * acknowledgement: ``This product includes software developed by the
12: * University of California, Berkeley and its contributors'' in the
13: * documentation or other materials provided with the distribution and in
14: * all advertising materials mentioning features or use of this software.
15: * Neither the name of the University nor the names of its contributors may
16: * be used to endorse or promote products derived from this software without
17: * specific prior written permission.
18: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
19: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
20: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21: */
22:
23: #ifndef lint
24: static char sccsid[] = "@(#)wwwrite.c 3.33 (Berkeley) 6/6/90";
25: #endif /* not lint */
26:
27: #include "ww.h"
28: #include "tt.h"
29: #include "char.h"
30:
31: #define UPDATE() \
32: if (!w->ww_noupdate && w->ww_cur.r >= 0 && w->ww_cur.r < wwnrow && \
33: wwtouched[w->ww_cur.r]) \
34: wwupdate1(w->ww_cur.r, w->ww_cur.r + 1)
35:
36: /*
37: * To support control character expansion, we save the old
38: * p and q values in r and s, and point p at the beginning
39: * of the expanded string, and q at some safe place beyond it
40: * (p + 10). At strategic points in the loops, we check
41: * for (r && !*p) and restore the saved values back into
42: * p and q. Essentially, we implement a stack of depth 2,
43: * to avoid recursion, which might be a better idea.
44: */
45: wwwrite(w, p, n)
46: register struct ww *w;
47: register char *p;
48: int n;
49: {
50: char hascursor;
51: char *savep = p;
52: char *q = p + n;
53: char *r = 0;
54: char *s;
55:
56: #ifdef lint
57: s = 0; /* define it before possible use */
58: #endif
59: if (hascursor = w->ww_hascursor)
60: wwcursor(w, 0);
61: while (p < q && !w->ww_stopped && (!wwinterrupt() || w->ww_nointr)) {
62: if (r && !*p) {
63: p = r;
64: q = s;
65: r = 0;
66: continue;
67: }
68: if (w->ww_wstate == 0 &&
69: (isprt(*p) || w->ww_unctrl && isunctrl(*p))) {
70: register i;
71: register union ww_char *bp;
72: int col, col1;
73:
74: if (w->ww_insert) { /* this is very slow */
75: if (*p == '\t') {
76: p++;
77: w->ww_cur.c += 8 -
78: (w->ww_cur.c - w->ww_w.l & 7);
79: goto chklf;
80: }
81: if (!isprt(*p)) {
82: r = p + 1;
83: s = q;
84: p = unctrl(*p);
85: q = p + 10;
86: }
87: wwinschar(w, w->ww_cur.r, w->ww_cur.c,
88: *p++, w->ww_modes);
89: goto right;
90: }
91:
92: bp = &w->ww_buf[w->ww_cur.r][w->ww_cur.c];
93: i = w->ww_cur.c;
94: while (i < w->ww_w.r && p < q)
95: if (!*p && r) {
96: p = r;
97: q = s;
98: r = 0;
99: } else if (*p == '\t') {
100: register tmp = 8 - (i - w->ww_w.l & 7);
101: p++;
102: i += tmp;
103: bp += tmp;
104: } else if (isprt(*p)) {
105: bp++->c_w = *p++
106: | w->ww_modes << WWC_MSHIFT;
107: i++;
108: } else if (w->ww_unctrl && isunctrl(*p)) {
109: r = p + 1;
110: s = q;
111: p = unctrl(*p);
112: q = p + 10;
113: } else
114: break;
115: col = MAX(w->ww_cur.c, w->ww_i.l);
116: col1 = MIN(i, w->ww_i.r);
117: w->ww_cur.c = i;
118: if (w->ww_cur.r >= w->ww_i.t
119: && w->ww_cur.r < w->ww_i.b) {
120: register union ww_char *ns = wwns[w->ww_cur.r];
121: register char *smap = &wwsmap[w->ww_cur.r][col];
122: register char *win = w->ww_win[w->ww_cur.r];
123: int nchanged = 0;
124:
125: bp = w->ww_buf[w->ww_cur.r];
126: for (i = col; i < col1; i++)
127: if (*smap++ == w->ww_index) {
128: nchanged++;
129: ns[i].c_w = bp[i].c_w
130: ^ win[i] << WWC_MSHIFT;
131: }
132: if (nchanged > 0)
133: wwtouched[w->ww_cur.r] |= WWU_TOUCHED;
134: }
135: chklf:
136: if (w->ww_cur.c >= w->ww_w.r)
137: goto crlf;
138: } else switch (w->ww_wstate) {
139: case 0:
140: switch (*p++) {
141: case '\n':
142: if (w->ww_mapnl)
143: crlf:
144: w->ww_cur.c = w->ww_w.l;
145: lf:
146: UPDATE();
147: if (++w->ww_cur.r >= w->ww_w.b) {
148: w->ww_cur.r = w->ww_w.b - 1;
149: if (w->ww_w.b < w->ww_b.b) {
150: (void) wwscroll1(w, w->ww_i.t,
151: w->ww_i.b, 1, 0);
152: w->ww_buf++;
153: w->ww_b.t--;
154: w->ww_b.b--;
155: } else
156: wwdelline(w, w->ww_b.t);
157: }
158: break;
159: case '\b':
160: if (--w->ww_cur.c < w->ww_w.l) {
161: w->ww_cur.c = w->ww_w.r - 1;
162: goto up;
163: }
164: break;
165: case '\r':
166: w->ww_cur.c = w->ww_w.l;
167: break;
168: case ctrl('g'):
169: ttputc(ctrl('g'));
170: break;
171: case ctrl('['):
172: w->ww_wstate = 1;
173: break;
174: }
175: break;
176: case 1:
177: w->ww_wstate = 0;
178: switch (*p++) {
179: case '@':
180: w->ww_insert = 1;
181: break;
182: case 'A':
183: up:
184: UPDATE();
185: if (--w->ww_cur.r < w->ww_w.t) {
186: w->ww_cur.r = w->ww_w.t;
187: if (w->ww_w.t > w->ww_b.t) {
188: (void) wwscroll1(w, w->ww_i.t,
189: w->ww_i.b, -1, 0);
190: w->ww_buf--;
191: w->ww_b.t++;
192: w->ww_b.b++;
193: } else
194: wwinsline(w, w->ww_b.t);
195: }
196: break;
197: case 'B':
198: goto lf;
199: case 'C':
200: right:
201: w->ww_cur.c++;
202: goto chklf;
203: case 'E':
204: w->ww_buf -= w->ww_w.t - w->ww_b.t;
205: w->ww_b.t = w->ww_w.t;
206: w->ww_b.b = w->ww_b.t + w->ww_b.nr;
207: w->ww_cur.r = w->ww_w.t;
208: w->ww_cur.c = w->ww_w.l;
209: wwclreos(w, w->ww_w.t, w->ww_w.l);
210: break;
211: case 'H':
212: UPDATE();
213: w->ww_cur.r = w->ww_w.t;
214: w->ww_cur.c = w->ww_w.l;
215: break;
216: case 'J':
217: wwclreos(w, w->ww_cur.r, w->ww_cur.c);
218: break;
219: case 'K':
220: wwclreol(w, w->ww_cur.r, w->ww_cur.c);
221: break;
222: case 'L':
223: UPDATE();
224: wwinsline(w, w->ww_cur.r);
225: break;
226: case 'M':
227: wwdelline(w, w->ww_cur.r);
228: break;
229: case 'N':
230: wwdelchar(w, w->ww_cur.r, w->ww_cur.c);
231: break;
232: case 'O':
233: w->ww_insert = 0;
234: break;
235: case 'P':
236: wwinschar(w, w->ww_cur.r, w->ww_cur.c, ' ', 0);
237: break;
238: case 'X':
239: wwupdate();
240: break;
241: case 'Y':
242: UPDATE();
243: w->ww_wstate = 2;
244: break;
245: case 'Z':
246: wwupdate();
247: xxflush(0);
248: break;
249: case 's':
250: w->ww_wstate = 4;
251: break;
252: case 'r':
253: w->ww_wstate = 5;
254: break;
255: }
256: break;
257: case 2:
258: w->ww_cur.r = w->ww_w.t +
259: (unsigned)(*p++ - ' ') % w->ww_w.nr;
260: w->ww_wstate = 3;
261: break;
262: case 3:
263: w->ww_cur.c = w->ww_w.l +
264: (unsigned)(*p++ - ' ') % w->ww_w.nc;
265: w->ww_wstate = 0;
266: break;
267: case 4:
268: w->ww_modes |= *p++ & wwavailmodes;
269: w->ww_wstate = 0;
270: break;
271: case 5:
272: w->ww_modes &= ~*p++;
273: w->ww_wstate = 0;
274: break;
275: }
276: }
277: if (hascursor)
278: wwcursor(w, 1);
279: wwnwwr++;
280: wwnwwra += n;
281: n = p - savep;
282: wwnwwrc += n;
283: return n;
284: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.