|
|
1.1 root 1: #define tempfree(x) if (istemp(x)) tfree(x); else
2:
3: #define execute(p) (isvalue(p) ? (Cell *)((p)->narg[0]) : real_execute(p))
4: /* #define execute(p) real_execute(p) */
5:
6: #define DEBUG
7: #include "awk.h"
8: #include <math.h>
9: #include "y.tab.h"
10: #include <stdio.h>
11: #include <ctype.h>
12:
13: #define getfval(p) (((p)->tval & (ARR|FLD|REC|NUM)) == NUM ? (p)->fval : real_getfval(p))
14: #define getsval(p) (((p)->tval & (ARR|FLD|REC|STR)) == STR ? (p)->sval : real_getsval(p))
15:
16: extern Awkfloat real_getfval();
17: extern char *real_getsval();
18: extern Cell *real_execute(), *fieldel(), *dopa2(), *gettemp(), *copycell();
19: extern FILE *openfile(), *redirect();
20: extern fa *makedfa();
21: extern double errcheck();
22:
23: #define PA2NUM 29
24: int pairstack[PA2NUM], paircnt;
25: Node *winner = NULL;
26: Cell *tmps;
27:
28: static Cell truecell ={ OBOOL, BTRUE, 0, 0, 1.0, NUM };
29: Cell *true = &truecell;
30: static Cell falsecell ={ OBOOL, BFALSE, 0, 0, 0.0, NUM };
31: Cell *false = &falsecell;
32: static Cell breakcell ={ OJUMP, JBREAK, 0, 0, 0.0, NUM };
33: Cell *jbreak = &breakcell;
34: static Cell contcell ={ OJUMP, JCONT, 0, 0, 0.0, NUM };
35: Cell *jcont = &contcell;
36: static Cell nextcell ={ OJUMP, JNEXT, 0, 0, 0.0, NUM };
37: Cell *jnext = &nextcell;
38: static Cell exitcell ={ OJUMP, JEXIT, 0, 0, 0.0, NUM };
39: Cell *jexit = &exitcell;
40: static Cell retcell ={ OJUMP, JRET, 0, 0, 0.0, NUM };
41: Cell *jret = &retcell;
42: static Cell tempcell ={ OCELL, CTEMP, 0, 0, 0.0, NUM };
43:
44: Node *curnode = NULL; /* the node being executed, for debugging */
45:
46: run(a) Node *a;
47: {
48: execute(a);
49: closeall();
50: }
51:
52: Cell *real_execute(u) Node *u;
53: {
54: register Cell *(*proc)();
55: register Cell *x;
56: register Node *a;
57:
58: if (u == NULL)
59: return(true);
60: for (a = u; ; a = a->nnext) {
61: curnode = a;
62: if (isvalue(a) || a->ntype == NFIELD) {
63: x = (Cell *) (a->narg[0]);
64: x->ctype = OCELL;
65: if ((x->tval & FLD) && !donefld)
66: fldbld();
67: else if ((x->tval & REC) && !donerec)
68: recbld();
69: return(x);
70: }
71: if (notlegal(a->nobj)) /* probably a Cell* but too risky to print */
72: error(FATAL, "illegal statement");
73: proc = proctab[a->nobj-FIRSTTOKEN];
74: x = (*proc)(a->narg, a->nobj);
75: if ((x->tval & FLD) && !donefld)
76: fldbld();
77: else if ((x->tval & REC) && !donerec)
78: recbld();
79: if (isexpr(a))
80: return(x);
81: /* a statement, goto next statement */
82: if (isjump(x))
83: return(x);
84: if (a->nnext == (Node *)NULL)
85: return(x);
86: tempfree(x);
87: }
88: }
89:
90: Cell *program(a, n) register Node **a;
91: {
92: register Cell *x;
93:
94: if (a[0] != NULL) { /* BEGIN */
95: x = execute(a[0]);
96: if (isexit(x))
97: return(true);
98: if (isjump(x))
99: error(FATAL, "unexpected break, continue or next");
100: tempfree(x);
101: }
102: loop:
103: while (getrec(record) > 0) {
104: x = execute(a[1]);
105: if (isexit(x))
106: break;
107: tempfree(x);
108: }
109: if (a[2] != NULL) { /* END */
110: x = execute(a[2]);
111: if (iscont(x)) /* read some more */
112: goto loop;
113: if (isbreak(x) || isnext(x))
114: error(FATAL, "unexpected break or next");
115: tempfree(x);
116: }
117: return(true);
118: }
119:
120: #define FRAME 100
121: struct Frame {
122: int nargs; /* number of arguments in this call */
123: Cell *fcncell; /* pointer to Cell for function */
124: Cell **args; /* pointer to array of arguments after execute */
125: Cell *retval; /* return value */
126: } frame[FRAME];
127:
128: struct Frame *fp = frame; /* frame pointer. bottom level unused */
129:
130: Cell *call(a, n) Node **a;
131: {
132: int i, ncall, ndef;
133: Node *x;
134: Cell **args, *y, *z, *fcn;
135: char *s;
136:
137: fcn = execute(a[0]); /* the function itself */
138: s = fcn->nval;
139: if (!isfunc(fcn))
140: error(FATAL, "calling undefined function %s", s);
141: for (ncall = 0, x = a[1]; x != NULL; x = x->nnext) /* args in call */
142: ncall++;
143: ndef = (int) fcn->fval; /* args in defn */
144: dprintf("calling %s, %d args (%d in defn), fp=%d\n", s, ncall, ndef, fp-frame);
145: args = (Cell **) Calloc(ndef>ncall ? ndef : ncall, sizeof (Cell *));
146: for (i = 0, x = a[1]; x != NULL; i++, x = x->nnext) { /* get call args */
147: dprintf("evaluate args[%d], fp=%d:\n", i, fp-frame);
148: y = execute(x);
149: dprintf("args[%d]: %s %f <%s>, t=%o\n",
150: i, y->nval, getfval(y), getsval(y), y->tval);
151: if (!isarr(y)) {
152: args[i] = copycell(y);
153: } else {
154: args[i] = y; /* arrays by ref */
155: }
156: tempfree(y);
157: }
158: for ( ; i < ndef; i++) { /* add null args for ones not provided */
159: args[i] = gettemp();
160: args[i]->sval = "";
161: args[i]->tval = STR|NUM|DONTFREE;
162: args[i]->csub = CCOPY;
163: }
164: fp++; /* now ok to up frame */
165: if (fp >= frame+FRAME)
166: error(FATAL, "function %s nested too deeply", s);
167: fp->fcncell = fcn;
168: fp->args = args;
169: fp->nargs = ndef; /* number defined with (can be more than call) */
170: fp->retval = gettemp();
171:
172: dprintf("start exec of %s, fp=%d\n", s, fp-frame);
173: y = execute((Node *)(fcn->sval)); /* execute body */
174: dprintf("finished exec of %s, fp=%d\n", s, fp-frame);
175:
176: for (i = 0; i < ndef; i++) {
177: Cell *t = fp->args[i];
178: if (t->csub == CCOPY) {
179: if (isarr(t))
180: freesymtab(t);
181: t->csub = CTEMP;
182: }
183: tempfree(t);
184: }
185: if (isexit(y) || isnext(y))
186: return y;
187: z = fp->retval; /* return value */
188: dprintf("%s returns %g |%s| %o\n", s, getfval(z), getsval(z), z->tval);
189: xfree(fp->args);
190: fp--;
191: tempfree(fcn);
192: return(z);
193: }
194:
195: Cell *copycell(x) /* make a copy of a cell in a temp */
196: Cell *x;
197: {
198: Cell *y;
199:
200: y = gettemp();
201: y->csub = CCOPY; /* prevents freeing until call is over */
202: y->nval = x->nval;
203: y->sval = x->sval ? tostring(x->sval) : NULL;
204: y->fval = x->fval;
205: y->tval = x->tval & ~CON; /* copy is not a constant */
206: return y;
207: }
208:
209: Cell *arg(a,n) Node **a;
210: {
211: int n;
212:
213: n = (int) a[0]; /* argument number, counting from 0 */
214: dprintf("arg(%d), fp->nargs=%d\n", n, fp->nargs);
215: if (n+1 > fp->nargs)
216: error(FATAL, "argument #%d of function %s was not supplied",
217: n+1, fp->fcncell->nval);
218: return fp->args[n];
219: }
220:
221: Cell *jump(a, n) Node **a;
222: {
223: register Cell *y;
224:
225: switch (n) {
226: case EXIT:
227: if (a[0] != NULL) {
228: y = execute(a[0]);
229: errorflag = getfval(y);
230: tempfree(y);
231: }
232: return(jexit);
233: case RETURN:
234: if (a[0] != NULL) {
235: y = execute(a[0]);
236: if ((y->tval & (STR|NUM)) == (STR|NUM)) {
237: setsval(fp->retval, getsval(y));
238: fp->retval->fval = getfval(y);
239: fp->retval->tval |= NUM;
240: }
241: else if (y->tval & STR)
242: setsval(fp->retval, getsval(y));
243: else if (y->tval & NUM)
244: setfval(fp->retval, getfval(y));
245: tempfree(y);
246: }
247: return(jret);
248: case NEXT:
249: return(jnext);
250: case BREAK:
251: return(jbreak);
252: case CONTINUE:
253: return(jcont);
254: default:
255: error(FATAL, "illegal jump type %d", n);
256: }
257: }
258:
259: Cell *getline(a, n) Node **a; int n;
260: {
261: /* a[0] is variable, a[1] is operator, a[2] is filename */
262: register Cell *r, *x;
263: char buf[RECSIZE];
264: FILE *fp;
265:
266: fflush(stdout); /* in case someone is waiting for a prompt */
267: r = gettemp();
268: if (a[1] != NULL) { /* getline < file */
269: x = execute(a[2]); /* filename */
270: if ((int) a[1] == '|') /* input pipe */
271: a[1] = (Node *) LE; /* arbitrary flag */
272: fp = openfile((int) a[1], getsval(x));
273: tempfree(x);
274: if (fp == NULL)
275: n = -1;
276: else
277: n = readrec(buf, sizeof(buf), fp);
278: if (n <= 0) {
279: ;
280: } else if (a[0] != NULL) { /* getline var <file */
281: setsval(execute(a[0]), buf);
282: } else { /* getline <file */
283: if (!(recloc->tval & DONTFREE))
284: xfree(recloc->sval);
285: strcpy(record, buf);
286: recloc->sval = record;
287: recloc->tval = REC | STR | DONTFREE;
288: donerec = 1; donefld = 0;
289: }
290: } else { /* bare getline; use current input */
291: if (a[0] == NULL) /* getline */
292: n = getrec(record);
293: else { /* getline var */
294: n = getrec(buf);
295: setsval(execute(a[0]), buf);
296: }
297: }
298: setfval(r, (Awkfloat) n);
299: return r;
300: }
301:
302: Cell *getnf(a,n) register Node **a;
303: {
304: if (donefld == 0)
305: fldbld();
306: return (Cell *) a[0];
307: }
308:
309: Cell *array(a,n) register Node **a;
310: {
311: register Cell *x, *y, *z;
312: register char *s;
313:
314: x = execute(a[0]); /* Cell* for symbol table */
315: y = execute(a[1]); /* subscript */
316: s = getsval(y);
317: if (!isarr(x)) {
318: xfree(x->sval);
319: x->tval &= ~STR;
320: x->tval |= ARR;
321: x->sval = (char *) makesymtab();
322: }
323: z = setsymtab(s, "", 0.0, STR|NUM, x->sval);
324: z->ctype = OCELL;
325: z->csub = CVAR;
326: tempfree(x);
327: tempfree(y);
328: return(z);
329: }
330:
331: Cell *delete(a, n) Node **a;
332: {
333: Cell *x, *y;
334:
335: x = execute(a[0]); /* Cell* for symbol table */
336: y = execute(a[1]); /* subscript */
337: freeelem(x, getsval(y));
338: tempfree(y);
339: tempfree(x);
340: return true;
341: }
342:
343: Cell *intest(a, n) Node **a;
344: {
345: register Cell *x, *ap;
346: int k;
347:
348: ap = execute(a[1]); /* array name */
349: if (!isarr(ap))
350: error(FATAL, "%s is not an array", ap->nval);
351: x = execute(a[0]); /* expr */
352: getsval(x);
353: k = lookup(x->sval, (Cell **) ap->sval) == NULL;
354: tempfree(x);
355: tempfree(ap);
356: if (k)
357: return(false);
358: else
359: return(true);
360: }
361:
362:
363: Cell *matchop(a,n) Node **a;
364: {
365: register Cell *x, *y;
366: register char *s, *t;
367: register int i;
368: static struct fa *pfa = NULL;
369: static char *prevre = NULL;
370:
371: x = execute(a[1]);
372: s = getsval(x);
373: if (a[0] == 0)
374: i = match(a[2], s);
375: else {
376: y = execute(a[2]);
377: t = getsval(y);
378: if (pfa == NULL) {
379: pfa = makedfa(reparse(t), 0);
380: prevre = tostring(t);
381: } else if (strcmp(t, prevre) != 0) {
382: free(prevre);
383: prevre = tostring(t);
384: freefa(pfa);
385: pfa = makedfa(reparse(t), 0);
386: }
387: i = match(pfa, s);
388: tempfree(y);
389: }
390: tempfree(x);
391: if (n == MATCH && i == 1 || n == NOTMATCH && i == 0)
392: return(true);
393: else
394: return(false);
395: }
396:
397:
398: Cell *boolop(a,n) Node **a;
399: {
400: register Cell *x, *y;
401: register int i;
402:
403: x = execute(a[0]);
404: i = istrue(x);
405: tempfree(x);
406: switch (n) {
407: case BOR:
408: if (i) return(true);
409: y = execute(a[1]);
410: i = istrue(y);
411: tempfree(y);
412: if (i) return(true);
413: else return(false);
414: case AND:
415: if ( !i ) return(false);
416: y = execute(a[1]);
417: i = istrue(y);
418: tempfree(y);
419: if (i) return(true);
420: else return(false);
421: case NOT:
422: if (i) return(false);
423: else return(true);
424: default:
425: error(FATAL, "unknown boolean operator %d", n);
426: }
427: }
428:
429: Cell *relop(a,n) Node **a;
430: {
431: register int i;
432: register Cell *x, *y;
433: Awkfloat j;
434:
435: x = execute(a[0]);
436: y = execute(a[1]);
437: if (x->tval&NUM && y->tval&NUM) {
438: j = x->fval - y->fval;
439: i = j<0? -1: (j>0? 1: 0);
440: } else {
441: i = strcmp(getsval(x), getsval(y));
442: }
443: tempfree(x);
444: tempfree(y);
445: switch (n) {
446: case LT: if (i<0) return(true);
447: else return(false);
448: case LE: if (i<=0) return(true);
449: else return(false);
450: case NE: if (i!=0) return(true);
451: else return(false);
452: case EQ: if (i == 0) return(true);
453: else return(false);
454: case GE: if (i>=0) return(true);
455: else return(false);
456: case GT: if (i>0) return(true);
457: else return(false);
458: default:
459: error(FATAL, "unknown relational operator %d", n);
460: }
461: }
462:
463: tfree(a) register Cell *a;
464: {
465: xfree(a->sval);
466: a->tval = 0;
467: a->ctype = OCELL;
468: a->cnext = tmps;
469: tmps = a;
470: }
471:
472: Cell *gettemp()
473: { int i;
474: register Cell *x;
475:
476: if (!tmps) {
477: tmps = (Cell *) Calloc(100, sizeof(Cell));
478: if (!tmps)
479: error(FATAL, "no space for temporaries");
480: for(i = 1; i < 100; i++)
481: tmps[i-1].cnext = &tmps[i];
482: tmps[i-1].cnext = 0;
483: }
484: x = tmps;
485: tmps = x->cnext;
486: *x = tempcell;
487: return(x);
488: }
489:
490: Cell *indirect(a,n) Node **a;
491: {
492: register Cell *x;
493: register int m;
494: register char *s;
495: Cell *fieldadr();
496:
497: x = execute(a[0]);
498: m = getfval(x);
499: if (m == 0 && !isnumber(s = getsval(x))) /* suspicion! */
500: error(FATAL, "illegal field $(%s)", s);
501: tempfree(x);
502: x = fieldadr(m);
503: x->ctype = OCELL;
504: x->csub = CFLD;
505: return(x);
506: }
507:
508: Cell *substr(a, nnn) Node **a;
509: {
510: register int k, m, n;
511: register char *s, temp;
512: register Cell *x;
513:
514: x = execute(a[0]);
515: s = getsval(x);
516: k = strlen(s) + 1;
517: tempfree(x);
518: if (k <= 1) {
519: x = gettemp();
520: setsval(x, "");
521: return(x);
522: }
523: x = execute(a[1]);
524: m = getfval(x);
525: if (m <= 0)
526: m = 1;
527: else if (m > k)
528: m = k;
529: tempfree(x);
530: if (a[2] != 0) {
531: x = execute(a[2]);
532: n = getfval(x);
533: tempfree(x);
534: }
535: else
536: n = k - 1;
537: if (n < 0)
538: n = 0;
539: else if (n > k - m)
540: n = k - m;
541: dprintf("substr: m=%d, n=%d, s=%s\n", m, n, s);
542: x = gettemp();
543: temp = s[n+m-1]; /* with thanks to John Linderman */
544: s[n+m-1] = '\0';
545: setsval(x, s + m - 1);
546: s[n+m-1] = temp;
547: return(x);
548: }
549:
550: Cell *sindex(a, nnn) Node **a;
551: {
552: register Cell *x;
553: register char *s1, *s2, *p1, *p2, *q;
554:
555: x = execute(a[0]);
556: s1 = getsval(x);
557: tempfree(x);
558: x = execute(a[1]);
559: s2 = getsval(x);
560: tempfree(x);
561:
562: x = gettemp();
563: for (p1 = s1; *p1 != '\0'; p1++) {
564: for (q=p1, p2=s2; *p2 != '\0' && *q == *p2; q++, p2++)
565: ;
566: if (*p2 == '\0') {
567: setfval(x, (Awkfloat) (p1 - s1 + 1)); /* origin 1 */
568: return(x);
569: }
570: }
571: setfval(x, 0.0);
572: return(x);
573: }
574:
575: char *format(buf, s, a) char *buf, *s; Node *a;
576: {
577: char fmt[RECSIZE];
578: register char *p, *t, *os;
579: register Cell *x;
580: int flag = 0;
581: Awkfloat xf;
582:
583: os = s;
584: p = buf;
585: while (*s) {
586: if (*s != '%') {
587: *p++ = *s++;
588: continue;
589: }
590: if (*(s+1) == '%') {
591: *p++ = '%';
592: s += 2;
593: continue;
594: }
595: for (t=fmt; (*t++ = *s) != '\0'; s++)
596: if (islower(*s) && *s != 'l')
597: break;
598: *t = '\0';
599: if (t >= fmt + sizeof(fmt))
600: error(FATAL, "format item %.20s... too long", os);
601: switch (*s) {
602: case 'f': case 'e': case 'g':
603: flag = 1;
604: break;
605: case 'd':
606: flag = 2;
607: if(*(s-1) == 'l') break;
608: *(t-1) = 'l';
609: *t = 'd';
610: *++t = '\0';
611: break;
612: case 'o': case 'x': case 'u':
613: flag = *(s-1) == 'l' ? 2 : 3;
614: break;
615: case 's':
616: flag = 4;
617: break;
618: case 'c':
619: flag = 5;
620: break;
621: default:
622: flag = 0;
623: break;
624: }
625: if (flag == 0) {
626: sprintf(p, "%s", fmt);
627: p += strlen(p);
628: continue;
629: }
630: if (a == NULL)
631: error(FATAL, "not enough args in printf(%s)", os);
632: x = execute(a);
633: a = a->nnext;
634: if (flag != 4) /* watch out for converting to numbers! */
635: xf = getfval(x);
636: switch (flag) {
637: case 1: sprintf(p, fmt, xf); break;
638: case 2: sprintf(p, fmt, (long) xf); break;
639: case 3: sprintf(p, fmt, (int) xf); break;
640: case 4: sprintf(p, fmt, getsval(x)); break;
641: case 5: sprintf(p, fmt, (int) xf); break;
642: }
643: tempfree(x);
644: p += strlen(p);
645: s++;
646: }
647: *p = '\0';
648: return buf;
649: }
650:
651: Cell *asprintf(a,n) Node **a;
652: {
653: register Cell *x;
654: register Node *y;
655: char buf[RECSIZE];
656:
657: y = a[0]->nnext;
658: x = execute(a[0]);
659: format(buf, getsval(x), y);
660: tempfree(x);
661: x = gettemp();
662: x->sval = tostring(buf);
663: x->tval = STR;
664: return(x);
665: }
666:
667: Cell *aprintf(a,n) Node **a;
668: {
669: FILE *fp;
670: register Cell *x;
671: register Node *y;
672: char buf[RECSIZE];
673:
674: y = a[0]->nnext;
675: x = execute(a[0]);
676: format(buf, getsval(x), y);
677: tempfree(x);
678: if (a[1] == NULL)
679: fputs(buf, stdout);
680: else {
681: fp = redirect((int)a[1], a[2]);
682: fputs(buf, fp);
683: fflush(fp);
684: }
685: return(true);
686: }
687:
688: Cell *arith(a,n) Node **a;
689: {
690: Awkfloat i, j;
691: register Cell *x, *y, *z;
692:
693: x = execute(a[0]);
694: i = getfval(x);
695: tempfree(x);
696: if (n != UMINUS) {
697: y = execute(a[1]);
698: j = getfval(y);
699: tempfree(y);
700: }
701: z = gettemp();
702: switch (n) {
703: case ADD:
704: i += j;
705: break;
706: case MINUS:
707: i -= j;
708: break;
709: case MULT:
710: i *= j;
711: break;
712: case DIVIDE:
713: if (j == 0)
714: error(FATAL, "division by zero");
715: i /= j;
716: break;
717: case MOD:
718: if (j == 0)
719: error(FATAL, "division by zero in mod");
720: i = i - j*(long)(i/j);
721: break;
722: case UMINUS:
723: i = -i;
724: break;
725: case POWER:
726: i = errcheck(pow(i, j), "pow");
727: break;
728: default:
729: error(FATAL, "illegal arithmetic operator %d", n);
730: }
731: setfval(z, i);
732: return(z);
733: }
734:
735: Cell *incrdecr(a, n) Node **a;
736: {
737: register Cell *x, *z;
738: register int k;
739: Awkfloat xf;
740:
741: x = execute(a[0]);
742: xf = getfval(x);
743: k = (n == PREINCR || n == POSTINCR) ? 1 : -1;
744: if (n == PREINCR || n == PREDECR) {
745: setfval(x, xf + k);
746: return(x);
747: }
748: z = gettemp();
749: setfval(z, xf);
750: setfval(x, xf + k);
751: tempfree(x);
752: return(z);
753: }
754:
755: Cell *assign(a,n) Node **a;
756: {
757: register Cell *x, *y;
758: Awkfloat xf, yf;
759:
760: x = execute(a[0]);
761: y = execute(a[1]);
762: if (n == ASSIGN) { /* ordinary assignment */
763: if ((y->tval & (STR|NUM)) == (STR|NUM)) {
764: setsval(x, getsval(y));
765: x->fval = getfval(y);
766: x->tval |= NUM;
767: }
768: else if (y->tval & STR)
769: setsval(x, getsval(y));
770: else if (y->tval & NUM)
771: setfval(x, getfval(y));
772: tempfree(y);
773: return(x);
774: }
775: xf = getfval(x);
776: yf = getfval(y);
777: switch (n) {
778: case ADDEQ:
779: xf += yf;
780: break;
781: case SUBEQ:
782: xf -= yf;
783: break;
784: case MULTEQ:
785: xf *= yf;
786: break;
787: case DIVEQ:
788: if (yf == 0)
789: error(FATAL, "division by zero");
790: xf /= yf;
791: break;
792: case MODEQ:
793: if (yf == 0)
794: error(FATAL, "division by zero");
795: xf = xf - yf*(long)(xf/yf);
796: break;
797: case POWEQ:
798: xf = errcheck(pow(xf, yf), "pow");
799: break;
800: default:
801: error(FATAL, "illegal assignment operator %d", n);
802: break;
803: }
804: tempfree(y);
805: setfval(x, xf);
806: return(x);
807: }
808:
809: Cell *cat(a,q) Node **a;
810: {
811: register Cell *x, *y, *z;
812: register int n1, n2;
813: register char *s;
814:
815: x = execute(a[0]);
816: y = execute(a[1]);
817: getsval(x);
818: getsval(y);
819: n1 = strlen(x->sval);
820: n2 = strlen(y->sval);
821: s = (char *) Malloc(n1 + n2 + 1);
822: strcpy(s, x->sval);
823: strcpy(s+n1, y->sval);
824: tempfree(y);
825: z = gettemp();
826: z->sval = s;
827: z->tval = STR;
828: tempfree(x);
829: return(z);
830: }
831:
832: Cell *pastat(a,n) Node **a;
833: {
834: register Cell *x;
835:
836: if (a[0] == 0)
837: x = execute(a[1]);
838: else {
839: x = execute(a[0]);
840: if (istrue(x)) {
841: tempfree(x);
842: x = execute(a[1]);
843: }
844: }
845: return x;
846: }
847:
848: Cell *dopa2(a,n) Node **a;
849: {
850: register Cell *x;
851: register int pair;
852:
853: pair = (int) a[3];
854: if (pairstack[pair] == 0) {
855: x = execute(a[0]);
856: if (istrue(x))
857: pairstack[pair] = 1;
858: tempfree(x);
859: }
860: if (pairstack[pair] == 1) {
861: x = execute(a[1]);
862: if (istrue(x))
863: pairstack[pair] = 0;
864: tempfree(x);
865: x = execute(a[2]);
866: return(x);
867: }
868: return(false);
869: }
870:
871: Cell *split(a,nnn) Node **a;
872: {
873: Cell *x, *y, *ap;
874: register char *s;
875: register int sep;
876: char *t, temp, num[5], *fs;
877: int n, tempstat;
878:
879: y = execute(a[0]);
880: s = getsval(y);
881: if (a[2] == 0)
882: fs = *FS;
883: else {
884: x = execute(a[2]);
885: fs = getsval(x);
886: }
887: sep = *fs;
888: ap = execute(a[1]); /* array name */
889: freesymtab(ap);
890: dprintf("split: s=|%s|, a=%s, sep=|%s|\n", s, ap->nval, fs);
891: ap->tval &= ~STR;
892: ap->tval |= ARR;
893: ap->sval = (char *) makesymtab();
894:
895: n = 0;
896: if (*s != '\0' && strlen(fs) > 1) { /* reg expr */
897: extern char *patbeg;
898: extern int patlen;
899: static fa *pfa = NULL;
900: static char *prevfs = NULL;
901: if (pfa == NULL) { /* first time thru */
902: pfa = makedfa(reparse(fs), 1);
903: prevfs = tostring(fs);
904: } else if (strcmp(fs, prevfs) != 0) { /* new fa needed for new FS */
905: freefa(pfa);
906: Free(prevfs);
907: pfa = makedfa(reparse(fs), 1);
908: prevfs = tostring(fs);
909: }
910: if (nematch(pfa,s)) {
911: tempstat = pfa->initstat;
912: pfa->initstat = 2;
913: do {
914: n++;
915: sprintf(num, "%d", n);
916: temp = *patbeg;
917: *patbeg = '\0';
918: if (isnumber(s))
919: setsymtab(num, s, atof(s), STR|NUM, ap->sval);
920: else
921: setsymtab(num, s, 0.0, STR, ap->sval);
922: *patbeg = temp;
923: s = patbeg + patlen;
924: if ((*(patbeg+patlen-1) == 0) || (*s == 0)) {
925: n++;
926: sprintf(num, "%d", n);
927: setsymtab(num, "", 0.0, STR, ap->sval);
928: pfa->initstat = tempstat;
929: goto spdone;
930: }
931: } while(nematch(pfa,s));
932: }
933: n++;
934: sprintf(num, "%d", n);
935: if (isnumber(s))
936: setsymtab(num, s, atof(s), STR|NUM, ap->sval);
937: else
938: setsymtab(num, s, 0.0, STR, ap->sval);
939: } else if (sep == ' ') {
940: for (n = 0; ; ) {
941: while (*s == ' ' || *s == '\t' || *s == '\n')
942: s++;
943: if (*s == 0)
944: break;
945: n++;
946: t = s;
947: do
948: s++;
949: while (*s!=' ' && *s!='\t' && *s!='\n' && *s!='\0');
950: temp = *s;
951: *s = '\0';
952: sprintf(num, "%d", n);
953: if (isnumber(t))
954: setsymtab(num, t, atof(t), STR|NUM, ap->sval);
955: else
956: setsymtab(num, t, 0.0, STR, ap->sval);
957: *s = temp;
958: if (*s != 0)
959: s++;
960: }
961: } else if (*s != 0) {
962: for (;;) {
963: n++;
964: t = s;
965: while (*s != sep && *s != '\n' && *s != '\0')
966: s++;
967: temp = *s;
968: *s = '\0';
969: sprintf(num, "%d", n);
970: if (isnumber(t))
971: setsymtab(num, t, atof(t), STR|NUM, ap->sval);
972: else
973: setsymtab(num, t, 0.0, STR, ap->sval);
974: *s = temp;
975: if (*s++ == 0)
976: break;
977: }
978: }
979: spdone:
980: tempfree(ap);
981: tempfree(y);
982: if (a[2] != 0)
983: tempfree(x);
984: x = gettemp();
985: x->tval = NUM;
986: x->fval = n;
987: return(x);
988: }
989:
990: Cell *ifstat(a,n) Node **a;
991: {
992: register Cell *x;
993:
994: x = execute(a[0]);
995: if (istrue(x)) {
996: tempfree(x);
997: x = execute(a[1]);
998: }
999: else if (a[2] != 0) {
1000: tempfree(x);
1001: x = execute(a[2]);
1002: }
1003: return(x);
1004: }
1005:
1006: Cell *whilestat(a,n) Node **a;
1007: {
1008: register Cell *x;
1009:
1010: for (;;) {
1011: x = execute(a[0]);
1012: if (!istrue(x)) return(x);
1013: tempfree(x);
1014: x = execute(a[1]);
1015: if (isbreak(x)) {
1016: x = true;
1017: return(x);
1018: }
1019: if (isnext(x) || isexit(x) || isret(x))
1020: return(x);
1021: tempfree(x);
1022: }
1023: }
1024:
1025: Cell *forstat(a,n) Node **a;
1026: {
1027: register Cell *x;
1028:
1029: x = execute(a[0]);
1030: tempfree(x);
1031: for (;;) {
1032: if (a[1]!=0) {
1033: x = execute(a[1]);
1034: if (!istrue(x)) return(x);
1035: else tempfree(x);
1036: }
1037: x = execute(a[3]);
1038: if (isbreak(x)) { /* turn off break */
1039: x = true;
1040: return(x);
1041: }
1042: if (isnext(x) || isexit(x) || isret(x))
1043: return(x);
1044: tempfree(x);
1045: x = execute(a[2]);
1046: tempfree(x);
1047: }
1048: }
1049:
1050: int indepth = 0; /* depth of for (i in ...) statements */
1051:
1052: Cell *instat(a, n) Node **a;
1053: {
1054: register Cell *x, *vp, *arrayp, *cp, *ncp, **tp;
1055: int i;
1056:
1057: vp = execute(a[0]);
1058: arrayp = execute(a[1]);
1059: if (!isarr(arrayp))
1060: error(FATAL, "%s is not an array", arrayp->nval);
1061: tp = (Cell **) arrayp->sval;
1062: tempfree(arrayp);
1063: indepth++;
1064: for (i = 0; i < MAXSYM; i++) { /* this routine knows too much */
1065: for (cp = tp[i]; cp != NULL; cp = ncp) {
1066: setsval(vp, cp->nval);
1067: ncp = cp->cnext;
1068: x = execute(a[2]);
1069: if (isbreak(x)) {
1070: tempfree(vp);
1071: x = true;
1072: indepth--;
1073: return(x);
1074: }
1075: if (isnext(x) || isexit(x) || isret(x)) {
1076: tempfree(vp);
1077: indepth--;
1078: return(x);
1079: }
1080: tempfree(x);
1081: }
1082: }
1083: indepth--;
1084: }
1085:
1086: Cell *bltin(a,n) Node **a;
1087: {
1088: register Cell *x, *y;
1089: Awkfloat u;
1090: register int t;
1091:
1092: t = (int) a[0];
1093: x = execute(a[1]);
1094: switch (t) {
1095: case FLENGTH:
1096: u = (Awkfloat) strlen(getsval(x)); break;
1097: case FLOG:
1098: u = errcheck(log(getfval(x)), "log"); break;
1099: case FINT:
1100: u = (Awkfloat) (long) getfval(x); break;
1101: case FEXP:
1102: u = errcheck(exp(getfval(x)), "exp"); break;
1103: case FSQRT:
1104: u = errcheck(sqrt(getfval(x)), "sqrt"); break;
1105: case FSIN:
1106: u = sin(getfval(x)); break;
1107: case FCOS:
1108: u = cos(getfval(x)); break;
1109: case FATAN:
1110: y = execute(a[1]->nnext);
1111: u = atan2(getfval(x), getfval(y));
1112: tempfree(y);
1113: break;
1114: case FSYSTEM:
1115: fflush(stdout); /* in case something buffered already */
1116: u = (Awkfloat) system(getsval(x)) / 256;
1117: break;
1118: case FRAND:
1119: u = (Awkfloat) rand() / 32767.0; break; /* 2^31-1 better on some systems? */
1120: case FSRAND:
1121: if (x->tval & REC)
1122: u = (Awkfloat) srand(time(0));
1123: else
1124: u = (Awkfloat) srand((int)getfval(x));
1125: break;
1126: default:
1127: error(FATAL, "illegal function type %d", t); break;
1128: }
1129: tempfree(x);
1130: x = gettemp();
1131: setfval(x, u);
1132: return(x);
1133: }
1134:
1135: Cell *print(a,n) Node **a;
1136: {
1137: register Node *x;
1138: register Cell *y;
1139: FILE *fp;
1140:
1141: if (a[1] == 0)
1142: fp = stdout;
1143: else
1144: fp = redirect((int)a[1], a[2]);
1145: for (x=a[0]; x!=NULL; x=x->nnext) {
1146: y = execute(x);
1147: fputs(getsval(y), fp);
1148: tempfree(y);
1149: if (x->nnext == NULL)
1150: fputs(*ORS, fp);
1151: else
1152: fputs(*OFS, fp);
1153: }
1154: if (a[1] != 0)
1155: fflush(fp);
1156: return(true);
1157: }
1158:
1159: Cell *nullproc() {}
1160:
1161:
1162: #define FILENUM 15
1163: struct
1164: {
1165: FILE *fp;
1166: char *fname;
1167: int mode; /* '|', 'a', 'w' */
1168: int imode; /* GT, LE, ... */
1169: } files[FILENUM];
1170: FILE *popen();
1171:
1172: FILE *redirect(a, b)
1173: Node *b;
1174: {
1175: FILE *fp;
1176: Cell *x;
1177: char *fname;
1178:
1179: x = execute(b);
1180: fname = getsval(x);
1181: fp = openfile(a, fname);
1182: if (fp == NULL)
1183: error(FATAL, "can't open file %s", fname);
1184: tempfree(x);
1185: return fp;
1186: }
1187:
1188: FILE *openfile(a, s)
1189: char *s;
1190: {
1191: register int i;
1192:
1193: if (*s == '\0')
1194: error(FATAL, "null file name in print or getline");
1195: for (i=0; i < FILENUM; i++)
1196: if (strcmp(s, files[i].fname) == 0 && files[i].imode == a)
1197: return files[i].fp;
1198: for (i=0; i < FILENUM; i++)
1199: if (files[i].fp == 0)
1200: break;
1201: if (i >= FILENUM)
1202: error(FATAL, "%s makes too many open files", s);
1203: if (a == GT) {
1204: files[i].fp = fopen(s, "w");
1205: files[i].mode = 'w';
1206: } else if (a == APPEND) {
1207: files[i].fp = fopen(s, "a");
1208: files[i].mode = 'a';
1209: } else if (a == '|') { /* output pipe */
1210: files[i].fp = popen(s, "w");
1211: files[i].mode = '|';
1212: } else if (a == LE) { /* input pipe */
1213: files[i].fp = popen(s, "r");
1214: files[i].mode = LE;
1215: } else if (a == LT) { /* getline <file */
1216: files[i].fp = fopen(s, "r");
1217: files[i].mode = 'r';
1218: } else
1219: error(FATAL, "illegal redirection");
1220: if (files[i].fp != NULL)
1221: files[i].fname = tostring(s);
1222: files[i].imode = a;
1223: return files[i].fp;
1224: }
1225:
1226:
1227: Cell *closefile(a) Node **a;
1228: {
1229: register Cell *x;
1230: int i;
1231:
1232: x = execute(a[0]);
1233: getsval(x);
1234: for (i = 0; i < FILENUM; i++)
1235: if (strcmp(x->sval, files[i].fname) == 0) {
1236: if (files[i].mode == '|' || files[i].mode == LE)
1237: pclose(files[i].fp);
1238: else
1239: fclose(files[i].fp);
1240: xfree(files[i].fname);
1241: files[i].fname = NULL; /* watch out for ref thru this */
1242: files[i].fp = NULL;
1243: }
1244: return(x);
1245: }
1246:
1247: closeall()
1248: {
1249: int i;
1250:
1251: for (i = 0; i < FILENUM; i++)
1252: if (files[i].fp) {
1253: if (files[i].mode == '|' || files[i].mode == LE)
1254: pclose(files[i].fp);
1255: else
1256: fclose(files[i].fp);
1257: }
1258: }
1259:
1260: Cell *sub(a, nnn) Node **a;
1261: {
1262: register char *sptr, *pb, *q;
1263: register Cell *x, *y;
1264: char buf[RECSIZE], *t;
1265: fa *pfa;
1266:
1267: extern char *patbeg;
1268: extern int patlen;
1269: x = execute(a[3]); /* source string */
1270: t = getsval(x);
1271: if (a[0] == 0)
1272: pfa = (fa *) a[1]; /* regular expression */
1273: else {
1274: y = execute(a[1]);
1275: pfa = makedfa(reparse(getsval(y)), 1);
1276: tempfree(y);
1277: }
1278: if (pmatch(pfa, t)) {
1279: pb = buf;
1280: sptr = t;
1281: while (sptr < patbeg)
1282: *pb++ = *sptr++;
1283: y = execute(a[2]); /* replacement */
1284: sptr = getsval(y);
1285: while (*sptr != 0)
1286: if (*sptr == '\\' && *(sptr+1) == '&') {
1287: sptr++; /* skip \, */
1288: *pb++ = *sptr++; /* add & */
1289: } else if (*sptr == '&') {
1290: sptr++;
1291: for (q = patbeg; q < patbeg+patlen; )
1292: *pb++ = *q++;
1293: } else
1294: *pb++ = *sptr++;
1295: tempfree(y);
1296: sptr = patbeg + patlen;
1297: while (*pb++ = *sptr++)
1298: ;
1299: setsval(x, buf);
1300: tempfree(x);
1301: return (true);
1302: }
1303: tempfree(x);
1304: return (false);
1305: }
1306:
1307: Cell *gsub(a, nnn) Node **a;
1308: {
1309: register Cell *x, *y;
1310: register char *rptr, *sptr, *t, *pb;
1311: char buf[RECSIZE];
1312: register fa *pfa;
1313: int mflag, tempstat, num;
1314:
1315: extern char *patbeg;
1316: extern int patlen;
1317:
1318: mflag = 0;
1319: num = 0;
1320: x = execute(a[3]);
1321: t = getsval(x);
1322: if (a[0] == 0)
1323: pfa = (fa *) a[1];
1324: else {
1325: y = execute(a[1]);
1326: pfa = makedfa(reparse(getsval(y)), 1);
1327: tempfree(y);
1328: }
1329: if (pmatch(pfa, t)) {
1330: tempstat = pfa->initstat;
1331: pfa->initstat = 2;
1332: pb = buf;
1333: y = execute(a[2]);
1334: rptr = getsval(y);
1335: do {
1336: /*
1337: char *p;
1338: int i;
1339: printf("target string: %s, *patbeg = %c, patlen = %d\n", t, *patbeg, patlen);
1340: printf(" match found: ");
1341: p=patbeg;
1342: for (i=0; i<patlen; i++)
1343: printf("%c", *p++);
1344: printf("\n");
1345: */
1346: num++;
1347: if (patlen == 0) { /* matched empty string */
1348: if (mflag == 0) { /* can replace empty */
1349: sptr = rptr;
1350: while (*sptr != 0)
1351: if (*sptr == '\\' && *(sptr+1) == '&') {
1352: sptr++;
1353: *pb++ = *sptr++;
1354: } else if (*sptr == '&') {
1355: char *q;
1356: sptr++;
1357: for (q = patbeg; q < patbeg+patlen; )
1358: *pb++ = *q++;
1359: } else
1360: *pb++ = *sptr++;
1361: }
1362: *pb++ = *t;
1363: if (*t == 0) /* at end */
1364: goto done;
1365: t++;
1366: mflag = 0;
1367: }
1368: else { /* matched nonempty string */
1369: if (*t == 0) { /* matched $ */
1370: if (mflag == 0) { /* can replace empty */
1371: sptr = rptr;
1372: while (*sptr != 0)
1373: if (*sptr == '\\' && *(sptr+1) == '&') {
1374: sptr++;
1375: *pb++ = *sptr++;
1376: } else if (*sptr == '&') {
1377: char *q;
1378: sptr++;
1379: for (q = patbeg; q < patbeg+patlen; )
1380: *pb++ = *q++;
1381: } else
1382: *pb++ = *sptr++;
1383: }
1384: *pb++ = 0;
1385: goto done;
1386: }
1387: sptr = t;
1388: while (sptr < patbeg)
1389: *pb++ = *sptr++;
1390: sptr = rptr;
1391: while (*sptr != 0)
1392: if (*sptr == '\\' && *(sptr+1) == '&') {
1393: sptr++;
1394: *pb++ = *sptr++;
1395: } else if (*sptr == '&') {
1396: char *q;
1397: sptr++;
1398: for (q = patbeg; q < patbeg+patlen; )
1399: *pb++ = *q++;
1400: } else
1401: *pb++ = *sptr++;
1402: mflag = 1;
1403: t = patbeg + patlen;
1404: if (*t == 0) {
1405: *pb = 0;
1406: goto done;
1407: }
1408: }
1409: } while (pmatch(pfa,t));
1410: sptr = t;
1411: while (*pb++ = *sptr++)
1412: ;
1413: done: tempfree(y);
1414: setsval(x, buf);
1415: pfa->initstat = tempstat;
1416: }
1417: tempfree(x);
1418: x = gettemp();
1419: x->tval = NUM;
1420: x->fval = num;
1421: return(x);
1422: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.