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