00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <stdio.h>
00017 #include <ctype.h>
00018 #include "awk.h"
00019 #include "regexp.h"
00020
00021 extern char **FS, **OFS, **ORS, **OFMT;
00022 extern double *RSTART, *RLENGTH;
00023 extern char record[];
00024 extern CELL *field[];
00025
00026 extern int r_start, r_length;
00027
00028 double getfval(), atof();
00029 char *strsave(), *getsval(), *strcat(), *strstr();
00030 CELL *mkcell(), *mktmp();
00031 CELL *Field(), *Split(), *Forin();
00032 CELL *Arith(), *Assign(), *Stat(), *Mathfun(), *Strfun(), *Cond();
00033 CELL *Print(), *Cat(), *Array(), *Element();
00034 CELL *If(), *While(), *For(), *Do(), *Jump();
00035 CELL *P1stat(), *P2stat(), *Print0();
00036 CELL *Arg(), *Call(), *Ret();
00037 CELL *Subst(), *In(), *Getline(), *Delete(), *Close();
00038 CELL *Nulproc(), *Usrfun();
00039 CELL *_Arg();
00040
00041 FILE *getfp();
00042
00043 CELL truecell = { NUM, NULL, 1.0 };
00044 CELL falsecell = { NUM, NULL, 0.0 };
00045 static CELL breakcell = { BRK, NULL, 0.0 };
00046 static CELL contcell = { CNT, NULL, 0.0 };
00047 static CELL nextcell = { NXT, NULL, 0.0 };
00048 static CELL retcell = { RTN, NULL, 0.0 };
00049
00050 static CELL *retval;
00051
00052 int pateval;
00053 static char *r_str;
00054 static regexp *r_pat;
00055
00056 CELL *(*proctab[])() = {
00057 Arg, Arith, Array, Assign, Call, Cat, Cond, Delete, Do, Element,
00058 Field, For, Forin, Getline, If, In, Jump, Mathfun, Nulproc, P1stat,
00059 P2stat, Print, Print0, Strfun, Subst, Usrfun, While
00060 };
00061
00062 CELL *
00063 execute(p) NODE *p;
00064 {
00065 int type, i;
00066 CELL *r, *(*proc)();
00067
00068 type = p->n_type;
00069 if (type == VALUE) {
00070 if ((r = (CELL *) p->n_arg[0])->c_type & PAT && pateval) {
00071 i = match(r->c_sval, (char *)record) ? 1 : 0;
00072 r = mktmp(NUM, NULL, (double) i);
00073 }
00074 return r;
00075 }
00076 for ( ; p != NULL; p = p->n_next) {
00077 #if 0
00078 if (p->n_type == VALUE) continue;
00079 #endif
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 i = (int) p->n_type;
00167 if (i < FIRSTP || i > LASTP)
00168 error("ILLEGAL PROC (%d)", i);
00169 proc = proctab[i - FIRSTP];
00170 r = (*proc)(p);
00171 if (r->c_type & (BRK|CNT|NXT|RTN))
00172 return r;
00173 if (p->n_next != NULL)
00174 c_free(r);
00175 #ifdef DOS
00176 kbhit();
00177 #endif
00178 }
00179 return r;
00180 }
00181
00182 static CELL *
00183 Arith(p) NODE *p;
00184 {
00185 int op;
00186 CELL *r, *u, *v, *execute();
00187 double x, y, fmod(), pow();
00188
00189 op = (int) p->n_arg[0];
00190 if (op == UMINUS) {
00191 u = execute(p->n_arg[1]);
00192 x = - getfval(u);
00193 }
00194 else if (op == INCDEC) {
00195 u = execute(p->n_arg[1]);
00196 x = getfval(u);
00197 setfval(u, x + (int) p->n_arg[2]);
00198 if ((int) p->n_arg[3] == PRE)
00199 return u;
00200
00201 }
00202 else {
00203 u = execute(p->n_arg[1]);
00204 v = execute(p->n_arg[2]);
00205 x = getfval(u);
00206 y = getfval(v);
00207 if (op == DIV || op == MOD) {
00208 if (y == 0.0)
00209 fprintf(stderr, "divid by 0\n");
00210 }
00211 switch (op) {
00212 case SUB: x -= y;break;
00213 case ADD: x += y; break;
00214 case MULT: x *= y; break;
00215 case DIV:
00216 if (y == 0.0)
00217 error("division by zero in \"/\"", (char *)0);
00218 x /= y; break;
00219 case MOD:
00220 if (y == 0.0)
00221 error("division by zero in \"%%\"", (char *)0);
00222 x = fmod(x, y); break;
00223 case POWER: x = pow(x, y); break;
00224 default: printf("UNSUPPORTED ARITH OPERATOR !\n"); break;
00225 }
00226 c_free(v);
00227 }
00228 c_free(u);
00229 r = mktmp(NUM, NULL, x);
00230 return r;
00231 }
00232
00233 static CELL *
00234 Assign(p) NODE *p;
00235 {
00236 CELL *u, *v, *execute();
00237 int op;
00238 double x, y, fmod(), pow();
00239
00240 op = (int) p->n_arg[0];
00241 u = execute(p->n_arg[1]);
00242
00243 #if 0
00244 if (u->c_type == UDF)
00245 u->c_type |= VAR|STR;
00246 #endif
00247 if (!(u->c_type & (VAR|FLD|REC)) && (u->c_type != UDF))
00248 fprintf(stderr, "ASSIGN TO NON VARIABLE (%d)\n", u->c_type);
00249 v = execute(p->n_arg[2]);
00250
00251 if (u == v)
00252 goto rtn;
00253
00254 if (op == ASSIGN) {
00255 if (v->c_type & NUM)
00256 setfval(u, getfval(v));
00257 else
00258 setsval(u, getsval(v));
00259 }
00260 else {
00261 x = getfval(u);
00262 y = getfval(v);
00263 switch (op) {
00264 case ADDEQ: x += y; break;
00265 case SUBEQ: x -= y; break;
00266 case MULTEQ: x *= y; break;
00267 case DIVEQ:
00268 if (y == 0.0)
00269 error("division by zero in \"/=\"", (char *)0);
00270 x /= y; break;
00271 case MODEQ:
00272 if (y == 0.0)
00273 error("division by zero in \"%=\"", (char *)0);
00274 x = fmod(x, y); break;
00275 case POWEQ: x = pow(x, y); break;
00276 default:
00277 synerr("illegal assign op (%d)", op);
00278 break;
00279 }
00280 setfval(u, x);
00281 }
00282 rtn:
00283 c_free(v);
00284 return u;
00285 }
00286
00287 static CELL *
00288 Cat(p) NODE *p;
00289 {
00290 CELL *u;
00291 char *s, *t, str[BUFSIZ];
00292
00293 u = execute(p->n_arg[0]);
00294 s = getsval(u);
00295 for (t = str; *s; )
00296 *t++ = *s++;
00297 c_free(u);
00298 u = execute(p->n_arg[1]);
00299 s = getsval(u);
00300 while (*s)
00301 *t++ = *s++;
00302 c_free(u);
00303 *t = '\0';
00304 return mktmp(STR, str, 0.0);
00305 }
00306
00307 static CELL *
00308 Print(p) NODE *p;
00309 {
00310 register int i, redir, typ;
00311 CELL *u;
00312 char *s, str[BUFSIZ];
00313 char *file;
00314 FILE *fp;
00315
00316 redir = (int) p->n_arg[0];
00317 if (typ = redir & PRMASK) {
00318 u = execute(p->n_arg[1]);
00319 file = getsval(u);
00320 if (typ == R_PIPE)
00321 typ = R_POUT;
00322 fp = getfp(file, typ);
00323 c_free(u);
00324 }
00325 else
00326 fp = stdout;
00327 if (redir & FORMAT)
00328 format(str, p);
00329 else {
00330 *str = '\0';
00331 for (i = 2; p->n_arg[i] != NULL; i++) {
00332 if (i > 2)
00333 strcat(str, *OFS);
00334 u = execute(p->n_arg[i]);
00335 s = getsval(u);
00336 strcat(str, s);
00337 c_free(u);
00338 }
00339 strcat(str, *ORS);
00340 }
00341 if (redir & STROUT)
00342 return mktmp(STR, str, 0.0);
00343 fputs(str, fp);
00344 fflush(fp);
00345 return &truecell;
00346 }
00347
00348 static CELL *
00349 Mathfun(p) NODE *p;
00350 {
00351 CELL *u, *v;
00352 double x, y;
00353 double atan2(), cos(), exp(), log(), sin(), sqrt(), modf();
00354
00355 if ((int) p->n_arg[1] == 0) {
00356 u = NULL;
00357 x = 0.0;
00358 }
00359 else {
00360 u = execute(p->n_arg[2]);
00361 x = getfval(u);
00362 }
00363 switch ((int) p->n_arg[0]) {
00364 case ATAN2:
00365 if ((int) p->n_arg[1] == 2) {
00366 v = execute(p->n_arg[3]);
00367 y = getfval(v);
00368 x = atan2(x, y);
00369 c_free(v);
00370 }
00371 else
00372 x = 0.0;
00373 break;
00374 case COS: x = cos(x); break;
00375 case EXP: x = exp(x); break;
00376 case INT: y = modf(x, &x); break;
00377 case LOG: x = log(x); break;
00378 case SIN: x = sin(x); break;
00379 case SQRT: x = sqrt(x); break;
00380 case RAND: x = (double) rand() / 32768.0; break;
00381 case SRAND: if (x == 0.0)
00382 x = (double) time(0);
00383 x = (double) srand((int) x);
00384 break;
00385 default:
00386 fprintf(stderr, "unknown math function (%d)\n", p->n_arg[2]);
00387 break;
00388 }
00389 if (u != NULL)
00390 c_free(u);
00391 return mktmp(NUM, NULL, x);
00392 }
00393
00394 static CELL *
00395 Strfun(p) NODE *p;
00396 {
00397 CELL *u, *v, *r;
00398 char *s, *t, str[BUFSIZ];
00399 int i, m, n;
00400 double x;
00401 regexp *pat, *getpat();
00402
00403 n = (int) p->n_arg[1];
00404 if (n > 0 && (int) p->n_arg[0] != SPLIT) {
00405 u = execute(p->n_arg[2]);
00406 s = getsval(u);
00407 }
00408 else {
00409 s = "";
00410 u = NULL;
00411 }
00412 switch ((int) p->n_arg[0]) {
00413 case INDEX:
00414 if (n > 1) {
00415 v = execute(p->n_arg[3]);
00416 t = getsval(v);
00417 i = Index(s, t);
00418 c_free(v);
00419 }
00420 else
00421 i = 0;
00422 r = mktmp(NUM, NULL, (double) i);
00423 break;
00424 case LENGTH:
00425 i = (n > 0) ? jstrlen(s) : jstrlen(record);
00426 r = mktmp(NUM, NULL, (double) i);
00427 break;
00428 case SPLIT:
00429 r = Split(p);
00430 break;
00431 case SUBSTR:
00432 if (n > 1) {
00433 v = execute(p->n_arg[3]);
00434 m = (int) getfval(v) - 1;
00435 c_free(v);
00436 }
00437 else
00438 m = 0;
00439 if (n > 2) {
00440 v = execute(p->n_arg[4]);
00441 n = (int) getfval(v);
00442 c_free(v);
00443 }
00444 else
00445 n = jstrlen(s) - m;
00446 for (t = str; *s && m-- > 0; s++)
00447 if (isKanji(*s))
00448 s++;
00449 while (*s && n-- > 0) {
00450 if (isKanji(*s))
00451 *t++ = *s++;
00452 *t++ = *s++;
00453 }
00454 *t = '\0';
00455 r = mktmp(STR, str, 0.0);
00456 break;
00457 case RMATCH:
00458 if (n > 1) {
00459 v = execute(p->n_arg[3]);
00460 pat = getpat(v);
00461 match(pat, s);
00462 c_free(v);
00463 if (r_start) {
00464 *RSTART = (double) r_start;
00465 *RLENGTH = (double) r_length;
00466 }
00467 r = mktmp(NUM, NULL, (double) r_start);
00468 }
00469 else
00470 error("missing regexpr in match(str, regexpr)");
00471 break;
00472 case CLOSE:
00473 r = Close(s);
00474 break;
00475 case SYSTEM:
00476 r = mktmp(NUM, NULL, system(s) == -1 ? 0.0 : 1.0);
00477 break;
00478 default:
00479 fprintf(stderr, "unknown string function");
00480 break;
00481 }
00482 c_free(u);
00483 return r;
00484 }
00485
00486 static regexp *
00487 getpat(r) CELL *r;
00488 {
00489 regexp *pat, *mkpat();
00490
00491 if (r->c_type & PAT)
00492 pat = (regexp *) r->c_sval;
00493 else {
00494 if (r_str && strcmp(r_str, r->c_sval) == 0)
00495 pat = r_pat;
00496 else {
00497 sfree(r_str); sfree(r_pat);
00498 r_str = strsave(getsval(r));
00499 pat = r_pat = mkpat(r_str);
00500 }
00501 }
00502 return pat;
00503 }
00504
00505 static CELL *
00506 Subst(p) NODE *p;
00507 {
00508 CELL *u, *v, *w;
00509 char *s, *t, *r, str[BUFSIZ], *strcpy();
00510 int i, n;
00511
00512 n = (int) p->n_arg[1];
00513 if (n > 1) {
00514 u = execute(p->n_arg[3]);
00515 s = getsval(u);
00516 v = execute(p->n_arg[2]);
00517 if (n > 2) {
00518 w = execute(p->n_arg[4]);
00519 t = getsval(w);
00520 r = str;
00521 }
00522 else {
00523 t = r = record;
00524 w = NULL;
00525 }
00526 i = (int) p->n_arg[0] == RGSUB ? 0 : 1;
00527 if (v->c_type & (PAT|STR))
00528 i = Sub(r, v->c_sval, (v->c_type & STR), s, t, i);
00529 else
00530 error("[g]sub(PAT, .. ) must be /../ or string (%d)",
00531 w->c_type);
00532 if (n > 2) {
00533 if (w->c_type & REC) {
00534 strcpy(record, str);
00535 mkfld(record, *FS, field);
00536 }
00537 else
00538 setsval(w, str);
00539 }
00540 else
00541 mkfld(record, *FS, field);
00542 c_free(u);
00543 c_free(v);
00544 c_free(w);
00545 }
00546 else
00547 i = 0;
00548 return mktmp(NUM, NULL, (double) i);
00549 }
00550
00551 static CELL *
00552 Cond(p) NODE *p;
00553 {
00554 CELL *u, *v;
00555 double x, y;
00556 int op, i, j;
00557 char *s;
00558 int save = pateval;
00559
00560 op = (int) p->n_arg[0];
00561 u = execute(p->n_arg[1]);
00562 x = getfval(u);
00563
00564
00565
00566 if (op == AND || op == OR || op == NOT) {
00567 if (u->c_type & NUM)
00568 i = (x != 0.0);
00569 else {
00570 s = getsval(u);
00571 i = (s != (char *)NULL) && (*s != '\0');
00572 }
00573 }
00574 if (op == AND && !i) {
00575 c_free(u);
00576 return &falsecell;
00577 }
00578 if (op == OR && i) {
00579 c_free(u);
00580 return &truecell;
00581 }
00582 if (op == NOT)
00583 i = i == 0 ? 1 : 0;
00584 else {
00585 if (op == MATCH || op == NOMATCH)
00586 pateval = 0;
00587 v = execute(p->n_arg[2]);
00588 y = getfval(v);
00589 if (op == AND || op == OR || op == BINAND || op == BINOR) {
00590 if (v->c_type & NUM)
00591 j = (y != 0.0);
00592 else {
00593 s = getsval(v);
00594 j = (s != (char *)NULL) && (*s != '\0');
00595 }
00596 switch (op) {
00597 case AND: i = i && j; break;
00598 case OR: i = i || j; break;
00599 case BINAND: i = i & j; break;
00600 case BINOR: i = i | j; break;
00601 }
00602 }
00603 else if (op == MATCH || op == NOMATCH) {
00604 char *s;
00605 regexp *pat, *getpat();
00606
00607 s = getsval(u);
00608 pat = getpat(v);
00609 i = match(pat, s) == 0 ? 0 : 1;
00610 if (op == NOMATCH)
00611 i = i == 0 ? 1 : 0;
00612 }
00613 else {
00614
00615
00616
00617 if ((u->c_type & NUM) && (v->c_type & NUM))
00618 i = x < y ? -1 : (x > y ? 1 : 0);
00619 else
00620 i = strcmp(getsval(u), getsval(v));
00621
00622
00623
00624
00625 switch (op) {
00626 case LT: i = i < 0 ? 1 : 0; break;
00627 case LE: i = i <= 0 ? 1 : 0; break;
00628 case EQ: i = i == 0 ? 1 : 0; break;
00629 case NE: i = i != 0 ? 1 : 0; break;
00630 case GT: i = i > 0 ? 1 : 0; break;
00631 case GE: i = i >= 0 ? 1 : 0; break;
00632 default:
00633 fprintf(stderr, "unknown relative operator (%d)\n", op);
00634 break;
00635 }
00636 }
00637 c_free(v);
00638 }
00639 c_free(u);
00640 pateval = save;
00641 return mktmp(NUM, NULL, (double) i);
00642 }
00643
00644 static CELL *
00645 If(p) NODE *p;
00646 {
00647 CELL *u;
00648 int i;
00649 char *s;
00650
00651 u = execute(p->n_arg[0]);
00652 if (u->c_type & NUM)
00653 i = (getfval(u) != 0.0);
00654 else {
00655 s = getsval(u);
00656 i = (s != (char *)NULL) && (*s != '\0');
00657 }
00658 c_free(u);
00659 if (i)
00660 u = execute(p->n_arg[1]);
00661 else if (p->n_arg[2])
00662 u = execute(p->n_arg[2]);
00663 else
00664 u = &truecell;
00665 return u;
00666 }
00667
00668 static CELL *
00669 While(p) NODE *p;
00670 {
00671 CELL *u;
00672 double x;
00673
00674 for (;;) {
00675 u = execute(p->n_arg[0]);
00676 x = getfval(u);
00677 if (x == 0.0)
00678 break;
00679 c_free(u);
00680 u = execute(p->n_arg[1]);
00681 switch (u->c_type) {
00682 case BRK:
00683 goto rtn;
00684 case NXT: case EXT: case RTN:
00685 return u;
00686 }
00687 c_free(u);
00688 }
00689 rtn:
00690 c_free(u);
00691 return &truecell;
00692 }
00693
00694 static CELL *
00695 Do(p) NODE *p;
00696 {
00697 CELL *u;
00698 double x;
00699
00700 for (;;) {
00701 u = execute(p->n_arg[0]);
00702 switch (u->c_type) {
00703 case BRK:
00704 goto rtn;
00705 case NXT: case EXT: case RTN:
00706 return u;
00707 }
00708 c_free(u);
00709 u = execute(p->n_arg[1]);
00710 if(getfval(u) == 0.0)
00711 break;
00712 c_free(u);
00713 }
00714 rtn:
00715 c_free(u);
00716 return &truecell;
00717 }
00718
00719 static CELL *
00720 For(p) NODE *p;
00721 {
00722 CELL *u;
00723 double x;
00724
00725 if (p->n_arg[0] != NULL) {
00726 u = execute(p->n_arg[0]);
00727 c_free(u);
00728 }
00729 for (;;) {
00730 if (p->n_arg[1] != NULL) {
00731 u = execute(p->n_arg[1]);
00732 x = getfval(u);
00733 c_free(u);
00734 if (x == 0.0)
00735 break;
00736 }
00737 u = execute(p->n_arg[3]);
00738 switch (u->c_type) {
00739 case BRK:
00740 c_free(u);
00741 goto rtn;
00742 case NXT: case EXT: case RTN:
00743 return u;
00744 }
00745 if (p->n_arg[2] != NULL) {
00746 u = execute(p->n_arg[2]);
00747 c_free(u);
00748 }
00749 }
00750 rtn:
00751 return &truecell;
00752 }
00753
00754 static CELL *
00755 Jump(p) NODE *p;
00756 {
00757 CELL *u;
00758 int i;
00759
00760 switch ((int) p->n_arg[0]) {
00761 case BREAK: u = &breakcell; break;
00762 case CONTIN: u = &contcell; break;
00763 case EXIT:
00764 if ((int) p->n_arg[1]) {
00765 u = execute(p->n_arg[1]);
00766 i = (int) getfval(u);
00767 }
00768 else
00769 i = 0;
00770 closeall();
00771 exit(i);
00772 case RETURN:
00773 Return(p);
00774 u = &retcell;
00775 break;
00776 case NEXT: u = &nextcell; break;
00777 }
00778 return u;
00779 }
00780
00781 static
00782 Return(p) NODE *p;
00783 {
00784 CELL *u;
00785 int i;
00786 char *s, str[BUFSIZ];
00787
00788 c_free(retval);
00789 if (p->n_arg[1] != NULL) {
00790 if (p->n_arg[2] == NULL) {
00791
00792
00793
00794 u = execute(p->n_arg[1]);
00795 if (u->c_type == UDF)
00796 retval = mktmp(STR, "", 0.0);
00797 else
00798 retval = mktmp(u->c_type, u->c_sval, u->c_fval);
00799 c_free(u);
00800 }
00801 else {
00802 for (i = 1; p->n_arg[i] != NULL; i++) {
00803 if (i == 1)
00804 *str = '\0';
00805 else
00806 strcat(str, *OFS);
00807 u = execute(p->n_arg[i]);
00808 s = getsval(u);
00809 strcat(str, s);
00810 c_free(u);
00811 }
00812
00813
00814
00815 if (isnum(str))
00816 retval = mktmp(STR|NUM, str, atof(str));
00817 else
00818 retval = mktmp(STR, str, 0.0);
00819 }
00820 }
00821 else
00822 retval = &truecell;
00823 }
00824
00825 #define MAXFRAME 100
00826 CELL **frame[MAXFRAME];
00827 static int framep;
00828
00829 static CELL *
00830 Arg(p) NODE *p;
00831 {
00832 CELL *u;
00833 int i;
00834
00835 u = (CELL *)p->n_arg[0];
00836 return _Arg((int)u->c_fval);
00837 }
00838
00839 CELL *
00840 _Arg(i)
00841 {
00842
00843
00844
00845 return frame[framep - 1][i];
00846 }
00847
00848 static CELL *
00849 Call(p) NODE *p;
00850 {
00851 CELL *u, *v, *r, **arg;
00852 NODE *q;
00853 int i, j, k, n;
00854 char *emalloc();
00855
00856 if (framep >= MAXFRAME - 2)
00857 error("stack frame overflow", (char *)0);
00858 retval = &truecell;
00859 r = (CELL *) p->n_arg[0];
00860 if (r->c_type != FUN)
00861 synerr("called function is not declared", (char *)0);
00862 n = (int) r->c_fval;
00863 if (n > 0) {
00864 arg = (CELL **) emalloc(sizeof(u) * n);
00865 for (i = 2, j = 0, k = (int) p->n_arg[1]; j < k; i++) {
00866 u = execute(p->n_arg[i]);
00867
00868
00869
00870 if (u->c_type & ARR)
00871 v = u;
00872 else {
00873 v = mkcell(UDF, u->c_sval, u->c_fval);
00874 if (u->c_type != UDF) {
00875 #if 0
00876 v->c_type = u->c_type;
00877 if (v->c_type & (NUM|STR))
00878 v->c_type |= VAR;
00879 v->c_type &= ~TMP;
00880 #else
00881 v->c_type |= (u->c_type & (NUM|STR))|VAR;
00882
00883 #endif
00884
00885 }
00886
00887
00888
00889 }
00890 arg[j++] = v;
00891 }
00892 for ( ; j < n; )
00893 arg[j++] = mkcell(UDF, NULL, 0.0);
00894 }
00895 else
00896 arg = NULL;
00897
00898 frame[framep] = arg;
00899 framep++;
00900
00901 r = execute(r->c_sval);
00902 c_free(r);
00903 framep--;
00904 if (n > 0) {
00905 for (j = n - 1 ; j > k; j--) {
00906 u = arg[j];
00907 if (u->c_type & ARR)
00908 a_free(u);
00909 else
00910 c_free(u);
00911 }
00912 for ( ; j >= 0; j--) {
00913 u = arg[j];
00914 if (!(u->c_type & ARR)) {
00915
00916 sfree(u->c_sval);
00917 sfree(u);
00918 }
00919 else {
00920 v = execute(p->n_arg[j + 2]);
00921 if (v->c_type == UDF) {
00922
00923
00924
00925 v->c_type = u->c_type;
00926 sfree(v->c_sval);
00927 v->c_sval = u->c_sval;
00928 v->c_fval = u->c_fval;
00929 sfree(u);
00930 }
00931 }
00932 }
00933 }
00934 sfree(arg);
00935
00936 u = mktmp(retval->c_type, retval->c_sval, retval->c_fval);
00937 return u;
00938 }
00939
00940 CELL *Nulproc()
00941 {
00942 return &truecell;
00943 }
00944
00945 CELL *
00946 Usrfun(p) NODE *p;
00947 {
00948 CELL *u;
00949
00950 u = execute(p);
00951 return u;
00952 }