diff options
author | Arnold D. Robbins <arnold@skeeve.com> | 2010-07-16 12:57:07 +0300 |
---|---|---|
committer | Arnold D. Robbins <arnold@skeeve.com> | 2010-07-16 12:57:07 +0300 |
commit | 3ca7f0b16d0a5c105380b284a81c6a1b2c210908 (patch) | |
tree | c2153d226b9cba3ebca0c3556b19bf3e52cd20dd /field.c | |
parent | f20ab7c3039a4023f41372bfe4bde3b16d481df7 (diff) | |
download | egawk-3ca7f0b16d0a5c105380b284a81c6a1b2c210908.tar.gz egawk-3ca7f0b16d0a5c105380b284a81c6a1b2c210908.tar.bz2 egawk-3ca7f0b16d0a5c105380b284a81c6a1b2c210908.zip |
Move to gawk-3.0.5.
Diffstat (limited to 'field.c')
-rw-r--r-- | field.c | 33 |
1 files changed, 31 insertions, 2 deletions
@@ -3,7 +3,7 @@ */ /* - * Copyright (C) 1986, 1988, 1989, 1991-1999 the Free Software Foundation, Inc. + * Copyright (C) 1986, 1988, 1989, 1991-2000 the Free Software Foundation, Inc. * * This file is part of GAWK, the GNU implementation of the * AWK Programming Language. @@ -219,6 +219,11 @@ rebuild_record() * set_record: * setup $0, but defer parsing rest of line until reference is made to $(>0) * or to NF. At that point, parse only as much as necessary. + * + * Manage a private buffer for the contents of $0. Doing so keeps us safe + * if `getline var' decides to rearrange the contents of the IOBUF that + * $0 might have been pointing into. The cost is the copying of the buffer; + * but better correct than fast. */ void set_record(buf, cnt, freeold) @@ -228,6 +233,10 @@ int freeold; { register int i; NODE *n; + static char *databuf; + static unsigned long databuf_size; +#define INITIAL_SIZE 512 +#define MAX_SIZE ((unsigned long) ~0) /* maximally portable ... */ NF = -1; for (i = 1; i <= parse_high_water; i++) { @@ -248,9 +257,24 @@ int freeold; save_FS = dupnode(FS_node->var_value); } if (freeold) { + /* buffer management: */ + if (databuf_size == 0) { /* first time */ + emalloc(databuf, char *, INITIAL_SIZE, "set_record"); + databuf_size = INITIAL_SIZE; + } + /* make sure there's enough room */ + if (cnt > databuf_size) { + while (cnt > databuf_size && databuf_size <= MAX_SIZE) + databuf_size *= 2; + erealloc(databuf, char *, databuf_size, "set_record"); + } + /* copy the data */ + memcpy(databuf, buf, cnt); + + /* manage field 0: */ unref(fields_arr[0]); getnode(n); - n->stptr = buf; + n->stptr = databuf; n->stlen = cnt; n->stref = 1; n->type = Node_val; @@ -260,6 +284,9 @@ int freeold; } fields_arr[0]->flags |= MAYBE_NUM; field0_valid = TRUE; + +#undef INITIAL_SIZE +#undef MAX_SIZE } /* reset_record --- start over again with current $0 */ @@ -759,6 +786,8 @@ NODE *tree; if (arr->type == Node_param_list) arr = stack_ptr[arr->param_cnt]; + if (arr->type == Node_array_ref) + arr = arr->orig_array; if (arr->type != Node_var && arr->type != Node_var_array) fatal("second argument of split is not an array"); arr->type = Node_var_array; |