AUSAM/source/S/em2.c
#include "em.h"
donothing()
{
char t1, t2;
t1 = rhsbuf[0];
t2 = rhsbuf[1];
rhsbuf[0] = '&';
rhsbuf[1] = 0;
dosub();
rhsbuf[0] = t1;
rhsbuf[1] = t2;
}
confirmed()
{
#ifdef BETTER_SWAP
register char *ptr;
#endif BETTER_SWAP
int ch;
int oldglobp;
if (xflag)
{
#ifndef BETTER_SWAP
putnls(linebuf);
#else
col = 0;
for (ptr = genbuf; ptr < ssp; putchar(*ptr++));
for (ptr = slp; *ptr; putchar(*ptr++));
putchar('\n');
#endif BETTER_SWAP
underline();
oldglobp = globp;
globp = 0;
ch = getchar();
if (ch != '\n')
{
while (getchar() != '\n');
if (ch != CONFIRM) putnls("? '.' to confirm");
}
globp = oldglobp;
return(ch == CONFIRM);
}
return(1);
}
underline()
{
int i1, i2;
register int i, j;
i1 = calccol(loc1);
i2 = calccol(loc2);
if (!listf && i1>i2) { i = i1; i1 = i2; i2 = i; }
j = i1 & ~7;
for (i = 0; i < j; i =+ 8) write(1, "\t", 1);
for (; i < i1; i++) write(1, " ", 1);
while (i != i2)
{
if (++i >= (LENGTH - 1) && listf) { write(1, "\r", 1); i = 1; }
write(1, "^", 1);
}
}
screensplit()
{
register a;
a = LENGTH - 2; /* as our VDUs do funny things in the last column position! */
col = 0;
while (a--) putchar('-');
putchar('\n');
}
/*
* Find actual column number
*/
calccol(ll)
char *ll;
{
register int i;
register char *p;
i = 0;
#ifndef BETTER_SWAP
for (p = linebuf; *p!='\0' && p<ll; p++)
{
if (*p=='\t' && !listf) i = (i+8) & ~7;
else if (*p=='\b' && !listf) i--; else i++;
}
#else
for (p = genbuf; p < ssp; p++)
{
if (*p=='\t' && !listf) i = (i+8) & ~7;
else if (*p=='\b' && !listf) i--; else i++;
}
for (p = slp; *p!='\0' && p<ll; p++)
{
if (*p=='\t' && !listf) i = (i+8) & ~7;
else if (*p=='\b' && !listf) i--; else i++;
}
#endif BETTER_SWAP
if (listf) i =% (LENGTH - 2);
return(i);
}
compsub()
{
#ifndef MISC
register seof, c;
#else
register c;
register char *rp;
int seof;
#endif
register char *p;
int gsubf;
gsubf = 0;
if ((seof = getchar()) == '\n') error(20);
compile(seof);
#ifndef MISC
p = rhsbuf;
#else
rp = rhsbuf;
p = linebuf;
#endif
for (;;)
{
c = getchar();
#ifdef MISC
if (c == '%')
{
if (*rp == 0) error(32);
while (*p++ = *rp++) if (p >= &linebuf[LBSIZE/2]) error(27);
rp = rhsbuf;
p--;
continue;
}
if (c==BACKSL)
{
if ((c = getchar()) >= '1' && c < NBRA + '1' && c >= nbra + '1') error(32);
c =| 0200;
}
if (c=='\n' && (globp == 0 || *globp == 0)) error(20);
#else
if (c==BACKSL) c = getchar() | 0200;
if (c=='\n' && globp == 0) error(20);
#endif
if (c==seof) break;
*p++ = c;
#ifndef MISC
if (p >= &rhsbuf[LBSIZE/2]) error(27);
#else
if (p >= &linebuf[LBSIZE/2]) error(27);
#endif
}
*p++ = 0;
#ifdef MISC
for (p = linebuf; *rp++ = *p++; );
#endif
if (((peekc = getchar()) | 040) == 'g') { peekc = 0; gsubf =| 1; }
if (((peekc = getchar()) | 040) == 'n') { peekc = 0; gsubf =| 2; }
newline();
return(gsubf);
}
getsub()
{
register char *p1, *p2;
p1 = linebuf;
if ((p2 = linebp) == 0) return(EOF);
while (*p1++ = *p2++);
linebp = 0;
return(0);
}
dosub()
{
register char *lp, *sp, *rp;
int c;
#ifndef BETTER_SWAP
lp = linebuf;
sp = genbuf;
#else
lp = slp;
sp = ssp;
#endif BETTER_SWAP
rp = rhsbuf;
while (lp < loc1) *sp++ = *lp++;
while (c = *rp++)
{
if (c=='&') { sp = place(sp, loc1, loc2); continue; }
if (c<0 && (c =& 0177) >='1' && c < NBRA+'1')
{
sp = place(sp, braslist[c-'1'], braelist[c-'1']);
continue;
}
*sp++ = c;
if (sp >= &genbuf[LBSIZE]) error(27);
}
#ifndef BETTER_SWAP
lp = loc2;
loc2 = sp + linebuf - genbuf;
while (*sp++ = *lp++) if (sp >= &genbuf[LBSIZE]) error(27);
lp = linebuf;
sp = genbuf;
while (*lp++ = *sp++);
#else
slp = loc2;
ssp = sp;
#endif BETTER_SWAP
}
place(asp, al1, al2)
{
register char *sp, *l1, *l2;
sp = asp;
l1 = al1;
l2 = al2;
if (sp > &genbuf[LBSIZE - (l2 - l1)]) error(27);
while (l1 < l2) *sp++ = *l1++;
return(sp);
}
move(cflag)
{
register int *adt, *ad1, *ad2;
int getcopy();
setdot();
nonzero();
if ((adt = address())==0) error(23);
newline();
ad1 = addr1;
ad2 = addr2;
if (cflag) { ad1 = dol; append(getcopy, ad1++); ad2 = dol; }
ad2++;
if (adt<ad1)
{
dot = adt + (ad2-ad1);
if ((++adt)==ad1) return;
reverse(adt, ad1);
reverse(ad1, ad2);
reverse(adt, ad2);
}
else if (adt >= ad2)
{
dot = adt++;
reverse(ad1, ad2);
reverse(ad2, adt);
reverse(ad1, adt);
}
else error(23);
}
reverse(aa1, aa2)
{
register int *a1, *a2, t;
a1 = aa1;
a2 = aa2;
for (;;)
{
t = *--a2;
if (a2 <= a1) return;
*a2 = *a1;
*a1++ = t;
}
}
getcopy()
{
if (addr1 > addr2) return(EOF);
getline(*addr1++);
return(0);
}
compile(aeof)
{
register eof, c;
register char *ep;
char *lastep;
char bracket[NBRA], *bracketp;
#ifndef MISC
int nbra;
#endif
int cclcnt;
#ifdef AUTOW
char tempbuf[ESIZE];
int savcirc;
char *ep1;
#endif AUTOW
#ifdef PRINT_STRING
char fstch;
#endif PRINT_STRING
ep = expbuf;
eof = aeof;
bracketp = bracket;
if ((c = getchar()) == eof) { if (*ep==0) error(20); return; }
nbra = 0;
lastep = 0;
#ifdef AUTOW
ep1 = tempbuf;
if (*ep) while (*ep != CEOF) *ep1++ = *ep++;
*ep1++ = CEOF;
ep = expbuf;
savcirc = circfl;
#endif AUTOW
circfl = 0;
if (c=='^') { c = getchar(); circfl++; }
#ifdef SEARCH_STRING
if (c=='\n' && *ep) error(20);
#endif SEARCH_STRING
peekc = c;
for (;;)
{
if (ep >= &expbuf[ESIZE]) goto cerror;
c = getchar();
if (c==eof) { *ep++ = CEOF; return; }
if (c!='*') lastep = ep;
switch (c)
{
case BACKSL:if ((c = getchar())=='(')
{
if (nbra >= NBRA) goto cerror;
#ifndef AUTOW
*bracketp++ = nbra;
#endif AUTOW
*ep++ = CBRA;
#ifdef AUTOW
*bracketp++ = nbra;
#endif AUTOW
*ep++ = nbra++;
continue;
}
if (c == ')')
{
#ifndef AUTOW
if (bracketp <= bracket) goto cerror;
#endif AUTOW
*ep++ = CKET;
#ifdef AUTOW
if (bracketp <= bracket) goto cerror;
#endif AUTOW
*ep++ = *--bracketp;
continue;
}
*ep++ = CCHR;
if (c=='\n') goto cerror;
*ep++ = c;
continue;
case '.': *ep++ = CDOT;
continue;
case '\n': goto cerror;
case '*': if (lastep == 0)
{
lastep = ep;
goto defchar;
}
if (*lastep==CBRA || *lastep==CKET)
#ifndef AUTOW
error(20);
#else
goto cerror;
#endif AUTOW
*lastep =| STAR;
continue;
case '$': if ((peekc=getchar()) != eof) goto defchar;
*ep++ = CDOL;
continue;
case '[': *ep++ = CCL;
*ep++ = 0;
cclcnt = 1;
if ((c=getchar()) == '^')
{
c = getchar();
ep[-2] = NCCL;
}
do
{
if (c=='\n') goto cerror;
#ifdef PRINT_STRING
if (c == '-' && cclcnt > 1)
{
if ((c = getchar()) == '\n' || c <= ep[-1] ||
ep >= &expbuf[ESIZE-2]) goto cerror;
*ep++ = 0; *ep++ = c; cclcnt =+ 2;
continue;
}
else if (c == BACKSL && (c = getchar()) == '\n') goto cerror;
#endif PRINT_STRING
*ep++ = c;
cclcnt++;
if (ep >= &expbuf[ESIZE]) goto cerror;
} while ((c = getchar()) != ']');
lastep[1] = cclcnt;
continue;
#ifdef MISC
case '%': if (*(ep1 = rhsbuf) == 0) { *expbuf = 0; error(32); }
while (*ep1)
{
*ep++ = CCHR;
*ep++ = *ep1++ & 0177;
if (ep >= &expbuf[ESIZE]) goto cerror;
}
continue;
#endif
case '&': if (*tempbuf == CEOF) { *expbuf = 0; error(32); }
if (savcirc)
if (ep == expbuf) circfl++;
else { lastep = ep; *ep++ = CCHR; *ep++ = '^'; }
ep1 = tempbuf;
while ((*ep = *ep1++) != CEOF)
{
if (ep >= &expbuf[ESIZE]) goto cerror;
switch (*ep)
{
case CBRA: ep1++;
if (nbra >= NBRA) goto cerror;
*bracketp++ = nbra;
*++ep = nbra++;
break;
case CKET: ep1++;
if (bracketp <= bracket) goto cerror;
*++ep = *--bracketp;
break;
case CCL:
case NCCL:
case CCL|STAR:
case NCCL|STAR:
*++ep = *ep1++;
break;
case CDOT:
case CDOT|STAR:
case CCHR:
case CCHR|STAR:
lastep = ep++;
continue;
default: ep++;
continue;
}
ep++;
lastep = ep-2;
}
if (ep[-1] == CDOL)
if ((peekc = getchar()) != eof)
{
ep[-1] = CCHR;
*ep++ = '$';
}
continue;
defchar:
default: *ep++ = CCHR;
*ep++ = c;
}
}
cerror: expbuf[0] = 0;
error(20);
}
#ifdef PRINT_STRING
printstring()
{
register char *ep, flag;
register int count;
static char empty[] "empty";
listf++;
write(1, "& = ", col = 4);
if (*expbuf)
{
putchar('/');
if (circfl) putchar('^');
for (ep = expbuf; *ep != CEOF; )
switch(*ep++)
{
case CCHR: putchar(*ep++); continue;
case CCHR|STAR:
putchar(*ep++); putchar('*'); continue;
case CBRA: ep++; putchar(BACKSL); putchar('('); continue;
case CKET: ep++; putchar(BACKSL); putchar(')'); continue;
case CDOT: putchar('.'); continue;
case CDOT|STAR:
putchar('.'); putchar('*'); continue;
case CDOL: putchar('$'); continue;
case NCCL|STAR:
case CCL|STAR:
case NCCL:
case CCL: flag = *(ep-1); count = *ep++; putchar('[');
if ((flag & ~STAR) == NCCL) putchar('^');
while (--count)
if (*ep=='\0') { ep++; putchar('-'); }
else putchar(*ep++);
putchar(']');
if (flag & STAR) putchar('*');
}
putnls("/");
}
else putnls(empty);
write(1, "% = ", col = 4);
if (*rhsbuf)
{
putchar('/');
for (ep = rhsbuf; *ep; )
{
if ((flag = *ep++) < 0)
{
putchar('\\');
flag =& 0177;
}
putchar(flag);
}
putnls("/");
}
else putnls(empty);
write(1, "! = ", col = 4);
if (*unixbuffer)
{
putchar('/');
for (ep = unixbuffer; *ep; putchar(*ep++));
putnls("/");
}
else putnls(empty);
listf = 0;
}
#endif PRINT_STRING
execute(gf, addr)
int *addr;
{
register char *p1, *p2, c;
if (gf)
{
if (circfl) return(0);
#ifndef BETTER_SWAP
p1 = linebuf;
p2 = genbuf;
while (*p1++ = *p2++);
#endif BETTER_SWAP
locs = p1 = loc2;
}
else
{
if (addr==zero) return(0);
p1 = getline(*addr);
locs = 0;
}
p2 = expbuf;
if (circfl) { loc1 = p1; return(advance(p1, p2)); }
if (*p2==CCHR) /* fast check for first character */
{
c = p2[1];
do
{
if (*p1!=c) continue;
if (advance(p1, p2)) { loc1 = p1; return(1); }
} while (*p1++);
return(0);
}
do /* regular algorithm */
if (advance(p1, p2)) { loc1 = p1; return(1); }
while (*p1++);
return(0);
}
advance(alp, aep)
{
register char *lp, *ep, *curlp;
char *nextep;
lp = alp;
ep = aep;
for (;;)
switch (*ep++)
{
case CCHR: if (*ep++ == *lp++) continue; return(0);
case CDOT: if (*lp++) continue; return(0);
case CDOL: if (*lp==0) continue; return(0);
case CEOF: loc2 = lp; return(1);
case CCL: if (cclass(ep, *lp++, 1)) { ep =+ *ep; continue; } return(0);
case NCCL: if (cclass(ep, *lp++, 0)) { ep =+ *ep; continue; } return(0);
case CBRA: braslist[*ep++] = lp; continue;
case CKET: braelist[*ep++] = lp; continue;
case CDOT|STAR:
curlp = lp;
while (*lp++);
goto star;
case CCHR|STAR:
curlp = lp;
while (*lp++ == *ep);
ep++;
goto star;
case CCL|STAR:
case NCCL|STAR:
curlp = lp;
while (cclass(ep, *lp++, ep[-1]==(CCL|STAR)));
ep =+ *ep;
star: do
{
lp--;
if (lp==locs) break;
if (advance(lp, ep)) return(1);
} while (lp > curlp);
return(0);
default: error(20);
}
}
cclass(aset, ac, af)
{
register char *set, c;
register n;
set = aset;
if ((c = ac) == 0) return(0);
n = *set++;
#ifndef PRINT_STRING
while (--n) if (*set++ == c) return(af);
#else
while (--n)
if (*set == '\0')
{
if (c > set[-1] && c <= set[1]) return(af);
set++; set++; n--;
}
else if (*set++ == c) return(af);
#endif PRINT_STRING
return(!af);
}
putd()
{
register r;
r = count % 10;
if (count =/ 10) putd();
putchar(r + '0');
}
puts(as)
{
register char *sp;
sp = as;
while (*sp) putchar(*sp++);
}
putnls(as)
{
col = 0;
puts(as);
putchar('\n');
}
char line[70];
char *linp line;
putchar(ac)
{
register char *lp;
register c;
lp = linp;
c = ac;
if (listf)
{
col++;
if (col >= LENGTH - 1) { col = 1; *lp++ = BACKSL; *lp++ = '\n'; }
if (c=='\t') { c = '>'; goto esc; }
if (c=='\b')
{
c = '<';
esc: *lp++ = '-';
*lp++ = '\b';
*lp++ = c;
goto out;
}
if (c<' ' && c!= '\n')
{
*lp++ = BACKSL;
*lp++ = (c>>3)+'0';
*lp++ = (c&07)+'0';
col =+ 2;
goto out;
}
}
*lp++ = c;
out: if(c == '\n' || lp >= &line[64])
{
linp = line;
write(1, line, lp-line);
return;
}
linp = lp;
}
#ifdef GETPID
/*
* Get process ID routine if system call is unavailable.
*/
getpid()
{
register f;
int b[1];
if((f = open("/dev/kmem", 0)) < 0) return(-1);
seek(f, 0140074, 0); /* u_procp */
read(f, b, 2);
seek(f, b[0]+8, 0); /* p_pid */
read(f, b, 2);
close(f);
return(b[0]);
}
#endif
op(inglob)
{
register int *a1;
register char *lp, *sp;
char seof, ch;
int t, nl;
int getopen();
int getnil();
threshold = genbuf + margin;
savethresh = 0;
ch = peekc = getchar();
switch (ch)
{
case BACKSL:t = 1;
delete();
addr2 = addr1;
break;
case ';':
case '+': t = 0;
break;
case '-': t =1;
break;
default: goto normal;
}
peekc = 0;
if (addr1 != addr2) error(23);
oflag = 0;
append(getnil, addr2-t);
addr1 = addr2 =- (t-1);
setdot();
nonzero();
normal: if (addr1 == zero) error(23);
seof = getchar();
if (seof == '\n') { loc2 = linebuf-1; seof = '\0'; }
else compile(seof);
setraw(); /* terminal into raw mode*/
for (a1 = addr1; a1 <= addr2; a1++)
{
if (seof != '\0')
{
if (execute(0, a1) == 0) continue;
}
else getline(*a1);
putnls("\\\r");
sp = genbuf;
inglob =| 01;
for (lp = linebuf; lp < loc2;)
{
putch(*lp);
*sp++ = *lp++;
}
lnp = lp;
gnp = sp;
#ifdef NICE_EXIT
oldline = *a1; thestart = a1; nline = 0;
#endif NICE_EXIT
oflag = gopen(); /* open the current line */
retag(*a1 = putline(linebuf), *a1); /* write revised line */
nl = append(getopen, a1);
a1 =+ nl;
addr2 =+ nl;
#ifdef AUTOW
if (writewaiting)
{
delaywrite = writewaiting = 0;
catchclock();
delaywrite++;
}
#endif AUTOW
}
setcook(); /* terminal into cooked mode */
putchar('\n');
if (inglob == 0) error(21);
}
getnil()
{
if (oflag == EOF) return(EOF);
linebuf[0] = '\0';
oflag = EOF;
return(0);
}
setraw()
{
if (gtty(0, tty) == -1) error(3);
savetty = tty[2];
tty[2] =| RAW;
stty(0, tty);
}
setcook()
{
tty[2] = savetty;
stty(0, tty);
}
inword(c)
char c;
{
if (c>='0' && c<='9') return(1);
c =& 0137; /* convert to upper case */
if (c>='A' && c<='Z') return(1);
return(0);
}
rescan()
{
register char *lp, *sp;
if (savethresh) { threshold = savethresh; savethresh = 0; }
lp = linebuf;
sp = genbuf;
while ((*lp++ = *sp++) != '\0')
if (lp > linebuf+LBSIZE) { *(--lp) = '\0'; break; }
}
/*
* Leaves revised line in linebuf,
* returns 0 if more to follow,
* EOF if last line.
*/
gopen()
{
register char *lp, *sp, *rp;
char ch, *br, *pr;
int tabs;
int retcode, savint, pid, rpid;
#ifdef MISC
char erase, kill;
kill = tty[1] >> 8 & 0177;
erase = tty[1] & 0177;
#endif
lp = lnp;
sp = gnp;
tabs = 0;
for (rp = genbuf; rp < sp; rp++) if (*rp == CTRLI) tabs =+ TABSET;
for (;;)
{
#ifdef MISC
if ((ch = getchar()) == RUBOUT)
{
*thestart++ = oldline;
if (nline) /* some lines added */
{
addr1 = thestart;
addr2 = thestart + nline - 1;
if (addr2 == dol) delete(); else { delete(); dot--; }
}
putnls("\\\r");
setcook();
lastc = '\n';
error(20); /* no return */
}
if (ch == kill)
{
sp = genbuf; /* delete displayed line backward */
tabs = 0;
goto verify;
}
if (ch == erase) goto erasechr;
if (ch >= ' ') /* not a control chr */
{
*--lp = ch;
goto forward;
}
switch(ch) /* what's left */
#else
switch (ch = getchar())
#endif
{
case CTRLD:
case ESCAPE: /* close the line (see case '\n' also) */
close:
putb(lp);
while (*sp++ = *lp++);
rescan();
return(EOF);
case CTRLA: /* verify line */
verify: putnls("\\\r");
*sp = '\0';
putb(genbuf);
continue;
case CTRLB: /* back a word */
if (sp == genbuf) goto backquery;
while ((*--lp = *--sp) == SPACE)
if (sp < genbuf) goto out;
if (inword(*sp))
{
while (inword(*--lp = *--sp))
if (sp < genbuf) goto out;
if (*sp == SPACE)
while ((*--lp = *--sp) == SPACE)
if (sp < genbuf) goto out;
}
else while (sp >= genbuf && !inword(*sp))
if ((*lp-- = *sp--) == CTRLI) tabs =- TABSET;
out: sp++;
lp++;
goto verify;
case CTRLC:
case CTRLQ: /* forward one char */
if (*lp == 0) goto backquery;
putch(*lp);
forward: if (*lp==SPACE && sp+tabs > threshold)
{
putch('\r');
ch = '\n';
putch(ch);
lp++;
*sp++ = ch;
br = sp;
break;
}
if (*lp == CTRLI) tabs =+ TABSET;
*sp++ = *lp++; /* one character */
if (sp+tabs == threshold) putch(BELL);
continue;
case CTRLE: putb(lp);
goto verify;
case CTRLF: while (*lp++); /* delete forward */
lp--;
goto verify;
#ifndef MISC
case CTRLH: help(); /* help */
goto verify;
#endif
case CTRLP: while (*lp != '\0') /* skip to eol */
{
if (*lp == CTRLI) tabs =+ TABSET;
putch(*sp++ = *lp++);
}
continue;
case CTRLR: /* margin release */
if (threshold-genbuf < LBSIZE-40)
{
savethresh = threshold;
threshold = genbuf+LBSIZE-40;
}
else goto backquery;
continue;
case CTRLS: while (*sp++ = *lp++); /* re-set to start of line */
rescan();
lp = linebuf;
sp = genbuf;
tabs = 0;
goto verify;
case CTRLT: /* backup one character */
if (sp == genbuf) goto backquery;
if ((*--lp = *--sp) == CTRLI) tabs =- TABSET;
goto verify;
case CTRLV: rp = sp; /* verify spelling */
#ifndef NOSPELL
pr = unixbuffer + UNIXBUFL - 2;
*pr = 0;
while (*(--rp) == SPACE);
while (inword(*rp) && rp >= genbuf) *--pr = *rp--;
if (*pr == 0) goto backquery;
putnls("!!");
setcook();
if ((pid = fork()) == 0)
{
signal(SIGHUP, onhup);
signal(SIGQUIT, onquit);
execl("/bin/spell", "spell", pr, 0);
#else
putchar('\n');
#endif
putnls("Sorry, can't spell today");
#ifndef NOSPELL
exit(1);
}
savint = signal(SIGINTR, 1);
do rpid = wait(&retcode); while (rpid!=pid && rpid!=-1);
signal(SIGINTR, savint);
setraw();
putnls("!!");
#endif NOSPELL
goto verify;
case CTRLW: /* forward one word */
if (*lp == '\0') goto backquery;
while (*lp == SPACE) putch(*sp++ = *lp++);
if (inword(*lp))
{
while (inword(*lp))
{
putch(*sp++ = *lp++);
if (sp+tabs == threshold) putch(BELL);
}
if (*lp == SPACE)
{
if (sp+tabs > threshold)
{
ch = '\n';
lp++;
*sp++ = ch;
br = sp;
putch('\r');
putch('\n');
}
if (*lp == SPACE)
while (lp[1] == SPACE)
putch(*sp++ = *lp++);
}
}
else while (*lp && !inword(*lp))
{
if (*lp == CTRLI) tabs =+ TABSET;
putch(*sp++ = *lp++);
if (sp+tabs == threshold) putch(BELL);
}
break;
case CTRLZ: /* delete a word */
if (sp == genbuf) goto backquery;
while (*--sp == SPACE) if (sp < genbuf) goto zout;
if (inword(*sp))
{
while (inword(*--sp)) if (sp < genbuf) goto zout;
if (*sp == SPACE)
while (*--sp == SPACE) if (sp < genbuf) goto zout;
}
else while (sp>=genbuf && !inword(*sp))
if (*sp-- == CTRLI) tabs =- TABSET;
zout: sp++;
goto verify;
#ifndef MISC
case '@': sp = genbuf; /* delete displayed line backward */
tabs = 0;
goto verify;
#endif
#ifndef MISC
case RUBOUT:
#ifdef NICE_EXIT
*thestart++ = oldline;
if (nline) /* some lines added */
{
addr1 = thestart;
addr2 = thestart + nline - 1;
if (addr2 == dol) delete(); else { delete(); dot--; }
}
#endif NICE_EXIT
putnls("\\\r");
setcook();
lastc = '\n';
error(20);
#endif MISC
case CTRLX:
#ifndef MISC
case '#': if (sp == genbuf) goto backquery;
#else
erasechr: if (sp == genbuf) goto backquery;
#endif
if (*--sp == CTRLI) tabs =- TABSET;
if (ch == CTRLX) goto verify;
continue;
case '\n':
case '\r': /*
* split line; actually handled at
* end of switch block
*/
ch = '\n';
*sp++ = ch;
br = sp;
break;
case '\0': continue;
case BACKSL: /* special symbols */
ch = getchar();
if (ch!=BACKSL && ch!='#' && ch!='@')
if (savetty & UCASE)
switch (ch)
{
case '(': ch = '{'; break;
case ')': ch = '}'; break;
case '!': ch = '|'; break;
case '^': ch = '~'; break;
case '\'': ch = '`'; break;
default: if (ch>='a' && ch<='z') ch =- 040;
else { peekc = ch; ch = BACKSL; }
break;
}
else { peekc = ch; ch = BACKSL; }
#ifndef MISC
default: *(--lp) = ch;
goto forward;
#else
case CTRLI:
case CTRLG: /* allow for bell, tab, form-feed */
case CTRLL: *--lp = ch;
goto forward;
default: help();
goto verify;
#endif
}
if (ch == '\n')
{
/* split line */
/* if (*(br-1) != '\n') putnls("!!"); /* debugging only */
lnp = sp;
while (*sp++ = *lp++); /* move the rest over */
brp = linebuf + (br - genbuf);
lnp = linebuf + (lnp - br);
rescan();
*(brp - 1) = '\0';
return(0);
}
else continue;
backquery: putch(BELL);
} /* end of forloop block */
} /* end of gopen */
/*
* calls gopen, deals with multiple lines etc.
*/
getopen()
{
register char *lp, *sp;
if (oflag == EOF) return(EOF);
/* otherwise, multiple lines */
lp = linebuf;
sp = brp;
while (*lp++ = *sp++); /* move it down */
sp = genbuf;
lp = linebuf;
while (lp < lnp) *sp++ = *lp++;
gnp = sp;
/* should check whether empty line returned */
oflag = gopen();
return(0);
}
putch(ch)
char ch;
{
write(1, &ch, 1);
}
putb(ptr)
char *ptr; /*display string */
{
register char *p;
p = ptr;
if (*p == '\0') return;
while (*(++p));
write(1, ptr, p-ptr);
}
help()
{
putnls("\n");
#ifdef MISC
putnls(" erase and kill characters unchanged");
#endif
putnls(" ^A display Again ^Q, ^C next character");
putnls(" ^B backup word ^R release margin");
putnls(" ESCAPE ^S re-scan from Start");
putnls(" or ^D close line and exit ^V verify spelling");
putnls(" ^E display to End ^W next Word");
putnls(" ^F delete line Forward ^Z delete word");
#ifndef MISC
putnls(" ^H Help # or ^X delete character");
#else
putnls(" ^O Help ^X delete character");
#endif
putnls(" ^P skip to End ^T backup one character");
#ifndef MISC
putnls(" RUBOUT exit unchanged @ delete line backward");
#else
putnls(" RUBOUT exit unchanged");
#endif
putnls("\n Other characters (including RETURN) inserted as typed");
}