static char sccsid
[] = "@(#)run.c 4.4 %G%";
extern obj
execute(), nodetoobj(), fieldel(), dopa2(), gettemp();
int pairstack
[PA2NUM
], paircnt
;
node
*winner
= (node
*)NULL
;
static cell nullval
={EMPTY
,EMPTY
,0.0,NUM
,0};
obj
true ={ OBOOL
, BTRUE
, 0 };
obj
false ={ OBOOL
, BFALSE
, 0 };
extern char *printname
[];
for (a
= u
; ; a
= a
->nnext
) {
error(FATAL
, "illegal statement %o", a
);
proc
= proctab
[a
->nobj
-FIRSTTOKEN
];
x
= (*proc
)(a
->narg
,a
->nobj
);
/* a statement, goto next statement */
if (a
->nnext
== (node
*)NULL
)
obj
program(a
, n
) node
**a
;
error(FATAL
, "unexpected break, continue or next");
if (isbreak(x
) || isnext(x
) || iscont(x
))
error(FATAL
, "unexpected break, continue or next");
setfval(x
.optr
, (awkfloat
) getrec());
obj
arrayel(a
,b
) node
*a
; obj b
;
x
->sval
= (char *) makesymtab();
y
.optr
= setsymtab(s
, tostring(""), 0.0, STR
|NUM
, x
->sval
);
obj
matchop(a
,n
) node
**a
;
if (isstr(x
)) s
= x
.optr
->sval
;
else s
= getsval(x
.optr
);
if (n
==MATCH
&& i
==1 || n
==NOTMATCH
&& i
==0)
obj
boolop(a
,n
) node
**a
;
error(FATAL
, "unknown boolean operator %d", n
);
if (x
.optr
->tval
&NUM
&& y
.optr
->tval
&NUM
) {
j
= x
.optr
->fval
- y
.optr
->fval
;
i
= j
<0? -1: (j
>0? 1: 0);
i
= strcmp(getsval(x
.optr
), getsval(y
.optr
));
error(FATAL
, "unknown relational operator %d", n
);
case LT
: if (i
<0) return(true);
case LE
: if (i
<=0) return(true);
case NE
: if (i
!=0) return(true);
case EQ
: if (i
==0) return(true);
case GE
: if (i
>=0) return(true);
case GT
: if (i
>0) return(true);
error(FATAL
, "out of temporaries in gettemp");
obj
indirect(a
,n
) node
**a
;
obj
substr(a
, nnn
) node
**a
;
dprintf("substr: m=%d, n=%d, s=%s\n", m
, n
, s
);
temp
= s
[n
+m
-1]; /* with thanks to John Linderman */
setsval(x
.optr
, s
+ m
- 1);
obj
sindex(a
, nnn
) node
**a
;
char *s1
, *s2
, *p1
, *p2
, *q
;
for (p1
= s1
; *p1
!= '\0'; p1
++) {
for (q
=p1
, p2
=s2
; *p2
!= '\0' && *q
== *p2
; q
++, p2
++)
setfval(x
.optr
, (awkfloat
) (p1
- s1
+ 1)); /* origin 1 */
char *format(s
,a
) char *s
; node
*a
;
char *buf
, *p
, fmt
[200], *t
, *os
;
p
= buf
= (char *)malloc(RECSIZE
);
for (t
=fmt
; (*t
++ = *s
) != '\0'; s
++)
if (*s
>= 'a' && *s
<= 'z' && *s
!= 'l')
if (t
>= fmt
+ sizeof(fmt
))
error(FATAL
, "format item %.20s... too long", os
);
case 'f': case 'e': case 'g':
flag
= *(s
-1)=='l' ? 2 : 3;
error(FATAL
, "not enough arguments in printf(%s)", os
);
if (flag
!= 4) /* watch out for converting to numbers! */
if (flag
==1) sprintf(p
, fmt
, xf
);
else if (flag
==2) sprintf(p
, fmt
, (long)xf
);
else if (flag
==3) sprintf(p
, fmt
, (int)xf
);
else if (flag
==4) sprintf(p
, fmt
, x
.optr
->sval
==NULL
? "" : getsval(x
.optr
));
obj
asprintf(a
,n
) node
**a
;
s
= format(getsval(x
.optr
), y
);
error(FATAL
, "illegal arithmetic operator %d", n
);
error(FATAL
, "division by zero");
error(FATAL
, "division by zero");
obj
incrdecr(a
, n
) node
**a
;
k
= (n
== PREINCR
|| n
== POSTINCR
) ? 1 : -1;
if (n
== PREINCR
|| n
== PREDECR
) {
obj
assign(a
,n
) node
**a
;
if (n
== ASSIGN
) { /* ordinary assignment */
if ((y
.optr
->tval
& (STR
|NUM
)) == (STR
|NUM
)) {
setsval(x
.optr
, y
.optr
->sval
);
x
.optr
->fval
= y
.optr
->fval
;
else if (y
.optr
->tval
& STR
)
setsval(x
.optr
, y
.optr
->sval
);
else if (y
.optr
->tval
& NUM
)
setfval(x
.optr
, y
.optr
->fval
);
error(FATAL
, "division by zero");
error(FATAL
, "division by zero");
xf
= xf
- yf
*(long)(xf
/yf
);
error(FATAL
, "illegal assignment operator %d", n
);
n1
= strlen(x
.optr
->sval
);
n2
= strlen(y
.optr
->sval
);
s
= (char *) malloc(n1
+ n2
+ 1);
strcpy(s
+n1
, y
.optr
->sval
);
obj
pastat(a
,n
) node
**a
;
obj
aprintf(a
,n
) node
**a
;
printf("%s", x
.optr
->sval
);
redirprint(x
.optr
->sval
, (int)a
[1], a
[2]);
obj
split(a
,nnn
) node
**a
;
sep
= getsval(x
.optr
)[0];
dprintf("split: s=|%s|, a=%s, sep=|%c|\n", s
, ap
->nval
, sep
);
ap
->sval
= (char *) makesymtab();
while (*s
== ' ' || *s
== '\t' || *s
== '\n')
while (*s
!=' ' && *s
!='\t' && *s
!='\n' && *s
!='\0');
setsymtab(num
, tostring(t
), atof(t
), STR
|NUM
, ap
->sval
);
setsymtab(num
, tostring(t
), 0.0, STR
, ap
->sval
);
while (*s
!= sep
&& *s
!= '\n' && *s
!= '\0')
setsymtab(num
, tostring(t
), atof(t
), STR
|NUM
, ap
->sval
);
setsymtab(num
, tostring(t
), 0.0, STR
, ap
->sval
);
obj
ifstat(a
,n
) node
**a
;
else if (a
[2] != nullstat
) {
obj
whilestat(a
,n
) node
**a
;
if (!istrue(x
)) return(x
);
if (isnext(x
) || isexit(x
))
obj
forstat(a
,n
) node
**a
;
if (!istrue(x
)) return(x
);
if (isbreak(x
)) { /* turn off break */
if (isnext(x
) || isexit(x
))
obj
instat(a
, n
) node
**a
;
cell
*vp
, *arrayp
, *cp
, **tp
;
if (!(arrayp
->tval
& ARR
))
error(FATAL
, "%s is not an array", arrayp
->nval
);
tp
= (cell
**) arrayp
->sval
;
for (i
= 0; i
< MAXSYM
; i
++) { /* this routine knows too much */
for (cp
= tp
[i
]; cp
!= NULL
; cp
= cp
->nextval
) {
if (isnext(x
) || isexit(x
))
error(FATAL
, "illegal jump type %d", n
);
errorflag
= getfval(y
.optr
);
u
= (awkfloat
) strlen(getsval(x
.optr
));
u
= log(getfval(x
.optr
));
u
= (awkfloat
) (long) getfval(x
.optr
);
u
= exp(getfval(x
.optr
));
u
= sqrt(getfval(x
.optr
));
error(FATAL
, "illegal function type %d", t
);
for (x
=a
[0]; x
!=NULL
; x
=x
->nnext
) {
strcat(s
, getsval(y
.optr
));
if (strlen(s
) >= RECSIZE
)
error(FATAL
, "string %.20s ... too long to print", s
);
redirprint(s
, (int)a
[1], a
[2]);
obj
nodetoobj(a
) node
*a
;
x
.optr
= (cell
*) a
->nobj
;
redirprint(s
, a
, b
) char *s
; node
*b
;
for (i
=0; i
<FILENUM
; i
++)
if (files
[i
].fp
&& strcmp(x
.optr
->sval
, files
[i
].fname
) == 0)
for (i
=0; i
<FILENUM
; i
++)
error(FATAL
, "too many output files %d", i
);
if (a
== '|') /* a pipe! */
files
[i
].fp
= popen(x
.optr
->sval
, "w");
files
[i
].fp
= fopen(x
.optr
->sval
, "a");
files
[i
].fp
= fopen(x
.optr
->sval
, "w");
error(FATAL
, "can't open file %s", x
.optr
->sval
);
files
[i
].fname
= tostring(x
.optr
->sval
);
fprintf(files
[i
].fp
, "%s", s
);
fflush(files
[i
].fp
); /* in case someone is waiting for the output */