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 76193d7c 2003-09-30 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 76193d7c 2003-09-30 devnull noflush = 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 76193d7c 2003-09-30 devnull noflush = 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 76193d7c 2003-09-30 devnull raspdelete(File *f, uint p1, uint p2, int toterm)
87 76193d7c 2003-09-30 devnull n = p2 - p1;
88 76193d7c 2003-09-30 devnull if(n == 0)
91 76193d7c 2003-09-30 devnull if(p2 <= f->dot.r.p1){
92 76193d7c 2003-09-30 devnull f->dot.r.p1 -= n;
93 76193d7c 2003-09-30 devnull f->dot.r.p2 -= n;
95 76193d7c 2003-09-30 devnull if(p2 <= f->mark.p1){
96 76193d7c 2003-09-30 devnull f->mark.p1 -= n;
97 76193d7c 2003-09-30 devnull f->mark.p2 -= n;
100 76193d7c 2003-09-30 devnull if(f->rasp == nil)
103 76193d7c 2003-09-30 devnull if(f==cmd && p1<cmdpt){
104 76193d7c 2003-09-30 devnull if(p2 <= cmdpt)
105 76193d7c 2003-09-30 devnull cmdpt -= n;
107 76193d7c 2003-09-30 devnull cmdpt = p1;
109 76193d7c 2003-09-30 devnull if(toterm){
110 76193d7c 2003-09-30 devnull if(grown){
111 76193d7c 2003-09-30 devnull outTsll(Hgrow, f->tag, growpos, grown);
112 76193d7c 2003-09-30 devnull grown = 0;
113 76193d7c 2003-09-30 devnull }else if(shrunk && shrinkpos!=p1 && shrinkpos!=p2){
114 76193d7c 2003-09-30 devnull outTsll(Hcut, f->tag, shrinkpos, shrunk);
115 76193d7c 2003-09-30 devnull shrunk = 0;
117 76193d7c 2003-09-30 devnull if(!shrunk || shrinkpos==p2)
118 76193d7c 2003-09-30 devnull shrinkpos = p1;
119 76193d7c 2003-09-30 devnull shrunk += n;
121 76193d7c 2003-09-30 devnull rcut(f->rasp, p1, p2);
125 76193d7c 2003-09-30 devnull raspinsert(File *f, uint p1, Rune *buf, uint n, int toterm)
127 76193d7c 2003-09-30 devnull Range r;
129 76193d7c 2003-09-30 devnull if(n == 0)
132 76193d7c 2003-09-30 devnull if(p1 < f->dot.r.p1){
133 76193d7c 2003-09-30 devnull f->dot.r.p1 += n;
134 76193d7c 2003-09-30 devnull f->dot.r.p2 += n;
136 76193d7c 2003-09-30 devnull if(p1 < f->mark.p1){
137 76193d7c 2003-09-30 devnull f->mark.p1 += n;
138 76193d7c 2003-09-30 devnull f->mark.p2 += n;
142 76193d7c 2003-09-30 devnull if(f->rasp == nil)
144 76193d7c 2003-09-30 devnull if(f==cmd && p1<cmdpt)
145 76193d7c 2003-09-30 devnull cmdpt += n;
146 76193d7c 2003-09-30 devnull if(toterm){
147 76193d7c 2003-09-30 devnull if(shrunk){
148 76193d7c 2003-09-30 devnull outTsll(Hcut, f->tag, shrinkpos, shrunk);
149 76193d7c 2003-09-30 devnull shrunk = 0;
151 76193d7c 2003-09-30 devnull if(n>GROWDATASIZE || !rterm(f->rasp, p1)){
152 76193d7c 2003-09-30 devnull rgrow(f->rasp, p1, n);
153 76193d7c 2003-09-30 devnull if(grown && growpos+grown!=p1 && growpos!=p1){
154 76193d7c 2003-09-30 devnull outTsll(Hgrow, f->tag, growpos, grown);
155 76193d7c 2003-09-30 devnull grown = 0;
157 76193d7c 2003-09-30 devnull if(!grown)
158 76193d7c 2003-09-30 devnull growpos = p1;
159 76193d7c 2003-09-30 devnull grown += n;
161 76193d7c 2003-09-30 devnull if(grown){
162 76193d7c 2003-09-30 devnull outTsll(Hgrow, f->tag, growpos, grown);
163 76193d7c 2003-09-30 devnull grown = 0;
165 76193d7c 2003-09-30 devnull rgrow(f->rasp, p1, n);
166 76193d7c 2003-09-30 devnull r = rdata(f->rasp, p1, n);
167 76193d7c 2003-09-30 devnull if(r.p1!=p1 || r.p2!=p1+n)
168 76193d7c 2003-09-30 devnull panic("rdata in toterminal");
169 76193d7c 2003-09-30 devnull outTsllS(Hgrowdata, f->tag, p1, n, tmprstr(buf, n));
172 76193d7c 2003-09-30 devnull rgrow(f->rasp, p1, n);
173 76193d7c 2003-09-30 devnull r = rdata(f->rasp, p1, n);
174 76193d7c 2003-09-30 devnull if(r.p1!=p1 || r.p2!=p1+n)
175 76193d7c 2003-09-30 devnull panic("rdata in toterminal");
179 76193d7c 2003-09-30 devnull #define M 0x80000000L
180 76193d7c 2003-09-30 devnull #define P(i) r->longptr[i]
181 76193d7c 2003-09-30 devnull #define T(i) (P(i)&M) /* in terminal */
182 76193d7c 2003-09-30 devnull #define L(i) (P(i)&~M) /* length of this piece */
185 76193d7c 2003-09-30 devnull rcut(List *r, Posn p1, Posn p2)
187 76193d7c 2003-09-30 devnull Posn p, x;
190 76193d7c 2003-09-30 devnull if(p1 == p2)
191 76193d7c 2003-09-30 devnull panic("rcut 0");
192 76193d7c 2003-09-30 devnull for(p=0,i=0; i<r->nused && p+L(i)<=p1; p+=L(i++))
194 76193d7c 2003-09-30 devnull if(i == r->nused)
195 76193d7c 2003-09-30 devnull panic("rcut 1");
196 76193d7c 2003-09-30 devnull if(p < p1){ /* chop this piece */
197 76193d7c 2003-09-30 devnull if(p+L(i) < p2){
198 76193d7c 2003-09-30 devnull x = p1-p;
199 76193d7c 2003-09-30 devnull p += L(i);
201 76193d7c 2003-09-30 devnull x = L(i)-(p2-p1);
204 76193d7c 2003-09-30 devnull if(T(i))
205 76193d7c 2003-09-30 devnull P(i) = x|M;
207 76193d7c 2003-09-30 devnull P(i) = x;
210 76193d7c 2003-09-30 devnull while(i<r->nused && p+L(i)<=p2){
211 76193d7c 2003-09-30 devnull p += L(i);
212 76193d7c 2003-09-30 devnull dellist(r, i);
214 76193d7c 2003-09-30 devnull if(p < p2){
215 76193d7c 2003-09-30 devnull if(i == r->nused)
216 76193d7c 2003-09-30 devnull panic("rcut 2");
217 76193d7c 2003-09-30 devnull x = L(i)-(p2-p);
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;
223 76193d7c 2003-09-30 devnull /* can we merge i and i-1 ? */
224 76193d7c 2003-09-30 devnull if(i>0 && i<r->nused && T(i-1)==T(i)){
225 76193d7c 2003-09-30 devnull x = L(i-1)+L(i);
226 76193d7c 2003-09-30 devnull dellist(r, i--);
227 76193d7c 2003-09-30 devnull if(T(i))
228 76193d7c 2003-09-30 devnull P(i)=x|M;
235 76193d7c 2003-09-30 devnull rgrow(List *r, Posn p1, Posn n)
240 76193d7c 2003-09-30 devnull if(n == 0)
241 76193d7c 2003-09-30 devnull panic("rgrow 0");
242 76193d7c 2003-09-30 devnull for(p=0,i=0; i<r->nused && p+L(i)<=p1; p+=L(i++))
244 76193d7c 2003-09-30 devnull if(i == r->nused){ /* stick on end of file */
245 76193d7c 2003-09-30 devnull if(p!=p1)
246 76193d7c 2003-09-30 devnull panic("rgrow 1");
247 76193d7c 2003-09-30 devnull if(i>0 && !T(i-1))
248 76193d7c 2003-09-30 devnull P(i-1)+=n;
250 76193d7c 2003-09-30 devnull inslist(r, i, n);
251 76193d7c 2003-09-30 devnull }else if(!T(i)) /* goes in this empty piece */
252 76193d7c 2003-09-30 devnull P(i)+=n;
253 76193d7c 2003-09-30 devnull else if(p==p1 && i>0 && !T(i-1)) /* special case; simplifies life */
254 76193d7c 2003-09-30 devnull P(i-1)+=n;
255 76193d7c 2003-09-30 devnull else if(p==p1)
256 76193d7c 2003-09-30 devnull inslist(r, i, n);
257 76193d7c 2003-09-30 devnull else{ /* must break piece in terminal */
258 76193d7c 2003-09-30 devnull inslist(r, i+1, (L(i)-(p1-p))|M);
259 76193d7c 2003-09-30 devnull inslist(r, i+1, n);
260 76193d7c 2003-09-30 devnull P(i) = (p1-p)|M;
265 76193d7c 2003-09-30 devnull rterm(List *r, Posn p1)
270 76193d7c 2003-09-30 devnull for(p = 0,i = 0; i<r->nused && p+L(i)<=p1; p+=L(i++))
272 76193d7c 2003-09-30 devnull if(i==r->nused && (i==0 || !T(i-1)))
273 76193d7c 2003-09-30 devnull return 0;
274 76193d7c 2003-09-30 devnull return T(i);
278 76193d7c 2003-09-30 devnull rdata(List *r, Posn p1, Posn n)
282 76193d7c 2003-09-30 devnull Range rg;
284 76193d7c 2003-09-30 devnull if(n==0)
285 76193d7c 2003-09-30 devnull panic("rdata 0");
286 76193d7c 2003-09-30 devnull for(p = 0,i = 0; i<r->nused && p+L(i)<=p1; p+=L(i++))
288 76193d7c 2003-09-30 devnull if(i==r->nused)
289 76193d7c 2003-09-30 devnull panic("rdata 1");
290 76193d7c 2003-09-30 devnull if(T(i)){
291 76193d7c 2003-09-30 devnull n-=L(i)-(p1-p);
292 76193d7c 2003-09-30 devnull if(n<=0){
293 76193d7c 2003-09-30 devnull rg.p1 = rg.p2 = p1;
294 76193d7c 2003-09-30 devnull return rg;
296 76193d7c 2003-09-30 devnull p+=L(i++);
299 76193d7c 2003-09-30 devnull if(T(i) || i==r->nused)
300 76193d7c 2003-09-30 devnull panic("rdata 2");
301 76193d7c 2003-09-30 devnull if(p+L(i)<p1+n)
302 76193d7c 2003-09-30 devnull n = L(i)-(p1-p);
303 76193d7c 2003-09-30 devnull rg.p1 = p1;
304 76193d7c 2003-09-30 devnull rg.p2 = p1+n;
305 76193d7c 2003-09-30 devnull if(p!=p1){
306 76193d7c 2003-09-30 devnull inslist(r, i+1, L(i)-(p1-p));
307 76193d7c 2003-09-30 devnull P(i)=p1-p;
310 76193d7c 2003-09-30 devnull if(L(i)!=n){
311 76193d7c 2003-09-30 devnull inslist(r, i+1, L(i)-n);
314 76193d7c 2003-09-30 devnull P(i)|=M;
315 76193d7c 2003-09-30 devnull /* now i is set; can we merge? */
316 76193d7c 2003-09-30 devnull if(i<r->nused-1 && T(i+1)){
317 76193d7c 2003-09-30 devnull P(i)=(n+=L(i+1))|M;
318 76193d7c 2003-09-30 devnull dellist(r, i+1);
320 76193d7c 2003-09-30 devnull if(i>0 && T(i-1)){
321 76193d7c 2003-09-30 devnull P(i)=(n+L(i-1))|M;
322 76193d7c 2003-09-30 devnull dellist(r, i-1);
324 76193d7c 2003-09-30 devnull return rg;