# HG changeset patch # User John W. Eaton # Date 1314202391 14400 # Node ID 7872afb42fab9501c6603f2e86f51b08896e978a # Parent 0413227e407bbd43afa588ad32771174ac6f599c fix scanf problem with reading I (bug #33722) * lo-utils.cc (read_inf_nan_na, read_float_inf_nan_na): Return characters to input stream and set stream state on failed reads. (read_float_inf_nan_na): Use Float versions of Inf, NaN, and NA * test_io.m: New tests. diff -r 0413227e407b -r 7872afb42fab liboctave/lo-utils.cc --- a/liboctave/lo-utils.cc Tue Aug 23 20:58:54 2011 -0400 +++ b/liboctave/lo-utils.cc Wed Aug 24 12:13:11 2011 -0400 @@ -196,44 +196,57 @@ } static inline double -read_inf_nan_na (std::istream& is, char c, char sign = '+') +read_inf_nan_na (std::istream& is, char c0, char sign = '+') { double d = 0.0; - switch (c) + switch (c0) { case 'i': case 'I': { - c = is.get (); - if (c == 'n' || c == 'N') + char c1 = is.get (); + if (c1 == 'n' || c1 == 'N') { - c = is.get (); - if (c == 'f' || c == 'F') + char c2 = is.get (); + if (c2 == 'f' || c2 == 'F') d = sign == '-' ? -octave_Inf : octave_Inf; else - is.putback (c); + { + is.putback (c2); + is.putback (c1); + is.putback (c0); + is.setstate (std::ios::failbit); + } } else - is.putback (c); + { + is.putback (c1); + is.putback (c0); + is.setstate (std::ios::failbit); + } } break; case 'n': case 'N': { - c = is.get (); - if (c == 'a' || c == 'A') + char c1 = is.get (); + if (c1 == 'a' || c1 == 'A') { - c = is.get (); - if (c == 'n' || c == 'N') + char c2 = is.get (); + if (c2 == 'n' || c2 == 'N') d = octave_NaN; else { - is.putback (c); + is.putback (c2); d = octave_NA; } } else - is.putback (c); + { + is.putback (c1); + is.putback (c0); + is.setstate (std::ios::failbit); + } } break; @@ -346,44 +359,57 @@ } static inline float -read_float_inf_nan_na (std::istream& is, char c, char sign = '+') +read_float_inf_nan_na (std::istream& is, char c0, char sign = '+') { float d = 0.0; - switch (c) + switch (c0) { case 'i': case 'I': { - c = is.get (); - if (c == 'n' || c == 'N') + char c1 = is.get (); + if (c1 == 'n' || c1 == 'N') { - c = is.get (); - if (c == 'f' || c == 'F') - d = sign == '-' ? -octave_Inf : octave_Inf; + char c2 = is.get (); + if (c2 == 'f' || c2 == 'F') + d = sign == '-' ? -octave_Float_Inf : octave_Float_Inf; else - is.putback (c); + { + is.putback (c2); + is.putback (c1); + is.putback (c0); + is.setstate (std::ios::failbit); + } } else - is.putback (c); + { + is.putback (c1); + is.putback (c0); + is.setstate (std::ios::failbit); + } } break; case 'n': case 'N': { - c = is.get (); - if (c == 'a' || c == 'A') + char c1 = is.get (); + if (c1 == 'a' || c1 == 'A') { - c = is.get (); - if (c == 'n' || c == 'N') - d = octave_NaN; + char c2 = is.get (); + if (c2 == 'n' || c2 == 'N') + d = octave_Float_NaN; else { - is.putback (c); - d = octave_NA; + is.putback (c2); + d = octave_Float_NA; } } else - is.putback (c); + { + is.putback (c1); + is.putback (c0); + is.setstate (std::ios::failbit); + } } break; diff -r 0413227e407b -r 7872afb42fab test/test_io.m --- a/test/test_io.m Tue Aug 23 20:58:54 2011 -0400 +++ b/test/test_io.m Wed Aug 24 12:13:11 2011 -0400 @@ -245,6 +245,27 @@ %!assert (sscanf ('123456', '%10c'), '123456') %!assert (sscanf ('123456', '%10s'), '123456') +%!test +%! [val, count, msg, pos] = sscanf ("3I2", "%f") +%! assert (val, 3); +%! assert (count, 1); +%! assert (msg, ""); +%! assert (pos, 2); + +%!test +%! [val, count, msg, pos] = sscanf ("3In2", "%f") +%! assert (val, 3); +%! assert (count, 1); +%! assert (msg, ""); +%! assert (pos, 2); + +%!test +%! [val, count, msg, pos] = sscanf ("3Inf2", "%f") +%! assert (val, [3; Inf, 2); +%! assert (count, 3); +%! assert (msg, ""); +%! assert (pos, 6); + %% test/octave.test/io/sscanf-1.m %!test %! [a, b, c] = sscanf ("1.2 3 foo", "%f%d%s", "C");