exporting patch:
# HG changeset patch
# User Daniel J Sebald <daniel.sebald@ieee.org>
# Date 1536723038 18000
#      Tue Sep 11 22:30:38 2018 -0500
# Node ID c6cc781735483ba9c5007d0b6d80b2cab48ee186
# Parent  11f63a33732eff5b1694b07284dfdd81b287a5b8
Allow processing standalone i/j/I/J in dlmread() routine (bug #54622)

* dlmread.cc (dlmread): Clear the status field of the stream when there is a
  conversion failure and check for standalone i/I/j/J taking into account a
  possible preceding +/-.  Skip white spaces.  Do the above for the imaginary
  portion of the complex number as well.  Change one of the BIST to test
  these scenarios.

* importdata.m: Change a BIST file element from "Inf" to "Infj".

diff --git a/libinterp/corefcn/dlmread.cc b/libinterp/corefcn/dlmread.cc
--- a/libinterp/corefcn/dlmread.cc
+++ b/libinterp/corefcn/dlmread.cc
@@ -435,8 +435,52 @@ such as text, are also replaced by the @
           tmp_stream.clear ();
 
           double x = octave_read_double (tmp_stream);
+
+          // Check for standalone i/I/j/J
+          if (! tmp_stream)
+            {
+              tmp_stream.clear ();
+
+              int next_char = tmp_stream.peek ();
+              // Skip spaces after sign operator.
+              while (isspace (next_char))
+                {
+                  tmp_stream.get ();
+                  next_char = tmp_stream.peek ();
+                }
+
+              bool negative = false;
+
+              if (next_char == '+' || next_char == '-')
+                {
+                  if (next_char == '-')
+                    negative = true;
+                  tmp_stream.get ();
+                  next_char = tmp_stream.peek ();
+                  // Skip spaces after sign operator.
+                  while (isspace (next_char))
+                    {
+                      tmp_stream.get ();
+                      next_char = tmp_stream.peek ();
+                    }
+                }
+
+              if (next_char == 'i' || next_char == 'j'
+                  || next_char == 'I' || next_char == 'J')
+                x = negative?-1:1;
+              else
+                tmp_stream.setstate (std::ios::failbit);
+            }
+
           if (tmp_stream)
             {
+              int next_char = tmp_stream.peek ();
+              // Skip spaces after sign operator.
+              while (isspace (next_char))
+                {
+                  tmp_stream.get ();
+                  next_char = tmp_stream.peek ();
+                }
               if (tmp_stream.eof ())
                 {
                   if (iscmplx)
@@ -446,13 +490,18 @@ such as text, are also replaced by the @
                 }
               else
                 {
-                  int next_char = tmp_stream.peek ();
                   if (next_char == 'i' || next_char == 'j'
                       || next_char == 'I' || next_char == 'J')
                     {
                       // Process pure imaginary numbers.
                       tmp_stream.get ();
                       next_char = tmp_stream.peek ();
+                      // Skip spaces after sign operator.
+                      while (isspace (next_char))
+                        {
+                          tmp_stream.get ();
+                          next_char = tmp_stream.peek ();
+                        }
                       if (next_char == std::istringstream::traits_type::eof ())
                         {
                           if (! iscmplx)
@@ -478,16 +527,92 @@ such as text, are also replaced by the @
                     {
                       double y = octave_read_double (tmp_stream);
 
-                      if (! iscmplx && y != 0.)
+                      // Check for standalone i/I/j/J
+                      if (! tmp_stream)
                         {
-                          iscmplx = true;
-                          cdata = ComplexMatrix (rdata);
+                          tmp_stream.clear ();
+
+                          int next_char = tmp_stream.peek ();
+                          // Skip spaces after sign operator.
+                          while (isspace (next_char))
+                            {
+                              tmp_stream.get ();
+                              next_char = tmp_stream.peek ();
+                            }
+
+                          bool negative = false;
+
+                          if (next_char == '+' || next_char == '-')
+                            {
+                              if (next_char == '-')
+                                negative = true;
+                              tmp_stream.get ();
+                              next_char = tmp_stream.peek ();
+                              // Skip spaces after sign operator.
+                              while (isspace (next_char))
+                                {
+                                  tmp_stream.get ();
+                                  next_char = tmp_stream.peek ();
+                                }
+                            }
+
+                          if (next_char == 'i' || next_char == 'j'
+                              || next_char == 'I' || next_char == 'J')
+                            y = negative?-1:1;
+                          else
+                            tmp_stream.setstate (std::ios::failbit);
                         }
 
-                      if (iscmplx)
-                        cdata(i,j++) = Complex (x, y);
+                      if (tmp_stream)
+                        {
+                          int next_char = tmp_stream.peek ();
+                          // Skip spaces after sign operator.
+                          while (isspace (next_char))
+                          {
+                            tmp_stream.get ();
+                            next_char = tmp_stream.peek ();
+                          }
+                          if (next_char == 'i' || next_char == 'j'
+                              || next_char == 'I' || next_char == 'J'
+                              || tmp_stream.eof ())
+                            {
+                              tmp_stream.get ();
+                              next_char = tmp_stream.peek ();
+                              // Skip spaces after sign operator.
+                              while (isspace (next_char))
+                                {
+                                  tmp_stream.get ();
+                                  next_char = tmp_stream.peek ();
+                                }
+                              if (next_char == std::istringstream::traits_type::eof ())
+                                {
+                                  if (! iscmplx && y != 0.)
+                                    {
+                                      iscmplx = true;
+                                      cdata = ComplexMatrix (rdata);
+                                    }
+
+                                  if (iscmplx)
+                                    cdata(i,j++) = Complex (x, y);
+                                  else
+                                    rdata(i,j++) = x;
+                                }
+                              else
+                                {
+                                  // Parsing failed, <number>i|j<extra text>
+                                  j++;  // Leave data initialized to empty_value
+                                }
+                            }
+                          else
+                            {
+                              // Parsing failed, <number>i|j<extra text>
+                              j++;  // Leave data initialized to empty_value
+                            }
+                        }
                       else
-                        rdata(i,j++) = x;
+                        {
+                          rdata(i,j++) = x;
+                        }
                     }
                 }
             }
@@ -696,10 +821,10 @@ such as text, are also replaced by the @
 %! file = tempname ();
 %! unwind_protect
 %!   fid = fopen (file, "wt");
-%!   fwrite (fid, "1,2jack,3");
+%!   fwrite (fid, "1,2jack,3,J,NaN+I");
 %!   fclose (fid);
 %!
-%!   assert (dlmread (file), [1, 0, 3]);
+%!   assert (dlmread (file), [1, 0, 3, complex(0,1), complex(NaN,1)]);
 %! unwind_protect_cleanup
 %!   unlink (file);
 %! end_unwind_protect
diff --git a/scripts/io/importdata.m b/scripts/io/importdata.m
--- a/scripts/io/importdata.m
+++ b/scripts/io/importdata.m
@@ -492,10 +492,10 @@ endfunction
 
 %!test
 %! ## Exceptional values (Inf, NaN, NA)
-%! A = [3.1 Inf NA; -Inf NaN 128];
+%! A = [3.1 complex(0,Inf) NA; -Inf NaN 128];
 %! fn  = tempname ();
 %! fid = fopen (fn, "w");
-%! fputs (fid, "3.1\tInf\tNA\n-Inf\tNaN\t128");
+%! fputs (fid, "3.1\tInfj\tNA\n-Inf\tNaN\t128");
 %! fclose (fid);
 %! [a,d,h] = importdata (fn, '\t');
 %! unlink (fn);
