io_lib_pretty.erl

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

ERL
547
字号
%% ``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%% compliance with the License. You should have received a copy of the%% Erlang Public License along with this software. If not, it can be%% retrieved via the world wide web at http://www.erlang.org/.%% %% Software distributed under the License is distributed on an "AS IS"%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See%% the License for the specific language governing rights and limitations%% under the License.%% %% The Initial Developer of the Original Code is Ericsson Utvecklings AB.%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings%% AB. All Rights Reserved.''%% %%     $Id $%%-module(io_lib_pretty).%%% Pretty printing Erlang terms%%%%%% In this module "print" means the formatted printing while "write"%%% means just writing out onto one line.-export([print/1,print/2,print/3,print/4,print/5]).%%%%%% Exported functions%%%%% print(Term) -> [Chars]%% print(Term, Column, LineLength, Depth) -> [Chars]%% Depth = -1 gives unlimited print depth. Use io_lib:write for atomic terms.print(Term) ->    print(Term, 1, 80, -1).%% print(Term, RecDefFun) -> [Chars]%% print(Term, Depth, RecDefFun) -> [Chars]%% RecDefFun = fun(Tag, NoFields) -> [FieldTag] | no%% Used by the shell for printing records.print(Term, RecDefFun) ->    print(Term, -1, RecDefFun).print(Term, Depth, RecDefFun) ->    print(Term, 1, 80, Depth, RecDefFun).print(Term, Col, Ll, D) ->    print(Term, Col, Ll, D, no_fun).print(_, _, _, 0, _RF) -> "...";print(Term, Col, Ll, D, RecDefFun) when Col =< 0 ->    print(Term, 1, Ll, D, RecDefFun);print(Term, Col, Ll, D, RecDefFun) when is_tuple(Term);                                         is_list(Term) ->    If = {_S, Len} = print_length(Term, D, RecDefFun),    if        Len < Ll - Col ->            write(If);        true ->            TInd = while_fail([-1, 4], fun(I) -> cind(If, Col, Ll, I) end, 1),            pp(If, Col, Ll, TInd, indent(Col), 0)    end;print(<<_/bitstr>>=Term, Col, Ll, D, RecDefFun) ->    If = {_S, Len} = print_length(Term, D, RecDefFun),    if        Len < Ll - Col ->            write(If);        true ->            TInd = while_fail([-1, 4], fun(I) -> cind(If, Col, Ll, I) end, 1),            pp(If, Col, Ll, TInd, indent(Col), 0)    end;print(Term, _Col, _Ll, _D, _RF) ->    io_lib:write(Term).%%%%%% Local functions%%%pp({_S, Len} = If, Col, Ll, _TInd, _Ind, LD) when Len < Ll - Col - LD ->    write(If);pp({{list,L}, _Len}, Col, Ll, TInd, Ind, LD) ->    [$[, pp_list(L, Col + 1, Ll, TInd, indent(1, Ind), LD, $|), $]];pp({{tuple,true,L}, _Len}, Col, Ll, TInd, Ind, LD) ->    [${, pp_tag_tuple(L, Col, Ll, TInd, Ind, LD), $}];pp({{tuple,false,L}, _Len}, Col, Ll, TInd, Ind, LD) ->    [${, pp_list(L, Col + 1, Ll, TInd, indent(1, Ind), LD, $,), $}];pp({{record,[{Name,NLen} | L]}, _Len}, Col, Ll, TInd, Ind, LD) ->    [Name, ${, pp_record(L, NLen, Col, Ll, TInd, Ind, LD), $}];pp({{bin,S}, _Len}, Col, Ll, _TInd, Ind, LD) ->    pp_binary(S, Col + 2, Ll, indent(2, Ind), LD);pp({S, _Len}, _Col, _Ll, _TInd, _Ind, _LD) ->    S.%%  Print a tagged tuple by indenting the rest of the elements%%  differently to the tag. Tuple has size >= 2.pp_tag_tuple([{Tag,Tlen} | L], Col, Ll, TInd, Ind, LD) ->    TagInd = Tlen + 2,    Tcol = Col + TagInd,    S = $,,    if        TInd > 0, TagInd > TInd ->            [Tag | pp_tail(L, Col+TInd, Ll, TInd, indent(TInd, Ind), LD, S)];        true ->            [Tag, S | pp_list(L, Tcol, Ll, TInd, indent(TagInd, Ind), LD, S)]    end.pp_record([], _Nlen, _Col, _Ll, _TInd, _Ind, _LD) ->    "";pp_record({dots, _}, _Nlen, _Col, _Ll, _TInd, _Ind, _LD) ->    "...";pp_record([F | Fs], Nlen, Col0, Ll, TInd, Ind0, LD) ->    Nind = Nlen + 1,    {Col, Ind, S} = rec_indent(Nind, TInd, Col0, Ind0),    [S, pp_field(F, Col, Ll, TInd, Ind, last_depth(Fs, LD)) |      pp_fields_tail(Fs, Col, Ll, TInd, Ind, LD)].    pp_fields_tail([], _Col, _Ll, _TInd, _Ind, _LD) ->    "";pp_fields_tail({dots, _}, _Col, _Ll, _TInd, _Ind, _LD) ->    ",...";pp_fields_tail([F | Fs], Col, Ll, TInd, Ind, LD) ->    [$,, $\n, Ind, pp_field(F, Col, Ll, TInd, Ind, last_depth(Fs, LD)) |     pp_fields_tail(Fs, Col, Ll, TInd, Ind, LD)].pp_field({_,Len}=Fl, Col, Ll, _TInd, _Ind, LD) when Len < Ll - Col - LD ->    write_field(Fl);pp_field({{field, Name, NameL, F}, _Len}, Col0, Ll, TInd, Ind0, LD) ->    {Col, Ind, S} = rec_indent(NameL, TInd, Col0, Ind0),    [Name, " = ", S | pp(F, Col, Ll, TInd, Ind, LD)].rec_indent(RInd, TInd, Col0, Ind0) ->    Nl = (TInd > 0) and (RInd > TInd),    DCol = case Nl of               true -> TInd;               false -> RInd           end,    Col = Col0 + DCol,    Ind = indent(DCol, Ind0),    S = case Nl of            true -> [$\n | Ind];            false -> ""        end,    {Col, Ind, S}.pp_list({dots, _}, _Col, _Ll, _TInd, _Ind, _LD, _S) ->    "...";pp_list([E | Es], Col, Ll, TInd, Ind, LD, S) ->    [pp(E, Col, Ll, TInd, Ind, last_depth(Es, LD)) |      pp_tail(Es, Col, Ll, TInd, Ind, LD, S)].pp_tail([], _Col, _Ll, _TInd, _Ind, _LD, _S) ->    "";pp_tail([E | Es], Col, Ll, TInd, Ind, LD, S) ->    [$,, $\n, Ind, pp(E, Col, Ll, TInd, Ind, last_depth(Es, LD)) |      pp_tail(Es, Col, Ll, TInd, Ind, LD, S)];pp_tail({dots, _}, _Col, _Ll, _TInd, _Ind, _LD, S) ->    [S | "..."];pp_tail(E, Col, Ll, TInd, Ind, LD, S) ->    [S, $\n, Ind | pp(E, Col, Ll, TInd, Ind, LD + 1)].last_depth([_ | _], _LD) ->    0;last_depth(_, LD) ->    LD + 1.%% Reuse the list created by io_lib:write_binary()...pp_binary([LT,LT,S,GT,GT], Col, Ll, Ind, LD) ->    N = max(8, Ll - Col - LD),    [LT,LT,pp_binary(S, N, N, Ind),GT,GT].pp_binary([BS, $, | S], N, N0, Ind) ->    Len = length(BS) + 1,    case N - Len of        N1 when N1 < 0 ->            [$\n, Ind, BS, $, | pp_binary(S, N0 - Len, N0, Ind)];        N1 ->            [BS, $, | pp_binary(S, N1, N0, Ind)]    end;pp_binary([BS1, $:, BS2]=S, N, _N0, Ind)          when length(BS1) + length(BS2) + 1 > N ->    [$\n, Ind, S];pp_binary(S, N, _N0, Ind) when length(S) > N ->    [$\n, Ind, S];pp_binary(S, _N, _N0, _Ind) ->    S.write({{tuple, _IsTagged, L}, _}) ->    [${, write_list(L, $,), $}];write({{list, L}, _}) ->    [$[, write_list(L, $|), $]];write({{record, [{Name,_} | L]}, _}) ->    [Name, ${, write_fields(L), $}];write({{bin, S}, _}) ->    S;write({S, _}) ->    S.write_fields([]) ->    "";write_fields({dots, _}) ->    "...";write_fields([F | Fs]) ->    [write_field(F) | write_fields_tail(Fs)].write_fields_tail([]) ->    "";write_fields_tail({dots, _}) ->    ",...";write_fields_tail([F | Fs]) ->    [$,, write_field(F) | write_fields_tail(Fs)].write_field({{field, Name, _NameL, F}, _}) ->    [Name, " = " | write(F)].write_list({dots, _}, _S) ->    "...";write_list([E | Es], S) ->    [write(E) | write_tail(Es, S)].write_tail([], _S) ->    [];write_tail([E | Es], S) ->    [$,, write(E) | write_tail(Es, S)];write_tail({dots, _}, S) ->    [S | "..."];write_tail(E, S) ->    [S | write(E)].%% The depth (D) is used for extracting and counting the characters to%% print. The structure is kept so that the returned intermediate%% format can be formatted. The separators (list, tuple, record) are%% counted but need to be added later.%% D =/= 0print_length([], _D, _RF) ->    {"[]", 2};print_length({}, _D, _RF) ->    {"{}", 2};print_length(List, D, RF) when is_list(List) ->    case printable_list(List, D) of        true ->            S = io_lib:write_string(List, $"), %"            {S, length(S)};        %% Truncated lists could break some existing code.        % {true, Prefix} ->        %    S = io_lib:write_string(Prefix, $"), %"        %    {[S | "..."], 3 + length(S)};        false ->            print_length_list(List, D, RF)    end;print_length(Fun, _D, _RF) when is_function(Fun) ->    S = io_lib:write(Fun),    {S, iolist_size(S)};print_length(R, D, RF) when is_atom(element(1, R)),                             is_function(RF) ->    case RF(element(1, R), size(R) - 1) of        no ->             print_length_tuple(R, D, RF);        RDefs ->            print_length_record(R, D, RF, RDefs)    end;print_length(Tuple, D, RF) when is_tuple(Tuple) ->    print_length_tuple(Tuple, D, RF);print_length(<<>>, _D, _RF) ->    {"<<>>", 4};print_length(<<_/bitstr>>, 1, _RF) ->    {"<<...>>", 7};print_length(<<_/bitstr>>=Bin, D, _RF) ->    case erlang:bitsize(Bin) rem 8 of        0 ->	    D1 = D - 1, 	    case printable_bin(Bin, D1) of	        List when is_list(List) ->

⌨️ 快捷键说明

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