From d3f0d1785e5847031f21484ca99c503c6ef704b8 Mon Sep 17 00:00:00 2001 From: Hans Bolinder Date: Mon, 9 Apr 2018 12:22:11 +0200 Subject: stdlib: io_lib{_pretty}: Avoid tuple_to_list when possible --- lib/stdlib/src/io_lib.erl | 31 ++++++++++++++++++++----------- lib/stdlib/src/io_lib_pretty.erl | 35 ++++++++++++++++++++++++++--------- 2 files changed, 46 insertions(+), 20 deletions(-) (limited to 'lib/stdlib/src') diff --git a/lib/stdlib/src/io_lib.erl b/lib/stdlib/src/io_lib.erl index 6be953f6ca..17b6e9967c 100644 --- a/lib/stdlib/src/io_lib.erl +++ b/lib/stdlib/src/io_lib.erl @@ -300,7 +300,7 @@ write1([H|T], D, E) -> if D =:= 1 -> "[...]"; true -> - [$[,[write1(H, D-1, E)|write_tail(T, D-1, E, $|)],$]] + [$[,[write1(H, D-1, E)|write_tail(T, D-1, E)],$]] end; write1(F, _D, _E) when is_function(F) -> erlang:fun_to_list(F); @@ -311,20 +311,24 @@ write1(T, D, E) when is_tuple(T) -> D =:= 1 -> "{...}"; true -> [${, - [write1(element(1, T), D-1, E)| - write_tail(tl(tuple_to_list(T)), D-1, E, $,)], + [write1(element(1, T), D-1, E)|write_tuple(T, 2, D-1, E)], $}] end. -%% write_tail(List, Depth, CharacterBeforeDots) +%% write_tail(List, Depth, Encoding) %% Test the terminating case first as this looks better with depth. -write_tail([], _D, _E, _S) -> ""; -write_tail(_, 1, _E, S) -> [S | "..."]; -write_tail([H|T], D, E, S) -> - [$,,write1(H, D-1, E)|write_tail(T, D-1, E, S)]; -write_tail(Other, D, E, S) -> - [S,write1(Other, D-1, E)]. +write_tail([], _D, _E) -> ""; +write_tail(_, 1, _E) -> [$| | "..."]; +write_tail([H|T], D, E) -> + [$,,write1(H, D-1, E)|write_tail(T, D-1, E)]; +write_tail(Other, D, E) -> + [$|,write1(Other, D-1, E)]. + +write_tuple(T, I, _D, _E) when I > tuple_size(T) -> ""; +write_tuple(_, _I, 1, _E) -> [$, | "..."]; +write_tuple(T, I, D, E) -> + [$,,write1(element(I, T), D-1, E)|write_tuple(T, I+1, D-1, E)]. write_port(Port) -> erlang:port_to_list(Port). @@ -947,7 +951,7 @@ limit(T, D) when is_tuple(T) -> D =:= 1 -> {'...'}; true -> list_to_tuple([limit(element(1, T), D-1)| - limit_tail(tl(tuple_to_list(T)), D-1)]) + limit_tuple(T, 2, D-1)]) end; limit(<<_/bitstring>>=Term, D) -> limit_bitstring(Term, D); limit(Term, _D) -> Term. @@ -959,6 +963,11 @@ limit_tail([H|T], D) -> limit_tail(Other, D) -> limit(Other, D-1). +limit_tuple(T, I, _D) when I > tuple_size(T) -> []; +limit_tuple(_, _I, 1) -> ['...']; +limit_tuple(T, I, D) -> + [limit(element(I, T), D-1)|limit_tuple(T, I+1, D-1)]. + %% Cannot limit maps properly since there is no guarantee that %% maps:from_list() creates a map with the same internal ordering of %% the selected associations as in Map. Instead of subtracting one diff --git a/lib/stdlib/src/io_lib_pretty.erl b/lib/stdlib/src/io_lib_pretty.erl index 656d2ddd41..785c602ac0 100644 --- a/lib/stdlib/src/io_lib_pretty.erl +++ b/lib/stdlib/src/io_lib_pretty.erl @@ -618,11 +618,24 @@ print_length_tuple(Tuple, 1, _T, RF, Enc, Str) -> More = fun(T1, Dd) -> ?FUNCTION_NAME(Tuple, 1+Dd, T1, RF, Enc, Str) end, {"{...}", 5, 3, More}; print_length_tuple(Tuple, D, T, RF, Enc, Str) -> - L = print_length_list1(tuple_to_list(Tuple), D, tsub(T, 2), RF, Enc, Str), + L = print_length_tuple1(Tuple, 1, D, tsub(T, 2), RF, Enc, Str), IsTagged = is_atom(element(1, Tuple)) and (tuple_size(Tuple) > 1), {Len, Dots} = list_length(L, 2, 0), {{tuple,IsTagged,L}, Len, Dots, no_more}. +print_length_tuple1(Tuple, I, _D, _T, _RF, _Enc, _Str) + when I > tuple_size(Tuple) -> + []; +print_length_tuple1(Tuple, I, D, T, RF, Enc, Str) when D =:= 1; T =:= 0-> + More = fun(T1, Dd) -> ?FUNCTION_NAME(Tuple, I, D+Dd, T1, RF, Enc, Str) end, + {dots, 3, 3, More}; +print_length_tuple1(Tuple, I, D, T, RF, Enc, Str) -> + E = element(I, Tuple), + T1 = tsub(T, 1), + {_, Len1, _, _} = Elem1 = print_length(E, D - 1, T1, RF, Enc, Str), + T2 = tsub(T1, Len1), + [Elem1 | print_length_tuple1(Tuple, I + 1, D - 1, T2, RF, Enc, Str)]. + print_length_record(Tuple, 1, _T, RF, RDefs, Enc, Str) -> More = fun(T1, Dd) -> ?FUNCTION_NAME(Tuple, 1+Dd, T1, RF, RDefs, Enc, Str) @@ -631,24 +644,28 @@ print_length_record(Tuple, 1, _T, RF, RDefs, Enc, Str) -> print_length_record(Tuple, D, T, RF, RDefs, Enc, Str) -> Name = [$# | write_atom(element(1, Tuple), Enc)], NameL = string:length(Name), - Elements = tl(tuple_to_list(Tuple)), T1 = tsub(T, NameL+2), - L = print_length_fields(RDefs, D - 1, T1, Elements, RF, Enc, Str), + L = print_length_fields(RDefs, D - 1, T1, Tuple, 2, RF, Enc, Str), {Len, Dots} = list_length(L, NameL + 2, 0), {{record, [{Name,NameL} | L]}, Len, Dots, no_more}. -print_length_fields([], _D, _T, [], _RF, _Enc, _Str) -> +print_length_fields([], _D, _T, Tuple, I, _RF, _Enc, _Str) + when I > tuple_size(Tuple) -> []; -print_length_fields(Term, D, T, Es, RF, Enc, Str) when D =:= 1; T =:= 0 -> +print_length_fields(Term, D, T, Tuple, I, RF, Enc, Str) + when D =:= 1; T =:= 0 -> More = fun(T1, Dd) -> - ?FUNCTION_NAME(Term, D+Dd, T1, Es, RF, Enc, Str) + ?FUNCTION_NAME(Term, D+Dd, T1, Tuple, I, RF, Enc, Str) end, {dots, 3, 3, More}; -print_length_fields([Def | Defs], D, T, [E | Es], RF, Enc, Str) -> - Field1 = print_length_field(Def, D - 1, tsub(T, 1), E, RF, Enc, Str), +print_length_fields([Def | Defs], D, T, Tuple, I, RF, Enc, Str) -> + E = element(I, Tuple), + T1 = tsub(T, 1), + Field1 = print_length_field(Def, D - 1, T1, E, RF, Enc, Str), {_, Len1, _, _} = Field1, + T2 = tsub(T1, Len1), [Field1 | - print_length_fields(Defs, D - 1, tsub(T, Len1 + 1), Es, RF, Enc, Str)]. + print_length_fields(Defs, D - 1, T2, Tuple, I + 1, RF, Enc, Str)]. print_length_field(Def, D, T, E, RF, Enc, Str) -> Name = write_atom(Def, Enc), -- cgit v1.2.3