From 55e3f80803f6d80aa43f081faaf62c20abe3a52d Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Mon, 8 Jun 1998 08:36:14 +0000 Subject: [PATCH] QED for Visual Studio, from 1992, 1994 --- visual-studio-1994/address.c | 81 ++++ visual-studio-1994/blkio.c | 93 +++++ visual-studio-1994/getfile.c | 264 ++++++++++++ visual-studio-1994/glob.c | 113 ++++++ visual-studio-1994/main.c | 689 ++++++++++++++++++++++++++++++++ visual-studio-1994/move.c | 137 +++++++ visual-studio-1994/pattern.c | 470 ++++++++++++++++++++++ visual-studio-1994/pseudoheap.c | 45 +++ visual-studio-1994/putchar.c | 154 +++++++ visual-studio-1994/setaddr.c | 32 ++ visual-studio-1994/string.c | 105 +++++ visual-studio-1994/subs.c | 418 +++++++++++++++++++ visual-studio-1994/vars.c | 103 +++++ visual-studio-1994/vars.h | 187 +++++++++ 14 files changed, 2891 insertions(+) create mode 100644 visual-studio-1994/address.c create mode 100644 visual-studio-1994/blkio.c create mode 100644 visual-studio-1994/getfile.c create mode 100644 visual-studio-1994/glob.c create mode 100644 visual-studio-1994/main.c create mode 100644 visual-studio-1994/move.c create mode 100644 visual-studio-1994/pattern.c create mode 100644 visual-studio-1994/pseudoheap.c create mode 100644 visual-studio-1994/putchar.c create mode 100644 visual-studio-1994/setaddr.c create mode 100644 visual-studio-1994/string.c create mode 100644 visual-studio-1994/subs.c create mode 100644 visual-studio-1994/vars.c create mode 100644 visual-studio-1994/vars.h diff --git a/visual-studio-1994/address.c b/visual-studio-1994/address.c new file mode 100644 index 0000000..efd54cb --- /dev/null +++ b/visual-studio-1994/address.c @@ -0,0 +1,81 @@ +/*% cc -c -O % + */ +#include "vars.h" +int * +address() +{ + register int sign, *a; + int opcnt, nextopand, *b; + register c; + + nextopand = -1; + sign = 1; + opcnt = 0; + a = dot; + do { + do c = getchar(); while (c==' ' || c=='\t'); + if ('0'<=c && c<='9') { + peekc = c; + if (!opcnt) + a = zero; + a += sign*getnum(); + } else switch (c) { + case '$': + a = dol; + /* fall through */ + case '.': + if (opcnt) + error('a'); + break; + case '\'': + c = getchar(); + if (opcnt) + error('a'); + if(posn(c, bname)<0) + error('k'); + a = zero; + c = posn(c, bname); /* outside loop for efficiency */ + do a++; while (a<=dol && names[c]!=(*a|01)); + break; + case '?': + sign = -sign; + /* fall through */ + case '/': + compile(c); + b = a; + for (;;) { + a += sign; + if (adol) + a = zero; + if (execute(a)) + break; + if (a==b) + error('/'); + } + break; + default: + if (nextopand == opcnt) { + a += sign; + if (a>8) & BLMASK; + do { + if (nl<=0) { + if (tl==oblock) + bp = obuff; + else { + bp = ibuff; + if (tl!=iblock) { + iblock = -1; /* signal protection */ + blkio(tl, bp, read); + iblock = tl; + } + } + tl++; + bp -= nl; + nl += BLKSIZE; + } + nl--; + } while (*lp++ = *bp++); + return(lbuf); +} +int putline() +{ + register char *op, *lp; + register int r; + extern int write(); + + modified(); + lp = linebuf; + r = (oblock<<8) + (ooff>>1); /* ooff may be 512! */ + op = obuff + ooff; + lock++; + do { + if (op >= obuff+BLKSIZE) { + /* delay updating oblock until after blkio succeeds */ + blkio(oblock, op=obuff, write); + oblock++; + ooff = 0; + } + if((*op = *lp++) == '\n') { + *op++ = '\0'; + linebp = lp; + break; + } + } while (*op++); + ooff = (((op-obuff)+3)&~3); + unlock(); + return (r); +} +blkio(b, buf, iofcn) + char *buf; + int (*iofcn)(); +{ + if (b>=MAXBLOCKS + || (lseek(tfile, ((long) b) * 512L, 0)<0L) + || (*iofcn)(tfile, buf, 512) != 512) { + error('T'); + } +} diff --git a/visual-studio-1994/getfile.c b/visual-studio-1994/getfile.c new file mode 100644 index 0000000..377387a --- /dev/null +++ b/visual-studio-1994/getfile.c @@ -0,0 +1,264 @@ +/*% cc -c -O % + */ +#include "vars.h" +char *nextip; +long count; +/* + * newfile: read a new file name (if given) from command line. + * + * nullerr: if true, error if file is null. + * savspec: decides if string[savedfile] is set. + * If savspec==SAVEIFFIRST, only save if deffile is null. + * deffile: default file name. + * + * return value: string[FILEBUF]!=deffile + * (unless SAVEIFFIRST && deffile null ==> return FALSE) + * side effects: + * can set string[savedfile] + * always sets string[FILEBUF] + * zeroes count + */ +newfile(nullerr, savspec, deffile) + char *deffile; +{ + register char c; + + count = 0L; + cpstr(deffile, genbuf); /* in case we strcompact() */ + startstring(); + c = getchar(); + if(c == '\n') + copystring(genbuf); + else { + if(c != ' ') + error('f'); + do c = getchar(); while(c == ' '); + while(posn(c, " \t\n") < 0){ + if(c<' ' || c=='\177') + error('f'); + addstring(c); + c = getchar(); + } + } + setstring(FILEBUF); + if(nullerr && string[FILEBUF].str[0]=='\0') + error('f'); + if(savspec==SAVEALWAYS || (savspec==SAVEIFFIRST && genbuf[0]=='\0')){ + startstring(); + dupstring(FILEBUF); + setstring(savedfile); + if(savspec==SAVEIFFIRST && genbuf[0]=='\0') + return(FALSE); + } + return(!eqstr(genbuf, string[FILEBUF].str)); +} +exfile() +{ + close(io); + io = -1; + if (vflag && initflag) + ncom('f'); + else if (vflag) { + putlong(count); + putchar('\n'); + } + setcount((int)count); +} +getfile() +{ + register c; + register char *lp, *fp; + lp = linebuf; + fp = nextip; + do { + if (--ninbuf < 0) { + if ((ninbuf = read(io, genbuf, LBSIZE)-1) < 0) { + if(ninbuf < -1) + error('r'); + if(lp != linebuf) + error('N'); + return(EOF); + } + fp = genbuf; + } + if (lp >= &linebuf[LBSIZE]) + error('l'); + if ((*lp++ = c = *fp++ ) == 0) { + lp--; + continue; + } + count++; + } while (c != '\n'); + *--lp = 0; + nextip = fp; + return(0); +} +putfile() +{ + int *a1; + register char *fp, *lp; + register nib; + nib = 512; + fp = genbuf; + a1 = addr1; + if(a1 == zero) + *a1++; + while(a1 <= addr2){ + lp = getline(*a1++, linebuf); + for(;;){ + if (--nib < 0) { + if(write(io, genbuf, fp-genbuf) < 0) + error('w'); + nib = 511; + fp = genbuf; + } + count++; + if ((*fp++ = *lp++) == 0) { + fp[-1] = '\n'; + break; + } + } + } + write(io, genbuf, fp-genbuf); +} +#define SIGHUP 1 +#define SIGINTR 2 +#define SIGQUIT 3 +#define SIGBPIPE 13 +int savint= -1; /* awful; this is known in error() */ +Unix(type) + char type; +{ +#ifdef THIS_IS_NOT_WINDOWS_NT + register pid, rpid; + register char *s; + int *a, c; + int getsvc(); + int onbpipe; + int retcode; + char unixbuf[512]; + int pipe1[2]; + int pipe2[2]; + int *a1, *a2, *ndot; + startstring(); /* for the \zU register */ + if(type == '!') + setnoaddr(); + else { + if(type == '>' || type == '|') + nonzero(); + count = 0L; + if(pipe(pipe1) == -1){ + lastc = '\n'; + error('|'); + } + } + /* Quick hack: if char is doubled, push \'zU */ + if(nextchar()==type){ + getchar(); /* throw it away */ + pushinp(STRING, UNIX, TRUE); + } + /* + * Use c not *s as EOF and getchar() are int's + */ + for(s=unixbuf;(c=getquote("\n", getsvc))!='\n' && c!=EOF;*s++=(c&0177)){ + if(s>=unixbuf+512) + error('l'); + } + dropstring(); /* drop the newline */ + setstring(UNIX); + *s='\0'; + a1 = addr1; + a2 = addr2; + if ((pid = fork()) == 0) { + signal(SIGHUP, onhup); + signal(SIGINTR, onintr); + signal(SIGQUIT, onquit); + if(type=='<' || type=='|'){ + close(1); + dup(pipe1[1]); + }else if(type == '>'){ + close(0); + dup(pipe1[0]); + } + if (type != '!') { + close(pipe1[0]); + close(pipe1[1]); + } + if(type == '|'){ + if(pipe(pipe2) == -1){ + puts("?|"); + exit(1); + } + if((pid=fork()) == 0){ + close(1); + dup(pipe2[1]); + close(pipe2[0]); + close(pipe2[1]); + tfile = tfile2; /* ugh */ + /* + * It's ok if we get SIGBPIPE here + */ + display('p'); + exit(0); + } + if(pid == -1){ + puts("Can't fork\n?!"); + exit(1); + } + close(0); + dup(pipe2[0]); + close(pipe2[0]); + close(pipe2[1]); + } + if (*unixbuf) + execl("/bin/sh", "sh", "-c", unixbuf, 0); + else + execl("/bin/sh", "sh", 0); + exit(-1); + } + if(pid == -1){ + puts("Can't fork"); + error('!'); + } + savint = signal(SIGINTR, 1); + if(type=='<' || type=='|') { + close(pipe1[1]); + io = pipe1[0]; + ninbuf = 0; + append(getfile,addr2); + close(io); + io = -1; + ndot = dot; + } else if(type == '>') { + onbpipe = signal(SIGBPIPE, 1); + close(pipe1[0]); + a=addr1; + do{ + s=getline(*a++, linebuf); + do; while(*s++); + *--s='\n'; + if (write(pipe1[1],linebuf,s-(linebuf-1))<0){ + puts("?o"); + break; + } + }while (a<=addr2); + close(pipe1[1]); + signal(SIGBPIPE, onbpipe); + } + while ((rpid = wait(&retcode)) != pid && rpid != -1); + retcode = (retcode>>8)&0377; + settruth(retcode); + signal(SIGINTR, savint); + if(type == '|'){ + if(retcode == 0){ + addr1 = a1; + addr2 = a2; + delete(); + dot = ndot - (a2-a1+1); + } else + error('0'); + } + if(vflag) + puts("!"); +#endif +} diff --git a/visual-studio-1994/glob.c b/visual-studio-1994/glob.c new file mode 100644 index 0000000..3689f68 --- /dev/null +++ b/visual-studio-1994/glob.c @@ -0,0 +1,113 @@ +/*% cc -c -O % + */ +#include "vars.h" +#define ALWAYS 2 +#define GBSIZE 256 +void +until(nfl, n) +{ + register c, type; + char ubuf[GBSIZE]; + + c = getchar(); + type=posn(c, "ft "); + if(type < 0){ + if(nfl==0) + error('x'); + ungetchar(c); + } + getglob(ubuf); + settruth(FALSE); + if(nfl && n<=0) + return; /* do it zero times */ + do ; while (exglob(ubuf, ubuf) && + !((nfl && --n==0) || + (type != ALWAYS && type == truth()))); +} +global(k) +{ + register int *a1; + char globuf[GBSIZE]; + struct buffer *startbuf; + + if(gflag++) + error('g'); + setall(); + if(nextchar() == '\n') + error('x'); + compile(getchar()); + getglob(globuf); + for (a1=zero; ++a1<=dol;) { + *a1 &= ~01; + if (a1>=addr1 && a1<=addr2 && execute(a1)==k) + *a1 |= 01; + } + startbuf = curbuf; + for (a1=zero; ++a1<=dol; ) { + if (*a1 & 01) { + *a1 &= ~01; + dot = a1; + if (!exglob(globuf, "p")) + break; + chngbuf(startbuf-buffer); + a1 = zero; + } + } + chngbuf(startbuf-buffer); + gflag=FALSE; +} + +globuf(k) +{ + register struct buffer *bp; + char globbuf[GBSIZE]; + + if (biggflag++) + error('G'); + if (nextchar() =='\n') + error('x'); + compile(getchar()); + getglob(globbuf); + for (bp=buffer; bp < &buffer[NBUFS]; bp++) + bp->gmark = FALSE; + ncom('G'); /* mark interesting buffers */ + for (bp=buffer; bp < &buffer[NBUFS]; bp++) + if (bp->gmark == k) { + chngbuf(bp-buffer); + if (!exglob(globbuf, "f\n")) + break; + } + biggflag = FALSE; +} + +getglob(globuf) + char globuf[]; +{ + register char *gp; + register c; + int getchar(); + gp = globuf; + while ((c = getquote("\n", getchar)) != '\n') { + if (c==EOF) + error('x'); + *gp++ = c & 0177; + if (gp >= &globuf[GBSIZE-2]) + error('l'); + } + *gp++ = '\n'; + *gp++ = 0; +} + +exglob(cmd, dflt) + char *cmd, *dflt; +{ + register int nesting; + + pushinp(GLOB, eqstr(cmd,"\n")? dflt : cmd, FALSE); + nesting = ++nestlevel; + commands(); + if (nesting!=nestlevel) + return(FALSE); + nestlevel--; + return(TRUE); +} diff --git a/visual-studio-1994/main.c b/visual-studio-1994/main.c new file mode 100644 index 0000000..5e9b2a2 --- /dev/null +++ b/visual-studio-1994/main.c @@ -0,0 +1,689 @@ +/*% cc -c -O % + */ +#include "vars.h" +#include +/*#include */ +#define SIGHUP 1 +#define SIGINTR 2 +#define SIGQUIT 3 +#define UP 1 +#define DOWN 0 +char lchars[]="pPlL"; +struct buffer *curbuf = buffer; +char *linp = line; +int appflag = 0; +int pagesize = PAGESIZE; +int prflag = 0; /* prflag==1 ==> much code to get it right. use the startup buffer */ +int lastttyc = '\n'; +int gflag = 0; +int tflag = 0; +int vflag = 0; /* initialization code turns it on */ +int uflag = 's'; +int dflag = 0; +int initflag = 1; +int *option[] = { + &cflag, &dflag, &eflag, &iflag, &prflag,&tflag, &vflag, +}; +char opcs[] = "cdeipTv"; +int tfile = -1; +/* DPM 90/12/22. + * struct sgttyb ttybuf = { 0, 0, '\b', '\b', /@0@/}; + */ +char QEDFILE[]="QEDFILE"; +void (*pending)(); +extern void savall(); +extern void commands(); + +void +rescue() +{ + /* Save in qed.hup:[ab]q on hangup */ + signal(SIGHUP,1); + if (lock) { + pending = rescue; + return; + } + startstring(); + copystring("qed.hup"); + setstring(FILEBUF); + savall(); + exit(SIGHUP); +} +char *filea() +{ + register struct string *sp; + register int i, d; + char c; + + sp = &string[FILEBUF]; + startstring(); + d = 0; + i = 0; + while((c=sp->str[i]) != '\0'){ + addstring(c); + i++; + if(c == '/') + d = i; + } + if((i-d) > 12) /* file name is >= 13 characters long */ + string[NSTRING].str -= (i-(d+12)); /* truncate string */ + copystring(":aq"); + setstring(FILEBUF); + return(sp->str); +} + +char *fileb() +{ + register struct string *sp; + + sp = &string[FILEBUF]; + sp->str[sp->len-2] = 'b'; + return(sp->str); +} +void +savall() +{ + register fi; + + syncbuf(); + addr1 = buffer[0].zero + 1; + addr2 = buffer[NBUFS-1].dol; + if(addr1 > addr2){ + error('$'); + return; + } + if((io = creat(filea(), 0644)) < 0) + error('o'|FILERR); + putfile(); + exfile(); + if((fi = creat(fileb(), 0644)) < 0) + error('o'|FILERR); + write(fi, (char *)buffer, sizeof buffer); + write(fi, strarea, sizeof strarea); + lock++; + shiftstring(DOWN); + write(fi, (char *)string, sizeof string); + shiftstring(UP); + unlock(); + close(fi); +} +restor() +{ + register i, t; + register struct buffer *b; + int fi; + int getfile(); + curbuf = buffer; + i = (int)curbuf->zero; + if((t = open(filea(), 0)) < 0){ + lastc = '\n'; + error('o'|FILERR); + } + initio(); + init(); + io = t; + ninbuf = 0; + append(getfile, dol); + exfile(); + if((fi = open(fileb(),0)) < 0) + error('o'|FILERR); + lock++; + if(read(fi,(char *)buffer,sizeof buffer) != sizeof buffer + || read(fi, strarea, sizeof strarea) != sizeof strarea + || read(fi, (char *)string, sizeof string) != sizeof string) + error('R'); + close(fi); + shiftstring(UP); + /* + * This code is incredibly sleazy and machine dependent for the 11. + * Sorry. There is no good reason why we don't have a shiftbuf(): + * feel free to write one (but lock before you call it!). + */ + t = (int)buffer[0].zero; + if(i != t){ + i -= t; + i >>= 1; + for(b = buffer;b <= &buffer[NBUFS-1];b++){ + b->zero += i; + b->dot += i; + b->dol += i; + } + } + newbuf(0); + error(0); /* ==> error, but don't print anything. calls unlock() */ +} + +/* + * On INTR, generate error '?' + */ + +void +interrupt() +{ + signal(SIGINTR, interrupt); + if (lock) { + pending = interrupt; + return; + } + if(iflag){ + close(tfile); + close(tfile2); /* DPM 94. Must close before unlink in NT */ + unlink(tfname); + exit(SIGINTR); + } + linp=line; + putchar('\n'); + lastc = '\n'; + error('?'); +} + +/* + * Unlock: exit a critical section, invoking any pending signal routines. + */ + +unlock() +{ + register void (*p)(); + + p = pending; + pending = 0; + lock = 0; + if (p) + (*p)(); +} + +char cleanup[] = "ba z~:\n"; +char setvflag[] = "ov?"; +char boot1[] = "G/^["; +char boot2[] = "].+\t./r\n"; + +main(int argc, char *argv[]) +{ + register char *p1; + register i; + char buf; + int rvflag; + char *startup=(char *)0; + + argv++; + onquit = signal(SIGQUIT, 1); + onhup = signal(SIGHUP, 1); + onintr = signal(SIGINTR, 1); + rvflag = 1; + for(i=0;i!=NSTRING;i++){ + string[i].str = nullstr; + string[i].len=0; + } + /* initialize strfree */ + string[NSTRING].str = strchars; + while(argc > 1 && **argv=='-'){ + switch(argv[0][1]){ + casedefault: + default: + rvflag = 0; + break; + case 'q': + /* allow debugging quits? */ + signal(SIGQUIT, 0); + break; + case 'i': + /* allow interrupt quits? */ + iflag++; + break; + case 'e': + /* Exit on error? */ + eflag++; + break; + case 'x': + if(argc == 2) + goto casedefault; + startup = argv[1]; + argv++; + --argc; + } + argv++; + --argc; + } +/* DPM 90/12/22 + * gtty(0,&ttybuf); + */ + if(startup==0) { /* DPM 94/12/15 */ + /* startup = getenv(QEDFILE); */ + startup = "/qedfile"; /* NT version */ + } + fendcore = (int *)sbrk(0); + curbuf = &buffer[0]; + init(); +/* if (onhup != 1) SUN invokes shell with onhup==1 */ + signal(SIGHUP, rescue); + if (onintr != 1) + signal(SIGINTR, interrupt); + /* + * Build the initialization code in register z~ + */ + if(startup){ + startstring(); + copystring(startup); + setstring(FILE(NBUFS-1)); + p1 = "b~ r\n\\b~\n"; + } else + p1 = ""; + startstring(); + copystring(p1); + setvflag[2] = "rs"[rvflag]; + copystring(setvflag); + /* + * z~ now has startup-buffer initialization; prepare the file list + * and generate a GLOBUF to read them in + */ + if(--argc > 0) { + if(argc >= 53) /* buffer names a-zA-Z */ + puts("?i"); + else { + copystring(boot1); + for(i=0; i 0) { + startstring(); + copystring(*argv); + setstring(FILE(buf++)); + --argc; + argv++; + } + } + } + else{ + copystring(cleanup); + setstring(NBUFS-1); + } + pushinp(STRING, NBUFS-1, FALSE); + setexit(); + lastttyc = '\n'; + commands(); + close(tfile); + close(tfile2); + unlink(tfname); + exit(lasterr); + return 0; +} + +int noaddr; +void +commands() +{ + register int *a; + register c, lastsep; + int getfile(), gettty(); + int r; + int changed; + long locn, lseek(); + int startline; + + for (;;) { + startline = (lastttyc == '\n' && peekc == 0); + cprflag=prflag; + c = '\n'; + for (addr1=0;;) { + lastsep = c; + a=address(); + c=getchar(); + if (c!=',' && c!=';') + break; + if (lastsep==',') + error('a'); + if (a==0) { + a = zero+1; + if (a>dol) + --a; + } + addr1 = a; + if (c==';') + dot = a; + } + if (lastsep!='\n' && a==0) + a=dol; + if((addr2=a) == 0) { + addr2=dot; + noaddr = TRUE; + } else + noaddr = FALSE; + + if(addr1 == 0) + addr1 = addr2; + + cprflag=FALSE; + switch(c){ + case 'a': + setdot(); + setapp(); + append(gettty, addr2); + continue; + case 'b': + if(posn((c=nextchar()), bname)<0){ /* browse command */ + setdot(); + nonzero(); + bcom(); + continue; + } + c = getaz('b'); + setnoaddr(); + chngbuf(c); + continue; + case 'c': + setdot(); + nonzero(); + setapp(); + append(gettty, addr2); + a = dot-(addr2-addr1+1); + delete(); + dot = a; + continue; + case 'd': + if(posn(nextchar(),"\377\npPlL \t") < 0) + error('x'); + delete(); + continue; + case 'E': + case 'e': + setnoaddr(); + if(c=='e' && !eok && cflag){ + eok=TRUE; + error('e'); + } + newfile(TRUE, SAVEALWAYS, ""); + delall(); + addr1 = zero; + addr2 = zero; + modified(); /* In case file open causes error */ + goto caseread; + case 'f': + setnoaddr(); + if((c = getchar()) != '\n'){ + ungetchar(c); + if(newfile(FALSE, SAVEALWAYS, string[savedfile].str)) + modified(); + if(vflag) + ncom('f'); + } + else + ncom('f'); + continue; + case 'g': + global(TRUE); + continue; + case 'G': + globuf(TRUE); + continue; + case 'h': + setnoaddr(); + if(nextchar()=='\n') + error('x'); + if('0'<=peekc && peekc<='9') + until(TRUE, getnum()); + else + until(FALSE, 0); + continue; + case 'i': + setdot(); + nonzero(); + setapp(); + append(gettty, addr2-1); + continue; + case 'j': + setdot(); + if (addr1 == addr2 && lastsep == '\n'){ + addr1--; + if(addr1 <= zero) + error('$'); + } + nonzero(); + join(); + continue; + case 'k': + c = getaz(c); + setdot(); + nonzero(); + names[c] = *addr2 | 01; + continue; + case 'm': + move(FALSE); + continue; + case 'n': + case 'N': + ncom(c); + continue; + case 'o': + setnoaddr(); + c = getchar(); + r=posn(c, opcs); + if(r >= 0) + setreset(option[r]); + else switch(c) { + case 'B': + if(nextchar() == '\n') + clearstring(BROWSE); + else { + startstring(); + while((c=getchar()) != '\n') + addstring(c); + copystring("\\N"); + setstring(BROWSE); + } + break; + case '?': + if ((r = posn(getchar(), opcs)) < 0) + error('O'); + settruth(*option[r]); + break; + case 'q': + c = getchar(); + if(c=='s' || c =='r') + signal(SIGQUIT, c=='r'); + else + error('x'); + break; + case 'u': + c = getchar(); + if(c == 'r') + uflag = 0; + else if(posn(c, "slu") >= 0) + uflag = c; + else + error('x'); + break; + case 'b': + if((r=getnum()) > 0) + pagesize = r; + if(posn(nextchar(), lchars) >=0) + bformat = getchar(); + break; + default: + error('x'); + } + continue; + case '\n': + if (a==0) { + if(stackp != &stack[0] || !startline) + continue; + if(*string[BROWSE].str){ + pushinp(BRWS, 0, FALSE); + continue; + } + a = dot+1; + addr2 = a; + addr1 = a; + } + if (lastsep==';') + addr1 = a; + c = 'p'; /* fall through */ + case 'L': + case 'l': + case 'p': + case 'P': + display(c); + continue; + case EOF: + return; + case 'Q': + case 'q': + setnoaddr(); + if(c!=EOF && (!startline || getchar()!='\n')) + error('x'); + if(c!='Q' && !qok){ + register struct buffer *bp; + syncbuf(); + qok=TRUE; + for(bp=buffer; bp<&buffer[NBUFS]; bp++) + if(bp->cflag && (bp->dol>bp->zero || + string[FILE(bp-buffer)].str[0])) + error('q'); + } + close(tfile); + close(tfile2); + unlink(tfname); + exit(lasterr); + case 'r': + newfile(TRUE, SAVEIFFIRST, string[savedfile].str); + caseread: + if((io = open(string[FILEBUF].str, 0)) < 0){ + if(initflag){ + putchar('?'); + putchar('o'); + putchar(' '); + puts(string[FILEBUF].str); + continue; + } + lastc = '\n'; + error('o'|FILERR); + } + setall(); + changed = (zero!=dol); + ninbuf = 0; + append(getfile, addr2); + if(eqstr(string[savedfile].str, string[FILEBUF].str)) + if(cflag = changed) /* Assignment = */ + modified(); + /* else append got cflag right */ + exfile(); + continue; + case 'R': + setnoaddr(); + newfile(TRUE, SAVENEVER, "q"); + restor(); + continue; + case 's': + setdot(); + nonzero(); + substitute(stackp != &stack[0], -1); + continue; + case 'S': + setnoaddr(); + newfile(TRUE, SAVENEVER, "q"); + savall(); + continue; + case 't': + move(TRUE); + continue; + case 'u': + setnoaddr(); + undo(); + modified(); + continue; + case 'v': + global(FALSE); + continue; + case 'V': + globuf(FALSE); + continue; + case 'W': + case 'w': + if(addr2==0 && dol==zero) + error('$'); + setall(); + if(newfile(TRUE, SAVEIFFIRST, string[savedfile].str)) + changed = cflag; + else + changed = (addr1>(zero+1) || addr2!=dol); + if(c=='w' || (io=open(string[FILEBUF].str,1))==-1){ + Create: + if ((io = creat(string[FILEBUF].str, 0666)) < 0) + error('o'|FILERR); + }else{ + if((locn=lseek(io, 0L, 2)) == -1L) + goto Create; + if(locn != 0L) /* W on non-empty file */ + changed = TRUE; /* PHEW! figured it out */ + } + putfile(); + if(cflag = changed) /* Assignment = */ + modified(); + exfile(); + continue; + case 'x': + setdot(); + nonzero(); + xform(); + continue; + case 'y': + jump(); + continue; + case 'z': + strcom(getaz('z')); + continue; + case 'Z': + setnoaddr(); + if((c=getchar())!=' ' && c!='\n') + error('x'); + delall(); + cflag=FALSE; + clearstring(savedfile); + continue; + case '"': + setdot(); + dot=addr2; + comment(); + continue; + case '=': + setall(); + putdn((addr2-zero)&077777); + continue; + case '>': + case '<': + case '|': + setall(); + case '!': + Unix(c); + continue; + case '#': + setnoaddr(); + allnums(); + continue; + case '%': + setnoaddr(); + allstrs(); + continue; + } + error('x'); + } +} +setreset(opt) + register int *opt; +{ + register c; + + c = getchar(); + if(c!='s' && c!= 'r') + error('x'); + *opt = (c=='s'); +} +delall(){ + if(dol!=zero){ + addr1=zero+1; + addr2=dol; + delete(); + } +} diff --git a/visual-studio-1994/move.c b/visual-studio-1994/move.c new file mode 100644 index 0000000..a2b6da6 --- /dev/null +++ b/visual-studio-1994/move.c @@ -0,0 +1,137 @@ +/*% cc -c -O % + */ +#include "vars.h" +extern void fixup(); +extern void reverse(); +move(copyflag) +{ + register int *adt, *ad1, *ad2; + int fb, tb; + int todot; + int tonewdot; + int totmved; + int temp; + int getcopy(); + + setdot(); + nonzero(); + fb = curbuf - buffer; + temp = getchar(); + tb = posn(temp, bname); + if(tb >= 0) + chngbuf(tb); + else{ + ungetchar(temp); + tb = fb; + } + if ((adt = address())==0){ + chngbuf(fb); + error('x'); + } + todot = adt - buffer[tb].zero; /* syncbuf not needed! */ + chngbuf(fb); + ad1 = addr1; + ad2 = addr2; + totmved = ad2 - ad1 + 1; + lock++; + if (copyflag) { + tonewdot = addr2 - buffer[fb].zero; + /* + * NOTE: in the copy command + * copies of the lines are created using append + * and then moved to the target position. + * They are appended at the dollar of their + * original buffer. (guarenteed to be higher address) + * They are NOT appended at the target position + * since, if the target position was lower than their + * source position, getcopy would have to account + * for the shift of the addresses due to the insert + * of the copies. + */ + ad1 = dol; + temp = cflag; + append(getcopy, ad1++); + cflag = temp; + ad2 = dol; + } else + tonewdot = addr1 - buffer[fb].zero - 1; + ad2++; + adt = buffer[tb].zero + todot; + chngbuf(tb); + if (adt= ad2) { + reverse(ad1, ad2); + reverse(ad2, adt); + reverse(ad1, adt); + } else { + if(ad2 != zero + 1){ + error('m'); + } + } + } + fixup(fb, tb, totmved); + buffer[fb].dot = buffer[fb].zero + tonewdot; + if(copyflag == 0 && fb == tb && todot >= tonewdot){ + todot -= totmved; + } + if(!copyflag) + buffer[fb].cflag = TRUE; + modified(); + dot = buffer[tb].dot = buffer[tb].zero + todot + totmved; + zero = buffer[tb].zero; + dol = buffer[tb].dol; + unlock(); +} +void +fixup(from,to,tot) int from, to, tot; +{ + register int b; + register int n; + register int lo; + int hi; + if(to == from){ + return; + } + if(to < from){ + n = tot; + lo = to; + hi = from; + } else { + n = -tot; + lo = from; + hi = to; + } + buffer[lo].dol += n; + for(b = lo;++b < hi;){ + buffer[b].zero += n; + buffer[b].dot += n; + buffer[b].dol += n; + } + buffer[hi].zero += n; +} +void +reverse(a1, a2) + register int *a1, *a2; +{ + register t; + for (;;) { + t = *--a2; + if (a2 <= a1) + return; + *a2 = *a1; + *a1++ = t; + } +} +getcopy() +{ + if (addr1 > addr2) + return(EOF); + getline(*addr1++, linebuf); + return(0); +} diff --git a/visual-studio-1994/pattern.c b/visual-studio-1994/pattern.c new file mode 100644 index 0000000..194b1f5 --- /dev/null +++ b/visual-studio-1994/pattern.c @@ -0,0 +1,470 @@ +/*% cc -c -O % + */ +#include "vars.h" +#define ESIZE 128 /* ESIZE-1 must fit in a signed byte */ +char expbuf[ESIZE+4]; +int expgood /*0*/; /* flag indicating if compiled exp is good */ +#define CCHR 2 +#define CDOT 4 +#define CCL 6 +#define NCCL 8 +#define CFUNNY 10 +#define CALT 12 +#define CBACK 14 + +#define STAR 01 +#define STARABLE CBACK + +#define CKET 16 +#define CDOL 17 +#define CEOF 18 +#define CBRA 19 +#define CBOI 20 +#define CEOI 21 +#define CSPACE 22 +int circfl; +char pmagic[] = "/.$^*+\\()<|>{}[!_123456789"; +void +compile(eof) +char eof; +{ + register c; + register char *ep, *penultep; + char *lastep, *bracketp, bracket[NBRA]; + int getsvc(); + int getchar(); + struct{ + char *althd; /* start of code for < ... > */ + char *altlast; /* start of code for last < or | */ + char *bpstart; /* bracketp at start of < and | */ + char *bpend; /* bracketp at end of > or | */ + int nbstart; /* nbra at start of < and | */ + int nbend; /* nbra at end of > or | */ + int firstalt; /* is this the first alternative? */ + } *asp, altstk[NBRA]; + + if(eof == '\n') + error('x'); + pmagic[0] = eof; + if ((c=nextchar()) == eof || c=='\n') { + if (!expgood) + goto cerror; + if(c!='\n') + getchar(); /* eat the eof character */ + return; + } + expgood = FALSE; + ep = expbuf; + lastep = 0; + bracketp = bracket; + nbra = 0; + asp = &altstk[-1]; + startstring(); /* for the saved pattern register */ + circfl = 0; + if (c=='^') { + getsvc(); /* save the caret */ + circfl++; + } + for (;;) { + c = getquote(pmagic, getsvc); + if (c==eof || c=='\n') { + if (bracketp!=bracket || asp>=altstk) + goto cerror; + *ep++ = CEOF; + expgood = TRUE; + dropstring(); /* lose the eof character */ + setstring(SAVPAT); + if(c=='\n') + ungetchar(c); + return; + } + if (ep >= &expbuf[ESIZE-5]) + goto cerror; + penultep = lastep; + lastep = ep; + + if(c != (eof|0200)) switch (c) { + case '('|0200: + if (nbra >= NBRA) + goto cerror; + *bracketp++ = nbra; + *ep++ = CBRA; + *ep++ = nbra++; + continue; + case ')'|0200: + if (bracketp <= bracket) + goto cerror; + *ep++ = CKET; + *ep++ = *--bracketp; + continue; + case '{'|0200: + *ep++ = CBOI; + continue; + case '}'|0200: + *ep++ = CEOI; + continue; + case '_'|0200: + *ep++ = CSPACE; + continue; + case '!'|0200: + *ep++ = CFUNNY; + continue; + case '<': + if (++asp >= &altstk[NBRA]) + goto cerror; + *ep++ = CALT; + asp->althd = ep; + ep++; + asp->bpstart = bracketp; + asp->nbstart = nbra; + asp->firstalt = TRUE; + asp->altlast = ep++; + lastep = 0; + continue; + case '|': + if (aspfirstalt) { + asp->bpend = bracketp; + asp->nbend = nbra; + } + if (bracketp!=asp->bpend || nbra!=asp->nbend) + goto cerror; + *ep++ = CEOF; + asp->altlast[0] = ep-asp->altlast; + asp->firstalt = FALSE; + bracketp = asp->bpstart; + nbra = asp->nbstart; + asp->altlast = ep++; + lastep = 0; + continue; + case '>': + if (aspfirstalt && + (bracketp!=asp->bpend || nbra!=asp->nbend)) + goto cerror; + *ep++ = CEOF; + asp->altlast[0] = ep-asp->altlast; + lastep = asp->althd; + *lastep = ep-lastep; + lastep--; + if (bracketp!=asp->bpstart || nbra!=asp->nbstart) + lastep = 0; + asp--; + continue; + case '*': + case '+': + if (penultep==0){ + *ep++ = CCHR; + *ep++ = c; + } else { + if(*penultep>STARABLE) + goto cerror; + if(c == '+'){ + if((ep-penultep)+ep >= &expbuf[ESIZE-1]) + goto cerror; + do + *ep++ = *penultep++; + while (penultep!=lastep); + } + *penultep |= STAR; + lastep = 0; + } + continue; + case '.': + *ep++ = CDOT; + continue; + + case '[': + penultep = ep; + *ep++ = CCL; + *ep++ = 0; + if ((c=getsvc()) == '^') { + c = getsvc(); + ep[-2] = NCCL; + } + do { + if (c == EOF || c == '\n') + goto cerror; + *ep++ = c; + if ((lastc=getsvc()) == '-') { + c=getsvc(); + if (c == EOF || c == '\n' || c<=ep[-1]) + goto cerror; + ep[-1] |= 0200; + *ep++ = c; + lastc = getsvc(); /* prime lastc */ + } else if (dflag&&'a'<=(c|' ')&&(c|' ')<='z') + *ep++ = c^' '; + if (ep >= &expbuf[ESIZE-1]) + goto cerror; + } while ((c=lastc) != ']'); + penultep[1] = ep-penultep-1; + continue; + + + case '$': + if (nextchar() == eof || peekc=='\n') { + *ep++ = CDOL; + continue; + } + /* fall through */ + default: + break; + } + /* if fell through switch, match literal character */ + /* Goddamned sign extension! */ + if ((c&0200) && (c&0177)>='1' && (c&0177)<='9') { + *ep++ = CBACK; + *ep++ = c-('1'|0200); + continue; + } + c &= ~0200; + if(dflag && c|' '>='a' && c|' '<='z'){ + *ep++ = CCL; + *ep++ = 3; + *ep++ = c; + *ep++ = c^' '; + } + else{ + *ep++ = CCHR; + *ep++ = c; + } + } + cerror: + error('p'); +} +getsvc(){ + register c; + addstring(c=getchar()); + return(c); +} +int +execute(addr) + int *addr; +{ + register char *p1, *p2; + + if (addr==0) { + if((p1=loc2) == 0) /* G command */ + p1 = linebuf; + else if (circfl) /* not first search in substitute */ + return(FALSE); + } else { + if (addr==zero) + return(FALSE); + p1 = getline(*addr, linebuf); + } + p2 = expbuf; + if (circfl) { + loc1 = p1; + return(advance(p1, p2)); + } + do { + if (*p2 != CCHR || p2[1] == *p1) { + if (advance(p1, p2)) { + loc1 = p1; + return(TRUE); + } + } + } while (*p1++); + return(FALSE); +} + +int +advance(lp, ep) + register char *lp, *ep; +{ + register char *curlp; + char *althd, *altend; + + for (;;) { + curlp = lp; + switch (*ep++) { + + case CCHR: + if (*ep++ == *lp++) + continue; + return(FALSE); + + case CCHR|STAR: + do ; while (*lp++ == *ep); + ep++; + break; + + case CDOT: + if (*lp++) + continue; + return(FALSE); + + case CDOT|STAR: + do ; while (*lp++); + break; + + case CCL: + case NCCL: + if (cclass(ep, *lp++, ep[-1]==CCL)) { + ep += *ep; + continue; + } + return(FALSE); + + case CCL|STAR: + case NCCL|STAR: + do ; while (cclass(ep, *lp++, ep[-1]==(CCL|STAR))); + ep += *ep; + break; + + case CFUNNY: + if (*lp>=' ' && *lp!='\177' || *lp=='\t' || *lp=='\0') + return(FALSE); + lp++; + continue; + + case CFUNNY|STAR: + while (*lp<' ' && *lp && *lp!='\t' || *lp=='\177') + lp++; + lp++; + break; + + case CBACK: + if (braelist[*ep]==0) + error('p'); + if (backref(*ep++, lp)) { + lp += braelist[ep[-1]] - braslist[ep[-1]]; + continue; + } + return(FALSE); + + case CBACK|STAR: + if (braelist[*ep] == 0) + error('p'); + curlp = lp; + while (backref(*ep, lp)) + lp += braelist[*ep] - braslist[*ep]; + while (lp >= curlp) { + if (advance(lp, ep+1)) + return(TRUE); + lp -= braelist[*ep] - braslist[*ep]; + } + ep++; + continue; + + case CBRA: + braslist[*ep++] = lp; + continue; + + case CKET: + braelist[*ep++] = lp; + continue; + + case CDOL: + if (*lp==0) + continue; + return(FALSE); + + case CEOF: + loc2 = lp; + return(TRUE); + + case CBOI: + if (alfmatch(*lp,0) + && (lp==linebuf || !alfmatch(lp[-1],1))) + continue; + return(FALSE); + + case CEOI: + if (!alfmatch(*lp,1) + && lp!=linebuf && alfmatch(lp[-1],1)) + continue; + return(FALSE); + + case CSPACE: + if (*lp==' ' || *lp=='\t') { + while (*lp == ' ' || *lp=='\t') + lp++; + continue; + } + return(FALSE); + + case CALT: + althd = ep-1; + altend = ep + *ep; + for(ep++; ; ep+= *ep) { + if(ep == altend) + return(FALSE); + if(advance(lp,ep+1) && advance(loc2,altend)) + return(TRUE); + } + + case CALT|STAR: + althd = ep-1; + altend = ep + *ep; + for(ep++; ep!=altend; ep+= *ep){ + if(advance(lp, ep+1)){ + if(loc2 == lp) + break; + if(advance(loc2, althd)) + return(TRUE); + } + } + /* return (advance(lp,altend)) */ + continue; + + default: + error('!'); + } + /* star logic: executed by falling out of switch */ + do { + lp--; + if (advance(lp, ep)) + return(TRUE); + } while (lp > curlp); + return(FALSE); + } +} + +backref(i, lp) +register i; +register char *lp; +{ + register char *bp; + + bp = braslist[i]; + while (*bp++ == *lp++) + if (bp >= braelist[i]) + return(TRUE); + return(FALSE); +} +int alfmatch(c,tail) +register char c; +{ + return (('a' <= c && c <= 'z') || + ('A' <= c && c <= 'Z') || + (c == '_') || + (tail && '0' <= c && c<= '9')); +} + + +cclass(set, c, f) + register char *set; + register c; +{ + register n; + if (c == 0) + return(0); + n = *set++; + while (--n) { + if (*set&0200) { + if ((*set++ & 0177) <= c) { + if (c <= *set++) + return(f); + } else + set++; + --n; + } else if (*set++ == c) + return(f); + } + return(!f); +} diff --git a/visual-studio-1994/pseudoheap.c b/visual-studio-1994/pseudoheap.c new file mode 100644 index 0000000..a2c2b9c --- /dev/null +++ b/visual-studio-1994/pseudoheap.c @@ -0,0 +1,45 @@ +/* + * simulate QED's evil sbrk tricks within malloc + * D. P. Mitchell 94/12/09. + */ +#include "vars.h" +#include +#define VSPACE 1000 + +static char *heap; +static char *breakValue; +static char *top; + +#define LDCHUNK 512 /* must be the same as in com.c! */ + +static +initHeap() +{ + + if (heap == 0) { + heap = (char *)malloc(LDCHUNK*sizeof(int *)*VSPACE); + top = heap + LDCHUNK*sizeof(int *)*VSPACE; + breakValue = heap; + } +} + +brk(char *endds) +{ + initHeap(); + if (endds >= heap && endds < top) + breakValue = endds; +} + +char * +sbrk(int incr) +{ + initHeap(); + breakValue += incr; + if (breakValue >= top) { + fprintf(stderr, "sbrk simulator failed!!\n"); + fprintf(stderr, "%d chunks allocated so far\n", + (breakValue-heap)/LDCHUNK/sizeof(int*)); + exit(1); + } + return breakValue; +} diff --git a/visual-studio-1994/putchar.c b/visual-studio-1994/putchar.c new file mode 100644 index 0000000..a2cd255 --- /dev/null +++ b/visual-studio-1994/putchar.c @@ -0,0 +1,154 @@ +/*% cc -c -O % + */ +#include "vars.h" +#ifdef PDP11 +typedef long ulong; +#else +typedef unsigned long ulong; +#endif +int col; +putdn(i) +{ + putlong((ulong)i); + putchar('\n'); +} +#ifdef PDP11 +/* + * In version 6, ldiv() is in the library. In version 7, it is separate: + .globl _ldiv, _ldivr + _ldiv: + mov 2(sp), r0 + mov 4(sp), r1 + div 6(sp), r0 + mov r1,_ldivr + rts pc + .bss + _ldivr: .=.+2 + */ +putlong(i) + long i; +{ + register char r; + extern int ldiv(), ldivr; + + /* the following pornography saves bundles of memory */ + i = ldiv(i,10); + r = ldivr + '0'; + if (i) + putlong(i); + putchar(r); +} +#endif +#ifndef PDP11 +putlong(i) + ulong i; +{ + register r; + r = i%10; + i /= 10; + if(i) + putlong(i); + putchar('0'+r); +} +#endif +putl(sp) + register char *sp; +{ + listf++; + puts(sp); + listf = FALSE; +} +puts(sp) + register char *sp; +{ + col = 0; + while (*sp) + putchar(*sp++); + putchar('\n'); +} +display(lf) +{ + register int *a1; + register int r; + register char *p; + register i; + int nf; + listf = (lf == 'l' || lf == 'L'); + nf = (lf == 'P' || lf == 'L'); + lf = listf; + setdot(); + nonzero(); + a1 = addr1; + r = (a1 - zero) & 077777; + do{ + col = 0; + if(nf){ + putlong((ulong)r++); + for(i=0; i= (72-4-2)) { + *lp++ = '\\'; + *lp++ = '\n'; + *lp++ = '\t'; + col = 8; + } + col++; + if (c=='\b' || c=='\\' || c=='\t') { + *lp++ = '\\'; + c = c=='\b'? 'b' : c=='\t'? 't' : '\\'; + col++; + } else if ((c&0200) || c<' ' || c=='\177') { + *lp++ = '\\'; + *lp++ = ((c>>6)&03)+'0'; + *lp++ = ((c>>3)&07)+'0'; + c = ( c &07)+'0'; + col += 3; + } + } + } + *lp++ = c; + if(c == '\n' || lp >= &line[(sizeof line)-2-4]) { + linp = lp; + flush(); + lp = linp; + } + linp = lp; +} +flush() +{ + if(linp != line){ + write(1, line, linp-line); + linp = line; + } +} diff --git a/visual-studio-1994/setaddr.c b/visual-studio-1994/setaddr.c new file mode 100644 index 0000000..3395665 --- /dev/null +++ b/visual-studio-1994/setaddr.c @@ -0,0 +1,32 @@ +/*% cc -c -O % + */ +#include "vars.h" +extern noaddr; +setdot() +{ + if (addr2 == 0) + addr1 = addr2 = dot; + if (addr1 > addr2) + error('$'); +} +setall() +{ + if (noaddr) { + addr1 = zero+1; + addr2 = dol; + if (dol==zero) + addr1 = zero; + } + setdot(); +} +setnoaddr() +{ + extern noaddr; + if (noaddr == FALSE) + error('$'); +} +nonzero() +{ + if (addr1<=zero || addr2>dol) + error('$'); +} diff --git a/visual-studio-1994/string.c b/visual-studio-1994/string.c new file mode 100644 index 0000000..0d0075e --- /dev/null +++ b/visual-studio-1994/string.c @@ -0,0 +1,105 @@ +/*% cc -c -O % + */ +#include "vars.h" +#define strfree string[NSTRING].str +char *strstart; + +length(s) + register char *s; +{ + register char *t; + if((t=s)==0) + return(0); + do;while(*t++); + return(t-s-1); +} +startstring(){ + strstart=strfree; +} +addstring(c){ + if(strfree==strchars+NSTRCHARS) + strcompact(); + *strfree++ = c; +} +dropstring(){ + --strfree; +} +cpstr(a, b) + register char *a, *b; +{ + do;while (*b++ = *a++); +} +shiftstring(up){ /* A highly machine-dependent routine */ + register struct string *sp; + for(sp=string; sp<=string+NSTRING; sp++) + if(up) + sp->str += (int)strarea; + else + sp->str -= (int)strarea; +} +clearstring(z){ + string[z].len = 0; + string[z].str = nullstr; +} +copystring(s) + register char *s; +{ + while(*s) + addstring(*s++); +} +eqstr(a, b) + register char *a, *b; +{ + while(*a) + if(*a++ != *b++) + return(FALSE); + return(*b=='\0'); +} +/* + * dupstring duplicates a string. + * Because we may strcompact(), we do it first if necessary. + */ +dupstring(z) +{ + if(strfree+string[z].len > strchars+NSTRCHARS) + strcompact(); /* if insufficient, will get error when we copystring() */ + copystring(string[z].str); +} +setstring(n){ + addstring('\0'); + if((string[n].len = length(strstart)) == 0) + string[n].str = nullstr; + else + string[n].str = strstart; + if(strfree >= strchars + NSTRCHARS) + strcompact(); +} +strcompact(){ + register struct string *cursor; + struct string *thisstr; + register char *s, *t; + lock++; + s=strchars; + for(;;){ + t=strchars+NSTRCHARS; + for(cursor=string;cursor!=string+NSTRING;cursor++) + if(s<=cursor->str && cursor->strstr; + thisstr = cursor; + } + if(t==strchars+NSTRCHARS) + break; + thisstr->str=s; + do;while(*s++ = *t++); + } + t=strstart; + strstart=s; + while(t!=strfree) + *s++ = *t++; + strfree=s; + if(s==strchars+NSTRCHARS){ + strfree=strstart; + error('Z'); + } + unlock(); +} diff --git a/visual-studio-1994/subs.c b/visual-studio-1994/subs.c new file mode 100644 index 0000000..2f88768 --- /dev/null +++ b/visual-studio-1994/subs.c @@ -0,0 +1,418 @@ +/*% cc -c -O % + */ +#include "vars.h" +char *next_new; +char *next_old; +int new_line; +int old_line; +char rhsbuf[RHSIZE]; + +substitute(inglob, reg) +{ + register int n, m; + register char *p; + char *q; + int *a1; + int gsubf; + extern int getsub(); + int t, count, autop=0; + + count=0; + t = FALSE; + n=getnum(); + gsubf = compsub(TRUE, &autop); + if(reg!= -1){ /* Substitution in a register */ + cpstr(string[reg].str, linebuf); + loc2=0; /* signal execute to take line from linebuf */ + a1=0; + goto Do_it; + } + for (a1 = addr1; a1 <= addr2 && reg==-1; a1++) { + Do_it: + if (execute(a1)) { + next_old=linebuf; + next_new=genbuf; + m=n; + do { + if (--m <= 0) { + dosub(); + t = TRUE; + count++; + if (!gsubf) + break; + } + /* can't find something at EOL twice */ + if (*loc2=='\0') + break; + /* can't match same location twice */ + if (loc1==loc2) + loc2++; + } while (execute((int *)0)); + if (m<=0) { + inglob |= TRUE; + p=next_old; + do ; while (*p++); + place(next_old,p,0); + if(reg==-1){ + p=linebuf; + q=genbuf; + do ; while (*p++ = *q++); + replace(a1,putline()); + m=append(getsub,a1); + a1 += m; + addr2 += m; + }else{ + startstring(); + copystring(genbuf); + setstring(reg); + } + } + } + } + if (!inglob) + error('s'); + settruth(t); + setcount(count); + if(autop) + if(reg>=0) + puts(string[reg].str); + else{ + addr1=addr2=dot; + display('p'); + } +} + +compsub(subbing, autop) + int subbing; + int *autop; +{ + register int seof, c; + char *rhsmagic; + register char *p; + int getsvc(); + + *autop=FALSE; + seof = getchar(); + if(subbing) { + compile(seof); + rhsmagic = "/&^\n\\123456789"; + } + else + rhsmagic = "/\\\n"; + rhsmagic[0] = seof; + p = rhsbuf; + startstring(); + for (;;) { + c = getquote(rhsmagic, getsvc); + if (c=='\n' || c==EOF){ + *autop=TRUE; + ungetchar('\n'); + break; + } + if (c==seof) + break; + *p++ = c; + if (p >= &rhsbuf[RHSIZE]) + error('l'); + } + *p = 0; + dropstring(); + setstring(SAVRHS); + if (subbing && nextchar() == 'g') { + getchar(); /* clear 'g' */ + return(1); + } + return(0); +} +int getsub() +{ + register char *p1, *p2; + + p1 = linebuf; + if ((p2 = linebp) == 0) + return(EOF); + do ; while (*p1++ = (*p2++ & 0177)); + linebp = 0; + return(0); +} + +dosub() +{ + register int c; + register char *p; + + place(next_old,loc1,0); + next_old=loc2; + p=rhsbuf; + while (c = *p++) { + if (c=='&' || (c == '^' && uflag)) + place(loc1,loc2,c=='^'); + else if ((c&0200) && (c &= 0177)>='1' && c<'1'+nbra) + place(braslist[c-'1'],braelist[c-'1'], 0); + else { + *next_new++ = c; + if (next_new >= genbuf+LBSIZE) + error('l'); + } + } +} + +place(l1, l2, ucase) + register char *l1; + char *l2; +{ + register char *sp; + register c; + + sp = next_new; + while (l1 < l2) { + *sp++ = (*l1++ & 0177); + if (sp >= &genbuf[LBSIZE]) + error('l'); + } + if(ucase){ + for(l1 = next_new;l1 < sp;){ + c = (*l1 & 0177); + if((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')){ + switch(uflag){ + case 's': + *l1++ ^= 040; + break; + case 'u': + *l1++ &= ~040; + break; + case 'l': + *l1++ |= 040; + break; + default: + l1++; + } + }else{ + l1++; + } + } + } + next_new = sp; +} + +undo() +{ + register int *l; + + for (l=zero+1; l<=dol && (*l|01)!=new_line; l++) + ; + if (l>dol) + error('u'); + replace(l,old_line); + dot=l; +} +replace(line,ptr) + register int *line; + register int ptr; +{ + register int *p; + + *line |= 01; + for (p=names; p= genbuf + sizeof genbuf) + error('l'); + } + if(l > addr2) + break; + if(rep) { + q = string[SAVRHS].str; + while (*q) { + *p++ = *q++; + if (p >= genbuf + sizeof genbuf) + error('l'); + } + } + } + *p = '\0'; + linebp=p=linebuf; + q=genbuf; + do ; while (*p++ = *q++); + getsub(); + *(l=addr1++)=putline(); + /* if you want marks preserved for join, change the above line to + /* the one commented out here. + /* problem: undo then undoes the join, but gets it wrong. Your choice. + replace(l=addr1++, putline()); + */ + if(l != addr2) + delete(); + append(getsub, l); + if(autop){ + addr1=addr2=dot; + display('p'); + } +} + +int next_col(col,cp,input) + register int col; + register char *cp; + int input; +{ + register c; + + c = *cp; + if (c=='\t') + col |= 07; + else if (c<' ' || c=='\177') + error('t'); /* invalid character in x data */ + else + /* DPM 90/12/22 - assume erase = BS|DEL, kill == ^U + * (input && (c==ttybuf.sg_erase || c==ttybuf.sg_kill)) + */ + if (input && (c == 010 || c == 0177 || c == 025)) + col++; /* One column for the backslash */ + return (++col); +} + +xform() +{ + register char *i, *m, *o; + int *line, insert, change, ic, mc, c; + char *tf, *tl; + + if(getchar() != '\n') + error('x'); + for (line=addr1; line<=addr2; line++) { + getline(*line, linebuf); + change=FALSE; + dot=line; + for(;;){ + puts(linebuf); + pushinp(XTTY, 0, FALSE); + m=rhsbuf; + while ((c = getchar())!='\n') { + if (c == EOF) + error('t'); /* unexpected EOF */ + *m++ = c; + if (m==rhsbuf+RHSIZE-1) + error('l'); /* out of space */ + } + *m='\0'; + if (m==rhsbuf) + break; + change++; + i=linebuf; + o=genbuf; + do ; while (*o++ = *i++); + if (i+(m-rhsbuf) > linebuf+LBSIZE) + error('l'); /* out of space */ + i=genbuf; + o=linebuf; + m=rhsbuf; + insert=FALSE; + ic=0; + mc=0; + while (*i && *m && !insert) { + if(*i=='\t' && *m!='#' && *m!='^' && *m!='$') { + ic=next_col(ic,i,FALSE); + tf=m; + tl=m; + do { + if (*m!=' ' && *m!='\t') { + if(*m=='%') + *m=' '; + tl=m+1; + } + mc=next_col(mc,m++,TRUE); + } while (ic>mc && *m && *m!='#' && + *m!='^' && *m!='$'); + if (ic>mc) { + ic=mc; + if (*m) + tl=m; + } else { + if (tl==m) + i++; + else + ic--; + } + while (tf!=tl) + *o++ = *tf++; + } else { + mc=next_col(mc,m,TRUE); + *o = *m; + switch (*m++) { + case ' ': + case '\t': + break; + case '^': + mc=ic; + insert++; + break; + case '$': + i=""; + break; + case '#': + ic=next_col(ic,i++,FALSE); + while(*m=='#' && ic>mc) + mc=next_col(mc,m++,TRUE); + if (ic!=mc) + error('t'); + break; + case '%': + *o = ' '; + /* fall through */ + default: + o++; + ic=next_col(ic,i++,FALSE); + } /* switch */ + } /* else */ + for (;;) { + if (ic>mc && *m) { + if (*m!=' ' && *m!='\t') + error('t'); + mc=next_col(mc,m++,TRUE); + } else if (mc>ic && *i) { + ic=next_col(ic,i,FALSE); + *o++ = *i++; + } else + break; + } + } /* while */ + if (mc>ic && m[-1]=='\t') + *o++ = '\t'; + if (insert && (*o++ = *m++) == '\0') { + replace(line,putline()); + linebp=i; + append(getsub,line); + line++; + addr2++; + change = FALSE; + } else { + while (*m) + *o++ = *m++; + do ; while (*o++ = *i++); + } + } + if (change) + replace(line,putline()); + } /* for */ +} diff --git a/visual-studio-1994/vars.c b/visual-studio-1994/vars.c new file mode 100644 index 0000000..8537327 --- /dev/null +++ b/visual-studio-1994/vars.c @@ -0,0 +1,103 @@ +/* + * The actual definitions of variables + */ +#include "vars.h" +#ifdef VAX +#endif +/* Fake setexit & reset from v6 using setjmp and longjmp */ +#include +jmp_buf env; +/* + * Stack types. Must appear in the order as in cspec[]/getchar. + * XTTY, GLOB and BRWS are special types with no corresponding special character. + * Special is never used directly - it is just used in tracing + * pushinp()/getchar.c can be called with a negative index for cspec[] + */ +extern char special[]; /* "xgBbBcfFlprzN\"\\'" */ +/* + * Getchar-linked macros + */ +/* + * The buffer structure. All info associated with each buffer stored here + */ +struct buffer buffer[NBUFS]; +/* + * The string structure + * The first NBUFS strings are the registers + * The next NBUFS are the file names + * The next two are the saved pattern and saved right hand side + * The next is the special register for browsing (the `ob' command) + * The next is a file buffer. + * Strings are stored in the `strarea' area and garbage collected + * when the area is full. The NSTRCHARS parameter can be increased + * if you've got lots of core. + * The first two characters of `strarea' form the null string. + * The third and subsequent characters are the storage for non null + * strings. + * The null string has to be stored in this area so that + * the R and S commands write out valid pointers to the null string. + * The last entry in the string structure is used to store the pointer + * to the next free position. + * In string.c strfree is defined as "string[NSTRING].str". + */ +struct string string[NSTRING+1]; +char strarea[NSTRCHARS + 2]; +/* + * The getchar stack. + */ +struct stack stack[STACKSIZE]; +struct stack *stackp; +int peekc; +int lastc; +char line[70]; +int savedfile; +char linebuf[LBSIZE]; +int *zero; +int *dot; +int *dol; +int *lastdol; +int *endcore; +int *fendcore; +int *addr1; +int *addr2; +char genbuf[LBSIZE]; +char *linebp; +/* DPM 90/12/22 - get rid of dialect-dependant tty stuff + * #include + * struct sgttyb ttybuf; + */ +int ninbuf; +int io; +int onhup; +int onquit; +int onintr; +char lasterr; +extern pagesize; +extern char bformat; /* = 'p' */ +int cflag; +int cprflag; +int eflag; +int biggflag; +int iflag; +int qok; +int eok; +int nestlevel; +int listf; +int tfile2; +char *tfname; +char *loc1; +char *loc2; +int names[NBUFS]; +char *braslist[NBRA]; +char *braelist[NBRA]; +int nbra; +int oneline; +int lock; +extern char bname[]; /* ="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~" */ +extern char lchars[]; /* = "pPlL" */ +int bbempty; /* whether getc's internal buffer buffer needs reloading */ +char *getline(); +int *address(); +char *getenv(); +long lseek(); +char *sbrk(); diff --git a/visual-studio-1994/vars.h b/visual-studio-1994/vars.h new file mode 100644 index 0000000..6664a9b --- /dev/null +++ b/visual-studio-1994/vars.h @@ -0,0 +1,187 @@ +/* + * QED + */ +#define VAX VAX +#ifdef VAX +#define BIGTMP LOTSOFBITS +#endif +/* Fake setexit & reset from v6 using setjmp and longjmp */ +#include +extern jmp_buf env; +#define setexit() setjmp(env) +#define reset() longjmp(env, 0) +#define TRUE 1 +#define FALSE 0 +#define LBSIZE 512 +#define RHSIZE (LBSIZE/4) /* ed says /2; but that's unreasonable! */ +#define NBRA 9 +#define EOF (-1) +#define FILERR 0200 +#define SAVENEVER 0 +#define SAVEIFFIRST 1 +#define SAVEALWAYS 2 +/* + * Stack types. Must appear in the order as in cspec[]/getchar. + * XTTY, GLOB and BRWS are special types with no corresponding special character. + * Special is never used directly - it is just used in tracing + * pushinp()/getchar.c can be called with a negative index for cspec[] + */ +extern char special[]; /* "xgBbBcfFlprzN\"\\'" */ +#define cspec (special + 3) +#define XTTY 0175 +#define GLOB 0176 +#define BRWS 0177 +#define BUF 0 +#define CURBN 1 +#define QUOTE 2 +#define FILEN 3 +#define BFILEN 4 +#define TTY 5 +#define PAT 6 +#define RHS 7 +#define STRING 8 +#define NEWL 9 +#define NOTHING 10 +#define BACKSLASH 11 +#define LITERAL 12 +/* + * Getchar-linked macros + */ +#define ungetchar(c) (peekc = (c)) +#define nextchar() (peekc = getchar()) +#define NBUFS 56 +/* + * The buffer structure. All info associated with each buffer stored here + */ +extern struct buffer{ + int *zero; + int *dot; + int *dol; + char cflag; + char gmark; +}buffer[NBUFS]; +extern struct buffer *curbuf; +/* + * The string structure + * The first NBUFS strings are the registers + * The next NBUFS are the file names + * The next two are the saved pattern and saved right hand side + * The next is the special register for browsing (the `ob' command) + * The next is a file buffer. + * Strings are stored in the `strarea' area and garbage collected + * when the area is full. The NSTRCHARS parameter can be increased + * if you've got lots of core. + * The first two characters of `strarea' form the null string. + * The third and subsequent characters are the storage for non null + * strings. + * The null string has to be stored in this area so that + * the R and S commands write out valid pointers to the null string. + * The last entry in the string structure is used to store the pointer + * to the next free position. + * In string.c strfree is defined as "string[NSTRING].str". + */ +#define NSTRING (NBUFS+NBUFS+4) +#define COUNT (26+'C'-'A') +#define TRUTH (26+'T'-'A') +#define UNIX (26+'U'-'A') +#define FILE(z) (NBUFS+(z)) +#define SAVPAT (NBUFS+NBUFS) +#define SAVRHS (SAVPAT+1) +#define BROWSE (SAVRHS+1) +#define FILEBUF (BROWSE+1) +extern struct string{ + int len; + char *str; +}string[NSTRING+1]; +#define NSTRCHARS 1024 +extern char strarea[NSTRCHARS + 2]; +#define nullstr strarea +#define strchars (&strarea[2]) +#define STACKSIZE 16 +/* + * The getchar stack. + */ +extern struct stack{ + char type; + char literal; + union{ + struct buffer *u1bufptr; + char *u1globp; + }u1; + union{ + int u2lineno; + int u2strname; + }u2; + int charno; +}stack[STACKSIZE]; +#define bufptr u1.u1bufptr +#define globp u1.u1globp +#define lineno u2.u2lineno +#define strname u2.u2strname +extern struct stack *stackp; +extern int peekc; +extern int lastc; +extern char line[70]; +extern char *linp; +extern int savedfile; +extern char linebuf[LBSIZE]; +extern int *zero; +extern int *dot; +extern int *dol; +extern int *lastdol; +extern int *endcore; +extern int *fendcore; +extern int *addr1; +extern int *addr2; +extern char genbuf[LBSIZE]; +extern char *linebp; +/* DPM 90/12/22 - get rid of dialect-dependant tty stuff + * #include + * struct sgttyb ttybuf; + */ +extern int ninbuf; +extern int io; +extern int onhup; +extern int onquit; +extern int onintr; +extern char lasterr; +#define PAGESIZE 22 +extern pagesize; +extern char bformat; /* = 'p' */ +extern int appflag; +extern int cflag; +extern int cprflag; +extern int dflag; +extern int eflag; +extern int gflag; +extern int biggflag; +extern int iflag; +extern int prflag; +extern int tflag; +extern int uflag; +extern int vflag; +extern int qok; +extern int eok; +extern int initflag; +extern int nestlevel; +extern int lastttyc; +extern int listf; +extern int tfile; +extern int tfile2; +extern char *tfname; +extern char *loc1; +extern char *loc2; +extern int names[NBUFS]; +extern char *braslist[NBRA]; +extern char *braelist[NBRA]; +extern int nbra; +extern int oneline; +extern int lock; +extern char bname[]; /* ="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~" */ +extern char lchars[]; /* = "pPlL" */ +extern int bbempty; /* whether getc's internal buffer buffer needs reloading */ +extern char *getline(); +extern int *address(); +extern char *getenv(); +extern long lseek(); +extern char *sbrk();