1 63a68686 2008-11-03 jas /****************************************************************
2 63a68686 2008-11-03 jas Copyright (C) Lucent Technologies 1997
3 63a68686 2008-11-03 jas All Rights Reserved
5 63a68686 2008-11-03 jas Permission to use, copy, modify, and distribute this software and
6 63a68686 2008-11-03 jas its documentation for any purpose and without fee is hereby
7 63a68686 2008-11-03 jas granted, provided that the above copyright notice appear in all
8 63a68686 2008-11-03 jas copies and that both that the copyright notice and this
9 63a68686 2008-11-03 jas permission notice and warranty disclaimer appear in supporting
10 63a68686 2008-11-03 jas documentation, and that the name Lucent Technologies or any of
11 63a68686 2008-11-03 jas its entities not be used in advertising or publicity pertaining
12 63a68686 2008-11-03 jas to distribution of the software without specific, written prior
15 63a68686 2008-11-03 jas LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 63a68686 2008-11-03 jas INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
17 63a68686 2008-11-03 jas IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
18 63a68686 2008-11-03 jas SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 63a68686 2008-11-03 jas WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
20 63a68686 2008-11-03 jas IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
21 63a68686 2008-11-03 jas ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
22 63a68686 2008-11-03 jas THIS SOFTWARE.
23 63a68686 2008-11-03 jas ****************************************************************/
25 63a68686 2008-11-03 jas #define DEBUG
26 63a68686 2008-11-03 jas #include <stdio.h>
27 63a68686 2008-11-03 jas #include <string.h>
28 63a68686 2008-11-03 jas #include <ctype.h>
29 63a68686 2008-11-03 jas #include <errno.h>
30 63a68686 2008-11-03 jas #include <stdlib.h>
31 63a68686 2008-11-03 jas #include <stdarg.h>
32 63a68686 2008-11-03 jas #include "awk.h"
33 63a68686 2008-11-03 jas #include "y.tab.h"
35 63a68686 2008-11-03 jas FILE *infile = NULL;
36 63a68686 2008-11-03 jas char *file = "";
37 63a68686 2008-11-03 jas char *record;
38 63a68686 2008-11-03 jas int recsize = RECSIZE;
39 63a68686 2008-11-03 jas char *fields;
40 63a68686 2008-11-03 jas int fieldssize = RECSIZE;
42 63a68686 2008-11-03 jas Cell **fldtab; /* pointers to Cells */
43 63a68686 2008-11-03 jas char inputFS[100] = " ";
45 63a68686 2008-11-03 jas #define MAXFLD 200
46 63a68686 2008-11-03 jas int nfields = MAXFLD; /* last allocated slot for $i */
48 63a68686 2008-11-03 jas int donefld; /* 1 = implies rec broken into fields */
49 63a68686 2008-11-03 jas int donerec; /* 1 = record is valid (no flds have changed) */
51 63a68686 2008-11-03 jas int lastfld = 0; /* last used field */
52 63a68686 2008-11-03 jas int argno = 1; /* current input argument number */
53 63a68686 2008-11-03 jas extern Awkfloat *ARGC;
55 63a68686 2008-11-03 jas static Cell dollar0 = { OCELL, CFLD, NULL, "", 0.0, REC|STR|DONTFREE };
56 63a68686 2008-11-03 jas static Cell dollar1 = { OCELL, CFLD, NULL, "", 0.0, FLD|STR|DONTFREE };
58 63a68686 2008-11-03 jas void recinit(unsigned int n)
60 63a68686 2008-11-03 jas record = (char *) malloc(n);
61 63a68686 2008-11-03 jas fields = (char *) malloc(n);
62 63a68686 2008-11-03 jas fldtab = (Cell **) malloc((nfields+1) * sizeof(Cell *));
63 63a68686 2008-11-03 jas if (record == NULL || fields == NULL || fldtab == NULL)
64 63a68686 2008-11-03 jas FATAL("out of space for $0 and fields");
65 63a68686 2008-11-03 jas fldtab[0] = (Cell *) malloc(sizeof (Cell));
66 63a68686 2008-11-03 jas *fldtab[0] = dollar0;
67 63a68686 2008-11-03 jas fldtab[0]->sval = record;
68 63a68686 2008-11-03 jas fldtab[0]->nval = tostring("0");
69 63a68686 2008-11-03 jas makefields(1, nfields);
72 63a68686 2008-11-03 jas void makefields(int n1, int n2) /* create $n1..$n2 inclusive */
74 63a68686 2008-11-03 jas char temp[50];
77 63a68686 2008-11-03 jas for (i = n1; i <= n2; i++) {
78 63a68686 2008-11-03 jas fldtab[i] = (Cell *) malloc(sizeof (struct Cell));
79 63a68686 2008-11-03 jas if (fldtab[i] == NULL)
80 63a68686 2008-11-03 jas FATAL("out of space in makefields %d", i);
81 63a68686 2008-11-03 jas *fldtab[i] = dollar1;
82 63a68686 2008-11-03 jas sprintf(temp, "%d", i);
83 63a68686 2008-11-03 jas fldtab[i]->nval = tostring(temp);
87 63a68686 2008-11-03 jas void initgetrec(void)
92 63a68686 2008-11-03 jas for (i = 1; i < *ARGC; i++) {
93 63a68686 2008-11-03 jas if (!isclvar(p = getargv(i))) { /* find 1st real filename */
94 63a68686 2008-11-03 jas setsval(lookup("FILENAME", symtab), getargv(i));
97 63a68686 2008-11-03 jas setclvar(p); /* a commandline assignment before filename */
100 63a68686 2008-11-03 jas infile = stdin; /* no filenames, so use stdin */
103 63a68686 2008-11-03 jas int getrec(char **pbuf, int *pbufsize, int isrecord) /* get next input record */
104 63a68686 2008-11-03 jas { /* note: cares whether buf == record */
106 63a68686 2008-11-03 jas static int firsttime = 1;
107 63a68686 2008-11-03 jas char *buf = *pbuf;
108 63a68686 2008-11-03 jas int bufsize = *pbufsize;
110 63a68686 2008-11-03 jas if (firsttime) {
111 63a68686 2008-11-03 jas firsttime = 0;
112 63a68686 2008-11-03 jas initgetrec();
114 63a68686 2008-11-03 jas dprintf( ("RS=<%s>, FS=<%s>, ARGC=%g, FILENAME=%s\n",
115 63a68686 2008-11-03 jas *RS, *FS, *ARGC, *FILENAME) );
116 63a68686 2008-11-03 jas if (isrecord) {
117 63a68686 2008-11-03 jas donefld = 0;
118 63a68686 2008-11-03 jas donerec = 1;
121 63a68686 2008-11-03 jas while (argno < *ARGC || infile == stdin) {
122 63a68686 2008-11-03 jas dprintf( ("argno=%d, file=|%s|\n", argno, file) );
123 63a68686 2008-11-03 jas if (infile == NULL) { /* have to open a new file */
124 63a68686 2008-11-03 jas file = getargv(argno);
125 63a68686 2008-11-03 jas if (*file == '\0') { /* it's been zapped */
129 63a68686 2008-11-03 jas if (isclvar(file)) { /* a var=value arg */
130 63a68686 2008-11-03 jas setclvar(file);
134 63a68686 2008-11-03 jas *FILENAME = file;
135 63a68686 2008-11-03 jas dprintf( ("opening file %s\n", file) );
136 63a68686 2008-11-03 jas if (*file == '-' && *(file+1) == '\0')
137 63a68686 2008-11-03 jas infile = stdin;
138 63a68686 2008-11-03 jas else if ((infile = fopen(file, "r")) == NULL)
139 63a68686 2008-11-03 jas FATAL("can't open file %s", file);
140 63a68686 2008-11-03 jas setfval(fnrloc, 0.0);
142 63a68686 2008-11-03 jas c = readrec(&buf, &bufsize, infile);
143 63a68686 2008-11-03 jas if (c != 0 || buf[0] != '\0') { /* normal record */
144 63a68686 2008-11-03 jas if (isrecord) {
145 63a68686 2008-11-03 jas if (freeable(fldtab[0]))
146 63a68686 2008-11-03 jas xfree(fldtab[0]->sval);
147 63a68686 2008-11-03 jas fldtab[0]->sval = buf; /* buf == record */
148 63a68686 2008-11-03 jas fldtab[0]->tval = REC | STR | DONTFREE;
149 63a68686 2008-11-03 jas if (is_number(fldtab[0]->sval)) {
150 63a68686 2008-11-03 jas fldtab[0]->fval = atof(fldtab[0]->sval);
151 63a68686 2008-11-03 jas fldtab[0]->tval |= NUM;
154 63a68686 2008-11-03 jas setfval(nrloc, nrloc->fval+1);
155 63a68686 2008-11-03 jas setfval(fnrloc, fnrloc->fval+1);
156 63a68686 2008-11-03 jas *pbuf = buf;
157 63a68686 2008-11-03 jas *pbufsize = bufsize;
160 63a68686 2008-11-03 jas /* EOF arrived on this file; set up next */
161 63a68686 2008-11-03 jas if (infile != stdin)
162 63a68686 2008-11-03 jas fclose(infile);
163 63a68686 2008-11-03 jas infile = NULL;
166 63a68686 2008-11-03 jas *pbuf = buf;
167 63a68686 2008-11-03 jas *pbufsize = bufsize;
168 63a68686 2008-11-03 jas return 0; /* true end of file */
171 63a68686 2008-11-03 jas void nextfile(void)
173 63a68686 2008-11-03 jas if (infile != stdin)
174 63a68686 2008-11-03 jas fclose(infile);
175 63a68686 2008-11-03 jas infile = NULL;
179 63a68686 2008-11-03 jas int readrec(char **pbuf, int *pbufsize, FILE *inf) /* read one record into buf */
182 63a68686 2008-11-03 jas char *rr, *buf = *pbuf;
183 63a68686 2008-11-03 jas int bufsize = *pbufsize;
185 63a68686 2008-11-03 jas if (strlen(*FS) >= sizeof(inputFS))
186 63a68686 2008-11-03 jas FATAL("field separator %.10s... is too long", *FS);
187 63a68686 2008-11-03 jas strcpy(inputFS, *FS); /* for subsequent field splitting */
188 63a68686 2008-11-03 jas if ((sep = **RS) == 0) {
190 63a68686 2008-11-03 jas while ((c=getc(inf)) == '\n' && c != EOF) /* skip leading \n's */
192 63a68686 2008-11-03 jas if (c != EOF)
193 63a68686 2008-11-03 jas ungetc(c, inf);
195 63a68686 2008-11-03 jas for (rr = buf; ; ) {
196 63a68686 2008-11-03 jas for (; (c=getc(inf)) != sep && c != EOF; ) {
197 63a68686 2008-11-03 jas if (rr-buf+1 > bufsize)
198 63a68686 2008-11-03 jas if (!adjbuf(&buf, &bufsize, 1+rr-buf, recsize, &rr, "readrec 1"))
199 63a68686 2008-11-03 jas FATAL("input record `%.30s...' too long", buf);
202 63a68686 2008-11-03 jas if (**RS == sep || c == EOF)
204 63a68686 2008-11-03 jas if ((c = getc(inf)) == '\n' || c == EOF) /* 2 in a row */
206 63a68686 2008-11-03 jas if (!adjbuf(&buf, &bufsize, 2+rr-buf, recsize, &rr, "readrec 2"))
207 63a68686 2008-11-03 jas FATAL("input record `%.30s...' too long", buf);
208 63a68686 2008-11-03 jas *rr++ = '\n';
211 63a68686 2008-11-03 jas if (!adjbuf(&buf, &bufsize, 1+rr-buf, recsize, &rr, "readrec 3"))
212 63a68686 2008-11-03 jas FATAL("input record `%.30s...' too long", buf);
214 63a68686 2008-11-03 jas dprintf( ("readrec saw <%s>, returns %d\n", buf, c == EOF && rr == buf ? 0 : 1) );
215 63a68686 2008-11-03 jas *pbuf = buf;
216 63a68686 2008-11-03 jas *pbufsize = bufsize;
217 63a68686 2008-11-03 jas return c == EOF && rr == buf ? 0 : 1;
220 63a68686 2008-11-03 jas char *getargv(int n) /* get ARGV[n] */
223 63a68686 2008-11-03 jas char *s, temp[50];
224 63a68686 2008-11-03 jas extern Array *ARGVtab;
226 63a68686 2008-11-03 jas sprintf(temp, "%d", n);
227 63a68686 2008-11-03 jas x = setsymtab(temp, "", 0.0, STR, ARGVtab);
228 63a68686 2008-11-03 jas s = getsval(x);
229 63a68686 2008-11-03 jas dprintf( ("getargv(%d) returns |%s|\n", n, s) );
233 63a68686 2008-11-03 jas void setclvar(char *s) /* set var=value from s */
238 63a68686 2008-11-03 jas for (p=s; *p != '='; p++)
241 63a68686 2008-11-03 jas p = qstring(p, '\0');
242 63a68686 2008-11-03 jas q = setsymtab(s, p, 0.0, STR, symtab);
243 63a68686 2008-11-03 jas setsval(q, p);
244 63a68686 2008-11-03 jas if (is_number(q->sval)) {
245 63a68686 2008-11-03 jas q->fval = atof(q->sval);
246 63a68686 2008-11-03 jas q->tval |= NUM;
248 63a68686 2008-11-03 jas dprintf( ("command line set %s to |%s|\n", s, p) );
252 63a68686 2008-11-03 jas void fldbld(void) /* create fields from current record */
254 63a68686 2008-11-03 jas /* this relies on having fields[] the same length as $0 */
255 63a68686 2008-11-03 jas /* the fields are all stored in this one array with \0's */
256 63a68686 2008-11-03 jas char *r, *fr, sep;
258 63a68686 2008-11-03 jas int i, j, n;
260 63a68686 2008-11-03 jas if (donefld)
262 63a68686 2008-11-03 jas if (!isstr(fldtab[0]))
263 63a68686 2008-11-03 jas getsval(fldtab[0]);
264 63a68686 2008-11-03 jas r = fldtab[0]->sval;
265 63a68686 2008-11-03 jas n = strlen(r);
266 63a68686 2008-11-03 jas if (n > fieldssize) {
267 63a68686 2008-11-03 jas xfree(fields);
268 63a68686 2008-11-03 jas if ((fields = (char *) malloc(n+1)) == NULL)
269 63a68686 2008-11-03 jas FATAL("out of space for fields in fldbld %d", n);
270 63a68686 2008-11-03 jas fieldssize = n;
272 63a68686 2008-11-03 jas fr = fields;
273 63a68686 2008-11-03 jas i = 0; /* number of fields accumulated here */
274 63a68686 2008-11-03 jas if (strlen(inputFS) > 1) { /* it's a regular expression */
275 63a68686 2008-11-03 jas i = refldbld(r, inputFS);
276 63a68686 2008-11-03 jas } else if ((sep = *inputFS) == ' ') { /* default whitespace */
277 63a68686 2008-11-03 jas for (i = 0; ; ) {
278 63a68686 2008-11-03 jas while (*r == ' ' || *r == '\t' || *r == '\n')
280 63a68686 2008-11-03 jas if (*r == 0)
283 63a68686 2008-11-03 jas if (i > nfields)
284 63a68686 2008-11-03 jas growfldtab(i);
285 63a68686 2008-11-03 jas if (freeable(fldtab[i]))
286 63a68686 2008-11-03 jas xfree(fldtab[i]->sval);
287 63a68686 2008-11-03 jas fldtab[i]->sval = fr;
288 63a68686 2008-11-03 jas fldtab[i]->tval = FLD | STR | DONTFREE;
290 63a68686 2008-11-03 jas *fr++ = *r++;
291 63a68686 2008-11-03 jas while (*r != ' ' && *r != '\t' && *r != '\n' && *r != '\0');
295 63a68686 2008-11-03 jas } else if ((sep = *inputFS) == 0) { /* new: FS="" => 1 char/field */
296 63a68686 2008-11-03 jas for (i = 0; *r != 0; r++) {
297 63a68686 2008-11-03 jas char buf[2];
299 63a68686 2008-11-03 jas if (i > nfields)
300 63a68686 2008-11-03 jas growfldtab(i);
301 63a68686 2008-11-03 jas if (freeable(fldtab[i]))
302 63a68686 2008-11-03 jas xfree(fldtab[i]->sval);
303 63a68686 2008-11-03 jas buf[0] = *r;
305 63a68686 2008-11-03 jas fldtab[i]->sval = tostring(buf);
306 63a68686 2008-11-03 jas fldtab[i]->tval = FLD | STR;
309 63a68686 2008-11-03 jas } else if (*r != 0) { /* if 0, it's a null field */
312 63a68686 2008-11-03 jas if (i > nfields)
313 63a68686 2008-11-03 jas growfldtab(i);
314 63a68686 2008-11-03 jas if (freeable(fldtab[i]))
315 63a68686 2008-11-03 jas xfree(fldtab[i]->sval);
316 63a68686 2008-11-03 jas fldtab[i]->sval = fr;
317 63a68686 2008-11-03 jas fldtab[i]->tval = FLD | STR | DONTFREE;
318 63a68686 2008-11-03 jas while (*r != sep && *r != '\n' && *r != '\0') /* \n is always a separator */
319 63a68686 2008-11-03 jas *fr++ = *r++;
321 63a68686 2008-11-03 jas if (*r++ == 0)
326 63a68686 2008-11-03 jas if (i > nfields)
327 63a68686 2008-11-03 jas FATAL("record `%.30s...' has too many fields; can't happen", r);
328 63a68686 2008-11-03 jas cleanfld(i+1, lastfld); /* clean out junk from previous record */
329 63a68686 2008-11-03 jas lastfld = i;
330 63a68686 2008-11-03 jas donefld = 1;
331 63a68686 2008-11-03 jas for (j = 1; j <= lastfld; j++) {
332 63a68686 2008-11-03 jas p = fldtab[j];
333 63a68686 2008-11-03 jas if(is_number(p->sval)) {
334 63a68686 2008-11-03 jas p->fval = atof(p->sval);
335 63a68686 2008-11-03 jas p->tval |= NUM;
338 63a68686 2008-11-03 jas setfval(nfloc, (Awkfloat) lastfld);
340 63a68686 2008-11-03 jas for (j = 0; j <= lastfld; j++) {
341 63a68686 2008-11-03 jas p = fldtab[j];
342 63a68686 2008-11-03 jas printf("field %d (%s): |%s|\n", j, p->nval, p->sval);
347 63a68686 2008-11-03 jas void cleanfld(int n1, int n2) /* clean out fields n1 .. n2 inclusive */
348 63a68686 2008-11-03 jas { /* nvals remain intact */
352 63a68686 2008-11-03 jas for (i = n1; i <= n2; i++) {
353 63a68686 2008-11-03 jas p = fldtab[i];
354 63a68686 2008-11-03 jas if (freeable(p))
355 63a68686 2008-11-03 jas xfree(p->sval);
356 63a68686 2008-11-03 jas p->sval = "";
357 63a68686 2008-11-03 jas p->tval = FLD | STR | DONTFREE;
361 63a68686 2008-11-03 jas void newfld(int n) /* add field n after end of existing lastfld */
363 63a68686 2008-11-03 jas if (n > nfields)
364 63a68686 2008-11-03 jas growfldtab(n);
365 63a68686 2008-11-03 jas cleanfld(lastfld+1, n);
366 63a68686 2008-11-03 jas lastfld = n;
367 63a68686 2008-11-03 jas setfval(nfloc, (Awkfloat) n);
370 63a68686 2008-11-03 jas Cell *fieldadr(int n) /* get nth field */
373 63a68686 2008-11-03 jas FATAL("trying to access field %d", n);
374 63a68686 2008-11-03 jas if (n > nfields) /* fields after NF are empty */
375 63a68686 2008-11-03 jas growfldtab(n); /* but does not increase NF */
376 63a68686 2008-11-03 jas return(fldtab[n]);
379 63a68686 2008-11-03 jas void growfldtab(int n) /* make new fields up to at least $n */
381 63a68686 2008-11-03 jas int nf = 2 * nfields;
385 63a68686 2008-11-03 jas fldtab = (Cell **) realloc(fldtab, (nf+1) * (sizeof (struct Cell *)));
386 63a68686 2008-11-03 jas if (fldtab == NULL)
387 63a68686 2008-11-03 jas FATAL("out of space creating %d fields", nf);
388 63a68686 2008-11-03 jas makefields(nfields+1, nf);
389 63a68686 2008-11-03 jas nfields = nf;
392 63a68686 2008-11-03 jas int refldbld(char *rec, char *fs) /* build fields from reg expr in FS */
394 63a68686 2008-11-03 jas /* this relies on having fields[] the same length as $0 */
395 63a68686 2008-11-03 jas /* the fields are all stored in this one array with \0's */
400 63a68686 2008-11-03 jas n = strlen(rec);
401 63a68686 2008-11-03 jas if (n > fieldssize) {
402 63a68686 2008-11-03 jas xfree(fields);
403 63a68686 2008-11-03 jas if ((fields = (char *) malloc(n+1)) == NULL)
404 63a68686 2008-11-03 jas FATAL("out of space for fields in refldbld %d", n);
405 63a68686 2008-11-03 jas fieldssize = n;
407 63a68686 2008-11-03 jas fr = fields;
409 63a68686 2008-11-03 jas if (*rec == '\0')
411 63a68686 2008-11-03 jas p = compre(fs);
412 63a68686 2008-11-03 jas dprintf( ("into refldbld, rec = <%s>, pat = <%s>\n", rec, fs) );
413 63a68686 2008-11-03 jas for (i = 1; ; i++) {
414 63a68686 2008-11-03 jas if (i > nfields)
415 63a68686 2008-11-03 jas growfldtab(i);
416 63a68686 2008-11-03 jas if (freeable(fldtab[i]))
417 63a68686 2008-11-03 jas xfree(fldtab[i]->sval);
418 63a68686 2008-11-03 jas fldtab[i]->tval = FLD | STR | DONTFREE;
419 63a68686 2008-11-03 jas fldtab[i]->sval = fr;
420 63a68686 2008-11-03 jas dprintf( ("refldbld: i=%d\n", i) );
421 63a68686 2008-11-03 jas if (nematch(p, rec, rec)) {
422 63a68686 2008-11-03 jas dprintf( ("match %s (%d chars)\n", patbeg, patlen) );
423 63a68686 2008-11-03 jas strncpy(fr, rec, patbeg-rec);
424 63a68686 2008-11-03 jas fr += patbeg - rec + 1;
425 63a68686 2008-11-03 jas *(fr-1) = '\0';
426 63a68686 2008-11-03 jas rec = patbeg + patlen;
428 63a68686 2008-11-03 jas dprintf( ("no match %s\n", rec) );
429 63a68686 2008-11-03 jas strcpy(fr, rec);
436 63a68686 2008-11-03 jas void recbld(void) /* create $0 from $1..$NF if necessary */
439 63a68686 2008-11-03 jas char *r, *p;
441 63a68686 2008-11-03 jas if (donerec == 1)
444 63a68686 2008-11-03 jas for (i = 1; i <= *NF; i++) {
445 63a68686 2008-11-03 jas p = getsval(fldtab[i]);
446 63a68686 2008-11-03 jas if (!adjbuf(&record, &recsize, 1+strlen(p)+r-record, recsize, &r, "recbld 1"))
447 63a68686 2008-11-03 jas FATAL("created $0 `%.30s...' too long", record);
448 63a68686 2008-11-03 jas while ((*r = *p++) != 0)
450 63a68686 2008-11-03 jas if (i < *NF) {
451 63a68686 2008-11-03 jas if (!adjbuf(&record, &recsize, 2+strlen(*OFS)+r-record, recsize, &r, "recbld 2"))
452 63a68686 2008-11-03 jas FATAL("created $0 `%.30s...' too long", record);
453 63a68686 2008-11-03 jas for (p = *OFS; (*r = *p++) != 0; )
457 63a68686 2008-11-03 jas if (!adjbuf(&record, &recsize, 2+r-record, recsize, &r, "recbld 3"))
458 63a68686 2008-11-03 jas FATAL("built giant record `%.30s...'", record);
460 63a68686 2008-11-03 jas dprintf( ("in recbld inputFS=%s, fldtab[0]=%p\n", inputFS, fldtab[0]) );
462 63a68686 2008-11-03 jas if (freeable(fldtab[0]))
463 63a68686 2008-11-03 jas xfree(fldtab[0]->sval);
464 63a68686 2008-11-03 jas fldtab[0]->tval = REC | STR | DONTFREE;
465 63a68686 2008-11-03 jas fldtab[0]->sval = record;
467 63a68686 2008-11-03 jas dprintf( ("in recbld inputFS=%s, fldtab[0]=%p\n", inputFS, fldtab[0]) );
468 63a68686 2008-11-03 jas dprintf( ("recbld = |%s|\n", record) );
469 63a68686 2008-11-03 jas donerec = 1;
472 63a68686 2008-11-03 jas int errorflag = 0;
474 63a68686 2008-11-03 jas void yyerror(char *s)
479 63a68686 2008-11-03 jas void SYNTAX(char *fmt, ...)
481 63a68686 2008-11-03 jas extern char *cmdname, *curfname;
482 63a68686 2008-11-03 jas static int been_here = 0;
483 63a68686 2008-11-03 jas va_list varg;
485 63a68686 2008-11-03 jas if (been_here++ > 2)
487 63a68686 2008-11-03 jas fprintf(stderr, "%s: ", cmdname);
488 63a68686 2008-11-03 jas va_start(varg, fmt);
489 63a68686 2008-11-03 jas vfprintf(stderr, fmt, varg);
490 63a68686 2008-11-03 jas va_end(varg);
491 63a68686 2008-11-03 jas if(compile_time == 1 && cursource() != NULL)
492 63a68686 2008-11-03 jas fprintf(stderr, " at %s:%d", cursource(), lineno);
494 63a68686 2008-11-03 jas fprintf(stderr, " at line %d", lineno);
495 63a68686 2008-11-03 jas if (curfname != NULL)
496 63a68686 2008-11-03 jas fprintf(stderr, " in function %s", curfname);
497 63a68686 2008-11-03 jas fprintf(stderr, "\n");
498 63a68686 2008-11-03 jas errorflag = 2;
502 63a68686 2008-11-03 jas void fpecatch(int n)
504 63a68686 2008-11-03 jas FATAL("floating point exception %d", n);
507 63a68686 2008-11-03 jas extern int bracecnt, brackcnt, parencnt;
509 63a68686 2008-11-03 jas void bracecheck(void)
512 63a68686 2008-11-03 jas static int beenhere = 0;
514 63a68686 2008-11-03 jas if (beenhere++)
516 63a68686 2008-11-03 jas while ((c = input()) != EOF && c != '\0')
518 63a68686 2008-11-03 jas bcheck2(bracecnt, '{', '}');
519 63a68686 2008-11-03 jas bcheck2(brackcnt, '[', ']');
520 63a68686 2008-11-03 jas bcheck2(parencnt, '(', ')');
523 63a68686 2008-11-03 jas void bcheck2(int n, int c1, int c2)
526 63a68686 2008-11-03 jas fprintf(stderr, "\tmissing %c\n", c2);
527 63a68686 2008-11-03 jas else if (n > 1)
528 63a68686 2008-11-03 jas fprintf(stderr, "\t%d missing %c's\n", n, c2);
529 63a68686 2008-11-03 jas else if (n == -1)
530 63a68686 2008-11-03 jas fprintf(stderr, "\textra %c\n", c2);
531 63a68686 2008-11-03 jas else if (n < -1)
532 63a68686 2008-11-03 jas fprintf(stderr, "\t%d extra %c's\n", -n, c2);
535 63a68686 2008-11-03 jas void FATAL(char *fmt, ...)
537 63a68686 2008-11-03 jas extern char *cmdname;
538 63a68686 2008-11-03 jas va_list varg;
540 63a68686 2008-11-03 jas fflush(stdout);
541 63a68686 2008-11-03 jas fprintf(stderr, "%s: ", cmdname);
542 63a68686 2008-11-03 jas va_start(varg, fmt);
543 63a68686 2008-11-03 jas vfprintf(stderr, fmt, varg);
544 63a68686 2008-11-03 jas va_end(varg);
546 63a68686 2008-11-03 jas if (dbg > 1) /* core dump if serious debugging on */
551 63a68686 2008-11-03 jas void WARNING(char *fmt, ...)
553 63a68686 2008-11-03 jas extern char *cmdname;
554 63a68686 2008-11-03 jas va_list varg;
556 63a68686 2008-11-03 jas fflush(stdout);
557 63a68686 2008-11-03 jas fprintf(stderr, "%s: ", cmdname);
558 63a68686 2008-11-03 jas va_start(varg, fmt);
559 63a68686 2008-11-03 jas vfprintf(stderr, fmt, varg);
560 63a68686 2008-11-03 jas va_end(varg);
564 63a68686 2008-11-03 jas void error()
566 63a68686 2008-11-03 jas extern Node *curnode;
569 63a68686 2008-11-03 jas fprintf(stderr, "\n");
570 63a68686 2008-11-03 jas if (compile_time != 2 && NR && *NR > 0) {
571 63a68686 2008-11-03 jas if (strcmp(*FILENAME, "-") != 0)
572 63a68686 2008-11-03 jas fprintf(stderr, " input record %s:%d", *FILENAME, (int) (*FNR));
574 63a68686 2008-11-03 jas fprintf(stderr, " input record number %d", (int) (*FNR));
575 63a68686 2008-11-03 jas fprintf(stderr, "\n");
577 63a68686 2008-11-03 jas if (compile_time != 2 && curnode)
578 63a68686 2008-11-03 jas line = curnode->lineno;
579 63a68686 2008-11-03 jas else if (compile_time != 2 && lineno)
580 63a68686 2008-11-03 jas line = lineno;
583 63a68686 2008-11-03 jas if (compile_time == 1 && cursource() != NULL){
584 63a68686 2008-11-03 jas if(line >= 0)
585 63a68686 2008-11-03 jas fprintf(stderr, " source %s:%d", cursource(), line);
587 63a68686 2008-11-03 jas fprintf(stderr, " source file %s", cursource());
588 63a68686 2008-11-03 jas }else if(line >= 0)
589 63a68686 2008-11-03 jas fprintf(stderr, " source line %d", line);
590 63a68686 2008-11-03 jas fprintf(stderr, "\n");
594 63a68686 2008-11-03 jas void eprint(void) /* try to print context around error */
596 63a68686 2008-11-03 jas char *p, *q;
598 63a68686 2008-11-03 jas static int been_here = 0;
599 63a68686 2008-11-03 jas extern char ebuf[], *ep;
601 63a68686 2008-11-03 jas if (compile_time == 2 || compile_time == 0 || been_here++ > 0)
604 63a68686 2008-11-03 jas if (p > ebuf && *p == '\n')
606 63a68686 2008-11-03 jas for ( ; p > ebuf && *p != '\n' && *p != '\0'; p--)
608 63a68686 2008-11-03 jas while (*p == '\n')
610 63a68686 2008-11-03 jas fprintf(stderr, " context is\n\t");
611 63a68686 2008-11-03 jas for (q=ep-1; q>=p && *q!=' ' && *q!='\t' && *q!='\n'; q--)
613 63a68686 2008-11-03 jas for ( ; p < q; p++)
615 63a68686 2008-11-03 jas putc(*p, stderr);
616 63a68686 2008-11-03 jas fprintf(stderr, " >>> ");
617 63a68686 2008-11-03 jas for ( ; p < ep; p++)
619 63a68686 2008-11-03 jas putc(*p, stderr);
620 63a68686 2008-11-03 jas fprintf(stderr, " <<< ");
622 63a68686 2008-11-03 jas while ((c = input()) != '\n' && c != '\0' && c != EOF) {
623 63a68686 2008-11-03 jas putc(c, stderr);
626 63a68686 2008-11-03 jas putc('\n', stderr);
630 63a68686 2008-11-03 jas void bclass(int c)
632 63a68686 2008-11-03 jas switch (c) {
633 63a68686 2008-11-03 jas case '{': bracecnt++; break;
634 63a68686 2008-11-03 jas case '}': bracecnt--; break;
635 63a68686 2008-11-03 jas case '[': brackcnt++; break;
636 63a68686 2008-11-03 jas case ']': brackcnt--; break;
637 63a68686 2008-11-03 jas case '(': parencnt++; break;
638 63a68686 2008-11-03 jas case ')': parencnt--; break;
642 63a68686 2008-11-03 jas double errcheck(double x, char *s)
645 63a68686 2008-11-03 jas if (errno == EDOM) {
647 63a68686 2008-11-03 jas WARNING("%s argument out of domain", s);
649 63a68686 2008-11-03 jas } else if (errno == ERANGE) {
651 63a68686 2008-11-03 jas WARNING("%s result out of range", s);
657 63a68686 2008-11-03 jas int isclvar(char *s) /* is s of form var=something ? */
659 63a68686 2008-11-03 jas char *os = s;
661 63a68686 2008-11-03 jas if (!isalpha(*s) && *s != '_')
663 63a68686 2008-11-03 jas for ( ; *s; s++)
664 63a68686 2008-11-03 jas if (!(isalnum(*s) || *s == '_'))
666 63a68686 2008-11-03 jas return *s == '=' && s > os && *(s+1) != '=';
669 63a68686 2008-11-03 jas /* strtod is supposed to be a proper test of what's a valid number */
671 63a68686 2008-11-03 jas #include <math.h>
672 63a68686 2008-11-03 jas int is_number(char *s)
678 63a68686 2008-11-03 jas * fast could-it-be-a-number check before calling strtod,
679 63a68686 2008-11-03 jas * which takes a surprisingly long time to reject non-numbers.
681 63a68686 2008-11-03 jas switch (*s) {
682 63a68686 2008-11-03 jas case '0': case '1': case '2': case '3': case '4':
683 63a68686 2008-11-03 jas case '5': case '6': case '7': case '8': case '9':
693 63a68686 2008-11-03 jas case 'n': /* nans */
695 63a68686 2008-11-03 jas case 'i': /* infs */
699 63a68686 2008-11-03 jas return 0; /* can't be a number */
703 63a68686 2008-11-03 jas r = strtod(s, &ep);
704 63a68686 2008-11-03 jas if (ep == s || r == HUGE_VAL || errno == ERANGE)
706 63a68686 2008-11-03 jas while (*ep == ' ' || *ep == '\t' || *ep == '\n')
708 63a68686 2008-11-03 jas if (*ep == '\0')