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 + -
显示快捷键?