changeset 33125:fc467370dacb

maint: merge stable to default
author Rik <rik@octave.org>
date Sat, 02 Mar 2024 13:58:51 -0800
parents 2b736846a81d (current diff) 9c08824262af (diff)
children 2ff2d201a344
files libinterp/corefcn/oct-stream.cc
diffstat 2 files changed, 38 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/oct-stream.cc	Sat Mar 02 15:32:36 2024 -0500
+++ b/libinterp/corefcn/oct-stream.cc	Sat Mar 02 13:58:51 2024 -0800
@@ -4390,8 +4390,6 @@
 octave_scan<>
 (std::istream& is, const scanf_format_elt& fmt, double *valptr)
 {
-  double& ref = *valptr;
-
   switch (fmt.type)
     {
     case 'e':
@@ -4401,19 +4399,24 @@
     case 'G':
       {
         is >> std::ws;  // skip through whitespace and advance stream pointer
-        if (is.good ())
+
+        std::streampos pos = is.tellg ();
+
+        double value = read_value<double> (is);
+
+        std::ios::iostate status = is.rdstate ();
+        if (! (status & std::ios::failbit))
           {
-            std::streampos pos = is.tellg ();
-
-            ref = read_value<double> (is);
-
-            std::ios::iostate status = is.rdstate ();
-            if (status & std::ios::failbit)
-              {
-                is.clear ();
-                is.seekg (pos);
-                is.setstate (status & ~std::ios_base::eofbit);
-              }
+            // Copy the converted value if the stream is in a good state
+            *valptr = value;
+          }
+        else
+          {
+            // True error.
+            // Reset stream to original position, clear eof bit, pass status on.
+            is.clear ();
+            is.seekg (pos);
+            is.setstate (status & ~std::ios_base::eofbit);
           }
       }
       break;
--- a/test/io.tst	Sat Mar 02 15:32:36 2024 -0500
+++ b/test/io.tst	Sat Mar 02 13:58:51 2024 -0800
@@ -600,7 +600,7 @@
 %! assert (pos, 5);
 
 ## Test '-' within string
-%!test <63383>
+%!test <*63383>
 %! [val, count, msg, pos] = sscanf ('1 2 - 3', '%d');
 %! assert (val, [1; 2]);
 %! assert (count, 2);
@@ -626,7 +626,7 @@
 %! assert (pos, 5);
 
 ## Test '+' within string
-%!test <63383>
+%!test <*63383>
 %! [val, count, msg, pos] = sscanf ('1 2 + 3', '%d');
 %! assert (val, [1; 2]);
 %! assert (count, 2);
@@ -638,7 +638,7 @@
 %! assert (msg, 'sscanf: format failed to match');
 %! assert (pos, 5);
 
-%## Test +NA, -NA, +NAN, -NAN
+## Test +NA, -NA, +NAN, -NAN
 %!test <*63383>
 %! [val, count, msg, pos] = sscanf ('+NA -NA 1 +NAN -NAN', '%f');
 %! assert (val, [NA; NA; 1; NaN; NaN]);
@@ -666,6 +666,24 @@
 %! assert (msg, '');
 %! assert (pos, 5);
 
+## Test space at end of input string
+%!test <63467>
+%! [val, count, msg, pos] = sscanf ('1 2 ', '%f');
+%! assert (val, [1; 2]);
+%! assert (count, 2);
+%! ## FIXME: The message should be empty, but is not.
+%! # assert (msg, '');
+%! assert (pos, 5);
+
+## Test newline at end of input string
+%!test <65390>
+%! [val, count, msg, pos] = sscanf ("1 2\n", '%f');
+%! assert (val, [1; 2]);
+%! assert (count, 2);
+%! ## FIXME: The message should be empty, but is not.
+%! # assert (msg, '');
+%! assert (pos, 5);
+
 %!test
 %! [a, b, c] = sscanf ("1.2 3 foo", "%f%d%s", "C");
 %! [v1, c1, m1] = sscanf ("1 2 3 4 5 6", "%d");