NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
standards/44063: awk: setting NF doesn't affect $<fieldnum>
>Number: 44063
>Category: standards
>Synopsis: awk: setting NF doesn't change $i
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: standards-manager
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sun Nov 07 20:25:00 +0000 2010
>Originator: Aleksey Cheusov
>Release: NetBSD 5.1_RC4
>Organization:
>Environment:
System: NetBSD asrock.chizhovka.net 5.1_RC4 NetBSD 5.1_RC4 (GENERIC) #0: Sat
Oct 30 14:10:25 EEST 2010
cheusov%asrock.chizhovka.net@localhost:/srv/obj/sys/arch/amd64/compile/GENERIC
amd64
Architecture: x86_64
Machine: amd64
>Description:
http://www.opengroup.org/onlinepubs/009695399/utilities/awk.html
...
References to nonexistent fields (that is, fields after $NF),
shall evaluate to the uninitialized value.
Now awk works like the following
$ echo ' 1 2 3 ' | awk.orig '{NF=2; print "`" $3 "`"}'
`3`
$ echo ' 1 2 3 ' | awk.orig '{NF=2; print "`" $0 "`"}'
` 1 2 3 `
$
As far as I can see POSIX allows variantions about changing $0,
but gawk and mawk change it. The following patch solves the problem
with $3 and makes awk compatible with gawk and mawk.
Result:
$ echo ' 1 2 3 ' | awk '{NF=2; print "`" $3 "`"}'
``
$ echo ' 1 2 3 ' | awk '{NF=2; print "`" $0 "`"}'
`1 2`
$
>How-To-Repeat:
See above
>Fix:
Index: lib.c
===================================================================
RCS file: /cvsroot/src/dist/nawk/lib.c,v
retrieving revision 1.14
diff -u -r1.14 lib.c
--- lib.c 19 Oct 2008 19:33:47 -0000 1.14
+++ lib.c 7 Nov 2010 19:38:29 -0000
@@ -362,6 +362,7 @@
}
}
setfval(nfloc, (Awkfloat) lastfld);
+ donerec = 1; /* restore */
if (dbg) {
for (j = 0; j <= lastfld; j++) {
p = fldtab[j];
@@ -393,6 +394,19 @@
setfval(nfloc, (Awkfloat) n);
}
+void setlastfld(int n) /* set lastfld cleaning fldtab cells if necessary */
+{
+ if (n > nfields)
+ growfldtab(n);
+
+ if (lastfld < n)
+ cleanfld(lastfld+1, n);
+ else
+ cleanfld(n+1, lastfld);
+
+ lastfld = n;
+}
+
Cell *fieldadr(int n) /* get nth field */
{
if (n < 0)
Index: proto.h
===================================================================
RCS file: /cvsroot/src/dist/nawk/proto.h,v
retrieving revision 1.6.12.2
diff -u -r1.6.12.2 proto.h
--- proto.h 14 Aug 2009 20:32:21 -0000 1.6.12.2
+++ proto.h 7 Nov 2010 19:38:29 -0000
@@ -127,6 +127,7 @@
extern void fldbld(void);
extern void cleanfld(int, int);
extern void newfld(int);
+extern void setlastfld(int);
extern int refldbld(const char *, const char *);
extern void recbld(void);
extern Cell *fieldadr(int);
Index: tran.c
===================================================================
RCS file: /cvsroot/src/dist/nawk/tran.c,v
retrieving revision 1.14
diff -u -r1.14 tran.c
--- tran.c 19 Oct 2008 19:33:48 -0000 1.14
+++ tran.c 7 Nov 2010 19:38:29 -0000
@@ -298,6 +298,10 @@
if (fldno > *NF)
newfld(fldno);
dprintf( ("setting field %d to %g\n", fldno, f) );
+ } else if (&vp->fval == NF) {
+ donerec = 0; /* mark $0 invalid */
+ setlastfld(f);
+ dprintf( ("setting NF to %g\n", f) );
} else if (isrec(vp)) {
donefld = 0; /* mark $1... invalid */
donerec = 1;
@@ -324,6 +328,7 @@
{
char *t;
int fldno;
+ Awkfloat f;
dprintf( ("starting setsval %p: %s = \"%s\", t=%o, r,f=%d,%d\n",
vp, NN(vp->nval), s, vp->tval, donerec, donefld) );
@@ -347,6 +352,14 @@
vp->tval &= ~DONTFREE;
dprintf( ("setsval %p: %s = \"%s (%p) \", t=%o r,f=%d,%d\n",
vp, NN(vp->nval), t,t, vp->tval, donerec, donefld) );
+
+ if (&vp->fval == NF) {
+ donerec = 0; /* mark $0 invalid */
+ f = getfval(vp);
+ setlastfld(f);
+ dprintf( ("setting NF to %g\n", f) );
+ }
+
return(vp->sval = t);
}
Home |
Main Index |
Thread Index |
Old Index