|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)run.c 4.4 8/11/83";
3: #endif
4:
5: #include "awk.def"
6: #include "math.h"
7: #include "awk.h"
8: #include "stdio.h"
9: #define RECSIZE BUFSIZ
10:
11: #define FILENUM 10
12: struct
13: {
14: FILE *fp;
15: char *fname;
16: } files[FILENUM];
17: FILE *popen();
18:
19: extern obj execute(), nodetoobj(), fieldel(), dopa2(), gettemp();
20: #define PA2NUM 29
21: int pairstack[PA2NUM], paircnt;
22: node *winner = (node *)NULL;
23: #define MAXTMP 20
24: cell tmps[MAXTMP];
25: static cell nullval ={EMPTY,EMPTY,0.0,NUM,0};
26: obj true ={ OBOOL, BTRUE, 0 };
27: obj false ={ OBOOL, BFALSE, 0 };
28:
29: run()
30: {
31: execute(winner);
32: }
33:
34: obj execute(u) node *u;
35: {
36: register obj (*proc)();
37: obj x;
38: node *a;
39: extern char *printname[];
40:
41: if (u==(node *)NULL)
42: return(true);
43: for (a = u; ; a = a->nnext) {
44: if (cantexec(a))
45: return(nodetoobj(a));
46: if (a->ntype==NPA2)
47: proc=dopa2;
48: else {
49: if (notlegal(a->nobj))
50: error(FATAL, "illegal statement %o", a);
51: proc = proctab[a->nobj-FIRSTTOKEN];
52: }
53: x = (*proc)(a->narg,a->nobj);
54: if (isfld(x)) fldbld();
55: if (isexpr(a))
56: return(x);
57: /* a statement, goto next statement */
58: if (isjump(x))
59: return(x);
60: if (a->nnext == (node *)NULL)
61: return(x);
62: tempfree(x);
63: }
64: }
65:
66: obj program(a, n) node **a;
67: {
68: obj x;
69:
70: if (a[0] != NULL) {
71: x = execute(a[0]);
72: if (isexit(x))
73: return(true);
74: if (isjump(x))
75: error(FATAL, "unexpected break, continue or next");
76: tempfree(x);
77: }
78: while (getrec()) {
79: x = execute(a[1]);
80: if (isexit(x)) break;
81: tempfree(x);
82: }
83: tempfree(x);
84: if (a[2] != NULL) {
85: x = execute(a[2]);
86: if (isbreak(x) || isnext(x) || iscont(x))
87: error(FATAL, "unexpected break, continue or next");
88: tempfree(x);
89: }
90: return(true);
91: }
92:
93: obj getline()
94: {
95: obj x;
96:
97: x = gettemp();
98: setfval(x.optr, (awkfloat) getrec());
99: return(x);
100: }
101:
102: obj array(a,n) node **a;
103: {
104: obj x, y;
105: extern obj arrayel();
106:
107: x = execute(a[1]);
108: y = arrayel(a[0], x);
109: tempfree(x);
110: return(y);
111: }
112:
113: obj arrayel(a,b) node *a; obj b;
114: {
115: char *s;
116: cell *x;
117: int i;
118: obj y;
119:
120: s = getsval(b.optr);
121: x = (cell *) a;
122: if (!(x->tval&ARR)) {
123: strfree(x->sval);
124: x->tval &= ~STR;
125: x->tval |= ARR;
126: x->sval = (char *) makesymtab();
127: }
128: y.optr = setsymtab(s, tostring(""), 0.0, STR|NUM, x->sval);
129: y.otype = OCELL;
130: y.osub = CVAR;
131: return(y);
132: }
133:
134: obj matchop(a,n) node **a;
135: {
136: obj x;
137: char *s;
138: int i;
139:
140: x = execute(a[0]);
141: if (isstr(x)) s = x.optr->sval;
142: else s = getsval(x.optr);
143: tempfree(x);
144: i = match(a[1], s);
145: if (n==MATCH && i==1 || n==NOTMATCH && i==0)
146: return(true);
147: else
148: return(false);
149: }
150:
151: obj boolop(a,n) node **a;
152: {
153: obj x, y;
154: int i;
155:
156: x = execute(a[0]);
157: i = istrue(x);
158: tempfree(x);
159: switch (n) {
160: default:
161: error(FATAL, "unknown boolean operator %d", n);
162: case BOR:
163: if (i) return(true);
164: y = execute(a[1]);
165: i = istrue(y);
166: tempfree(y);
167: if (i) return(true);
168: else return(false);
169: case AND:
170: if ( !i ) return(false);
171: y = execute(a[1]);
172: i = istrue(y);
173: tempfree(y);
174: if (i) return(true);
175: else return(false);
176: case NOT:
177: if (i) return(false);
178: else return(true);
179: }
180: }
181:
182: obj relop(a,n) node **a;
183: {
184: int i;
185: obj x, y;
186: awkfloat j;
187:
188: x = execute(a[0]);
189: y = execute(a[1]);
190: if (x.optr->tval&NUM && y.optr->tval&NUM) {
191: j = x.optr->fval - y.optr->fval;
192: i = j<0? -1: (j>0? 1: 0);
193: } else {
194: i = strcmp(getsval(x.optr), getsval(y.optr));
195: }
196: tempfree(x);
197: tempfree(y);
198: switch (n) {
199: default:
200: error(FATAL, "unknown relational operator %d", n);
201: case LT: if (i<0) return(true);
202: else return(false);
203: case LE: if (i<=0) return(true);
204: else return(false);
205: case NE: if (i!=0) return(true);
206: else return(false);
207: case EQ: if (i==0) return(true);
208: else return(false);
209: case GE: if (i>=0) return(true);
210: else return(false);
211: case GT: if (i>0) return(true);
212: else return(false);
213: }
214: }
215:
216: tempfree(a) obj a;
217: {
218: if (!istemp(a)) return;
219: strfree(a.optr->sval);
220: a.optr->tval = 0;
221: }
222:
223: obj gettemp()
224: {
225: int i;
226: obj x;
227:
228: for (i=0; i<MAXTMP; i++)
229: if (tmps[i].tval==0)
230: break;
231: if (i==MAXTMP)
232: error(FATAL, "out of temporaries in gettemp");
233: x.optr = &tmps[i];
234: tmps[i] = nullval;
235: x.otype = OCELL;
236: x.osub = CTEMP;
237: return(x);
238: }
239:
240: obj indirect(a,n) node **a;
241: {
242: obj x;
243: int m;
244: cell *fieldadr();
245:
246: x = execute(a[0]);
247: m = getfval(x.optr);
248: tempfree(x);
249: x.optr = fieldadr(m);
250: x.otype = OCELL;
251: x.osub = CFLD;
252: return(x);
253: }
254:
255: obj substr(a, nnn) node **a;
256: {
257: char *s, temp;
258: obj x;
259: int k, m, n;
260:
261: x = execute(a[0]);
262: s = getsval(x.optr);
263: k = strlen(s) + 1;
264: tempfree(x);
265: x = execute(a[1]);
266: m = getfval(x.optr);
267: if (m <= 0)
268: m = 1;
269: else if (m > k)
270: m = k;
271: tempfree(x);
272: if (a[2] != nullstat) {
273: x = execute(a[2]);
274: n = getfval(x.optr);
275: tempfree(x);
276: }
277: else
278: n = k - 1;
279: if (n < 0)
280: n = 0;
281: else if (n > k - m)
282: n = k - m;
283: dprintf("substr: m=%d, n=%d, s=%s\n", m, n, s);
284: x = gettemp();
285: temp = s[n+m-1]; /* with thanks to John Linderman */
286: s[n+m-1] = '\0';
287: setsval(x.optr, s + m - 1);
288: s[n+m-1] = temp;
289: return(x);
290: }
291:
292: obj sindex(a, nnn) node **a;
293: {
294: obj x;
295: char *s1, *s2, *p1, *p2, *q;
296:
297: x = execute(a[0]);
298: s1 = getsval(x.optr);
299: tempfree(x);
300: x = execute(a[1]);
301: s2 = getsval(x.optr);
302: tempfree(x);
303:
304: x = gettemp();
305: for (p1 = s1; *p1 != '\0'; p1++) {
306: for (q=p1, p2=s2; *p2 != '\0' && *q == *p2; q++, p2++)
307: ;
308: if (*p2 == '\0') {
309: setfval(x.optr, (awkfloat) (p1 - s1 + 1)); /* origin 1 */
310: return(x);
311: }
312: }
313: setfval(x.optr, 0.0);
314: return(x);
315: }
316:
317: char *format(s,a) char *s; node *a;
318: {
319: char *buf, *p, fmt[200], *t, *os;
320: obj x;
321: int flag = 0;
322: awkfloat xf;
323:
324: os = s;
325: p = buf = (char *)malloc(RECSIZE);
326: while (*s) {
327: if (*s != '%') {
328: *p++ = *s++;
329: continue;
330: }
331: if (*(s+1) == '%') {
332: *p++ = '%';
333: s += 2;
334: continue;
335: }
336: for (t=fmt; (*t++ = *s) != '\0'; s++)
337: if (*s >= 'a' && *s <= 'z' && *s != 'l')
338: break;
339: *t = '\0';
340: if (t >= fmt + sizeof(fmt))
341: error(FATAL, "format item %.20s... too long", os);
342: switch (*s) {
343: case 'f': case 'e': case 'g':
344: flag = 1;
345: break;
346: case 'd':
347: flag = 2;
348: if(*(s-1) == 'l') break;
349: *(t-1) = 'l';
350: *t = 'd';
351: *++t = '\0';
352: break;
353: case 'o': case 'x':
354: flag = *(s-1)=='l' ? 2 : 3;
355: break;
356: case 'c':
357: flag = 3;
358: break;
359: case 's':
360: flag = 4;
361: break;
362: default:
363: flag = 0;
364: break;
365: }
366: if (flag == 0) {
367: sprintf(p, "%s", fmt);
368: p += strlen(p);
369: continue;
370: }
371: if (a == NULL)
372: error(FATAL, "not enough arguments in printf(%s)", os);
373: x = execute(a);
374: a = a->nnext;
375: if (flag != 4) /* watch out for converting to numbers! */
376: xf = getfval(x.optr);
377: if (flag==1) sprintf(p, fmt, xf);
378: else if (flag==2) sprintf(p, fmt, (long)xf);
379: else if (flag==3) sprintf(p, fmt, (int)xf);
380: else if (flag==4) sprintf(p, fmt, x.optr->sval==NULL ? "" : getsval(x.optr));
381: tempfree(x);
382: p += strlen(p);
383: s++;
384: }
385: *p = '\0';
386: return(buf);
387: }
388:
389: obj asprintf(a,n) node **a;
390: {
391: obj x;
392: node *y;
393: char *s;
394:
395: y = a[0]->nnext;
396: x = execute(a[0]);
397: s = format(getsval(x.optr), y);
398: tempfree(x);
399: x = gettemp();
400: x.optr->sval = s;
401: x.optr->tval = STR;
402: return(x);
403: }
404:
405: obj arith(a,n) node **a;
406: {
407: awkfloat i,j;
408: obj x,y,z;
409:
410: x = execute(a[0]);
411: i = getfval(x.optr);
412: tempfree(x);
413: if (n != UMINUS) {
414: y = execute(a[1]);
415: j = getfval(y.optr);
416: tempfree(y);
417: }
418: z = gettemp();
419: switch (n) {
420: default:
421: error(FATAL, "illegal arithmetic operator %d", n);
422: case ADD:
423: i += j;
424: break;
425: case MINUS:
426: i -= j;
427: break;
428: case MULT:
429: i *= j;
430: break;
431: case DIVIDE:
432: if (j == 0)
433: error(FATAL, "division by zero");
434: i /= j;
435: break;
436: case MOD:
437: if (j == 0)
438: error(FATAL, "division by zero");
439: i = i - j*(long)(i/j);
440: break;
441: case UMINUS:
442: i = -i;
443: break;
444: }
445: setfval(z.optr, i);
446: return(z);
447: }
448:
449: obj incrdecr(a, n) node **a;
450: {
451: obj x, z;
452: int k;
453: awkfloat xf;
454:
455: x = execute(a[0]);
456: xf = getfval(x.optr);
457: k = (n == PREINCR || n == POSTINCR) ? 1 : -1;
458: if (n == PREINCR || n == PREDECR) {
459: setfval(x.optr, xf + k);
460: return(x);
461: }
462: z = gettemp();
463: setfval(z.optr, xf);
464: setfval(x.optr, xf + k);
465: tempfree(x);
466: return(z);
467: }
468:
469:
470: obj assign(a,n) node **a;
471: {
472: obj x, y;
473: awkfloat xf, yf;
474:
475: x = execute(a[0]);
476: y = execute(a[1]);
477: if (n == ASSIGN) { /* ordinary assignment */
478: if ((y.optr->tval & (STR|NUM)) == (STR|NUM)) {
479: setsval(x.optr, y.optr->sval);
480: x.optr->fval = y.optr->fval;
481: x.optr->tval |= NUM;
482: }
483: else if (y.optr->tval & STR)
484: setsval(x.optr, y.optr->sval);
485: else if (y.optr->tval & NUM)
486: setfval(x.optr, y.optr->fval);
487: tempfree(y);
488: return(x);
489: }
490: xf = getfval(x.optr);
491: yf = getfval(y.optr);
492: switch (n) {
493: case ADDEQ:
494: xf += yf;
495: break;
496: case SUBEQ:
497: xf -= yf;
498: break;
499: case MULTEQ:
500: xf *= yf;
501: break;
502: case DIVEQ:
503: if (yf == 0)
504: error(FATAL, "division by zero");
505: xf /= yf;
506: break;
507: case MODEQ:
508: if (yf == 0)
509: error(FATAL, "division by zero");
510: xf = xf - yf*(long)(xf/yf);
511: break;
512: default:
513: error(FATAL, "illegal assignment operator %d", n);
514: break;
515: }
516: tempfree(y);
517: setfval(x.optr, xf);
518: return(x);
519: }
520:
521: obj cat(a,q) node **a;
522: {
523: obj x,y,z;
524: int n1, n2;
525: char *s;
526:
527: x = execute(a[0]);
528: y = execute(a[1]);
529: getsval(x.optr);
530: getsval(y.optr);
531: n1 = strlen(x.optr->sval);
532: n2 = strlen(y.optr->sval);
533: s = (char *) malloc(n1 + n2 + 1);
534: strcpy(s, x.optr->sval);
535: strcpy(s+n1, y.optr->sval);
536: tempfree(y);
537: z = gettemp();
538: z.optr->sval = s;
539: z.optr->tval = STR;
540: tempfree(x);
541: return(z);
542: }
543:
544: obj pastat(a,n) node **a;
545: {
546: obj x;
547:
548: if (a[0]==nullstat)
549: x = true;
550: else
551: x = execute(a[0]);
552: if (istrue(x)) {
553: tempfree(x);
554: x = execute(a[1]);
555: }
556: return(x);
557: }
558:
559: obj dopa2(a,n) node **a;
560: {
561: obj x;
562:
563: if (pairstack[n]==0) {
564: x = execute(a[0]);
565: if (istrue(x))
566: pairstack[n] = 1;
567: tempfree(x);
568: }
569: if (pairstack[n] == 1) {
570: x = execute(a[1]);
571: if (istrue(x))
572: pairstack[n] = 0;
573: tempfree(x);
574: x = execute(a[2]);
575: return(x);
576: }
577: return(false);
578: }
579:
580: obj aprintf(a,n) node **a;
581: {
582: obj x;
583:
584: x = asprintf(a,n);
585: if (a[1]==NULL) {
586: printf("%s", x.optr->sval);
587: tempfree(x);
588: return(true);
589: }
590: redirprint(x.optr->sval, (int)a[1], a[2]);
591: return(x);
592: }
593:
594: obj split(a,nnn) node **a;
595: {
596: obj x;
597: cell *ap;
598: register char *s, *p;
599: char *t, temp, num[5];
600: register int sep;
601: int n, flag;
602:
603: x = execute(a[0]);
604: s = getsval(x.optr);
605: tempfree(x);
606: if (a[2] == nullstat)
607: sep = **FS;
608: else {
609: x = execute(a[2]);
610: sep = getsval(x.optr)[0];
611: tempfree(x);
612: }
613: ap = (cell *) a[1];
614: freesymtab(ap);
615: dprintf("split: s=|%s|, a=%s, sep=|%c|\n", s, ap->nval, sep);
616: ap->tval &= ~STR;
617: ap->tval |= ARR;
618: ap->sval = (char *) makesymtab();
619:
620: n = 0;
621: if (sep == ' ')
622: for (n = 0; ; ) {
623: while (*s == ' ' || *s == '\t' || *s == '\n')
624: s++;
625: if (*s == 0)
626: break;
627: n++;
628: t = s;
629: do
630: s++;
631: while (*s!=' ' && *s!='\t' && *s!='\n' && *s!='\0');
632: temp = *s;
633: *s = '\0';
634: sprintf(num, "%d", n);
635: if (isnumber(t))
636: setsymtab(num, tostring(t), atof(t), STR|NUM, ap->sval);
637: else
638: setsymtab(num, tostring(t), 0.0, STR, ap->sval);
639: *s = temp;
640: if (*s != 0)
641: s++;
642: }
643: else if (*s != 0)
644: for (;;) {
645: n++;
646: t = s;
647: while (*s != sep && *s != '\n' && *s != '\0')
648: s++;
649: temp = *s;
650: *s = '\0';
651: sprintf(num, "%d", n);
652: if (isnumber(t))
653: setsymtab(num, tostring(t), atof(t), STR|NUM, ap->sval);
654: else
655: setsymtab(num, tostring(t), 0.0, STR, ap->sval);
656: *s = temp;
657: if (*s++ == 0)
658: break;
659: }
660: x = gettemp();
661: x.optr->tval = NUM;
662: x.optr->fval = n;
663: return(x);
664: }
665:
666: obj ifstat(a,n) node **a;
667: {
668: obj x;
669:
670: x = execute(a[0]);
671: if (istrue(x)) {
672: tempfree(x);
673: x = execute(a[1]);
674: }
675: else if (a[2] != nullstat) {
676: tempfree(x);
677: x = execute(a[2]);
678: }
679: return(x);
680: }
681:
682: obj whilestat(a,n) node **a;
683: {
684: obj x;
685:
686: for (;;) {
687: x = execute(a[0]);
688: if (!istrue(x)) return(x);
689: tempfree(x);
690: x = execute(a[1]);
691: if (isbreak(x)) {
692: x = true;
693: return(x);
694: }
695: if (isnext(x) || isexit(x))
696: return(x);
697: tempfree(x);
698: }
699: }
700:
701: obj forstat(a,n) node **a;
702: {
703: obj x;
704:
705: tempfree(execute(a[0]));
706: for (;;) {
707: if (a[1]!=nullstat) {
708: x = execute(a[1]);
709: if (!istrue(x)) return(x);
710: else tempfree(x);
711: }
712: x = execute(a[3]);
713: if (isbreak(x)) { /* turn off break */
714: x = true;
715: return(x);
716: }
717: if (isnext(x) || isexit(x))
718: return(x);
719: tempfree(x);
720: tempfree(execute(a[2]));
721: }
722: }
723:
724: obj instat(a, n) node **a;
725: {
726: cell *vp, *arrayp, *cp, **tp;
727: obj x;
728: int i;
729:
730: vp = (cell *) a[0];
731: arrayp = (cell *) a[1];
732: if (!(arrayp->tval & ARR))
733: error(FATAL, "%s is not an array", arrayp->nval);
734: tp = (cell **) arrayp->sval;
735: for (i = 0; i < MAXSYM; i++) { /* this routine knows too much */
736: for (cp = tp[i]; cp != NULL; cp = cp->nextval) {
737: setsval(vp, cp->nval);
738: x = execute(a[2]);
739: if (isbreak(x)) {
740: x = true;
741: return(x);
742: }
743: if (isnext(x) || isexit(x))
744: return(x);
745: tempfree(x);
746: }
747: }
748: return (true);
749: }
750:
751: obj jump(a,n) node **a;
752: {
753: obj x, y;
754:
755: x.otype = OJUMP;
756: switch (n) {
757: default:
758: error(FATAL, "illegal jump type %d", n);
759: break;
760: case EXIT:
761: if (a[0] != 0) {
762: y = execute(a[0]);
763: errorflag = getfval(y.optr);
764: }
765: x.osub = JEXIT;
766: break;
767: case NEXT:
768: x.osub = JNEXT;
769: break;
770: case BREAK:
771: x.osub = JBREAK;
772: break;
773: case CONTINUE:
774: x.osub = JCONT;
775: break;
776: }
777: return(x);
778: }
779:
780: obj fncn(a,n) node **a;
781: {
782: obj x;
783: awkfloat u;
784: int t;
785:
786: t = (int) a[0];
787: x = execute(a[1]);
788: if (t == FLENGTH)
789: u = (awkfloat) strlen(getsval(x.optr));
790: else if (t == FLOG)
791: u = log(getfval(x.optr));
792: else if (t == FINT)
793: u = (awkfloat) (long) getfval(x.optr);
794: else if (t == FEXP)
795: u = exp(getfval(x.optr));
796: else if (t == FSQRT)
797: u = sqrt(getfval(x.optr));
798: else
799: error(FATAL, "illegal function type %d", t);
800: tempfree(x);
801: x = gettemp();
802: setfval(x.optr, u);
803: return(x);
804: }
805:
806: obj print(a,n) node **a;
807: {
808: register node *x;
809: obj y;
810: char s[RECSIZE];
811:
812: s[0] = '\0';
813: for (x=a[0]; x!=NULL; x=x->nnext) {
814: y = execute(x);
815: strcat(s, getsval(y.optr));
816: tempfree(y);
817: if (x->nnext==NULL)
818: strcat(s, *ORS);
819: else
820: strcat(s, *OFS);
821: }
822: if (strlen(s) >= RECSIZE)
823: error(FATAL, "string %.20s ... too long to print", s);
824: if (a[1]==nullstat) {
825: printf("%s", s);
826: return(true);
827: }
828: redirprint(s, (int)a[1], a[2]);
829: return(false);
830: }
831:
832: obj nullproc() {}
833:
834: obj nodetoobj(a) node *a;
835: {
836: obj x;
837:
838: x.optr = (cell *) a->nobj;
839: x.otype = OCELL;
840: x.osub = a->subtype;
841: if (isfld(x)) fldbld();
842: return(x);
843: }
844:
845: redirprint(s, a, b) char *s; node *b;
846: {
847: register int i;
848: obj x;
849:
850: x = execute(b);
851: getsval(x.optr);
852: for (i=0; i<FILENUM; i++)
853: if (files[i].fp && strcmp(x.optr->sval, files[i].fname) == 0)
854: goto doit;
855: for (i=0; i<FILENUM; i++)
856: if (files[i].fp == 0)
857: break;
858: if (i >= FILENUM)
859: error(FATAL, "too many output files %d", i);
860: if (a == '|') /* a pipe! */
861: files[i].fp = popen(x.optr->sval, "w");
862: else if (a == APPEND)
863: files[i].fp = fopen(x.optr->sval, "a");
864: else
865: files[i].fp = fopen(x.optr->sval, "w");
866: if (files[i].fp == NULL)
867: error(FATAL, "can't open file %s", x.optr->sval);
868: files[i].fname = tostring(x.optr->sval);
869: doit:
870: fprintf(files[i].fp, "%s", s);
871: #ifndef gcos
872: fflush(files[i].fp); /* in case someone is waiting for the output */
873: #endif
874: tempfree(x);
875: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.