Skip to content

Commit

Permalink
Merge branch 'ay/precisionfix/OTP-8989' into dev
Browse files Browse the repository at this point in the history
* ay/precisionfix/OTP-8989:
  Fix ~F.Fs bug, add testcase and improve documentation
  io_lib_format string precision fix
  • Loading branch information
RaimoNiskanen committed Mar 11, 2011
2 parents df45465 + d16aa7f commit 7c77ebb
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 27 deletions.
8 changes: 5 additions & 3 deletions lib/stdlib/doc/src/io.xml
Expand Up @@ -464,9 +464,9 @@ ok</pre>
<p>Prints the argument with the <c>string</c> syntax. The
argument is, if no Unicode translation modifier is present, an
<seealso marker="erts:erlang#iolist_definition">I/O list</seealso>, a binary, or an atom. If the Unicode translation modifier ('t') is in effect, the argument is chardata(), meaning that binaries are in UTF-8. The characters
are printed without quotes. In this format, the printed
argument is truncated to the given precision and field
width.</p>
are printed without quotes. The string is first truncated
by the given precision and then padded and justified
to the given field width. The default precision is the field width.</p>
<p>This format can be used for printing any object and
truncating the output so it fits a specified field:</p>
<pre>
Expand All @@ -475,6 +475,8 @@ ok</pre>
ok
4> <input>io:fwrite("|~10s|~n", [io_lib:write({hey, hey, hey})]).</input>
|{hey,hey,h|
5> <input>io:fwrite("|~-10.8s|~n", [io_lib:write({hey, hey, hey})]).</input>
|{hey,hey |
ok</pre>
<p>A list with integers larger than 255 is considered an error if the Unicode translation modifier is not given:</p>
<pre>
Expand Down
44 changes: 23 additions & 21 deletions lib/stdlib/src/io_lib_format.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
Expand Down Expand Up @@ -558,28 +558,30 @@ iolist_to_chars(B) when is_binary(B) ->

string(S, none, _Adj, none, _Pad) -> S;
string(S, F, Adj, none, Pad) ->
N = lists:flatlength(S),
if N > F -> flat_trunc(S, F);
N =:= F -> S;
true -> adjust(S, chars(Pad, F-N), Adj)
end;
string_field(S, F, Adj, lists:flatlength(S), Pad);
string(S, none, _Adj, P, Pad) ->
string_field(S, P, left, lists:flatlength(S), Pad);
string(S, F, Adj, P, Pad) when F >= P ->
N = lists:flatlength(S),
if N > P -> flat_trunc(S, P);
N =:= P -> S;
true -> [S|chars(Pad, P-N)]
end;
string(S, F, Adj, F, Pad) ->
string(S, none, Adj, F, Pad);
string(S, F, Adj, P, Pad) when F > P ->
N = lists:flatlength(S),
if N > F -> flat_trunc(S, F);
N =:= F -> S;
N > P -> adjust(flat_trunc(S, P), chars(Pad, F-P), Adj);
N =:= P -> adjust(S, chars(Pad, F-P), Adj);
true -> adjust([S|chars(Pad, P-N)], chars(Pad, F-P), Adj)
if F > P ->
if N > P ->
adjust(flat_trunc(S, P), chars(Pad, F-P), Adj);
N < P ->
adjust([S|chars(Pad, P-N)], chars(Pad, F-P), Adj);
true -> % N == P
adjust(S, chars(Pad, F-P), Adj)
end;
true -> % F == P
string_field(S, F, Adj, N, Pad)
end.

string_field(S, F, _Adj, N, _Pad) when N > F ->
flat_trunc(S, F);
string_field(S, F, Adj, N, Pad) when N < F ->
adjust(S, chars(Pad, F-N), Adj);
string_field(S, _, _, _, _) -> % N == F
S.

%% unprefixed_integer(Int, Field, Adjust, Base, PadChar, Lowercase)
%% -> [Char].

Expand Down Expand Up @@ -624,8 +626,8 @@ newline(F, right, _P, _Pad) -> chars($\n, F).
%%

adjust(Data, [], _) -> Data;
adjust(Data, Pad, left) -> [Data,Pad];
adjust(Data, Pad, right) -> [Pad,Data].
adjust(Data, Pad, left) -> [Data|Pad];
adjust(Data, Pad, right) -> [Pad|Data].

%% Flatten and truncate a deep list to at most N elements.

Expand Down
84 changes: 81 additions & 3 deletions lib/stdlib/test/io_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
Expand All @@ -27,7 +27,7 @@
otp_6282/1, otp_6354/1, otp_6495/1, otp_6517/1, otp_6502/1,
manpage/1, otp_6708/1, otp_7084/1, otp_7421/1,
io_lib_collect_line_3_wb/1, cr_whitespace_in_string/1,
io_fread_newlines/1]).
io_fread_newlines/1, otp_8989/1]).

