13e12c5d1SDavid du Colombier /* 23e12c5d1SDavid du Colombier * Editor 33e12c5d1SDavid du Colombier */ 43e12c5d1SDavid du Colombier #include <u.h> 53e12c5d1SDavid du Colombier #include <libc.h> 63e12c5d1SDavid du Colombier #include <bio.h> 7*219b2ee8SDavid du Colombier #include <regexp.h> 83e12c5d1SDavid du Colombier 93e12c5d1SDavid du Colombier enum 103e12c5d1SDavid du Colombier { 113e12c5d1SDavid du Colombier FNSIZE = 128, /* file name */ 123e12c5d1SDavid du Colombier LBSIZE = 4096, /* max line size */ 133e12c5d1SDavid du Colombier BLKSIZE = 4096, /* block size in temp file */ 14*219b2ee8SDavid du Colombier NBLK = 4095, /* max size of temp file */ 153e12c5d1SDavid du Colombier ESIZE = 256, /* max size of reg exp */ 163e12c5d1SDavid du Colombier GBSIZE = 256, /* max size of global command */ 173e12c5d1SDavid du Colombier MAXSUB = 9, /* max number of sub reg exp */ 183e12c5d1SDavid du Colombier ESCFLG = 0xFFFF, /* escape Rune - user defined code */ 193e12c5d1SDavid du Colombier EOF = -1, 203e12c5d1SDavid du Colombier }; 213e12c5d1SDavid du Colombier 223e12c5d1SDavid du Colombier void (*oldhup)(int); 233e12c5d1SDavid du Colombier void (*oldquit)(int); 243e12c5d1SDavid du Colombier int* addr1; 253e12c5d1SDavid du Colombier int* addr2; 263e12c5d1SDavid du Colombier int anymarks; 273e12c5d1SDavid du Colombier int col; 283e12c5d1SDavid du Colombier long count; 293e12c5d1SDavid du Colombier int* dol; 303e12c5d1SDavid du Colombier int* dot; 313e12c5d1SDavid du Colombier int fchange; 323e12c5d1SDavid du Colombier char file[FNSIZE]; 333e12c5d1SDavid du Colombier Rune genbuf[LBSIZE]; 343e12c5d1SDavid du Colombier int given; 353e12c5d1SDavid du Colombier Rune* globp; 363e12c5d1SDavid du Colombier int iblock; 373e12c5d1SDavid du Colombier int ichanged; 383e12c5d1SDavid du Colombier int io; 393e12c5d1SDavid du Colombier Biobuf iobuf; 403e12c5d1SDavid du Colombier int lastc; 413e12c5d1SDavid du Colombier char line[70]; 423e12c5d1SDavid du Colombier Rune* linebp; 433e12c5d1SDavid du Colombier Rune linebuf[LBSIZE]; 443e12c5d1SDavid du Colombier int listf; 453e12c5d1SDavid du Colombier int listn; 463e12c5d1SDavid du Colombier Rune* loc1; 473e12c5d1SDavid du Colombier Rune* loc2; 483e12c5d1SDavid du Colombier int names[26]; 493e12c5d1SDavid du Colombier int nleft; 503e12c5d1SDavid du Colombier int oblock; 513e12c5d1SDavid du Colombier int oflag; 523e12c5d1SDavid du Colombier Reprog *pattern; 533e12c5d1SDavid du Colombier int peekc; 543e12c5d1SDavid du Colombier int pflag; 553e12c5d1SDavid du Colombier int rescuing; 563e12c5d1SDavid du Colombier Rune rhsbuf[LBSIZE/2]; 573e12c5d1SDavid du Colombier char savedfile[FNSIZE]; 583e12c5d1SDavid du Colombier jmp_buf savej; 593e12c5d1SDavid du Colombier int subnewa; 603e12c5d1SDavid du Colombier int subolda; 613e12c5d1SDavid du Colombier Resub subexp[MAXSUB]; 623e12c5d1SDavid du Colombier char* tfname; 633e12c5d1SDavid du Colombier int tline; 643e12c5d1SDavid du Colombier int wrapp; 653e12c5d1SDavid du Colombier int* zero; 663e12c5d1SDavid du Colombier 673e12c5d1SDavid du Colombier char Q[] = ""; 683e12c5d1SDavid du Colombier char T[] = "TMP"; 693e12c5d1SDavid du Colombier char WRERR[] = "WRITE ERROR"; 703e12c5d1SDavid du Colombier int bpagesize = 20; 713e12c5d1SDavid du Colombier char hex[] = "0123456789abcdef"; 723e12c5d1SDavid du Colombier char* linp = line; 733e12c5d1SDavid du Colombier ulong nlall = 128; 743e12c5d1SDavid du Colombier int tfile = -1; 753e12c5d1SDavid du Colombier int vflag = 1; 763e12c5d1SDavid du Colombier 773e12c5d1SDavid du Colombier void add(int); 783e12c5d1SDavid du Colombier int* address(void); 793e12c5d1SDavid du Colombier int append(int(*)(void), int*); 803e12c5d1SDavid du Colombier void browse(void); 813e12c5d1SDavid du Colombier void callunix(void); 823e12c5d1SDavid du Colombier void commands(void); 833e12c5d1SDavid du Colombier void compile(int); 843e12c5d1SDavid du Colombier int compsub(void); 853e12c5d1SDavid du Colombier void dosub(void); 863e12c5d1SDavid du Colombier void error(char*); 873e12c5d1SDavid du Colombier int match(int*); 883e12c5d1SDavid du Colombier void exfile(int); 893e12c5d1SDavid du Colombier void filename(int); 903e12c5d1SDavid du Colombier Rune* getblock(int, int); 913e12c5d1SDavid du Colombier int getchr(void); 923e12c5d1SDavid du Colombier int getcopy(void); 933e12c5d1SDavid du Colombier int getfile(void); 943e12c5d1SDavid du Colombier Rune* getline(int); 953e12c5d1SDavid du Colombier int getnum(void); 963e12c5d1SDavid du Colombier int getsub(void); 973e12c5d1SDavid du Colombier int gettty(void); 983e12c5d1SDavid du Colombier void global(int); 993e12c5d1SDavid du Colombier void init(void); 1003e12c5d1SDavid du Colombier void join(void); 1013e12c5d1SDavid du Colombier void move(int); 1023e12c5d1SDavid du Colombier void newline(void); 1033e12c5d1SDavid du Colombier void nonzero(void); 1043e12c5d1SDavid du Colombier void notifyf(void*, char*); 1053e12c5d1SDavid du Colombier Rune* place(Rune*, Rune*, Rune*); 1063e12c5d1SDavid du Colombier void printcom(void); 1073e12c5d1SDavid du Colombier void putchr(int); 1083e12c5d1SDavid du Colombier void putd(void); 1093e12c5d1SDavid du Colombier void putfile(void); 1103e12c5d1SDavid du Colombier int putline(void); 1113e12c5d1SDavid du Colombier void putshst(Rune*); 1123e12c5d1SDavid du Colombier void putst(char*); 1133e12c5d1SDavid du Colombier void quit(void); 1143e12c5d1SDavid du Colombier void rdelete(int*, int*); 1153e12c5d1SDavid du Colombier void regerror(char *); 1163e12c5d1SDavid du Colombier void reverse(int*, int*); 1173e12c5d1SDavid du Colombier void setnoaddr(void); 1183e12c5d1SDavid du Colombier void setwide(void); 1193e12c5d1SDavid du Colombier void squeeze(int); 1203e12c5d1SDavid du Colombier void substitute(int); 1213e12c5d1SDavid du Colombier 1223e12c5d1SDavid du Colombier void 1233e12c5d1SDavid du Colombier main(int argc, char *argv[]) 1243e12c5d1SDavid du Colombier { 1253e12c5d1SDavid du Colombier char *p1, *p2; 1263e12c5d1SDavid du Colombier 1273e12c5d1SDavid du Colombier notify(notifyf); 1283e12c5d1SDavid du Colombier ARGBEGIN { 1293e12c5d1SDavid du Colombier case 'o': 1303e12c5d1SDavid du Colombier oflag = 1; 1313e12c5d1SDavid du Colombier vflag = 0; 1323e12c5d1SDavid du Colombier break; 1333e12c5d1SDavid du Colombier } ARGEND 1343e12c5d1SDavid du Colombier 1353e12c5d1SDavid du Colombier USED(argc); 1363e12c5d1SDavid du Colombier if(*argv && (strcmp(*argv, "-") == 0)) { 1373e12c5d1SDavid du Colombier argv++; 1383e12c5d1SDavid du Colombier vflag = 0; 1393e12c5d1SDavid du Colombier } 1403e12c5d1SDavid du Colombier if(oflag) { 1413e12c5d1SDavid du Colombier p1 = "/fd/1"; 1423e12c5d1SDavid du Colombier p2 = savedfile; 1433e12c5d1SDavid du Colombier while(*p2++ = *p1++) 1443e12c5d1SDavid du Colombier ; 1453e12c5d1SDavid du Colombier globp = L"a"; 1463e12c5d1SDavid du Colombier } else 1473e12c5d1SDavid du Colombier if(*argv) { 1483e12c5d1SDavid du Colombier p1 = *argv; 1493e12c5d1SDavid du Colombier p2 = savedfile; 1503e12c5d1SDavid du Colombier while(*p2++ = *p1++) 1513e12c5d1SDavid du Colombier if(p2 >= &savedfile[sizeof(savedfile)]) 1523e12c5d1SDavid du Colombier p2--; 1533e12c5d1SDavid du Colombier globp = L"r"; 1543e12c5d1SDavid du Colombier } 1553e12c5d1SDavid du Colombier zero = malloc((nlall+5)*sizeof(int*)); 1563e12c5d1SDavid du Colombier tfname = mktemp("/tmp/eXXXXX"); 1573e12c5d1SDavid du Colombier init(); 1583e12c5d1SDavid du Colombier setjmp(savej); 1593e12c5d1SDavid du Colombier commands(); 1603e12c5d1SDavid du Colombier quit(); 1613e12c5d1SDavid du Colombier } 1623e12c5d1SDavid du Colombier 1633e12c5d1SDavid du Colombier void 1643e12c5d1SDavid du Colombier commands(void) 1653e12c5d1SDavid du Colombier { 1663e12c5d1SDavid du Colombier int *a1, c, temp; 1673e12c5d1SDavid du Colombier char lastsep; 168*219b2ee8SDavid du Colombier Dir d; 1693e12c5d1SDavid du Colombier 1703e12c5d1SDavid du Colombier for(;;) { 1713e12c5d1SDavid du Colombier if(pflag) { 1723e12c5d1SDavid du Colombier pflag = 0; 1733e12c5d1SDavid du Colombier addr1 = addr2 = dot; 1743e12c5d1SDavid du Colombier printcom(); 1753e12c5d1SDavid du Colombier } 1763e12c5d1SDavid du Colombier c = '\n'; 1773e12c5d1SDavid du Colombier for(addr1 = 0;;) { 1783e12c5d1SDavid du Colombier lastsep = c; 1793e12c5d1SDavid du Colombier a1 = address(); 1803e12c5d1SDavid du Colombier c = getchr(); 1813e12c5d1SDavid du Colombier if(c != ',' && c != ';') 1823e12c5d1SDavid du Colombier break; 1833e12c5d1SDavid du Colombier if(lastsep == ',') 1843e12c5d1SDavid du Colombier error(Q); 1853e12c5d1SDavid du Colombier if(a1 == 0) { 1863e12c5d1SDavid du Colombier a1 = zero+1; 1873e12c5d1SDavid du Colombier if(a1 > dol) 1883e12c5d1SDavid du Colombier a1--; 1893e12c5d1SDavid du Colombier } 1903e12c5d1SDavid du Colombier addr1 = a1; 1913e12c5d1SDavid du Colombier if(c == ';') 1923e12c5d1SDavid du Colombier dot = a1; 1933e12c5d1SDavid du Colombier } 1943e12c5d1SDavid du Colombier if(lastsep != '\n' && a1 == 0) 1953e12c5d1SDavid du Colombier a1 = dol; 1963e12c5d1SDavid du Colombier if((addr2=a1) == 0) { 1973e12c5d1SDavid du Colombier given = 0; 1983e12c5d1SDavid du Colombier addr2 = dot; 1993e12c5d1SDavid du Colombier } else 2003e12c5d1SDavid du Colombier given = 1; 2013e12c5d1SDavid du Colombier if(addr1 == 0) 2023e12c5d1SDavid du Colombier addr1 = addr2; 2033e12c5d1SDavid du Colombier switch(c) { 2043e12c5d1SDavid du Colombier 2053e12c5d1SDavid du Colombier case 'a': 2063e12c5d1SDavid du Colombier add(0); 2073e12c5d1SDavid du Colombier continue; 2083e12c5d1SDavid du Colombier 2093e12c5d1SDavid du Colombier case 'b': 2103e12c5d1SDavid du Colombier nonzero(); 2113e12c5d1SDavid du Colombier browse(); 2123e12c5d1SDavid du Colombier continue; 2133e12c5d1SDavid du Colombier 2143e12c5d1SDavid du Colombier case 'c': 2153e12c5d1SDavid du Colombier nonzero(); 2163e12c5d1SDavid du Colombier newline(); 2173e12c5d1SDavid du Colombier rdelete(addr1, addr2); 2183e12c5d1SDavid du Colombier append(gettty, addr1-1); 2193e12c5d1SDavid du Colombier continue; 2203e12c5d1SDavid du Colombier 2213e12c5d1SDavid du Colombier case 'd': 2223e12c5d1SDavid du Colombier nonzero(); 2233e12c5d1SDavid du Colombier newline(); 2243e12c5d1SDavid du Colombier rdelete(addr1, addr2); 2253e12c5d1SDavid du Colombier continue; 2263e12c5d1SDavid du Colombier 2273e12c5d1SDavid du Colombier case 'E': 2283e12c5d1SDavid du Colombier fchange = 0; 2293e12c5d1SDavid du Colombier c = 'e'; 2303e12c5d1SDavid du Colombier case 'e': 2313e12c5d1SDavid du Colombier setnoaddr(); 2323e12c5d1SDavid du Colombier if(vflag && fchange) { 2333e12c5d1SDavid du Colombier fchange = 0; 2343e12c5d1SDavid du Colombier error(Q); 2353e12c5d1SDavid du Colombier } 2363e12c5d1SDavid du Colombier filename(c); 2373e12c5d1SDavid du Colombier init(); 2383e12c5d1SDavid du Colombier addr2 = zero; 2393e12c5d1SDavid du Colombier goto caseread; 2403e12c5d1SDavid du Colombier 2413e12c5d1SDavid du Colombier case 'f': 2423e12c5d1SDavid du Colombier setnoaddr(); 2433e12c5d1SDavid du Colombier filename(c); 2443e12c5d1SDavid du Colombier putst(savedfile); 2453e12c5d1SDavid du Colombier continue; 2463e12c5d1SDavid du Colombier 2473e12c5d1SDavid du Colombier case 'g': 2483e12c5d1SDavid du Colombier global(1); 2493e12c5d1SDavid du Colombier continue; 2503e12c5d1SDavid du Colombier 2513e12c5d1SDavid du Colombier case 'i': 2523e12c5d1SDavid du Colombier add(-1); 2533e12c5d1SDavid du Colombier continue; 2543e12c5d1SDavid du Colombier 2553e12c5d1SDavid du Colombier 2563e12c5d1SDavid du Colombier case 'j': 2573e12c5d1SDavid du Colombier if(!given) 2583e12c5d1SDavid du Colombier addr2++; 2593e12c5d1SDavid du Colombier newline(); 2603e12c5d1SDavid du Colombier join(); 2613e12c5d1SDavid du Colombier continue; 2623e12c5d1SDavid du Colombier 2633e12c5d1SDavid du Colombier case 'k': 2643e12c5d1SDavid du Colombier nonzero(); 2653e12c5d1SDavid du Colombier c = getchr(); 2663e12c5d1SDavid du Colombier if(c < 'a' || c > 'z') 2673e12c5d1SDavid du Colombier error(Q); 2683e12c5d1SDavid du Colombier newline(); 2693e12c5d1SDavid du Colombier names[c-'a'] = *addr2 & ~01; 2703e12c5d1SDavid du Colombier anymarks |= 01; 2713e12c5d1SDavid du Colombier continue; 2723e12c5d1SDavid du Colombier 2733e12c5d1SDavid du Colombier case 'm': 2743e12c5d1SDavid du Colombier move(0); 2753e12c5d1SDavid du Colombier continue; 2763e12c5d1SDavid du Colombier 2773e12c5d1SDavid du Colombier case 'n': 2783e12c5d1SDavid du Colombier listn++; 2793e12c5d1SDavid du Colombier newline(); 2803e12c5d1SDavid du Colombier printcom(); 2813e12c5d1SDavid du Colombier continue; 2823e12c5d1SDavid du Colombier 2833e12c5d1SDavid du Colombier case '\n': 2843e12c5d1SDavid du Colombier if(a1==0) { 2853e12c5d1SDavid du Colombier a1 = dot+1; 2863e12c5d1SDavid du Colombier addr2 = a1; 2873e12c5d1SDavid du Colombier addr1 = a1; 2883e12c5d1SDavid du Colombier } 2893e12c5d1SDavid du Colombier if(lastsep==';') 2903e12c5d1SDavid du Colombier addr1 = a1; 2913e12c5d1SDavid du Colombier printcom(); 2923e12c5d1SDavid du Colombier continue; 2933e12c5d1SDavid du Colombier 2943e12c5d1SDavid du Colombier case 'l': 2953e12c5d1SDavid du Colombier listf++; 2963e12c5d1SDavid du Colombier case 'p': 2973e12c5d1SDavid du Colombier case 'P': 2983e12c5d1SDavid du Colombier newline(); 2993e12c5d1SDavid du Colombier printcom(); 3003e12c5d1SDavid du Colombier continue; 3013e12c5d1SDavid du Colombier 3023e12c5d1SDavid du Colombier case 'Q': 3033e12c5d1SDavid du Colombier fchange = 0; 3043e12c5d1SDavid du Colombier case 'q': 3053e12c5d1SDavid du Colombier setnoaddr(); 3063e12c5d1SDavid du Colombier newline(); 3073e12c5d1SDavid du Colombier quit(); 3083e12c5d1SDavid du Colombier 3093e12c5d1SDavid du Colombier case 'r': 3103e12c5d1SDavid du Colombier filename(c); 3113e12c5d1SDavid du Colombier caseread: 3123e12c5d1SDavid du Colombier if((io=open(file, OREAD)) < 0) { 3133e12c5d1SDavid du Colombier lastc = '\n'; 3143e12c5d1SDavid du Colombier error(file); 3153e12c5d1SDavid du Colombier } 316*219b2ee8SDavid du Colombier if(dirfstat(io, &d) >= 0){ 317*219b2ee8SDavid du Colombier if(d.mode & CHAPPEND) 318*219b2ee8SDavid du Colombier print("warning: %s is append only\n", file); 319*219b2ee8SDavid du Colombier } 3203e12c5d1SDavid du Colombier Binit(&iobuf, io, OREAD); 3213e12c5d1SDavid du Colombier setwide(); 3223e12c5d1SDavid du Colombier squeeze(0); 3233e12c5d1SDavid du Colombier c = zero != dol; 3243e12c5d1SDavid du Colombier append(getfile, addr2); 3253e12c5d1SDavid du Colombier exfile(OREAD); 3263e12c5d1SDavid du Colombier 3273e12c5d1SDavid du Colombier fchange = c; 3283e12c5d1SDavid du Colombier continue; 3293e12c5d1SDavid du Colombier 3303e12c5d1SDavid du Colombier case 's': 3313e12c5d1SDavid du Colombier nonzero(); 3323e12c5d1SDavid du Colombier substitute(globp != 0); 3333e12c5d1SDavid du Colombier continue; 3343e12c5d1SDavid du Colombier 3353e12c5d1SDavid du Colombier case 't': 3363e12c5d1SDavid du Colombier move(1); 3373e12c5d1SDavid du Colombier continue; 3383e12c5d1SDavid du Colombier 3393e12c5d1SDavid du Colombier case 'u': 3403e12c5d1SDavid du Colombier nonzero(); 3413e12c5d1SDavid du Colombier newline(); 3423e12c5d1SDavid du Colombier if((*addr2&~01) != subnewa) 3433e12c5d1SDavid du Colombier error(Q); 3443e12c5d1SDavid du Colombier *addr2 = subolda; 3453e12c5d1SDavid du Colombier dot = addr2; 3463e12c5d1SDavid du Colombier continue; 3473e12c5d1SDavid du Colombier 3483e12c5d1SDavid du Colombier case 'v': 3493e12c5d1SDavid du Colombier global(0); 3503e12c5d1SDavid du Colombier continue; 3513e12c5d1SDavid du Colombier 3523e12c5d1SDavid du Colombier case 'W': 3533e12c5d1SDavid du Colombier wrapp++; 3543e12c5d1SDavid du Colombier case 'w': 3553e12c5d1SDavid du Colombier setwide(); 3563e12c5d1SDavid du Colombier squeeze(dol>zero); 3573e12c5d1SDavid du Colombier temp = getchr(); 3583e12c5d1SDavid du Colombier if(temp != 'q' && temp != 'Q') { 3593e12c5d1SDavid du Colombier peekc = temp; 3603e12c5d1SDavid du Colombier temp = 0; 3613e12c5d1SDavid du Colombier } 3623e12c5d1SDavid du Colombier filename(c); 3633e12c5d1SDavid du Colombier if(!wrapp || 3643e12c5d1SDavid du Colombier ((io = open(file, OWRITE)) == -1) || 3653e12c5d1SDavid du Colombier ((seek(io, 0L, 2)) == -1)) 3663e12c5d1SDavid du Colombier if((io = create(file, OWRITE, 0666)) < 0) 3673e12c5d1SDavid du Colombier error(file); 3683e12c5d1SDavid du Colombier Binit(&iobuf, io, OWRITE); 3693e12c5d1SDavid du Colombier wrapp = 0; 3703e12c5d1SDavid du Colombier if(dol > zero) 3713e12c5d1SDavid du Colombier putfile(); 3723e12c5d1SDavid du Colombier exfile(OWRITE); 3733e12c5d1SDavid du Colombier if(addr1<=zero+1 && addr2==dol) 3743e12c5d1SDavid du Colombier fchange = 0; 3753e12c5d1SDavid du Colombier if(temp == 'Q') 3763e12c5d1SDavid du Colombier fchange = 0; 3773e12c5d1SDavid du Colombier if(temp) 3783e12c5d1SDavid du Colombier quit(); 3793e12c5d1SDavid du Colombier continue; 3803e12c5d1SDavid du Colombier 3813e12c5d1SDavid du Colombier case '=': 3823e12c5d1SDavid du Colombier setwide(); 3833e12c5d1SDavid du Colombier squeeze(0); 3843e12c5d1SDavid du Colombier newline(); 3853e12c5d1SDavid du Colombier count = addr2 - zero; 3863e12c5d1SDavid du Colombier putd(); 3873e12c5d1SDavid du Colombier putchr(L'\n'); 3883e12c5d1SDavid du Colombier continue; 3893e12c5d1SDavid du Colombier 3903e12c5d1SDavid du Colombier case '!': 3913e12c5d1SDavid du Colombier callunix(); 3923e12c5d1SDavid du Colombier continue; 3933e12c5d1SDavid du Colombier 3943e12c5d1SDavid du Colombier case EOF: 3953e12c5d1SDavid du Colombier return; 3963e12c5d1SDavid du Colombier 3973e12c5d1SDavid du Colombier } 3983e12c5d1SDavid du Colombier error(Q); 3993e12c5d1SDavid du Colombier } 4003e12c5d1SDavid du Colombier } 4013e12c5d1SDavid du Colombier 4023e12c5d1SDavid du Colombier void 4033e12c5d1SDavid du Colombier printcom(void) 4043e12c5d1SDavid du Colombier { 4053e12c5d1SDavid du Colombier int *a1; 4063e12c5d1SDavid du Colombier 4073e12c5d1SDavid du Colombier nonzero(); 4083e12c5d1SDavid du Colombier a1 = addr1; 4093e12c5d1SDavid du Colombier do { 4103e12c5d1SDavid du Colombier if(listn) { 4113e12c5d1SDavid du Colombier count = a1-zero; 4123e12c5d1SDavid du Colombier putd(); 4133e12c5d1SDavid du Colombier putchr(L'\t'); 4143e12c5d1SDavid du Colombier } 4153e12c5d1SDavid du Colombier putshst(getline(*a1++)); 4163e12c5d1SDavid du Colombier } while(a1 <= addr2); 4173e12c5d1SDavid du Colombier dot = addr2; 4183e12c5d1SDavid du Colombier listf = 0; 4193e12c5d1SDavid du Colombier listn = 0; 4203e12c5d1SDavid du Colombier pflag = 0; 4213e12c5d1SDavid du Colombier } 4223e12c5d1SDavid du Colombier 4233e12c5d1SDavid du Colombier int* 4243e12c5d1SDavid du Colombier address(void) 4253e12c5d1SDavid du Colombier { 4263e12c5d1SDavid du Colombier int sign, *a, opcnt, nextopand, *b, c; 4273e12c5d1SDavid du Colombier 4283e12c5d1SDavid du Colombier nextopand = -1; 4293e12c5d1SDavid du Colombier sign = 1; 4303e12c5d1SDavid du Colombier opcnt = 0; 4313e12c5d1SDavid du Colombier a = dot; 4323e12c5d1SDavid du Colombier do { 4333e12c5d1SDavid du Colombier do { 4343e12c5d1SDavid du Colombier c = getchr(); 4353e12c5d1SDavid du Colombier } while(c == ' ' || c == '\t'); 4363e12c5d1SDavid du Colombier if(c >= '0' && c <= '9') { 4373e12c5d1SDavid du Colombier peekc = c; 4383e12c5d1SDavid du Colombier if(!opcnt) 4393e12c5d1SDavid du Colombier a = zero; 4403e12c5d1SDavid du Colombier a += sign*getnum(); 4413e12c5d1SDavid du Colombier } else 4423e12c5d1SDavid du Colombier switch(c) { 4433e12c5d1SDavid du Colombier case '$': 4443e12c5d1SDavid du Colombier a = dol; 4453e12c5d1SDavid du Colombier case '.': 4463e12c5d1SDavid du Colombier if(opcnt) 4473e12c5d1SDavid du Colombier error(Q); 4483e12c5d1SDavid du Colombier break; 4493e12c5d1SDavid du Colombier case '\'': 4503e12c5d1SDavid du Colombier c = getchr(); 4513e12c5d1SDavid du Colombier if(opcnt || c < 'a' || c > 'z') 4523e12c5d1SDavid du Colombier error(Q); 4533e12c5d1SDavid du Colombier a = zero; 4543e12c5d1SDavid du Colombier do { 4553e12c5d1SDavid du Colombier a++; 4563e12c5d1SDavid du Colombier } while(a <= dol && names[c-'a'] != (*a & ~01)); 4573e12c5d1SDavid du Colombier break; 4583e12c5d1SDavid du Colombier case '?': 4593e12c5d1SDavid du Colombier sign = -sign; 4603e12c5d1SDavid du Colombier case '/': 4613e12c5d1SDavid du Colombier compile(c); 4623e12c5d1SDavid du Colombier b = a; 4633e12c5d1SDavid du Colombier for(;;) { 4643e12c5d1SDavid du Colombier a += sign; 4653e12c5d1SDavid du Colombier if(a <= zero) 4663e12c5d1SDavid du Colombier a = dol; 4673e12c5d1SDavid du Colombier if(a > dol) 4683e12c5d1SDavid du Colombier a = zero; 4693e12c5d1SDavid du Colombier if(match(a)) 4703e12c5d1SDavid du Colombier break; 4713e12c5d1SDavid du Colombier if(a == b) 4723e12c5d1SDavid du Colombier error(Q); 4733e12c5d1SDavid du Colombier } 4743e12c5d1SDavid du Colombier break; 4753e12c5d1SDavid du Colombier default: 4763e12c5d1SDavid du Colombier if(nextopand == opcnt) { 4773e12c5d1SDavid du Colombier a += sign; 4783e12c5d1SDavid du Colombier if(a < zero || dol < a) 4793e12c5d1SDavid du Colombier continue; /* error(Q); */ 4803e12c5d1SDavid du Colombier } 4813e12c5d1SDavid du Colombier if(c != '+' && c != '-' && c != '^') { 4823e12c5d1SDavid du Colombier peekc = c; 4833e12c5d1SDavid du Colombier if(opcnt == 0) 4843e12c5d1SDavid du Colombier a = 0; 4853e12c5d1SDavid du Colombier return a; 4863e12c5d1SDavid du Colombier } 4873e12c5d1SDavid du Colombier sign = 1; 4883e12c5d1SDavid du Colombier if(c != '+') 4893e12c5d1SDavid du Colombier sign = -sign; 4903e12c5d1SDavid du Colombier nextopand = ++opcnt; 4913e12c5d1SDavid du Colombier continue; 4923e12c5d1SDavid du Colombier } 4933e12c5d1SDavid du Colombier sign = 1; 4943e12c5d1SDavid du Colombier opcnt++; 4953e12c5d1SDavid du Colombier } while(zero <= a && a <= dol); 4963e12c5d1SDavid du Colombier error(Q); 4973e12c5d1SDavid du Colombier return 0; 4983e12c5d1SDavid du Colombier } 4993e12c5d1SDavid du Colombier 5003e12c5d1SDavid du Colombier int 5013e12c5d1SDavid du Colombier getnum(void) 5023e12c5d1SDavid du Colombier { 5033e12c5d1SDavid du Colombier int r, c; 5043e12c5d1SDavid du Colombier 5053e12c5d1SDavid du Colombier r = 0; 5063e12c5d1SDavid du Colombier for(;;) { 5073e12c5d1SDavid du Colombier c = getchr(); 5083e12c5d1SDavid du Colombier if(c < '0' || c > '9') 5093e12c5d1SDavid du Colombier break; 5103e12c5d1SDavid du Colombier r = r*10 + (c-'0'); 5113e12c5d1SDavid du Colombier } 5123e12c5d1SDavid du Colombier peekc = c; 5133e12c5d1SDavid du Colombier return r; 5143e12c5d1SDavid du Colombier } 5153e12c5d1SDavid du Colombier 5163e12c5d1SDavid du Colombier void 5173e12c5d1SDavid du Colombier setwide(void) 5183e12c5d1SDavid du Colombier { 5193e12c5d1SDavid du Colombier if(!given) { 5203e12c5d1SDavid du Colombier addr1 = zero + (dol>zero); 5213e12c5d1SDavid du Colombier addr2 = dol; 5223e12c5d1SDavid du Colombier } 5233e12c5d1SDavid du Colombier } 5243e12c5d1SDavid du Colombier 5253e12c5d1SDavid du Colombier void 5263e12c5d1SDavid du Colombier setnoaddr(void) 5273e12c5d1SDavid du Colombier { 5283e12c5d1SDavid du Colombier if(given) 5293e12c5d1SDavid du Colombier error(Q); 5303e12c5d1SDavid du Colombier } 5313e12c5d1SDavid du Colombier 5323e12c5d1SDavid du Colombier void 5333e12c5d1SDavid du Colombier nonzero(void) 5343e12c5d1SDavid du Colombier { 5353e12c5d1SDavid du Colombier squeeze(1); 5363e12c5d1SDavid du Colombier } 5373e12c5d1SDavid du Colombier 5383e12c5d1SDavid du Colombier void 5393e12c5d1SDavid du Colombier squeeze(int i) 5403e12c5d1SDavid du Colombier { 5413e12c5d1SDavid du Colombier if(addr1 < zero+i || addr2 > dol || addr1 > addr2) 5423e12c5d1SDavid du Colombier error(Q); 5433e12c5d1SDavid du Colombier } 5443e12c5d1SDavid du Colombier 5453e12c5d1SDavid du Colombier void 5463e12c5d1SDavid du Colombier newline(void) 5473e12c5d1SDavid du Colombier { 5483e12c5d1SDavid du Colombier int c; 5493e12c5d1SDavid du Colombier 5503e12c5d1SDavid du Colombier c = getchr(); 5513e12c5d1SDavid du Colombier if(c == '\n' || c == EOF) 5523e12c5d1SDavid du Colombier return; 5533e12c5d1SDavid du Colombier if(c == 'p' || c == 'l' || c == 'n') { 5543e12c5d1SDavid du Colombier pflag++; 5553e12c5d1SDavid du Colombier if(c == 'l') 5563e12c5d1SDavid du Colombier listf++; 5573e12c5d1SDavid du Colombier else 5583e12c5d1SDavid du Colombier if(c == 'n') 5593e12c5d1SDavid du Colombier listn++; 5603e12c5d1SDavid du Colombier c = getchr(); 5613e12c5d1SDavid du Colombier if(c == '\n') 5623e12c5d1SDavid du Colombier return; 5633e12c5d1SDavid du Colombier } 5643e12c5d1SDavid du Colombier error(Q); 5653e12c5d1SDavid du Colombier } 5663e12c5d1SDavid du Colombier 5673e12c5d1SDavid du Colombier void 5683e12c5d1SDavid du Colombier filename(int comm) 5693e12c5d1SDavid du Colombier { 5703e12c5d1SDavid du Colombier char *p1, *p2; 5713e12c5d1SDavid du Colombier Rune rune; 5723e12c5d1SDavid du Colombier int c; 5733e12c5d1SDavid du Colombier 5743e12c5d1SDavid du Colombier count = 0; 5753e12c5d1SDavid du Colombier c = getchr(); 5763e12c5d1SDavid du Colombier if(c == '\n' || c == EOF) { 5773e12c5d1SDavid du Colombier p1 = savedfile; 5783e12c5d1SDavid du Colombier if(*p1 == 0 && comm != 'f') 5793e12c5d1SDavid du Colombier error(Q); 5803e12c5d1SDavid du Colombier p2 = file; 5813e12c5d1SDavid du Colombier while(*p2++ = *p1++) 5823e12c5d1SDavid du Colombier ; 5833e12c5d1SDavid du Colombier return; 5843e12c5d1SDavid du Colombier } 5853e12c5d1SDavid du Colombier if(c != ' ') 5863e12c5d1SDavid du Colombier error(Q); 5873e12c5d1SDavid du Colombier while((c=getchr()) == ' ') 5883e12c5d1SDavid du Colombier ; 5893e12c5d1SDavid du Colombier if(c == '\n') 5903e12c5d1SDavid du Colombier error(Q); 5913e12c5d1SDavid du Colombier p1 = file; 5923e12c5d1SDavid du Colombier do { 5933e12c5d1SDavid du Colombier if(p1 >= &file[sizeof(file)-6] || c == ' ' || c == EOF) 5943e12c5d1SDavid du Colombier error(Q); 5953e12c5d1SDavid du Colombier rune = c; 5963e12c5d1SDavid du Colombier p1 += runetochar(p1, &rune); 5973e12c5d1SDavid du Colombier } while((c=getchr()) != '\n'); 5983e12c5d1SDavid du Colombier *p1 = 0; 5993e12c5d1SDavid du Colombier if(savedfile[0] == 0 || comm == 'e' || comm == 'f') { 6003e12c5d1SDavid du Colombier p1 = savedfile; 6013e12c5d1SDavid du Colombier p2 = file; 6023e12c5d1SDavid du Colombier while(*p1++ = *p2++) 6033e12c5d1SDavid du Colombier ; 6043e12c5d1SDavid du Colombier } 6053e12c5d1SDavid du Colombier } 6063e12c5d1SDavid du Colombier 6073e12c5d1SDavid du Colombier void 6083e12c5d1SDavid du Colombier exfile(int om) 6093e12c5d1SDavid du Colombier { 6103e12c5d1SDavid du Colombier 6113e12c5d1SDavid du Colombier if(om == OWRITE) 6123e12c5d1SDavid du Colombier if(Bflush(&iobuf) < 0) 6133e12c5d1SDavid du Colombier error(Q); 6143e12c5d1SDavid du Colombier close(io); 6153e12c5d1SDavid du Colombier io = -1; 6163e12c5d1SDavid du Colombier if(vflag) { 6173e12c5d1SDavid du Colombier putd(); 6183e12c5d1SDavid du Colombier putchr(L'\n'); 6193e12c5d1SDavid du Colombier } 6203e12c5d1SDavid du Colombier } 6213e12c5d1SDavid du Colombier 6223e12c5d1SDavid du Colombier void 6233e12c5d1SDavid du Colombier error1(char *s) 6243e12c5d1SDavid du Colombier { 6253e12c5d1SDavid du Colombier int c; 6263e12c5d1SDavid du Colombier 6273e12c5d1SDavid du Colombier wrapp = 0; 6283e12c5d1SDavid du Colombier listf = 0; 6293e12c5d1SDavid du Colombier listn = 0; 6303e12c5d1SDavid du Colombier count = 0; 6313e12c5d1SDavid du Colombier seek(0, 0, 2); 6323e12c5d1SDavid du Colombier pflag = 0; 6333e12c5d1SDavid du Colombier if(globp) 6343e12c5d1SDavid du Colombier lastc = '\n'; 6353e12c5d1SDavid du Colombier globp = 0; 6363e12c5d1SDavid du Colombier peekc = lastc; 6373e12c5d1SDavid du Colombier if(lastc) 6383e12c5d1SDavid du Colombier for(;;) { 6393e12c5d1SDavid du Colombier c = getchr(); 6403e12c5d1SDavid du Colombier if(c == '\n' || c == EOF) 6413e12c5d1SDavid du Colombier break; 6423e12c5d1SDavid du Colombier } 6433e12c5d1SDavid du Colombier if(io > 0) { 6443e12c5d1SDavid du Colombier close(io); 6453e12c5d1SDavid du Colombier io = -1; 6463e12c5d1SDavid du Colombier } 6473e12c5d1SDavid du Colombier putchr(L'?'); 6483e12c5d1SDavid du Colombier putst(s); 6493e12c5d1SDavid du Colombier } 6503e12c5d1SDavid du Colombier 6513e12c5d1SDavid du Colombier void 6523e12c5d1SDavid du Colombier error(char *s) 6533e12c5d1SDavid du Colombier { 6543e12c5d1SDavid du Colombier error1(s); 6553e12c5d1SDavid du Colombier longjmp(savej, 1); 6563e12c5d1SDavid du Colombier } 6573e12c5d1SDavid du Colombier 6583e12c5d1SDavid du Colombier void 6593e12c5d1SDavid du Colombier rescue(void) 6603e12c5d1SDavid du Colombier { 6613e12c5d1SDavid du Colombier rescuing = 1; 6623e12c5d1SDavid du Colombier if(dol > zero) { 6633e12c5d1SDavid du Colombier addr1 = zero+1; 6643e12c5d1SDavid du Colombier addr2 = dol; 6653e12c5d1SDavid du Colombier io = create("ed.hup", OWRITE, 0666); 6663e12c5d1SDavid du Colombier if(io > 0) 6673e12c5d1SDavid du Colombier putfile(); 6683e12c5d1SDavid du Colombier } 6693e12c5d1SDavid du Colombier fchange = 0; 6703e12c5d1SDavid du Colombier quit(); 6713e12c5d1SDavid du Colombier } 6723e12c5d1SDavid du Colombier 6733e12c5d1SDavid du Colombier void 6743e12c5d1SDavid du Colombier notifyf(void *a, char *s) 6753e12c5d1SDavid du Colombier { 6763e12c5d1SDavid du Colombier if(strcmp(s, "interrupt") == 0){ 6773e12c5d1SDavid du Colombier if(rescuing) 6783e12c5d1SDavid du Colombier noted(NCONT); 6793e12c5d1SDavid du Colombier putchr(L'\n'); 6803e12c5d1SDavid du Colombier lastc = '\n'; 6813e12c5d1SDavid du Colombier error1(Q); 6823e12c5d1SDavid du Colombier notejmp(a, savej, 0); 6833e12c5d1SDavid du Colombier } 6843e12c5d1SDavid du Colombier if(strcmp(s, "hangup") == 0){ 6853e12c5d1SDavid du Colombier if(rescuing) 6863e12c5d1SDavid du Colombier noted(NDFLT); 6873e12c5d1SDavid du Colombier rescue(); 6883e12c5d1SDavid du Colombier } 6893e12c5d1SDavid du Colombier fprint(2, "ed: note: %s\n", s); 6903e12c5d1SDavid du Colombier abort(); 6913e12c5d1SDavid du Colombier } 6923e12c5d1SDavid du Colombier 6933e12c5d1SDavid du Colombier int 6943e12c5d1SDavid du Colombier getchr(void) 6953e12c5d1SDavid du Colombier { 6963e12c5d1SDavid du Colombier char s[UTFmax]; 6973e12c5d1SDavid du Colombier int i; 6983e12c5d1SDavid du Colombier Rune r; 6993e12c5d1SDavid du Colombier 7003e12c5d1SDavid du Colombier if(lastc = peekc) { 7013e12c5d1SDavid du Colombier peekc = 0; 7023e12c5d1SDavid du Colombier return lastc; 7033e12c5d1SDavid du Colombier } 7043e12c5d1SDavid du Colombier if(globp) { 7053e12c5d1SDavid du Colombier if((lastc=*globp++) != 0) 7063e12c5d1SDavid du Colombier return lastc; 7073e12c5d1SDavid du Colombier globp = 0; 7083e12c5d1SDavid du Colombier return EOF; 7093e12c5d1SDavid du Colombier } 7103e12c5d1SDavid du Colombier for(i=0;;) { 7113e12c5d1SDavid du Colombier if(read(0, s+i, 1) <= 0) 7123e12c5d1SDavid du Colombier return lastc = EOF; 7133e12c5d1SDavid du Colombier i++; 7143e12c5d1SDavid du Colombier if(fullrune(s, i)) 7153e12c5d1SDavid du Colombier break; 7163e12c5d1SDavid du Colombier 7173e12c5d1SDavid du Colombier } 7183e12c5d1SDavid du Colombier chartorune(&r, s); 7193e12c5d1SDavid du Colombier lastc = r; 7203e12c5d1SDavid du Colombier return lastc; 7213e12c5d1SDavid du Colombier } 7223e12c5d1SDavid du Colombier 7233e12c5d1SDavid du Colombier int 7243e12c5d1SDavid du Colombier gety(void) 7253e12c5d1SDavid du Colombier { 7263e12c5d1SDavid du Colombier int c; 7273e12c5d1SDavid du Colombier Rune *gf, *p; 7283e12c5d1SDavid du Colombier 7293e12c5d1SDavid du Colombier p = linebuf; 7303e12c5d1SDavid du Colombier gf = globp; 7313e12c5d1SDavid du Colombier for(;;) { 7323e12c5d1SDavid du Colombier c = getchr(); 7333e12c5d1SDavid du Colombier if(c == '\n') { 7343e12c5d1SDavid du Colombier *p = 0; 7353e12c5d1SDavid du Colombier return 0; 7363e12c5d1SDavid du Colombier } 7373e12c5d1SDavid du Colombier if(c == EOF) { 7383e12c5d1SDavid du Colombier if(gf) 7393e12c5d1SDavid du Colombier peekc = c; 7403e12c5d1SDavid du Colombier return c; 7413e12c5d1SDavid du Colombier } 7423e12c5d1SDavid du Colombier if(c == 0) 7433e12c5d1SDavid du Colombier continue; 7443e12c5d1SDavid du Colombier *p++ = c; 7453e12c5d1SDavid du Colombier if(p >= &linebuf[LBSIZE-2]) 7463e12c5d1SDavid du Colombier error(Q); 7473e12c5d1SDavid du Colombier } 7483e12c5d1SDavid du Colombier return 0; 7493e12c5d1SDavid du Colombier } 7503e12c5d1SDavid du Colombier 7513e12c5d1SDavid du Colombier int 7523e12c5d1SDavid du Colombier gettty(void) 7533e12c5d1SDavid du Colombier { 7543e12c5d1SDavid du Colombier int rc; 7553e12c5d1SDavid du Colombier 7563e12c5d1SDavid du Colombier rc = gety(); 7573e12c5d1SDavid du Colombier if(rc) 7583e12c5d1SDavid du Colombier return rc; 7593e12c5d1SDavid du Colombier if(linebuf[0] == '.' && linebuf[1] == 0) 7603e12c5d1SDavid du Colombier return EOF; 7613e12c5d1SDavid du Colombier return 0; 7623e12c5d1SDavid du Colombier } 7633e12c5d1SDavid du Colombier 7643e12c5d1SDavid du Colombier int 7653e12c5d1SDavid du Colombier getfile(void) 7663e12c5d1SDavid du Colombier { 7673e12c5d1SDavid du Colombier int c; 7683e12c5d1SDavid du Colombier Rune *lp; 7693e12c5d1SDavid du Colombier 7703e12c5d1SDavid du Colombier lp = linebuf; 7713e12c5d1SDavid du Colombier do { 7723e12c5d1SDavid du Colombier c = Bgetrune(&iobuf); 7733e12c5d1SDavid du Colombier if(c < 0) { 7743e12c5d1SDavid du Colombier if(lp > linebuf) { 7753e12c5d1SDavid du Colombier putst("'\\n' appended"); 7763e12c5d1SDavid du Colombier c = '\n'; 7773e12c5d1SDavid du Colombier } else 7783e12c5d1SDavid du Colombier return EOF; 7793e12c5d1SDavid du Colombier } 7803e12c5d1SDavid du Colombier if(lp >= &linebuf[LBSIZE]) { 7813e12c5d1SDavid du Colombier lastc = '\n'; 7823e12c5d1SDavid du Colombier error(Q); 7833e12c5d1SDavid du Colombier } 7843e12c5d1SDavid du Colombier *lp++ = c; 7853e12c5d1SDavid du Colombier count++; 7863e12c5d1SDavid du Colombier } while(c != '\n'); 7873e12c5d1SDavid du Colombier lp[-1] = 0; 7883e12c5d1SDavid du Colombier return 0; 7893e12c5d1SDavid du Colombier } 7903e12c5d1SDavid du Colombier 7913e12c5d1SDavid du Colombier void 7923e12c5d1SDavid du Colombier putfile(void) 7933e12c5d1SDavid du Colombier { 7943e12c5d1SDavid du Colombier int *a1; 7953e12c5d1SDavid du Colombier Rune *lp; 7963e12c5d1SDavid du Colombier long c; 7973e12c5d1SDavid du Colombier 7983e12c5d1SDavid du Colombier a1 = addr1; 7993e12c5d1SDavid du Colombier do { 8003e12c5d1SDavid du Colombier lp = getline(*a1++); 8013e12c5d1SDavid du Colombier for(;;) { 8023e12c5d1SDavid du Colombier count++; 8033e12c5d1SDavid du Colombier c = *lp++; 8043e12c5d1SDavid du Colombier if(c == 0) { 8053e12c5d1SDavid du Colombier if(Bputrune(&iobuf, '\n') < 0) 8063e12c5d1SDavid du Colombier error(Q); 8073e12c5d1SDavid du Colombier break; 8083e12c5d1SDavid du Colombier } 8093e12c5d1SDavid du Colombier if(Bputrune(&iobuf, c) < 0) 8103e12c5d1SDavid du Colombier error(Q); 8113e12c5d1SDavid du Colombier } 8123e12c5d1SDavid du Colombier } while(a1 <= addr2); 8133e12c5d1SDavid du Colombier if(Bflush(&iobuf) < 0) 8143e12c5d1SDavid du Colombier error(Q); 8153e12c5d1SDavid du Colombier } 8163e12c5d1SDavid du Colombier 8173e12c5d1SDavid du Colombier int 8183e12c5d1SDavid du Colombier append(int (*f)(void), int *a) 8193e12c5d1SDavid du Colombier { 8203e12c5d1SDavid du Colombier int *a1, *a2, *rdot, nline, tl; 8213e12c5d1SDavid du Colombier 8223e12c5d1SDavid du Colombier nline = 0; 8233e12c5d1SDavid du Colombier dot = a; 8243e12c5d1SDavid du Colombier while((*f)() == 0) { 8253e12c5d1SDavid du Colombier if((dol-zero) >= nlall) { 8263e12c5d1SDavid du Colombier nlall += 512; 8273e12c5d1SDavid du Colombier a1 = realloc(zero, (nlall+5)*sizeof(int*)); 8283e12c5d1SDavid du Colombier if(a1 == 0) { 8293e12c5d1SDavid du Colombier error("MEM?"); 8303e12c5d1SDavid du Colombier rescue(); 8313e12c5d1SDavid du Colombier } 8323e12c5d1SDavid du Colombier tl = a1 - zero; /* relocate pointers */ 8333e12c5d1SDavid du Colombier zero += tl; 8343e12c5d1SDavid du Colombier addr1 += tl; 8353e12c5d1SDavid du Colombier addr2 += tl; 8363e12c5d1SDavid du Colombier dol += tl; 8373e12c5d1SDavid du Colombier dot += tl; 8383e12c5d1SDavid du Colombier } 8393e12c5d1SDavid du Colombier tl = putline(); 8403e12c5d1SDavid du Colombier nline++; 8413e12c5d1SDavid du Colombier a1 = ++dol; 8423e12c5d1SDavid du Colombier a2 = a1+1; 8433e12c5d1SDavid du Colombier rdot = ++dot; 8443e12c5d1SDavid du Colombier while(a1 > rdot) 8453e12c5d1SDavid du Colombier *--a2 = *--a1; 8463e12c5d1SDavid du Colombier *rdot = tl; 8473e12c5d1SDavid du Colombier } 8483e12c5d1SDavid du Colombier return nline; 8493e12c5d1SDavid du Colombier } 8503e12c5d1SDavid du Colombier 8513e12c5d1SDavid du Colombier void 8523e12c5d1SDavid du Colombier add(int i) 8533e12c5d1SDavid du Colombier { 8543e12c5d1SDavid du Colombier if(i && (given || dol > zero)) { 8553e12c5d1SDavid du Colombier addr1--; 8563e12c5d1SDavid du Colombier addr2--; 8573e12c5d1SDavid du Colombier } 8583e12c5d1SDavid du Colombier squeeze(0); 8593e12c5d1SDavid du Colombier newline(); 8603e12c5d1SDavid du Colombier append(gettty, addr2); 8613e12c5d1SDavid du Colombier } 8623e12c5d1SDavid du Colombier 8633e12c5d1SDavid du Colombier void 8643e12c5d1SDavid du Colombier browse(void) 8653e12c5d1SDavid du Colombier { 8663e12c5d1SDavid du Colombier int forward, n; 8673e12c5d1SDavid du Colombier static bformat, bnum; /* 0 */ 8683e12c5d1SDavid du Colombier 8693e12c5d1SDavid du Colombier forward = 1; 8703e12c5d1SDavid du Colombier peekc = getchr(); 8713e12c5d1SDavid du Colombier if(peekc != '\n'){ 8723e12c5d1SDavid du Colombier if(peekc == '-' || peekc == '+') { 8733e12c5d1SDavid du Colombier if(peekc == '-') 8743e12c5d1SDavid du Colombier forward = 0; 8753e12c5d1SDavid du Colombier getchr(); 8763e12c5d1SDavid du Colombier } 8773e12c5d1SDavid du Colombier n = getnum(); 8783e12c5d1SDavid du Colombier if(n > 0) 8793e12c5d1SDavid du Colombier bpagesize = n; 8803e12c5d1SDavid du Colombier } 8813e12c5d1SDavid du Colombier newline(); 8823e12c5d1SDavid du Colombier if(pflag) { 8833e12c5d1SDavid du Colombier bformat = listf; 8843e12c5d1SDavid du Colombier bnum = listn; 8853e12c5d1SDavid du Colombier } else { 8863e12c5d1SDavid du Colombier listf = bformat; 8873e12c5d1SDavid du Colombier listn = bnum; 8883e12c5d1SDavid du Colombier } 8893e12c5d1SDavid du Colombier if(forward) { 8903e12c5d1SDavid du Colombier addr1 = addr2; 8913e12c5d1SDavid du Colombier addr2 += bpagesize; 8923e12c5d1SDavid du Colombier if(addr2 > dol) 8933e12c5d1SDavid du Colombier addr2 = dol; 8943e12c5d1SDavid du Colombier } else { 8953e12c5d1SDavid du Colombier addr1 = addr2-bpagesize; 8963e12c5d1SDavid du Colombier if(addr1 <= zero) 8973e12c5d1SDavid du Colombier addr1 = zero+1; 8983e12c5d1SDavid du Colombier } 8993e12c5d1SDavid du Colombier printcom(); 9003e12c5d1SDavid du Colombier } 9013e12c5d1SDavid du Colombier 9023e12c5d1SDavid du Colombier void 9033e12c5d1SDavid du Colombier callunix(void) 9043e12c5d1SDavid du Colombier { 9053e12c5d1SDavid du Colombier int c; 9063e12c5d1SDavid du Colombier Rune rune; 9073e12c5d1SDavid du Colombier Waitmsg w; 9083e12c5d1SDavid du Colombier char buf[512]; 9093e12c5d1SDavid du Colombier char *p; 9103e12c5d1SDavid du Colombier 9113e12c5d1SDavid du Colombier setnoaddr(); 9123e12c5d1SDavid du Colombier p = buf; 9133e12c5d1SDavid du Colombier while((c=getchr()) != EOF && c != '\n') 9143e12c5d1SDavid du Colombier if(p < &buf[sizeof(buf) - 6]) { 9153e12c5d1SDavid du Colombier rune = c; 9163e12c5d1SDavid du Colombier p += runetochar(p, &rune); 9173e12c5d1SDavid du Colombier } 9183e12c5d1SDavid du Colombier *p = 0; 9193e12c5d1SDavid du Colombier if(fork() == 0) { 9203e12c5d1SDavid du Colombier execl("/bin/rc", "rc", "-c", buf, 0); 9213e12c5d1SDavid du Colombier exits("execl failed"); 9223e12c5d1SDavid du Colombier } 9233e12c5d1SDavid du Colombier wait(&w); 9243e12c5d1SDavid du Colombier if(vflag) 9253e12c5d1SDavid du Colombier putst("!"); 9263e12c5d1SDavid du Colombier } 9273e12c5d1SDavid du Colombier 9283e12c5d1SDavid du Colombier void 9293e12c5d1SDavid du Colombier quit(void) 9303e12c5d1SDavid du Colombier { 9313e12c5d1SDavid du Colombier if(vflag && fchange && dol!=zero) { 9323e12c5d1SDavid du Colombier fchange = 0; 9333e12c5d1SDavid du Colombier error(Q); 9343e12c5d1SDavid du Colombier } 9353e12c5d1SDavid du Colombier remove(tfname); 9363e12c5d1SDavid du Colombier exits(0); 9373e12c5d1SDavid du Colombier } 9383e12c5d1SDavid du Colombier 9393e12c5d1SDavid du Colombier void 9403e12c5d1SDavid du Colombier onquit(int sig) 9413e12c5d1SDavid du Colombier { 9423e12c5d1SDavid du Colombier USED(sig); 9433e12c5d1SDavid du Colombier quit(); 9443e12c5d1SDavid du Colombier } 9453e12c5d1SDavid du Colombier 9463e12c5d1SDavid du Colombier void 9473e12c5d1SDavid du Colombier rdelete(int *ad1, int *ad2) 9483e12c5d1SDavid du Colombier { 9493e12c5d1SDavid du Colombier int *a1, *a2, *a3; 9503e12c5d1SDavid du Colombier 9513e12c5d1SDavid du Colombier a1 = ad1; 9523e12c5d1SDavid du Colombier a2 = ad2+1; 9533e12c5d1SDavid du Colombier a3 = dol; 9543e12c5d1SDavid du Colombier dol -= a2 - a1; 9553e12c5d1SDavid du Colombier do { 9563e12c5d1SDavid du Colombier *a1++ = *a2++; 9573e12c5d1SDavid du Colombier } while(a2 <= a3); 9583e12c5d1SDavid du Colombier a1 = ad1; 9593e12c5d1SDavid du Colombier if(a1 > dol) 9603e12c5d1SDavid du Colombier a1 = dol; 9613e12c5d1SDavid du Colombier dot = a1; 9623e12c5d1SDavid du Colombier fchange = 1; 9633e12c5d1SDavid du Colombier } 9643e12c5d1SDavid du Colombier 9653e12c5d1SDavid du Colombier void 9663e12c5d1SDavid du Colombier gdelete(void) 9673e12c5d1SDavid du Colombier { 9683e12c5d1SDavid du Colombier int *a1, *a2, *a3; 9693e12c5d1SDavid du Colombier 9703e12c5d1SDavid du Colombier a3 = dol; 9713e12c5d1SDavid du Colombier for(a1=zero; (*a1&01)==0; a1++) 9723e12c5d1SDavid du Colombier if(a1>=a3) 9733e12c5d1SDavid du Colombier return; 9743e12c5d1SDavid du Colombier for(a2=a1+1; a2<=a3;) { 9753e12c5d1SDavid du Colombier if(*a2 & 01) { 9763e12c5d1SDavid du Colombier a2++; 9773e12c5d1SDavid du Colombier dot = a1; 9783e12c5d1SDavid du Colombier } else 9793e12c5d1SDavid du Colombier *a1++ = *a2++; 9803e12c5d1SDavid du Colombier } 9813e12c5d1SDavid du Colombier dol = a1-1; 9823e12c5d1SDavid du Colombier if(dot > dol) 9833e12c5d1SDavid du Colombier dot = dol; 9843e12c5d1SDavid du Colombier fchange = 1; 9853e12c5d1SDavid du Colombier } 9863e12c5d1SDavid du Colombier 9873e12c5d1SDavid du Colombier Rune* 9883e12c5d1SDavid du Colombier getline(int tl) 9893e12c5d1SDavid du Colombier { 9903e12c5d1SDavid du Colombier Rune *lp, *bp; 9913e12c5d1SDavid du Colombier int nl; 9923e12c5d1SDavid du Colombier 9933e12c5d1SDavid du Colombier lp = linebuf; 9943e12c5d1SDavid du Colombier bp = getblock(tl, OREAD); 9953e12c5d1SDavid du Colombier nl = nleft; 9963e12c5d1SDavid du Colombier tl &= ~((BLKSIZE/2) - 1); 9973e12c5d1SDavid du Colombier while(*lp++ = *bp++) { 9983e12c5d1SDavid du Colombier nl -= sizeof(Rune); 9993e12c5d1SDavid du Colombier if(nl == 0) { 10003e12c5d1SDavid du Colombier bp = getblock(tl += BLKSIZE/2, OREAD); 10013e12c5d1SDavid du Colombier nl = nleft; 10023e12c5d1SDavid du Colombier } 10033e12c5d1SDavid du Colombier } 10043e12c5d1SDavid du Colombier return linebuf; 10053e12c5d1SDavid du Colombier } 10063e12c5d1SDavid du Colombier 10073e12c5d1SDavid du Colombier int 10083e12c5d1SDavid du Colombier putline(void) 10093e12c5d1SDavid du Colombier { 10103e12c5d1SDavid du Colombier Rune *lp, *bp; 10113e12c5d1SDavid du Colombier int nl, tl; 10123e12c5d1SDavid du Colombier 10133e12c5d1SDavid du Colombier fchange = 1; 10143e12c5d1SDavid du Colombier lp = linebuf; 10153e12c5d1SDavid du Colombier tl = tline; 10163e12c5d1SDavid du Colombier bp = getblock(tl, OWRITE); 10173e12c5d1SDavid du Colombier nl = nleft; 10183e12c5d1SDavid du Colombier tl &= ~((BLKSIZE/2)-1); 10193e12c5d1SDavid du Colombier while(*bp = *lp++) { 10203e12c5d1SDavid du Colombier if(*bp++ == '\n') { 10213e12c5d1SDavid du Colombier bp[-1] = 0; 10223e12c5d1SDavid du Colombier linebp = lp; 10233e12c5d1SDavid du Colombier break; 10243e12c5d1SDavid du Colombier } 10253e12c5d1SDavid du Colombier nl -= sizeof(Rune); 10263e12c5d1SDavid du Colombier if(nl == 0) { 10273e12c5d1SDavid du Colombier tl += BLKSIZE/2; 10283e12c5d1SDavid du Colombier bp = getblock(tl, OWRITE); 10293e12c5d1SDavid du Colombier nl = nleft; 10303e12c5d1SDavid du Colombier } 10313e12c5d1SDavid du Colombier } 10323e12c5d1SDavid du Colombier nl = tline; 10333e12c5d1SDavid du Colombier tline += ((lp-linebuf) + 03) & 077776; 10343e12c5d1SDavid du Colombier return nl; 10353e12c5d1SDavid du Colombier } 10363e12c5d1SDavid du Colombier 10373e12c5d1SDavid du Colombier void 10383e12c5d1SDavid du Colombier blkio(int b, uchar *buf, long (*iofcn)(int, void *, long)) 10393e12c5d1SDavid du Colombier { 10403e12c5d1SDavid du Colombier seek(tfile, b*BLKSIZE, 0); 10413e12c5d1SDavid du Colombier if((*iofcn)(tfile, buf, BLKSIZE) != BLKSIZE) { 10423e12c5d1SDavid du Colombier error(T); 10433e12c5d1SDavid du Colombier } 10443e12c5d1SDavid du Colombier } 10453e12c5d1SDavid du Colombier 10463e12c5d1SDavid du Colombier Rune* 10473e12c5d1SDavid du Colombier getblock(int atl, int iof) 10483e12c5d1SDavid du Colombier { 10493e12c5d1SDavid du Colombier int bno, off; 10503e12c5d1SDavid du Colombier 10513e12c5d1SDavid du Colombier static uchar ibuff[BLKSIZE]; 10523e12c5d1SDavid du Colombier static uchar obuff[BLKSIZE]; 10533e12c5d1SDavid du Colombier 10543e12c5d1SDavid du Colombier bno = atl / (BLKSIZE/2); 10553e12c5d1SDavid du Colombier off = (atl<<1) & (BLKSIZE-1) & ~03; 10563e12c5d1SDavid du Colombier if(bno >= NBLK) { 10573e12c5d1SDavid du Colombier lastc = '\n'; 10583e12c5d1SDavid du Colombier error(T); 10593e12c5d1SDavid du Colombier } 10603e12c5d1SDavid du Colombier nleft = BLKSIZE - off; 10613e12c5d1SDavid du Colombier if(bno == iblock) { 10623e12c5d1SDavid du Colombier ichanged |= iof; 10633e12c5d1SDavid du Colombier return (Rune*)(ibuff+off); 10643e12c5d1SDavid du Colombier } 10653e12c5d1SDavid du Colombier if(bno == oblock) 10663e12c5d1SDavid du Colombier return (Rune*)(obuff+off); 10673e12c5d1SDavid du Colombier if(iof == OREAD) { 10683e12c5d1SDavid du Colombier if(ichanged) 10693e12c5d1SDavid du Colombier blkio(iblock, ibuff, write); 10703e12c5d1SDavid du Colombier ichanged = 0; 10713e12c5d1SDavid du Colombier iblock = bno; 10723e12c5d1SDavid du Colombier blkio(bno, ibuff, read); 10733e12c5d1SDavid du Colombier return (Rune*)(ibuff+off); 10743e12c5d1SDavid du Colombier } 10753e12c5d1SDavid du Colombier if(oblock >= 0) 10763e12c5d1SDavid du Colombier blkio(oblock, obuff, write); 10773e12c5d1SDavid du Colombier oblock = bno; 10783e12c5d1SDavid du Colombier return (Rune*)(obuff+off); 10793e12c5d1SDavid du Colombier } 10803e12c5d1SDavid du Colombier 10813e12c5d1SDavid du Colombier void 10823e12c5d1SDavid du Colombier init(void) 10833e12c5d1SDavid du Colombier { 10843e12c5d1SDavid du Colombier int *markp; 10853e12c5d1SDavid du Colombier 10863e12c5d1SDavid du Colombier close(tfile); 10873e12c5d1SDavid du Colombier tline = 2; 10883e12c5d1SDavid du Colombier for(markp = names; markp < &names[26]; ) 10893e12c5d1SDavid du Colombier *markp++ = 0; 10903e12c5d1SDavid du Colombier subnewa = 0; 10913e12c5d1SDavid du Colombier anymarks = 0; 10923e12c5d1SDavid du Colombier iblock = -1; 10933e12c5d1SDavid du Colombier oblock = -1; 10943e12c5d1SDavid du Colombier ichanged = 0; 10953e12c5d1SDavid du Colombier if((tfile = create(tfname, ORDWR, 0600)) < 0){ 10963e12c5d1SDavid du Colombier error1(T); 10973e12c5d1SDavid du Colombier exits(0); 10983e12c5d1SDavid du Colombier } 10993e12c5d1SDavid du Colombier dot = dol = zero; 11003e12c5d1SDavid du Colombier } 11013e12c5d1SDavid du Colombier 11023e12c5d1SDavid du Colombier void 11033e12c5d1SDavid du Colombier global(int k) 11043e12c5d1SDavid du Colombier { 11053e12c5d1SDavid du Colombier Rune *gp, globuf[GBSIZE]; 11063e12c5d1SDavid du Colombier int c, *a1; 11073e12c5d1SDavid du Colombier 11083e12c5d1SDavid du Colombier if(globp) 11093e12c5d1SDavid du Colombier error(Q); 11103e12c5d1SDavid du Colombier setwide(); 11113e12c5d1SDavid du Colombier squeeze(dol > zero); 11123e12c5d1SDavid du Colombier c = getchr(); 11133e12c5d1SDavid du Colombier if(c == '\n') 11143e12c5d1SDavid du Colombier error(Q); 11153e12c5d1SDavid du Colombier compile(c); 11163e12c5d1SDavid du Colombier gp = globuf; 11173e12c5d1SDavid du Colombier while((c=getchr()) != '\n') { 11183e12c5d1SDavid du Colombier if(c == EOF) 11193e12c5d1SDavid du Colombier error(Q); 11203e12c5d1SDavid du Colombier if(c == '\\') { 11213e12c5d1SDavid du Colombier c = getchr(); 11223e12c5d1SDavid du Colombier if(c != '\n') 11233e12c5d1SDavid du Colombier *gp++ = '\\'; 11243e12c5d1SDavid du Colombier } 11253e12c5d1SDavid du Colombier *gp++ = c; 11263e12c5d1SDavid du Colombier if(gp >= &globuf[GBSIZE-2]) 11273e12c5d1SDavid du Colombier error(Q); 11283e12c5d1SDavid du Colombier } 11293e12c5d1SDavid du Colombier if(gp == globuf) 11303e12c5d1SDavid du Colombier *gp++ = 'p'; 11313e12c5d1SDavid du Colombier *gp++ = '\n'; 11323e12c5d1SDavid du Colombier *gp = 0; 11333e12c5d1SDavid du Colombier for(a1=zero; a1<=dol; a1++) { 11343e12c5d1SDavid du Colombier *a1 &= ~01; 11353e12c5d1SDavid du Colombier if(a1 >= addr1 && a1 <= addr2 && match(a1) == k) 11363e12c5d1SDavid du Colombier *a1 |= 01; 11373e12c5d1SDavid du Colombier } 11383e12c5d1SDavid du Colombier 11393e12c5d1SDavid du Colombier /* 11403e12c5d1SDavid du Colombier * Special case: g/.../d (avoid n^2 algorithm) 11413e12c5d1SDavid du Colombier */ 11423e12c5d1SDavid du Colombier if(globuf[0] == 'd' && globuf[1] == '\n' && globuf[2] == 0) { 11433e12c5d1SDavid du Colombier gdelete(); 11443e12c5d1SDavid du Colombier return; 11453e12c5d1SDavid du Colombier } 11463e12c5d1SDavid du Colombier for(a1=zero; a1<=dol; a1++) { 11473e12c5d1SDavid du Colombier if(*a1 & 01) { 11483e12c5d1SDavid du Colombier *a1 &= ~01; 11493e12c5d1SDavid du Colombier dot = a1; 11503e12c5d1SDavid du Colombier globp = globuf; 11513e12c5d1SDavid du Colombier commands(); 11523e12c5d1SDavid du Colombier a1 = zero; 11533e12c5d1SDavid du Colombier } 11543e12c5d1SDavid du Colombier } 11553e12c5d1SDavid du Colombier } 11563e12c5d1SDavid du Colombier 11573e12c5d1SDavid du Colombier void 11583e12c5d1SDavid du Colombier join(void) 11593e12c5d1SDavid du Colombier { 11603e12c5d1SDavid du Colombier Rune *gp, *lp; 11613e12c5d1SDavid du Colombier int *a1; 11623e12c5d1SDavid du Colombier 11633e12c5d1SDavid du Colombier nonzero(); 11643e12c5d1SDavid du Colombier gp = genbuf; 11653e12c5d1SDavid du Colombier for(a1=addr1; a1<=addr2; a1++) { 11663e12c5d1SDavid du Colombier lp = getline(*a1); 11673e12c5d1SDavid du Colombier while(*gp = *lp++) 11683e12c5d1SDavid du Colombier if(gp++ >= &genbuf[LBSIZE-2]) 11693e12c5d1SDavid du Colombier error(Q); 11703e12c5d1SDavid du Colombier } 11713e12c5d1SDavid du Colombier lp = linebuf; 11723e12c5d1SDavid du Colombier gp = genbuf; 11733e12c5d1SDavid du Colombier while(*lp++ = *gp++) 11743e12c5d1SDavid du Colombier ; 11753e12c5d1SDavid du Colombier *addr1 = putline(); 11763e12c5d1SDavid du Colombier if(addr1 < addr2) 11773e12c5d1SDavid du Colombier rdelete(addr1+1, addr2); 11783e12c5d1SDavid du Colombier dot = addr1; 11793e12c5d1SDavid du Colombier } 11803e12c5d1SDavid du Colombier 11813e12c5d1SDavid du Colombier void 11823e12c5d1SDavid du Colombier substitute(int inglob) 11833e12c5d1SDavid du Colombier { 11843e12c5d1SDavid du Colombier int *mp, *a1, nl, gsubf, n; 11853e12c5d1SDavid du Colombier 11863e12c5d1SDavid du Colombier n = getnum(); /* OK even if n==0 */ 11873e12c5d1SDavid du Colombier gsubf = compsub(); 11883e12c5d1SDavid du Colombier for(a1 = addr1; a1 <= addr2; a1++) { 11893e12c5d1SDavid du Colombier if(match(a1)){ 11903e12c5d1SDavid du Colombier int *ozero; 11913e12c5d1SDavid du Colombier int m = n; 11923e12c5d1SDavid du Colombier 11933e12c5d1SDavid du Colombier do { 11943e12c5d1SDavid du Colombier int span = loc2-loc1; 11953e12c5d1SDavid du Colombier 11963e12c5d1SDavid du Colombier if(--m <= 0) { 11973e12c5d1SDavid du Colombier dosub(); 11983e12c5d1SDavid du Colombier if(!gsubf) 11993e12c5d1SDavid du Colombier break; 12003e12c5d1SDavid du Colombier if(span == 0) { /* null RE match */ 12013e12c5d1SDavid du Colombier if(*loc2 == 0) 12023e12c5d1SDavid du Colombier break; 12033e12c5d1SDavid du Colombier loc2++; 12043e12c5d1SDavid du Colombier } 12053e12c5d1SDavid du Colombier } 12063e12c5d1SDavid du Colombier } while(match(0)); 12073e12c5d1SDavid du Colombier if(m <= 0) { 12083e12c5d1SDavid du Colombier inglob |= 01; 12093e12c5d1SDavid du Colombier subnewa = putline(); 12103e12c5d1SDavid du Colombier *a1 &= ~01; 12113e12c5d1SDavid du Colombier if(anymarks) { 12123e12c5d1SDavid du Colombier for(mp=names; mp<&names[26]; mp++) 12133e12c5d1SDavid du Colombier if(*mp == *a1) 12143e12c5d1SDavid du Colombier *mp = subnewa; 12153e12c5d1SDavid du Colombier } 12163e12c5d1SDavid du Colombier subolda = *a1; 12173e12c5d1SDavid du Colombier *a1 = subnewa; 12183e12c5d1SDavid du Colombier ozero = zero; 12193e12c5d1SDavid du Colombier nl = append(getsub, a1); 12203e12c5d1SDavid du Colombier addr2 += nl; 12213e12c5d1SDavid du Colombier nl += zero-ozero; 12223e12c5d1SDavid du Colombier a1 += nl; 12233e12c5d1SDavid du Colombier } 12243e12c5d1SDavid du Colombier } 12253e12c5d1SDavid du Colombier } 12263e12c5d1SDavid du Colombier if(inglob == 0) 12273e12c5d1SDavid du Colombier error(Q); 12283e12c5d1SDavid du Colombier } 12293e12c5d1SDavid du Colombier 12303e12c5d1SDavid du Colombier int 12313e12c5d1SDavid du Colombier compsub(void) 12323e12c5d1SDavid du Colombier { 12333e12c5d1SDavid du Colombier int seof, c; 12343e12c5d1SDavid du Colombier Rune *p; 12353e12c5d1SDavid du Colombier 12363e12c5d1SDavid du Colombier seof = getchr(); 12373e12c5d1SDavid du Colombier if(seof == '\n' || seof == ' ') 12383e12c5d1SDavid du Colombier error(Q); 12393e12c5d1SDavid du Colombier compile(seof); 12403e12c5d1SDavid du Colombier p = rhsbuf; 12413e12c5d1SDavid du Colombier for(;;) { 12423e12c5d1SDavid du Colombier c = getchr(); 12433e12c5d1SDavid du Colombier if(c == '\\') { 12443e12c5d1SDavid du Colombier c = getchr(); 12453e12c5d1SDavid du Colombier *p++ = ESCFLG; 12463e12c5d1SDavid du Colombier if(p >= &rhsbuf[LBSIZE/2]) 12473e12c5d1SDavid du Colombier error(Q); 12483e12c5d1SDavid du Colombier } else 12493e12c5d1SDavid du Colombier if(c == '\n' && (!globp || !globp[0])) { 12503e12c5d1SDavid du Colombier peekc = c; 12513e12c5d1SDavid du Colombier pflag++; 12523e12c5d1SDavid du Colombier break; 12533e12c5d1SDavid du Colombier } else 12543e12c5d1SDavid du Colombier if(c == seof) 12553e12c5d1SDavid du Colombier break; 12563e12c5d1SDavid du Colombier *p++ = c; 12573e12c5d1SDavid du Colombier if(p >= &rhsbuf[LBSIZE/2]) 12583e12c5d1SDavid du Colombier error(Q); 12593e12c5d1SDavid du Colombier } 12603e12c5d1SDavid du Colombier *p = 0; 12613e12c5d1SDavid du Colombier peekc = getchr(); 12623e12c5d1SDavid du Colombier if(peekc == 'g') { 12633e12c5d1SDavid du Colombier peekc = 0; 12643e12c5d1SDavid du Colombier newline(); 12653e12c5d1SDavid du Colombier return 1; 12663e12c5d1SDavid du Colombier } 12673e12c5d1SDavid du Colombier newline(); 12683e12c5d1SDavid du Colombier return 0; 12693e12c5d1SDavid du Colombier } 12703e12c5d1SDavid du Colombier 12713e12c5d1SDavid du Colombier int 12723e12c5d1SDavid du Colombier getsub(void) 12733e12c5d1SDavid du Colombier { 12743e12c5d1SDavid du Colombier Rune *p1, *p2; 12753e12c5d1SDavid du Colombier 12763e12c5d1SDavid du Colombier p1 = linebuf; 12773e12c5d1SDavid du Colombier if((p2 = linebp) == 0) 12783e12c5d1SDavid du Colombier return EOF; 12793e12c5d1SDavid du Colombier while(*p1++ = *p2++) 12803e12c5d1SDavid du Colombier ; 12813e12c5d1SDavid du Colombier linebp = 0; 12823e12c5d1SDavid du Colombier return 0; 12833e12c5d1SDavid du Colombier } 12843e12c5d1SDavid du Colombier 12853e12c5d1SDavid du Colombier void 12863e12c5d1SDavid du Colombier dosub(void) 12873e12c5d1SDavid du Colombier { 12883e12c5d1SDavid du Colombier Rune *lp, *sp, *rp; 12893e12c5d1SDavid du Colombier int c, n; 12903e12c5d1SDavid du Colombier 12913e12c5d1SDavid du Colombier lp = linebuf; 12923e12c5d1SDavid du Colombier sp = genbuf; 12933e12c5d1SDavid du Colombier rp = rhsbuf; 12943e12c5d1SDavid du Colombier while(lp < loc1) 12953e12c5d1SDavid du Colombier *sp++ = *lp++; 12963e12c5d1SDavid du Colombier while(c = *rp++) { 12973e12c5d1SDavid du Colombier if(c == '&'){ 12983e12c5d1SDavid du Colombier sp = place(sp, loc1, loc2); 12993e12c5d1SDavid du Colombier continue; 13003e12c5d1SDavid du Colombier } 13013e12c5d1SDavid du Colombier if(c == ESCFLG && (c = *rp++) >= '1' && c < MAXSUB+'0') { 13023e12c5d1SDavid du Colombier n = c-'0'; 13033e12c5d1SDavid du Colombier if(subexp[n].rsp && subexp[n].rep) { 13043e12c5d1SDavid du Colombier sp = place(sp, subexp[n].rsp, subexp[n].rep); 13053e12c5d1SDavid du Colombier continue; 13063e12c5d1SDavid du Colombier } 13073e12c5d1SDavid du Colombier error(Q); 13083e12c5d1SDavid du Colombier } 13093e12c5d1SDavid du Colombier *sp++ = c; 13103e12c5d1SDavid du Colombier if(sp >= &genbuf[LBSIZE]) 13113e12c5d1SDavid du Colombier error(Q); 13123e12c5d1SDavid du Colombier } 13133e12c5d1SDavid du Colombier lp = loc2; 13143e12c5d1SDavid du Colombier loc2 = sp - genbuf + linebuf; 13153e12c5d1SDavid du Colombier while(*sp++ = *lp++) 13163e12c5d1SDavid du Colombier if(sp >= &genbuf[LBSIZE]) 13173e12c5d1SDavid du Colombier error(Q); 13183e12c5d1SDavid du Colombier lp = linebuf; 13193e12c5d1SDavid du Colombier sp = genbuf; 13203e12c5d1SDavid du Colombier while(*lp++ = *sp++) 13213e12c5d1SDavid du Colombier ; 13223e12c5d1SDavid du Colombier } 13233e12c5d1SDavid du Colombier 13243e12c5d1SDavid du Colombier Rune* 13253e12c5d1SDavid du Colombier place(Rune *sp, Rune *l1, Rune *l2) 13263e12c5d1SDavid du Colombier { 13273e12c5d1SDavid du Colombier 13283e12c5d1SDavid du Colombier while(l1 < l2) { 13293e12c5d1SDavid du Colombier *sp++ = *l1++; 13303e12c5d1SDavid du Colombier if(sp >= &genbuf[LBSIZE]) 13313e12c5d1SDavid du Colombier error(Q); 13323e12c5d1SDavid du Colombier } 13333e12c5d1SDavid du Colombier return sp; 13343e12c5d1SDavid du Colombier } 13353e12c5d1SDavid du Colombier 13363e12c5d1SDavid du Colombier void 13373e12c5d1SDavid du Colombier move(int cflag) 13383e12c5d1SDavid du Colombier { 13393e12c5d1SDavid du Colombier int *adt, *ad1, *ad2; 13403e12c5d1SDavid du Colombier 13413e12c5d1SDavid du Colombier nonzero(); 13423e12c5d1SDavid du Colombier if((adt = address())==0) /* address() guarantees addr is in range */ 13433e12c5d1SDavid du Colombier error(Q); 13443e12c5d1SDavid du Colombier newline(); 13453e12c5d1SDavid du Colombier if(cflag) { 13463e12c5d1SDavid du Colombier int *ozero, delta; 13473e12c5d1SDavid du Colombier ad1 = dol; 13483e12c5d1SDavid du Colombier ozero = zero; 13493e12c5d1SDavid du Colombier append(getcopy, ad1++); 13503e12c5d1SDavid du Colombier ad2 = dol; 13513e12c5d1SDavid du Colombier delta = zero - ozero; 13523e12c5d1SDavid du Colombier ad1 += delta; 13533e12c5d1SDavid du Colombier adt += delta; 13543e12c5d1SDavid du Colombier } else { 13553e12c5d1SDavid du Colombier ad2 = addr2; 13563e12c5d1SDavid du Colombier for(ad1 = addr1; ad1 <= ad2;) 13573e12c5d1SDavid du Colombier *ad1++ &= ~01; 13583e12c5d1SDavid du Colombier ad1 = addr1; 13593e12c5d1SDavid du Colombier } 13603e12c5d1SDavid du Colombier ad2++; 13613e12c5d1SDavid du Colombier if(adt<ad1) { 13623e12c5d1SDavid du Colombier dot = adt + (ad2-ad1); 13633e12c5d1SDavid du Colombier if((++adt)==ad1) 13643e12c5d1SDavid du Colombier return; 13653e12c5d1SDavid du Colombier reverse(adt, ad1); 13663e12c5d1SDavid du Colombier reverse(ad1, ad2); 13673e12c5d1SDavid du Colombier reverse(adt, ad2); 13683e12c5d1SDavid du Colombier } else 13693e12c5d1SDavid du Colombier if(adt >= ad2) { 13703e12c5d1SDavid du Colombier dot = adt++; 13713e12c5d1SDavid du Colombier reverse(ad1, ad2); 13723e12c5d1SDavid du Colombier reverse(ad2, adt); 13733e12c5d1SDavid du Colombier reverse(ad1, adt); 13743e12c5d1SDavid du Colombier } else 13753e12c5d1SDavid du Colombier error(Q); 13763e12c5d1SDavid du Colombier fchange = 1; 13773e12c5d1SDavid du Colombier } 13783e12c5d1SDavid du Colombier 13793e12c5d1SDavid du Colombier void 13803e12c5d1SDavid du Colombier reverse(int *a1, int *a2) 13813e12c5d1SDavid du Colombier { 13823e12c5d1SDavid du Colombier int t; 13833e12c5d1SDavid du Colombier 13843e12c5d1SDavid du Colombier for(;;) { 13853e12c5d1SDavid du Colombier t = *--a2; 13863e12c5d1SDavid du Colombier if(a2 <= a1) 13873e12c5d1SDavid du Colombier return; 13883e12c5d1SDavid du Colombier *a2 = *a1; 13893e12c5d1SDavid du Colombier *a1++ = t; 13903e12c5d1SDavid du Colombier } 13913e12c5d1SDavid du Colombier } 13923e12c5d1SDavid du Colombier 13933e12c5d1SDavid du Colombier int 13943e12c5d1SDavid du Colombier getcopy(void) 13953e12c5d1SDavid du Colombier { 13963e12c5d1SDavid du Colombier if(addr1 > addr2) 13973e12c5d1SDavid du Colombier return EOF; 13983e12c5d1SDavid du Colombier getline(*addr1++); 13993e12c5d1SDavid du Colombier return 0; 14003e12c5d1SDavid du Colombier } 14013e12c5d1SDavid du Colombier 14023e12c5d1SDavid du Colombier void 14033e12c5d1SDavid du Colombier compile(int eof) 14043e12c5d1SDavid du Colombier { 14053e12c5d1SDavid du Colombier Rune c; 14063e12c5d1SDavid du Colombier char *ep; 14073e12c5d1SDavid du Colombier char expbuf[ESIZE]; 14083e12c5d1SDavid du Colombier 14093e12c5d1SDavid du Colombier if((c = getchr()) == '\n') { 14103e12c5d1SDavid du Colombier peekc = c; 14113e12c5d1SDavid du Colombier c = eof; 14123e12c5d1SDavid du Colombier } 14133e12c5d1SDavid du Colombier if(c == eof) { 14143e12c5d1SDavid du Colombier if(!pattern) 14153e12c5d1SDavid du Colombier error(Q); 14163e12c5d1SDavid du Colombier return; 14173e12c5d1SDavid du Colombier } 14183e12c5d1SDavid du Colombier if(pattern) { 14193e12c5d1SDavid du Colombier free(pattern); 14203e12c5d1SDavid du Colombier pattern = 0; 14213e12c5d1SDavid du Colombier } 14223e12c5d1SDavid du Colombier ep = expbuf; 14233e12c5d1SDavid du Colombier do { 14243e12c5d1SDavid du Colombier if(c == '\\') { 14253e12c5d1SDavid du Colombier if(ep >= expbuf+sizeof(expbuf)) { 14263e12c5d1SDavid du Colombier error(Q); 14273e12c5d1SDavid du Colombier return; 14283e12c5d1SDavid du Colombier } 14293e12c5d1SDavid du Colombier ep += runetochar(ep, &c); 14303e12c5d1SDavid du Colombier if((c = getchr()) == '\n') { 14313e12c5d1SDavid du Colombier error(Q); 14323e12c5d1SDavid du Colombier return; 14333e12c5d1SDavid du Colombier } 14343e12c5d1SDavid du Colombier } 14353e12c5d1SDavid du Colombier if(ep >= expbuf+sizeof(expbuf)) { 14363e12c5d1SDavid du Colombier error(Q); 14373e12c5d1SDavid du Colombier return; 14383e12c5d1SDavid du Colombier } 14393e12c5d1SDavid du Colombier ep += runetochar(ep, &c); 14403e12c5d1SDavid du Colombier } while((c = getchr()) != eof && c != '\n'); 14413e12c5d1SDavid du Colombier if(c == '\n') 14423e12c5d1SDavid du Colombier peekc = c; 14433e12c5d1SDavid du Colombier *ep = 0; 14443e12c5d1SDavid du Colombier pattern = regcomp(expbuf); 14453e12c5d1SDavid du Colombier } 14463e12c5d1SDavid du Colombier 14473e12c5d1SDavid du Colombier int 14483e12c5d1SDavid du Colombier match(int *addr) 14493e12c5d1SDavid du Colombier { 14503e12c5d1SDavid du Colombier if(!pattern) 14513e12c5d1SDavid du Colombier return 0; 14523e12c5d1SDavid du Colombier if(addr){ 14533e12c5d1SDavid du Colombier if(addr == zero) 14543e12c5d1SDavid du Colombier return 0; 14553e12c5d1SDavid du Colombier subexp[0].rsp = getline(*addr); 14563e12c5d1SDavid du Colombier } else 14573e12c5d1SDavid du Colombier subexp[0].rsp = loc2; 14583e12c5d1SDavid du Colombier subexp[0].rep = 0; 14593e12c5d1SDavid du Colombier if(rregexec(pattern, linebuf, subexp, MAXSUB)) { 14603e12c5d1SDavid du Colombier loc1 = subexp[0].rsp; 14613e12c5d1SDavid du Colombier loc2 = subexp[0].rep; 14623e12c5d1SDavid du Colombier return 1; 14633e12c5d1SDavid du Colombier } 14643e12c5d1SDavid du Colombier loc1 = loc2 = 0; 14653e12c5d1SDavid du Colombier return 0; 14663e12c5d1SDavid du Colombier 14673e12c5d1SDavid du Colombier } 14683e12c5d1SDavid du Colombier 14693e12c5d1SDavid du Colombier void 14703e12c5d1SDavid du Colombier putd(void) 14713e12c5d1SDavid du Colombier { 14723e12c5d1SDavid du Colombier int r; 14733e12c5d1SDavid du Colombier 14743e12c5d1SDavid du Colombier r = count%10; 14753e12c5d1SDavid du Colombier count /= 10; 14763e12c5d1SDavid du Colombier if(count) 14773e12c5d1SDavid du Colombier putd(); 14783e12c5d1SDavid du Colombier putchr(r + L'0'); 14793e12c5d1SDavid du Colombier } 14803e12c5d1SDavid du Colombier 14813e12c5d1SDavid du Colombier void 14823e12c5d1SDavid du Colombier putst(char *sp) 14833e12c5d1SDavid du Colombier { 14843e12c5d1SDavid du Colombier Rune r; 14853e12c5d1SDavid du Colombier 14863e12c5d1SDavid du Colombier col = 0; 14873e12c5d1SDavid du Colombier for(;;) { 14883e12c5d1SDavid du Colombier sp += chartorune(&r, sp); 14893e12c5d1SDavid du Colombier if(r == 0) 14903e12c5d1SDavid du Colombier break; 14913e12c5d1SDavid du Colombier putchr(r); 14923e12c5d1SDavid du Colombier } 14933e12c5d1SDavid du Colombier putchr(L'\n'); 14943e12c5d1SDavid du Colombier } 14953e12c5d1SDavid du Colombier 14963e12c5d1SDavid du Colombier void 14973e12c5d1SDavid du Colombier putshst(Rune *sp) 14983e12c5d1SDavid du Colombier { 14993e12c5d1SDavid du Colombier col = 0; 15003e12c5d1SDavid du Colombier while(*sp) 15013e12c5d1SDavid du Colombier putchr(*sp++); 15023e12c5d1SDavid du Colombier putchr(L'\n'); 15033e12c5d1SDavid du Colombier } 15043e12c5d1SDavid du Colombier 15053e12c5d1SDavid du Colombier void 15063e12c5d1SDavid du Colombier putchr(int ac) 15073e12c5d1SDavid du Colombier { 15083e12c5d1SDavid du Colombier char *lp; 15093e12c5d1SDavid du Colombier int c; 15103e12c5d1SDavid du Colombier Rune rune; 15113e12c5d1SDavid du Colombier 15123e12c5d1SDavid du Colombier lp = linp; 15133e12c5d1SDavid du Colombier c = ac; 15143e12c5d1SDavid du Colombier if(listf) { 15153e12c5d1SDavid du Colombier if(c == '\n') { 15163e12c5d1SDavid du Colombier if(linp != line && linp[-1] == ' ') { 15173e12c5d1SDavid du Colombier *lp++ = '\\'; 15183e12c5d1SDavid du Colombier *lp++ = 'n'; 15193e12c5d1SDavid du Colombier } 15203e12c5d1SDavid du Colombier } else { 15213e12c5d1SDavid du Colombier if(col > (72-6-2)) { 15223e12c5d1SDavid du Colombier col = 8; 15233e12c5d1SDavid du Colombier *lp++ = '\\'; 15243e12c5d1SDavid du Colombier *lp++ = '\n'; 15253e12c5d1SDavid du Colombier *lp++ = '\t'; 15263e12c5d1SDavid du Colombier } 15273e12c5d1SDavid du Colombier col++; 15283e12c5d1SDavid du Colombier if(c=='\b' || c=='\t' || c=='\\') { 15293e12c5d1SDavid du Colombier *lp++ = '\\'; 15303e12c5d1SDavid du Colombier if(c == '\b') 15313e12c5d1SDavid du Colombier c = 'b'; 15323e12c5d1SDavid du Colombier else 15333e12c5d1SDavid du Colombier if(c == '\t') 15343e12c5d1SDavid du Colombier c = 't'; 15353e12c5d1SDavid du Colombier col++; 15363e12c5d1SDavid du Colombier } else 15373e12c5d1SDavid du Colombier if(c<' ' || c>='\177') { 15383e12c5d1SDavid du Colombier *lp++ = '\\'; 15393e12c5d1SDavid du Colombier *lp++ = 'x'; 15403e12c5d1SDavid du Colombier *lp++ = hex[c>>12]; 15413e12c5d1SDavid du Colombier *lp++ = hex[c>>8&0xF]; 15423e12c5d1SDavid du Colombier *lp++ = hex[c>>4&0xF]; 15433e12c5d1SDavid du Colombier c = hex[c&0xF]; 15443e12c5d1SDavid du Colombier col += 5; 15453e12c5d1SDavid du Colombier } 15463e12c5d1SDavid du Colombier } 15473e12c5d1SDavid du Colombier } 15483e12c5d1SDavid du Colombier 15493e12c5d1SDavid du Colombier rune = c; 15503e12c5d1SDavid du Colombier lp += runetochar(lp, &rune); 15513e12c5d1SDavid du Colombier 15523e12c5d1SDavid du Colombier if(c == '\n' || lp >= &line[sizeof(line)-5]) { 15533e12c5d1SDavid du Colombier linp = line; 15543e12c5d1SDavid du Colombier write(oflag? 2: 1, line, lp-line); 15553e12c5d1SDavid du Colombier return; 15563e12c5d1SDavid du Colombier } 15573e12c5d1SDavid du Colombier linp = lp; 15583e12c5d1SDavid du Colombier } 15593e12c5d1SDavid du Colombier 15603e12c5d1SDavid du Colombier char* 15613e12c5d1SDavid du Colombier mktemp(char *as) 15623e12c5d1SDavid du Colombier { 15633e12c5d1SDavid du Colombier char *s; 15643e12c5d1SDavid du Colombier unsigned pid; 15653e12c5d1SDavid du Colombier int i; 15663e12c5d1SDavid du Colombier 15673e12c5d1SDavid du Colombier pid = getpid(); 15683e12c5d1SDavid du Colombier s = as; 15693e12c5d1SDavid du Colombier while(*s++) 15703e12c5d1SDavid du Colombier ; 15713e12c5d1SDavid du Colombier s--; 15723e12c5d1SDavid du Colombier while(*--s == 'X') { 15733e12c5d1SDavid du Colombier *s = pid % 10 + '0'; 15743e12c5d1SDavid du Colombier pid /= 10; 15753e12c5d1SDavid du Colombier } 15763e12c5d1SDavid du Colombier s++; 15773e12c5d1SDavid du Colombier i = 'a'; 15783e12c5d1SDavid du Colombier while(access(as, 0) != -1) { 15793e12c5d1SDavid du Colombier if(i == 'z') 15803e12c5d1SDavid du Colombier return "/"; 15813e12c5d1SDavid du Colombier *s = i++; 15823e12c5d1SDavid du Colombier } 15833e12c5d1SDavid du Colombier return as; 15843e12c5d1SDavid du Colombier } 15853e12c5d1SDavid du Colombier 15863e12c5d1SDavid du Colombier void 15873e12c5d1SDavid du Colombier regerror(char *s) 15883e12c5d1SDavid du Colombier { 15893e12c5d1SDavid du Colombier USED(s); 15903e12c5d1SDavid du Colombier error(Q); 15913e12c5d1SDavid du Colombier } 1592