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