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