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