summaryrefslogtreecommitdiff
path: root/usr/src/cmd/awk
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd/awk')
-rw-r--r--usr/src/cmd/awk/awk.h1
-rw-r--r--usr/src/cmd/awk/lib.c24
-rw-r--r--usr/src/cmd/awk/tran.c2
3 files changed, 21 insertions, 6 deletions
diff --git a/usr/src/cmd/awk/awk.h b/usr/src/cmd/awk/awk.h
index b1db39fadb..01495d108d 100644
--- a/usr/src/cmd/awk/awk.h
+++ b/usr/src/cmd/awk/awk.h
@@ -338,6 +338,7 @@ extern void FATAL(const char *, ...) __attribute__((__noreturn__));
extern void WARNING(const char *, ...);
extern void error(void);
extern void nextfile(void);
+extern void savefs(void);
extern int isclvar(const char *);
extern int is_number(const char *);
diff --git a/usr/src/cmd/awk/lib.c b/usr/src/cmd/awk/lib.c
index ae60fde3f1..bec53b6e32 100644
--- a/usr/src/cmd/awk/lib.c
+++ b/usr/src/cmd/awk/lib.c
@@ -144,6 +144,23 @@ 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);
+ (void) strcpy(inputFS, *FS);
+}
+
static int firsttime = 1;
/*
@@ -167,6 +184,7 @@ getrec(char **pbuf, size_t *pbufsize, int isrecord)
if (isrecord) {
donefld = 0;
donerec = 1;
+ savefs();
}
saveb0 = buf[0];
buf[0] = '\0';
@@ -242,9 +260,6 @@ readrec(char **pbuf, size_t *pbufsize, FILE *inf) /* read one record into buf */
size_t bufsize = *pbufsize;
char *rs = getsval(rsloc);
- if (strlen(getsval(fsloc)) >= sizeof (inputFS))
- FATAL("field separator %.10s... is too long", *FS);
- (void) strcpy(inputFS, *FS); /* for subsequent field splitting */
if ((sep = *rs) == 0) {
sep = '\n';
/* skip leading \n's */
@@ -342,9 +357,6 @@ 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);
- (void) strcpy(inputFS, *FS);
if (strlen(inputFS) > 1) { /* it's a regular expression */
i = refldbld(r, inputFS);
} else if ((sep = *inputFS) == ' ') { /* default whitespace */
diff --git a/usr/src/cmd/awk/tran.c b/usr/src/cmd/awk/tran.c
index 012b90acf4..417bede66d 100644
--- a/usr/src/cmd/awk/tran.c
+++ b/usr/src/cmd/awk/tran.c
@@ -377,6 +377,7 @@ 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();
@@ -424,6 +425,7 @@ 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();