~ubuntu-branches/debian/squeeze/erlang/squeeze

« back to all changes in this revision

Viewing changes to lib/stdlib/src/io_lib_pretty.erl

  • Committer: Bazaar Package Importer
  • Author(s): Erlang Packagers, Sergei Golovan
  • Date: 2006-12-03 17:07:44 UTC
  • mfrom: (2.1.11 feisty)
  • Revision ID: james.westby@ubuntu.com-20061203170744-rghjwupacqlzs6kv
Tags: 1:11.b.2-4
[ Sergei Golovan ]
Fixed erlang-base and erlang-base-hipe prerm scripts.

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
%% correctly. We also want to be sure that the length calcualtions are
26
26
%% the same.
27
27
 
28
 
-export([print/1,print/4]).
 
28
-export([print/1,print/2,print/3,print/4,print/5]).
29
29
 
30
30
%% print(Term) -> [Chars]
31
31
%% print(Term, Column, LineLength, Depth) -> [Chars]
34
34
print(Term) ->
35
35
    print(Term, 1, 80, -1).
36
36
 
37
 
print(List, Col, Ll, D) ->
38
 
    print(List, Col, Ll, D, indent(Col)).
39
 
 
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).
 
43
 
 
44
print(Term, Depth, RecDefFun) ->
 
45
    print(Term, 1, 80, Depth, RecDefFun).
 
46
 
 
47
print(Term, Col, Ll, D) ->
 
48
    print(Term, Col, Ll, D, no_fun).
 
49
 
 
50
print(Term, Col, Ll, D, RecDefFun) ->
 
51
    print(Term, Col, Ll, D, indent(Col), RecDefFun).
 
52
 
 
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
45
58
        true ->
46
 
            io_lib:write_string(List, $");
 
59
            io_lib:write_string(List, $");      %"
47
60
        false ->
48
 
            Len = write_length(List, D, 0, Ll - Col),
 
61
            Len = write_length(List, D, 0, Ll - Col, RF),
49
62
            if
50
 
                D == 1 -> "[...]";
 
63
                D =:= 1 -> "[...]";
51
64
                Len + Col < Ll ->
52
 
                    write(List, D);
 
65
                    write(List, D, RF);
53
66
                true ->
54
67
                    [$[,
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)],
57
70
                     $]]
58
71
            end
59
72
    end;
60
 
print(Fun, _Col, _Ll, _D, _Ind) when function(Fun) ->
 
73
print(Fun, _Col, _Ll, _D, _Ind, _RF) when is_function(Fun) ->
61
74
    io_lib:write(Fun);
62
 
print(Tuple, Col, Ll, D, Ind) when tuple(Tuple) ->
63
 
    Len = write_length(Tuple, D, 0, Ll - Col),
64
 
    if
65
 
        D == 1 -> "{...}";
 
75
print(Rec, Col, Ll, D, Ind, RF) when is_atom(element(1, Rec)), 
 
76
                                     is_function(RF) ->
 
77
    case RF(element(1, Rec), size(Rec) - 1) of
 
78
       no ->
 
79
            print_tuple(Rec, Col, Ll, D, Ind, RF);
 
80
       RDefs ->
 
81
            print_record(Rec, RDefs, Col, Ll, D, Ind, RF)
 
82
    end;
 
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).
 
88
 
 
89
print_record(Rec, RDefs, Col, Ll, D, Ind, RF) ->
 
90
    Len = write_length(Rec, D, 0, Ll - Col, RF),
 
91
    if
 
92
        Len + Col < Ll ->
 
93
            write(Rec, D, RF);
 
94
        D =:= 1 -> "{...}";
 
95
        true ->
 
96
            Name = io_lib:write_atom(element(1, Rec)),
 
97
            Nlen = length(Name),
 
98
            Nind = Nlen + 2,
 
99
            Ncol = Col + Nind,
 
100
            {DCol,S} = if
 
101
                           Ncol >= Ll div 2, Nlen > 2 ->
 
102
                               {4,[$\n,indent(4, Ind)]};
 
103
                           true ->
 
104
                               {Nind,[]}
 
105
                       end,
 
106
            [$#,Name,${,
 
107
             print_fields(RDefs, tl(tuple_to_list(Rec)), 
 
108
                          Col + DCol, Ll, D - 2, indent(DCol, Ind), RF, S),
 
109
             $}]
 
110
    end.
 
111
 
 
112
print_fields([], [], _Col, _Ll, _D, _Ind, _RF, _S) ->
 
113
    "";
 
114
print_fields(_Defs, _Es, _Col, _Ll, 1, _Ind, _RF, _S) ->
 
115
    "|...";
 
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])].
 
