|
|
1.1 root 1: #include "samterm.h"
2:
3: rinit(r)
4: register Rasp *r;
5: {
6: r->nbytes=0;
7: r->sect=0;
8: }
9: rclear(r)
10: register Rasp *r;
11: {
12: register Section *s, *ns;
13: for(s=r->sect; s; s=ns){
14: ns=s->next;
15: gcfree(s->text);
16: free(s);
17: }
18: r->sect=0;
19: }
20: Section *
21: rsinsert(r, s) /* insert before s */
22: register Rasp *r;
23: register Section *s;
24: {
25: register Section *t=(Section *)ALLOC(sizeof(Section));
26: register Section *u;
27: if(r->sect==s){ /* includes empty list case: r->sect==s==0 */
28: r->sect=t;
29: t->next=s;
30: }else{
31: u=r->sect;
32: if(u==0)
33: panic("rsinsert 1");
34: do{
35: if(u->next==s){
36: t->next=s;
37: u->next=t;
38: goto Return;
39: }
40: u=u->next;
41: }while(u);
42: panic("rsinsert 2");
43: }
44: Return:
45: return t; /* for cyntax */
46: }
47: rsdelete(r, s)
48: register Rasp *r;
49: register Section *s;
50: {
51: register Section *t;
52: if(s==0)
53: panic("rsdelete");
54: if(r->sect==s){
55: r->sect=s->next;
56: goto Free;
57: }
58: for(t=r->sect; t; t=t->next)
59: if(t->next==s){
60: t->next=s->next;
61: Free:
62: gcfree(s->text); /* freeing 0 is ok */
63: free(s);
64: return;
65: }
66: panic("rsdelete 2");
67: }
68: splitsect(r, s, n0)
69: register Rasp *r;
70: register Section *s;
71: register long n0;
72: {
73: if(s==0)
74: panic("splitsect");
75: rsinsert(r, s->next);
76: if(s->text==0)
77: s->next->text=0;
78: else{
79: GCALLOC(TBLOCKSIZE+1, &s->next->text);
80: copystr(s->text+n0, s->next->text);
81: s->text[n0]=0;
82: }
83: s->next->nbytes=s->nbytes-n0;
84: s->nbytes=n0;
85: }
86: Section *
87: findsect(r, s, p, q) /* find sect containing q and put q on a sect boundary */
88: register Rasp *r;
89: register Section *s;
90: register long p, q;
91: {
92: if(s==0 && p!=q)
93: panic("findsect");
94: for(; s && p+s->nbytes<=q; s=s->next)
95: p+=s->nbytes;
96: if(p!=q){
97: splitsect(r, s, q-p);
98: s=s->next;
99: }
100: return s;
101: }
102: rresize(r, a, old, new)
103: register Rasp *r;
104: register long a;
105: long old, new;
106: {
107: register Section *s, *t, *ns;
108: s=findsect(r, r->sect, 0L, a);
109: t=findsect(r, s, a, a+old);
110: for(; s!=t; s=ns){
111: ns=s->next;
112: rsdelete(r, s);
113: }
114: /* now insert the new piece before t */
115: if(new>0){
116: ns=rsinsert(r, t);
117: ns->nbytes=new;
118: ns->text=0;
119: }
120: r->nbytes+=new-old;
121: }
122: rdata(r, p0, p1, cp)
123: register Rasp *r;
124: register long p0, p1;
125: uchar *cp;
126: {
127: register Section *s, *t, *ns;
128: s=findsect(r, r->sect, 0L, p0);
129: t=findsect(r, s, p0, p1);
130: for(; s!=t; s=ns){
131: ns=s->next;
132: if(s->text)
133: panic("rdata");
134: rsdelete(r, s);
135: }
136: p1-=p0;
137: s=rsinsert(r, t);
138: GCALLOC(TBLOCKSIZE+1, &s->text);
139: copystr(cp, s->text);
140: s->nbytes=p1;
141: }
142: rclean(r)
143: register Rasp *r;
144: {
145: register Section *s;
146: for(s=r->sect; s; s=s->next)
147: while(s->next && (s->text!=0)==(s->next->text!=0)){
148: if(s->text){
149: if(s->nbytes+s->next->nbytes>TBLOCKSIZE)
150: break;
151: copystr(s->next->text, s->text+s->nbytes);
152: }
153: s->nbytes+=s->next->nbytes;
154: rsdelete(r, s->next);
155: }
156: }
157: uchar **
158: rload(r, p0, p1)
159: register Rasp *r;
160: register unsigned long p0, p1;
161: {
162: register Section *s;
163: register long p;
164: register n, nb=0;
165: strgrow(&scratch, &nscralloc, (int)(p1-p0+1));
166: scratch[0]=0;
167: for(p=0,s=r->sect; s && p+s->nbytes<=p0; s=s->next)
168: p+=s->nbytes;
169: while(p<p1 && s){
170: /*
171: * Subtle and important. If we are preparing to handle an 'rdata'
172: * call, it's because we have an 'rresize' hole here, so the
173: * screen doesn't have data for that space anyway (it got cut
174: * first). So pretend it isn't there.
175: */
176: if(s->text){
177: n=s->nbytes-(p0-p);
178: if(n>p1-p0) /* all in this section */
179: n=p1-p0;
180: copystrn(s->text+(p0-p), scratch+nb, n);
181: nb+=n;
182: }
183: p+=s->nbytes;
184: p0=p;
185: s=s->next;
186: }
187: return &scratch;
188: }
189: rmissing(r, p0, p1)
190: register Rasp *r;
191: register unsigned long p0, p1;
192: {
193: register Section *s;
194: register long p;
195: register n;
196: register nm=0;
197: for(p=0,s=r->sect; s && p+s->nbytes<=p0; s=s->next)
198: p+=s->nbytes;
199: while(p<p1 && s){
200: if(s->text==0){
201: n=s->nbytes-(p0-p);
202: if(n>p1-p0) /* all in this section */
203: n=p1-p0;
204: nm+=n;
205: }
206: p+=s->nbytes;
207: p0=p;
208: s=s->next;
209: }
210: return nm;
211: }
212: rcontig(r, p0, p1, text)
213: register Rasp *r;
214: register unsigned long p0, p1;
215: {
216: register Section *s;
217: register long p;
218: register n;
219: register np=0;
220: for(p=0,s=r->sect; s && p+s->nbytes<=p0; s=s->next)
221: p+=s->nbytes;
222: while(p<p1 && s && (text? (int)s->text : (s->text==0))){
223: n=s->nbytes-(p0-p);
224: if(n>p1-p0) /* all in this section */
225: n=p1-p0;
226: np+=n;
227: p+=s->nbytes;
228: p0=p;
229: s=s->next;
230: }
231: return np;
232: }
233: copystrn(from, to, n)
234: register uchar *from, *to;
235: register n;
236: {
237: if(n) do
238: *to++ = *from++;
239: while(--n);
240: *to=0;
241: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.