📄 ed.c
字号:
c = *lp++; if(c == 0) { if(Bputrune(&iobuf, '\n') < 0) error(Q); break; } if(Bputrune(&iobuf, c) < 0) error(Q); } } while(a1 <= addr2); if(Bflush(&iobuf) < 0) error(Q);}intappend(int (*f)(void), int *a){ int *a1, *a2, *rdot, nline, tl; nline = 0; dot = a; while((*f)() == 0) { if((dol-zero) >= nlall) { nlall += 512; a1 = realloc(zero, (nlall+5)*sizeof(int*)); if(a1 == 0) { error("MEM?"); rescue(); } tl = a1 - zero; /* relocate pointers */ zero += tl; addr1 += tl; addr2 += tl; dol += tl; dot += tl; } tl = putline(); nline++; a1 = ++dol; a2 = a1+1; rdot = ++dot; while(a1 > rdot) *--a2 = *--a1; *rdot = tl; } return nline;}voidadd(int i){ if(i && (given || dol > zero)) { addr1--; addr2--; } squeeze(0); newline(); append(gettty, addr2);}voidbrowse(void){ int forward, n; static bformat, bnum; /* 0 */ forward = 1; peekc = getchr(); if(peekc != '\n'){ if(peekc == '-' || peekc == '+') { if(peekc == '-') forward = 0; getchr(); } n = getnum(); if(n > 0) bpagesize = n; } newline(); if(pflag) { bformat = listf; bnum = listn; } else { listf = bformat; listn = bnum; } if(forward) { addr1 = addr2; addr2 += bpagesize; if(addr2 > dol) addr2 = dol; } else { addr1 = addr2-bpagesize; if(addr1 <= zero) addr1 = zero+1; } printcom();}voidcallunix(void){ int c, pid; Rune rune; char buf[512]; char *p; setnoaddr(); p = buf; while((c=getchr()) != EOF && c != '\n') if(p < &buf[sizeof(buf) - 6]) { rune = c; p += runetochar(p, &rune); } *p = 0; pid = fork(); if(pid == 0) { execl("/bin/rc", "rc", "-c", buf, nil); exits("execl failed"); } waiting = 1; while(waitpid() != pid) ; waiting = 0; if(vflag) putst("!");}voidquit(void){ if(vflag && fchange && dol!=zero) { fchange = 0; error(Q); } remove(tfname); exits(0);}voidonquit(int sig){ USED(sig); quit();}voidrdelete(int *ad1, int *ad2){ int *a1, *a2, *a3; a1 = ad1; a2 = ad2+1; a3 = dol; dol -= a2 - a1; do { *a1++ = *a2++; } while(a2 <= a3); a1 = ad1; if(a1 > dol) a1 = dol; dot = a1; fchange = 1;}voidgdelete(void){ int *a1, *a2, *a3; a3 = dol; for(a1=zero; (*a1&01)==0; a1++) if(a1>=a3) return; for(a2=a1+1; a2<=a3;) { if(*a2 & 01) { a2++; dot = a1; } else *a1++ = *a2++; } dol = a1-1; if(dot > dol) dot = dol; fchange = 1;}Rune*getline(int tl){ Rune *lp, *bp; int nl; lp = linebuf; bp = getblock(tl, OREAD); nl = nleft; tl &= ~((BLKSIZE/2) - 1); while(*lp++ = *bp++) { nl -= sizeof(Rune); if(nl == 0) { bp = getblock(tl += BLKSIZE/2, OREAD); nl = nleft; } } return linebuf;}intputline(void){ Rune *lp, *bp; int nl, tl; fchange = 1; lp = linebuf; tl = tline; bp = getblock(tl, OWRITE); nl = nleft; tl &= ~((BLKSIZE/2)-1); while(*bp = *lp++) { if(*bp++ == '\n') { bp[-1] = 0; linebp = lp; break; } nl -= sizeof(Rune); if(nl == 0) { tl += BLKSIZE/2; bp = getblock(tl, OWRITE); nl = nleft; } } nl = tline; tline += ((lp-linebuf) + 03) & 077776; return nl;}voidblkio(int b, uchar *buf, long (*iofcn)(int, void *, long)){ seek(tfile, b*BLKSIZE, 0); if((*iofcn)(tfile, buf, BLKSIZE) != BLKSIZE) { error(T); }}Rune*getblock(int atl, int iof){ int bno, off; static uchar ibuff[BLKSIZE]; static uchar obuff[BLKSIZE]; bno = atl / (BLKSIZE/2); off = (atl<<1) & (BLKSIZE-1) & ~03; if(bno >= NBLK) { lastc = '\n'; error(T); } nleft = BLKSIZE - off; if(bno == iblock) { ichanged |= iof; return (Rune*)(ibuff+off); } if(bno == oblock) return (Rune*)(obuff+off); if(iof == OREAD) { if(ichanged) blkio(iblock, ibuff, write); ichanged = 0; iblock = bno; blkio(bno, ibuff, read); return (Rune*)(ibuff+off); } if(oblock >= 0) blkio(oblock, obuff, write); oblock = bno; return (Rune*)(obuff+off);}voidinit(void){ int *markp; close(tfile); tline = 2; for(markp = names; markp < &names[26]; ) *markp++ = 0; subnewa = 0; anymarks = 0; iblock = -1; oblock = -1; ichanged = 0; if((tfile = create(tfname, ORDWR, 0600)) < 0){ error1(T); exits(0); } dot = dol = zero;}voidglobal(int k){ Rune *gp, globuf[GBSIZE]; int c, *a1; if(globp) error(Q); setwide(); squeeze(dol > zero); c = getchr(); if(c == '\n') error(Q); compile(c); gp = globuf; while((c=getchr()) != '\n') { if(c == EOF) error(Q); if(c == '\\') { c = getchr(); if(c != '\n') *gp++ = '\\'; } *gp++ = c; if(gp >= &globuf[GBSIZE-2]) error(Q); } if(gp == globuf) *gp++ = 'p'; *gp++ = '\n'; *gp = 0; for(a1=zero; a1<=dol; a1++) { *a1 &= ~01; if(a1 >= addr1 && a1 <= addr2 && match(a1) == k) *a1 |= 01; } /* * Special case: g/.../d (avoid n^2 algorithm) */ if(globuf[0] == 'd' && globuf[1] == '\n' && globuf[2] == 0) { gdelete(); return; } for(a1=zero; a1<=dol; a1++) { if(*a1 & 01) { *a1 &= ~01; dot = a1; globp = globuf; commands(); a1 = zero; } }}voidjoin(void){ Rune *gp, *lp; int *a1; nonzero(); gp = genbuf; for(a1=addr1; a1<=addr2; a1++) { lp = getline(*a1); while(*gp = *lp++) if(gp++ >= &genbuf[LBSIZE-2]) error(Q); } lp = linebuf; gp = genbuf; while(*lp++ = *gp++) ; *addr1 = putline(); if(addr1 < addr2) rdelete(addr1+1, addr2); dot = addr1;}voidsubstitute(int inglob){ int *mp, *a1, nl, gsubf, n; n = getnum(); /* OK even if n==0 */ gsubf = compsub(); for(a1 = addr1; a1 <= addr2; a1++) { if(match(a1)){ int *ozero; int m = n; do { int span = loc2-loc1; if(--m <= 0) { dosub(); if(!gsubf) break; if(span == 0) { /* null RE match */ if(*loc2 == 0) break; loc2++; } } } while(match(0)); if(m <= 0) { inglob |= 01; subnewa = putline(); *a1 &= ~01; if(anymarks) { for(mp=names; mp<&names[26]; mp++) if(*mp == *a1) *mp = subnewa; } subolda = *a1; *a1 = subnewa; ozero = zero; nl = append(getsub, a1); addr2 += nl; nl += zero-ozero; a1 += nl; } } } if(inglob == 0) error(Q);}intcompsub(void){ int seof, c; Rune *p; seof = getchr(); if(seof == '\n' || seof == ' ') error(Q); compile(seof); p = rhsbuf; for(;;) { c = getchr(); if(c == '\\') { c = getchr(); *p++ = ESCFLG; if(p >= &rhsbuf[LBSIZE/2]) error(Q); } else if(c == '\n' && (!globp || !globp[0])) { peekc = c; pflag++; break; } else if(c == seof) break; *p++ = c; if(p >= &rhsbuf[LBSIZE/2]) error(Q); } *p = 0; peekc = getchr(); if(peekc == 'g') { peekc = 0; newline(); return 1; } newline(); return 0;}intgetsub(void){ Rune *p1, *p2; p1 = linebuf; if((p2 = linebp) == 0) return EOF; while(*p1++ = *p2++) ; linebp = 0; return 0;}voiddosub(void){ Rune *lp, *sp, *rp; int c, n; lp = linebuf; sp = genbuf; rp = rhsbuf; while(lp < loc1) *sp++ = *lp++; while(c = *rp++) { if(c == '&'){ sp = place(sp, loc1, loc2); continue; } if(c == ESCFLG && (c = *rp++) >= '1' && c < MAXSUB+'0') { n = c-'0'; if(subexp[n].rsp && subexp[n].rep) { sp = place(sp, subexp[n].rsp, subexp[n].rep); continue; } error(Q); } *sp++ = c; if(sp >= &genbuf[LBSIZE]) error(Q); } lp = loc2; loc2 = sp - genbuf + linebuf; while(*sp++ = *lp++) if(sp >= &genbuf[LBSIZE]) error(Q); lp = linebuf; sp = genbuf; while(*lp++ = *sp++) ;}Rune*place(Rune *sp, Rune *l1, Rune *l2){ while(l1 < l2) { *sp++ = *l1++; if(sp >= &genbuf[LBSIZE]) error(Q); } return sp;}voidmove(int cflag){ int *adt, *ad1, *ad2; nonzero(); if((adt = address())==0) /* address() guarantees addr is in range */ error(Q); newline(); if(cflag) { int *ozero, delta; ad1 = dol; ozero = zero; append(getcopy, ad1++); ad2 = dol; delta = zero - ozero; ad1 += delta; adt += delta; } else { ad2 = addr2; for(ad1 = addr1; ad1 <= ad2;) *ad1++ &= ~01; ad1 = addr1; } ad2++; if(adt<ad1) { dot = adt + (ad2-ad1); if((++adt)==ad1) return; reverse(adt, ad1); reverse(ad1, ad2); reverse(adt, ad2); } else if(adt >= ad2) { dot = adt++; reverse(ad1, ad2); reverse(ad2, adt); reverse(ad1, adt); } else error(Q); fchange = 1;}voidreverse(int *a1, int *a2){ int t; for(;;) { t = *--a2; if(a2 <= a1) return; *a2 = *a1; *a1++ = t; }}intgetcopy(void){ if(addr1 > addr2) return EOF; getline(*addr1++); return 0;}voidcompile(int eof){ Rune c; char *ep; char expbuf[ESIZE]; if((c = getchr()) == '\n') { peekc = c; c = eof; } if(c == eof) { if(!pattern) error(Q); return; } if(pattern) { free(pattern); pattern = 0; } ep = expbuf; do { if(c == '\\') { if(ep >= expbuf+sizeof(expbuf)) { error(Q); return; } ep += runetochar(ep, &c); if((c = getchr()) == '\n') { error(Q); return; } } if(ep >= expbuf+sizeof(expbuf)) { error(Q); return; } ep += runetochar(ep, &c); } while((c = getchr()) != eof && c != '\n'); if(c == '\n') peekc = c; *ep = 0; pattern = regcomp(expbuf);}intmatch(int *addr){ if(!pattern) return 0; if(addr){ if(addr == zero) return 0; subexp[0].rsp = getline(*addr); } else subexp[0].rsp = loc2; subexp[0].rep = 0; if(rregexec(pattern, linebuf, subexp, MAXSUB)) { loc1 = subexp[0].rsp; loc2 = subexp[0].rep; return 1; } loc1 = loc2 = 0; return 0; }voidputd(void){ int r; r = count%10; count /= 10; if(count) putd(); putchr(r + L'0');}voidputst(char *sp){ Rune r; col = 0; for(;;) { sp += chartorune(&r, sp); if(r == 0) break; putchr(r); } putchr(L'\n');}voidputshst(Rune *sp){ col = 0; while(*sp) putchr(*sp++); putchr(L'\n');}voidputchr(int ac){ char *lp; int c; Rune rune; lp = linp; c = ac; if(listf) { if(c == '\n') { if(linp != line && linp[-1] == ' ') { *lp++ = '\\'; *lp++ = 'n'; } } else { if(col > (72-6-2)) { col = 8; *lp++ = '\\'; *lp++ = '\n'; *lp++ = '\t'; } col++; if(c=='\b' || c=='\t' || c=='\\') { *lp++ = '\\'; if(c == '\b') c = 'b'; else if(c == '\t') c = 't'; col++; } else if(c<' ' || c>='\177') { *lp++ = '\\'; *lp++ = 'x'; *lp++ = hex[c>>12]; *lp++ = hex[c>>8&0xF]; *lp++ = hex[c>>4&0xF]; c = hex[c&0xF]; col += 5; } } } rune = c; lp += runetochar(lp, &rune); if(c == '\n' || lp >= &line[sizeof(line)-5]) { linp = line; write(oflag? 2: 1, line, lp-line); return; } linp = lp;}char*mktemp(char *as){ char *s; unsigned pid; int i; pid = getpid(); s = as; while(*s++) ; s--; while(*--s == 'X') { *s = pid % 10 + '0'; pid /= 10; } s++; i = 'a'; while(access(as, 0) != -1) { if(i == 'z') return "/"; *s = i++; } return as;}voidregerror(char *s){ USED(s); error(Q);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -