# HG changeset patch # User Rik # Date 1377021980 25200 # Node ID c5073ed27cdca71feed56c33ea21c3d2ea4b21f8 # Parent 756bb4b58ad0f2c1c807d196fcd170c68ecc2872 Handle '+' format modifier in sprintf (bug #39773) * libinterp/corefcn/oct-stream.cc: Print '+' character even for Inf and NaN when '+' format specified. * scripts/general/num2str.m: Handle Inf values correctly when generating format for sprintf. Add new %!tests. * test/io.tst: Add %! tests for sprintf behavior. Use Octave coding conventions on rest of file. diff -r 756bb4b58ad0 -r c5073ed27cdc libinterp/corefcn/oct-stream.cc --- a/libinterp/corefcn/oct-stream.cc Tue Aug 20 19:11:17 2013 +0200 +++ b/libinterp/corefcn/oct-stream.cc Tue Aug 20 11:06:20 2013 -0700 @@ -2544,9 +2544,17 @@ nsa--; } - const char *tval = xisinf (val) - ? (val < 0 ? "-Inf" : "Inf") - : (lo_ieee_is_NA (val) ? "NA" : "NaN"); + const char *tval; + if (xisinf (val)) + if (elt->flags.find ('+') != std::string::npos) + tval = (val < 0 ? "-Inf" : "+Inf"); + else + tval = (val < 0 ? "-Inf" : "Inf"); + else + if (elt->flags.find ('+') != std::string::npos) + tval = (lo_ieee_is_NA (val) ? "+NA" : "+NaN"); + else + tval = (lo_ieee_is_NA (val) ? "NA" : "NaN"); retval += do_printf_conv (os, tfmt.c_str (), nsa, sa_1, sa_2, diff -r 756bb4b58ad0 -r c5073ed27cdc scripts/general/num2str.m --- a/scripts/general/num2str.m Tue Aug 20 19:11:17 2013 +0200 +++ b/scripts/general/num2str.m Tue Aug 20 11:06:20 2013 -0700 @@ -92,10 +92,9 @@ if (isnumeric (x)) ## Setup a suitable format string, ignoring inf entries dgt = floor (log10 (max (abs (x(!isinf (x(:))))))); - - ## If the whole input array is inf... if (isempty (dgt)) - dgt = 0; + ## If the whole input array is inf... + dgt = 1; endif if (any (x(:) != fix (x(:)))) @@ -130,8 +129,15 @@ endif else ## Setup a suitable format string - dgt = floor (log10 (max (max (abs (real (x(:)))), - max (abs (imag (x(:))))))); + #dgt = floor (log10 (max (max (abs (real (x(:)))), + # max (abs (imag (x(:))))))); + dgt = floor (log10 (max (max (abs (real (x(!isinf (real (x(:))))))), + max (abs (imag (x(!isinf (imag (x(:)))))))))); + if (isempty (dgt)) + ## If the whole input array is inf... + dgt = 1; + endif + if (any (x(:) != fix (x(:)))) ## Floating point input dgt = max (dgt + 4, 5); # Keep 4 sig. figures after decimal point @@ -183,7 +189,16 @@ %!assert (num2str (2^33+1i), "8589934592+1i") %!assert (num2str (-2^33+1i), "-8589934592+1i") %!assert (num2str (inf), "Inf") +%!assert (num2str ([inf -inf]), "Inf -Inf") +%!assert (num2str ([complex(Inf,0), complex(0,-Inf)]), "Inf+0i 0-Infi") +%!assert (num2str (complex(Inf,1)), "Inf+1i") +%!assert (num2str (complex(1,Inf)), "1+Infi") %!assert (num2str (nan), "NaN") +%!assert (num2str (complex (NaN, 1)), "NaN+1i") +%!assert (num2str (complex (1, NaN)), "1+NaNi") +%!assert (num2str (NA), "NA") +%!assert (num2str (complex (NA, 1)), "NA+1i") +%!assert (num2str (complex (1, NA)), "1+NAi") ## FIXME: Integers greater than bitmax() should be masked to show just ## 16 digits of precision. diff -r 756bb4b58ad0 -r c5073ed27cdc test/io.tst --- a/test/io.tst Tue Aug 20 19:11:17 2013 +0200 +++ b/test/io.tst Tue Aug 20 11:06:20 2013 -0700 @@ -222,7 +222,7 @@ %! matrix1 = rand (100, 2); %! save -ascii matrix.ascii matrix1 %! matrix2 = load ("matrix.ascii"); -%! assert (matrix1, matrix2, 1e-9) +%! assert (matrix1, matrix2, 1e-9); %! %! delete matrix.ascii; @@ -237,7 +237,6 @@ %!assert (puts (1),-1) %!error puts () - %!error puts (1, 2) %!assert (sscanf ('123456', '%10c'), '123456') @@ -245,11 +244,11 @@ %!assert (sscanf (['ab'; 'cd'], '%s'), 'acbd') -%!assert (sscanf ('02:08:30', '%i:%i:%i'), [2; 0]); -%!assert (sscanf ('02:08:30', '%d:%d:%d'), [2; 8; 30]); +%!assert (sscanf ('02:08:30', '%i:%i:%i'), [2; 0]) +%!assert (sscanf ('02:08:30', '%d:%d:%d'), [2; 8; 30]) -%!assert (sscanf ('0177 08', '%i'), [127; 0; 8]); -%!assert (sscanf ('0177 08', '%d'), [177; 8]); +%!assert (sscanf ('0177 08', '%i'), [127; 0; 8]) +%!assert (sscanf ('0177 08', '%d'), [177; 8]) %!test %! [val, count, msg, pos] = sscanf ("3I2", "%f"); @@ -282,9 +281,7 @@ %! && v2 == [1; 2] && c2 == 2 && ischar (m2))); %!error sscanf () - %!error sscanf (1, 2) - %!error sscanf ("foo", "bar", "C", 1) %!test @@ -305,21 +302,25 @@ %! assert (str, "test:1"); %!error printf (1) - %!error printf () %!test %! [s, msg, status] = sprintf ("%s: %d\n", "test", 1); -%! %! assert (s == "test: 1\n" && ischar (msg) && status == 8); -%!error sprintf (1) +%!assert (sprintf ("%-+6.2f", Inf), "+Inf ") +%!assert (sprintf ("%-6.2f", Inf), "Inf ") +%!assert (sprintf ("%-+6.2f", nan), "+NaN ") # lowercase nan is part of test +%!assert (sprintf ("%-6.2f", nan), "NaN ") +%!assert (sprintf ("%-+6.2f", NA), "+NA ") +%!assert (sprintf ("%-6.2f", NA), "NA ") %!error sprintf () +%!error sprintf (1) %!test %! arch_list = {"native"; "ieee-le"; "ieee-be"; "vaxd"; "vaxg"; "cray"}; -%! warning ("off", "Octave:fopen-mode") +%! warning ("off", "Octave:fopen-mode"); %! status = 1; %! %! for i = 1:6 @@ -386,17 +387,14 @@ %! assert (__prog_output_assert__ ("error:")); %!error fopen () - %!error fopen ("foo", "wb", "native", 1) %!error fclose (0) - %!error fclose (1, 2) %!assert (ischar (tmpnam ())) %!warning tmpnam (1); - %!warning tmpnam ("foo", 1); %!error tmpnam (1, 2, 3) @@ -472,81 +470,60 @@ %! endif %! unlink (nm); -%!error fputs () - -%!error fputs (1, "foo", 1) - %!assert (fputs (1, 1),-1) -%!error fgetl () - -%!error fgetl (1, 2, 3) +%!error fputs () +%!error fputs (1, "foo", 1) %!error fgetl ("foo", 1) -%!error fgets () - -%!error fgets (1, 2, 3) +%!error fgetl () +%!error fgetl (1, 2, 3) %!error fgets ("foo", 1) -%!error fprintf () - -%!error fprintf (1) +%!error fgets () +%!error fgets (1, 2, 3) %!test %! s.a = 1; %! fail ("fprintf (s)", "Invalid call to fprintf"); +%!error fprintf () +%!error fprintf (1) %!error fprintf (1, 1) - %!error fprintf (-1, "foo") -%!error fscanf () - -%!error fscanf (1) - %!error fscanf ("foo", "bar") -%!error fread () +%!error fscanf () +%!error fscanf (1) +%!error fread () %!error fread (1, 2, "char", 1, "native", 2) - %!error fread ("foo") %!error fwrite () - %!error fwrite (1, rand (10), "char", 1, "native", 2) - %!error fwrite ("foo", 1) %!error feof () - %!error feof (1, 2) - %!error feof ("foo") %!error ferror () - %!error ferror (1, 'clear', 2) - %!error ferror ("foo") %!error ftell () - %!error ftell (1, 2) - %!error ftell ("foo") %!error fseek () - %!error fseek (1, 0, SEEK_SET, 1) - %!error fseek ("foo", 0, SEEK_SET) %!error frewind () - %!error frewind (1, 2) - %!error frewind ("foo")