119
 
 
120
print_field(_Def, _E, _Col, _Ll, 0, _Ind, _RF) ->
 
121
    "...";
 
122
print_field(Def, E, Col, Ll, D, Ind, RF) ->
 
123
    [io_lib:write_atom(Def)," = ",print(E, Col, Ll, D, Ind, RF)].
 
124
 
 
125
print_tuple(Tuple, Col, Ll, D, Ind, RF) ->
 
126
    Len = write_length(Tuple, D, 0, Ll - Col, RF),
 
127
    if
 
128
        D =:= 1 -> "{...}";
66
129
        Len + Col < Ll ->
67
 
            write(Tuple, D);
68
 
        atom(element(1, Tuple)), size(Tuple) > 1 ->
69
 
            print_tag_tuple(Tuple, Col, Ll, D, Ind);
 
130
            write(Tuple, D, RF);
 
131
        is_atom(element(1, Tuple)), size(Tuple) > 1 ->
 
132
            print_tag_tuple(Tuple, Col, Ll, D, Ind, RF);
70
133
        true ->
71
134
            [${,
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)],
75
138
             $}]
76
 
    end;
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 ->
80
 
    "#Vector<>";
81
 
print(Vec, Col, Ll, D, Ind) when size(Vec) >= 0 ->
82
 
    Len = write_length(Vec, D, 0, Ll - Col),
83
 
    if
84
 
        D == 1 -> "#Vector<...>";
85
 
        Len + Col < Ll ->
86
 
            write(Vec, D);
87
 
        true ->
88
 
            ["#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))],
92
 
             $>]
93
 
    end;
94
 
print(Term, _Col, _Ll, D, _Ind) -> io_lib:write(Term, D).
 
139
    end.
95
140
 
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.
100
145
 
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),
104
149
    Tind = Tlen + 2,
107
152
        Tcol >= Ll div 2, Tlen > 2 ->
108
153
            [${,Tag,
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),
111
156
             $}];
112
157
        true ->
113
158
            [${,Tag,$,,
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)],
117
162
             $}]
118
163
    end.
119
164
 
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.
122
167
 
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)].
130
175
 
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
133
178
%%  atomic terms.
134
179
 
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).
 
181
 
 
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
140
187
        true ->
141
 
            io_lib:write_string(List, $");
 
188
            io_lib:write_string(List, $");      %"
142
189
        false ->
143
190
            if
144
 
                D == 1 -> "[...]";
 
191
                D =:= 1 -> "[...]";
145
192
                true ->
146
193
                    [$[,
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)],
148
195
                     $]]
149
196
            end
150
197
    end;
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
 
202
        no ->
 
203
            write_tuple(R, D, RF);
 
204
        RDefs ->
 
205
            [$#, io_lib:write_atom(element(1, R)), ${, 
 
206
             write_fields(RDefs, D - 1, tl(tuple_to_list(R)), RF, []),
 
207
             $}]
 
208
    end;
 
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).
 
214
 
 
215
write_binary(Binary, _D) when size(Binary) =:= 0 ->
 
216
    "<<>>";
 
217
write_binary(Binary, D) ->
 
218
    PLen = if
 
219
               D < 0 -> size(Binary);
 
220
               true -> min(size(Binary), D-1)
 
221
           end,
 
222
    case is_printable(Binary, PLen) of
 
223
        true when PLen =:= 0 ->
 
224
            "<<...>>";
 
225
        true when size(Binary) =< PLen ->
 
226
            List = binary_to_list(Binary),
 
227
            [$<, $<, io_lib:write_string(List, $"), $>, $>];
 
228
        true ->
 
229
            Prefix = binary_to_list(Binary, 1, PLen),
 
230
            [$<,$<,io_lib:write_string(Prefix, $"), "...>>"];
 
231
        false ->
 
232
            io_lib:write(Binary, D)
 
233
    end.
 
234
 
 
235
write_tuple(T, D, RF) ->
153
236
    if
154
 
        D == 1 -> "{...}";
 
237
        D =:= 1 -> "{...}";
155
238
        true ->
156
239
            [${,
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)],
158
242
             $}]
159
 
    end;
160
 
write(Bin, D) when binary(Bin) -> io_lib:write(Bin, D);
161
 
write(T, D) when size(T) >= 0 ->
162
 
    if
163
 
        D == 1 -> "#Vector<...>";
164
 
        true ->
165
 
            ["#Vector<",
166
 
             [write(vector:get(1, T), D-1)|write_tail(tl(vector:to_list(T)), D-1)],
167
 
             $>]
168
 
    end;
169
 
write(Term, D) -> io_lib:write(Term, D).
 
243
    end.
170
244
 
171
 
write_tail([], _D) -> "";
172
 
write_tail(_, 1) -> "|...";
173
 
write_tail([E|Es], D) ->
174
 
    [$,,write(E, D - 1)|write_tail(Es, D - 1)];
175
 
write_tail(E, D) ->
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)].
177
251
     
