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