aboutsummaryrefslogtreecommitdiff
path: root/libgfortran/io/transfer.c
diff options
context:
space:
mode:
Diffstat (limited to 'libgfortran/io/transfer.c')
-rw-r--r--libgfortran/io/transfer.c112
1 files changed, 70 insertions, 42 deletions
diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c
index 98072d0..6009c12 100644
--- a/libgfortran/io/transfer.c
+++ b/libgfortran/io/transfer.c
@@ -737,7 +737,7 @@ write_block (st_parameter_dt *dtp, int length)
if (is_internal_unit (dtp))
{
- if (dtp->common.unit) /* char4 internel unit. */
+ if (is_char4_unit(dtp)) /* char4 internel unit. */
{
gfc_char4_t *dest4;
dest4 = mem_alloc_w4 (dtp->u.p.current_unit->s, &length);
@@ -2606,7 +2606,7 @@ data_transfer_init (st_parameter_dt *dtp, int read_flag)
st_parameter_open opp;
unit_convert conv;
- if (dtp->common.unit < 0)
+ if (dtp->common.unit < 0 && !is_internal_unit (dtp))
{
close_unit (dtp->u.p.current_unit);
dtp->u.p.current_unit = NULL;
@@ -3943,18 +3943,34 @@ st_read_done (st_parameter_dt *dtp)
{
finalize_transfer (dtp);
- if (is_internal_unit (dtp) || dtp->u.p.format_not_saved)
- {
- free_format_data (dtp->u.p.fmt);
- free_format (dtp);
- }
-
free_ionml (dtp);
- if (dtp->u.p.current_unit != NULL)
- unlock_unit (dtp->u.p.current_unit);
-
- free_internal_unit (dtp);
+ /* If this is a parent READ statement we do not need to retain the
+ internal unit structure for child use. Free it and stash the unit
+ number for reuse. */
+ if (dtp->u.p.current_unit != NULL
+ && dtp->u.p.current_unit->child_dtio == 0)
+ {
+ if (is_internal_unit (dtp) &&
+ (dtp->common.flags & IOPARM_DT_HAS_UDTIO) == 0)
+ {
+ free (dtp->u.p.current_unit->filename);
+ dtp->u.p.current_unit->filename = NULL;
+ free_format_hash_table (dtp->u.p.current_unit);
+ free (dtp->u.p.current_unit->s);
+ dtp->u.p.current_unit->s = NULL;
+ if (dtp->u.p.current_unit->ls)
+ free (dtp->u.p.current_unit->ls);
+ dtp->u.p.current_unit->ls = NULL;
+ stash_internal_unit (dtp);
+ }
+ if (is_internal_unit (dtp) || dtp->u.p.format_not_saved)
+ {
+ free_format_data (dtp->u.p.fmt);
+ free_format (dtp);
+ }
+ unlock_unit (dtp->u.p.current_unit);
+ }
library_end ();
}
@@ -3977,43 +3993,55 @@ st_write_done (st_parameter_dt *dtp)
{
finalize_transfer (dtp);
- /* Deal with endfile conditions associated with sequential files. */
-
if (dtp->u.p.current_unit != NULL
- && dtp->u.p.current_unit->flags.access == ACCESS_SEQUENTIAL
&& dtp->u.p.current_unit->child_dtio == 0)
- switch (dtp->u.p.current_unit->endfile)
- {
- case AT_ENDFILE: /* Remain at the endfile record. */
- break;
-
- case AFTER_ENDFILE:
- dtp->u.p.current_unit->endfile = AT_ENDFILE; /* Just at it now. */
- break;
-
- case NO_ENDFILE:
- /* Get rid of whatever is after this record. */
- if (!is_internal_unit (dtp))
- unit_truncate (dtp->u.p.current_unit,
- stell (dtp->u.p.current_unit->s),
- &dtp->common);
- dtp->u.p.current_unit->endfile = AT_ENDFILE;
- break;
- }
-
- if (is_internal_unit (dtp) || dtp->u.p.format_not_saved)
{
- free_format_data (dtp->u.p.fmt);
- free_format (dtp);
- }
+ /* Deal with endfile conditions associated with sequential files. */
+ if (dtp->u.p.current_unit->flags.access == ACCESS_SEQUENTIAL)
+ switch (dtp->u.p.current_unit->endfile)
+ {
+ case AT_ENDFILE: /* Remain at the endfile record. */
+ break;
- free_ionml (dtp);
+ case AFTER_ENDFILE:
+ dtp->u.p.current_unit->endfile = AT_ENDFILE; /* Just at it now. */
+ break;
- if (dtp->u.p.current_unit != NULL)
- unlock_unit (dtp->u.p.current_unit);
+ case NO_ENDFILE:
+ /* Get rid of whatever is after this record. */
+ if (!is_internal_unit (dtp))
+ unit_truncate (dtp->u.p.current_unit,
+ stell (dtp->u.p.current_unit->s),
+ &dtp->common);
+ dtp->u.p.current_unit->endfile = AT_ENDFILE;
+ break;
+ }
- free_internal_unit (dtp);
+ free_ionml (dtp);
+ /* If this is a parent WRITE statement we do not need to retain the
+ internal unit structure for child use. Free it and stash the
+ unit number for reuse. */
+ if (is_internal_unit (dtp) &&
+ (dtp->common.flags & IOPARM_DT_HAS_UDTIO) == 0)
+ {
+ free (dtp->u.p.current_unit->filename);
+ dtp->u.p.current_unit->filename = NULL;
+ free_format_hash_table (dtp->u.p.current_unit);
+ free (dtp->u.p.current_unit->s);
+ dtp->u.p.current_unit->s = NULL;
+ if (dtp->u.p.current_unit->ls)
+ free (dtp->u.p.current_unit->ls);
+ dtp->u.p.current_unit->ls = NULL;
+ stash_internal_unit (dtp);
+ }
+ if (is_internal_unit (dtp) || dtp->u.p.format_not_saved)
+ {
+ free_format_data (dtp->u.p.fmt);
+ free_format (dtp);
+ }
+ unlock_unit (dtp->u.p.current_unit);
+ }
library_end ();
}