2007-07-21 Jerry DeLisle PR libgfortran/32678 * io/transfer.c (formatted_transfer_scalar): Fix off by one error in calculation of pos and skips. Don't allow pending_spaces to go negative. PR fortran/32678 * gfortran.dg/fmt_t_5.f90: New test. --- libgfortran/io/transfer.c (revision 126821) +++ libgfortran/io/transfer.c (revision 126823) @@ -893,9 +893,9 @@ formatted_transfer_scalar (st_parameter_ case FMT_TR: consume_data_flag = 0 ; - pos = bytes_used + f->u.n + dtp->u.p.skips; - dtp->u.p.skips = f->u.n + dtp->u.p.skips; - dtp->u.p.pending_spaces = pos - dtp->u.p.max_pos; + dtp->u.p.skips += f->u.n; + pos = bytes_used + dtp->u.p.skips - 1; + dtp->u.p.pending_spaces = pos - dtp->u.p.max_pos + 1; /* Writes occur just before the switch on f->format, above, so that trailing blanks are suppressed, unless we are doing a @@ -922,8 +922,6 @@ formatted_transfer_scalar (st_parameter_ if (bytes_used == 0) { dtp->u.p.pending_spaces -= f->u.n; - dtp->u.p.pending_spaces = dtp->u.p.pending_spaces < 0 ? 0 - : dtp->u.p.pending_spaces; dtp->u.p.skips -= f->u.n; dtp->u.p.skips = dtp->u.p.skips < 0 ? 0 : dtp->u.p.skips; } @@ -945,6 +943,8 @@ formatted_transfer_scalar (st_parameter_ dtp->u.p.skips = dtp->u.p.skips + pos - bytes_used; dtp->u.p.pending_spaces = dtp->u.p.pending_spaces + pos - dtp->u.p.max_pos; + dtp->u.p.pending_spaces = dtp->u.p.pending_spaces < 0 + ? 0 : dtp->u.p.pending_spaces; if (dtp->u.p.skips == 0) break; --- gcc/testsuite/gfortran.dg/fmt_t_5.f90 (revision 126821) +++ gcc/testsuite/gfortran.dg/fmt_t_5.f90 (revision 126823) @@ -0,0 +1,17 @@ +! { dg-do run } +! PR32678 GFortan works incorrectly when writing with FORMAT Tx +! Before patch, NULLs were inserted in output. +! Test case from reporter enhanced to detect this problem. + character(25) :: output + character(1) :: c + output = "" + open (unit=10, file="pr32678testfile", status="replace") + write (10,10) '12','a','b' + close (10, status="keep") + open (unit=10, file="pr32678testfile") + read(10,20) output(1:21) + if (output(1:21).ne."ab x") call abort + close (10, status="delete") + 10 format (a2,t1,a1,t2,a1,t20,' x') + 20 format (a21) + end