changeset 27424:17b915ad4b73

Fix error with %q format and textscan (bug #56917). * file-io.cc (Ftextscan): Add BIST test for bug #56917. * oct-stream.cc (textscan::scan_qstring): Use peek_undelim() which sets EOF rather than peek() which does not. * oct-stream.cc: Small spacing fixes, addition of FIXME.
author Rik <rik@octave.org>
date Tue, 17 Sep 2019 17:51:43 -0700
parents e87289e352c0
children 633f7a8347c8
files libinterp/corefcn/file-io.cc libinterp/corefcn/oct-stream.cc
diffstat 2 files changed, 15 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/file-io.cc	Tue Sep 17 14:31:45 2019 -0700
+++ b/libinterp/corefcn/file-io.cc	Tue Sep 17 17:51:43 2019 -0700
@@ -2294,8 +2294,13 @@
 %! unwind_protect_cleanup
 %!   unlink (f);
 %! end_unwind_protect
+
+%!test <*56917>
+%! str = '"a,b","c"';
+%! obs = textscan (str, "%q", "delimiter", ",");
+%! assert (obs, { { "a,b"; "c" } });
+
 */
-
 // These tests have end-comment sequences, so can't just be in a comment
 #if 0
 ## Test unfinished comment
--- a/libinterp/corefcn/oct-stream.cc	Tue Sep 17 14:31:45 2019 -0700
+++ b/libinterp/corefcn/oct-stream.cc	Tue Sep 17 17:51:43 2019 -0700
@@ -1247,6 +1247,9 @@
     int get_undelim (void);
 
     // Read character that will be got by the next get.
+    // FIXME: This will not set EOF if delimited stream is at EOF and a peek
+    // is attempted.  This does *NOT* behave like C++ input stream.
+    // For a compatible peek function, use peek_undelim.  See bug #56917.
     int peek (void) { return eof () ? std::istream::traits_type::eof () : *idx; }
 
     // Read character that will be got by the next get.
@@ -1317,7 +1320,7 @@
     // Position after last character in buffer.
     char *eob;
 
-    // True if there is delimiter in the bufer after idx.
+    // True if there is delimiter in the buffer after idx.
     bool delimited;
 
     // Longest lookahead required.
@@ -3048,7 +3051,7 @@
                         std::string& val) const
   {
     int c1 = std::istream::traits_type::eof ();
-    std::ostringstream obuf;              // Is this optimized for growing?
+    std::ostringstream obuf;   // FIXME: is this optimized for growing?
 
     while (is && ((c1 = (is && ! is.eof ())
                    ? is.get_undelim ()
@@ -3199,9 +3202,9 @@
         scan_caret (is, R"(")", val);     // read everything until "
         is.get ();                        // swallow "
 
-        while (is && is.peek () == '"')  // if double ", insert one in stream,
-          {                               // and keep looking for single "
-            is.get ();
+        while (is && is.peek_undelim () == '"')  // if double ",
+          {                                      // insert one in stream,
+            is.get ();                           // keep looking for single "
             std::string val1;
             scan_caret (is, R"(")", val1);
             val = val + '"' + val1;
@@ -3835,6 +3838,7 @@
 
     if (c1 != std::istream::traits_type::eof ())
       is.putback (c1);
+
     return c1;
   }