aboutsummaryrefslogtreecommitdiff
path: root/libgfortran
diff options
context:
space:
mode:
authorJerry DeLisle <jvdelisle@gcc.gnu.org>2024-04-05 19:25:13 -0700
committerJerry DeLisle <jvdelisle@gcc.gnu.org>2024-04-06 06:55:45 -0700
commit93adf88cc6744aa2c732b765e1e3b96e66cb3300 (patch)
treed39c79f18a09953b9d277139223c409a3df0d7e2 /libgfortran
parent09992f8b881aa2dfbee1e9d6954c3ca90cd3fe41 (diff)
downloadgcc-93adf88cc6744aa2c732b765e1e3b96e66cb3300.zip
gcc-93adf88cc6744aa2c732b765e1e3b96e66cb3300.tar.gz
gcc-93adf88cc6744aa2c732b765e1e3b96e66cb3300.tar.bz2
libfortran: Fix handling of formatted separators.
PR libfortran/114304 PR libfortran/105473 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. Add check and error message for ';'. (list_formatted_read_scalar): Treat comma as a decimal point when specified by the decimal mode on the first item. gcc/testsuite/ChangeLog: * gfortran.dg/pr105473.f90: Modify to verify new error message. * gfortran.dg/pr114304.f90: New test.
Diffstat (limited to 'libgfortran')
-rw-r--r--libgfortran/io/list_read.c41
1 files changed, 36 insertions, 5 deletions
diff --git a/libgfortran/io/list_read.c b/libgfortran/io/list_read.c
index fb3f7db..b56f2a4 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,8 +495,18 @@ eat_separator (st_parameter_dt *dtp)
unget_char (dtp, c);
break;
}
- /* Fall through. */
+ dtp->u.p.comma_flag = 1;
+ eat_spaces (dtp);
+ break;
+
case ';':
+ if (dtp->u.p.current_unit->decimal_status == DECIMAL_POINT)
+ {
+ generate_error (&dtp->common, LIBERROR_READ_VALUE,
+ "Semicolon not allowed as separator with DECIMAL='point'");
+ unget_char (dtp, c);
+ break;
+ }
dtp->u.p.comma_flag = 1;
eat_spaces (dtp);
break;
@@ -2144,7 +2173,9 @@ list_formatted_read_scalar (st_parameter_dt *dtp, bt type, void *p,
err = LIBERROR_END;
goto cleanup;
}
- if (is_separator (c))
+ if (c == ',' && dtp->u.p.current_unit->decimal_status == DECIMAL_COMMA)
+ c = '.';
+ else if (is_separator (c))
{
/* Found a null value. */
dtp->u.p.repeat_count = 0;