%-define(debug, true).

Expand Down Expand Up @@ -62,7 +62,7 @@ all() ->
otp_6282, otp_6354, otp_6495, otp_6517, otp_6502,
manpage, otp_6708, otp_7084, otp_7421,
io_lib_collect_line_3_wb, cr_whitespace_in_string,
io_fread_newlines].
io_fread_newlines, otp_8989].

groups() ->
[].
Expand Down Expand Up @@ -1917,3 +1917,81 @@ read_newlines(Fd, Acc, N0) ->
eof ->
{lists:reverse(Acc),N0}
end.



otp_8989(doc) ->
"OTP-8989 io:format for ~F.Ps ignores P in some cases";
otp_8989(Suite) when is_list(Suite) ->
Hello = "Hello",
?line " Hello" = fmt("~6.6s", [Hello]),
?line " Hello" = fmt("~*.6s", [6,Hello]),
?line " Hello" = fmt("~6.*s", [6,Hello]),
?line " Hello" = fmt("~*.*s", [6,6,Hello]),
%%
?line " Hello" = fmt("~6.5s", [Hello]),
?line " Hello" = fmt("~*.5s", [6,Hello]),
?line " Hello" = fmt("~6.*s", [5,Hello]),
?line " Hello" = fmt("~*.*s", [6,5,Hello]),
%%
?line " Hell" = fmt("~6.4s", [Hello]),
?line " Hell" = fmt("~*.4s", [6,Hello]),
?line " Hell" = fmt("~6.*s", [4,Hello]),
?line " Hell" = fmt("~*.*s", [6,4,Hello]),
%%
?line "Hello" = fmt("~5.5s", [Hello]),
?line "Hello" = fmt("~*.5s", [5,Hello]),
?line "Hello" = fmt("~5.*s", [5,Hello]),
?line "Hello" = fmt("~*.*s", [5,5,Hello]),
%%
?line " Hell" = fmt("~5.4s", [Hello]),
?line " Hell" = fmt("~*.4s", [5,Hello]),
?line " Hell" = fmt("~5.*s", [4,Hello]),
?line " Hell" = fmt("~*.*s", [5,4,Hello]),
%%
?line "Hell" = fmt("~4.4s", [Hello]),
?line "Hell" = fmt("~*.4s", [4,Hello]),
?line "Hell" = fmt("~4.*s", [4,Hello]),
?line "Hell" = fmt("~*.*s", [4,4,Hello]),
%%
?line " Hel" = fmt("~4.3s", [Hello]),
?line " Hel" = fmt("~*.3s", [4,Hello]),
?line " Hel" = fmt("~4.*s", [3,Hello]),
?line " Hel" = fmt("~*.*s", [4,3,Hello]),
%%
%%
?line "Hello " = fmt("~-6.6s", [Hello]),
?line "Hello " = fmt("~*.6s", [-6,Hello]),
?line "Hello " = fmt("~-6.*s", [6,Hello]),
?line "Hello " = fmt("~*.*s", [-6,6,Hello]),
%%
?line "Hello " = fmt("~-6.5s", [Hello]),
?line "Hello " = fmt("~*.5s", [-6,Hello]),
?line "Hello " = fmt("~-6.*s", [5,Hello]),
?line "Hello " = fmt("~*.*s", [-6,5,Hello]),
%%
?line "Hell " = fmt("~-6.4s", [Hello]),
?line "Hell " = fmt("~*.4s", [-6,Hello]),
?line "Hell " = fmt("~-6.*s", [4,Hello]),
?line "Hell " = fmt("~*.*s", [-6,4,Hello]),
%%
?line "Hello" = fmt("~-5.5s", [Hello]),
?line "Hello" = fmt("~*.5s", [-5,Hello]),
?line "Hello" = fmt("~-5.*s", [5,Hello]),
?line "Hello" = fmt("~*.*s", [-5,5,Hello]),
%%
?line "Hell " = fmt("~-5.4s", [Hello]),
?line "Hell " = fmt("~*.4s", [-5,Hello]),
?line "Hell " = fmt("~-5.*s", [4,Hello]),
?line "Hell " = fmt("~*.*s", [-5,4,Hello]),
%%
?line "Hell" = fmt("~-4.4s", [Hello]),
?line "Hell" = fmt("~*.4s", [-4,Hello]),
?line "Hell" = fmt("~-4.*s", [4,Hello]),
?line "Hell" = fmt("~*.*s", [-4,4,Hello]),
%%
?line "Hel " = fmt("~-4.3s", [Hello]),
?line "Hel " = fmt("~*.3s", [-4,Hello]),
?line "Hel " = fmt("~-4.*s", [3,Hello]),
?line "Hel " = fmt("~*.*s", [-4,3,Hello]),
ok.

0 comments on commit 7c77ebb

Please sign in to comment.