changeset 21532:936ab0fca2f7

Textscan returns emptyVal for rows with literal but no conversion (bug #47458) * oct-stream.cc (scan): only skip final line if nothing worked (err & 8) * oct-stream.cc (read_format_once): Record whether anything worked. * file-io.cc: Add built-in self test.
author Lachlan Andrew <lachlanbis@gmail.com>
date Tue, 22 Mar 2016 20:39:16 +1100
parents 32101a071a9c
children 6187f1d2ca13
files libinterp/corefcn/file-io.cc libinterp/corefcn/oct-stream.cc
diffstat 2 files changed, 23 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/file-io.cc	Thu Mar 24 22:31:25 2016 -0700
+++ b/libinterp/corefcn/file-io.cc	Tue Mar 22 20:39:16 2016 +1100
@@ -2123,6 +2123,11 @@
 %! C = textscan ("1 2\t3 4", '%f %[^\t] %f %f');
 %! assert (C, {1, {"2"}, 3, 4});
 
+%% Check a non-empty line with no valid conversion registers empytValue
+%!test
+%! C = textscan ("Empty\n", "Empty%f %f");
+%! assert (C, { NaN, NaN })
+
 %% Check overflow and underflow of integer types
 %!test
 %! a = "-1e90 ";
--- a/libinterp/corefcn/oct-stream.cc	Thu Mar 24 22:31:25 2016 -0700
+++ b/libinterp/corefcn/oct-stream.cc	Tue Mar 22 20:39:16 2016 +1100
@@ -2699,7 +2699,8 @@
   if (err & 1)
     done_after = out.size () + 1;
 
-  int valid_rows = (row == ntimes) ? ntimes : ((err & 1) ? row : row+1);
+  int valid_rows = (row == ntimes) ? ntimes
+                   : (((err & 1) && (err & 8)) ? row : row+1);
   dim_vector dv (valid_rows, 1);
 
   ra_idx(0) = 0;
@@ -3458,6 +3459,7 @@
   bool no_conversions = true;
   bool done = false;
   bool conversion_failed = false;       // Record for ReturnOnError
+  bool nothing_worked = true;
 
   octave_quit ();
 
@@ -3522,6 +3524,15 @@
          )
         skip_delim (is);
 
+      if (is.eof ())
+        {
+          if (! done)
+            done_after = i+1;
+
+          // note EOF, but process others to get empty_val.
+          done = true;
+        }
+
       if (this_conversion_failed)
         {
           if (is.tellg () == pos && ! conversion_failed)
@@ -3532,28 +3543,17 @@
           else
             this_conversion_failed = false;
         }
-
-      if (is.eof ())
-        {
-          if (! done)
-            done_after = i+1;
-
-          // note EOF, but process others to get empty_val.
-          done = true;
-        }
+      else if (! done && !conversion_failed)
+        nothing_worked = false;
     }
 
   if (done)
     is.setstate (std::ios::eofbit);
 
-  // Returning -3 means "error, and no columns read this row".
-  if (is.eof ())
-    return (2 + no_conversions);
-
-  if (conversion_failed)
-    return (4 + no_conversions);
-
-  return 0;
+  return no_conversions + (is.eof () ? 2 : 0)
+                        + (conversion_failed ? 4 : 0)
+                        + (nothing_worked ? 8 : 0);
+
 }
 
 void