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