Update field-splitting behaviour to match POSIX definition
This commit is contained in:
parent
fabf9efece
commit
b463680594
24
lib.c
24
lib.c
@ -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 */
|
||||
|
1
proto.h
1
proto.h
@ -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
2
tran.c
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user