aboutsummaryrefslogtreecommitdiffstats
path: root/lib/asn1/src/asn1ct_pretty_format.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/asn1/src/asn1ct_pretty_format.erl')
-rw-r--r--lib/asn1/src/asn1ct_pretty_format.erl201
1 files changed, 201 insertions, 0 deletions
diff --git a/lib/asn1/src/asn1ct_pretty_format.erl b/lib/asn1/src/asn1ct_pretty_format.erl
new file mode 100644
index 0000000000..a01c1db8c5
--- /dev/null
+++ b/lib/asn1/src/asn1ct_pretty_format.erl
@@ -0,0 +1,201 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%%
+%% 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 online 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.
+%%
+%% %CopyrightEnd%
+%%
+%%
+
+%% usage: pretty_format:term(Term) -> PNF list of characters
+%%
+%% Note: this is usually used in expressions like:
+%% io:format('~s\n',[pretty_format:term(Term)]).
+%%
+%% Uses the following simple heuristics
+%%
+%% 1) Simple tuples are printed across the page
+%% (Simple means *all* the elements are "flat")
+%% 2) The Complex tuple {Arg1, Arg2, Arg3,....} is printed thus:
+%% {Arg1,
+%% Arg2,
+%% Arg3,
+%% ...}
+%% 3) Lists are treated as for tuples
+%% 4) Lists of printable characters are treated as strings
+%%
+%% This method seems to work reasonable well for {Tag, ...} type
+%% data structures
+
+-module(asn1ct_pretty_format).
+
+-export([term/1]).
+
+-import(io_lib, [write/1, write_string/1]).
+
+term(Term) ->
+ element(2, term(Term, 0)).
+
+%%______________________________________________________________________
+%% pretty_format:term(Term, Indent} -> {Indent', Chars}
+%% Format <Term> -- use <Indent> to indent the *next* line
+%% Note: Indent' is a new indentaion level (sometimes printing <Term>
+%% the next line to need an "extra" indent!).
+
+term([], Indent) ->
+ {Indent, [$[,$]]};
+term(L, Indent) when is_list(L) ->
+ case is_string(L) of
+ true ->
+ {Indent, write_string(L)};
+ false ->
+ case complex_list(L) of
+ true ->
+ write_complex_list(L, Indent);
+ false ->
+ write_simple_list(L, Indent)
+ end
+ end;
+term(T, Indent) when is_tuple(T) ->
+ case complex_tuple(T) of
+ true ->
+ write_complex_tuple(T, Indent);
+ false ->
+ write_simple_tuple(T, Indent)
+ end;
+term(A, Indent) ->
+ {Indent, write(A)}.
+
+%%______________________________________________________________________
+%% write_simple_list([H|T], Indent) -> {Indent', Chars}
+
+write_simple_list([H|T], Indent) ->
+ {_, S1} = term(H, Indent),
+ {_, S2} = write_simple_list_tail(T, Indent),
+ {Indent, [$[,S1|S2]}.
+
+write_simple_list_tail([H|T], Indent) ->
+ {_, S1} = term(H, Indent),
+ {_, S2} = write_simple_list_tail(T, Indent),
+ {Indent, [$,,S1| S2]};
+write_simple_list_tail([], Indent) ->
+ {Indent, "]"};
+write_simple_list_tail(Other, Indent) ->
+ {_, S} = term(Other, Indent),
+ {Indent, [$|,S,$]]}.
+
+%%______________________________________________________________________
+%% write_complex_list([H|T], Indent) -> {Indent', Chars}
+
+write_complex_list([H|T], Indent) ->
+ {I1, S1} = term(H, Indent+1),
+ {_, S2} = write_complex_list_tail(T, I1),
+ {Indent, [$[,S1|S2]}.
+
+write_complex_list_tail([H|T], Indent) ->
+ {I1, S1} = term(H, Indent),
+ {_, S2} = write_complex_list_tail(T, I1),
+ {Indent, [$,,nl_indent(Indent),S1,S2]};
+write_complex_list_tail([], Indent) ->
+ {Indent, "]"};
+write_complex_list_tail(Other, Indent) ->
+ {_, S} = term(Other, Indent),
+ {Indent, [$|,S,$]]}.
+
+%%______________________________________________________________________
+%% complex_list(List) -> true | false
+%% returns true if the list is complex otherwise false
+
+complex_list([]) ->
+ false;
+complex_list([H|T]) when is_list(H) =:= false , is_tuple(H) =:= false ->
+ complex_list(T);
+complex_list([H|T]) ->
+ case is_string(H) of
+ true ->
+ complex_list(T);
+ false ->
+ true
+ end;
+complex_list(_) -> true.
+
+%%______________________________________________________________________
+%% complex_tuple(Tuple) -> true | false
+%% returns true if the tuple is complex otherwise false
+
+complex_tuple(T) ->
+ complex_list(tuple_to_list(T)).
+
+%%______________________________________________________________________
+%% write_simple_tuple(Tuple, Indent} -> {Indent', Chars}
+
+write_simple_tuple({}, Indent) ->
+ {Indent, "{}"};
+write_simple_tuple(Tuple, Indent) ->
+ {_, S} = write_simple_tuple_args(tuple_to_list(Tuple), Indent),
+ {Indent, [${, S, $}]}.
+
+write_simple_tuple_args([X], Indent) ->
+ term(X, Indent);
+write_simple_tuple_args([H|T], Indent) ->
+ {_, SH} = term(H, Indent),
+ {_, ST} = write_simple_tuple_args(T, Indent),
+ {Indent, [SH, $,, ST]}.
+
+%%______________________________________________________________________
+%% write_complex_tuple(Tuple, Indent} -> {Indent', Chars}
+
+write_complex_tuple(Tuple, Indent) ->
+ [H|T] = tuple_to_list(Tuple),
+ {I1, SH} = term(H, Indent+2),
+ {_, ST} = write_complex_tuple_args(T, I1),
+ {Indent, [${, SH, ST, $}]}.
+
+write_complex_tuple_args([X], Indent) ->
+ {_, S} = term(X, Indent),
+ {Indent, [$,, nl_indent(Indent), S]};
+write_complex_tuple_args([H|T], Indent) ->
+ {I1, SH} = term(H, Indent),
+ {_, ST} = write_complex_tuple_args(T, I1),
+ {Indent, [$,, nl_indent(Indent) , SH, ST]};
+write_complex_tuple_args([], Indent) ->
+ {Indent, []}.
+
+%%______________________________________________________________________
+%% utilities
+
+nl_indent(I) when I >= 0 ->
+ ["\n"|indent(I)];
+nl_indent(_) ->
+ [$\s].
+
+indent(I) when I >= 8 ->
+ [$\t|indent(I-8)];
+indent(I) when I > 0 ->
+ [$\s|indent(I-1)];
+indent(_) ->
+ [].
+
+is_string([9|T]) ->
+ is_string(T);
+is_string([10|T]) ->
+ is_string(T);
+is_string([H|T]) when H >31, H < 127 ->
+ is_string(T);
+is_string([]) ->
+ true;
+is_string(_) ->
+ false.
+
+