changeset 14091:c3ea07298af4 stable

str2double: correctly handle things like ["1"; "2 3"; "4i"] * str2double.cc (extract_num): Gobble trailing whitespace after reading number.
author John W. Eaton <jwe@octave.org>
date Wed, 21 Dec 2011 21:01:22 -0500
parents 281ecc6fb431
children 22c50cbad2ce
files src/DLD-FUNCTIONS/str2double.cc
diffstat 1 files changed, 24 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/src/DLD-FUNCTIONS/str2double.cc	Wed Dec 21 16:53:43 2011 -0800
+++ b/src/DLD-FUNCTIONS/str2double.cc	Wed Dec 21 21:01:22 2011 -0500
@@ -62,7 +62,7 @@
       if (c1 == 'n' && c2 == 'f')
         {
           num = octave_Inf;
-          is.peek (); // Sets eof bit.
+          is.peek (); // May sets EOF bit.
         }
       else
         is.setstate (std::ios::failbit); // indicate that read has failed.
@@ -75,7 +75,7 @@
       if (c1 == 'A')
         {
           num = octave_NA;
-          is.peek (); // Sets eof bit.
+          is.peek (); // May set EOF bit.
         }
       else
         {
@@ -83,7 +83,7 @@
           if (c1 == 'a' && c2 == 'N')
             {
               num = octave_NaN;
-              is.peek (); // Sets eof bit.
+              is.peek (); // May set EOF bit.
             }
           else
             is.setstate (std::ios::failbit); // indicate that read has failed.
@@ -130,22 +130,24 @@
   // It's i*num or just i.
   if (is_imag_unit (c))
     {
-      c = is.get ();
       imag = true;
-      char cn = is.peek ();
+      is.get ();
+      c = is.peek ();
 
       // Skip spaces after imaginary unit.
-      while (isspace (cn))
+      while (isspace (c))
         {
           is.get ();
-          cn = is.peek ();
+          c = is.peek ();
         }
 
-      if (cn == '*')
+      if (c == '*')
         {
           // Multiplier follows, we extract it as a number.
           is.get ();
           single_num (is, num);
+          if (is.good ())
+            c = is.peek ();
         }
       else
         num = 1.0;
@@ -181,7 +183,7 @@
                 {
                   imag = true;
                   is.get ();
-                  is.peek (); // Sets eof bit.
+                  c = is.peek ();
                 }
               else
                 is.setstate (std::ios::failbit); // indicate that read has failed.
@@ -190,11 +192,21 @@
             {
               imag = true;
               is.get ();
-              is.peek (); // Sets eof bit.
+              c = is.peek ();
             }
         }
     }
 
+  if (is.good ())
+    {
+      // Skip trailing spaces.
+      while (isspace (c))
+        {
+          is.get ();
+          c = is.peek ();
+        }
+    }
+
   if (negative)
     num = -num;
 
@@ -341,6 +353,8 @@
 
 %!assert (str2double ("1"), 1)
 %!assert (str2double ("-.1e-5"), -1e-6)
+%!assert (str2double (char ("1", "2 3", "4i")), [1; NaN; 4i]);
+%!assert (str2double ("-.1e-5"), -1e-6)
 %!assert (str2double ("1,222.5"), 1222.5)
 %!assert (str2double ("i"), i)
 %!assert (str2double ("2j"), 2i)