소스 검색

Try to give more equal allocations to large terms

pull/4/head
Andrew Thompson 14 년 전
부모
커밋
37f190f037
1개의 변경된 파일46개의 추가작업 그리고 30개의 파일을 삭제
  1. +46
    -30
      src/trunc_io.erl

+ 46
- 30
src/trunc_io.erl 파일 보기

@ -40,8 +40,9 @@ format(String, Args, Max) ->
Maxlen = Max - length(String),
format(Parts, Args, Maxlen, [], []).
format([], _Args, _Max, Acc, ArgAcc) ->
io_lib:format(lists:flatten(lists:reverse(Acc)), lists:reverse(ArgAcc));
format([], _Args, Max, Acc, ArgAcc) ->
FmtArgs = resolve_futures(Max, ArgAcc),
io_lib:format(lists:flatten(lists:reverse(Acc)), lists:reverse(FmtArgs));
format([[] | T], Args, Max, Acc, ArgAcc) ->
% discard the null list generated by split
format(T, Args, Max, Acc, ArgAcc);
@ -62,21 +63,21 @@ format([[$~|H]| T], [AH | AT], Max, Acc, ArgAcc) when length(H) == 1 ->
case H of
_ when H == "p"; H == "w"; H == "s" ->
%okay, these are prime candidates for rewriting
{String, Length} = case print(AH, Max) of
case print(AH, Max) of
{_Res, Max} when AT /= [] ->
% this isn't the last argument, but it consumed all available space, give it half instead
print(AH, Max div 2);
{Res, Len} ->;
{Res, Len}
end,
{Value, RealLen} = case H of
"s" ->
% strip off the doublequotes
{string:substr(String, 2, length(String) -2), Length -2};
_ ->
{String, Length}
end,
format(T, AT, Max + 2 - RealLen, ["~s" | Acc], [Value | ArgAcc]);
% this isn't the last argument, but it consumed all available space
% delay calculating the print size until the end
format(T, AT, Max + 2, ["~s" | Acc], [{future, AH} | ArgAcc]);
{String, Length} ->
{Value, RealLen} = case H of
"s" ->
% strip off the doublequotes
{string:substr(String, 2, length(String) -2), Length -2};
_ ->;
{String, Length}
end,
format(T, AT, Max + 2 - RealLen, ["~s" | Acc], [Value | ArgAcc])
end;
_ ->
% whatever, just pass them on through
format(T, AT, Max, [[$~ | H], Acc], [AH | ArgAcc])
@ -87,22 +88,26 @@ format([[$~|H]| T], [AH | AT], Max, Acc, ArgAcc) ->
case re:run(H, "^(?:-??(\\d+|\\*)\\.|)(?:-??(\\d+|\\*)\\.|)(-??\\d+|\\*|)(t|)([cfegswpWPBX#bx+ni])$", [{capture, all_but_first, list}]) of
{match, [_F, _P, _Pad, _Mod, C]} when C == "p"; C=="w"; C=="s" ->
%okay, these are prime candidates for rewriting
{String, Length} = case print(AH, Max) of
case print(AH, Max) of
{_Res, Max} when AT /= [] ->
% this isn't the last argument, but it consumed all available space, give it half instead
print(AH, Max div 2);
{Res, Len} ->;
{Res, Len}
end,
{Value, RealLen} = case H of
"s" ->
% strip off the doublequotes
{string:substr(String, 2, length(String) -2), Length -2};
_ ->
{String, Length}
end,
format(T, AT, Max + length(H) + 1 - RealLen, ["~s" | Acc], [Value | ArgAcc]);
% this isn't the last argument, but it consumed all available space
% delay calculating the print size until the end
format(T, AT, Max + length(H) + 1, ["~s" | Acc], [{future, AH} | ArgAcc]);
{String, Length} ->
{Value, RealLen} = case H of
"s" ->
% strip off the doublequotes
{string:substr(String, 2, length(String) -2), Length -2};
_ ->;
{String, Length}
end,
format(T, AT, Max + length(H) + 1 - RealLen, ["~s" | Acc], [Value | ArgAcc])
end;
{match, [_F, _P, _Pad, _Mod, C]} when C == "P"; C=="W" ->
% these crazy ones consume TWO arguments, just pass them through
% because W and P implicitly limit size so we trust the user knows
% what they're doing. Unfortunately we can't change Max at all because
% depth based limits are not of known length.
[AH2 | AT2] = AT,
format(T, AT2, Max, [[$~|H]|Acc], [AH2, AH |ArgAcc]);
{match, _} ->
@ -114,6 +119,17 @@ format([[$~|H]| T], [AH | AT], Max, Acc, ArgAcc) ->
format([H | T], Args, Max, Acc, ArgAcc) ->
format(T, Args, Max, [H | Acc], ArgAcc).
%% for all the really big terms encountered in a format/3 call, try to give each of them an equal share
resolve_futures(Max, Args) ->
Count = length(lists:filter(fun({future, _}) -> true; (_) -> false end, Args)),
case Count of
0 ->
Args;
_ ->
SingleFmt = Max div Count,
lists:map(fun({future, Value}) -> element(1, print(Value, SingleFmt)); (X) -> X end, Args)
end.
%% @doc Returns an flattened list containing the ASCII representation of the given
%% term.
-spec fprint(term(), pos_integer()) -> string().

불러오는 중...
취소
저장