diff options
author | Jerry DeLisle <jvdelisle@gcc.gnu.org> | 2024-04-05 19:25:13 -0700 |
---|---|---|
committer | Jerry DeLisle <jvdelisle@gcc.gnu.org> | 2024-04-06 06:55:45 -0700 |
commit | 93adf88cc6744aa2c732b765e1e3b96e66cb3300 (patch) | |
tree | d39c79f18a09953b9d277139223c409a3df0d7e2 /libgfortran | |
parent | 09992f8b881aa2dfbee1e9d6954c3ca90cd3fe41 (diff) | |
download | gcc-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.c | 41 |
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; |