178
 
%% write_length(Term, Depth, Accumulator, MaxLength) -> integer()
 
252
write_fields([], _D, [], _RF, _S) ->
 
253
    "";
 
254
write_fields(_, 1, _, _RF, _S) ->
 
255
    "|...";
 
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, $,)].
 
258
 
 
259
write_field(_Def, 0, _E, _RF) ->
 
260
    "...";
 
261
write_field(Def, D, E, RF) ->
 
262
    [io_lib:write_atom(Def)," = ",write(E, D, RF)].
 
263
 
 
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.
181
267
 
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
188
274
        true ->
189
 
            Acc + length(io_lib:write_string(List, $"));
 
275
            Acc + length(io_lib:write_string(List, $"));        %"
190
276
        false ->
191
 
            write_length_list(List, D, Acc, Max)
 
277
            write_length_list(List, D, Acc, Max, RF)
192
278
    end;
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)), 
 
282
                                      is_function(RF) ->
 
283
    case RF(element(1, R), size(R) - 1 ) of
 
284
        no -> 
 
285
            write_length_list(tuple_to_list(R), D, Acc, Max, RF);
 
286
        RDefs ->
 
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)
 
289
    end;
 
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) ->
 
293
    PLen = if
 
294
               D < 0 -> min(size(Bin), Max);
 
295
               true -> min(size(Bin), D - 1)
 
296
           end,
 
297
    case is_printable(Bin, PLen) of
 
298
        true when PLen =:= 0 ->
 
299
            Acc + 7;
200
300
        true ->
201
 
            Acc + 4 + 4*(D+1)
 
301
            List = binary_to_list(Bin, 1, PLen),
 
302
            Acc + 4 + length(io_lib:write_string(List, $"));    %"
 
303
        false when D < 0;                % Print all
 
304
                  size(Bin) =< D ->  
 
305
            Acc + 4 + 4*size(Bin);      % Overestimation
 
306
        false ->
 
307
            Acc + 4 + 4*D
202
308
    end;
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)).
208
311
 
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,
214
317
                      D - 1,
215
 
                      write_length(E, D - 1, Acc + 1, Max),
216
 
                      Max);
217
 
write_length_list(E, D, Acc, Max) ->
218
 
    write_length(E, D - 1, Acc + 2, Max).       %| ]
219
 
 
220
 
indent(N) when integer(N), N > 0 ->
 
318
                      write_length(E, D - 1, Acc + 1, Max, RF),
 
319
                      Max,
 
320
                      RF);
 
321
write_length_list(E, D, Acc, Max, RF) ->
 
322
    write_length(E, D - 1, Acc + 2, Max, RF).   %| ]
 
323
 
 
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).
 
330
 
 
331
write_length_field(_Def, 0, Acc, _Max, _E, _RF) ->
 
332
    Acc + 3; %...
 
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).
 
335
 
 
336
indent(N) when is_integer(N), N > 0 ->
221
337
    chars($\s, N-1);
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
224
340
 
225
341
indent(0, Ind) ->
226
342
    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
230
346
    [$\s|Ind];
231
347
indent(4, Ind) -> % Optimization of common case
232
348
    S2 = [$\s,$\s],
233
349
    [S2,S2|Ind];
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].
236
352
 
237
353
%% A deep version of string:chars/2
243
359
    [C,C];
244
360
chars(C, 3) ->
245
361
    [C,C,C];
246
 
chars(C, N) when (N band 1) == 0 ->
 
362
chars(C, N) when (N band 1) =:= 0 ->
247
363
    S = chars(C, N bsr 1),
248
364
    [S|S];
249
365
chars(C, N) ->
250
366
    S = chars(C, N bsr 1),
251
367
    [C,S|S].
 
368
 
 
369
is_printable(Bin, Len) when is_integer(Len) ->
 
370
    is_printable(Bin, 1, min(Len, size(Bin))).
 
371
 
 
372
is_printable(_Bin, _Start, 0) ->
 
373
    true;
 
374
is_printable(Bin, Start, Len) ->
 
375
    N = min(10000, Len),
 
376
    case io_lib:printable_list(binary_to_list(Bin, Start, Start+N-1)) of
 
377
        true -> 
 
378
            is_printable(Bin, Start+N, Len-N);
 
379
        false ->
 
380
            false
 
381
    end.
 
382
 
 
383
min(X, Y) when X =< Y -> X;
 
384
min(_X, Y) -> Y.