Print this page
3731 Update nawk to version 20121220
*** 22,105 ****
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
! /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
! /* All Rights Reserved */
!
! #pragma ident "%Z%%M% %I% %E% SMI"
#include <errno.h>
#include "awk.h"
#include "y.tab.h"
uchar *record;
! size_t record_size;
int donefld; /* 1 = implies rec broken into fields */
int donerec; /* 1 = record is valid (no flds have changed) */
! static struct fldtab_chunk {
! struct fldtab_chunk *next;
! Cell fields[FLD_INCR];
! } *fldtab_head, *fldtab_tail;
!
! static size_t fldtab_maxidx;
static FILE *infile = NULL;
static uchar *file = (uchar*) "";
static uchar *fields;
! static size_t fields_size = LINE_INCR;
- static int maxfld = 0; /* last used field */
static int argno = 1; /* current input argument number */
static uchar *getargv(int);
static void cleanfld(int, int);
static int refldbld(uchar *, uchar *);
static void bcheck2(int, int, int);
static void eprint(void);
static void bclass(int);
static void
initgetrec(void)
{
int i;
uchar *p;
for (i = 1; i < *ARGC; i++) {
! if (!isclvar(p = getargv(i))) /* find 1st real filename */
return;
setclvar(p); /* a commandline assignment before filename */
argno++;
}
infile = stdin; /* no filenames, so use stdin */
- /* *FILENAME = file = (uchar*) "-"; */
}
int
! getrec(uchar **bufp, size_t *bufsizep)
! {
int c;
! static int firsttime = 1;
! uchar_t *buf, *nbuf;
! size_t len;
if (firsttime) {
firsttime = 0;
initgetrec();
}
dprintf(("RS=<%s>, FS=<%s>, ARGC=%f, FILENAME=%s\n",
*RS, *FS, *ARGC, *FILENAME));
donefld = 0;
donerec = 1;
while (argno < *ARGC || infile == stdin) {
dprintf(("argno=%d, file=|%s|\n", argno, file));
if (infile == NULL) { /* have to open a new file */
file = getargv(argno);
! if (*file == '\0') { /* it's been zapped */
argno++;
continue;
}
if (isclvar(file)) { /* a var=value arg */
setclvar(file);
--- 22,176 ----
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
! /*
! * Copyright (C) Lucent Technologies 1997
! * All Rights Reserved
! *
! * Permission to use, copy, modify, and distribute this software and
! * its documentation for any purpose and without fee is hereby
! * granted, provided that the above copyright notice appear in all
! * copies and that both that the copyright notice and this
! * permission notice and warranty disclaimer appear in supporting
! * documentation, and that the name Lucent Technologies or any of
! * its entities not be used in advertising or publicity pertaining
! * to distribution of the software without specific, written prior
! * permission.
! *
! * LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
! * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
! * IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
! * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
! * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
! * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
! * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
! * THIS SOFTWARE.
! */
#include <errno.h>
+ #include <stdarg.h>
+ #include <math.h>
#include "awk.h"
#include "y.tab.h"
uchar *record;
! size_t record_size = RECSIZE;
!
! Cell **fldtab; /* pointers to Cells */
! char inputFS[100] = " ";
!
! #define MAXFLD 2
! int nfields = MAXFLD; /* last allocated slot for $i */
int donefld; /* 1 = implies rec broken into fields */
int donerec; /* 1 = record is valid (no flds have changed) */
! int lastfld = 0; /* last used field */
static FILE *infile = NULL;
static uchar *file = (uchar*) "";
static uchar *fields;
! static size_t fields_size = RECSIZE;
static int argno = 1; /* current input argument number */
static uchar *getargv(int);
static void cleanfld(int, int);
static int refldbld(uchar *, uchar *);
static void bcheck2(int, int, int);
static void eprint(void);
static void bclass(int);
+ static void makefields(int, int);
+
+
+ static Cell dollar0 = { OCELL, CFLD, NULL, (uchar *)"", 0.0, REC|STR|DONTFREE };
+ static Cell dollar1 = { OCELL, CFLD, NULL, (uchar *)"", 0.0, FLD|STR|DONTFREE };
+
+ void
+ recinit(unsigned int n)
+ {
+ if ((record = (uchar *)malloc(n)) == NULL ||
+ (fields = (uchar *)malloc(n+1)) == NULL ||
+ (fldtab = (Cell **)malloc((nfields + 1) *
+ sizeof (Cell *))) == NULL ||
+ (fldtab[0] = (Cell *)malloc(sizeof (Cell))) == NULL)
+ FATAL("out of space for $0 and fields");
+ *fldtab[0] = dollar0;
+ fldtab[0]->sval = record;
+ fldtab[0]->nval = tostring((uchar *)"0");
+ makefields(1, nfields);
+ }
+
+ static void
+ makefields(int n1, int n2) /* create $n1..$n2 inclusive */
+ {
+ char temp[50];
+ int i;
+
+ for (i = n1; i <= n2; i++) {
+ fldtab[i] = (Cell *)malloc(sizeof (struct Cell));
+ if (fldtab[i] == NULL)
+ FATAL("out of space in makefields %d", i);
+ *fldtab[i] = dollar1;
+ (void) sprintf(temp, "%d", i);
+ fldtab[i]->nval = tostring((uchar *)temp);
+ }
+ }
static void
initgetrec(void)
{
int i;
uchar *p;
for (i = 1; i < *ARGC; i++) {
! p = getargv(i); /* find 1st real filename */
! if (p == NULL || *p == '\0') { /* deleted or zapped */
! argno++;
! continue;
! }
! if (!isclvar(p)) {
! (void) setsval(lookup((uchar *)"FILENAME", symtab), p);
return;
+ }
setclvar(p); /* a commandline assignment before filename */
argno++;
}
infile = stdin; /* no filenames, so use stdin */
}
+ static int firsttime = 1;
+
int
! getrec(uchar **pbuf, size_t *pbufsize, int isrecord)
! { /* get next input record */
! /* note: cares whether buf == record */
int c;
! uchar_t *buf = *pbuf;
! uchar saveb0;
! size_t bufsize = *pbufsize, savebufsize = bufsize;
if (firsttime) {
firsttime = 0;
initgetrec();
}
dprintf(("RS=<%s>, FS=<%s>, ARGC=%f, FILENAME=%s\n",
*RS, *FS, *ARGC, *FILENAME));
+ if (isrecord) {
donefld = 0;
donerec = 1;
+ }
+ saveb0 = buf[0];
+ buf[0] = 0;
while (argno < *ARGC || infile == stdin) {
dprintf(("argno=%d, file=|%s|\n", argno, file));
if (infile == NULL) { /* have to open a new file */
file = getargv(argno);
! /* deleted or zapped */
! if (file == NULL || *file == '\0') {
argno++;
continue;
}
if (isclvar(file)) { /* a var=value arg */
setclvar(file);
*** 109,201 ****
*FILENAME = file;
dprintf(("opening file %s\n", file));
if (*file == '-' && *(file+1) == '\0')
infile = stdin;
else if ((infile = fopen((char *)file, "r")) == NULL)
! ERROR "can't open file %s", file FATAL;
(void) setfval(fnrloc, 0.0);
}
! c = readrec(&nbuf, &len, infile);
! expand_buf(bufp, bufsizep, len);
! buf = *bufp;
! (void) memcpy(buf, nbuf, len);
! buf[len] = '\0';
! free(nbuf);
!
if (c != 0 || buf[0] != '\0') { /* normal record */
! if (bufp == &record) {
! if (!(recloc->tval & DONTFREE))
! xfree(recloc->sval);
! recloc->sval = record;
! recloc->tval = REC | STR | DONTFREE;
! if (is_number(recloc->sval)) {
! recloc->fval =
! atof((const char *)recloc->sval);
! recloc->tval |= NUM;
}
}
(void) setfval(nrloc, nrloc->fval+1);
(void) setfval(fnrloc, fnrloc->fval+1);
return (1);
}
/* EOF arrived on this file; set up next */
if (infile != stdin)
(void) fclose(infile);
infile = NULL;
argno++;
}
return (0); /* true end of file */
}
int
! readrec(uchar **bufp, size_t *sizep, FILE *inf) /* read one record into buf */
{
int sep, c;
! uchar *buf;
! int count;
! size_t bufsize;
! init_buf(&buf, &bufsize, LINE_INCR);
if ((sep = **RS) == 0) {
sep = '\n';
/* skip leading \n's */
while ((c = getc(inf)) == '\n' && c != EOF)
;
if (c != EOF)
(void) ungetc(c, inf);
}
! count = 0;
! for (;;) {
! while ((c = getc(inf)) != sep && c != EOF) {
! expand_buf(&buf, &bufsize, count);
! buf[count++] = c;
}
if (**RS == sep || c == EOF)
break;
if ((c = getc(inf)) == '\n' || c == EOF) /* 2 in a row */
break;
! expand_buf(&buf, &bufsize, count + 1);
! buf[count++] = '\n';
! buf[count++] = c;
! }
! buf[count] = '\0';
dprintf(("readrec saw <%s>, returns %d\n",
! buf, c == EOF && count == 0 ? 0 : 1));
! *bufp = buf;
! *sizep = count;
! return (c == EOF && count == 0 ? 0 : 1);
}
- /* get ARGV[n] */
static uchar *
! getargv(int n)
{
Cell *x;
! uchar *s, temp[11];
extern Array *ARGVtab;
(void) sprintf((char *)temp, "%d", n);
x = setsymtab(temp, (uchar *)"", 0.0, STR, ARGVtab);
s = getsval(x);
dprintf(("getargv(%d) returns |%s|\n", n, s));
return (s);
}
--- 180,298 ----
*FILENAME = file;
dprintf(("opening file %s\n", file));
if (*file == '-' && *(file+1) == '\0')
infile = stdin;
else if ((infile = fopen((char *)file, "r")) == NULL)
! FATAL("can't open file %s", file);
(void) setfval(fnrloc, 0.0);
}
! c = readrec(&buf, &bufsize, infile);
if (c != 0 || buf[0] != '\0') { /* normal record */
! if (isrecord) {
! if (freeable(fldtab[0]))
! xfree(fldtab[0]->sval);
! fldtab[0]->sval = buf; /* buf == record */
! fldtab[0]->tval = REC | STR | DONTFREE;
! if (is_number(fldtab[0]->sval)) {
! fldtab[0]->fval =
! atof((const char *)fldtab[0]->sval);
! fldtab[0]->tval |= NUM;
}
}
(void) setfval(nrloc, nrloc->fval+1);
(void) setfval(fnrloc, fnrloc->fval+1);
+ *pbuf = buf;
+ *pbufsize = bufsize;
return (1);
}
/* EOF arrived on this file; set up next */
if (infile != stdin)
(void) fclose(infile);
infile = NULL;
argno++;
}
+ buf[0] = saveb0;
+ *pbuf = buf;
+ *pbufsize = savebufsize;
return (0); /* true end of file */
}
+ void
+ nextfile(void)
+ {
+ if (infile != NULL && infile != stdin)
+ (void) fclose(infile);
+ infile = NULL;
+ argno++;
+ }
+
+ /*
+ * read one record into buf
+ */
int
! readrec(uchar **pbuf, size_t *pbufsize, FILE *inf)
{
int sep, c;
! uchar *rr, *buf = *pbuf;
! size_t bufsize = *pbufsize;
!
! if (strlen((char *)*FS) >= sizeof (inputFS))
! FATAL("field separator %.10s... is too long", *FS);
! /*
! * fflush(stdout); avoids some buffering problem
! * but makes it 25% slower
! */
! /* for subsequent field splitting */
! (void) strcpy(inputFS, (char *)*FS);
if ((sep = **RS) == 0) {
sep = '\n';
/* skip leading \n's */
while ((c = getc(inf)) == '\n' && c != EOF)
;
if (c != EOF)
(void) ungetc(c, inf);
}
! for (rr = buf; ; ) {
! for (; (c = getc(inf)) != sep && c != EOF; ) {
! if (rr-buf+1 > bufsize)
! if (!adjbuf(&buf, &bufsize, 1+rr-buf,
! record_size, &rr, "readrec 1"))
! FATAL(
! "input record `%.30s...' too long", buf);
! *rr++ = c;
}
if (**RS == sep || c == EOF)
break;
if ((c = getc(inf)) == '\n' || c == EOF) /* 2 in a row */
break;
! if (!adjbuf(&buf, &bufsize, 2+rr-buf, record_size, &rr,
! "readrec 2"))
! FATAL("input record `%.30s...' too long", buf);
! *rr++ = '\n';
! *rr++ = c;
! }
! if (!adjbuf(&buf, &bufsize, 1+rr-buf, record_size, &rr, "readrec 3"))
! FATAL("input record `%.30s...' too long", buf);
! *rr = 0;
dprintf(("readrec saw <%s>, returns %d\n",
! buf, c == EOF && rr == buf ? 0 : 1));
! *pbuf = buf;
! *pbufsize = bufsize;
! return (c == EOF && rr == buf ? 0 : 1);
}
static uchar *
! getargv(int n) /* get ARGV[n] */
{
Cell *x;
! uchar *s, temp[50];
extern Array *ARGVtab;
(void) sprintf((char *)temp, "%d", n);
+ if (lookup(temp, ARGVtab) == NULL)
+ return (NULL);
x = setsymtab(temp, (uchar *)"", 0.0, STR, ARGVtab);
s = getsval(x);
dprintf(("getargv(%d) returns |%s|\n", n, s));
return (s);
}
*** 215,450 ****
if (is_number(q->sval)) {
q->fval = atof((const char *)q->sval);
q->tval |= NUM;
}
dprintf(("command line set %s to |%s|\n", s, p));
- free(p);
}
void
! fldbld(void)
{
uchar *r, *fr, sep;
Cell *p;
! int i;
! size_t len;
if (donefld)
return;
! if (!(recloc->tval & STR))
! (void) getsval(recloc);
! r = recloc->sval; /* was record! */
!
! /* make sure fields is always allocated */
! adjust_buf(&fields, fields_size);
!
! /*
! * make sure fields has enough size. We don't expand the buffer
! * in the middle of the loop, since p->sval has already pointed
! * the address in the fields.
! */
! len = strlen((char *)r) + 1;
! expand_buf(&fields, &fields_size, len);
fr = fields;
-
i = 0; /* number of fields accumulated here */
! if (strlen((char *)*FS) > 1) { /* it's a regular expression */
! i = refldbld(r, *FS);
! } else if ((sep = **FS) == ' ') {
for (i = 0; ; ) {
while (*r == ' ' || *r == '\t' || *r == '\n')
r++;
if (*r == 0)
break;
i++;
! p = getfld(i);
! if (!(p->tval & DONTFREE))
! xfree(p->sval);
! p->sval = fr;
! p->tval = FLD | STR | DONTFREE;
do
*fr++ = *r++;
while (*r != ' ' && *r != '\t' && *r != '\n' &&
*r != '\0')
;
*fr++ = 0;
}
*fr = 0;
} else if (*r != 0) { /* if 0, it's a null field */
for (;;) {
i++;
! p = getfld(i);
! if (!(p->tval & DONTFREE))
! xfree(p->sval);
! p->sval = fr;
! p->tval = FLD | STR | DONTFREE;
! /* \n always a separator */
! while (*r != sep && *r != '\n' && *r != '\0')
*fr++ = *r++;
*fr++ = 0;
if (*r++ == 0)
break;
}
*fr = 0;
}
/* clean out junk from previous record */
! cleanfld(i, maxfld);
! maxfld = i;
donefld = 1;
! for (i = 1; i <= maxfld; i++) {
! p = getfld(i);
if (is_number(p->sval)) {
p->fval = atof((const char *)p->sval);
p->tval |= NUM;
}
}
!
! (void) setfval(nfloc, (Awkfloat) maxfld);
if (dbg) {
! for (i = 0; i <= maxfld; i++) {
! p = getfld(i);
! (void) printf("field %d: |%s|\n", i, p->sval);
}
}
}
static void
cleanfld(int n1, int n2) /* clean out fields n1..n2 inclusive */
! {
! static uchar *nullstat = (uchar *) "";
Cell *p;
int i;
! for (i = n2; i > n1; i--) {
! p = getfld(i);
! if (!(p->tval & DONTFREE))
xfree(p->sval);
- p->tval = FLD | STR | DONTFREE;
p->sval = nullstat;
}
}
void
! newfld(int n) /* add field n (after end) */
! {
! if (n < 0)
! ERROR "accessing invalid field", record FATAL;
! (void) getfld(n);
! cleanfld(maxfld, n);
! maxfld = n;
! (void) setfval(nfloc, (Awkfloat) n);
! }
!
! /*
! * allocate field table. We don't reallocate the table since there
! * might be somewhere recording the address of the table.
! */
! static void
! morefld(void)
{
! int i;
! struct fldtab_chunk *fldcp;
! Cell *newfld;
!
! if ((fldcp = calloc(sizeof (struct fldtab_chunk), 1)) == NULL)
! ERROR "out of space in morefld" FATAL;
!
! newfld = &fldcp->fields[0];
! for (i = 0; i < FLD_INCR; i++) {
! newfld[i].ctype = OCELL;
! newfld[i].csub = CFLD;
! newfld[i].nval = NULL;
! newfld[i].sval = (uchar *)"";
! newfld[i].fval = 0.0;
! newfld[i].tval = FLD|STR|DONTFREE;
! newfld[i].cnext = NULL;
! }
! /*
! * link this field chunk
! */
! if (fldtab_head == NULL)
! fldtab_head = fldcp;
! else
! fldtab_tail->next = fldcp;
! fldtab_tail = fldcp;
! fldcp->next = NULL;
!
! fldtab_maxidx += FLD_INCR;
}
Cell *
! getfld(int idx)
{
! struct fldtab_chunk *fldcp;
! int cbase;
!
! if (idx < 0)
! ERROR "trying to access field %d", idx FATAL;
! while (idx >= fldtab_maxidx)
! morefld();
! cbase = 0;
! for (fldcp = fldtab_head; fldcp != NULL; fldcp = fldcp->next) {
! if (idx < (cbase + FLD_INCR))
! return (&fldcp->fields[idx - cbase]);
! cbase += FLD_INCR;
! }
! /* should never happen */
! ERROR "trying to access invalid field %d", idx FATAL;
! return (NULL);
}
! int
! fldidx(Cell *vp)
! {
! struct fldtab_chunk *fldcp;
! Cell *tbl;
! int cbase;
!
! cbase = 0;
! for (fldcp = fldtab_head; fldcp != NULL; fldcp = fldcp->next) {
! tbl = &fldcp->fields[0];
! if (vp >= tbl && vp < (tbl + FLD_INCR))
! return (cbase + (vp - tbl));
! cbase += FLD_INCR;
! }
! /* should never happen */
! ERROR "trying to access unknown field" FATAL;
! return (0);
}
static int
refldbld(uchar *rec, uchar *fs) /* build fields from reg expr in FS */
{
uchar *fr;
int i, tempstat;
fa *pfa;
! Cell *p;
! size_t len;
! /* make sure fields is allocated */
! adjust_buf(&fields, fields_size);
fr = fields;
*fr = '\0';
if (*rec == '\0')
return (0);
-
- len = strlen((char *)rec) + 1;
- expand_buf(&fields, &fields_size, len);
- fr = fields;
-
pfa = makedfa(fs, 1);
dprintf(("into refldbld, rec = <%s>, pat = <%s>\n", rec, fs));
tempstat = pfa->initstat;
for (i = 1; ; i++) {
! p = getfld(i);
! if (!(p->tval & DONTFREE))
! xfree(p->sval);
! p->tval = FLD | STR | DONTFREE;
! p->sval = fr;
dprintf(("refldbld: i=%d\n", i));
if (nematch(pfa, rec)) {
! pfa->initstat = 2;
dprintf(("match %s (%d chars)\n", patbeg, patlen));
(void) strncpy((char *)fr, (char *)rec, patbeg-rec);
fr += patbeg - rec + 1;
*(fr-1) = '\0';
rec = patbeg + patlen;
--- 312,526 ----
if (is_number(q->sval)) {
q->fval = atof((const char *)q->sval);
q->tval |= NUM;
}
dprintf(("command line set %s to |%s|\n", s, p));
}
void
! fldbld(void) /* create fields from current record */
{
+ /* this relies on having fields[] the same length as $0 */
+ /* the fields are all stored in this one array with \0's */
+ /* possibly with a final trailing \0 not associated with any field */
uchar *r, *fr, sep;
Cell *p;
! int i, j;
! size_t n;
if (donefld)
return;
! if (!isstr(fldtab[0]))
! (void) getsval(fldtab[0]);
! r = fldtab[0]->sval;
! n = strlen((char *)r);
! if (n > fields_size) {
! xfree(fields);
! /* possibly 2 final \0s */
! if ((fields = (uchar *)malloc(n + 2)) == NULL)
! FATAL("out of space for fields in fldbld %d", n);
! fields_size = n;
! }
fr = fields;
i = 0; /* number of fields accumulated here */
! (void) strcpy(inputFS, (char *)*FS);
! if (strlen(inputFS) > 1) { /* it's a regular expression */
! i = refldbld(r, (uchar *)inputFS);
! } else if ((sep = *inputFS) == ' ') { /* default whitespace */
for (i = 0; ; ) {
while (*r == ' ' || *r == '\t' || *r == '\n')
r++;
if (*r == 0)
break;
i++;
! if (i > nfields)
! growfldtab(i);
! if (freeable(fldtab[i]))
! xfree(fldtab[i]->sval);
! fldtab[i]->sval = fr;
! fldtab[i]->tval = FLD | STR | DONTFREE;
do
*fr++ = *r++;
while (*r != ' ' && *r != '\t' && *r != '\n' &&
*r != '\0')
;
*fr++ = 0;
}
*fr = 0;
+ } else if ((sep = *inputFS) == 0) { /* new: FS="" => 1 char/field */
+ for (i = 0; *r != 0; r++) {
+ uchar buf[2];
+ i++;
+ if (i > nfields)
+ growfldtab(i);
+ if (freeable(fldtab[i]))
+ xfree(fldtab[i]->sval);
+ buf[0] = *r;
+ buf[1] = 0;
+ fldtab[i]->sval = tostring(buf);
+ fldtab[i]->tval = FLD | STR;
+ }
+ *fr = 0;
} else if (*r != 0) { /* if 0, it's a null field */
+ /*
+ * subtlecase : if length(FS) == 1 && length(RS > 0)
+ * \n is NOT a field separator (cf awk book 61,84).
+ * this variable is tested in the inner while loop.
+ */
+ int rtest = '\n'; /* normal case */
+ if (strlen((char *)*RS) > 0)
+ rtest = '\0';
for (;;) {
i++;
! if (i > nfields)
! growfldtab(i);
! if (freeable(fldtab[i]))
! xfree(fldtab[i]->sval);
! fldtab[i]->sval = fr;
! fldtab[i]->tval = FLD | STR | DONTFREE;
! /* \n is always a separator */
! while (*r != sep && *r != rtest && *r != '\0')
*fr++ = *r++;
*fr++ = 0;
if (*r++ == 0)
break;
}
*fr = 0;
}
+ if (i > nfields)
+ FATAL("record `%.30s...' has too many fields; can't happen", r);
/* clean out junk from previous record */
! cleanfld(i + 1, lastfld);
! lastfld = i;
donefld = 1;
! for (j = 1; j <= lastfld; j++) {
! p = fldtab[j];
if (is_number(p->sval)) {
p->fval = atof((const char *)p->sval);
p->tval |= NUM;
}
}
! (void) setfval(nfloc, (Awkfloat)lastfld);
if (dbg) {
! for (j = 0; j <= lastfld; j++) {
! p = fldtab[j];
! (void) printf("field %d (%s): |%s|\n", j, p->nval,
! p->sval);
}
}
}
static void
cleanfld(int n1, int n2) /* clean out fields n1..n2 inclusive */
! { /* nvals remain intact */
! static uchar *nullstat = (uchar *)"";
Cell *p;
int i;
! for (i = n1; i <= n2; i++) {
! p = fldtab[i];
! if (freeable(p))
xfree(p->sval);
p->sval = nullstat;
+ p->tval = FLD | STR | DONTFREE;
}
}
void
! newfld(int n) /* add field n after end of existing lastfld */
{
! if (n > nfields)
! growfldtab(n);
! cleanfld(lastfld + 1, n);
! lastfld = n;
! (void) setfval(nfloc, (Awkfloat)n);
}
Cell *
! fieldadr(int n) /* get nth field */
{
! if (n < 0)
! FATAL("trying to access out of range field %d", n);
! if (n > nfields) /* fields after NF are empty */
! growfldtab(n); /* but does not increase NF */
! return (fldtab[n]);
}
! void
! growfldtab(int n) /* make new fields up to at least $n */
! {
! int nf = 2 * nfields;
! size_t s;
!
! if (n > nf)
! nf = n;
! /* freebsd: how much do we need? */
! s = (nf + 1) * (sizeof (struct Cell *));
! if (s / sizeof (struct Cell *) - 1 == nf) /* didn't overflow */
! fldtab = (Cell **) realloc(fldtab, s);
! else /* overflow sizeof int */
! xfree(fldtab); /* make it null */
! if (fldtab == NULL)
! FATAL("out of space creating %d fields", nf);
! makefields(nfields + 1, nf);
! nfields = nf;
}
static int
refldbld(uchar *rec, uchar *fs) /* build fields from reg expr in FS */
{
+ /* this relies on having fields[] the same length as $0 */
+ /* the fields are all stored in this one array with \0's */
uchar *fr;
int i, tempstat;
fa *pfa;
! size_t n;
! n = strlen((char *)rec);
! if (n > fields_size) {
! xfree(fields);
! if ((fields = (uchar *)malloc(n + 1)) == NULL)
! FATAL("out of space for fields in refldbld %d", n);
! fields_size = n;
! }
fr = fields;
*fr = '\0';
if (*rec == '\0')
return (0);
pfa = makedfa(fs, 1);
dprintf(("into refldbld, rec = <%s>, pat = <%s>\n", rec, fs));
tempstat = pfa->initstat;
for (i = 1; ; i++) {
! if (i > nfields)
! growfldtab(i);
! if (freeable(fldtab[i]))
! xfree(fldtab[i]->sval);
! fldtab[i]->tval = FLD | STR | DONTFREE;
! fldtab[i]->sval = fr;
dprintf(("refldbld: i=%d\n", i));
if (nematch(pfa, rec)) {
! pfa->initstat = 2; /* horrible coupling to b.c */
dprintf(("match %s (%d chars)\n", patbeg, patlen));
(void) strncpy((char *)fr, (char *)rec, patbeg-rec);
fr += patbeg - rec + 1;
*(fr-1) = '\0';
rec = patbeg + patlen;
*** 457,531 ****
}
return (i);
}
void
! recbld(void)
{
int i;
! uchar *p;
! size_t cnt, len, olen;
if (donerec == 1)
return;
! cnt = 0;
! olen = strlen((char *)*OFS);
for (i = 1; i <= *NF; i++) {
! p = getsval(getfld(i));
! len = strlen((char *)p);
! expand_buf(&record, &record_size, cnt + len + olen);
! (void) memcpy(&record[cnt], p, len);
! cnt += len;
if (i < *NF) {
! (void) memcpy(&record[cnt], *OFS, olen);
! cnt += olen;
}
}
! record[cnt] = '\0';
! dprintf(("in recbld FS=%o, recloc=%p\n", **FS, (void *)recloc));
! if (!(recloc->tval & DONTFREE))
! xfree(recloc->sval);
! recloc->tval = REC | STR | DONTFREE;
! recloc->sval = record;
! dprintf(("in recbld FS=%o, recloc=%p\n", **FS, (void *)recloc));
dprintf(("recbld = |%s|\n", record));
donerec = 1;
}
- Cell *
- fieldadr(int n)
- {
- if (n < 0)
- ERROR "trying to access field %d", n FATAL;
- return (getfld(n));
- }
-
int errorflag = 0;
- char errbuf[200];
void
yyerror(char *s)
{
extern uchar *cmdname, *curfname;
static int been_here = 0;
if (been_here++ > 2)
return;
! (void) fprintf(stderr, "%s: %s", cmdname, s);
(void) fprintf(stderr, gettext(" at source line %lld"), lineno);
if (curfname != NULL)
(void) fprintf(stderr, gettext(" in function %s"), curfname);
(void) fprintf(stderr, "\n");
errorflag = 2;
eprint();
}
- /*ARGSUSED*/
void
! fpecatch(int sig)
{
! ERROR "floating point exception" FATAL;
}
extern int bracecnt, brackcnt, parencnt;
void
--- 533,619 ----
}
return (i);
}
void
! recbld(void) /* create $0 from $1..$NF if necessary */
{
int i;
! uchar *r, *p;
if (donerec == 1)
return;
! r = record;
for (i = 1; i <= *NF; i++) {
! p = getsval(fldtab[i]);
! if (!adjbuf(&record, &record_size, 1 + strlen((char *)p) + r -
! record, record_size, &r, "recbld 1"))
! FATAL("created $0 `%.30s...' too long", record);
! while ((*r = *p++) != 0)
! r++;
if (i < *NF) {
! if (!adjbuf(&record, &record_size, 2 +
! strlen((char *)*OFS) + r - record, record_size,
! &r, "recbld 2"))
! FATAL("created $0 `%.30s...' too long", record);
! for (p = *OFS; (*r = *p++) != 0; )
! r++;
}
}
! if (!adjbuf(&record, &record_size, 2 + r - record, record_size, &r,
! "recbld 3"))
! FATAL("built giant record `%.30s...'", record);
! *r = '\0';
! dprintf(("in recbld inputFS=%s, fldtab[0]=%p\n", inputFS,
! (void *)fldtab[0]));
!
! if (freeable(fldtab[0]))
! xfree(fldtab[0]->sval);
! fldtab[0]->tval = REC | STR | DONTFREE;
! fldtab[0]->sval = record;
!
! dprintf(("in recbld inputFS=%s, fldtab[0]=%p\n", inputFS,
! (void *)fldtab[0]));
dprintf(("recbld = |%s|\n", record));
donerec = 1;
}
int errorflag = 0;
void
yyerror(char *s)
{
+ SYNTAX("%s", s);
+ }
+
+ void
+ SYNTAX(const char *fmt, ...)
+ {
extern uchar *cmdname, *curfname;
static int been_here = 0;
+ va_list varg;
if (been_here++ > 2)
return;
! (void) fprintf(stderr, "%s: ", cmdname);
! va_start(varg, fmt);
! (void) vfprintf(stderr, fmt, varg);
! va_end(varg);
(void) fprintf(stderr, gettext(" at source line %lld"), lineno);
if (curfname != NULL)
(void) fprintf(stderr, gettext(" in function %s"), curfname);
+ if (compile_time == 1 && cursource() != NULL)
+ (void) fprintf(stderr, gettext(" source file %s"), cursource());
(void) fprintf(stderr, "\n");
errorflag = 2;
eprint();
}
void
! fpecatch(int n)
{
! FATAL("floating point exception %d", n);
}
extern int bracecnt, brackcnt, parencnt;
void
*** 556,603 ****
else if (n < -1)
(void) fprintf(stderr, gettext("\t%d extra %c's\n"), -n, c2);
}
void
! error(int f, char *s)
{
- extern Node *curnode;
extern uchar *cmdname;
(void) fflush(stdout);
(void) fprintf(stderr, "%s: ", cmdname);
! (void) fprintf(stderr, "%s", s);
(void) fprintf(stderr, "\n");
if (compile_time != 2 && NR && *NR > 0) {
(void) fprintf(stderr,
! gettext(" input record number %g"), *FNR);
if (strcmp((char *)*FILENAME, "-") != 0)
(void) fprintf(stderr, gettext(", file %s"), *FILENAME);
(void) fprintf(stderr, "\n");
}
if (compile_time != 2 && curnode)
! (void) fprintf(stderr, gettext(" source line number %lld\n"),
curnode->lineno);
else if (compile_time != 2 && lineno) {
(void) fprintf(stderr,
! gettext(" source line number %lld\n"), lineno);
}
eprint();
- if (f) {
- if (dbg)
- abort();
- exit(2);
- }
}
static void
eprint(void) /* try to print context around error */
{
uchar *p, *q;
int c;
static int been_here = 0;
! extern uchar ebuf[300], *ep;
if (compile_time == 2 || compile_time == 0 || been_here++ > 0)
return;
p = ep - 1;
if (p > ebuf && *p == '\n')
--- 644,717 ----
else if (n < -1)
(void) fprintf(stderr, gettext("\t%d extra %c's\n"), -n, c2);
}
void
! FATAL(const char *fmt, ...)
{
extern uchar *cmdname;
+ va_list varg;
(void) fflush(stdout);
(void) fprintf(stderr, "%s: ", cmdname);
! va_start(varg, fmt);
! (void) vfprintf(stderr, fmt, varg);
! va_end(varg);
! error();
! if (dbg > 1) /* core dump if serious debugging on */
! abort();
! exit(2);
! }
!
! void
! WARNING(const char *fmt, ...)
! {
! extern uchar *cmdname;
! va_list varg;
!
! (void) fflush(stdout);
! (void) fprintf(stderr, "%s: ", cmdname);
! va_start(varg, fmt);
! (void) vfprintf(stderr, fmt, varg);
! va_end(varg);
! error();
! }
!
! void
! error(void)
! {
! extern Node *curnode;
!
(void) fprintf(stderr, "\n");
if (compile_time != 2 && NR && *NR > 0) {
(void) fprintf(stderr,
! gettext(" input record number %g"), (int) (*FNR));
if (strcmp((char *)*FILENAME, "-") != 0)
(void) fprintf(stderr, gettext(", file %s"), *FILENAME);
(void) fprintf(stderr, "\n");
}
if (compile_time != 2 && curnode)
! (void) fprintf(stderr, gettext(" source line number %d"),
curnode->lineno);
else if (compile_time != 2 && lineno) {
(void) fprintf(stderr,
! gettext(" source line number %d"), lineno);
}
+ if (compile_time == 1 && cursource() != NULL)
+ (void) fprintf(stderr,
+ gettext(" source file %s"), cursource());
+ (void) fprintf(stderr, "\n");
eprint();
}
static void
eprint(void) /* try to print context around error */
{
uchar *p, *q;
int c;
static int been_here = 0;
! extern uchar ebuf[], *ep;
if (compile_time == 2 || compile_time == 0 || been_here++ > 0)
return;
p = ep - 1;
if (p > ebuf && *p == '\n')
*** 638,795 ****
case ')': parencnt--; break;
}
}
double
! errcheck(double x, char *s)
{
- extern int errno;
-
if (errno == EDOM) {
errno = 0;
! ERROR "%s argument out of domain", s WARNING;
x = 1;
} else if (errno == ERANGE) {
errno = 0;
! ERROR "%s result out of range", s WARNING;
x = 1;
}
return (x);
}
- void
- PUTS(uchar *s)
- {
- dprintf(("%s\n", s));
- }
-
int
! isclvar(uchar *s) /* is s of form var=something? */
{
! if (s != NULL) {
! /* Must begin with an underscore or alphabetic character */
! if (isalpha(*s) || (*s == '_')) {
!
! for (s++; *s; s++) {
! /*
! * followed by a sequence of underscores,
! * digits, and alphabetics
! */
! if (!(isalnum(*s) || *s == '_')) {
break;
}
- }
- return (*s == '=' && *(s + 1) != '=');
- }
- }
! return (0);
}
! #define MAXEXPON 38 /* maximum exponent for fp number */
int
! is_number(uchar *s)
{
! int d1, d2;
! int point;
! uchar *es;
! extern char radixpoint;
!
! d1 = d2 = point = 0;
! while (*s == ' ' || *s == '\t' || *s == '\n')
! s++;
! if (*s == '\0')
! return (0); /* empty stuff isn't number */
! if (*s == '+' || *s == '-')
! s++;
! if (!isdigit(*s) && *s != radixpoint)
! return (0);
! if (isdigit(*s)) {
! do {
! d1++;
! s++;
! } while (isdigit(*s));
! }
! if (d1 >= MAXEXPON)
! return (0); /* too many digits to convert */
! if (*s == radixpoint) {
! point++;
! s++;
! }
! if (isdigit(*s)) {
! d2++;
! do {
! s++;
! } while (isdigit(*s));
! }
! if (!(d1 || point && d2))
! return (0);
! if (*s == 'e' || *s == 'E') {
! s++;
! if (*s == '+' || *s == '-')
! s++;
! if (!isdigit(*s))
! return (0);
! es = s;
! do {
! s++;
! } while (isdigit(*s));
! if (s - es > 2) {
! return (0);
! } else if (s - es == 2 &&
! (int)(10 * (*es-'0') + *(es+1)-'0') >= MAXEXPON) {
return (0);
! }
! }
! while (*s == ' ' || *s == '\t' || *s == '\n')
! s++;
! if (*s == '\0')
return (1);
else
return (0);
}
-
- void
- init_buf(uchar **optr, size_t *sizep, size_t amt)
- {
- uchar *nptr = NULL;
-
- if ((nptr = malloc(amt)) == NULL)
- ERROR "out of space in init_buf" FATAL;
- /* initial buffer should have NULL terminated */
- *nptr = '\0';
- if (sizep != NULL)
- *sizep = amt;
- *optr = nptr;
- }
-
- void
- r_expand_buf(uchar **optr, size_t *sizep, size_t req)
- {
- uchar *nptr;
- size_t amt, size = *sizep;
-
- if (size != 0 && req < (size - 1))
- return;
- amt = req + 1 - size;
- amt = (amt / LINE_INCR + 1) * LINE_INCR;
-
- if ((nptr = realloc(*optr, size + amt)) == NULL)
- ERROR "out of space in expand_buf" FATAL;
- /* initial buffer should have NULL terminated */
- if (size == 0)
- *nptr = '\0';
- *sizep += amt;
- *optr = nptr;
- }
-
- void
- adjust_buf(uchar **optr, size_t size)
- {
- uchar *nptr;
-
- if ((nptr = realloc(*optr, size)) == NULL)
- ERROR "out of space in adjust_buf" FATAL;
- *optr = nptr;
- }
--- 752,805 ----
case ')': parencnt--; break;
}
}
double
! errcheck(double x, const char *s)
{
if (errno == EDOM) {
errno = 0;
! WARNING("%s argument out of domain", s);
x = 1;
} else if (errno == ERANGE) {
errno = 0;
! WARNING("%s result out of range", s);
x = 1;
}
return (x);
}
int
! isclvar(const uchar *s) /* is s of form var=something? */
{
! const uchar *os = s;
! if (!isalpha(*s) && *s != '_')
! return (0);
! for (; *s; s++) {
! if (!(isalnum(*s) || *s == '_'))
break;
}
! return (*s == '=' && s > os && *(s+1) != '=');
}
! /* strtod is supposed to be a proper test of what's a valid number */
! /* appears to be broken in gcc on linux: thinks 0x123 is a valid FP number */
! /* wrong: violates 4.10.1.4 of ansi C standard */
int
! is_number(const uchar *s)
{
! double r;
! char *ep;
! errno = 0;
! r = strtod((const char *)s, &ep);
! if (ep == (char *)s || r == HUGE_VAL || errno == ERANGE)
return (0);
! while (*ep == ' ' || *ep == '\t' || *ep == '\n')
! ep++;
! if (*ep == '\0')
return (1);
else
return (0);
}