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