9
#undef EOF /* stdio? */
13
FNSIZE = 128, /* file name */
14
LBSIZE = 4096, /* max line size */
15
BLKSIZE = 4096, /* block size in temp file */
16
NBLK = 8191, /* max size of temp file */
17
ESIZE = 256, /* max size of reg exp */
18
GBSIZE = 256, /* max size of global command */
19
MAXSUB = 9, /* max number of sub reg exp */
20
ESCFLG = 0xFFFF, /* escape Rune - user defined code */
58
Rune rhsbuf[LBSIZE/sizeof(Rune)];
59
char savedfile[FNSIZE];
72
char WRERR[] = "WRITE ERROR";
74
char hex[] = "0123456789abcdef";
82
int append(int(*)(void), int*);
93
Rune* getblock(int, int);
107
void notifyf(void*, char*);
108
Rune* place(Rune*, Rune*, Rune*);
117
void rdelete(int*, int*);
118
void regerror(char *);
119
void reverse(int*, int*);
120
void setnoaddr(void);
123
void substitute(int);
124
char* _mktemp(char *as);
126
Rune La[] = { 'a', 0 };
127
Rune Lr[] = { 'r', 0 };
129
char tmp[] = "/var/tmp/eXXXXX";
132
main(int argc, char *argv[])
145
if(*argv && (strcmp(*argv, "-") == 0)) {
160
if(p2 >= &savedfile[sizeof(savedfile)])
164
zero = malloc((nlall+5)*sizeof(int*));
165
tfname = _mktemp(tmp);
190
if(c != ',' && c != ';')
203
if(lastsep != '\n' && a1 == 0)
205
if((addr2=a1) == 0) {
226
rdelete(addr1, addr2);
227
append(gettty, addr1-1);
233
rdelete(addr1, addr2);
241
if(vflag && fchange) {
275
if(c < 'a' || c > 'z')
278
names[c-'a'] = *addr2 & ~01;
321
if((io=open(file, OREAD)) < 0) {
325
if((d = dirfstat(io)) != nil){
326
if(d->mode & DMAPPEND)
327
print("warning: %s is append only\n", file);
330
Binit(&iobuf, io, OREAD);
334
append(getfile, addr2);
342
substitute(globp != 0);
352
if((*addr2&~01) != subnewa)
368
if(temp != 'q' && temp != 'Q') {
374
((io = open(file, OWRITE)) == -1) ||
375
((seek(io, 0L, 2)) == -1))
376
if((io = create(file, OWRITE, 0666)) < 0)
378
Binit(&iobuf, io, OWRITE);
383
if(addr1<=zero+1 && addr2==dol)
395
count = addr2 - zero;
425
putshst(getline(*a1++));
426
} while(a1 <= addr2);
436
int sign, *a, opcnt, nextopand, *b, c;
445
} while(c == ' ' || c == '\t');
446
if(c >= '0' && c <= '9') {
461
if(opcnt || c < 'a' || c > 'z')
466
} while(a <= dol && names[c-'a'] != (*a & ~01));
486
if(nextopand == opcnt) {
488
if(a < zero || dol < a)
489
continue; /* error(Q); */
491
if(c != '+' && c != '-' && c != '^') {
505
} while(zero <= a && a <= dol);
518
if(c < '0' || c > '9')
530
addr1 = zero + (dol>zero);
551
if(addr1 < zero+i || addr2 > dol || addr1 > addr2)
561
if(c == '\n' || c == EOF)
563
if(c == 'p' || c == 'l' || c == 'n') {
586
if(c == '\n' || c == EOF) {
588
if(*p1 == 0 && comm != 'f')
597
while((c=getchr()) == ' ')
603
if(p1 >= &file[sizeof(file)-6] || c == ' ' || c == EOF)
606
p1 += runetochar(p1, &rune);
607
} while((c=getchr()) != '\n');
609
if(savedfile[0] == 0 || comm == 'e' || comm == 'f') {
622
if(Bflush(&iobuf) < 0)
650
if(c == '\n' || c == EOF)
675
io = create("ed.hup", OWRITE, 0666);
677
Binit(&iobuf, io, OWRITE);
686
notifyf(void *a, char *s)
688
if(strcmp(s, "interrupt") == 0){
689
if(rescuing || waiting)
694
notejmp(a, savej, 0);
696
if(strcmp(s, "hangup") == 0 || strcmp(s, "kill") == 0){
701
if(strstr(s, "child"))
703
fprint(2, "ed: note: %s\n", s);
719
if((lastc=*globp++) != 0)
725
if(read(0, s+i, 1) <= 0)
759
if(p >= &linebuf[LBSIZE-2])
772
if(linebuf[0] == '.' && linebuf[1] == 0)
785
c = Bgetrune(&iobuf);
788
putst("'\\n' appended");
793
if(lp >= &linebuf[LBSIZE]) {
818
if(Bputrune(&iobuf, '\n') < 0)
822
if(Bputrune(&iobuf, c) < 0)
825
} while(a1 <= addr2);
826
if(Bflush(&iobuf) < 0)
831
append(int (*f)(void), int *a)
833
int *a1, *a2, *rdot, nline, d;
838
if((dol-zero) >= nlall) {
840
a1 = realloc(zero, (nlall+50)*sizeof(int*));
845
/* relocate pointers; avoid wraparound if sizeof(int) < sizeof(int*) */
871
if(i && (given || dol > zero)) {
877
append(gettty, addr2);
884
static int bformat, bnum; /* 0 */
889
if(peekc == '-' || peekc == '+') {
912
addr1 = addr2-bpagesize;
929
while((c=getchr()) != EOF && c != '\n')
930
if(p < &buf[sizeof(buf) - 6]) {
932
p += runetochar(p, &rune);
937
execlp("rc", "rc", "-c", buf, (char*)0);
938
sysfatal("exec failed: %r");
939
exits("execl failed");
942
while(waitpid() != pid)
952
if(vflag && fchange && dol!=zero) {
968
rdelete(int *ad1, int *ad2)
992
for(a1=zero; (*a1&01)==0; a1++)
995
for(a2=a1+1; a2<=a3;) {
1015
bp = getblock(tl, OREAD);
1017
tl &= ~((BLKSIZE/sizeof(Rune)) - 1);
1018
while(*lp++ = *bp++) {
1021
bp = getblock(tl += BLKSIZE/sizeof(Rune), OREAD);
1037
bp = getblock(tl, OWRITE);
1039
tl &= ~((BLKSIZE/sizeof(Rune))-1);
1040
while(*bp = *lp++) {
1048
tl += BLKSIZE/sizeof(Rune);
1049
bp = getblock(tl, OWRITE);
1054
tline += ((lp-linebuf) + 03) & 077776;
1059
blkio(int b, uchar *buf, int isread)
1063
seek(tfile, b*BLKSIZE, 0);
1065
n = read(tfile, buf, BLKSIZE);
1067
n = write(tfile, buf, BLKSIZE);
1073
getblock(int atl, int iof)
1077
static uchar ibuff[BLKSIZE];
1078
static uchar obuff[BLKSIZE];
1080
bno = atl / (BLKSIZE/sizeof(Rune));
1081
off = (atl*sizeof(Rune)) & (BLKSIZE-1) & ~03;
1086
nleft = BLKSIZE - off;
1089
return (Rune*)(ibuff+off);
1092
return (Rune*)(obuff+off);
1095
blkio(iblock, ibuff, 0);
1098
blkio(bno, ibuff, 1);
1099
return (Rune*)(ibuff+off);
1102
blkio(oblock, obuff, 0);
1104
return (Rune*)(obuff+off);
1114
for(markp = names; markp < &names[26]; )
1121
if((tfile = create(tfname, ORDWR, 0600)) < 0){
1131
Rune *gp, globuf[GBSIZE];
1137
squeeze(dol > zero);
1143
while((c=getchr()) != '\n') {
1152
if(gp >= &globuf[GBSIZE-2])
1159
for(a1=zero; a1<=dol; a1++) {
1161
if(a1 >= addr1 && a1 <= addr2 && match(a1) == k)
1166
* Special case: g/.../d (avoid n^2 algorithm)
1168
if(globuf[0] == 'd' && globuf[1] == '\n' && globuf[2] == 0) {
1172
for(a1=zero; a1<=dol; a1++) {
1191
for(a1=addr1; a1<=addr2; a1++) {
1194
if(gp++ >= &genbuf[LBSIZE-2])
1199
while(*lp++ = *gp++)
1203
rdelete(addr1+1, addr2);
1208
substitute(int inglob)
1210
int *mp, *a1, nl, gsubf, n;
1212
n = getnum(); /* OK even if n==0 */
1214
for(a1 = addr1; a1 <= addr2; a1++) {
1220
int span = loc2-loc1;
1226
if(span == 0) { /* null RE match */
1235
subnewa = putline();
1238
for(mp=names; mp<&names[26]; mp++)
1245
nl = append(getsub, a1);
1263
if(seof == '\n' || seof == ' ')
1272
if(p >= &rhsbuf[LBSIZE/sizeof(Rune)])
1275
if(c == '\n' && (!globp || !globp[0])) {
1283
if(p >= &rhsbuf[LBSIZE/sizeof(Rune)])
1303
if((p2 = linebp) == 0)
1305
while(*p1++ = *p2++)
1324
sp = place(sp, loc1, loc2);
1327
if(c == ESCFLG && (c = *rp++) >= '1' && c < MAXSUB+'0') {
1329
if(subexp[n].s.rsp && subexp[n].e.rep) {
1330
sp = place(sp, subexp[n].s.rsp, subexp[n].e.rep);
1336
if(sp >= &genbuf[LBSIZE])
1340
loc2 = sp - genbuf + linebuf;
1341
while(*sp++ = *lp++)
1342
if(sp >= &genbuf[LBSIZE])
1346
while(*lp++ = *sp++)
1351
place(Rune *sp, Rune *l1, Rune *l2)
1356
if(sp >= &genbuf[LBSIZE])
1365
int *adt, *ad1, *ad2;
1368
if((adt = address())==0) /* address() guarantees addr is in range */
1375
append(getcopy, ad1++);
1377
delta = zero - ozero;
1382
for(ad1 = addr1; ad1 <= ad2;)
1388
dot = adt + (ad2-ad1);
1406
reverse(int *a1, int *a2)
1435
if((c = getchr()) == '\n') {
1451
if(ep >= expbuf+sizeof(expbuf)) {
1455
ep += runetochar(ep, &c);
1456
if((c = getchr()) == '\n') {
1461
if(ep >= expbuf+sizeof(expbuf)) {
1465
ep += runetochar(ep, &c);
1466
} while((c = getchr()) != eof && c != '\n');
1470
pattern = regcomp(expbuf);
1481
subexp[0].s.rsp = getline(*addr);
1483
subexp[0].s.rsp = loc2;
1484
subexp[0].e.rep = 0;
1485
if(rregexec(pattern, linebuf, subexp, MAXSUB)) {
1486
loc1 = subexp[0].s.rsp;
1487
loc2 = subexp[0].e.rep;
1514
sp += chartorune(&r, sp);
1542
if(linp != line && linp[-1] == ' ') {
1547
if(col > (72-6-2)) {
1554
if(c=='\b' || c=='\t' || c=='\\') {
1563
if(c<' ' || c>='\177') {
1567
*lp++ = hex[c>>8&0xF];
1568
*lp++ = hex[c>>4&0xF];
1576
lp += runetochar(lp, &rune);
1578
if(c == '\n' || lp >= &line[sizeof(line)-5]) {
1580
write(oflag? 2: 1, line, lp-line);
1598
while(*--s == 'X') {
1599
*s = pid % 10 + '0';
1604
while(access(as, 0) != -1) {