commit 7d1a958d6b099ea88b6c51649baf5dbd5e598909 Author: Jerry DeLisle Date: Wed Apr 3 18:07:30 2024 -0700 libfortran: Fix handling of formatted separators. PR libfortran/114304 libgfortran/ChangeLog: * io/list_read.c (eat_separator): Add logic to handle spaces preceding a comma or semicolon such that that a 'null' read occurs without error at the end of comma or semicolon terminated input lines. gcc/testsuite/ChangeLog: * gfortran.dg/pr114304.f90: New test. diff --git a/gcc/testsuite/gfortran.dg/pr114304.f90 b/gcc/testsuite/gfortran.dg/pr114304.f90 new file mode 100644 index 00000000000..57af619246b --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr114304.f90 @@ -0,0 +1,49 @@ +! { dg-do run } +! pr114304 +real :: x(3) +character(len=1) :: s +integer :: ios + +s = 'x' + +open(99, decimal="comma", status='scratch') +write(99, '(a)') '1,23435 1243,24 13,24 a' +rewind(99) +read(99, *, iostat=ios) x, s +if (ios /= 0 .or. s /= 'a') stop 1 + +rewind(99) +write(99, '(a)') '1,23435;1243,24;13,24;a' +rewind(99) +read(99, *, iostat=ios) x, s +if (ios /= 0 .or. s /= 'a') stop 2 + +! Note: not reading 's' +rewind(99) +write(99, '(a)') '1,23435 1243,24 13,24 ,' +rewind(99) +read(99, *) x +if (ios /= 0) stop 3 + +rewind(99) +write(99, '(a)') '1,23435;1243,24;13,24 ,' +rewind(99) +read(99, *, iostat=ios) x +if (ios /= 0) stop 4 + +! Now reading 's' +s = 'w' +rewind(99) +write(99, '(a)') '1,23435 1243,24 13,24 ,' +rewind(99) +read(99, *, iostat=ios) x, s +if (ios /= 0 .or. s /= 'w') stop 5 + +s = 'w' +rewind(99) +write(99, '(a)') '1,23435;1243,24;13,24 ,' +rewind(99) +read(99, *, iostat=ios) x, s +if (ios /= 0 .or. s /= 'w') stop 6 +close(99) +end diff --git a/libgfortran/io/list_read.c b/libgfortran/io/list_read.c index fb3f7dbc34d..f6f169043bf 100644 --- a/libgfortran/io/list_read.c +++ b/libgfortran/io/list_read.c @@ -461,11 +461,30 @@ eat_separator (st_parameter_dt *dtp) int c, n; int err = 0; - eat_spaces (dtp); dtp->u.p.comma_flag = 0; + c = next_char (dtp); + if (c == ' ') + { + eat_spaces (dtp); + c = next_char (dtp); + if (c == ',') + { + if (dtp->u.p.current_unit->decimal_status == DECIMAL_COMMA) + unget_char (dtp, ';'); + dtp->u.p.comma_flag = 1; + eat_spaces (dtp); + return err; + } + if (c == ';') + { + if (dtp->u.p.current_unit->decimal_status == DECIMAL_POINT) + unget_char (dtp, ','); + dtp->u.p.comma_flag = 1; + eat_spaces (dtp); + return err; + } + } - if ((c = next_char (dtp)) == EOF) - return LIBERROR_END; switch (c) { case ',': @@ -476,7 +495,10 @@ eat_separator (st_parameter_dt *dtp) unget_char (dtp, c); break; } - /* Fall through. */ + dtp->u.p.comma_flag = 1; + eat_spaces (dtp); + break; + case ';': dtp->u.p.comma_flag = 1; eat_spaces (dtp);