1 76193d7c 2003-09-30 devnull #include "sam.h"
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!).
6 78439d25 2007-01-12 devnull #define GROWDATASIZE 50 /* if size is <= this, send data with grow */
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);
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;
18 76193d7c 2003-09-30 devnull * rasp routines inform the terminal of changes to the file.
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.
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.
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.
31 76193d7c 2003-09-30 devnull * only called for initial load of file
34 76193d7c 2003-09-30 devnull raspload(File *f)
36 76193d7c 2003-09-30 devnull if(f->rasp == nil)
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);
46 76193d7c 2003-09-30 devnull raspstart(File *f)
48 76193d7c 2003-09-30 devnull if(f->rasp == nil)
50 76193d7c 2003-09-30 devnull grown = 0;
51 76193d7c 2003-09-30 devnull shrunk = 0;
52 5369e5ea 2007-01-12 devnull outbuffered = 1;
56 76193d7c 2003-09-30 devnull raspdone(File *f, int toterm)
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)
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;
83 78439d25 2007-01-12 devnull raspflush(File *f)
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;
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;
93 78439d25 2007-01-12 devnull outflush();
97 76193d7c 2003-09-30 devnull raspdelete(File *f, uint p1, uint p2, int toterm)
101 76193d7c 2003-09-30 devnull n = p2 - p1;
102 76193d7c 2003-09-30 devnull if(n == 0)
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;
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;
114 76193d7c 2003-09-30 devnull if(f->rasp == nil)
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;
121 76193d7c 2003-09-30 devnull cmdpt = p1;
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;
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;
135 76193d7c 2003-09-30 devnull rcut(f->rasp, p1, p2);
139 76193d7c 2003-09-30 devnull raspinsert(File *f, uint p1, Rune *buf, uint n, int toterm)
141 76193d7c 2003-09-30 devnull Range r;
143 76193d7c 2003-09-30 devnull if(n == 0)
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;
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;
156 76193d7c 2003-09-30 devnull if(f->rasp == nil)
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;
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;
171 76193d7c 2003-09-30 devnull if(!grown)
172 76193d7c 2003-09-30 devnull growpos = p1;
173 76193d7c 2003-09-30 devnull grown += n;
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;
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));
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");
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 */
199 76193d7c 2003-09-30 devnull rcut(List *r, Posn p1, Posn p2)
201 76193d7c 2003-09-30 devnull Posn p, x;
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++))
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);
215 76193d7c 2003-09-30 devnull x = L(i)-(p2-p1);
218 76193d7c 2003-09-30 devnull if(T(i))
219 76193d7c 2003-09-30 devnull P(i) = x|M;
221 76193d7c 2003-09-30 devnull P(i) = x;
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);
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;
235 76193d7c 2003-09-30 devnull P(i) = x;
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;
249 76193d7c 2003-09-30 devnull rgrow(List *r, Posn p1, Posn n)
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++))
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;
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;
279 76193d7c 2003-09-30 devnull rterm(List *r, Posn p1)
284 76193d7c 2003-09-30 devnull for(p = 0,i = 0; i<r->nused && p+L(i)<=p1; p+=L(i++))
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);
292 76193d7c 2003-09-30 devnull rdata(List *r, Posn p1, Posn n)
296 76193d7c 2003-09-30 devnull Range rg;
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++))
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;
310 76193d7c 2003-09-30 devnull p+=L(i++);
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;
324 76193d7c 2003-09-30 devnull if(L(i)!=n){
325 76193d7c 2003-09-30 devnull inslist(r, i+1, L(i)-n);
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);
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);
338 76193d7c 2003-09-30 devnull return rg;