diff options
author | Jerry DeLisle <jvdelisle@gcc.gnu.org> | 2005-12-16 19:32:21 +0000 |
---|---|---|
committer | Jerry DeLisle <jvdelisle@gcc.gnu.org> | 2005-12-16 19:32:21 +0000 |
commit | 494ef4c25495d4014677388a002715ac2eb018ed (patch) | |
tree | ed85a1c7eab7de8f4194a119aa77e351e168bcda /libgfortran/io | |
parent | 282b7663e6a1695244b185fbd09e7e993a94c594 (diff) | |
download | gcc-494ef4c25495d4014677388a002715ac2eb018ed.zip gcc-494ef4c25495d4014677388a002715ac2eb018ed.tar.gz gcc-494ef4c25495d4014677388a002715ac2eb018ed.tar.bz2 |
re PR fortran/25264 (write to internal unit from the string itself gives wrong result ?)
2005-12-16 Jerry DeLisle <jvdelisle@gcc.gnu.org>
PR libgfortran/25264
PR libgfortran/25349
* io/unit.c (get_unit): Delete code that cleared the string when the
unit was opened, which is too soon.
* io/transfer.c (next_record_w): Pass done flag in. Change logic for
setting max_pos. Add code to position unit and pad record as needed.
From-SVN: r108671
Diffstat (limited to 'libgfortran/io')
-rw-r--r-- | libgfortran/io/transfer.c | 68 | ||||
-rw-r--r-- | libgfortran/io/unit.c | 3 |
2 files changed, 58 insertions, 13 deletions
diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c index f3ca8df..7696643 100644 --- a/libgfortran/io/transfer.c +++ b/libgfortran/io/transfer.c @@ -1746,13 +1746,14 @@ next_record_r (st_parameter_dt *dtp) /* Position to the next record in write mode. */ static void -next_record_w (st_parameter_dt *dtp) +next_record_w (st_parameter_dt *dtp, int done) { - gfc_offset c, m, record; - int bytes_left, length; + gfc_offset c, m, record, max_pos; + int length; char *p; /* Zero counters for X- and T-editing. */ + max_pos = dtp->u.p.max_pos; dtp->u.p.max_pos = dtp->u.p.skips = dtp->u.p.pending_spaces = 0; switch (current_mode (dtp)) @@ -1831,18 +1832,31 @@ next_record_w (st_parameter_dt *dtp) { if (is_array_io (dtp)) { - bytes_left = (int) dtp->u.p.current_unit->bytes_left; - p = salloc_w (dtp->u.p.current_unit->s, &bytes_left); + length = (int) dtp->u.p.current_unit->bytes_left; + + /* If the farthest position reached is greater than current + position, adjust the position and set length to pad out + whats left. Otherwise just pad whats left. + (for character array unit) */ + m = dtp->u.p.current_unit->recl + - dtp->u.p.current_unit->bytes_left; + if (max_pos > m) + { + length = (int) (max_pos - m); + p = salloc_w (dtp->u.p.current_unit->s, &length); + length = (int) (dtp->u.p.current_unit->recl - max_pos); + } + + p = salloc_w (dtp->u.p.current_unit->s, &length); if (p == NULL) { generate_error (&dtp->common, ERROR_END, NULL); return; } - memset(p, ' ', bytes_left); + memset(p, ' ', length); /* Now that the current record has been padded out, determine where the next record in the array is. */ - record = next_array_record (dtp, dtp->u.p.current_unit->ls); /* Now seek to this record */ @@ -1856,13 +1870,47 @@ next_record_w (st_parameter_dt *dtp) else { length = 1; + + /* If this is the last call to next_record move to the farthest + position reached and set length to pad out the remainder + of the record. (for character scaler unit) */ + if (done) + { + m = dtp->u.p.current_unit->recl + - dtp->u.p.current_unit->bytes_left; + if (max_pos > m) + { + length = (int) (max_pos - m); + p = salloc_w (dtp->u.p.current_unit->s, &length); + length = (int) (dtp->u.p.current_unit->recl - max_pos); + } + else + length = (int) dtp->u.p.current_unit->bytes_left; + } p = salloc_w (dtp->u.p.current_unit->s, &length); if (p == NULL) - goto io_error; + { + generate_error (&dtp->common, ERROR_END, NULL); + return; + } + memset (p, ' ', length); } - } + } else { + /* If this is the last call to next_record move to the farthest + position reached in preparation for completing the record. + (for file unit) */ + if (done) + { + m = dtp->u.p.current_unit->recl - + dtp->u.p.current_unit->bytes_left; + if (max_pos > m) + { + length = (int) (max_pos - m); + p = salloc_w (dtp->u.p.current_unit->s, &length); + } + } #ifdef HAVE_CRLF length = 2; #else @@ -1905,7 +1953,7 @@ next_record (st_parameter_dt *dtp, int done) if (dtp->u.p.mode == READING) next_record_r (dtp); else - next_record_w (dtp); + next_record_w (dtp, done); /* keep position up to date for INQUIRE */ dtp->u.p.current_unit->flags.position = POSITION_ASIS; diff --git a/libgfortran/io/unit.c b/libgfortran/io/unit.c index 1366a9e..337e10c 100644 --- a/libgfortran/io/unit.c +++ b/libgfortran/io/unit.c @@ -384,9 +384,6 @@ get_unit (st_parameter_dt *dtp, int do_create) internal_unit.maxrec=0; internal_unit.current_record=0; - if (dtp->u.p.mode==WRITING && !is_array_io (dtp)) - empty_internal_buffer (internal_unit.s); - /* Set flags for the internal unit */ internal_unit.flags.access = ACCESS_SEQUENTIAL; |