diff options
Diffstat (limited to 'libgfortran/io')
-rw-r--r-- | libgfortran/io/file_pos.c | 2 | ||||
-rw-r--r-- | libgfortran/io/list_read.c | 13 | ||||
-rw-r--r-- | libgfortran/io/read.c | 16 | ||||
-rw-r--r-- | libgfortran/io/transfer.c | 4 | ||||
-rw-r--r-- | libgfortran/io/write_float.def | 10 |
5 files changed, 38 insertions, 7 deletions
diff --git a/libgfortran/io/file_pos.c b/libgfortran/io/file_pos.c index 85183a6..061f42e 100644 --- a/libgfortran/io/file_pos.c +++ b/libgfortran/io/file_pos.c @@ -36,7 +36,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see record, and we have to sift backwards to find the newline before that or the start of the file, whichever comes first. */ -static const int READ_CHUNK = 4096; +#define READ_CHUNK 4096 static void formatted_backspace (st_parameter_filepos *fpp, gfc_unit *u) diff --git a/libgfortran/io/list_read.c b/libgfortran/io/list_read.c index 1cb329f..20b2b83 100644 --- a/libgfortran/io/list_read.c +++ b/libgfortran/io/list_read.c @@ -3132,16 +3132,27 @@ get_name: if (component_flag) { +#define EXT_STACK_SZ 100 + char ext_stack[EXT_STACK_SZ]; + char *ext_name; size_t var_len = strlen (root_nl->var_name); size_t saved_len = dtp->u.p.saved_string ? strlen (dtp->u.p.saved_string) : 0; - char ext_name[var_len + saved_len + 1]; + size_t ext_size = var_len + saved_len + 1; + + if (ext_size > EXT_STACK_SZ) + ext_name = xmalloc (ext_size); + else + ext_name = ext_stack; memcpy (ext_name, root_nl->var_name, var_len); if (dtp->u.p.saved_string) memcpy (ext_name + var_len, dtp->u.p.saved_string, saved_len); ext_name[var_len + saved_len] = '\0'; nl = find_nml_node (dtp, ext_name); + + if (ext_size > EXT_STACK_SZ) + free (ext_name); } else nl = find_nml_node (dtp, dtp->u.p.saved_string); diff --git a/libgfortran/io/read.c b/libgfortran/io/read.c index 64f2ddf..5c56dc2 100644 --- a/libgfortran/io/read.c +++ b/libgfortran/io/read.c @@ -881,6 +881,9 @@ read_radix (st_parameter_dt *dtp, const fnode *f, char *dest, int length, void read_f (st_parameter_dt *dtp, const fnode *f, char *dest, int length) { +#define READF_TMP 50 + char tmp[READF_TMP]; + size_t buf_size = 0; int w, seen_dp, exponent; int exponent_sign; const char *p; @@ -895,6 +898,7 @@ read_f (st_parameter_dt *dtp, const fnode *f, char *dest, int length) exponent_sign = 1; exponent = 0; w = f->u.w; + buffer = tmp; /* Read in the next block. */ p = read_block_form (dtp, &w); @@ -911,7 +915,10 @@ read_f (st_parameter_dt *dtp, const fnode *f, char *dest, int length) exponent because of an implicit decimal point or the like. Thus allocating strlen ("+0.0e-1000") == 10 characters plus one for NUL more than the original buffer had should be enough. */ - buffer = gfc_alloca (w + 11); + buf_size = w + 11; + if (buf_size > READF_TMP) + buffer = xmalloc (buf_size); + out = buffer; /* Optional sign */ @@ -984,6 +991,8 @@ read_f (st_parameter_dt *dtp, const fnode *f, char *dest, int length) goto bad_float; convert_infnan (dtp, dest, buffer, length); + if (buf_size > READF_TMP) + free (buffer); return; } @@ -1170,7 +1179,8 @@ done: /* Do the actual conversion. */ convert_real (dtp, dest, buffer, length); - + if (buf_size > READF_TMP) + free (buffer); return; /* The value read is zero. */ @@ -1203,6 +1213,8 @@ zero: return; bad_float: + if (buf_size > READF_TMP) + free (buffer); generate_error (&dtp->common, LIBERROR_READ_VALUE, "Bad value during floating point read"); next_record (dtp, 1); diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c index 87b8c05..71c60b6 100644 --- a/libgfortran/io/transfer.c +++ b/libgfortran/io/transfer.c @@ -2982,7 +2982,7 @@ static void skip_record (st_parameter_dt *dtp, ssize_t bytes) { ssize_t rlength, readb; - static const ssize_t MAX_READ = 4096; +#define MAX_READ 4096 char p[MAX_READ]; dtp->u.p.current_unit->bytes_left_subrecord += bytes; @@ -3282,7 +3282,7 @@ next_record_w_unf (st_parameter_dt *dtp, int next_subrecord) static ssize_t sset (stream * s, int c, ssize_t nbyte) { - static const int WRITE_CHUNK = 256; +#define WRITE_CHUNK 256 char p[WRITE_CHUNK]; ssize_t bytes_left, trans; diff --git a/libgfortran/io/write_float.def b/libgfortran/io/write_float.def index 99f6ff8..1b345f8 100644 --- a/libgfortran/io/write_float.def +++ b/libgfortran/io/write_float.def @@ -1277,7 +1277,13 @@ write_float (st_parameter_dt *dtp, const fnode *f, const char *source, \ trailing null, and finally some extra digits depending on the requested precision. */ const size_t size = 4932 + 3 + precision; - char buffer[size]; +#define BUF_STACK_SZ 5000 + char buf_stack[BUF_STACK_SZ]; + char *buffer; + if (size > BUF_STACK_SZ) + buffer = xmalloc (size); + else + buffer = buf_stack; switch (len) { @@ -1306,4 +1312,6 @@ write_float (st_parameter_dt *dtp, const fnode *f, const char *source, \ default: internal_error (NULL, "bad real kind"); } + if (size > BUF_STACK_SZ) + free (buffer); } |