# HG changeset patch # User Rik # Date 1559577881 25200 # Node ID 30f53f7a7293184f38b832a6494901636f5f2015 # Parent 512399fefc1bff78cd46d97d3da43c83e2c93c4b Return correct error messages on octave-streams when scanf fails (bug #56396) * file-io.cc (Fsscanf): Add BIST test for bug #56396. * oct-stream.cc (base_stream::do_scanf): Perform end-of-scan processing if EOF has been detected, not just when FAILBIT has been set. If FAILBIT has been set, call error() to set an error message on the octave-stream. At end of function, assign any partial results obtained to output. Don't require that all conversions were successful. * io.tst: Update BIST tests to reflect new Matlab-compatible behavior for error message output. diff -r 512399fefc1b -r 30f53f7a7293 libinterp/corefcn/file-io.cc --- a/libinterp/corefcn/file-io.cc Sat Jun 01 21:01:45 2019 -0700 +++ b/libinterp/corefcn/file-io.cc Mon Jun 03 09:04:41 2019 -0700 @@ -1166,6 +1166,15 @@ return retval; } +/* +%!test <*56396> +%! [val, count, errmsg, nextpos] = sscanf ('1234a6', '%2d', 3); +%! assert (val, [12; 34]); +%! assert (count, 2); +%! assert (errmsg, "sscanf: format failed to match"); +%! assert (nextpos, 5); +*/ + DEFMETHOD (scanf, interp, args, , doc: /* -*- texinfo -*- @deftypefn {} {[@var{val}, @var{count}, @var{errmsg}] =} scanf (@var{template}, @var{size}) diff -r 512399fefc1b -r 30f53f7a7293 libinterp/corefcn/oct-stream.cc --- a/libinterp/corefcn/oct-stream.cc Sat Jun 01 21:01:45 2019 -0700 +++ b/libinterp/corefcn/oct-stream.cc Mon Jun 03 09:04:41 2019 -0700 @@ -4903,7 +4903,7 @@ { break; } - else if (! is) + else if (is.eof () || ! is) { if (all_char_conv) { @@ -4945,7 +4945,10 @@ // If it looks like we have a matching failure, then // reset the failbit in the stream state. if (is.rdstate () & std::ios::failbit) - is.clear (is.rdstate () & (~std::ios::failbit)); + { + error (who, "format failed to match"); + is.clear (is.rdstate () & (~std::ios::failbit)); + } // FIXME: is this the right thing to do? if (application::interactive () @@ -4996,15 +4999,12 @@ } } - if (ok ()) - { - mval.resize (final_nr, final_nc, 0.0); - - retval = mval; - - if (all_char_conv) - retval = retval.convert_to_str (false, true); - } + mval.resize (final_nr, final_nc, 0.0); + + retval = mval; + + if (all_char_conv) + retval = retval.convert_to_str (false, true); return retval; } diff -r 512399fefc1b -r 30f53f7a7293 test/io.tst --- a/test/io.tst Sat Jun 01 21:01:45 2019 -0700 +++ b/test/io.tst Mon Jun 03 09:04:41 2019 -0700 @@ -336,7 +336,7 @@ %! [val, count, msg, pos] = sscanf ("3I2", "%f"); %! assert (val, 3); %! assert (count, 1); -%! assert (msg, ""); +%! assert (msg, "sscanf: format failed to match"); %! assert (pos, 2); %!xtest <47413> @@ -345,14 +345,14 @@ %! [val, count, msg, pos] = sscanf ("3I2", "%f"); %! assert (val, 3); %! assert (count, 1); -%! assert (msg, ""); +%! assert (msg, "sscanf: format failed to match"); %! assert (pos, 2); %!testif ; ! ismac () %! [val, count, msg, pos] = sscanf ("3In2", "%f"); %! assert (val, 3); %! assert (count, 1); -%! assert (msg, ""); +%! assert (msg, "sscanf: format failed to match"); %! assert (pos, 2); %!xtest <47413>