|
|
1.1 root 1: #define DEBUG
2: #include <stdio.h>
3: #include <ctype.h>
4: #include <errno.h>
5: #include "awk.h"
6: #include "y.tab.h"
7:
8: #define getfval(p) (((p)->tval & (ARR|FLD|REC|NUM)) == NUM ? (p)->fval : r_getfval(p))
9: #define getsval(p) (((p)->tval & (ARR|FLD|REC|STR)) == STR ? (p)->sval : r_getsval(p))
10:
11: extern Awkfloat r_getfval();
12: extern uchar *r_getsval();
13:
14: FILE *infile = NULL;
15: uchar *file = (uchar*) "";
16: uchar recdata[RECSIZE];
17: uchar *record = recdata;
18: uchar fields[RECSIZE];
19:
20: #define MAXFLD 100
21: int donefld; /* 1 = implies rec broken into fields */
22: int donerec; /* 1 = record is valid (no flds have changed) */
23:
24: #define FINIT { OCELL, CFLD, NULL, (uchar*) "", 0.0, FLD|STR|DONTFREE }
25:
26: Cell fldtab[MAXFLD] = { /* room for fields */
27: { OCELL, CFLD, (uchar*) "$0", recdata, 0.0, REC|STR|DONTFREE},
28: FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT,
29: FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT,
30: FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT,
31: FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT,
32: FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT,
33: FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT,
34: FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT,
35: FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT,
36: FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT,
37: FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT,
38: };
39: int maxfld = 0; /* last used field */
40: int argno = 1; /* current input argument number */
41:
42: initgetrec()
43: {
44: infile = stdin;
45: *FILENAME = file = (uchar*) "-";
46: }
47:
48: getrec(buf)
49: uchar *buf;
50: {
51: uchar *getargv();
52: int c;
53: extern Awkfloat *ARGC;
54:
55: dprintf("RS=<%s>, FS=<%s>\n", *RS, *FS);
56: donefld = 0;
57: donerec = 1;
58: buf[0] = 0;
59: while (argno < *ARGC || infile == stdin) {
60: dprintf("argno=%d, file=|%s|\n", argno, file);
61: if (infile == NULL) { /* have to open a new file */
62: file = getargv(argno);
63: if (*file == '\0') { /* it's been zapped */
64: argno++;
65: continue;
66: }
67: if (isclvar(file)) { /* a var=value arg */
68: setclvar(file);
69: argno++;
70: continue;
71: }
72: *FILENAME = file;
73: dprintf("opening file %s\n", file);
74: if (*file == '-' && *(file+1) == '\0')
75: infile = stdin;
76: else if ((infile = fopen(file, "r")) == NULL)
77: error(FATAL, "can't open %s", file);
78: setfval(fnrloc, 0.0);
79: }
80: c = readrec(buf, RECSIZE, infile);
81: if (c != 0 || buf[0] != '\0') { /* normal record */
82: if (buf == record) {
83: if (!(recloc->tval & DONTFREE))
84: xfree(recloc->sval);
85: recloc->sval = record;
86: recloc->tval = REC | STR | DONTFREE;
87: if (isnumber(recloc->sval)) {
88: recloc->fval = atof(recloc->sval);
89: recloc->tval |= NUM;
90: }
91: }
92: setfval(nrloc, nrloc->fval+1);
93: setfval(fnrloc, fnrloc->fval+1);
94: return 1;
95: }
96: /* EOF arrived on this file; set up next */
97: if (infile != stdin)
98: fclose(infile);
99: infile = NULL;
100: argno++;
101: }
102: return 0; /* true end of file */
103: }
104:
105: readrec(buf, bufsize, inf) /* read one record into buf */
106: uchar *buf;
107: int bufsize;
108: FILE *inf;
109: {
110: register int sep, c;
111: register uchar *rr;
112:
113: if ((sep = **RS) == 0) {
114: sep = '\n';
115: while ((c=getc(inf)) == '\n' && c != EOF) /* skip leading \n's */
116: ;
117: if (c != EOF)
118: ungetc(c, inf);
119: }
120: for (rr = buf; ; ) {
121: for (; (c=getc(inf)) != sep && c != EOF; *rr++ = c)
122: ;
123: if (**RS == sep || c == EOF)
124: break;
125: if ((c = getc(inf)) == '\n' || c == EOF) /* 2 in a row */
126: break;
127: *rr++ = '\n';
128: *rr++ = c;
129: }
130: if (rr > buf + bufsize)
131: error(FATAL, "input record `%.20s...' too long", buf);
132: *rr = 0;
133: dprintf("readrec saw <%s>, returns %d\n", buf, c == EOF && rr == buf ? 0 : 1);
134: return c == EOF && rr == buf ? 0 : 1;
135: }
136:
137: uchar *getargv(n) /* get ARGV[n] */
138: int n;
139: {
140: Cell *x;
141: uchar *s, temp[10];
142: extern Array *ARGVtab;
143:
144: sprintf(temp, "%d", n);
145: x = setsymtab(temp, "", 0.0, STR, ARGVtab);
146: s = getsval(x);
147: dprintf("getargv(%d) returns |%s|\n", n, s, NULL);
148: return s;
149: }
150:
151: setclvar(s) /* set var=value from s */
152: uchar *s;
153: {
154: uchar *p;
155: Cell *q;
156:
157: for (p=s; *p != '='; p++)
158: ;
159: *p++ = 0;
160: p = qstring(p, '\0');
161: q = setsymtab(s, p, 0.0, STR, symtab);
162: setsval(q, p);
163: if (isnumber(q->sval)) {
164: q->fval = atof(q->sval);
165: q->tval |= NUM;
166: }
167: dprintf("command line set %s to |%s|\n", s, p, NULL);
168: }
169:
170:
171: fldbld()
172: {
173: register uchar *r, *fr, sep;
174: Cell *p;
175: int i;
176:
177: if (donefld)
178: return;
179: if (!(recloc->tval & STR))
180: getsval(recloc);
181: r = recloc->sval; /* was record! */
182: fr = fields;
183: i = 0; /* number of fields accumulated here */
184: if (strlen(*FS) > 1) { /* it's a regular expression */
185: i = refldbld(r, *FS);
186: } else if ((sep = **FS) == ' ') {
187: for (i = 0; ; ) {
188: while (*r == ' ' || *r == '\t' || *r == '\n')
189: r++;
190: if (*r == 0)
191: break;
192: i++;
193: if (i >= MAXFLD)
194: break;
195: if (!(fldtab[i].tval & DONTFREE))
196: xfree(fldtab[i].sval);
197: fldtab[i].sval = fr;
198: fldtab[i].tval = FLD | STR | DONTFREE;
199: do
200: *fr++ = *r++;
201: while (*r != ' ' && *r != '\t' && *r != '\n' && *r != '\0');
202: *fr++ = 0;
203: }
204: *fr = 0;
205: } else if (*r != 0) { /* if 0, it's a null field */
206: for (;;) {
207: i++;
208: if (i >= MAXFLD)
209: break;
210: if (!(fldtab[i].tval & DONTFREE))
211: xfree(fldtab[i].sval);
212: fldtab[i].sval = fr;
213: fldtab[i].tval = FLD | STR | DONTFREE;
214: while (*r != sep && *r != '\n' && *r != '\0') /* \n always a separator */
215: *fr++ = *r++;
216: *fr++ = 0;
217: if (*r++ == 0)
218: break;
219: }
220: *fr = 0;
221: }
222: if (i >= MAXFLD)
223: error(FATAL, "record `%.20s...' has too many fields", record);
224: /* clean out junk from previous record */
225: cleanfld(i, maxfld);
226: maxfld = i;
227: donefld = 1;
228: for (p = fldtab+1; p <= fldtab+maxfld; p++) {
229: if(isnumber(p->sval)) {
230: p->fval = atof(p->sval);
231: p->tval |= NUM;
232: }
233: }
234: setfval(nfloc, (Awkfloat) maxfld);
235: if (dbg)
236: for (p = fldtab; p <= fldtab+maxfld; p++)
237: printf("field %d: |%s|\n", p-fldtab, p->sval);
238: }
239:
240: cleanfld(n1, n2) /* clean out fields n1..n2 inclusive */
241: {
242: static uchar *nullstat = (uchar *) "";
243: register Cell *p, *q;
244:
245: for (p = &fldtab[n2], q = &fldtab[n1]; p > q; p--) {
246: if (!(p->tval & DONTFREE))
247: xfree(p->sval);
248: p->tval = FLD | STR | DONTFREE;
249: p->sval = nullstat;
250: }
251: }
252:
253: newfld(n) /* add field n (after end) */
254: {
255: if (n >= MAXFLD)
256: error(FATAL, "creating too many fields", record);
257: cleanfld(maxfld, n);
258: maxfld = n;
259: setfval(nfloc, (Awkfloat) n);
260: }
261:
262: refldbld(rec, fs) /* build fields from reg expr in FS */
263: uchar *rec, *fs;
264: {
265: fa *makedfa();
266: uchar *fr;
267: int i, tempstat;
268: fa *pfa;
269:
270: fr = fields;
271: *fr = '\0';
272: if (*rec == '\0')
273: return 0;
274: pfa = makedfa(fs, 1);
275: dprintf("into refldbld, rec = <%s>, pat = <%s>\n", rec, fs);
276: tempstat = pfa->initstat;
277: for (i = 1; i < MAXFLD; i++) {
278: if (!(fldtab[i].tval & DONTFREE))
279: xfree(fldtab[i].sval);
280: fldtab[i].tval = FLD | STR | DONTFREE;
281: fldtab[i].sval = fr;
282: dprintf("refldbld: i=%d\n", i);
283: if (nematch(pfa, rec)) {
284: pfa->initstat = 2;
285: dprintf("match %s (%d chars)\n", patbeg, patlen);
286: strncpy(fr, rec, patbeg-rec);
287: fr += patbeg - rec + 1;
288: *(fr-1) = '\0';
289: rec = patbeg + patlen;
290: } else {
291: dprintf("no match %s\n", rec);
292: strcpy(fr, rec);
293: pfa->initstat = tempstat;
294: break;
295: }
296: }
297: return i;
298: }
299:
300: recbld()
301: {
302: int i;
303: register uchar *r, *p;
304: static uchar rec[RECSIZE];
305:
306: if (donerec == 1)
307: return;
308: r = rec;
309: for (i = 1; i <= *NF; i++) {
310: p = getsval(&fldtab[i]);
311: while (*r = *p++)
312: r++;
313: if (i < *NF)
314: for (p = *OFS; *r = *p++; )
315: r++;
316: }
317: *r = '\0';
318: dprintf("in recbld FS=%o, recloc=%o\n", **FS, recloc, NULL);
319: recloc->tval = REC | STR | DONTFREE;
320: recloc->sval = record = rec;
321: dprintf("in recbld FS=%o, recloc=%o\n", **FS, recloc, NULL);
322: if (r > record + RECSIZE)
323: error(FATAL, "built giant record `%.20s...'", record);
324: dprintf("recbld = |%s|\n", record, NULL, NULL);
325: donerec = 1;
326: }
327:
328: Cell *fieldadr(n)
329: {
330: if (n < 0 || n >= MAXFLD)
331: error(FATAL, "trying to access field %d", n);
332: return(&fldtab[n]);
333: }
334:
335: int errorflag = 0;
336:
337: yyerror(s, a1, a2, a3, a4, a5, a6, a7)
338: uchar *s;
339: {
340: extern uchar *cmdname, *curfname;
341: static int been_here = 0;
342:
343: if (been_here++ > 2)
344: return;
345: fprintf(stderr, "%s: ", cmdname);
346: fprintf(stderr, s, a1, a2, a3, a4, a5, a6, a7);
347: fprintf(stderr, " at source line %d", lineno);
348: if (curfname != NULL)
349: fprintf(stderr, " in function %s", curfname);
350: fprintf(stderr, "\n");
351: errorflag = 2;
352: eprint();
353: }
354:
355: fpecatch()
356: {
357: error(FATAL, "floating point exception");
358: }
359:
360: bracecheck()
361: {
362: extern int bracecnt, brackcnt, parencnt;
363: int c;
364: static int beenhere = 0;
365:
366: if (beenhere++)
367: return;
368: while ((c = input()) != EOF && c != '\0')
369: bclass(c);
370: bcheck2(bracecnt, '{', '}');
371: bcheck2(brackcnt, '[', ']');
372: bcheck2(parencnt, '(', ')');
373: }
374:
375: bcheck2(n, c1, c2)
376: {
377: if (n == 1)
378: fprintf(stderr, "\tmissing %c\n", c2);
379: else if (n > 1)
380: fprintf(stderr, "\t%d missing %c's\n", n, c2);
381: else if (n == -1)
382: fprintf(stderr, "\textra %c\n", c2);
383: else if (n < -1)
384: fprintf(stderr, "\t%d extra %c's\n", -n, c2);
385: }
386:
387: error(f, s, a1, a2, a3, a4, a5, a6, a7)
388: char *s;
389: {
390: extern Node *curnode;
391: extern uchar *cmdname;
392:
393: fprintf(stderr, "%s: ", cmdname);
394: fprintf(stderr, s, a1, a2, a3, a4, a5, a6, a7);
395: fprintf(stderr, "\n");
396: if (NR && *NR > 0) {
397: fprintf(stderr, " input record number %g", *FNR);
398: if (strcmp(*FILENAME, "-") != 0)
399: fprintf(stderr, ", file %s", *FILENAME);
400: fprintf(stderr, "\n");
401: }
402: if (curnode)
403: fprintf(stderr, " source line number %d\n", curnode->lineno);
404: else if (lineno)
405: fprintf(stderr, " source line number %d\n", lineno);
406: eprint();
407: if (f) {
408: if (dbg)
409: abort();
410: exit(2);
411: }
412: }
413:
414: eprint() /* try to print context around error */
415: {
416: uchar *p, *q;
417: int c;
418: static int been_here = 0;
419: extern uchar ebuf[300], *ep;
420:
421: if (compile_time == 0 || been_here++ > 0)
422: return;
423: p = ep - 1;
424: if (p > ebuf && *p == '\n')
425: p--;
426: for ( ; p > ebuf && *p != '\n' && *p != '\0'; p--)
427: ;
428: while (*p == '\n')
429: p++;
430: fprintf(stderr, " context is\n\t");
431: for (q=ep-1; q>=p && *q!=' ' && *q!='\t' && *q!='\n'; q--)
432: ;
433: while (p < q)
434: putc(*p++, stderr);
435: fprintf(stderr, " >>> ");
436: while (p < ep)
437: putc(*p++, stderr);
438: fprintf(stderr, " <<< ");
439: if (*ep)
440: while ((c = input()) != '\n' && c != '\0' && c != EOF) {
441: putc(c, stderr);
442: bclass(c);
443: }
444: putc('\n', stderr);
445: ep = ebuf;
446: }
447:
448: bclass(c)
449: {
450: switch (c) {
451: case '{': bracecnt++; break;
452: case '}': bracecnt--; break;
453: case '[': brackcnt++; break;
454: case ']': brackcnt--; break;
455: case '(': parencnt++; break;
456: case ')': parencnt--; break;
457: }
458: }
459:
460: double errcheck(x, s)
461: double x;
462: uchar *s;
463: {
464: extern int errno;
465:
466: if (errno == EDOM) {
467: errno = 0;
468: error(!FATAL, "%s argument out of domain", s);
469: x = 1;
470: } else if (errno == ERANGE) {
471: errno = 0;
472: error(!FATAL, "%s result out of range", s);
473: x = 1;
474: }
475: return x;
476: }
477:
478: PUTS(s) uchar *s; {
479: dprintf("%s\n", s, NULL, NULL);
480: }
481:
482: isclvar(s) /* is s of form var=something? */
483: char *s;
484: {
485: for ( ; *s; s++)
486: if (!isalnum(*s))
487: break;
488: return *s == '=';
489: }
490:
491: #define MAXEXPON 38 /* maximum exponent for fp number */
492:
493: isnumber(s)
494: register uchar *s;
495: {
496: register d1, d2;
497: int point;
498: uchar *es;
499:
500: d1 = d2 = point = 0;
501: while (*s == ' ' || *s == '\t' || *s == '\n')
502: s++;
503: if (*s == '\0')
504: return(0); /* empty stuff isn't number */
505: if (*s == '+' || *s == '-')
506: s++;
507: if (!isdigit(*s) && *s != '.')
508: return(0);
509: if (isdigit(*s)) {
510: do {
511: d1++;
512: s++;
513: } while (isdigit(*s));
514: }
515: if(d1 >= MAXEXPON)
516: return(0); /* too many digits to convert */
517: if (*s == '.') {
518: point++;
519: s++;
520: }
521: if (isdigit(*s)) {
522: d2++;
523: do {
524: s++;
525: } while (isdigit(*s));
526: }
527: if (!(d1 || point && d2))
528: return(0);
529: if (*s == 'e' || *s == 'E') {
530: s++;
531: if (*s == '+' || *s == '-')
532: s++;
533: if (!isdigit(*s))
534: return(0);
535: es = s;
536: do {
537: s++;
538: } while (isdigit(*s));
539: if (s - es > 2)
540: return(0);
541: else if (s - es == 2 && 10 * (*es-'0') + *(es+1)-'0' >= MAXEXPON)
542: return(0);
543: }
544: while (*s == ' ' || *s == '\t' || *s == '\n')
545: s++;
546: if (*s == '\0')
547: return(1);
548: else
549: return(0);
550: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.