1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 1996-2019. 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-module(io_lib_format).
21
22%% Formatting functions of io library.
23
24-export([fwrite/2,fwrite/3,fwrite_g/1,indentation/2,scan/2,unscan/1,
25         build/1, build/2]).
26
27%%  Format the arguments in Args after string Format. Just generate
28%%  an error if there is an error in the arguments.
29%%
30%%  To do the printing command correctly we need to calculate the
31%%  current indentation for everything before it. This may be very
32%%  expensive, especially when it is not needed, so we first determine
33%%  if, and for how long, we need to calculate the indentations. We do
34%%  this by first collecting all the control sequences and
35%%  corresponding arguments, then counting the print sequences and
36%%  then building the output.  This method has some drawbacks, it does
37%%  two passes over the format string and creates more temporary data,
38%%  and it also splits the handling of the control characters into two
39%%  parts.
40
41-spec fwrite(Format, Data) -> io_lib:chars() when
42      Format :: io:format(),
43      Data :: [term()].
44
45fwrite(Format, Args) ->
46    build(scan(Format, Args)).
47
48-spec fwrite(Format, Data, Options) -> io_lib:chars() when
49      Format :: io:format(),
50      Data :: [term()],
51      Options :: [Option],
52      Option :: {'chars_limit', CharsLimit},
53      CharsLimit :: io_lib:chars_limit().
54
55fwrite(Format, Args, Options) ->
56    build(scan(Format, Args), Options).
57
58%% Build the output text for a pre-parsed format list.
59
60-spec build(FormatList) -> io_lib:chars() when
61      FormatList :: [char() | io_lib:format_spec()].
62
63build(Cs) ->
64    build(Cs, []).
65
66-spec build(FormatList, Options) -> io_lib:chars() when
67      FormatList :: [char() | io_lib:format_spec()],
68      Options :: [Option],
69      Option :: {'chars_limit', CharsLimit},
70      CharsLimit :: io_lib:chars_limit().
71
72build(Cs, Options) ->
73    CharsLimit = get_option(chars_limit, Options, -1),
74    Res1 = build_small(Cs),
75    {P, S, W, Other} = count_small(Res1),
76    case P + S + W of
77        0 ->
78            Res1;
79        NumOfLimited ->
80            RemainingChars = sub(CharsLimit, Other),
81            build_limited(Res1, P, NumOfLimited, RemainingChars, 0)
82    end.
83
84%% Parse all control sequences in the format string.
85
86-spec scan(Format, Data) -> FormatList when
87      Format :: io:format(),
88      Data :: [term()],
89      FormatList :: [char() | io_lib:format_spec()].
90
91scan(Format, Args) when is_atom(Format) ->
92    scan(atom_to_list(Format), Args);
93scan(Format, Args) when is_binary(Format) ->
94    scan(binary_to_list(Format), Args);
95scan(Format, Args) ->
96    collect(Format, Args).
97
98%% Revert a pre-parsed format list to a plain character list and a
99%% list of arguments.
100
101-spec unscan(FormatList) -> {Format, Data} when
102      FormatList :: [char() | io_lib:format_spec()],
103      Format :: io:format(),
104      Data :: [term()].
105
106unscan(Cs) ->
107    {print(Cs), args(Cs)}.
108
109args([#{args := As} | Cs]) ->
110    As ++ args(Cs);
111args([_C | Cs]) ->
112    args(Cs);
113args([]) ->
114    [].
115
116print([#{control_char := C, width := F, adjust := Ad, precision := P,
117         pad_char := Pad, encoding := Encoding, strings := Strings} | Cs]) ->
118    print(C, F, Ad, P, Pad, Encoding, Strings) ++ print(Cs);
119print([C | Cs]) ->
120    [C | print(Cs)];
121print([]) ->
122    [].
123
124print(C, F, Ad, P, Pad, Encoding, Strings) ->
125    [$~] ++ print_field_width(F, Ad) ++ print_precision(P, Pad) ++
126        print_pad_char(Pad) ++ print_encoding(Encoding) ++
127        print_strings(Strings) ++ [C].
128
129print_field_width(none, _Ad) -> "";
130print_field_width(F, left) -> integer_to_list(-F);
131print_field_width(F, right) -> integer_to_list(F).
132
133print_precision(none, $\s) -> "";
134print_precision(none, _Pad) -> ".";  % pad must be second dot
135print_precision(P, _Pad) -> [$. | integer_to_list(P)].
136
137print_pad_char($\s) -> ""; % default, no need to make explicit
138print_pad_char(Pad) -> [$., Pad].
139
140print_encoding(unicode) -> "t";
141print_encoding(latin1) -> "".
142
143print_strings(false) -> "l";
144print_strings(true) -> "".
145
146collect([$~|Fmt0], Args0) ->
147    {C,Fmt1,Args1} = collect_cseq(Fmt0, Args0),
148    [C|collect(Fmt1, Args1)];
149collect([C|Fmt], Args) ->
150    [C|collect(Fmt, Args)];
151collect([], []) -> [].
152
153collect_cseq(Fmt0, Args0) ->
154    {F,Ad,Fmt1,Args1} = field_width(Fmt0, Args0),
155    {P,Fmt2,Args2} = precision(Fmt1, Args1),
156    {Pad,Fmt3,Args3} = pad_char(Fmt2, Args2),
157    Spec0 = #{width => F,
158              adjust => Ad,
159              precision => P,
160              pad_char => Pad,
161              encoding => latin1,
162              strings => true},
163    {Spec1,Fmt4} = modifiers(Fmt3, Spec0),
164    {C,As,Fmt5,Args4} = collect_cc(Fmt4, Args3),
165    Spec2 = Spec1#{control_char => C, args => As},
166    {Spec2,Fmt5,Args4}.
167
168modifiers([$t|Fmt], Spec) ->
169    modifiers(Fmt, Spec#{encoding => unicode});
170modifiers([$l|Fmt], Spec) ->
171    modifiers(Fmt, Spec#{strings => false});
172modifiers(Fmt, Spec) ->
173    {Spec, Fmt}.
174
175field_width([$-|Fmt0], Args0) ->
176    {F,Fmt,Args} = field_value(Fmt0, Args0),
177    field_width(-F, Fmt, Args);
178field_width(Fmt0, Args0) ->
179    {F,Fmt,Args} = field_value(Fmt0, Args0),
180    field_width(F, Fmt, Args).
181
182field_width(F, Fmt, Args) when F < 0 ->
183    {-F,left,Fmt,Args};
184field_width(F, Fmt, Args) when F >= 0 ->
185    {F,right,Fmt,Args}.
186
187precision([$.|Fmt], Args) ->
188    field_value(Fmt, Args);
189precision(Fmt, Args) ->
190    {none,Fmt,Args}.
191
192field_value([$*|Fmt], [A|Args]) when is_integer(A) ->
193    {A,Fmt,Args};
194field_value([C|Fmt], Args) when is_integer(C), C >= $0, C =< $9 ->
195    field_value([C|Fmt], Args, 0);
196field_value(Fmt, Args) ->
197    {none,Fmt,Args}.
198
199field_value([C|Fmt], Args, F) when is_integer(C), C >= $0, C =< $9 ->
200    field_value(Fmt, Args, 10*F + (C - $0));
201field_value(Fmt, Args, F) ->		%Default case
202    {F,Fmt,Args}.
203
204pad_char([$.,$*|Fmt], [Pad|Args]) -> {Pad,Fmt,Args};
205pad_char([$.,Pad|Fmt], Args) -> {Pad,Fmt,Args};
206pad_char(Fmt, Args) -> {$\s,Fmt,Args}.
207
208%% collect_cc([FormatChar], [Argument]) ->
209%%	{Control,[ControlArg],[FormatChar],[Arg]}.
210%%  Here we collect the argments for each control character.
211%%  Be explicit to cause failure early.
212
213collect_cc([$w|Fmt], [A|Args]) -> {$w,[A],Fmt,Args};
214collect_cc([$p|Fmt], [A|Args]) -> {$p,[A],Fmt,Args};
215collect_cc([$W|Fmt], [A,Depth|Args]) -> {$W,[A,Depth],Fmt,Args};
216collect_cc([$P|Fmt], [A,Depth|Args]) -> {$P,[A,Depth],Fmt,Args};
217collect_cc([$s|Fmt], [A|Args]) -> {$s,[A],Fmt,Args};
218collect_cc([$e|Fmt], [A|Args]) -> {$e,[A],Fmt,Args};
219collect_cc([$f|Fmt], [A|Args]) -> {$f,[A],Fmt,Args};
220collect_cc([$g|Fmt], [A|Args]) -> {$g,[A],Fmt,Args};
221collect_cc([$b|Fmt], [A|Args]) -> {$b,[A],Fmt,Args};
222collect_cc([$B|Fmt], [A|Args]) -> {$B,[A],Fmt,Args};
223collect_cc([$x|Fmt], [A,Prefix|Args]) -> {$x,[A,Prefix],Fmt,Args};
224collect_cc([$X|Fmt], [A,Prefix|Args]) -> {$X,[A,Prefix],Fmt,Args};
225collect_cc([$+|Fmt], [A|Args]) -> {$+,[A],Fmt,Args};
226collect_cc([$#|Fmt], [A|Args]) -> {$#,[A],Fmt,Args};
227collect_cc([$c|Fmt], [A|Args]) -> {$c,[A],Fmt,Args};
228collect_cc([$~|Fmt], Args) when is_list(Args) -> {$~,[],Fmt,Args};
229collect_cc([$n|Fmt], Args) when is_list(Args) -> {$n,[],Fmt,Args};
230collect_cc([$i|Fmt], [A|Args]) -> {$i,[A],Fmt,Args}.
231
232%% count_small([ControlC]) -> Count.
233%%  Count the number of big (pPwWsS) print requests and
234%%  number of characters of other print (small) requests.
235
236count_small(Cs) ->
237    count_small(Cs, #{p => 0, s => 0, w => 0, other => 0}).
238
239count_small([#{control_char := $p}|Cs], #{p := P} = Cnts) ->
240    count_small(Cs, Cnts#{p := P + 1});
241count_small([#{control_char := $P}|Cs], #{p := P} = Cnts) ->
242    count_small(Cs, Cnts#{p := P + 1});
243count_small([#{control_char := $w}|Cs], #{w := W} = Cnts) ->
244    count_small(Cs, Cnts#{w := W + 1});
245count_small([#{control_char := $W}|Cs], #{w := W} = Cnts) ->
246    count_small(Cs, Cnts#{w := W + 1});
247count_small([#{control_char := $s}|Cs], #{w := W} = Cnts) ->
248    count_small(Cs, Cnts#{w := W + 1});
249count_small([S|Cs], #{other := Other} = Cnts) when is_list(S);
250                                                   is_binary(S) ->
251    count_small(Cs, Cnts#{other := Other + io_lib:chars_length(S)});
252count_small([C|Cs], #{other := Other} = Cnts) when is_integer(C) ->
253    count_small(Cs, Cnts#{other := Other + 1});
254count_small([], #{p := P, s := S, w := W, other := Other}) ->
255    {P, S, W, Other}.
256
257%% build_small([Control]) -> io_lib:chars().
258%%  Interpret the control structures, but only the small ones.
259%%  The big ones are saved for later.
260%% build_limited([Control], NumberOfPps, NumberOfLimited,
261%%               CharsLimit, Indentation)
262%%  Interpret the control structures. Count the number of print
263%%  remaining and only calculate indentation when necessary. Must also
264%%  be smart when calculating indentation for characters in format.
265
266build_small([#{control_char := C, args := As, width := F, adjust := Ad,
267               precision := P, pad_char := Pad, encoding := Enc}=CC | Cs]) ->
268    case control_small(C, As, F, Ad, P, Pad, Enc) of
269        not_small -> [CC | build_small(Cs)];
270        S -> lists:flatten(S) ++ build_small(Cs)
271    end;
272build_small([C|Cs]) -> [C|build_small(Cs)];
273build_small([]) -> [].
274
275build_limited([#{control_char := C, args := As, width := F, adjust := Ad,
276                 precision := P, pad_char := Pad, encoding := Enc,
277                 strings := Str} | Cs], NumOfPs0, Count0, MaxLen0, I) ->
278    MaxChars = if
279                   MaxLen0 < 0 -> MaxLen0;
280                   true -> MaxLen0 div Count0
281               end,
282    S = control_limited(C, As, F, Ad, P, Pad, Enc, Str, MaxChars, I),
283    NumOfPs = decr_pc(C, NumOfPs0),
284    Count = Count0 - 1,
285    MaxLen = if
286                 MaxLen0 < 0 -> % optimization
287                     MaxLen0;
288                 true ->
289                     Len = io_lib:chars_length(S),
290                     sub(MaxLen0, Len)
291             end,
292    if
293	NumOfPs > 0 -> [S|build_limited(Cs, NumOfPs, Count,
294                                        MaxLen, indentation(S, I))];
295	true -> [S|build_limited(Cs, NumOfPs, Count, MaxLen, I)]
296    end;
297build_limited([$\n|Cs], NumOfPs, Count, MaxLen, _I) ->
298    [$\n|build_limited(Cs, NumOfPs, Count, MaxLen, 0)];
299build_limited([$\t|Cs], NumOfPs, Count, MaxLen, I) ->
300    [$\t|build_limited(Cs, NumOfPs, Count, MaxLen, ((I + 8) div 8) * 8)];
301build_limited([C|Cs], NumOfPs, Count, MaxLen, I) ->
302    [C|build_limited(Cs, NumOfPs, Count, MaxLen, I+1)];
303build_limited([], _, _, _, _) -> [].
304
305decr_pc($p, Pc) -> Pc - 1;
306decr_pc($P, Pc) -> Pc - 1;
307decr_pc(_, Pc) -> Pc.
308
309%%  Calculate the indentation of the end of a string given its start
310%%  indentation. We assume tabs at 8 cols.
311
312-spec indentation(String, StartIndent) -> integer() when
313      String :: io_lib:chars(),
314      StartIndent :: integer().
315
316indentation([$\n|Cs], _I) -> indentation(Cs, 0);
317indentation([$\t|Cs], I) -> indentation(Cs, ((I + 8) div 8) * 8);
318indentation([C|Cs], I) when is_integer(C) ->
319    indentation(Cs, I+1);
320indentation([C|Cs], I) ->
321    indentation(Cs, indentation(C, I));
322indentation([], I) -> I.
323
324%% control_small(FormatChar, [Argument], FieldWidth, Adjust, Precision,
325%%               PadChar, Encoding) -> String
326%% control_limited(FormatChar, [Argument], FieldWidth, Adjust, Precision,
327%%                 PadChar, Encoding, StringP, ChrsLim, Indentation) -> String
328%%  These are the dispatch functions for the various formatting controls.
329
330control_small($s, [A], F, Adj, P, Pad, latin1=Enc) when is_atom(A) ->
331    L = iolist_to_chars(atom_to_list(A)),
332    string(L, F, Adj, P, Pad, Enc);
333control_small($s, [A], F, Adj, P, Pad, unicode=Enc) when is_atom(A) ->
334    string(atom_to_list(A), F, Adj, P, Pad, Enc);
335control_small($e, [A], F, Adj, P, Pad, _Enc) when is_float(A) ->
336    fwrite_e(A, F, Adj, P, Pad);
337control_small($f, [A], F, Adj, P, Pad, _Enc) when is_float(A) ->
338    fwrite_f(A, F, Adj, P, Pad);
339control_small($g, [A], F, Adj, P, Pad, _Enc) when is_float(A) ->
340    fwrite_g(A, F, Adj, P, Pad);
341control_small($b, [A], F, Adj, P, Pad, _Enc) when is_integer(A) ->
342    unprefixed_integer(A, F, Adj, base(P), Pad, true);
343control_small($B, [A], F, Adj, P, Pad, _Enc) when is_integer(A) ->
344    unprefixed_integer(A, F, Adj, base(P), Pad, false);
345control_small($x, [A,Prefix], F, Adj, P, Pad, _Enc) when is_integer(A),
346                                                         is_atom(Prefix) ->
347    prefixed_integer(A, F, Adj, base(P), Pad, atom_to_list(Prefix), true);
348control_small($x, [A,Prefix], F, Adj, P, Pad, _Enc) when is_integer(A) ->
349    true = io_lib:deep_char_list(Prefix), %Check if Prefix a character list
350    prefixed_integer(A, F, Adj, base(P), Pad, Prefix, true);
351control_small($X, [A,Prefix], F, Adj, P, Pad, _Enc) when is_integer(A),
352                                                         is_atom(Prefix) ->
353    prefixed_integer(A, F, Adj, base(P), Pad, atom_to_list(Prefix), false);
354control_small($X, [A,Prefix], F, Adj, P, Pad, _Enc) when is_integer(A) ->
355    true = io_lib:deep_char_list(Prefix), %Check if Prefix a character list
356    prefixed_integer(A, F, Adj, base(P), Pad, Prefix, false);
357control_small($+, [A], F, Adj, P, Pad, _Enc) when is_integer(A) ->
358    Base = base(P),
359    Prefix = [integer_to_list(Base), $#],
360    prefixed_integer(A, F, Adj, Base, Pad, Prefix, true);
361control_small($#, [A], F, Adj, P, Pad, _Enc) when is_integer(A) ->
362    Base = base(P),
363    Prefix = [integer_to_list(Base), $#],
364    prefixed_integer(A, F, Adj, Base, Pad, Prefix, false);
365control_small($c, [A], F, Adj, P, Pad, unicode) when is_integer(A) ->
366    char(A, F, Adj, P, Pad);
367control_small($c, [A], F, Adj, P, Pad, _Enc) when is_integer(A) ->
368    char(A band 255, F, Adj, P, Pad);
369control_small($~, [], F, Adj, P, Pad, _Enc) -> char($~, F, Adj, P, Pad);
370control_small($n, [], F, Adj, P, Pad, _Enc) -> newline(F, Adj, P, Pad);
371control_small($i, [_A], _F, _Adj, _P, _Pad, _Enc) -> [];
372control_small(_C, _As, _F, _Adj, _P, _Pad, _Enc) -> not_small.
373
374control_limited($s, [L0], F, Adj, P, Pad, latin1=Enc, _Str, CL, _I) ->
375    L = iolist_to_chars(L0, F, CL),
376    string(L, limit_field(F, CL), Adj, P, Pad, Enc);
377control_limited($s, [L0], F, Adj, P, Pad, unicode=Enc, _Str, CL, _I) ->
378    L = cdata_to_chars(L0, F, CL),
379    uniconv(string(L, limit_field(F, CL), Adj, P, Pad, Enc));
380control_limited($w, [A], F, Adj, P, Pad, Enc, _Str, CL, _I) ->
381    Chars = io_lib:write(A, [{depth, -1}, {encoding, Enc}, {chars_limit, CL}]),
382    term(Chars, F, Adj, P, Pad);
383control_limited($p, [A], F, Adj, P, Pad, Enc, Str, CL, I) ->
384    print(A, -1, F, Adj, P, Pad, Enc, Str, CL, I);
385control_limited($W, [A,Depth], F, Adj, P, Pad, Enc, _Str, CL, _I)
386           when is_integer(Depth) ->
387    Chars = io_lib:write(A, [{depth, Depth}, {encoding, Enc}, {chars_limit, CL}]),
388    term(Chars, F, Adj, P, Pad);
389control_limited($P, [A,Depth], F, Adj, P, Pad, Enc, Str, CL, I)
390           when is_integer(Depth) ->
391    print(A, Depth, F, Adj, P, Pad, Enc, Str, CL, I).
392
393-ifdef(UNICODE_AS_BINARIES).
394uniconv(C) ->
395    unicode:characters_to_binary(C,unicode).
396-else.
397uniconv(C) ->
398    C.
399-endif.
400%% Default integer base
401base(none) ->
402    10;
403base(B) when is_integer(B) ->
404    B.
405
406%% term(TermList, Field, Adjust, Precision, PadChar)
407%%  Output the characters in a term.
408%%  Adjust the characters within the field if length less than Max padding
409%%  with PadChar.
410
411term(T, none, _Adj, none, _Pad) -> T;
412term(T, none, Adj, P, Pad) -> term(T, P, Adj, P, Pad);
413term(T, F, Adj, P0, Pad) ->
414    L = io_lib:chars_length(T),
415    P = erlang:min(L, case P0 of none -> F; _ -> min(P0, F) end),
416    if
417	L > P ->
418	    adjust(chars($*, P), chars(Pad, F-P), Adj);
419	F >= P ->
420	    adjust(T, chars(Pad, F-L), Adj)
421    end.
422
423%% print(Term, Depth, Field, Adjust, Precision, PadChar, Encoding,
424%%       Indentation)
425%% Print a term. Field width sets maximum line length, Precision sets
426%% initial indentation.
427
428print(T, D, none, Adj, P, Pad, E, Str, ChLim, I) ->
429    print(T, D, 80, Adj, P, Pad, E, Str, ChLim, I);
430print(T, D, F, Adj, none, Pad, E, Str, ChLim, I) ->
431    print(T, D, F, Adj, I+1, Pad, E, Str, ChLim, I);
432print(T, D, F, right, P, _Pad, Enc, Str, ChLim, _I) ->
433    Options = [{chars_limit, ChLim},
434               {column, P},
435               {line_length, F},
436               {depth, D},
437               {encoding, Enc},
438               {strings, Str}],
439    io_lib_pretty:print(T, Options).
440
441%% fwrite_e(Float, Field, Adjust, Precision, PadChar)
442
443fwrite_e(Fl, none, Adj, none, Pad) ->		%Default values
444    fwrite_e(Fl, none, Adj, 6, Pad);
445fwrite_e(Fl, none, _Adj, P, _Pad) when P >= 2 ->
446    float_e(Fl, float_data(Fl), P);
447fwrite_e(Fl, F, Adj, none, Pad) ->
448    fwrite_e(Fl, F, Adj, 6, Pad);
449fwrite_e(Fl, F, Adj, P, Pad) when P >= 2 ->
450    term(float_e(Fl, float_data(Fl), P), F, Adj, F, Pad).
451
452float_e(Fl, Fd, P) when Fl < 0.0 ->		%Negative numbers
453    [$-|float_e(-Fl, Fd, P)];
454float_e(_Fl, {Ds,E}, P) ->
455    case float_man(Ds, 1, P-1) of
456	{[$0|Fs],true} -> [[$1|Fs]|float_exp(E)];
457	{Fs,false} -> [Fs|float_exp(E-1)]
458    end.
459
460%% float_man([Digit], Icount, Dcount) -> {[Char],CarryFlag}.
461%%  Generate the characters in the mantissa from the digits with Icount
462%%  characters before the '.' and Dcount decimals. Handle carry and let
463%%  caller decide what to do at top.
464
465float_man(Ds, 0, Dc) ->
466    {Cs,C} = float_man(Ds, Dc),
467    {[$.|Cs],C};
468float_man([D|Ds], I, Dc) ->
469    case float_man(Ds, I-1, Dc) of
470	{Cs,true} when D =:= $9 -> {[$0|Cs],true};
471	{Cs,true} -> {[D+1|Cs],false};
472	{Cs,false} -> {[D|Cs],false}
473    end;
474float_man([], I, Dc) ->				%Pad with 0's
475    {lists:duplicate(I, $0) ++ [$.|lists:duplicate(Dc, $0)],false}.
476
477float_man([D|_], 0) when D >= $5 -> {[],true};
478float_man([_|_], 0) -> {[],false};
479float_man([D|Ds], Dc) ->
480    case float_man(Ds, Dc-1) of
481	{Cs,true} when D =:= $9 -> {[$0|Cs],true};
482	{Cs,true} -> {[D+1|Cs],false};
483	{Cs,false} -> {[D|Cs],false}
484    end;
485float_man([], Dc) -> {lists:duplicate(Dc, $0),false}.	%Pad with 0's
486
487%% float_exp(Exponent) -> [Char].
488%%  Generate the exponent of a floating point number. Always include sign.
489
490float_exp(E) when E >= 0 ->
491    [$e,$+|integer_to_list(E)];
492float_exp(E) ->
493    [$e|integer_to_list(E)].
494
495%% fwrite_f(FloatData, Field, Adjust, Precision, PadChar)
496
497fwrite_f(Fl, none, Adj, none, Pad) ->		%Default values
498    fwrite_f(Fl, none, Adj, 6, Pad);
499fwrite_f(Fl, none, _Adj, P, _Pad) when P >= 1 ->
500    float_f(Fl, float_data(Fl), P);
501fwrite_f(Fl, F, Adj, none, Pad) ->
502    fwrite_f(Fl, F, Adj, 6, Pad);
503fwrite_f(Fl, F, Adj, P, Pad) when P >= 1 ->
504    term(float_f(Fl, float_data(Fl), P), F, Adj, F, Pad).
505
506float_f(Fl, Fd, P) when Fl < 0.0 ->
507    [$-|float_f(-Fl, Fd, P)];
508float_f(Fl, {Ds,E}, P) when E =< 0 ->
509    float_f(Fl, {lists:duplicate(-E+1, $0)++Ds,1}, P);	%Prepend enough 0's
510float_f(_Fl, {Ds,E}, P) ->
511    case float_man(Ds, E, P) of
512	{Fs,true} -> "1" ++ Fs;			%Handle carry
513	{Fs,false} -> Fs
514    end.
515
516%% float_data([FloatChar]) -> {[Digit],Exponent}
517
518float_data(Fl) ->
519    float_data(float_to_list(Fl), []).
520
521float_data([$e|E], Ds) ->
522    {lists:reverse(Ds),list_to_integer(E)+1};
523float_data([D|Cs], Ds) when D >= $0, D =< $9 ->
524    float_data(Cs, [D|Ds]);
525float_data([_|Cs], Ds) ->
526    float_data(Cs, Ds).
527
528%%  Writes the shortest, correctly rounded string that converts
529%%  to Float when read back with list_to_float/1.
530%%
531%%  See also "Printing Floating-Point Numbers Quickly and Accurately"
532%%  in Proceedings of the SIGPLAN '96 Conference on Programming
533%%  Language Design and Implementation.
534
535-spec fwrite_g(float()) -> string().
536
537fwrite_g(0.0) ->
538    "0.0";
539fwrite_g(Float) when is_float(Float) ->
540    {Frac, Exp} = mantissa_exponent(Float),
541    {Place, Digits} = fwrite_g_1(Float, Exp, Frac),
542    R = insert_decimal(Place, [$0 + D || D <- Digits]),
543    [$- || true <- [Float < 0.0]] ++ R.
544
545-define(BIG_POW, (1 bsl 52)).
546-define(MIN_EXP, (-1074)).
547
548mantissa_exponent(F) ->
549    case <<F:64/float>> of
550        <<_S:1, 0:11, M:52>> -> % denormalized
551            E = log2floor(M),
552            {M bsl (53 - E), E - 52 - 1075};
553        <<_S:1, BE:11, M:52>> when BE < 2047 ->
554            {M + ?BIG_POW, BE - 1075}
555    end.
556
557fwrite_g_1(Float, Exp, Frac) ->
558    Round = (Frac band 1) =:= 0,
559    if
560        Exp >= 0  ->
561            BExp = 1 bsl Exp,
562            if
563                Frac =:= ?BIG_POW ->
564                    scale(Frac * BExp * 4, 4, BExp * 2, BExp,
565                          Round, Round, Float);
566                true ->
567                    scale(Frac * BExp * 2, 2, BExp, BExp,
568                          Round, Round, Float)
569            end;
570        Exp < ?MIN_EXP ->
571            BExp = 1 bsl (?MIN_EXP - Exp),
572            scale(Frac * 2, 1 bsl (1 - Exp), BExp, BExp,
573                  Round, Round, Float);
574        Exp > ?MIN_EXP, Frac =:= ?BIG_POW ->
575            scale(Frac * 4, 1 bsl (2 - Exp), 2, 1,
576                  Round, Round, Float);
577        true ->
578            scale(Frac * 2, 1 bsl (1 - Exp), 1, 1,
579                  Round, Round, Float)
580    end.
581
582scale(R, S, MPlus, MMinus, LowOk, HighOk, Float) ->
583    Est = int_ceil(math:log10(abs(Float)) - 1.0e-10),
584    %% Note that the scheme implementation uses a 326 element look-up
585    %% table for int_pow(10, N) where we do not.
586    if
587        Est >= 0 ->
588            fixup(R, S * int_pow(10, Est), MPlus, MMinus, Est,
589                  LowOk, HighOk);
590        true ->
591            Scale = int_pow(10, -Est),
592            fixup(R * Scale, S, MPlus * Scale, MMinus * Scale, Est,
593                  LowOk, HighOk)
594    end.
595
596fixup(R, S, MPlus, MMinus, K, LowOk, HighOk) ->
597    TooLow = if
598                 HighOk ->  R + MPlus >= S;
599                 true -> R + MPlus > S
600             end,
601    case TooLow of
602        true ->
603            {K + 1, generate(R, S, MPlus, MMinus, LowOk, HighOk)};
604        false ->
605            {K, generate(R * 10, S, MPlus * 10, MMinus * 10, LowOk, HighOk)}
606    end.
607
608generate(R0, S, MPlus, MMinus, LowOk, HighOk) ->
609    D = R0 div S,
610    R = R0 rem S,
611    TC1 = if
612              LowOk -> R =< MMinus;
613              true -> R < MMinus
614          end,
615    TC2 = if
616              HighOk -> R + MPlus >= S;
617              true -> R + MPlus > S
618          end,
619    case {TC1, TC2} of
620        {false, false} ->
621            [D | generate(R * 10, S, MPlus * 10, MMinus * 10, LowOk, HighOk)];
622        {false, true} ->
623            [D + 1];
624        {true, false} ->
625            [D];
626        {true, true} when R * 2 < S ->
627            [D];
628        {true, true} ->
629            [D + 1]
630    end.
631
632insert_decimal(0, S) ->
633    "0." ++ S;
634insert_decimal(Place, S) ->
635    L = length(S),
636    if
637        Place < 0;
638        Place >= L ->
639            ExpL = integer_to_list(Place - 1),
640            ExpDot = if L =:= 1 -> 2; true -> 1 end,
641            ExpCost = length(ExpL) + 1 + ExpDot,
642            if
643                Place < 0 ->
644                    if
645                        2 - Place =< ExpCost ->
646                            "0." ++ lists:duplicate(-Place, $0) ++ S;
647                        true ->
648                            insert_exp(ExpL, S)
649                    end;
650                true ->
651                    if
652                        Place - L + 2 =< ExpCost ->
653                            S ++ lists:duplicate(Place - L, $0) ++ ".0";
654                        true ->
655                            insert_exp(ExpL, S)
656                    end
657            end;
658        true ->
659            {S0, S1} = lists:split(Place, S),
660            S0 ++ "." ++ S1
661    end.
662
663insert_exp(ExpL, [C]) ->
664    [C] ++ ".0e" ++ ExpL;
665insert_exp(ExpL, [C | S]) ->
666    [C] ++ "." ++ S ++ "e" ++ ExpL.
667
668int_ceil(X) when is_float(X) ->
669    T = trunc(X),
670    case (X - T) of
671        Neg when Neg < 0 -> T;
672        Pos when Pos > 0 -> T + 1;
673        _ -> T
674    end.
675
676int_pow(X, 0) when is_integer(X) ->
677    1;
678int_pow(X, N) when is_integer(X), is_integer(N), N > 0 ->
679    int_pow(X, N, 1).
680
681int_pow(X, N, R) when N < 2 ->
682    R * X;
683int_pow(X, N, R) ->
684    int_pow(X * X, N bsr 1, case N band 1 of 1 -> R * X; 0 -> R end).
685
686log2floor(Int) when is_integer(Int), Int > 0 ->
687    log2floor(Int, 0).
688
689log2floor(0, N) ->
690    N;
691log2floor(Int, N) ->
692    log2floor(Int bsr 1, 1 + N).
693
694%% fwrite_g(Float, Field, Adjust, Precision, PadChar)
695%%  Use the f form if Float is >= 0.1 and < 1.0e4,
696%%  and the prints correctly in the f form, else the e form.
697%%  Precision always means the # of significant digits.
698
699fwrite_g(Fl, F, Adj, none, Pad) ->
700    fwrite_g(Fl, F, Adj, 6, Pad);
701fwrite_g(Fl, F, Adj, P, Pad) when P >= 1 ->
702    A = abs(Fl),
703    E = if A < 1.0e-1 -> -2;
704	   A < 1.0e0  -> -1;
705	   A < 1.0e1  -> 0;
706	   A < 1.0e2  -> 1;
707	   A < 1.0e3  -> 2;
708	   A < 1.0e4  -> 3;
709	   true       -> fwrite_f
710	end,
711    if  P =< 1, E =:= -1;
712	P-1 > E, E >= -1 ->
713	    fwrite_f(Fl, F, Adj, P-1-E, Pad);
714	P =< 1 ->
715	    fwrite_e(Fl, F, Adj, 2, Pad);
716	true ->
717	    fwrite_e(Fl, F, Adj, P, Pad)
718    end.
719
720
721iolist_to_chars(Cs, F, CharsLimit) when CharsLimit < 0; CharsLimit >= F ->
722    iolist_to_chars(Cs);
723iolist_to_chars(Cs, _, CharsLimit) ->
724    limit_iolist_to_chars(Cs, sub(CharsLimit, 3), [], normal). % three dots
725
726iolist_to_chars([C|Cs]) when is_integer(C), C >= $\000, C =< $\377 ->
727    [C | iolist_to_chars(Cs)];
728iolist_to_chars([I|Cs]) ->
729    [iolist_to_chars(I) | iolist_to_chars(Cs)];
730iolist_to_chars([]) ->
731    [];
732iolist_to_chars(B) when is_binary(B) ->
733    binary_to_list(B).
734
735limit_iolist_to_chars(Cs, 0, S, normal) ->
736    L = limit_iolist_to_chars(Cs, 4, S, final),
737    case iolist_size(L) of
738        N when N < 4 -> L;
739        4 -> "..."
740    end;
741limit_iolist_to_chars(_Cs, 0, _S, final) -> [];
742limit_iolist_to_chars([C|Cs], Limit, S, Mode) when C >= $\000, C =< $\377 ->
743    [C | limit_iolist_to_chars(Cs, Limit - 1, S, Mode)];
744limit_iolist_to_chars([I|Cs], Limit, S, Mode) ->
745    limit_iolist_to_chars(I, Limit, [Cs|S], Mode);
746limit_iolist_to_chars([], _Limit, [], _Mode) ->
747    [];
748limit_iolist_to_chars([], Limit, [Cs|S], Mode) ->
749    limit_iolist_to_chars(Cs, Limit, S, Mode);
750limit_iolist_to_chars(B, Limit, S, Mode) when is_binary(B) ->
751    case byte_size(B) of
752        Sz when Sz > Limit ->
753            {B1, B2} = split_binary(B, Limit),
754            [binary_to_list(B1) | limit_iolist_to_chars(B2, 0, S, Mode)];
755        Sz ->
756            [binary_to_list(B) | limit_iolist_to_chars([], Limit-Sz, S, Mode)]
757    end.
758
759cdata_to_chars(Cs, F, CharsLimit) when CharsLimit < 0; CharsLimit >= F ->
760    cdata_to_chars(Cs);
761cdata_to_chars(Cs, _, CharsLimit) ->
762    limit_cdata_to_chars(Cs, sub(CharsLimit, 3), normal). % three dots
763
764cdata_to_chars([C|Cs]) when is_integer(C), C >= $\000 ->
765    [C | cdata_to_chars(Cs)];
766cdata_to_chars([I|Cs]) ->
767    [cdata_to_chars(I) | cdata_to_chars(Cs)];
768cdata_to_chars([]) ->
769    [];
770cdata_to_chars(B) when is_binary(B) ->
771    case catch unicode:characters_to_list(B) of
772        L when is_list(L) -> L;
773        _ -> binary_to_list(B)
774    end.
775
776limit_cdata_to_chars(Cs, 0, normal) ->
777    L = limit_cdata_to_chars(Cs, 4, final),
778    case string:length(L) of
779        N when N < 4 -> L;
780        4 -> "..."
781    end;
782limit_cdata_to_chars(_Cs, 0, final) -> [];
783limit_cdata_to_chars(Cs, Limit, Mode) ->
784    case string:next_grapheme(Cs) of
785        {error, <<C,Cs1/binary>>} ->
786            %% This is how ~ts handles Latin1 binaries with option
787            %% chars_limit.
788            [C | limit_cdata_to_chars(Cs1, Limit - 1, Mode)];
789        {error, [C|Cs1]} -> % not all versions of module string return this
790            [C | limit_cdata_to_chars(Cs1, Limit - 1, Mode)];
791        [] ->
792            [];
793        [GC|Cs1] ->
794            [GC | limit_cdata_to_chars(Cs1, Limit - 1, Mode)]
795    end.
796
797limit_field(F, CharsLimit) when CharsLimit < 0; F =:= none ->
798    F;
799limit_field(F, CharsLimit) ->
800    max(3, min(F, CharsLimit)).
801
802%% string(String, Field, Adjust, Precision, PadChar)
803
804string(S, none, _Adj, none, _Pad, _Enc) -> S;
805string(S, F, Adj, none, Pad, Enc) ->
806    string_field(S, F, Adj, io_lib:chars_length(S), Pad, Enc);
807string(S, none, _Adj, P, Pad, Enc) ->
808    string_field(S, P, left, io_lib:chars_length(S), Pad, Enc);
809string(S, F, Adj, P, Pad, Enc) when F >= P ->
810    N = io_lib:chars_length(S),
811    if F > P ->
812	    if N > P ->
813		    adjust(flat_trunc(S, P, Enc), chars(Pad, F-P), Adj);
814	       N < P ->
815		    adjust([S|chars(Pad, P-N)], chars(Pad, F-P), Adj);
816	       true -> % N == P
817		    adjust(S, chars(Pad, F-P), Adj)
818	    end;
819       true -> % F == P
820	    string_field(S, F, Adj, N, Pad, Enc)
821    end.
822
823string_field(S, F, _Adj, N, _Pad, Enc) when N > F ->
824    flat_trunc(S, F, Enc);
825string_field(S, F, Adj, N, Pad, _Enc) when N < F ->
826    adjust(S, chars(Pad, F-N), Adj);
827string_field(S, _, _, _, _, _) -> % N == F
828    S.
829
830%% unprefixed_integer(Int, Field, Adjust, Base, PadChar, Lowercase)
831%% -> [Char].
832
833unprefixed_integer(Int, F, Adj, Base, Pad, Lowercase)
834  when Base >= 2, Base =< 1+$Z-$A+10 ->
835    if Int < 0 ->
836	    S = cond_lowercase(erlang:integer_to_list(-Int, Base), Lowercase),
837	    term([$-|S], F, Adj, none, Pad);
838       true ->
839	    S = cond_lowercase(erlang:integer_to_list(Int, Base), Lowercase),
840	    term(S, F, Adj, none, Pad)
841    end.
842
843%% prefixed_integer(Int, Field, Adjust, Base, PadChar, Prefix, Lowercase)
844%% -> [Char].
845
846prefixed_integer(Int, F, Adj, Base, Pad, Prefix, Lowercase)
847  when Base >= 2, Base =< 1+$Z-$A+10 ->
848    if Int < 0 ->
849	    S = cond_lowercase(erlang:integer_to_list(-Int, Base), Lowercase),
850	    term([$-,Prefix|S], F, Adj, none, Pad);
851       true ->
852	    S = cond_lowercase(erlang:integer_to_list(Int, Base), Lowercase),
853	    term([Prefix|S], F, Adj, none, Pad)
854    end.
855
856%% char(Char, Field, Adjust, Precision, PadChar) -> chars().
857
858char(C, none, _Adj, none, _Pad) -> [C];
859char(C, F, _Adj, none, _Pad) -> chars(C, F);
860char(C, none, _Adj, P, _Pad) -> chars(C, P);
861char(C, F, Adj, P, Pad) when F >= P ->
862    adjust(chars(C, P), chars(Pad, F - P), Adj).
863
864%% newline(Field, Adjust, Precision, PadChar) -> [Char].
865
866newline(none, _Adj, _P, _Pad) -> "\n";
867newline(F, right, _P, _Pad) -> chars($\n, F).
868
869%%
870%% Utilities
871%%
872
873adjust(Data, [], _) -> Data;
874adjust(Data, Pad, left) -> [Data|Pad];
875adjust(Data, Pad, right) -> [Pad|Data].
876
877%% Flatten and truncate a deep list to at most N elements.
878
879flat_trunc(List, N, latin1) when is_integer(N), N >= 0 ->
880    {S, _} = lists:split(N, lists:flatten(List)),
881    S;
882flat_trunc(List, N, unicode) when is_integer(N), N >= 0 ->
883    string:slice(List, 0, N).
884
885%% A deep version of lists:duplicate/2
886
887chars(_C, 0) ->
888    [];
889chars(C, 1) ->
890    [C];
891chars(C, 2) ->
892    [C,C];
893chars(C, 3) ->
894    [C,C,C];
895chars(C, N) when is_integer(N), (N band 1) =:= 0 ->
896    S = chars(C, N bsr 1),
897    [S|S];
898chars(C, N) when is_integer(N) ->
899    S = chars(C, N bsr 1),
900    [C,S|S].
901
902%chars(C, N, Tail) ->
903%    [chars(C, N)|Tail].
904
905%% Lowercase conversion
906
907cond_lowercase(String, true) ->
908    lowercase(String);
909cond_lowercase(String,false) ->
910    String.
911
912lowercase([H|T]) when is_integer(H), H >= $A, H =< $Z ->
913    [(H-$A+$a)|lowercase(T)];
914lowercase([H|T]) ->
915    [H|lowercase(T)];
916lowercase([]) ->
917    [].
918
919%% Make sure T does change sign.
920sub(T, _) when T < 0 -> T;
921sub(T, E) when T >= E -> T - E;
922sub(_, _) -> 0.
923
924get_option(Key, TupleList, Default) ->
925    case lists:keyfind(Key, 1, TupleList) of
926	false -> Default;
927	{Key, Value} -> Value;
928	_ -> Default
929    end.
930