1
0
mirror of synced 2026-01-11 23:43:06 +00:00

620 lines
9.9 KiB
C

/*% cc -c -O %
*/
#include "vars.h"
#define OUT 10
#define BACKWARD 11
#define FORWARD 12
char jumpcs[] "0123456789o`'";
jump() /* this should be pronounced with a Swedish accent */
{
register int i;
int cond;
register c;
register struct buffer *bufp;
if(stackp->type==TTY)
error('y');
c = getchar();
cond = TRUE;
if(c=='t' || c=='f'){
cond = ((c=='t') == (truth!=FALSE));
c = getchar();
}
i = posn(c, jumpcs);
if(i==-1){ /* to handle y[tf] without labels for globals */
ungetchar(c);
if(cond){
while((c = getc())!='\n')
if(c==EOF)
return;
}
}
else if(i<=9){
stacktype(BUF);
ungetchar(c);
i = getnum();
stacktype(BUF); /* we may have popped stack! */
if(cond){
/* getchar will handle problems if off end of buffer */
bbempty = TRUE;
stackp->lineno = i;
stackp->charno = 0;
}
}
else if(i==OUT){
if(cond){
if(stackp==stack)
error('y');
if(stackp->type==GLOB){
--nestlevel;
stackp->globp = "";
}else
popinp();
}
}
else if(i==FORWARD || i==BACKWARD){
stacktype(BUF);
getlabel(); /* must eat label even if not yumping */
stacktype(BUF);
if(cond)
search(i==FORWARD);
}
}
stacktype(t)
{
if(stackp->type != t)
error('y');
}
getlabel(){
register char *p, c;
p = genbuf;
for(c=getchar(); posn(c," \"\t\n")<0; c=getchar()){
*p++ = c;
*p = '\0';
}
if(p==genbuf)
error('y');
}
search(forward)
{
register int *a1;
register char *p1;
struct buffer *bufp;
bufp = stackp->bufptr;
if(forward){
if((a1 = looper(bufp->zero + stackp->lineno + 1,
bufp->dol,genbuf,1))==0){
a1 = looper(bufp->zero + 1,bufp->zero + stackp->lineno - 1,genbuf,1);
}
}else{
if((a1 = looper(bufp->zero + stackp->lineno - 1,
bufp->zero + 1,genbuf,0))==0){
a1 = looper(bufp->dol,bufp->zero + stackp->lineno + 1,genbuf,0);
}
}
if(a1){
stackp->lineno = a1 - bufp->zero;
stackp->charno = 0;
}
}
looper(a1,a2,str,dir) register int *a1; int *a2; char *str;
{
register char *p1;
register char *p2;
while(dir ? a1<=a2 : a1>=a2){
p2 = getline(*a1, linebuf);
while(*p2==' ' || *p2=='\t')
p2++;
if(*p2++=='"' && *p2!=' ' && *p2!='\t' && *p2) {
for(p1=str; *p2 && *p1==*p2; p2++)
p1++;
if(*p1==0 && (*p2==0 || *p2==' ' || *p2=='\t'))
return(a1);
}
if(dir)
a1++;
else
--a1;
}
return(0);
}
int pchar;
setapp()
{
register c;
c=getchar();
if(posn(c, lchars)>=0) {
pchar = c;
c = getchar();
}
if(c==' ' || c=='\t'){
oneline++;
if(c=='\t')
ungetchar(c);
}
else if(c!='\n')
error('x');
}
append(f, a) int (*f)();
{
register *a1, *a2, *rdot;
int nline, tl;
struct { int iint; };
appflag++;
nline = 0;
dot = a;
while ((*f)()==0) {
if (lastdol>=endcore) {
if (sbrk(1024)==-1)
error('c');
endcore.iint =+ 1024;
}
tl = putline();
nline++;
lock++;
++dol;
a1 = ++lastdol;
fixbufs(1);
a2 = a1+1;
rdot = ++dot;
while (a1 > rdot)
*--a2 = *--a1;
*rdot = tl;
unlock();
if(oneline)
break;
}
appflag=0;
oneline=0;
if(pchar) {
addr1 = dot;
addr2 = dot;
display(pchar);
pchar = 0;
}
return(nline);
}
char bformat = 'p';
bcom()
{
register forward, n;
forward=1;
if((peekc=getchar())!='\n'){
if (peekc=='-' || peekc=='+') {
if(peekc=='-')
forward=0;
getchar();
}
if((n=getnum())>0)
pagesize=n;
}
if(posn(nextchar(), lchars)>=0)
bformat=getchar();
if (forward) {
addr1=addr2;
if((addr2+=pagesize)>dol)
addr2=dol;
} else {
if((addr1=addr2-pagesize)<=zero)
addr1=zero+1;
}
display(bformat);
}
delete()
{
register *a1, *a2, *a3;
setdot();
a1 = addr1;
a2 = addr2;
if(a1==zero) {
if(a2!=zero)
*(a1++);
else
return; /* 0,$d on an empty buffer */
}
*(a2++);
a3 = lastdol;
lock++;
dol =- a2 - a1;
lastdol =- a2 - a1;
fixbufs(a1-a2);
do
*a1++ = *a2++;
while (a2<=a3);
a1 = addr1;
if (a1 > dol)
a1 = dol;
dot = a1;
unlock();
cflag = TRUE;
}
allnums()
{
register int i;
register char *p;
setdot();
for(i=0; i<NBUFS; i++){
p = string[i].str;
if(*p!='\0' && alldigs(p)){
putct(bname[i]);
puts(p);
}
}
putct('T');
putdn(truth);
putct('C');
putd(); /* == putlong(count) */
putchar('\n');
}
numcom(z)
{
register n;
register struct string *sp;
register char *l;
char c;
int numeric;
extern char digits[]; /* defined in getchar.c = "0123456789" */
/*
* Must generate error if attempt is made to do arithmetic on
* a register which is not numeric; this is done by remembering
* (via `numeric') whether the initial string was numeric or not.
*/
sp = &string[z];
numeric = alldigs(sp->str);
n = atoi(sp->str);
while((c=getchar())=='#'){
switch(c=getchar()){
default:
error('#');
case ':':
n=getsigned();
goto Not_numeric;
case 'a':
n=addr2-zero;
goto Not_numeric;
case 'r':
if(z+1>=NBUFS)
error('z');
n = addr1-zero;
numset(z+1, addr2-zero);
goto Not_numeric;
case 'l':
nonzero();
l = getline(*addr2,linebuf);
do; while(*l++);
n = l - linebuf - 1;
goto Not_numeric;
case '?':
n = rand();
goto Not_numeric;
case 't':
n = truth;
goto Not_numeric;
case 'c':
n=count;
Not_numeric:
numeric = TRUE; /* It's numeric now! */
break;
case 'p':
if(n<0)
putchar('-');
putdn(abs(n));
goto Numeric;
case '+':
n =+ getsigned();
goto Numeric;
case '-':
n =- getsigned();
goto Numeric;
case '*':
n =* getsigned();
goto Numeric;
case '/':
n =/ getsigned();
goto Numeric;
case '%':
n =% getsigned();
goto Numeric;
case '<':
truth = n<getsigned();
goto Numeric;
case '=':
truth = n==getsigned();
goto Numeric;
case '>':
truth = n>getsigned();
Numeric:
if(numeric == FALSE)
error('#');
break;
}
}
ungetchar(c);
numset(z, n);
}
numset(z, n)
register z;
register n;
{
startstring();
numbuild(n);
setstring(z);
}
numbuild(n)
register n;
{
register i;
if(n<0){
addstring('-');
n = -n;
}
i = n/10;
if(i)
numbuild(i);
addstring(n%10+'0');
}
strcom(z)
{
register char *q;
register i;
int n;
int getchar();
register struct string *sp;
char c, cond;
setdot();
sp = &string[z];
if(nextchar()=='#'){
numcom(z);
return;
}
switch(cond=getchar()){
default:
error('x');
case 'p':
putl(sp->str);
break;
case ':':
case '^':
case '$':
startstring();
if(cond=='$')
dupstring(z);
for(;;){
c = getquote("\n", getchar);
if(c=='\n'){
if(cond=='^'){
dupstring(z);
}
setstring(z);
return;
}
addstring(c&0177);
}
case '\'':
startstring();
dupstring(getname('z'));
setstring(z);
break;
case '.':
nonzero();
startstring();
copystring(getline(*addr2, linebuf));
setstring(z);
break;
case '/':
truth = FALSE;
nonzero();
compile('/');
if(execute(addr2)==0){
clearstring(z);
return;
}
truth = TRUE;
q = loc1;
startstring();
while(q < loc2)
addstring(*q++);
setstring(z);
return;
case '+':
strinc(z, getsigned());
break;
case '-':
strinc(z, -getsigned());
break;
case 'l':
count=sp->len;
break;
case '(':
n=getsigned();
if(abs(n) > sp->len)
error('[');
if(n>=0){
sp->str =+ n;
sp->len =- n;
}
else{
sp->str[sp->len+n]='\0';
sp->len =+ n;
}
break;
case ')':
n=getsigned();
if(abs(n) > sp->len)
error('[');
if(n<0){
sp->str =+ sp->len+n;
sp->len = -n;
}
else{
sp->str[n]='\0';
sp->len=n;
}
break;
case '[':
q=genbuf;
do;while((*q++ = getchar())!='\n');
*--q=0;
truth = FALSE;
count=locn(genbuf,sp->str);
if(count != -1)
truth = TRUE;
break;
/*
* clean string dmt dec 79
*/
case 'C':
startstring();
clean(z);
setstring(z);
break;
/* end clean */
case '=':
case '<':
case '>':
truth=FALSE;
q=sp->str;
for(;;){
c=getchar();
if(c=='\n' && *q==0){
if(cond=='=')
truth=1;
return;
}
if(*q++!=c){
if(cond=='<')
truth = *--q < c;
else if(cond=='>')
truth = *--q > c;
while(c!='\n')
c=getchar();
return;
}
}
}
}
strinc(z, n)
{
register char *q;
q=string[z].str;
while(*q)
*q++ =+ n;
}
locn(ap, aq)
char *ap, *aq;
{
register char *p, *q, *lastq;
p=ap;
q=aq;
for(;;){
lastq=q;
while(*p==*q){
if(*p++==0 || *p==0)
return(lastq - aq);
q++;
}
if(*q==0)
return(-1);
p=ap;
q=lastq+1;
}
}
#define EMPTY (TRUE+1) /* ==> ignore this buf in G/V */
ncom(c)
{
register struct buffer *bufp;
struct buffer *stop;
register char *f, *lp;
int globflag;
setnoaddr();
syncbuf();
globflag = FALSE;
if(c == 'f')
stop = bufp = curbuf;
else{
bufp = buffer;
stop = buffer+NBUFS-1;
if(c=='G')
globflag = TRUE;
}
do{
lp = linebuf;
f = string[FILE(bufp-buffer)].str;
if(c=='N' && (!bufp->cflag || *f==0))
continue;
if(bufp->dol==bufp->zero && *f=='\0'){
if(globflag)
bufp->gmark = EMPTY;
if(globflag || bufp!=curbuf)
continue;
}
*lp++ = bname[bufp-buffer];
*lp++ = (bufp->cflag) ? '\'' : ' ';
*lp++ = (bufp==curbuf) ? '.' : ' ';
numset(FILEBUF, bufp->dol-bufp->zero);
cpstr(string[FILEBUF].str, lp);
lp += string[FILEBUF].len;
*lp++ = '\t';
if(globflag){
cpstr(f, lp);
loc2 = 0; /* ==> we are about to search for 1st time */
bufp->gmark = execute(0);
} else {
*lp = '\0';
lp = linebuf;
while(*lp)
putchar(*lp++);
putl(f);
}
}while(bufp++!=stop);
}
allstrs()
{
register int i;
char *p;
setdot();
for(i=0; i<NBUFS; i++){
p=string[i].str;
if(*p!=0){
putct(bname[i]);
putl(p);
}
}
putct('P');
putl(string[SAVPAT].str);
putct('R');
putl(string[SAVRHS].str);
if(*string[BROWSE].str) {
putct('B');
putl(string[BROWSE].str);
}
}
/*
* clean (string) to support zaC
* strips leading and trailing white space from a string
* and replaces interior white space by single blanks
*/
clean(z) {
register char *s;
register char *d;
register char c;
d = genbuf;
for (s = string[z].str; (c = *s) == ' ' || c == '\t'; s++);
while (c = *s++) {
if (c == ' ' || c == '\t') {
*d++ = ' ';
while(*s == ' ' || *s == '\t')
s++;
} else {
*d++ = c;
}
}
while (d > genbuf && d[-1] == ' ')
--d;
*d = 0;
copystring(genbuf);
}