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 76193d7c 2003-09-30 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 76193d7c 2003-09-30 devnull noflush = 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 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;
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 76193d7c 2003-09-30 devnull raspdelete(File *f, uint p1, uint p2, int toterm)
84 76193d7c 2003-09-30 devnull {
85 76193d7c 2003-09-30 devnull long n;
86 76193d7c 2003-09-30 devnull
87 76193d7c 2003-09-30 devnull n = p2 - p1;
88 76193d7c 2003-09-30 devnull if(n == 0)
89 76193d7c 2003-09-30 devnull return;
90 76193d7c 2003-09-30 devnull
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;
94 76193d7c 2003-09-30 devnull }
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;
98 76193d7c 2003-09-30 devnull }
99 76193d7c 2003-09-30 devnull
100 76193d7c 2003-09-30 devnull if(f->rasp == nil)
101 76193d7c 2003-09-30 devnull return;
102 76193d7c 2003-09-30 devnull
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;
106 76193d7c 2003-09-30 devnull else
107 76193d7c 2003-09-30 devnull cmdpt = p1;
108 76193d7c 2003-09-30 devnull }
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;
116 76193d7c 2003-09-30 devnull }
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;
120 76193d7c 2003-09-30 devnull }
121 76193d7c 2003-09-30 devnull rcut(f->rasp, p1, p2);
122 76193d7c 2003-09-30 devnull }
123 76193d7c 2003-09-30 devnull
124 76193d7c 2003-09-30 devnull void
125 76193d7c 2003-09-30 devnull raspinsert(File *f, uint p1, Rune *buf, uint n, int toterm)
126 76193d7c 2003-09-30 devnull {
127 76193d7c 2003-09-30 devnull Range r;
128 76193d7c 2003-09-30 devnull
129 76193d7c 2003-09-30 devnull if(n == 0)
130 76193d7c 2003-09-30 devnull return;
131 76193d7c 2003-09-30 devnull
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;
135 76193d7c 2003-09-30 devnull }
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;
139 76193d7c 2003-09-30 devnull }
140 76193d7c 2003-09-30 devnull
141 76193d7c 2003-09-30 devnull
142 76193d7c 2003-09-30 devnull if(f->rasp == nil)
143 76193d7c 2003-09-30 devnull return;
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;
150 76193d7c 2003-09-30 devnull }
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;
156 76193d7c 2003-09-30 devnull }
157 76193d7c 2003-09-30 devnull if(!grown)
158 76193d7c 2003-09-30 devnull growpos = p1;
159 76193d7c 2003-09-30 devnull grown += n;
160 76193d7c 2003-09-30 devnull }else{
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;
164 76193d7c 2003-09-30 devnull }
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));
170 76193d7c 2003-09-30 devnull }
171 76193d7c 2003-09-30 devnull }else{
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");
176 76193d7c 2003-09-30 devnull }
177 76193d7c 2003-09-30 devnull }
178 76193d7c 2003-09-30 devnull
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 */
183 76193d7c 2003-09-30 devnull
184 76193d7c 2003-09-30 devnull void
185 76193d7c 2003-09-30 devnull rcut(List *r, Posn p1, Posn p2)
186 76193d7c 2003-09-30 devnull {
187 76193d7c 2003-09-30 devnull Posn p, x;
188 76193d7c 2003-09-30 devnull int i;
189 76193d7c 2003-09-30 devnull
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++))
193 76193d7c 2003-09-30 devnull ;
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);
200 76193d7c 2003-09-30 devnull }else{
201 76193d7c 2003-09-30 devnull x = L(i)-(p2-p1);
202 76193d7c 2003-09-30 devnull p = p2;
203 76193d7c 2003-09-30 devnull }
204 76193d7c 2003-09-30 devnull if(T(i))
205 76193d7c 2003-09-30 devnull P(i) = x|M;
206 76193d7c 2003-09-30 devnull else
207 76193d7c 2003-09-30 devnull P(i) = x;
208 76193d7c 2003-09-30 devnull i++;
209 76193d7c 2003-09-30 devnull }
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);
213 76193d7c 2003-09-30 devnull }
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;
220 76193d7c 2003-09-30 devnull else
221 76193d7c 2003-09-30 devnull P(i) = x;
222 76193d7c 2003-09-30 devnull }
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;
229 76193d7c 2003-09-30 devnull else
230 76193d7c 2003-09-30 devnull P(i)=x;
231 76193d7c 2003-09-30 devnull }
232 76193d7c 2003-09-30 devnull }
233 76193d7c 2003-09-30 devnull
234 76193d7c 2003-09-30 devnull void
235 76193d7c 2003-09-30 devnull rgrow(List *r, Posn p1, Posn n)
236 76193d7c 2003-09-30 devnull {
237 76193d7c 2003-09-30 devnull Posn p;
238 76193d7c 2003-09-30 devnull int i;
239 76193d7c 2003-09-30 devnull
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++))
243 76193d7c 2003-09-30 devnull ;
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;
249 76193d7c 2003-09-30 devnull else
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;
261 76193d7c 2003-09-30 devnull }
262 76193d7c 2003-09-30 devnull }
263 76193d7c 2003-09-30 devnull
264 76193d7c 2003-09-30 devnull int
265 76193d7c 2003-09-30 devnull rterm(List *r, Posn p1)
266 76193d7c 2003-09-30 devnull {
267 76193d7c 2003-09-30 devnull Posn p;
268 76193d7c 2003-09-30 devnull int i;
269 76193d7c 2003-09-30 devnull
270 76193d7c 2003-09-30 devnull for(p = 0,i = 0; i<r->nused && p+L(i)<=p1; p+=L(i++))
271 76193d7c 2003-09-30 devnull ;
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);
275 76193d7c 2003-09-30 devnull }
276 76193d7c 2003-09-30 devnull
277 76193d7c 2003-09-30 devnull Range
278 76193d7c 2003-09-30 devnull rdata(List *r, Posn p1, Posn n)
279 76193d7c 2003-09-30 devnull {
280 76193d7c 2003-09-30 devnull Posn p;
281 76193d7c 2003-09-30 devnull int i;
282 76193d7c 2003-09-30 devnull Range rg;
283 76193d7c 2003-09-30 devnull
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++))
287 76193d7c 2003-09-30 devnull ;
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;
295 76193d7c 2003-09-30 devnull }
296 76193d7c 2003-09-30 devnull p+=L(i++);
297 76193d7c 2003-09-30 devnull p1 = p;
298 76193d7c 2003-09-30 devnull }
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;
308 76193d7c 2003-09-30 devnull i++;
309 76193d7c 2003-09-30 devnull }
310 76193d7c 2003-09-30 devnull if(L(i)!=n){
311 76193d7c 2003-09-30 devnull inslist(r, i+1, L(i)-n);
312 76193d7c 2003-09-30 devnull P(i)=n;
313 76193d7c 2003-09-30 devnull }
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);
319 76193d7c 2003-09-30 devnull }
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);
323 76193d7c 2003-09-30 devnull }
324 76193d7c 2003-09-30 devnull return rg;
325 76193d7c 2003-09-30 devnull }