changeset 24303:ddc91a2ee0e0 stable

Remove all delimiters from whitespace list in textscan function (bug #52479). * oct-stream.cc (textscan::parse_options): After all options have been processed, remove all characters in 'delims' string and all strings in 'delim_list' cell from the 'whitespace' string in case user adds a whitespace character as a delimiter. * file-io.cc (Ftextscan): Add BIST test for bug #52479.
author Daniel J Sebald <daniel.sebald@ieee.org>
date Wed, 22 Nov 2017 14:06:44 -0600
parents 117107eed917
children ddaee520d342 30921b835960
files libinterp/corefcn/file-io.cc libinterp/corefcn/oct-stream.cc
diffstat 2 files changed, 30 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/file-io.cc	Thu Nov 23 13:33:48 2017 -0800
+++ b/libinterp/corefcn/file-io.cc	Wed Nov 22 14:06:44 2017 -0600
@@ -2196,6 +2196,17 @@
 
 ## Check for delimiter after exponent
 %!assert (textscan ("1e-3|42", "%f", "delimiter", "|"), {[1e-3; 42]})
+
+%!test <*52479>
+%! str = "\t\ta\tb\tc\n";
+%! ret = textscan (str, "%s", "delimiter", "\t");
+%! assert (ret, { {''; ''; 'a'; 'b'; 'c'} }) ;
+
+%!test <*52479>
+%! str = "\t\ta\tb\tc\n";
+%! ret = textscan (str, "%s", "delimiter", {"\t"});
+%! assert (ret, { {''; ''; 'a'; 'b'; 'c'} }) ;
+
 */
 
 // These tests have end-comment sequences, so can't just be in a comment
--- a/libinterp/corefcn/oct-stream.cc	Thu Nov 23 13:33:48 2017 -0800
+++ b/libinterp/corefcn/oct-stream.cc	Wed Nov 22 14:06:44 2017 -0600
@@ -29,6 +29,7 @@
 #include <cctype>
 #include <cstring>
 
+#include <algorithm>
 #include <deque>
 #include <fstream>
 #include <iomanip>
@@ -3717,6 +3718,24 @@
           error ("%s: unrecognized option '%s'", who.c_str (), param.c_str ());
       }
 
+    // Remove any user-supplied delimiter from whitespace list
+    for (unsigned int j = 0; j < delims.length (); j++)
+      {
+        whitespace.erase (std::remove (whitespace.begin (),
+                                       whitespace.end (),
+                                       delims[j]),
+                          whitespace.end ());
+      }
+    for (int j = 0; j < delim_list.numel (); j++)
+      {
+        std::string delim = delim_list(j).string_value ();
+        if (delim.length () == 1)
+          whitespace.erase (std::remove (whitespace.begin (), 
+                                         whitespace.end (),
+                                         delim[0]),
+                            whitespace.end ());
+      }
+
     whitespace_table = std::string (256, '\0');
     for (unsigned int i = 0; i < whitespace.length (); i++)
       whitespace_table[whitespace[i]] = '1';