aboutsummaryrefslogtreecommitdiffstats
path: root/extension
diff options
context:
space:
mode:
authorAndrew J. Schorr <aschorr@telemetry-investments.com>2021-12-08 17:48:25 -0500
committerAndrew J. Schorr <aschorr@telemetry-investments.com>2021-12-08 17:48:25 -0500
commit08ebc9359fdd78998e638c06c58e0e7acdcd519a (patch)
tree2ae6526d860515d8ec55478d5b9b3effc7be87cc /extension
parent508e9368d2d461b2290af6787cad6dfbed357176 (diff)
downloadegawk-08ebc9359fdd78998e638c06c58e0e7acdcd519a.tar.gz
egawk-08ebc9359fdd78998e638c06c58e0e7acdcd519a.tar.bz2
egawk-08ebc9359fdd78998e638c06c58e0e7acdcd519a.zip
Fix rwarray extension to allocate mpz & mpfr values at proper scope.
Diffstat (limited to 'extension')
-rw-r--r--extension/ChangeLog17
-rw-r--r--extension/rwarray.c45
2 files changed, 41 insertions, 21 deletions
diff --git a/extension/ChangeLog b/extension/ChangeLog
index 1a0e34a6..c71c5a0e 100644
--- a/extension/ChangeLog
+++ b/extension/ChangeLog
@@ -1,5 +1,22 @@
2021-12-08 Andrew J. Schorr <aschorr@telemetry-investments.com>
+ * rwarray.c: Fix valgrind complaints related to creating mpz and mpfr
+ values on the stack in read_number by passing down storage from
+ the calling function that loads the data into gawk.
+ (value_storage): New union type to contain mpz_t or mpfr_t data.
+ (read_global): Allocate value_storage on the stack and pass a pointer
+ to read_elem.
+ (read_array): Ditto.
+ (read_elem): Receive new arg pointing to value_storage, and pass it
+ down to read_value.
+ (read_value): Receive new arg pointing to value_storage, and pass it
+ down to read_number.
+ (read_number): Receive new arg pointing to value_storage, and create
+ mpz and mpfr variables using that storage instead of in the local
+ scope.
+
+2021-12-08 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
* rwarray.c: Add new functions writeall and readall to implement
persistent state.
(write_backend): New helper function containing most of the logic
diff --git a/extension/rwarray.c b/extension/rwarray.c
index 4dbfaa86..8d6d28ef 100644
--- a/extension/rwarray.c
+++ b/extension/rwarray.c
@@ -78,11 +78,16 @@ static awk_bool_t write_elem(FILE *fp, awk_element_t *element);
static awk_bool_t write_value(FILE *fp, awk_value_t *val);
static awk_bool_t write_number(FILE *fp, awk_value_t *val);
+typedef union {
+ mpz_t mpz_val;
+ mpfr_t mpfr_val;
+} value_storage;
+
typedef awk_array_t (*array_handle_t)(awk_value_t *);
static awk_bool_t read_array(FILE *fp, awk_array_t array);
-static awk_bool_t read_elem(FILE *fp, awk_element_t *element, array_handle_t);
-static awk_bool_t read_value(FILE *fp, awk_value_t *value, array_handle_t, awk_value_t *idx);
-static awk_bool_t read_number(FILE *fp, awk_value_t *value, uint32_t code);
+static awk_bool_t read_elem(FILE *fp, awk_element_t *element, array_handle_t, value_storage *);
+static awk_bool_t read_value(FILE *fp, awk_value_t *value, array_handle_t, awk_value_t *idx, value_storage *vs);
+static awk_bool_t read_number(FILE *fp, awk_value_t *value, uint32_t code, value_storage *);
/*
* Format of array info:
@@ -481,6 +486,7 @@ read_global(FILE *fp, awk_array_t unused)
uint32_t i;
uint32_t count;
awk_element_t new_elem;
+ value_storage vs;
if (fread(& count, 1, sizeof(count), fp) != sizeof(count))
return awk_false;
@@ -488,7 +494,7 @@ read_global(FILE *fp, awk_array_t unused)
count = ntohl(count);
for (i = 0; i < count; i++) {
- if (read_elem(fp, & new_elem, global_array_handle)) {
+ if (read_elem(fp, & new_elem, global_array_handle, &vs)) {
if (! do_poke(& new_elem))
free_value(& new_elem.value);
if (new_elem.index.str_value.len)
@@ -620,6 +626,7 @@ read_array(FILE *fp, awk_array_t array)
uint32_t i;
uint32_t count;
awk_element_t new_elem;
+ value_storage vs;
if (fread(& count, 1, sizeof(count), fp) != sizeof(count))
return awk_false;
@@ -627,7 +634,7 @@ read_array(FILE *fp, awk_array_t array)
count = ntohl(count);
for (i = 0; i < count; i++) {
- if (read_elem(fp, & new_elem, regular_array_handle)) {
+ if (read_elem(fp, & new_elem, regular_array_handle, &vs)) {
/* add to array */
if (! set_array_element_by_elem(array, & new_elem)) {
warning(ext_id, _("read_array: set_array_element failed"));
@@ -646,7 +653,7 @@ read_array(FILE *fp, awk_array_t array)
/* read_elem --- read in a single element */
static awk_bool_t
-read_elem(FILE *fp, awk_element_t *element, array_handle_t array_handle)
+read_elem(FILE *fp, awk_element_t *element, array_handle_t array_handle, value_storage *vs)
{
uint32_t index_len;
static char *buffer;
@@ -684,7 +691,7 @@ read_elem(FILE *fp, awk_element_t *element, array_handle_t array_handle)
make_null_string(& element->index);
}
- if (! read_value(fp, & element->value, array_handle, & element->index))
+ if (! read_value(fp, & element->value, array_handle, & element->index, vs))
return awk_false;
return awk_true;
@@ -693,7 +700,7 @@ read_elem(FILE *fp, awk_element_t *element, array_handle_t array_handle)
/* read_value --- read a number or a string */
static awk_bool_t
-read_value(FILE *fp, awk_value_t *value, array_handle_t array_handle, awk_value_t *idx)
+read_value(FILE *fp, awk_value_t *value, array_handle_t array_handle, awk_value_t *idx, value_storage *vs)
{
uint32_t code, len;
@@ -714,7 +721,7 @@ read_value(FILE *fp, awk_value_t *value, array_handle_t array_handle, awk_value_
} else if (code == VT_NUMBER
|| code == VT_GMP
|| code == VT_MPFR) {
- return read_number(fp, value, code);
+ return read_number(fp, value, code, vs);
} else {
if (fread(& len, 1, sizeof(len), fp) != sizeof(len)) {
return awk_false;
@@ -767,7 +774,7 @@ read_value(FILE *fp, awk_value_t *value, array_handle_t array_handle, awk_value_
/* read_number --- read a double, GMP, or MPFR number */
static awk_bool_t
-read_number(FILE *fp, awk_value_t *value, uint32_t code)
+read_number(FILE *fp, awk_value_t *value, uint32_t code, value_storage *vs)
{
uint32_t len;
@@ -789,28 +796,24 @@ read_number(FILE *fp, awk_value_t *value, uint32_t code)
} else {
#ifdef HAVE_MPFR
if (code == VT_GMP) {
- mpz_t mp_ptr;
-
- mpz_init(mp_ptr);
- if (mpz_inp_raw(mp_ptr, fp) == 0)
+ mpz_init(vs->mpz_val);
+ if (mpz_inp_raw(vs->mpz_val, fp) == 0)
return awk_false;
- value = make_number_mpz(mp_ptr, value);
+ value = make_number_mpz(vs->mpz_val, value);
} else {
- mpfr_t mpfr_val;
- mpfr_init(mpfr_val);
-
+ mpfr_init(vs->mpfr_val);
#ifdef USE_MPFR_FPIF
/* preferable if widely available and stable */
- if (mpfr_fpif_import(mpfr_val, fp) != 0)
+ if (mpfr_fpif_import(vs->mpfr_val, fp) != 0)
#else
/* N.B. need to consume the terminating space we wrote
* after mpfr_out_str */
- if ((mpfr_inp_str(mpfr_val, fp, MPFR_STR_BASE, MPFR_STR_ROUND) == 0) || (getc(fp) != ' '))
+ if ((mpfr_inp_str(vs->mpfr_val, fp, MPFR_STR_BASE, MPFR_STR_ROUND) == 0) || (getc(fp) != ' '))
#endif
return awk_false;
- value = make_number_mpfr(& mpfr_val, value);
+ value = make_number_mpfr(vs->mpfr_val, value);
}
#else
fatal(ext_id(_("rwarray extension: GMP/MPFR value in file but compiled without GMP/MPFR support."));