35
35
print(Term, 1, 80, -1).
37
print(List, Col, Ll, D) ->
38
print(List, Col, Ll, D, indent(Col)).
40
print(_, _, _, 0, _) -> "...";
41
print([], _, _, _, _) -> "[]";
42
print({}, _, _, _, _) -> "{}";
43
print(List, Col, Ll, D, Ind) when list(List) ->
37
%% print(Term, RecDefFun) -> [Chars]
38
%% print(Term, Depth, RecDefFun) -> [Chars]
39
%% RecDefFun = fun(Tag, NoFields) -> [FieldTag] | no
40
%% Used by the shell to print records.
41
print(Term, RecDefFun) ->
42
print(Term, -1, RecDefFun).
44
print(Term, Depth, RecDefFun) ->
45
print(Term, 1, 80, Depth, RecDefFun).
47
print(Term, Col, Ll, D) ->
48
print(Term, Col, Ll, D, no_fun).
50
print(Term, Col, Ll, D, RecDefFun) ->
51
print(Term, Col, Ll, D, indent(Col), RecDefFun).
53
print(_, _, _, 0, _, _RF) -> "...";
54
print([], _, _, _, _, _RF) -> "[]";
55
print({}, _, _, _, _, _RF) -> "{}";
56
print(List, Col, Ll, D, Ind, RF) when is_list(List) ->
44
57
case io_lib:printable_list(List) of
46
io_lib:write_string(List, $");
59
io_lib:write_string(List, $"); %"
48
Len = write_length(List, D, 0, Ll - Col),
61
Len = write_length(List, D, 0, Ll - Col, RF),
55
[print(hd(List), Col + 1, Ll, D - 1, indent(1, Ind))|
56
print_tail(tl(List), Col + 1, Ll, D - 1, indent(1, Ind))],
68
[print(hd(List), Col + 1, Ll, D - 1, indent(1, Ind), RF)|
69
print_tail(tl(List), Col + 1, Ll, D - 1, indent(1, Ind), RF)],
60
print(Fun, _Col, _Ll, _D, _Ind) when function(Fun) ->
73
print(Fun, _Col, _Ll, _D, _Ind, _RF) when is_function(Fun) ->
62
print(Tuple, Col, Ll, D, Ind) when tuple(Tuple) ->
63
Len = write_length(Tuple, D, 0, Ll - Col),
75
print(Rec, Col, Ll, D, Ind, RF) when is_atom(element(1, Rec)),
77
case RF(element(1, Rec), size(Rec) - 1) of
79
print_tuple(Rec, Col, Ll, D, Ind, RF);
81
print_record(Rec, RDefs, Col, Ll, D, Ind, RF)
83
print(Tuple, Col, Ll, D, Ind, RF) when is_tuple(Tuple) ->
84
print_tuple(Tuple, Col, Ll, D, Ind, RF);
85
print(Binary, _Col, _Ll, D, _Ind, _RF) when is_binary(Binary) ->
86
write_binary(Binary, D);
87
print(Term, _Col, _Ll, D, _Ind, _RF) -> io_lib:write(Term, D).
89
print_record(Rec, RDefs, Col, Ll, D, Ind, RF) ->
90
Len = write_length(Rec, D, 0, Ll - Col, RF),
96
Name = io_lib:write_atom(element(1, Rec)),
101
Ncol >= Ll div 2, Nlen > 2 ->
102
{4,[$\n,indent(4, Ind)]};
107
print_fields(RDefs, tl(tuple_to_list(Rec)),
108
Col + DCol, Ll, D - 2, indent(DCol, Ind), RF, S),
112
print_fields([], [], _Col, _Ll, _D, _Ind, _RF, _S) ->
114
print_fields(_Defs, _Es, _Col, _Ll, 1, _Ind, _RF, _S) ->
116
print_fields([Def|Defs], [E|Es], Col, Ll, D, Ind, RF, S) ->
117
[S,print_field(Def,E, Col, Ll, D-1, Ind, RF)|
118
print_fields(Defs, Es, Col, Ll, D-1, Ind, RF, [$,,$\n,Ind])].
120
print_field(_Def, _E, _Col, _Ll, 0, _Ind, _RF) ->
122
print_field(Def, E, Col, Ll, D, Ind, RF) ->
123
[io_lib:write_atom(Def)," = ",print(E, Col, Ll, D, Ind, RF)].
125
print_tuple(Tuple, Col, Ll, D, Ind, RF) ->
126
Len = write_length(Tuple, D, 0, Ll - Col, RF),
68
atom(element(1, Tuple)), size(Tuple) > 1 ->
69
print_tag_tuple(Tuple, Col, Ll, D, Ind);
131
is_atom(element(1, Tuple)), size(Tuple) > 1 ->
132
print_tag_tuple(Tuple, Col, Ll, D, Ind, RF);
72
[print(element(1, Tuple), Col + 1, Ll, D - 1, indent(1, Ind))|
135
[print(element(1, Tuple), Col + 1, Ll, D - 1, indent(1, Ind), RF)|
73
136
print_tail(tl(tuple_to_list(Tuple)),
74
Col + 1, Ll, D - 1, indent(1, Ind))],
137
Col + 1, Ll, D - 1, indent(1, Ind), RF)],
77
print(Binary, _Col, _Ll, D, _Ind) when binary(Binary) ->
78
io_lib:write(Binary, D);
79
print(Vec, _Col, _Ll, _D, _Ind) when size(Vec) == 0 ->
81
print(Vec, Col, Ll, D, Ind) when size(Vec) >= 0 ->
82
Len = write_length(Vec, D, 0, Ll - Col),
84
D == 1 -> "#Vector<...>";
89
[print(vector:get(1, Vec), Col + 1, Ll, D - 1, indent(1, Ind))|
90
print_tail(tl(vector:to_list(Vec)),
91
Col + 1, Ll, D - 1, indent(1, Ind))],
94
print(Term, _Col, _Ll, D, _Ind) -> io_lib:write(Term, D).
96
%% print_tag_tuple(Tuple, Column, LineLength, Depth, Ind) -> [Char]
141
%% print_tag_tuple(Tuple, Column, LineLength, Depth, Ind, RecDefFun) -> [Char]
97
142
%% Print a tagged tuple by indenting the rest of the elements differently
98
143
%% to the tag. Start beside the tag if start column not too far to
99
144
%% the right. Tuple has size >= 2.
101
print_tag_tuple(Tuple, Col, Ll, D, Ind) ->
146
print_tag_tuple(Tuple, Col, Ll, D, Ind, RF) ->
102
147
Tag = io_lib:write_atom(element(1, Tuple)),
103
148
Tlen = length(Tag),
107
152
Tcol >= Ll div 2, Tlen > 2 ->
109
154
print_tail(tl(tuple_to_list(Tuple)),
110
Col + 4, Ll, D - 2, indent(4, Ind)),
155
Col + 4, Ll, D - 2, indent(4, Ind), RF),
114
[print(element(2, Tuple), Tcol, Ll, D - 2, indent(Tind, Ind))|
159
[print(element(2, Tuple), Tcol, Ll, D - 2, indent(Tind,Ind), RF)|
115
160
print_tail(tl(tl(tuple_to_list(Tuple))),
116
Tcol, Ll, D - 3, indent(Tind, Ind))],
161
Tcol, Ll, D - 3, indent(Tind, Ind), RF)],
120
%% print_tail([Element], Column, LineLength, D, Ind) -> [Char]
165
%% print_tail([Element], Column, LineLength, D, Ind, RecDefFun) -> [Char]
121
166
%% Pretty print the elements of a list or tuple.
123
print_tail([], _Col, _Ll, _D, _Ind) -> "";
124
print_tail(_, _Col, _Ll, 1, _Ind) -> "|...";
125
print_tail([E|Es], Col, Ll, D, Ind) ->
126
[$,,$\n,Ind,print(E, Col, Ll, D-1)|
127
print_tail(Es, Col, Ll, D-1, Ind)];
128
print_tail(E, Col, Ll, D, Ind) ->
129
[$|,$\n,Ind,print(E, Col, Ll, D-1)].
168
print_tail([], _Col, _Ll, _D, _Ind, _RF) -> "";
169
print_tail(_, _Col, _Ll, 1, _Ind, _RF) -> "|...";
170
print_tail([E|Es], Col, Ll, D, Ind, RF) ->
171
[$,,$\n,Ind,print(E, Col, Ll, D-1, RF)|
172
print_tail(Es, Col, Ll, D-1, Ind, RF)];
173
print_tail(E, Col, Ll, D, Ind, RF) ->
174
[$|,$\n,Ind,print(E, Col, Ll, D-1, RF)].
131
%% write(Term, Depth) -> [Char]
176
%% write(Term, Depth, RecDefFun) -> [Char]
132
177
%% Write a term down to Depth on one line. Use io_lib:write/2 for
135
write(_, 0) -> "...";
136
write([], _) -> "[]";
137
write({}, _) -> "{}";
138
write(List, D) when list(List) ->
180
write(T, D, RF) when is_integer(D) -> write1(T, D, RF).
182
write1(_, 0, _RF) -> "...";
183
write1([], _, _RF) -> "[]";
184
write1({}, _, _RF) -> "{}";
185
write1(List, D, RF) when is_list(List) ->
139
186
case io_lib:printable_list(List) of
141
io_lib:write_string(List, $");
188
io_lib:write_string(List, $"); %"
147
[write(hd(List), D-1)|write_tail(tl(List), D-1)],
194
[write1(hd(List), D-1, RF)|write_tail(tl(List), D-1, RF)],
151
write(Fun, _D) when function(Fun) -> io_lib:write(Fun); %Must catch this first
152
write(T, D) when tuple(T) ->
198
write1(Fun, _D, _RF) when is_function(Fun) ->
199
io_lib:write(Fun); %Must catch this first
200
write1(R, D, RF) when is_atom(element(1, R)), is_function(RF) ->
201
case RF(element(1, R), size(R) - 1) of
203
write_tuple(R, D, RF);
205
[$#, io_lib:write_atom(element(1, R)), ${,
206
write_fields(RDefs, D - 1, tl(tuple_to_list(R)), RF, []),
209
write1(T, D, RF) when is_tuple(T) ->
210
write_tuple(T, D, RF);
211
write1(Bin, D, _RF) when is_binary(Bin) ->
212
write_binary(Bin, D);
213
write1(Term, D, _RF) -> io_lib:write(Term, D).
215
write_binary(Binary, _D) when size(Binary) =:= 0 ->
217
write_binary(Binary, D) ->
219
D < 0 -> size(Binary);
220
true -> min(size(Binary), D-1)
222
case is_printable(Binary, PLen) of
223
true when PLen =:= 0 ->
225
true when size(Binary) =< PLen ->
226
List = binary_to_list(Binary),
227
[$<, $<, io_lib:write_string(List, $"), $>, $>];
229
Prefix = binary_to_list(Binary, 1, PLen),
230
[$<,$<,io_lib:write_string(Prefix, $"), "...>>"];
232
io_lib:write(Binary, D)
235
write_tuple(T, D, RF) ->
157
[write(element(1, T), D-1)|write_tail(tl(tuple_to_list(T)), D-1)],
240
[write(element(1, T), D-1, RF) |
241
write_tail(tl(tuple_to_list(T)), D-1, RF)],
160
write(Bin, D) when binary(Bin) -> io_lib:write(Bin, D);
161
write(T, D) when size(T) >= 0 ->
163
D == 1 -> "#Vector<...>";
166
[write(vector:get(1, T), D-1)|write_tail(tl(vector:to_list(T)), D-1)],
169
write(Term, D) -> io_lib:write(Term, D).
171
write_tail([], _D) -> "";
172
write_tail(_, 1) -> "|...";
173
write_tail([E|Es], D) ->
174
[$,,write(E, D - 1)|write_tail(Es, D - 1)];
176
[$|,write(E, D - 1)].
245
write_tail([], _D, _RF) -> "";
246
write_tail(_, 1, _RF) -> "|...";
247
write_tail([E|Es], D, RF) ->
248
[$,,write(E, D - 1, RF)|write_tail(Es, D - 1, RF)];
249
write_tail(E, D, RF) ->
250
[$|,write(E, D - 1, RF)].
178
%% write_length(Term, Depth, Accumulator, MaxLength) -> integer()
252
write_fields([], _D, [], _RF, _S) ->
254
write_fields(_, 1, _, _RF, _S) ->
256
write_fields([Def|Defs], D, [E|Es], RF, S) ->
257
[S,write_field(Def, D - 1, E, RF)|write_fields(Defs, D - 1, Es, RF, $,)].
259
write_field(_Def, 0, _E, _RF) ->
261
write_field(Def, D, E, RF) ->
262
[io_lib:write_atom(Def)," = ",write(E, D, RF)].
264
%% write_length(Term, Depth, Accumulator, MaxLength, RecDefFun) -> integer()
179
265
%% Calculate the print length of a term, but exit when length becomes
180
266
%% greater than MaxLength.
182
write_length(_, _D, Acc, Max) when Acc > Max -> Acc;
183
write_length(_, 0, Acc, _Max) -> Acc + 3;
184
write_length([], _, Acc, _) -> Acc + 2;
185
write_length({}, _, Acc, _) -> Acc + 2;
186
write_length(List, D, Acc, Max) when list(List) ->
268
write_length(_, _D, Acc, Max, _RF) when Acc > Max -> Acc;
269
write_length(_, 0, Acc, _Max, _RF) -> Acc + 3;
270
write_length([], _, Acc, _, _RF) -> Acc + 2;
271
write_length({}, _, Acc, _, _RF) -> Acc + 2;
272
write_length(List, D, Acc, Max, RF) when is_list(List) ->
187
273
case io_lib:printable_list(List) of
189
Acc + length(io_lib:write_string(List, $"));
275
Acc + length(io_lib:write_string(List, $")); %"
191
write_length_list(List, D, Acc, Max)
277
write_length_list(List, D, Acc, Max, RF)
193
write_length(Fun, _D, Acc, _Max) when function(Fun) ->
279
write_length(Fun, _D, Acc, _Max, _RF) when is_function(Fun) ->
194
280
Acc + length(io_lib:write(Fun));
195
write_length(Tuple, D, Acc, Max) when tuple(Tuple) ->
196
write_length_list(tuple_to_list(Tuple), D, Acc, Max);
197
write_length(Bin, D, Acc, _Max) when binary(Bin) ->
198
if D < 0 -> %Used to print all
199
Acc + 4 + 4*size(Bin); %Acc + << 4*size >>
281
write_length(R, D, Acc, Max, RF) when is_atom(element(1, R)),
283
case RF(element(1, R), size(R) - 1 ) of
285
write_length_list(tuple_to_list(R), D, Acc, Max, RF);
287
Acc1 = Acc + 2 + length(io_lib:write_atom(element(1, R))),
288
write_length_fields(RDefs, D - 1, Acc1, Max, tl(tuple_to_list(R)), RF, 0)
290
write_length(Tuple, D, Acc, Max, RF) when is_tuple(Tuple) ->
291
write_length_list(tuple_to_list(Tuple), D, Acc, Max, RF);
292
write_length(Bin, D, Acc, Max, _RF) when is_binary(Bin) ->
294
D < 0 -> min(size(Bin), Max);
295
true -> min(size(Bin), D - 1)
297
case is_printable(Bin, PLen) of
298
true when PLen =:= 0 ->
301
List = binary_to_list(Bin, 1, PLen),
302
Acc + 4 + length(io_lib:write_string(List, $")); %"
303
false when D < 0; % Print all
305
Acc + 4 + 4*size(Bin); % Overestimation
203
write_length(Vec, _D, Acc, _Max) when size(Vec) == 0 -> Acc + 9;
204
write_length(Vec, D, Acc, Max) when size(Vec) >= 0 ->
205
write_length_list(vector:to_list(Vec), D, Acc, Max);
206
write_length(Term, _D, Acc, _Max) ->
309
write_length(Term, _D, Acc, _Max, _RF) ->
207
310
Acc + length(io_lib:write(Term)).
209
write_length_list(_, _, Acc, Max) when Acc > Max -> Acc;
210
write_length_list([], _, Acc, _) -> Acc + 1; %]
211
write_length_list(_, 1, Acc, _) -> Acc + 5; %|...]
212
write_length_list([E|Es], D, Acc, Max) ->
312
write_length_list(_, _, Acc, Max, _RF) when Acc > Max -> Acc;
313
write_length_list([], _, Acc, _, _RF) -> Acc + 1; %]
314
write_length_list(_, 1, Acc, _, _RF) -> Acc + 5; %|...]
315
write_length_list([E|Es], D, Acc, Max, RF) ->
213
316
write_length_list(Es,
215
write_length(E, D - 1, Acc + 1, Max),
217
write_length_list(E, D, Acc, Max) ->
218
write_length(E, D - 1, Acc + 2, Max). %| ]
220
indent(N) when integer(N), N > 0 ->
318
write_length(E, D - 1, Acc + 1, Max, RF),
321
write_length_list(E, D, Acc, Max, RF) ->
322
write_length(E, D - 1, Acc + 2, Max, RF). %| ]
324
write_length_fields(_, _D, Acc, Max, _, _RF, _Sl) when Acc > Max -> Acc;
325
write_length_fields([], _D, Acc, _Max, [], _RF, _Sl) -> Acc + 1; %}
326
write_length_fields(_, 1, Acc, _Max, _, _RF, Sl) -> Acc + Sl + 4; %|...}
327
write_length_fields([Def|Defs], D, Acc, Max, [E|Es], RF, Sl) ->
328
Acc1 = write_length_field(Def, D - 1, Acc + Sl, Max, E, RF),
329
write_length_fields(Defs, D-1, Acc1, Max, Es, RF, 1).
331
write_length_field(_Def, 0, Acc, _Max, _E, _RF) ->
333
write_length_field(Def, D, Acc, Max, E, RF) ->
334
write_length(E, D, Acc + length(io_lib:write_atom(Def)) + 3, Max, RF).
336
indent(N) when is_integer(N), N > 0 ->
222
indent(N) when integer(N) ->
338
indent(N) when is_integer(N) ->
223
339
[[]]. % This is an ugly kludge not crash for column less than 1
225
341
indent(0, Ind) ->
227
indent(N, [[]]) when integer(N), N > 0 ->
343
indent(N, [[]]) when is_integer(N), N > 0 ->
228
344
indent(N-1, []); % Same kludge as above
229
345
indent(1, Ind) -> % Optimization of common case
231
347
indent(4, Ind) -> % Optimization of common case
234
indent(N, Ind) when integer(N), N > 0 ->
350
indent(N, Ind) when is_integer(N), N > 0 ->
235
351
[chars($\s, N)|Ind].
237
353
%% A deep version of string:chars/2