|
|
1.1 ! root 1: #include "sam.h" ! 2: /* ! 3: * GROWDATASIZE must be big enough that all errors go out as Hgrowdata's, ! 4: * so they will be scrolled into visibility in the ~~sam~~ window (yuck!). ! 5: */ ! 6: #define GROWDATASIZE 50 /* if size is < this, send data with grow */ ! 7: ! 8: toterminal(f, toterm) ! 9: register File *f; ! 10: { ! 11: register Buffer *t=f->transcript; ! 12: register Posn n, p0, p1, p2, nbytes, delta=0, deltacmd=0; ! 13: Range r; ! 14: uchar buf[16+GROWDATASIZE]; ! 15: if(f->rasp==0) ! 16: return; ! 17: nbytes=f->nbytes; ! 18: if(f->marked) ! 19: p0=f->markp+sizeof(Mark); ! 20: else ! 21: p0=0; ! 22: while(Bread(t, buf, sizeof buf, p0)>0){ ! 23: switch(buf[0]){ ! 24: default: ! 25: panic("unknown in toterminal"); ! 26: case 'd': ! 27: GETPOSN(p1, buf+1); ! 28: GETPOSN(p2, buf+1+sizeof(Posn)); ! 29: p1+=delta, p2+=delta; ! 30: if(p2<=p1) ! 31: panic("toterminal delete 0"); ! 32: if(f==cmd && p1<cmdpt){ ! 33: if(p2<=cmdpt) ! 34: deltacmd-=(p2-p1); ! 35: else ! 36: deltacmd-=cmdpt-p1; ! 37: } ! 38: p0+=1+2*sizeof(Posn); ! 39: if(toterm) ! 40: outTsll(Hcut, f->tag, p1, p2-p1); ! 41: rcut(f->rasp, p1, p2); ! 42: delta-=p2-p1; ! 43: nbytes-=p2-p1; ! 44: break; ! 45: case 'f': ! 46: n=buf[1]&0xFF; ! 47: n|=buf[2]<<8; ! 48: p0+=1+SS+n; ! 49: break; ! 50: case 'i': ! 51: n=buf[1]&0xFF; ! 52: n|=buf[2]<<8; ! 53: if(n<=0) ! 54: panic("toterminal insert 0"); ! 55: GETPOSN(p1, (buf+1+SS)); ! 56: p1+=delta; ! 57: p0+=1+SS+sizeof(Posn)+n; ! 58: if(f==cmd && p1<cmdpt) ! 59: deltacmd+=n; ! 60: if(toterm){ ! 61: if(n>GROWDATASIZE || !rterm(f->rasp, p1)){ ! 62: rgrow(f->rasp, p1, n); ! 63: outTsll(Hgrow, f->tag, p1, n); ! 64: }else{ ! 65: uchar *s=buf+1+SS+sizeof(Posn); ! 66: rgrow(f->rasp, p1, n); ! 67: r=rdata(f->rasp, p1, n); ! 68: if(r.p1!=p1 || r.p2!=p1+n) ! 69: panic("rdata in toterminal"); ! 70: s[n]=0; ! 71: outTsllS(Hgrowdata, f->tag, p1, n, s); ! 72: } ! 73: }else{ ! 74: rgrow(f->rasp, p1, n); ! 75: r=rdata(f->rasp, p1, n); ! 76: if(r.p1!=p1 || r.p2!=p1+n) ! 77: panic("rdata in toterminal"); ! 78: } ! 79: delta+=n; ! 80: nbytes+=n; ! 81: break; ! 82: } ! 83: } ! 84: if(toterm) ! 85: outTs(Hcheck0, f->tag); ! 86: if(f==cmd){ ! 87: cmdpt+=deltacmd+cmdptadv; ! 88: cmdptadv=0; ! 89: } ! 90: } ! 91: #define M 0x80000000L ! 92: #define P(i) r->ptr[i] ! 93: #define T(i) (P(i)&M) /* in terminal */ ! 94: #define L(i) (P(i)&~M) /* length of this piece */ ! 95: rcut(r, p1, p2) ! 96: register List *r; ! 97: register Posn p1, p2; ! 98: { ! 99: register Posn p, x; ! 100: register i; ! 101: if(p1==p2) ! 102: panic("rcut 0"); ! 103: for(p=0,i=0; i<r->nused && p+L(i)<=p1; p+=L(i++)) ! 104: ; ! 105: if(i==r->nused) ! 106: panic("rcut 1"); ! 107: if(p<p1){ /* chop this piece */ ! 108: if(p+L(i)<p2){ ! 109: x=p1-p; ! 110: p+=L(i); ! 111: }else{ ! 112: x=L(i)-(p2-p1); ! 113: p=p2; ! 114: } ! 115: if(T(i)) ! 116: P(i)=x|M; ! 117: else ! 118: P(i)=x; ! 119: i++; ! 120: } ! 121: while(i<r->nused && p+L(i)<=p2){ ! 122: p+=L(i); ! 123: dellist(r, i); ! 124: } ! 125: if(p<p2){ ! 126: if(i==r->nused) ! 127: panic("rcut 2"); ! 128: x=L(i)-(p2-p); ! 129: if(T(i)) ! 130: P(i)=x|M; ! 131: else ! 132: P(i)=x; ! 133: } ! 134: /* can we merge i and i-1 ? */ ! 135: if(i>0 && i<r->nused && T(i-1)==T(i)){ ! 136: x=L(i-1)+L(i); ! 137: dellist(r, i--); ! 138: if(T(i)) ! 139: P(i)=x|M; ! 140: else ! 141: P(i)=x; ! 142: } ! 143: } ! 144: rgrow(r, p1, n) ! 145: register List *r; ! 146: register Posn p1, n; ! 147: { ! 148: register Posn p; ! 149: register i; ! 150: if(n==0) ! 151: panic("rgrow 0"); ! 152: for(p=0,i=0; i<r->nused && p+L(i)<=p1; p+=L(i++)) ! 153: ; ! 154: if(i==r->nused){ /* stick on end of file */ ! 155: if(p!=p1) ! 156: panic("rgrow 1"); ! 157: if(i>0 && !T(i-1)) ! 158: P(i-1)+=n; ! 159: else ! 160: inslist(r, i, n); ! 161: }else if(!T(i)) /* goes in this empty piece */ ! 162: P(i)+=n; ! 163: else if(p==p1 && i>0 && !T(i-1)) /* special case; simplifies life */ ! 164: P(i-1)+=n; ! 165: else if(p==p1) ! 166: inslist(r, i, n); ! 167: else{ /* must break piece in terminal */ ! 168: inslist(r, i+1, (L(i)-(p1-p))|M); ! 169: inslist(r, i+1, n); ! 170: P(i)=(p1-p)|M; ! 171: } ! 172: } ! 173: rterm(r, p1) ! 174: register List *r; ! 175: register Posn p1; ! 176: { ! 177: register Posn p; ! 178: register i; ! 179: for(p=0,i=0; i<r->nused && p+L(i)<=p1; p+=L(i++)) ! 180: ; ! 181: if(i==r->nused && (i==0 || !T(i-1))) ! 182: return 0; ! 183: return T(i); ! 184: } ! 185: Range ! 186: rdata(r, p1, n) ! 187: register List *r; ! 188: register Posn p1, n; ! 189: { ! 190: register Posn p; ! 191: register i; ! 192: Range rg; ! 193: if(n==0) ! 194: panic("rdata 0"); ! 195: for(p=0,i=0; i<r->nused && p+L(i)<=p1; p+=L(i++)) ! 196: ; ! 197: if(i==r->nused) ! 198: panic("rdata 1"); ! 199: if(T(i)){ ! 200: n-=L(i)-(p1-p); ! 201: if(n<=0){ ! 202: rg.p1=rg.p2=p1; ! 203: return rg; ! 204: } ! 205: p+=L(i++); ! 206: p1=p; ! 207: } ! 208: if(T(i) || i==r->nused) ! 209: panic("rdata 2"); ! 210: if(p+L(i)<p1+n) ! 211: n=L(i)-(p1-p); ! 212: rg.p1=p1; ! 213: rg.p2=p1+n; ! 214: if(p!=p1){ ! 215: inslist(r, i+1, L(i)-(p1-p)); ! 216: P(i)=p1-p; ! 217: i++; ! 218: } ! 219: if(L(i)!=n){ ! 220: inslist(r, i+1, L(i)-n); ! 221: P(i)=n; ! 222: } ! 223: P(i)|=M; ! 224: /* now i is set; can we merge? */ ! 225: if(i<r->nused-1 && T(i+1)){ ! 226: P(i)=(n+=L(i+1))|M; ! 227: dellist(r, i+1); ! 228: } ! 229: if(i>0 && T(i-1)){ ! 230: P(i)=(n+L(i-1))|M; ! 231: dellist(r, i-1); ! 232: } ! 233: return rg; ! 234: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.