Re: [patch, libgfortran] PR55818 Reading a REAL from a file which doesn't end in a new line fails
Jerry DeLisle wrote: This updated patch addresses the issues with infinities, nans, characters, and valid reals. And complex. OK for trunk? Test case attached. Thanks for the patch. It looks okay (with a ChangeLog). However, I found yet another case which is not handled, namely reals with exponentials such as 1.0e3. Hopefully, we have then covered all cases. open(99, file=test.dat, access=stream, form=unformatted, status=new) write(99) 1.0e3 close(99) !or: stream open(99, file=test.dat,access=sequential, form=formatted, status=old) read (99,*, iostat=stat) var if (stat /= 0 .or. var /= 1000) call abort() close(99) Tobias
Re: [patch, libgfortran] PR55818 Reading a REAL from a file which doesn't end in a new line fails
On 01/02/2013 01:00 AM, Tobias Burnus wrote: Jerry DeLisle wrote: This updated patch addresses the issues with infinities, nans, characters, and valid reals. And complex. OK for trunk? Test case attached. Thanks for the patch. It looks okay (with a ChangeLog). ChangeLog created However, I found yet another case which is not handled, namely reals with exponentials such as 1.0e3. Hopefully, we have then covered all cases. Missed one spot for exponents, trivial, fixed, and added to test case. Also added logical kind to test case. (It was already addressed in the patch) I will commit after one more full regression test. Thanks for review. Jerry
Re: [patch, libgfortran] PR55818 Reading a REAL from a file which doesn't end in a new line fails
This updated patch addresses the issues with infinities, nans, characters, and valid reals. OK for trunk? Test case attached. Regards, Jerry Index: list_read.c === --- list_read.c (revision 194731) +++ list_read.c (working copy) @@ -697,6 +697,7 @@ read_logical (st_parameter_dt *dtp, int length) break; CASE_SEPARATORS: +case EOF: unget_char (dtp, c); eat_separator (dtp); return; /* Null value. */ @@ -951,6 +952,7 @@ read_character (st_parameter_dt *dtp, int length _ break; CASE_SEPARATORS: +case EOF: unget_char (dtp, c); /* NULL value. */ eat_separator (dtp); return; @@ -975,8 +977,7 @@ read_character (st_parameter_dt *dtp, int length _ for (;;) { - if ((c = next_char (dtp)) == EOF) - goto eof; + c = next_char (dtp); switch (c) { CASE_DIGITS: @@ -984,6 +985,7 @@ read_character (st_parameter_dt *dtp, int length _ break; CASE_SEPARATORS: + case EOF: unget_char (dtp, c); goto done; /* String was only digits! */ @@ -1041,7 +1043,7 @@ read_character (st_parameter_dt *dtp, int length _ the string. */ if ((c = next_char (dtp)) == EOF) - goto eof; + goto done_eof; if (c == quote) { push_char (dtp, quote); @@ -1167,6 +1169,7 @@ parse_real (st_parameter_dt *dtp, void *buffer, in goto exp2; CASE_SEPARATORS: + case EOF: goto done; default: @@ -1202,6 +1205,7 @@ parse_real (st_parameter_dt *dtp, void *buffer, in break; CASE_SEPARATORS: + case EOF: unget_char (dtp, c); goto done; @@ -1243,7 +1247,7 @@ parse_real (st_parameter_dt *dtp, void *buffer, in ((c = next_char (dtp)) == 'y' || c == 'Y') (c = next_char (dtp { - if (is_separator (c)) + if (is_separator (c) || (c == EOF)) unget_char (dtp, c); push_char (dtp, 'i'); push_char (dtp, 'n'); @@ -1255,7 +1259,7 @@ parse_real (st_parameter_dt *dtp, void *buffer, in ((c = next_char (dtp)) == 'n' || c == 'N') (c = next_char (dtp))) { - if (is_separator (c)) + if (is_separator (c) || (c == EOF)) unget_char (dtp, c); push_char (dtp, 'n'); push_char (dtp, 'a'); @@ -1269,7 +1273,7 @@ parse_real (st_parameter_dt *dtp, void *buffer, in goto bad; c = next_char (dtp); - if (is_separator (c)) + if (is_separator (c) || (c == EOF)) unget_char (dtp, c); } goto done_infnan; @@ -1315,6 +1319,7 @@ read_complex (st_parameter_dt *dtp, void * dest, i break; CASE_SEPARATORS: +case EOF: unget_char (dtp, c); eat_separator (dtp); return; @@ -1369,7 +1374,7 @@ eol_4: goto bad_complex; c = next_char (dtp); - if (!is_separator (c)) + if (!is_separator (c) (c != EOF)) goto bad_complex; unget_char (dtp, c); @@ -1429,6 +1434,7 @@ read_real (st_parameter_dt *dtp, void * dest, int goto got_sign; CASE_SEPARATORS: +case EOF: unget_char (dtp, c); /* Single null. */ eat_separator (dtp); return; @@ -1484,6 +1490,7 @@ read_real (st_parameter_dt *dtp, void * dest, int goto got_repeat; CASE_SEPARATORS: + case EOF: if (c != '\n' c != ',' c != '\r' c != ';') unget_char (dtp, c); goto done; @@ -1647,7 +1654,7 @@ read_real (st_parameter_dt *dtp, void * dest, int goto unwind; c = next_char (dtp); l_push_char (dtp, c); - if (!is_separator (c)) + if (!is_separator (c) (c != EOF)) { if (c != 'i' c != 'I') goto unwind; @@ -1700,7 +1707,7 @@ read_real (st_parameter_dt *dtp, void * dest, int } } - if (!is_separator (c)) + if (!is_separator (c) (c != EOF)) goto unwind; if (dtp-u.p.namelist_mode) @@ -2537,16 +2544,16 @@ nml_read_obj (st_parameter_dt *dtp, namelist_info switch (nl-type) { case BT_INTEGER: - read_integer (dtp, len); - break; + read_integer (dtp, len); +break; case BT_LOGICAL: - read_logical (dtp, len); - break; + read_logical (dtp, len); + break; case BT_CHARACTER: - read_character (dtp, len); - break; + read_character (dtp, len); + break; case BT_REAL: /* Need to copy data back from the real location to the temp in order ! { dg-do run } ! PR55818 Reading a REAL from a file which doesn't end in a new line fails ! Test case from PR reporter. implicit none integer :: stat !integer :: var ! works real:: var ! fails character(len=10):: cvar ! fails complex :: cval open(99, file=test.dat, access=stream, form=unformatted, status=new) write(99) 1, new_line() write(99) 2, new_line() write(99) 3 close(99) ! Test character kind open(99, file=test.dat) read (99,*, iostat=stat) cvar if (stat /= 0 .or. cvar /= 1) call abort() read (99,*, iostat=stat) cvar if (stat /= 0 .or. cvar /= 2) call
Re: [patch, libgfortran] PR55818 Reading a REAL from a file which doesn't end in a new line fails
On 12/27/2012 05:51 PM, Jerry DeLisle wrote: Hi, The attached patch fixes this problem by not calling hit_eof if EOF can be a valid separator. Regression tested on x86-64. OK for trunk with test case from PR? Regards, Jerry 2012-12-27 Jerry DeLisle jvdeli...@gcc.gnu.org PR libfortran/55818 * io/list_read.c (read_real): Do not call hit_eof when EOF can be treated as a value separator Attached updated patch addresses the similar problem with complex and character variables (mentioned in subsequent PR comments). Regression tested on x86-64 linux. OK for trunk with updated ChangeLog and test cases from PR? Regards, Jerry Index: list_read.c === --- list_read.c (revision 194731) +++ list_read.c (working copy) @@ -951,6 +951,7 @@ read_character (st_parameter_dt *dtp, int length _ break; CASE_SEPARATORS: +case EOF: unget_char (dtp, c); /* NULL value. */ eat_separator (dtp); return; @@ -975,8 +976,7 @@ read_character (st_parameter_dt *dtp, int length _ for (;;) { - if ((c = next_char (dtp)) == EOF) - goto eof; + c = next_char (dtp); switch (c) { CASE_DIGITS: @@ -984,6 +984,7 @@ read_character (st_parameter_dt *dtp, int length _ break; CASE_SEPARATORS: + case EOF: unget_char (dtp, c); goto done; /* String was only digits! */ @@ -1005,6 +1006,7 @@ read_character (st_parameter_dt *dtp, int length _ if ((c = next_char (dtp)) == EOF) goto eof; + switch (c) { CASE_SEPARATORS: @@ -1041,7 +1043,7 @@ read_character (st_parameter_dt *dtp, int length _ the string. */ if ((c = next_char (dtp)) == EOF) - goto eof; + goto done_eof; if (c == quote) { push_char (dtp, quote); @@ -1315,6 +1317,7 @@ read_complex (st_parameter_dt *dtp, void * dest, i break; CASE_SEPARATORS: +case EOF: unget_char (dtp, c); eat_separator (dtp); return; @@ -1369,7 +1372,7 @@ eol_4: goto bad_complex; c = next_char (dtp); - if (!is_separator (c)) + if (!is_separator (c) (c != EOF)) goto bad_complex; unget_char (dtp, c); @@ -1429,6 +1432,7 @@ read_real (st_parameter_dt *dtp, void * dest, int goto got_sign; CASE_SEPARATORS: +case EOF: unget_char (dtp, c); /* Single null. */ eat_separator (dtp); return; @@ -1484,6 +1488,7 @@ read_real (st_parameter_dt *dtp, void * dest, int goto got_repeat; CASE_SEPARATORS: + case EOF: if (c != '\n' c != ',' c != '\r' c != ';') unget_char (dtp, c); goto done;
[patch, libgfortran] PR55818 Reading a REAL from a file which doesn't end in a new line fails
Hi, The attached patch fixes this problem by not calling hit_eof if EOF can be a valid separator. Regression tested on x86-64. OK for trunk with test case from PR? Regards, Jerry 2012-12-27 Jerry DeLisle jvdeli...@gcc.gnu.org PR libfortran/55818 * io/list_read.c (read_real): Do not call hit_eof when EOF can be treated as a value separator Index: list_read.c === --- list_read.c (revision 194731) +++ list_read.c (working copy) @@ -1429,6 +1429,7 @@ read_real (st_parameter_dt *dtp, void * dest, int goto got_sign; CASE_SEPARATORS: +case EOF: unget_char (dtp, c); /* Single null. */ eat_separator (dtp); return; @@ -1484,6 +1485,7 @@ read_real (st_parameter_dt *dtp, void * dest, int goto got_repeat; CASE_SEPARATORS: + case EOF: if (c != '\n' c != ',' c != '\r' c != ';') unget_char (dtp, c); goto done;