aboutsummaryrefslogtreecommitdiff
path: root/libgfortran/io
diff options
context:
space:
mode:
Diffstat (limited to 'libgfortran/io')
-rw-r--r--libgfortran/io/file_pos.c2
-rw-r--r--libgfortran/io/list_read.c13
-rw-r--r--libgfortran/io/read.c16
-rw-r--r--libgfortran/io/transfer.c4
-rw-r--r--libgfortran/io/write_float.def10
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);
}