version 1.14, 1999/04/18 17:06:31 |
version 1.15, 1999/04/20 17:31:30 |
|
|
Cell *tmps; /* free temporary cells for execution */ |
Cell *tmps; /* free temporary cells for execution */ |
|
|
static Cell truecell ={ OBOOL, BTRUE, 0, 0, 1.0, NUM }; |
static Cell truecell ={ OBOOL, BTRUE, 0, 0, 1.0, NUM }; |
Cell *true = &truecell; |
Cell *True = &truecell; |
static Cell falsecell ={ OBOOL, BFALSE, 0, 0, 0.0, NUM }; |
static Cell falsecell ={ OBOOL, BFALSE, 0, 0, 0.0, NUM }; |
Cell *false = &falsecell; |
Cell *False = &falsecell; |
static Cell breakcell ={ OJUMP, JBREAK, 0, 0, 0.0, NUM }; |
static Cell breakcell ={ OJUMP, JBREAK, 0, 0, 0.0, NUM }; |
Cell *jbreak = &breakcell; |
Cell *jbreak = &breakcell; |
static Cell contcell ={ OJUMP, JCONT, 0, 0, 0.0, NUM }; |
static Cell contcell ={ OJUMP, JCONT, 0, 0, 0.0, NUM }; |
|
|
/* round up to next multiple of quantum */ |
/* round up to next multiple of quantum */ |
if (rminlen) |
if (rminlen) |
minlen += quantum - rminlen; |
minlen += quantum - rminlen; |
tbuf = realloc(*pbuf, minlen); |
tbuf = (char *) realloc(*pbuf, minlen); |
if (tbuf == NULL) { |
if (tbuf == NULL) { |
if (whatrtn) |
if (whatrtn) |
ERROR "out of memory in %s", whatrtn FATAL; |
ERROR "out of memory in %s", whatrtn FATAL; |
|
|
Node *a; |
Node *a; |
|
|
if (u == NULL) |
if (u == NULL) |
return(true); |
return(True); |
for (a = u; ; a = a->nnext) { |
for (a = u; ; a = a->nnext) { |
curnode = a; |
curnode = a; |
if (isvalue(a)) { |
if (isvalue(a)) { |
|
|
if (a[0]) { /* BEGIN */ |
if (a[0]) { /* BEGIN */ |
x = execute(a[0]); |
x = execute(a[0]); |
if (isexit(x)) |
if (isexit(x)) |
return(true); |
return(True); |
if (isjump(x)) |
if (isjump(x)) |
ERROR "illegal break, continue, next or nextfile from BEGIN" FATAL; |
ERROR "illegal break, continue, next or nextfile from BEGIN" FATAL; |
tempfree(x); |
tempfree(x); |
|
|
tempfree(x); |
tempfree(x); |
} |
} |
ex1: |
ex1: |
return(true); |
return(True); |
} |
} |
|
|
struct Frame { /* stack frame for awk function calls */ |
struct Frame { /* stack frame for awk function calls */ |
|
|
for (ncall = 0, x = a[1]; x != NULL; x = x->nnext) /* args in call */ |
for (ncall = 0, x = a[1]; x != NULL; x = x->nnext) /* args in call */ |
ncall++; |
ncall++; |
ndef = (int) fcn->fval; /* args in defn */ |
ndef = (int) fcn->fval; /* args in defn */ |
dprintf( ("calling %s, %d args (%d in defn), fp=%d\n", s, ncall, ndef, fp-frame) ); |
dprintf( ("calling %s, %d args (%d in defn), fp=%d\n", s, ncall, ndef, (int) (fp-frame)) ); |
if (ncall > ndef) |
if (ncall > ndef) |
ERROR "function %s called with %d args, uses only %d", |
ERROR "function %s called with %d args, uses only %d", |
s, ncall, ndef WARNING; |
s, ncall, ndef WARNING; |
if (ncall + ndef > NARGS) |
if (ncall + ndef > NARGS) |
ERROR "function %s has %d arguments, limit %d", s, ncall+ndef, NARGS FATAL; |
ERROR "function %s has %d arguments, limit %d", s, ncall+ndef, NARGS FATAL; |
for (i = 0, x = a[1]; x != NULL; i++, x = x->nnext) { /* get call args */ |
for (i = 0, x = a[1]; x != NULL; i++, x = x->nnext) { /* get call args */ |
dprintf( ("evaluate args[%d], fp=%d:\n", i, fp-frame) ); |
dprintf( ("evaluate args[%d], fp=%d:\n", i, (int) (fp-frame)) ); |
y = execute(x); |
y = execute(x); |
oargs[i] = y; |
oargs[i] = y; |
dprintf( ("args[%d]: %s %f <%s>, t=%o\n", |
dprintf( ("args[%d]: %s %f <%s>, t=%o\n", |
|
|
fp->nargs = ndef; /* number defined with (excess are locals) */ |
fp->nargs = ndef; /* number defined with (excess are locals) */ |
fp->retval = gettemp(); |
fp->retval = gettemp(); |
|
|
dprintf( ("start exec of %s, fp=%d\n", s, fp-frame) ); |
dprintf( ("start exec of %s, fp=%d\n", s, (int) (fp-frame)) ); |
y = execute((Node *)(fcn->sval)); /* execute body */ |
y = execute((Node *)(fcn->sval)); /* execute body */ |
dprintf( ("finished exec of %s, fp=%d\n", s, fp-frame) ); |
dprintf( ("finished exec of %s, fp=%d\n", s, (int) (fp-frame)) ); |
|
|
for (i = 0; i < ndef; i++) { |
for (i = 0; i < ndef; i++) { |
Cell *t = fp->args[i]; |
Cell *t = fp->args[i]; |
|
|
Cell *arg(Node **a, int n) /* nth argument of a function */ |
Cell *arg(Node **a, int n) /* nth argument of a function */ |
{ |
{ |
|
|
n = (int) a[0]; /* argument number, counting from 0 */ |
n = ptoi(a[0]); /* argument number, counting from 0 */ |
dprintf( ("arg(%d), fp->nargs=%d\n", n, fp->nargs) ); |
dprintf( ("arg(%d), fp->nargs=%d\n", n, fp->nargs) ); |
if (n+1 > fp->nargs) |
if (n+1 > fp->nargs) |
ERROR "argument #%d of function %s was not supplied", |
ERROR "argument #%d of function %s was not supplied", |
|
|
FILE *fp; |
FILE *fp; |
char *buf; |
char *buf; |
int bufsize = recsize; |
int bufsize = recsize; |
|
int mode; |
|
|
if ((buf = (char *) malloc(bufsize)) == NULL) |
if ((buf = (char *) malloc(bufsize)) == NULL) |
ERROR "out of memory in getline" FATAL; |
ERROR "out of memory in getline" FATAL; |
|
|
r = gettemp(); |
r = gettemp(); |
if (a[1] != NULL) { /* getline < file */ |
if (a[1] != NULL) { /* getline < file */ |
x = execute(a[2]); /* filename */ |
x = execute(a[2]); /* filename */ |
if ((int) a[1] == '|') /* input pipe */ |
mode = ptoi(a[1]); |
a[1] = (Node *) LE; /* arbitrary flag */ |
if (mode == '|') /* input pipe */ |
fp = openfile((int) a[1], getsval(x)); |
mode = LE; /* arbitrary flag */ |
|
fp = openfile(mode, getsval(x)); |
tempfree(x); |
tempfree(x); |
if (fp == NULL) |
if (fp == NULL) |
n = -1; |
n = -1; |
|
|
int bufsz = recsize; |
int bufsz = recsize; |
int nsub = strlen(*SUBSEP); |
int nsub = strlen(*SUBSEP); |
|
|
if ((buf = malloc(bufsz)) == NULL) |
if ((buf = (char *) malloc(bufsz)) == NULL) |
ERROR "out of memory in array" FATAL; |
ERROR "out of memory in array" FATAL; |
|
|
x = execute(a[0]); /* Cell* for symbol table */ |
x = execute(a[0]); /* Cell* for symbol table */ |
|
|
|
|
x = execute(a[0]); /* Cell* for symbol table */ |
x = execute(a[0]); /* Cell* for symbol table */ |
if (!isarr(x)) |
if (!isarr(x)) |
return true; |
return True; |
if (a[1] == 0) { /* delete the elements, not the table */ |
if (a[1] == 0) { /* delete the elements, not the table */ |
freesymtab(x); |
freesymtab(x); |
x->tval &= ~STR; |
x->tval &= ~STR; |
|
|
} else { |
} else { |
int bufsz = recsize; |
int bufsz = recsize; |
char *buf; |
char *buf; |
if ((buf = malloc(bufsz)) == NULL) |
if ((buf = (char *) malloc(bufsz)) == NULL) |
ERROR "out of memory in adelete" FATAL; |
ERROR "out of memory in adelete" FATAL; |
buf[0] = 0; |
buf[0] = 0; |
for (np = a[1]; np; np = np->nnext) { |
for (np = a[1]; np; np = np->nnext) { |
|
|
free(buf); |
free(buf); |
} |
} |
tempfree(x); |
tempfree(x); |
return true; |
return True; |
} |
} |
|
|
Cell *intest(Node **a, int n) /* a[0] is index (list), a[1] is symtab */ |
Cell *intest(Node **a, int n) /* a[0] is index (list), a[1] is symtab */ |
|
|
ap->tval |= ARR; |
ap->tval |= ARR; |
ap->sval = (char *) makesymtab(NSYMTAB); |
ap->sval = (char *) makesymtab(NSYMTAB); |
} |
} |
if ((buf = malloc(bufsz)) == NULL) { |
if ((buf = (char *) malloc(bufsz)) == NULL) { |
ERROR "out of memory in intest" FATAL; |
ERROR "out of memory in intest" FATAL; |
} |
} |
buf[0] = 0; |
buf[0] = 0; |
|
|
tempfree(ap); |
tempfree(ap); |
free(buf); |
free(buf); |
if (k == NULL) |
if (k == NULL) |
return(false); |
return(False); |
else |
else |
return(true); |
return(True); |
} |
} |
|
|
|
|
|
|
x->fval = start; |
x->fval = start; |
return x; |
return x; |
} else if ((n == MATCH && i == 1) || (n == NOTMATCH && i == 0)) |
} else if ((n == MATCH && i == 1) || (n == NOTMATCH && i == 0)) |
return(true); |
return(True); |
else |
else |
return(false); |
return(False); |
} |
} |
|
|
|
|
|
|
tempfree(x); |
tempfree(x); |
switch (n) { |
switch (n) { |
case BOR: |
case BOR: |
if (i) return(true); |
if (i) return(True); |
y = execute(a[1]); |
y = execute(a[1]); |
i = istrue(y); |
i = istrue(y); |
tempfree(y); |
tempfree(y); |
if (i) return(true); |
if (i) return(True); |
else return(false); |
else return(False); |
case AND: |
case AND: |
if ( !i ) return(false); |
if ( !i ) return(False); |
y = execute(a[1]); |
y = execute(a[1]); |
i = istrue(y); |
i = istrue(y); |
tempfree(y); |
tempfree(y); |
if (i) return(true); |
if (i) return(True); |
else return(false); |
else return(False); |
case NOT: |
case NOT: |
if (i) return(false); |
if (i) return(False); |
else return(true); |
else return(True); |
default: /* can't happen */ |
default: /* can't happen */ |
ERROR "unknown boolean operator %d", n FATAL; |
ERROR "unknown boolean operator %d", n FATAL; |
} |
} |
|
|
tempfree(x); |
tempfree(x); |
tempfree(y); |
tempfree(y); |
switch (n) { |
switch (n) { |
case LT: if (i<0) return(true); |
case LT: if (i<0) return(True); |
else return(false); |
else return(False); |
case LE: if (i<=0) return(true); |
case LE: if (i<=0) return(True); |
else return(false); |
else return(False); |
case NE: if (i!=0) return(true); |
case NE: if (i!=0) return(True); |
else return(false); |
else return(False); |
case EQ: if (i == 0) return(true); |
case EQ: if (i == 0) return(True); |
else return(false); |
else return(False); |
case GE: if (i>=0) return(true); |
case GE: if (i>=0) return(True); |
else return(false); |
else return(False); |
case GT: if (i>0) return(true); |
case GT: if (i>0) return(True); |
else return(false); |
else return(False); |
default: /* can't happen */ |
default: /* can't happen */ |
ERROR "unknown relational operator %d", n FATAL; |
ERROR "unknown relational operator %d", n FATAL; |
} |
} |
|
|
|
|
os = s; |
os = s; |
p = buf; |
p = buf; |
if ((fmt = malloc(fmtsz)) == NULL) |
if ((fmt = (char *) malloc(fmtsz)) == NULL) |
ERROR "out of memory in format()" FATAL; |
ERROR "out of memory in format()" FATAL; |
while (*s) { |
while (*s) { |
adjbuf(&buf, &bufsize, MAXNUMSIZE+1+p-buf, recsize, &p, "format"); |
adjbuf(&buf, &bufsize, MAXNUMSIZE+1+p-buf, recsize, &p, "format"); |
|
|
char *buf; |
char *buf; |
int bufsz=3*recsize; |
int bufsz=3*recsize; |
|
|
if ((buf=malloc(bufsz)) == NULL) |
if ((buf = (char *) malloc(bufsz)) == NULL) |
ERROR "out of memory in awksprintf" FATAL; |
ERROR "out of memory in awksprintf" FATAL; |
y = a[0]->nnext; |
y = a[0]->nnext; |
x = execute(a[0]); |
x = execute(a[0]); |
|
|
int len; |
int len; |
int bufsz=3*recsize; |
int bufsz=3*recsize; |
|
|
if ((buf=malloc(bufsz)) == NULL) |
if ((buf = (char *) malloc(bufsz)) == NULL) |
ERROR "out of memory in awkprintf" FATAL; |
ERROR "out of memory in awkprintf" FATAL; |
y = a[0]->nnext; |
y = a[0]->nnext; |
x = execute(a[0]); |
x = execute(a[0]); |
|
|
if (ferror(stdout)) |
if (ferror(stdout)) |
ERROR "write error on stdout" FATAL; |
ERROR "write error on stdout" FATAL; |
} else { |
} else { |
fp = redirect((int)a[1], a[2]); |
fp = redirect(ptoi(a[1]), a[2]); |
/* fputs(buf, fp); */ |
/* fputs(buf, fp); */ |
fwrite(buf, len, 1, fp); |
fwrite(buf, len, 1, fp); |
fflush(fp); |
fflush(fp); |
|
|
ERROR "write error on %s", filename(fp) FATAL; |
ERROR "write error on %s", filename(fp) FATAL; |
} |
} |
free(buf); |
free(buf); |
return(true); |
return(True); |
} |
} |
|
|
Cell *arith(Node **a, int n) /* a[0] + a[1], etc. also -a[0] */ |
Cell *arith(Node **a, int n) /* a[0] + a[1], etc. also -a[0] */ |
|
|
Cell *x; |
Cell *x; |
int pair; |
int pair; |
|
|
pair = (int) a[3]; |
pair = ptoi(a[3]); |
if (pairstack[pair] == 0) { |
if (pairstack[pair] == 0) { |
x = execute(a[0]); |
x = execute(a[0]); |
if (istrue(x)) |
if (istrue(x)) |
|
|
x = execute(a[2]); |
x = execute(a[2]); |
return(x); |
return(x); |
} |
} |
return(false); |
return(False); |
} |
} |
|
|
Cell *split(Node **a, int nnn) /* split(a[0], a[1], a[2]); a[3] is type */ |
Cell *split(Node **a, int nnn) /* split(a[0], a[1], a[2]); a[3] is type */ |
|
|
char *s; |
char *s; |
int sep; |
int sep; |
char *t, temp, num[50], *fs = 0; |
char *t, temp, num[50], *fs = 0; |
int n, tempstat; |
int n, tempstat, arg3type; |
|
|
y = execute(a[0]); /* source string */ |
y = execute(a[0]); /* source string */ |
s = getsval(y); |
s = getsval(y); |
|
arg3type = ptoi(a[3]); |
if (a[2] == 0) /* fs string */ |
if (a[2] == 0) /* fs string */ |
fs = *FS; |
fs = *FS; |
else if ((int) a[3] == STRING) { /* split(str,arr,"string") */ |
else if (arg3type == STRING) { /* split(str,arr,"string") */ |
x = execute(a[2]); |
x = execute(a[2]); |
fs = getsval(x); |
fs = getsval(x); |
} else if ((int) a[3] == REGEXPR) |
} else if (arg3type == REGEXPR) |
fs = "(regexpr)"; /* split(str,arr,/regexpr/) */ |
fs = "(regexpr)"; /* split(str,arr,/regexpr/) */ |
else |
else |
ERROR "illegal type of split" FATAL; |
ERROR "illegal type of split" FATAL; |
|
|
ap->sval = (char *) makesymtab(NSYMTAB); |
ap->sval = (char *) makesymtab(NSYMTAB); |
|
|
n = 0; |
n = 0; |
if ((*s != '\0' && strlen(fs) > 1) || (int) a[3] == REGEXPR) { /* reg expr */ |
if ((*s != '\0' && strlen(fs) > 1) || arg3type == REGEXPR) { /* reg expr */ |
fa *pfa; |
fa *pfa; |
if ((int) a[3] == REGEXPR) { /* it's ready already */ |
if (arg3type == REGEXPR) { /* it's ready already */ |
pfa = (fa *) a[2]; |
pfa = (fa *) a[2]; |
} else { |
} else { |
pfa = makedfa(fs, 1); |
pfa = makedfa(fs, 1); |
|
|
} |
} |
tempfree(ap); |
tempfree(ap); |
tempfree(y); |
tempfree(y); |
if (a[2] != 0 && (int) a[3] == STRING) |
if (a[2] != 0 && arg3type == STRING) |
tempfree(x); |
tempfree(x); |
x = gettemp(); |
x = gettemp(); |
x->tval = NUM; |
x->tval = NUM; |
|
|
tempfree(x); |
tempfree(x); |
x = execute(a[1]); |
x = execute(a[1]); |
if (isbreak(x)) { |
if (isbreak(x)) { |
x = true; |
x = True; |
return(x); |
return(x); |
} |
} |
if (isnext(x) || isexit(x) || isret(x)) |
if (isnext(x) || isexit(x) || isret(x)) |
|
|
for (;;) { |
for (;;) { |
x = execute(a[0]); |
x = execute(a[0]); |
if (isbreak(x)) |
if (isbreak(x)) |
return true; |
return True; |
if (isnext(x) || isnextfile(x) || isexit(x) || isret(x)) |
if (isnext(x) || isnextfile(x) || isexit(x) || isret(x)) |
return(x); |
return(x); |
tempfree(x); |
tempfree(x); |
|
|
} |
} |
x = execute(a[3]); |
x = execute(a[3]); |
if (isbreak(x)) /* turn off break */ |
if (isbreak(x)) /* turn off break */ |
return true; |
return True; |
if (isnext(x) || isexit(x) || isret(x)) |
if (isnext(x) || isexit(x) || isret(x)) |
return(x); |
return(x); |
tempfree(x); |
tempfree(x); |
|
|
vp = execute(a[0]); |
vp = execute(a[0]); |
arrayp = execute(a[1]); |
arrayp = execute(a[1]); |
if (!isarr(arrayp)) { |
if (!isarr(arrayp)) { |
return true; |
return True; |
} |
} |
tp = (Array *) arrayp->sval; |
tp = (Array *) arrayp->sval; |
tempfree(arrayp); |
tempfree(arrayp); |
|
|
x = execute(a[2]); |
x = execute(a[2]); |
if (isbreak(x)) { |
if (isbreak(x)) { |
tempfree(vp); |
tempfree(vp); |
return true; |
return True; |
} |
} |
if (isnext(x) || isexit(x) || isret(x)) { |
if (isnext(x) || isexit(x) || isret(x)) { |
tempfree(vp); |
tempfree(vp); |
|
|
tempfree(x); |
tempfree(x); |
} |
} |
} |
} |
return true; |
return True; |
} |
} |
|
|
Cell *bltin(Node **a, int n) /* builtin functions. a[0] is type, a[1] is arg list */ |
Cell *bltin(Node **a, int n) /* builtin functions. a[0] is type, a[1] is arg list */ |
|
|
Node *nextarg; |
Node *nextarg; |
FILE *fp; |
FILE *fp; |
|
|
t = (int) a[0]; |
t = ptoi(a[0]); |
x = execute(a[1]); |
x = execute(a[1]); |
nextarg = a[1]->nnext; |
nextarg = a[1]->nnext; |
switch (t) { |
switch (t) { |
|
|
if (a[1] == 0) /* a[1] is redirection operator, a[2] is file */ |
if (a[1] == 0) /* a[1] is redirection operator, a[2] is file */ |
fp = stdout; |
fp = stdout; |
else |
else |
fp = redirect((int)a[1], a[2]); |
fp = redirect(ptoi(a[1]), a[2]); |
for (x = a[0]; x != NULL; x = x->nnext) { |
for (x = a[0]; x != NULL; x = x->nnext) { |
y = execute(x); |
y = execute(x); |
fputs(getsval(y), fp); |
fputs(getsval(y), fp); |
|
|
fflush(fp); |
fflush(fp); |
if (ferror(fp)) |
if (ferror(fp)) |
ERROR "write error on %s", filename(fp) FATAL; |
ERROR "write error on %s", filename(fp) FATAL; |
return(true); |
return(True); |
} |
} |
|
|
Cell *nullproc(Node **a, int n) |
Cell *nullproc(Node **a, int n) |
{ |
{ |
n = 0; |
n = n; |
a = 0; |
a = a; |
return 0; |
return 0; |
} |
} |
|
|
|
|
Cell *x; |
Cell *x; |
int i, stat; |
int i, stat; |
|
|
n = 0; |
n = n; |
x = execute(a[0]); |
x = execute(a[0]); |
getsval(x); |
getsval(x); |
for (i = 0; i < FOPEN_MAX; i++) |
for (i = 0; i < FOPEN_MAX; i++) |
|
|
files[i].fp = NULL; |
files[i].fp = NULL; |
} |
} |
tempfree(x); |
tempfree(x); |
return(true); |
return(True); |
} |
} |
|
|
void closeall(void) |
void closeall(void) |
|
|
fa *pfa; |
fa *pfa; |
int bufsz = recsize; |
int bufsz = recsize; |
|
|
if ((buf=malloc(bufsz)) == NULL) |
if ((buf = (char *) malloc(bufsz)) == NULL) |
ERROR "out of memory in sub" FATAL; |
ERROR "out of memory in sub" FATAL; |
x = execute(a[3]); /* target string */ |
x = execute(a[3]); /* target string */ |
t = getsval(x); |
t = getsval(x); |
|
|
tempfree(y); |
tempfree(y); |
} |
} |
y = execute(a[2]); /* replacement string */ |
y = execute(a[2]); /* replacement string */ |
result = false; |
result = False; |
if (pmatch(pfa, t)) { |
if (pmatch(pfa, t)) { |
sptr = t; |
sptr = t; |
adjbuf(&buf, &bufsz, 1+patbeg-sptr, recsize, 0, "sub"); |
adjbuf(&buf, &bufsz, 1+patbeg-sptr, recsize, 0, "sub"); |
|
|
if (pb > buf + bufsz) |
if (pb > buf + bufsz) |
ERROR "sub result2 %.30s too big; can't happen", buf FATAL; |
ERROR "sub result2 %.30s too big; can't happen", buf FATAL; |
setsval(x, buf); /* BUG: should be able to avoid copy */ |
setsval(x, buf); /* BUG: should be able to avoid copy */ |
result = true;; |
result = True;; |
} |
} |
tempfree(x); |
tempfree(x); |
tempfree(y); |
tempfree(y); |
|
|
int mflag, tempstat, num; |
int mflag, tempstat, num; |
int bufsz = recsize; |
int bufsz = recsize; |
|
|
if ((buf=malloc(bufsz)) == NULL) |
if ((buf = (char *) malloc(bufsz)) == NULL) |
ERROR "out of memory in gsub" FATAL; |
ERROR "out of memory in gsub" FATAL; |
mflag = 0; /* if mflag == 0, can replace empty string */ |
mflag = 0; /* if mflag == 0, can replace empty string */ |
num = 0; |
num = 0; |