Aucbvax.4930 fa.unix-wizards utzoo!decvax!ucbvax!unix-wizards Tue Nov 3 00:03:04 1981 >From sdcsvax!sdcattb:madden@NPRDC Mon Nov 2 23:49:51 1981 The following simple awk program exhibits an apparant bug in awk's field handling: { $1 = "newfield1" v = $0 print v # This will erroneously generate the original # contents of field 1, not "newfield1". length # This implicit reference to $0 causes the following v = $0 # assignment to proceed properly so that print v # this statement prints the expected result } When pointed at an input record, such as abc this program will produce printoutwhich looks like abc newfield1 rather than the expected newfield1 newfield1 Since it is remotely possible that some program might take advantage of the update failure, perhaps this is not a bug although the inconsistency involved makes this unlikely. In any case, the following changes to awk sources run.c and lib.c correct the problem. The commented lines are the changes. Jim Madden UCSD Computer Center ------- run.c ------- obj nodetoobj(a) node *a; { obj x; x.optr = (cell *) a->nobj; x.otype = OCELL; x.osub = a->subtype; if (x.optr->sval == record && donerec == 0) /* Added to force recbld */ recbld(); /* on $1="ab"; x=$0 */ if (isfld(x)) fldbld(); return(x); } ------- lib.c ------- recbld() { int i; register char *r, *p; if (donefld == 0 || donerec == 1) return; donerec = 1; /* Added to avoid repeated calls on recbld */ r = record; for (i = 1; i <= *NF; i++) { p = getsval(&fldtab[i]); while (*r++ = *p++) ; *(r-1) = **OFS; } *(r-1) = '\0'; dprintf("in recbld FS=%o, recloc=%o\n", **FS, recloc, NULL); recloc->tval = STR | FLD; dprintf("in recbld FS=%o, recloc=%o\n", **FS, recloc, NULL); if (r > record+RECSIZE) error(FATAL, "built giant record `%.20s...'", record); dprintf("recbld = |%s|\n", record, NULL, NULL); }