1%% 2%% %CopyrightBegin% 3%% 4%% Copyright Ericsson AB 1997-2016. All Rights Reserved. 5%% 6%% Licensed under the Apache License, Version 2.0 (the "License"); 7%% you may not use this file except in compliance with the License. 8%% You may obtain a copy of the License at 9%% 10%% http://www.apache.org/licenses/LICENSE-2.0 11%% 12%% Unless required by applicable law or agreed to in writing, software 13%% distributed under the License is distributed on an "AS IS" BASIS, 14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15%% See the License for the specific language governing permissions and 16%% limitations under the License. 17%% 18%% %CopyrightEnd% 19%% 20%% 21 22%% usage: pretty_format:term(Term) -> PNF list of characters 23%% 24%% Note: this is usually used in expressions like: 25%% io:format('~s\n',[pretty_format:term(Term)]). 26%% 27%% Uses the following simple heuristics 28%% 29%% 1) Simple tuples are printed across the page 30%% (Simple means *all* the elements are "flat") 31%% 2) The Complex tuple {Arg1, Arg2, Arg3,....} is printed thus: 32%% {Arg1, 33%% Arg2, 34%% Arg3, 35%% ...} 36%% 3) Lists are treated as for tuples 37%% 4) Lists of printable characters are treated as strings 38%% 39%% This method seems to work reasonable well for {Tag, ...} type 40%% data structures 41 42-module(asn1ct_pretty_format). 43 44-export([term/1]). 45 46-import(io_lib, [write/1, write_string/1]). 47 48term(Term) -> 49 element(2, term(Term, 0)). 50 51%%______________________________________________________________________ 52%% pretty_format:term(Term, Indent} -> {Indent', Chars} 53%% Format <Term> -- use <Indent> to indent the *next* line 54%% Note: Indent' is a new indentaion level (sometimes printing <Term> 55%% the next line to need an "extra" indent!). 56 57term([], Indent) -> 58 {Indent, [$[,$]]}; 59term(L, Indent) when is_list(L) -> 60 case is_string(L) of 61 true -> 62 {Indent, write_string(L)}; 63 false -> 64 case complex_list(L) of 65 true -> 66 write_complex_list(L, Indent); 67 false -> 68 write_simple_list(L, Indent) 69 end 70 end; 71term(T, Indent) when is_tuple(T) -> 72 case complex_tuple(T) of 73 true -> 74 write_complex_tuple(T, Indent); 75 false -> 76 write_simple_tuple(T, Indent) 77 end; 78term(A, Indent) -> 79 {Indent, write(A)}. 80 81%%______________________________________________________________________ 82%% write_simple_list([H|T], Indent) -> {Indent', Chars} 83 84write_simple_list([H|T], Indent) -> 85 {_, S1} = term(H, Indent), 86 {_, S2} = write_simple_list_tail(T, Indent), 87 {Indent, [$[,S1|S2]}. 88 89write_simple_list_tail([H|T], Indent) -> 90 {_, S1} = term(H, Indent), 91 {_, S2} = write_simple_list_tail(T, Indent), 92 {Indent, [$,,S1| S2]}; 93write_simple_list_tail([], Indent) -> 94 {Indent, "]"}; 95write_simple_list_tail(Other, Indent) -> 96 {_, S} = term(Other, Indent), 97 {Indent, [$|,S,$]]}. 98 99%%______________________________________________________________________ 100%% write_complex_list([H|T], Indent) -> {Indent', Chars} 101 102write_complex_list([H|T], Indent) -> 103 {I1, S1} = term(H, Indent+1), 104 {_, S2} = write_complex_list_tail(T, I1), 105 {Indent, [$[,S1|S2]}. 106 107write_complex_list_tail([H|T], Indent) -> 108 {I1, S1} = term(H, Indent), 109 {_, S2} = write_complex_list_tail(T, I1), 110 {Indent, [$,,nl_indent(Indent),S1,S2]}; 111write_complex_list_tail([], Indent) -> 112 {Indent, "]"}; 113write_complex_list_tail(Other, Indent) -> 114 {_, S} = term(Other, Indent), 115 {Indent, [$|,S,$]]}. 116 117%%______________________________________________________________________ 118%% complex_list(List) -> true | false 119%% returns true if the list is complex otherwise false 120 121complex_list([]) -> 122 false; 123complex_list([H|T]) when is_list(H) =:= false , is_tuple(H) =:= false -> 124 complex_list(T); 125complex_list([H|T]) -> 126 case is_string(H) of 127 true -> 128 complex_list(T); 129 false -> 130 true 131 end; 132complex_list(_) -> true. 133 134%%______________________________________________________________________ 135%% complex_tuple(Tuple) -> true | false 136%% returns true if the tuple is complex otherwise false 137 138complex_tuple(T) -> 139 complex_list(tuple_to_list(T)). 140 141%%______________________________________________________________________ 142%% write_simple_tuple(Tuple, Indent} -> {Indent', Chars} 143 144write_simple_tuple({}, Indent) -> 145 {Indent, "{}"}; 146write_simple_tuple(Tuple, Indent) -> 147 {_, S} = write_simple_tuple_args(tuple_to_list(Tuple), Indent), 148 {Indent, [${, S, $}]}. 149 150write_simple_tuple_args([X], Indent) -> 151 term(X, Indent); 152write_simple_tuple_args([H|T], Indent) -> 153 {_, SH} = term(H, Indent), 154 {_, ST} = write_simple_tuple_args(T, Indent), 155 {Indent, [SH, $,, ST]}. 156 157%%______________________________________________________________________ 158%% write_complex_tuple(Tuple, Indent} -> {Indent', Chars} 159 160write_complex_tuple(Tuple, Indent) -> 161 [H|T] = tuple_to_list(Tuple), 162 {I1, SH} = term(H, Indent+2), 163 {_, ST} = write_complex_tuple_args(T, I1), 164 {Indent, [${, SH, ST, $}]}. 165 166write_complex_tuple_args([X], Indent) -> 167 {_, S} = term(X, Indent), 168 {Indent, [$,, nl_indent(Indent), S]}; 169write_complex_tuple_args([H|T], Indent) -> 170 {I1, SH} = term(H, Indent), 171 {_, ST} = write_complex_tuple_args(T, I1), 172 {Indent, [$,, nl_indent(Indent) , SH, ST]}; 173write_complex_tuple_args([], Indent) -> 174 {Indent, []}. 175 176%%______________________________________________________________________ 177%% utilities 178 179nl_indent(I) when I >= 0 -> 180 ["\n"|indent(I)]; 181nl_indent(_) -> 182 [$\s]. 183 184indent(I) when I >= 8 -> 185 [$\t|indent(I-8)]; 186indent(I) when I > 0 -> 187 [$\s|indent(I-1)]; 188indent(_) -> 189 []. 190 191is_string([9|T]) -> 192 is_string(T); 193is_string([10|T]) -> 194 is_string(T); 195is_string([H|T]) when H >31, H < 127 -> 196 is_string(T); 197is_string([]) -> 198 true; 199is_string(_) -> 200 false. 201 202 203