Blame


1 76193d7c 2003-09-30 devnull #include "sam.h"
2 76193d7c 2003-09-30 devnull /*
3 76193d7c 2003-09-30 devnull * GROWDATASIZE must be big enough that all errors go out as Hgrowdata's,
4 76193d7c 2003-09-30 devnull * so they will be scrolled into visibility in the ~~sam~~ window (yuck!).
5 76193d7c 2003-09-30 devnull */
6 78439d25 2007-01-12 devnull #define GROWDATASIZE 50 /* if size is <= this, send data with grow */
7 76193d7c 2003-09-30 devnull
8 76193d7c 2003-09-30 devnull void rcut(List*, Posn, Posn);
9 76193d7c 2003-09-30 devnull int rterm(List*, Posn);
10 76193d7c 2003-09-30 devnull void rgrow(List*, Posn, Posn);
11 76193d7c 2003-09-30 devnull
12 76193d7c 2003-09-30 devnull static Posn growpos;
13 76193d7c 2003-09-30 devnull static Posn grown;
14 76193d7c 2003-09-30 devnull static Posn shrinkpos;
15 76193d7c 2003-09-30 devnull static Posn shrunk;
16 76193d7c 2003-09-30 devnull
17 76193d7c 2003-09-30 devnull /*
18 76193d7c 2003-09-30 devnull * rasp routines inform the terminal of changes to the file.
19 76193d7c 2003-09-30 devnull *
20 76193d7c 2003-09-30 devnull * a rasp is a list of spans within the file, and an indication
21 76193d7c 2003-09-30 devnull * of whether the terminal knows about the span.
22 76193d7c 2003-09-30 devnull *
23 76193d7c 2003-09-30 devnull * optimize by coalescing multiple updates to the same span
24 76193d7c 2003-09-30 devnull * if it is not known by the terminal.
25 76193d7c 2003-09-30 devnull *
26 76193d7c 2003-09-30 devnull * other possible optimizations: flush terminal's rasp by cut everything,
27 76193d7c 2003-09-30 devnull * insert everything if rasp gets too large.
28 76193d7c 2003-09-30 devnull */
29 76193d7c 2003-09-30 devnull
30 76193d7c 2003-09-30 devnull /*
31 76193d7c 2003-09-30 devnull * only called for initial load of file
32 76193d7c 2003-09-30 devnull */
33 76193d7c 2003-09-30 devnull void
34 76193d7c 2003-09-30 devnull raspload(File *f)
35 76193d7c 2003-09-30 devnull {
36 76193d7c 2003-09-30 devnull if(f->rasp == nil)
37 76193d7c 2003-09-30 devnull return;
38 522b0689 2003-09-30 devnull grown = f->b.nc;
39 76193d7c 2003-09-30 devnull growpos = 0;
40 522b0689 2003-09-30 devnull if(f->b.nc)
41 522b0689 2003-09-30 devnull rgrow(f->rasp, 0, f->b.nc);
42 76193d7c 2003-09-30 devnull raspdone(f, 1);
43 76193d7c 2003-09-30 devnull }
44 76193d7c 2003-09-30 devnull
45 76193d7c 2003-09-30 devnull void
46 76193d7c 2003-09-30 devnull raspstart(File *f)
47 76193d7c 2003-09-30 devnull {
48 76193d7c 2003-09-30 devnull if(f->rasp == nil)
49 76193d7c 2003-09-30 devnull return;
50 76193d7c 2003-09-30 devnull grown = 0;
51 76193d7c 2003-09-30 devnull shrunk = 0;
52 5369e5ea 2007-01-12 devnull outbuffered = 1;
53 76193d7c 2003-09-30 devnull }
54 76193d7c 2003-09-30 devnull
55 76193d7c 2003-09-30 devnull void
56 76193d7c 2003-09-30 devnull raspdone(File *f, int toterm)
57 76193d7c 2003-09-30 devnull {
58 522b0689 2003-09-30 devnull if(f->dot.r.p1 > f->b.nc)
59 522b0689 2003-09-30 devnull f->dot.r.p1 = f->b.nc;
60 522b0689 2003-09-30 devnull if(f->dot.r.p2 > f->b.nc)
61 522b0689 2003-09-30 devnull f->dot.r.p2 = f->b.nc;
62 522b0689 2003-09-30 devnull if(f->mark.p1 > f->b.nc)
63 522b0689 2003-09-30 devnull f->mark.p1 = f->b.nc;
64 522b0689 2003-09-30 devnull if(f->mark.p2 > f->b.nc)
65 522b0689 2003-09-30 devnull f->mark.p2 = f->b.nc;
66 76193d7c 2003-09-30 devnull if(f->rasp == nil)
67 76193d7c 2003-09-30 devnull return;
68 76193d7c 2003-09-30 devnull if(grown)
69 76193d7c 2003-09-30 devnull outTsll(Hgrow, f->tag, growpos, grown);
70 76193d7c 2003-09-30 devnull else if(shrunk)
71 76193d7c 2003-09-30 devnull outTsll(Hcut, f->tag, shrinkpos, shrunk);
72 76193d7c 2003-09-30 devnull if(toterm)
73 76193d7c 2003-09-30 devnull outTs(Hcheck0, f->tag);
74 76193d7c 2003-09-30 devnull outflush();
75 5369e5ea 2007-01-12 devnull outbuffered = 0;
76 76193d7c 2003-09-30 devnull if(f == cmd){
77 76193d7c 2003-09-30 devnull cmdpt += cmdptadv;
78 76193d7c 2003-09-30 devnull cmdptadv = 0;
79 76193d7c 2003-09-30 devnull }
80 76193d7c 2003-09-30 devnull }
81 76193d7c 2003-09-30 devnull
82 76193d7c 2003-09-30 devnull void
83 78439d25 2007-01-12 devnull raspflush(File *f)
84 78439d25 2007-01-12 devnull {
85 78439d25 2007-01-12 devnull if(grown){
86 78439d25 2007-01-12 devnull outTsll(Hgrow, f->tag, growpos, grown);
87 78439d25 2007-01-12 devnull grown = 0;
88 78439d25 2007-01-12 devnull }
89 78439d25 2007-01-12 devnull else if(shrunk){
90 78439d25 2007-01-12 devnull outTsll(Hcut, f->tag, shrinkpos, shrunk);
91 78439d25 2007-01-12 devnull shrunk = 0;
92 78439d25 2007-01-12 devnull }
93 78439d25 2007-01-12 devnull outflush();
94 78439d25 2007-01-12 devnull }
95 78439d25 2007-01-12 devnull
96 78439d25 2007-01-12 devnull void
97 76193d7c 2003-09-30 devnull raspdelete(File *f, uint p1, uint p2, int toterm)
98 76193d7c 2003-09-30 devnull {
99 76193d7c 2003-09-30 devnull long n;
100 76193d7c 2003-09-30 devnull
101 76193d7c 2003-09-30 devnull n = p2 - p1;
102 76193d7c 2003-09-30 devnull if(n == 0)
103 76193d7c 2003-09-30 devnull return;
104 76193d7c 2003-09-30 devnull
105 76193d7c 2003-09-30 devnull if(p2 <= f->dot.r.p1){
106 76193d7c 2003-09-30 devnull f->dot.r.p1 -= n;
107 76193d7c 2003-09-30 devnull f->dot.r.p2 -= n;
108 76193d7c 2003-09-30 devnull }
109 76193d7c 2003-09-30 devnull if(p2 <= f->mark.p1){
110 76193d7c 2003-09-30 devnull f->mark.p1 -= n;
111 76193d7c 2003-09-30 devnull f->mark.p2 -= n;
112 76193d7c 2003-09-30 devnull }
113 76193d7c 2003-09-30 devnull
114 76193d7c 2003-09-30 devnull if(f->rasp == nil)
115 76193d7c 2003-09-30 devnull return;
116 76193d7c 2003-09-30 devnull
117 76193d7c 2003-09-30 devnull if(f==cmd && p1<cmdpt){
118 76193d7c 2003-09-30 devnull if(p2 <= cmdpt)
119 76193d7c 2003-09-30 devnull cmdpt -= n;
120 76193d7c 2003-09-30 devnull else
121 76193d7c 2003-09-30 devnull cmdpt = p1;
122 76193d7c 2003-09-30 devnull }
123 76193d7c 2003-09-30 devnull if(toterm){
124 76193d7c 2003-09-30 devnull if(grown){
125 76193d7c 2003-09-30 devnull outTsll(Hgrow, f->tag, growpos, grown);
126 76193d7c 2003-09-30 devnull grown = 0;
127 76193d7c 2003-09-30 devnull }else if(shrunk && shrinkpos!=p1 && shrinkpos!=p2){
128 76193d7c 2003-09-30 devnull outTsll(Hcut, f->tag, shrinkpos, shrunk);
129 76193d7c 2003-09-30 devnull shrunk = 0;
130 76193d7c 2003-09-30 devnull }
131 76193d7c 2003-09-30 devnull if(!shrunk || shrinkpos==p2)
132 76193d7c 2003-09-30 devnull shrinkpos = p1;
133 76193d7c 2003-09-30 devnull shrunk += n;
134 76193d7c 2003-09-30 devnull }
135 76193d7c 2003-09-30 devnull rcut(f->rasp, p1, p2);
136 76193d7c 2003-09-30 devnull }
137 76193d7c 2003-09-30 devnull
138 76193d7c 2003-09-30 devnull void
139 76193d7c 2003-09-30 devnull raspinsert(File *f, uint p1, Rune *buf, uint n, int toterm)
140 76193d7c 2003-09-30 devnull {
141 76193d7c 2003-09-30 devnull Range r;
142 76193d7c 2003-09-30 devnull
143 76193d7c 2003-09-30 devnull if(n == 0)
144 76193d7c 2003-09-30 devnull return;
145 76193d7c 2003-09-30 devnull
146 76193d7c 2003-09-30 devnull if(p1 < f->dot.r.p1){
147 76193d7c 2003-09-30 devnull f->dot.r.p1 += n;
148 76193d7c 2003-09-30 devnull f->dot.r.p2 += n;
149 76193d7c 2003-09-30 devnull }
150 76193d7c 2003-09-30 devnull if(p1 < f->mark.p1){
151 76193d7c 2003-09-30 devnull f->mark.p1 += n;
152 76193d7c 2003-09-30 devnull f->mark.p2 += n;
153 76193d7c 2003-09-30 devnull }
154 76193d7c 2003-09-30 devnull
155 76193d7c 2003-09-30 devnull
156 76193d7c 2003-09-30 devnull if(f->rasp == nil)
157 76193d7c 2003-09-30 devnull return;
158 76193d7c 2003-09-30 devnull if(f==cmd && p1<cmdpt)
159 76193d7c 2003-09-30 devnull cmdpt += n;
160 76193d7c 2003-09-30 devnull if(toterm){
161 76193d7c 2003-09-30 devnull if(shrunk){
162 76193d7c 2003-09-30 devnull outTsll(Hcut, f->tag, shrinkpos, shrunk);
163 76193d7c 2003-09-30 devnull shrunk = 0;
164 76193d7c 2003-09-30 devnull }
165 76193d7c 2003-09-30 devnull if(n>GROWDATASIZE || !rterm(f->rasp, p1)){
166 76193d7c 2003-09-30 devnull rgrow(f->rasp, p1, n);
167 76193d7c 2003-09-30 devnull if(grown && growpos+grown!=p1 && growpos!=p1){
168 76193d7c 2003-09-30 devnull outTsll(Hgrow, f->tag, growpos, grown);
169 76193d7c 2003-09-30 devnull grown = 0;
170 76193d7c 2003-09-30 devnull }
171 76193d7c 2003-09-30 devnull if(!grown)
172 76193d7c 2003-09-30 devnull growpos = p1;
173 76193d7c 2003-09-30 devnull grown += n;
174 76193d7c 2003-09-30 devnull }else{
175 76193d7c 2003-09-30 devnull if(grown){
176 76193d7c 2003-09-30 devnull outTsll(Hgrow, f->tag, growpos, grown);
177 76193d7c 2003-09-30 devnull grown = 0;
178 76193d7c 2003-09-30 devnull }
179 76193d7c 2003-09-30 devnull rgrow(f->rasp, p1, n);
180 76193d7c 2003-09-30 devnull r = rdata(f->rasp, p1, n);
181 76193d7c 2003-09-30 devnull if(r.p1!=p1 || r.p2!=p1+n)
182 76193d7c 2003-09-30 devnull panic("rdata in toterminal");
183 76193d7c 2003-09-30 devnull outTsllS(Hgrowdata, f->tag, p1, n, tmprstr(buf, n));
184 76193d7c 2003-09-30 devnull }
185 76193d7c 2003-09-30 devnull }else{
186 76193d7c 2003-09-30 devnull rgrow(f->rasp, p1, n);
187 76193d7c 2003-09-30 devnull r = rdata(f->rasp, p1, n);
188 76193d7c 2003-09-30 devnull if(r.p1!=p1 || r.p2!=p1+n)
189 76193d7c 2003-09-30 devnull panic("rdata in toterminal");
190 76193d7c 2003-09-30 devnull }
191 76193d7c 2003-09-30 devnull }
192 76193d7c 2003-09-30 devnull
193 76193d7c 2003-09-30 devnull #define M 0x80000000L
194 2c0f3733 2006-04-20 devnull #define P(i) r->posnptr[i]
195 76193d7c 2003-09-30 devnull #define T(i) (P(i)&M) /* in terminal */
196 76193d7c 2003-09-30 devnull #define L(i) (P(i)&~M) /* length of this piece */
197 76193d7c 2003-09-30 devnull
198 76193d7c 2003-09-30 devnull void
199 76193d7c 2003-09-30 devnull rcut(List *r, Posn p1, Posn p2)
200 76193d7c 2003-09-30 devnull {
201 76193d7c 2003-09-30 devnull Posn p, x;
202 76193d7c 2003-09-30 devnull int i;
203 76193d7c 2003-09-30 devnull
204 76193d7c 2003-09-30 devnull if(p1 == p2)
205 76193d7c 2003-09-30 devnull panic("rcut 0");
206 76193d7c 2003-09-30 devnull for(p=0,i=0; i<r->nused && p+L(i)<=p1; p+=L(i++))
207 76193d7c 2003-09-30 devnull ;
208 76193d7c 2003-09-30 devnull if(i == r->nused)
209 76193d7c 2003-09-30 devnull panic("rcut 1");
210 76193d7c 2003-09-30 devnull if(p < p1){ /* chop this piece */
211 76193d7c 2003-09-30 devnull if(p+L(i) < p2){
212 76193d7c 2003-09-30 devnull x = p1-p;
213 76193d7c 2003-09-30 devnull p += L(i);
214 76193d7c 2003-09-30 devnull }else{
215 76193d7c 2003-09-30 devnull x = L(i)-(p2-p1);
216 76193d7c 2003-09-30 devnull p = p2;
217 76193d7c 2003-09-30 devnull }
218 76193d7c 2003-09-30 devnull if(T(i))
219 76193d7c 2003-09-30 devnull P(i) = x|M;
220 76193d7c 2003-09-30 devnull else
221 76193d7c 2003-09-30 devnull P(i) = x;
222 76193d7c 2003-09-30 devnull i++;
223 76193d7c 2003-09-30 devnull }
224 76193d7c 2003-09-30 devnull while(i<r->nused && p+L(i)<=p2){
225 76193d7c 2003-09-30 devnull p += L(i);
226 76193d7c 2003-09-30 devnull dellist(r, i);
227 76193d7c 2003-09-30 devnull }
228 76193d7c 2003-09-30 devnull if(p < p2){
229 76193d7c 2003-09-30 devnull if(i == r->nused)
230 76193d7c 2003-09-30 devnull panic("rcut 2");
231 76193d7c 2003-09-30 devnull x = L(i)-(p2-p);
232 76193d7c 2003-09-30 devnull if(T(i))
233 76193d7c 2003-09-30 devnull P(i) = x|M;
234 76193d7c 2003-09-30 devnull else
235 76193d7c 2003-09-30 devnull P(i) = x;
236 76193d7c 2003-09-30 devnull }
237 76193d7c 2003-09-30 devnull /* can we merge i and i-1 ? */
238 76193d7c 2003-09-30 devnull if(i>0 && i<r->nused && T(i-1)==T(i)){
239 76193d7c 2003-09-30 devnull x = L(i-1)+L(i);
240 76193d7c 2003-09-30 devnull dellist(r, i--);
241 76193d7c 2003-09-30 devnull if(T(i))
242 76193d7c 2003-09-30 devnull P(i)=x|M;
243 76193d7c 2003-09-30 devnull else
244 76193d7c 2003-09-30 devnull P(i)=x;
245 76193d7c 2003-09-30 devnull }
246 76193d7c 2003-09-30 devnull }
247 76193d7c 2003-09-30 devnull
248 76193d7c 2003-09-30 devnull void
249 76193d7c 2003-09-30 devnull rgrow(List *r, Posn p1, Posn n)
250 76193d7c 2003-09-30 devnull {
251 76193d7c 2003-09-30 devnull Posn p;
252 76193d7c 2003-09-30 devnull int i;
253 76193d7c 2003-09-30 devnull
254 76193d7c 2003-09-30 devnull if(n == 0)
255 76193d7c 2003-09-30 devnull panic("rgrow 0");
256 76193d7c 2003-09-30 devnull for(p=0,i=0; i<r->nused && p+L(i)<=p1; p+=L(i++))
257 76193d7c 2003-09-30 devnull ;
258 76193d7c 2003-09-30 devnull if(i == r->nused){ /* stick on end of file */
259 76193d7c 2003-09-30 devnull if(p!=p1)
260 76193d7c 2003-09-30 devnull panic("rgrow 1");
261 76193d7c 2003-09-30 devnull if(i>0 && !T(i-1))
262 76193d7c 2003-09-30 devnull P(i-1)+=n;
263 76193d7c 2003-09-30 devnull else
264 76193d7c 2003-09-30 devnull inslist(r, i, n);
265 76193d7c 2003-09-30 devnull }else if(!T(i)) /* goes in this empty piece */
266 76193d7c 2003-09-30 devnull P(i)+=n;
267 76193d7c 2003-09-30 devnull else if(p==p1 && i>0 && !T(i-1)) /* special case; simplifies life */
268 76193d7c 2003-09-30 devnull P(i-1)+=n;
269 76193d7c 2003-09-30 devnull else if(p==p1)
270 76193d7c 2003-09-30 devnull inslist(r, i, n);
271 76193d7c 2003-09-30 devnull else{ /* must break piece in terminal */
272 76193d7c 2003-09-30 devnull inslist(r, i+1, (L(i)-(p1-p))|M);
273 76193d7c 2003-09-30 devnull inslist(r, i+1, n);
274 76193d7c 2003-09-30 devnull P(i) = (p1-p)|M;
275 76193d7c 2003-09-30 devnull }
276 76193d7c 2003-09-30 devnull }
277 76193d7c 2003-09-30 devnull
278 76193d7c 2003-09-30 devnull int
279 76193d7c 2003-09-30 devnull rterm(List *r, Posn p1)
280 76193d7c 2003-09-30 devnull {
281 76193d7c 2003-09-30 devnull Posn p;
282 76193d7c 2003-09-30 devnull int i;
283 76193d7c 2003-09-30 devnull
284 76193d7c 2003-09-30 devnull for(p = 0,i = 0; i<r->nused && p+L(i)<=p1; p+=L(i++))
285 76193d7c 2003-09-30 devnull ;
286 3ccd6162 2021-01-14 rsc if(i==r->nused)
287 3ccd6162 2021-01-14 rsc return i > 0 && T(i-1);
288 76193d7c 2003-09-30 devnull return T(i);
289 76193d7c 2003-09-30 devnull }
290 76193d7c 2003-09-30 devnull
291 76193d7c 2003-09-30 devnull Range
292 76193d7c 2003-09-30 devnull rdata(List *r, Posn p1, Posn n)
293 76193d7c 2003-09-30 devnull {
294 76193d7c 2003-09-30 devnull Posn p;
295 76193d7c 2003-09-30 devnull int i;
296 76193d7c 2003-09-30 devnull Range rg;
297 76193d7c 2003-09-30 devnull
298 76193d7c 2003-09-30 devnull if(n==0)
299 76193d7c 2003-09-30 devnull panic("rdata 0");
300 76193d7c 2003-09-30 devnull for(p = 0,i = 0; i<r->nused && p+L(i)<=p1; p+=L(i++))
301 76193d7c 2003-09-30 devnull ;
302 76193d7c 2003-09-30 devnull if(i==r->nused)
303 76193d7c 2003-09-30 devnull panic("rdata 1");
304 76193d7c 2003-09-30 devnull if(T(i)){
305 76193d7c 2003-09-30 devnull n-=L(i)-(p1-p);
306 76193d7c 2003-09-30 devnull if(n<=0){
307 76193d7c 2003-09-30 devnull rg.p1 = rg.p2 = p1;
308 76193d7c 2003-09-30 devnull return rg;
309 76193d7c 2003-09-30 devnull }
310 76193d7c 2003-09-30 devnull p+=L(i++);
311 76193d7c 2003-09-30 devnull p1 = p;
312 76193d7c 2003-09-30 devnull }
313 76193d7c 2003-09-30 devnull if(T(i) || i==r->nused)
314 76193d7c 2003-09-30 devnull panic("rdata 2");
315 76193d7c 2003-09-30 devnull if(p+L(i)<p1+n)
316 76193d7c 2003-09-30 devnull n = L(i)-(p1-p);
317 76193d7c 2003-09-30 devnull rg.p1 = p1;
318 76193d7c 2003-09-30 devnull rg.p2 = p1+n;
319 76193d7c 2003-09-30 devnull if(p!=p1){
320 76193d7c 2003-09-30 devnull inslist(r, i+1, L(i)-(p1-p));
321 76193d7c 2003-09-30 devnull P(i)=p1-p;
322 76193d7c 2003-09-30 devnull i++;
323 76193d7c 2003-09-30 devnull }
324 76193d7c 2003-09-30 devnull if(L(i)!=n){
325 76193d7c 2003-09-30 devnull inslist(r, i+1, L(i)-n);
326 76193d7c 2003-09-30 devnull P(i)=n;
327 76193d7c 2003-09-30 devnull }
328 76193d7c 2003-09-30 devnull P(i)|=M;
329 76193d7c 2003-09-30 devnull /* now i is set; can we merge? */
330 76193d7c 2003-09-30 devnull if(i<r->nused-1 && T(i+1)){
331 76193d7c 2003-09-30 devnull P(i)=(n+=L(i+1))|M;
332 76193d7c 2003-09-30 devnull dellist(r, i+1);
333 76193d7c 2003-09-30 devnull }
334 76193d7c 2003-09-30 devnull if(i>0 && T(i-1)){
335 76193d7c 2003-09-30 devnull P(i)=(n+L(i-1))|M;
336 76193d7c 2003-09-30 devnull dellist(r, i-1);
337 76193d7c 2003-09-30 devnull }
338 76193d7c 2003-09-30 devnull return rg;
339 76193d7c 2003-09-30 devnull }