Update field-splitting behaviour to match POSIX definition

This commit is contained in:
Cody Peter Mello 2018-10-19 15:07:53 -07:00
parent fabf9efece
commit b463680594
3 changed files with 20 additions and 7 deletions

24
lib.c
View File

@ -104,6 +104,22 @@ void initgetrec(void)
infile = stdin; /* no filenames, so use stdin */
}
/*
* POSIX specifies that fields are supposed to be evaluated as if they were
* split using the value of FS at the time that the record's value ($0) was
* read.
*
* Since field-splitting is done lazily, we save the current value of FS
* whenever a new record is read in (implicitly or via getline), or when
* a new value is assigned to $0.
*/
void savefs(void)
{
if (strlen(getsval(fsloc)) >= sizeof (inputFS))
FATAL("field separator %.10s... is too long", *FS);
strcpy(inputFS, *FS);
}
static int firsttime = 1;
int getrec(char **pbuf, int *pbufsize, int isrecord) /* get next input record */
@ -122,6 +138,7 @@ int getrec(char **pbuf, int *pbufsize, int isrecord) /* get next input record */
if (isrecord) {
donefld = 0;
donerec = 1;
savefs();
}
saveb0 = buf[0];
buf[0] = 0;
@ -191,10 +208,6 @@ int readrec(char **pbuf, int *pbufsize, FILE *inf) /* read one record into buf *
int bufsize = *pbufsize;
char *rs = getsval(rsloc);
if (strlen(getsval(fsloc)) >= sizeof (inputFS))
FATAL("field separator %.10s... is too long", *FS);
/*fflush(stdout); avoids some buffering problem but makes it 25% slower*/
strcpy(inputFS, *FS); /* for subsequent field splitting */
if ((sep = *rs) == 0) {
sep = '\n';
while ((c=getc(inf)) == '\n' && c != EOF) /* skip leading \n's */
@ -284,9 +297,6 @@ void fldbld(void) /* create fields from current record */
}
fr = fields;
i = 0; /* number of fields accumulated here */
if (strlen(getsval(fsloc)) >= sizeof (inputFS))
FATAL("field separator %.10s... is too long", *FS);
strcpy(inputFS, *FS);
if (strlen(inputFS) > 1) { /* it's a regular expression */
i = refldbld(r, inputFS);
} else if ((sep = *inputFS) == ' ') { /* default whitespace */

View File

@ -116,6 +116,7 @@ extern void recinit(unsigned int);
extern void initgetrec(void);
extern void makefields(int, int);
extern void growfldtab(int n);
extern void savefs(void);
extern int getrec(char **, int *, int);
extern void nextfile(void);
extern int readrec(char **buf, int *bufsize, FILE *inf);

2
tran.c
View File

@ -318,6 +318,7 @@ Awkfloat setfval(Cell *vp, Awkfloat f) /* set float val of a Cell */
} else if (isrec(vp)) {
donefld = 0; /* mark $1... invalid */
donerec = 1;
savefs();
} else if (vp == ofsloc) {
if (donerec == 0)
recbld();
@ -362,6 +363,7 @@ char *setsval(Cell *vp, const char *s) /* set string val of a Cell */
} else if (isrec(vp)) {
donefld = 0; /* mark $1... invalid */
donerec = 1;
savefs();
} else if (vp == ofsloc) {
if (donerec == 0)
recbld();