diff options
-rw-r--r-- | ChangeLog | 18 | ||||
-rw-r--r-- | array.c | 2 | ||||
-rw-r--r-- | awk.h | 5 | ||||
-rw-r--r-- | eval.c | 1 | ||||
-rw-r--r-- | field.c | 22 | ||||
-rw-r--r-- | interpret.h | 14 | ||||
-rw-r--r-- | node.c | 1 |
7 files changed, 47 insertions, 16 deletions
@@ -1,3 +1,21 @@ +2016-07-05 Andrew J. Schorr <aschorr@telemetry-investments.com> + + * awk.h (FIELD): Remove unnecessary flag. + (MALLOC): Move definition to join the others, and improve the comment. + * array.c (value_info): Replace FIELD test with MALLOC test. + * eval.c (flags2str): Remove FIELD flag. + * field.c (init_fields): Remove FIELD bit from Null_field->flags. + (set_field): Remove FIELD bit from flags. + (rebuild_record): Test against MALLOC instead of FIELD. If a field + node has valref > 1, we should make a copy, although I don't think + it is valid for this to happen. + (set_record): Remove FIELD bit from flags. + * interpret.h (UNFIELD): Add comment, and test MALLOC flag instead of + FIELD. Remove probably buggy code to disable the FIELD flag when + valref is 1; that would have created a node where neither the FIELD + nor MALLOC flag was set, which seems invalid. + * node.c (r_dupnode): Remove code disabling FIELD flag. + 2016-07-04 Andrew J. Schorr <aschorr@telemetry-investments.com> * awk.h (force_string_fmt): New inline function to get the string @@ -696,7 +696,7 @@ value_info(NODE *n) fprintf(output_fp, ":%s", flags2str(n->flags)); - if ((n->flags & FIELD) == 0) + if ((n->flags & MALLOC) != 0) fprintf(output_fp, ":%ld", n->valref); else fprintf(output_fp, ":"); @@ -387,9 +387,6 @@ typedef struct exp_node { NODETYPE type; unsigned int flags; -/* any type */ -# define MALLOC 0x0001 /* can be free'd */ - /* type = Node_val */ /* * STRING and NUMBER are mutually exclusive, except for the special @@ -426,13 +423,13 @@ typedef struct exp_node { * * We hope that the rest of the flags are self-explanatory. :-) */ +# define MALLOC 0x0001 /* stptr can be free'd, i.e. not a field node pointing into a shared buffer */ # define STRING 0x0002 /* assigned as string */ # define STRCUR 0x0004 /* string value is current */ # define NUMCUR 0x0008 /* numeric value is current */ # define NUMBER 0x0010 /* assigned as number */ # define MAYBE_NUM 0x0020 /* user input: if NUMERIC then * a NUMBER */ -# define FIELD 0x0040 /* this is a field */ # define INTLSTR 0x0080 /* use localized version */ # define NUMINT 0x0100 /* numeric value is an integer */ # define INTIND 0x0200 /* integral value is array index; @@ -435,7 +435,6 @@ flags2str(int flagval) { NUMCUR, "NUMCUR" }, { NUMBER, "NUMBER" }, { MAYBE_NUM, "MAYBE_NUM" }, - { FIELD, "FIELD" }, { INTLSTR, "INTLSTR" }, { NUMINT, "NUMINT" }, { INTIND, "INTIND" }, @@ -93,7 +93,7 @@ init_fields() getnode(Null_field); *Null_field = *Nnull_string; Null_field->valref = 1; - Null_field->flags = (FIELD|STRCUR|STRING|NULL_FIELD); + Null_field->flags = (STRCUR|STRING|NULL_FIELD); /* do not set MALLOC */ field0_valid = true; } @@ -131,7 +131,7 @@ set_field(long num, n = fields_arr[num]; n->stptr = str; n->stlen = len; - n->flags = (STRCUR|STRING|MAYBE_NUM|FIELD); + n->flags = (STRCUR|STRING|MAYBE_NUM); /* do not set MALLOC */ } /* rebuild_record --- Someone assigned a value to $(something). @@ -198,7 +198,7 @@ rebuild_record() NODE *n; getnode(n); - if ((r->flags & FIELD) == 0) { + if ((r->flags & MALLOC) != 0) { *n = *Null_field; n->stlen = r->stlen; if ((r->flags & (NUMCUR|NUMBER)) != 0) { @@ -216,7 +216,19 @@ rebuild_record() } } else { *n = *r; - n->flags &= ~MALLOC; + if (r->valref > 1) { + /* + * XXX This probably should never + * happen, but we can't leave r with + * stptr pointing into the old $0 + * buffer. Perhaps we should issue a + * warning message about memory + * corruption... + */ + emalloc(r->stptr, char *, r->stlen + 1, "rebuild_record"); + memcpy(r->stptr, cops, r->stlen); + r->stptr[r->stlen] = '\0'; + } } n->stptr = cops; @@ -289,7 +301,7 @@ set_record(const char *buf, int cnt) n->valref = 1; n->type = Node_val; n->stfmt = STFMT_UNUSED; - n->flags = (STRING|STRCUR|MAYBE_NUM|FIELD); + n->flags = (STRING|STRCUR|MAYBE_NUM); /* do not set MALLOC */ fields_arr[0] = n; #undef INITIAL_SIZE diff --git a/interpret.h b/interpret.h index 3bb4532e..bbddd5a7 100644 --- a/interpret.h +++ b/interpret.h @@ -23,13 +23,19 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +/* + * If "r" is a field, valref should normally be > 1, because the field is + * created initially with valref 1, and valref should be bumped when it is + * pushed onto the stack by Op_field_spec. On the other hand, if we are + * assigning to $n, then Op_store_field calls unref(*lhs) before assigning + * the new value, so that decrements valref. So if the RHS is a field with + * valref 1, that effectively means that this is an assignment like "$n = $n", + * so a no-op, other than triggering $0 reconstitution. + */ #define UNFIELD(l, r) \ { \ /* if was a field, turn it into a var */ \ - if ((r->flags & FIELD) == 0) { \ - l = r; \ - } else if (r->valref == 1) { \ - r->flags &= ~FIELD; \ + if ((r->flags & MALLOC) != 0 || r->valref == 1) { \ l = r; \ } else { \ l = dupnode(r); \ @@ -300,7 +300,6 @@ r_dupnode(NODE *n) getnode(r); *r = *n; - r->flags &= ~FIELD; r->flags |= MALLOC; r->valref = 1; /* |