io_lib_pretty.erl

来自「OTP是开放电信平台的简称」· ERL 代码 · 共 547 行 · 第 1/2 页

ERL
547
字号
                    S = io_lib:write_string(List, $"),						            {[$<,$<,S,$>,$>], 4 + length(S)};	        {true, Prefix} -> 	            S = io_lib:write_string(Prefix, $"), 	            {[$<,$<, S | "...>>"], 4 + length(S)};	        false ->	            S = io_lib:write(Bin, D),	            {{bin,S}, iolist_size(S)}	    end;        _ ->            S = io_lib:write(Bin, D),	   {{bin,S}, iolist_size(S)}    end;    print_length(Term, _D, _RF) ->    S = io_lib:write(Term),    {S, iolist_size(S)}.print_length_tuple(_Tuple, 1, _RF) ->    {"{...}", 5};print_length_tuple(Tuple, D, RF) ->    L = print_length_list1(tuple_to_list(Tuple), D, RF),    IsTagged = is_atom(element(1, Tuple)) and (size(Tuple) > 1),    {{tuple,IsTagged,L}, list_length(L, 2)}.print_length_record(_Tuple, 1, _RF, _RDefs) ->    {"{...}", 5};print_length_record(Tuple, D, RF, RDefs) ->    Name = [$# | io_lib:write_atom(element(1, Tuple))],    NameL = length(Name),    L = print_length_fields(RDefs, D - 1, tl(tuple_to_list(Tuple)), RF),    {{record, [{Name,NameL} | L]}, list_length(L, NameL + 2)}.print_length_fields([], _D, [], _RF) ->    [];print_length_fields(_, 1, _, _RF) ->     {dots, 3};print_length_fields([Def | Defs], D, [E | Es], RF) ->    [print_length_field(Def, D - 1, E, RF) |      print_length_fields(Defs, D - 1, Es, RF)].print_length_field(Def, D, E, RF) ->    Name = io_lib:write_atom(Def),    {S, L} = print_length(E, D, RF),    NameL = length(Name) + 3,    {{field, Name, NameL, {S, L}}, NameL + L}.print_length_list(List, D, RF) ->     L = print_length_list1(List, D, RF),    {{list, L}, list_length(L, 2)}.print_length_list1([], _D, _RF) ->    [];print_length_list1(_, 1, _RF) ->    {dots, 3};print_length_list1([E | Es], D, RF) ->    [print_length(E, D - 1, RF) | print_length_list1(Es, D - 1, RF)];print_length_list1(E, D, RF) ->    print_length(E, D - 1, RF).list_length([], Acc) ->    Acc;list_length([{_, Len} | Es], Acc) ->    list_length_tail(Es, Acc + Len);list_length({_, Len}, Acc) ->    Acc + Len.list_length_tail([], Acc) ->    Acc;list_length_tail([{_,Len} | Es], Acc) ->    list_length_tail(Es, Acc + 1 + Len);list_length_tail({_, Len}, Acc) ->    Acc + 1 + Len.%% ?CHARS printable characters has depth 1.-define(CHARS, 4).printable_list(L, D) when D < 0 ->    io_lib:printable_list(L);printable_list(_L, 1) ->    false;printable_list(L, _D) ->    io_lib:printable_list(L).%% Truncated lists could break some existing code.% printable_list(L, D) ->%     Len = ?CHARS * (D - 1),%     case printable_list1(L, Len) of%         all ->%             true;%         N when is_integer(N), Len - N >= D - 1 ->%             {L1, _} = lists:split(Len - N, L),%             {true, L1};%         N when is_integer(N) ->%             false%     end.printable_bin(Bin, D) when D >= 0, ?CHARS * D =< size(Bin) ->    printable_bin(Bin, min(?CHARS * D, size(Bin)), D);printable_bin(Bin, D) ->    printable_bin(Bin, size(Bin), D).printable_bin(Bin, Len, D) ->    N = min(20, Len),    L = binary_to_list(Bin, 1, N),    case printable_list1(L, N) of        all when N =:= size(Bin)  ->            L;        all when N =:= Len -> % N < size(Bin)            {true, L};        all ->            case printable_bin1(Bin, 1 + N, Len - N) of                0 when size(Bin) =:= Len ->                    binary_to_list(Bin);                NC when D > 0, Len - NC >= D ->                    {true, binary_to_list(Bin, 1, Len - NC)};                NC when is_integer(NC) ->                    false            end;        NC when is_integer(NC), D > 0, N - NC >= D ->            {true, binary_to_list(Bin, 1, N - NC)};        NC when is_integer(NC) ->            false    end.printable_bin1(_Bin, _Start, 0) ->    0;printable_bin1(Bin, Start, Len) ->    N = min(10000, Len),    L = binary_to_list(Bin, Start, Start + N - 1),    case printable_list1(L, N) of        all ->            printable_bin1(Bin, Start + N, Len - N);        NC when is_integer(NC) ->            Len - (N - NC)    end.%% -> all | integer() >=0. Adopted from io_lib.erl.% printable_list1([_ | _], 0) -> 0;printable_list1([C | Cs], N) when is_integer(C), C >= $\s, C =< $~ ->    printable_list1(Cs, N - 1);printable_list1([C | Cs], N) when is_integer(C), C >= $\240, C =< $\377 ->    printable_list1(Cs, N - 1);printable_list1([$\n | Cs], N) -> printable_list1(Cs, N - 1);printable_list1([$\r | Cs], N) -> printable_list1(Cs, N - 1);printable_list1([$\t | Cs], N) -> printable_list1(Cs, N - 1);printable_list1([$\v | Cs], N) -> printable_list1(Cs, N - 1);printable_list1([$\b | Cs], N) -> printable_list1(Cs, N - 1);printable_list1([$\f | Cs], N) -> printable_list1(Cs, N - 1);printable_list1([$\e | Cs], N) -> printable_list1(Cs, N - 1);printable_list1([], _) -> all;printable_list1(_, N) -> N.%% Throw 'no_good' if the indentation exceeds half the line length.cind({_S, Len}, Col, Ll, Ind) when Len < Ll - Col ->    Ind;cind({{list,L}, _Len}, Col, Ll, Ind) ->    cind_list(L, Col + 1, Ll, Ind);cind({{tuple,true,L}, _Len}, Col, Ll, Ind) ->    cind_tag_tuple(L, Col, Ll, Ind);cind({{tuple,false,L}, _Len}, Col, Ll, Ind) ->    cind_list(L, Col + 1, Ll, Ind);cind({{record,[{_Name,NLen} | L]}, _Len}, Col, Ll, Ind) ->    cind_record(L, NLen, Col, Ll, Ind);cind({{bin,_S}, _Len}, _Col, _Ll, Ind) ->    Ind;cind({_S, _Len}, _Col, _Ll, Ind) ->    Ind.cind_tag_tuple([{_Tag,Tlen} | L], Col, Ll, Ind) ->    Tind = Tlen + 2,    Tcol = Col + Tind,    if        Ind > 0, Tind > Ind ->            Tcoli = Col + Ind,            if                Tcoli > Ll div 2 ->                    throw(no_good);                true ->                      cind_tail(L, Tcoli, Ll, Ind)            end;        Tcol >= Ll div 2 ->            throw(no_good);        true ->            cind_list(L, Tcol, Ll, Ind)    end.cind_record([F | Fs], Nlen, Col0, Ll, Ind) ->    Nind = Nlen + 1,    Col = cind_tag(Nind, Col0, Ll, Ind),    cind_field(F, Col, Ll, Ind),    cind_fields_tail(Fs, Col, Ll, Ind);cind_record(_, _Nlen, _Col, _Ll, Ind) ->    Ind.cind_fields_tail([F | Fs], Col, Ll, Ind) ->    cind_field(F, Col, Ll, Ind),    cind_fields_tail(Fs, Col, Ll, Ind);cind_fields_tail(_, _Col, _Ll, Ind) ->    Ind.cind_field({{field, _N, _NL, _F}, Len}, Col, Ll, Ind) when Len < Ll - Col ->    Ind;cind_field({{field, _Name, NameL, F}, _Len}, Col0, Ll, Ind) ->    Col = cind_tag(NameL, Col0, Ll, Ind),    cind(F, Col, Ll, Ind).cind_tag(TInd, Col0, Ll, Ind) ->    DCol = if               Ind > 0, TInd > Ind ->                   Ind;               true ->                   TInd           end,    Col = Col0 + DCol,    if        Col > Ll div 2 ->            throw(no_good);        true ->            Col    end.cind_list({dots, _}, _Col, _Ll, Ind) ->    Ind;cind_list([E | Es], Col, Ll, Ind) ->    cind(E, Col, Ll, Ind),    cind_tail(Es, Col, Ll, Ind).cind_tail([], _Col, _Ll, Ind) ->    Ind;cind_tail([E | Es], Col, Ll, Ind) ->    cind(E, Col, Ll, Ind),    cind_tail(Es, Col, Ll, Ind);cind_tail({dots, _}, _Col, _Ll, Ind) ->    Ind;cind_tail(E, Col, Ll, Ind) ->    cind(E, Col, Ll, Ind).while_fail([], _F, V) ->    V;while_fail([A | As], F, V) ->    try F(A) catch _ -> while_fail(As, F, V) end.min(X, Y) when X =< Y -> X;min(_X, Y) -> Y.max(X, Y) when X >= Y -> X;max(_X, Y) -> Y.indent(N) when is_integer(N), N > 0 ->    chars($\s, N-1).indent(1, Ind) -> % Optimization of common case    [$\s | Ind];indent(4, Ind) -> % Optimization of common case    S2 = [$\s, $\s],    [S2, S2 | Ind];indent(N, Ind) when is_integer(N), N > 0 ->    [chars($\s, N) | Ind].%% A deep version of string:chars/2chars(_C, 0) ->    [];chars(C, 2) ->    [C, C];chars(C, 3) ->    [C, C, C];chars(C, N) when (N band 1) =:= 0 ->    S = chars(C, N bsr 1),    [S | S];chars(C, N) ->    S = chars(C, N bsr 1),    [C, S | S].

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?