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