|
|
@ -1,627 +0,0 @@ |
|
|
|
-module(eFmtFormat). |
|
|
|
|
|
|
|
-include("eFmt.hrl"). |
|
|
|
|
|
|
|
-compile(export_all). |
|
|
|
|
|
|
|
%% Formatting functions of io library. |
|
|
|
-export([ |
|
|
|
fwrite/2 |
|
|
|
, fwrite/3 |
|
|
|
, floatG/1 |
|
|
|
, scan/2 |
|
|
|
, build/1 |
|
|
|
, build/2 |
|
|
|
]). |
|
|
|
|
|
|
|
%% 在字符串格式之后将参数格式化为Args。刚产生 |
|
|
|
%% 如果参数中有错误,则为错误。 |
|
|
|
%% |
|
|
|
%% 要正确执行打印命令,我们需要计算 |
|
|
|
%% 当前缩进的所有内容。这可能非常 |
|
|
|
%% 价格昂贵,尤其是在不需要时,因此我们首先确定 |
|
|
|
%% 是否以及需要多长时间来计算缩进。我们的确是 |
|
|
|
%% 首先收集所有控制序列,然后 |
|
|
|
%% 相应的参数,然后计算打印顺序,然后 |
|
|
|
%% 然后构建输出。这种方法有一些缺点,它确实 |
|
|
|
%% 在格式字符串上两次传递并创建更多临时数据, |
|
|
|
%% 并且还将控制字符的处理分为两个 |
|
|
|
%% 部分。 |
|
|
|
|
|
|
|
-spec fwrite(Format :: io:format(), Data :: [term()]) -> eFmt:chars(). |
|
|
|
fwrite(Format, Args) -> |
|
|
|
build(scan(Format, Args), []). |
|
|
|
|
|
|
|
-spec fwrite(Format :: io:format(), Data :: [term()], Options :: [{'chars_limit', CharsLimit :: integer()}]) -> eFmt:chars(). |
|
|
|
fwrite(Format, Args, Options) -> |
|
|
|
build(scan(Format, Args), Options). |
|
|
|
|
|
|
|
|
|
|
|
%% Parse all control sequences in the format string. |
|
|
|
-spec scan(Format :: io:format(), Data :: [term()]) -> FormatList :: [char() | eFmt:fmtSpec()]. |
|
|
|
|
|
|
|
%% 格式 ~F.P.PadModC |
|
|
|
scan(Format, Args) -> |
|
|
|
if |
|
|
|
is_atom(Format) -> |
|
|
|
doCollect(atom_to_binary(Format, utf8), Args, []); |
|
|
|
is_list(Format) -> |
|
|
|
doCollect(list_to_binary(Format), Args, []); |
|
|
|
true -> |
|
|
|
doCollect(Format, Args, []) |
|
|
|
end. |
|
|
|
|
|
|
|
doCollect(FmtBinStr, Args, Acc) -> |
|
|
|
case binary:split(FmtBinStr, <<"~">>) of |
|
|
|
[NotMatch] -> |
|
|
|
[NotMatch | Acc]; |
|
|
|
[FPart, LPart] -> |
|
|
|
doCollWidth(LPart, Args, 0, right, [FPart | Acc]) |
|
|
|
end. |
|
|
|
|
|
|
|
doCollWidth(<<>>, _Args, _Width, _Adjust, Acc) -> |
|
|
|
Acc; |
|
|
|
doCollWidth(LPart, Args, Width, Adjust, Acc) -> |
|
|
|
%% 匹配宽度 |
|
|
|
case LPart of |
|
|
|
<<"-*", LeftLPart/binary>> -> |
|
|
|
[WidthArgs | LeftArgs] = Args, |
|
|
|
doCollPrecision(LeftLPart, LeftArgs, WidthArgs, left, Acc); |
|
|
|
<<"-", LeftLPart/binary>> -> |
|
|
|
doCollWidth(LeftLPart, Args, Width, left, Acc); |
|
|
|
<<"*", LeftLPart/binary>> -> |
|
|
|
[WidthArgs | LeftArgs] = Args, |
|
|
|
doCollPrecision(LeftLPart, LeftArgs, WidthArgs, right, Acc); |
|
|
|
<<WidthInt:8/integer, LeftLPart/binary>> -> |
|
|
|
case WidthInt >= $0 andalso WidthInt =< $9 of |
|
|
|
true -> |
|
|
|
doCollWidth(LeftLPart, Args, 10 * Width + (WidthInt - $0), Adjust, Acc); |
|
|
|
_ -> |
|
|
|
case Width == 0 of |
|
|
|
true -> |
|
|
|
doCollPrecision(LPart, Args, none, left, Acc); |
|
|
|
_ -> |
|
|
|
doCollPrecision(LPart, Args, Width, Adjust, Acc) |
|
|
|
end |
|
|
|
end |
|
|
|
end. |
|
|
|
|
|
|
|
doCollPrecision(LPart, Args, Width, Adjust, Acc) -> |
|
|
|
case LPart of |
|
|
|
<<".", LeftLPart/binary>> -> |
|
|
|
doCollPrecision(LeftLPart, Args, Width, Adjust, 0, Acc); |
|
|
|
_ -> |
|
|
|
doCollPadChar(LPart, Args, Width, Adjust, none, Acc) |
|
|
|
end. |
|
|
|
|
|
|
|
doCollPrecision(LPart, Args, Width, Adjust, Precision, Acc) -> |
|
|
|
case LPart of |
|
|
|
<<"*", LeftLPart/binary>> -> |
|
|
|
[PrecisionArgs | LeftArgs] = Args, |
|
|
|
doCollPadChar(LeftLPart, LeftArgs, Width, Adjust, PrecisionArgs, Acc); |
|
|
|
<<PrecisionInt:8/integer, LeftLPart/binary>> -> |
|
|
|
case PrecisionInt >= $0 andalso PrecisionInt =< $9 of |
|
|
|
true -> |
|
|
|
doCollPrecision(LeftLPart, Args, Width, Adjust, 10 * Precision + (PrecisionInt - $0), Acc); |
|
|
|
_ -> |
|
|
|
case Precision == 0 of |
|
|
|
true -> |
|
|
|
doCollPadChar(LPart, Args, Width, Adjust, none, Acc); |
|
|
|
_ -> |
|
|
|
doCollPadChar(LPart, Args, Width, Adjust, Precision, Acc) |
|
|
|
end |
|
|
|
end |
|
|
|
end. |
|
|
|
|
|
|
|
doCollPadChar(LPart, Args, Width, Adjust, Precision, Acc) -> |
|
|
|
case LPart of |
|
|
|
<<".*", LeftLPart/binary>> -> |
|
|
|
[PadChar | LeftArgs] = Args, |
|
|
|
doCollEncoding(LeftLPart, LeftArgs, Width, Adjust, Precision, PadChar, Acc); |
|
|
|
<<".", PadChar:8/integer, LeftLPart/binary>> -> |
|
|
|
doCollEncoding(LeftLPart, Args, Width, Adjust, Precision, PadChar, Acc); |
|
|
|
_ -> |
|
|
|
doCollEncoding(LPart, Args, Width, Adjust, Precision, 32, Acc) |
|
|
|
end. |
|
|
|
|
|
|
|
doCollEncoding(LPart, Args, Width, Adjust, Precision, PadChar, Acc) -> |
|
|
|
case LPart of |
|
|
|
<<"t", LeftLPart/binary>> -> |
|
|
|
%true = Char =/= $l, |
|
|
|
doCollStrings(LeftLPart, Args, Width, Adjust, Precision, PadChar, unicode, Acc); |
|
|
|
_ -> |
|
|
|
doCollStrings(LPart, Args, Width, Adjust, Precision, PadChar, latin1, Acc) |
|
|
|
end. |
|
|
|
|
|
|
|
doCollStrings(LPart, Args, Width, Adjust, Precision, PadChar, Encoding, Acc) -> |
|
|
|
case LPart of |
|
|
|
<<"l", LeftLPart/binary>> -> |
|
|
|
%true = Char =/= $t, |
|
|
|
doCollCA(LeftLPart, Args, Width, Adjust, Precision, PadChar, Encoding, false, Acc); |
|
|
|
_ -> |
|
|
|
doCollCA(LPart, Args, Width, Adjust, Precision, PadChar, Encoding, true, Acc) |
|
|
|
end. |
|
|
|
|
|
|
|
doCollCA(LPart, Args, Width, Adjust, Precision, PadChar, Encoding, Strings, Acc) -> |
|
|
|
<<CtlChar:8/integer, LeftLPart/binary>> = LPart, |
|
|
|
io:format("IMY*********************doCollCA:~p~p~n", [CtlChar, LPart]), |
|
|
|
case CtlChar of |
|
|
|
$w -> [OneArgs | LeftArgs] = Args, As = OneArgs, NextArgs = LeftArgs; |
|
|
|
$p ->[OneArgs | LeftArgs] = Args, As = OneArgs, NextArgs = LeftArgs; |
|
|
|
$W ->[OneArgs | LeftArgs] = Args, [Depth | LastArgs] = LeftArgs, As = [OneArgs, Depth], NextArgs = LastArgs; |
|
|
|
$P -> [OneArgs | LeftArgs] = Args,[Depth | LastArgs] = LeftArgs, As = [OneArgs, Depth], NextArgs = LastArgs; |
|
|
|
$s ->[OneArgs | LeftArgs] = Args, As = OneArgs, NextArgs = LeftArgs; |
|
|
|
$e ->[OneArgs | LeftArgs] = Args, As = OneArgs, NextArgs = LeftArgs; |
|
|
|
$f ->[OneArgs | LeftArgs] = Args, As = OneArgs, NextArgs = LeftArgs; |
|
|
|
$g -> [OneArgs | LeftArgs] = Args,As = OneArgs, NextArgs = LeftArgs; |
|
|
|
$b ->[OneArgs | LeftArgs] = Args, As = OneArgs, NextArgs = LeftArgs; |
|
|
|
$B ->[OneArgs | LeftArgs] = Args, As = OneArgs, NextArgs = LeftArgs; |
|
|
|
$x ->[OneArgs | LeftArgs] = Args, [Prefix | LastArgs] = LeftArgs, As = [OneArgs, Prefix], NextArgs = LastArgs; |
|
|
|
$X -> [OneArgs | LeftArgs] = Args,[Prefix | LastArgs] = LeftArgs, As = [OneArgs, Prefix], NextArgs = LastArgs; |
|
|
|
$+ -> [OneArgs | LeftArgs] = Args,As = OneArgs, NextArgs = LeftArgs; |
|
|
|
$# ->[OneArgs | LeftArgs] = Args, As = OneArgs, NextArgs = LeftArgs; |
|
|
|
$c ->[OneArgs | LeftArgs] = Args, As = OneArgs, NextArgs = LeftArgs; |
|
|
|
$~ -> As = undefined, NextArgs = Args; |
|
|
|
$n -> As = undefined, NextArgs = Args; |
|
|
|
$i ->[OneArgs | LeftArgs] = Args, As = OneArgs, NextArgs = LeftArgs |
|
|
|
end, |
|
|
|
FmtSpec = #fmtSpec{ctlChar = CtlChar, args = As, width = Width, adjust = Adjust, precision = Precision, padChar = PadChar, encoding = Encoding, strings = Strings}, |
|
|
|
io:format("IMY***************~p~n", [FmtSpec]), |
|
|
|
doCollect(LeftLPart, NextArgs, [FmtSpec | Acc]). |
|
|
|
|
|
|
|
%% Build the output text for a pre-parsed format list. |
|
|
|
-spec build(FormatList :: [char() | eFmt:fmtSpec()]) -> eFmt:chars(). |
|
|
|
build(Cs) -> |
|
|
|
build(Cs, []). |
|
|
|
|
|
|
|
-spec build(FormatList :: [char() | eFmt:fmtSpec()], Options :: [{'chars_limit', CharsLimit :: integer()}]) -> eFmt:chars(). |
|
|
|
build(Cs, Options) -> |
|
|
|
CharsLimit = getOpt(chars_limit, Options, -1), |
|
|
|
ResList = buildSmall(Cs, []), |
|
|
|
{P, S, W, Other} = cntSmall(ResList, 0, 0, 0, 0), |
|
|
|
NumOfLimited = P + S + W, |
|
|
|
case NumOfLimited of |
|
|
|
0 -> |
|
|
|
ResList; |
|
|
|
_ -> |
|
|
|
RemainChars = remainChars(CharsLimit, Other), |
|
|
|
buildLimited(ResList, P, NumOfLimited, RemainChars, 0, []) |
|
|
|
end. |
|
|
|
|
|
|
|
%% build_small([Control]) -> eFmt:chars(). |
|
|
|
%% Interpret the control structures, but only the small ones. The big ones are saved for later. |
|
|
|
%% build_limited([Control], NumberOfPps, NumberOfLimited, CharsLimit, Indentation) |
|
|
|
%% Interpret the control structures. Count the number of print |
|
|
|
%% remaining and only calculate indentation when necessary. Must also |
|
|
|
%% be smart when calculating indentation for characters in format. |
|
|
|
buildSmall([], Acc) -> Acc; |
|
|
|
buildSmall([OneCA | Cs], Acc) -> |
|
|
|
case OneCA of |
|
|
|
#fmtSpec{ctlChar = CtlChar, args = Args, width = Width, adjust = Adjust, precision = Precision, padChar = PadChar, encoding = Encoding} -> |
|
|
|
case ctlSmall(CtlChar, Args, Width, Adjust, Precision, PadChar, Encoding) of |
|
|
|
not_small -> buildSmall(Cs, [OneCA | Acc]); |
|
|
|
ignore -> buildSmall(Cs, Acc); |
|
|
|
Str -> buildSmall(Cs, [Str | Acc]) |
|
|
|
end; |
|
|
|
_ -> |
|
|
|
buildSmall(Cs, [OneCA | Acc]) |
|
|
|
end. |
|
|
|
|
|
|
|
%% control_small(FormatChar, [Argument], FieldWidth, Adjust, Precision, |
|
|
|
%% PadChar, Encoding) -> String |
|
|
|
%% control_limited(FormatChar, [Argument], FieldWidth, Adjust, Precision, |
|
|
|
%% PadChar, Encoding, StringP, ChrsLim, Indentation) -> String |
|
|
|
%% These are the dispatch functions for the various formatting controls. |
|
|
|
|
|
|
|
ctlSmall($s, Args, Width, Adjust, Precision, PadChar, Encoding) when is_atom(Args) -> |
|
|
|
case Encoding of |
|
|
|
latin1 -> |
|
|
|
AtomBinStr = eFmt:writeAtom(Args, latin1); |
|
|
|
_ -> |
|
|
|
AtomBinStr = eFmt:writeAtom(Args, uft8) |
|
|
|
end, |
|
|
|
string(AtomBinStr, Width, Adjust, Precision, PadChar, Encoding); |
|
|
|
ctlSmall($e, Args, Width, Adjust, Precision, PadChar, _Encoding) when is_float(Args) -> |
|
|
|
floatE(Args, Width, Adjust, Precision, PadChar); |
|
|
|
ctlSmall($f, Args, Width, Adjust, Precision, PadChar, _Encoding) when is_float(Args) -> |
|
|
|
floatF(Args, Width, Adjust, Precision, PadChar); |
|
|
|
ctlSmall($g, Args, Width, Adjust, Precision, PadChar, _Encoding) when is_float(Args) -> |
|
|
|
floatG(Args, Width, Adjust, Precision, PadChar); |
|
|
|
ctlSmall($b, Args, Width, Adjust, Precision, PadChar, _Encoding) when is_integer(Args) -> |
|
|
|
unPrefixedInt(Args, Width, Adjust, ?base(Precision), PadChar, true); |
|
|
|
ctlSmall($B, Args, Width, Adjust, Precision, PadChar, _Encoding) when is_integer(Args) -> |
|
|
|
unPrefixedInt(Args, Width, Adjust, ?base(Precision), PadChar, false); |
|
|
|
ctlSmall($x, [Args, Prefix], Width, Adjust, Precision, PadChar, _Encoding) when is_integer(Args), is_atom(Prefix) -> |
|
|
|
prefixedInt(Args, Width, Adjust, ?base(Precision), PadChar, atom_to_binary(Prefix, utf8), true); |
|
|
|
ctlSmall($x, [Args, Prefix], Width, Adjust, Precision, PadChar, _Encoding) when is_integer(Args) -> |
|
|
|
prefixedInt(Args, Width, Adjust, ?base(Precision), PadChar, Prefix, true); |
|
|
|
ctlSmall($X, [Args, Prefix], Width, Adjust, Precision, PadChar, _Encoding) when is_integer(Args), is_atom(Prefix) -> |
|
|
|
prefixedInt(Args, Width, Adjust, ?base(Precision), PadChar, atom_to_binary(Prefix, utf8), false); |
|
|
|
ctlSmall($X, [Args, Prefix], Width, Adjust, Precision, PadChar, _Encoding) when is_integer(Args) -> |
|
|
|
prefixedInt(Args, Width, Adjust, ?base(Precision), PadChar, Prefix, false); |
|
|
|
ctlSmall($+, Args, Width, Adjust, Precision, PadChar, _Encoding) when is_integer(Args) -> |
|
|
|
Base = ?base(Precision), |
|
|
|
prefixedInt(Args, Width, Adjust, Base, PadChar, integer_to_binary(Base), $#, true); |
|
|
|
ctlSmall($#, Args, Width, Adjust, Precision, PadChar, _Encoding) when is_integer(Args) -> |
|
|
|
Base = ?base(Precision), |
|
|
|
prefixedInt(Args, Width, Adjust, Base, PadChar, integer_to_binary(Base), $#, false); |
|
|
|
ctlSmall($c,Args, Width, Adjust, Precision, PadChar, Encoding) when is_integer(Args) -> |
|
|
|
case Encoding of |
|
|
|
unicode -> |
|
|
|
char(Args, Width, Adjust, Precision, PadChar); |
|
|
|
_ -> |
|
|
|
char(Args band 255, Width, Adjust, Precision, PadChar) |
|
|
|
end; |
|
|
|
ctlSmall($~, _Args, Width, Adjust, Precision, PadChar, _Encoding) -> char($~, Width, Adjust, Precision, PadChar); |
|
|
|
ctlSmall($n, _Args, Width, Adjust, Precision, PadChar, _Encoding) -> newline(Width, Adjust, Precision, PadChar); |
|
|
|
ctlSmall($i, _Args, _Width, _Adjust, _Precision, _PadChar, _Encoding) -> ignore; |
|
|
|
ctlSmall(_C, _Args, _Width, _Adjust, _Precision, _PadChar, _Encoding) -> not_small. |
|
|
|
|
|
|
|
cntSmall([], P, S, W, Other) -> |
|
|
|
{P, S, W, Other}; |
|
|
|
cntSmall([OneRes | Cs], P, S, W, Other) -> |
|
|
|
case OneRes of |
|
|
|
#fmtSpec{ctlChar = CtlChar} -> |
|
|
|
case CtlChar of |
|
|
|
$p -> |
|
|
|
cntSmall(Cs, P + 1, S, W, Other); |
|
|
|
$P -> |
|
|
|
cntSmall(Cs, P + 1, S, W, Other); |
|
|
|
$w -> |
|
|
|
cntSmall(Cs, P, S, W + 1, Other); |
|
|
|
$W -> |
|
|
|
cntSmall(Cs, P, S, W + 1, Other); |
|
|
|
$s -> |
|
|
|
cntSmall(Cs, P, S, W + 1, Other); |
|
|
|
_ -> |
|
|
|
cntSmall(Cs, P, S, W, Other) |
|
|
|
end; |
|
|
|
_ -> |
|
|
|
if |
|
|
|
is_binary(OneRes) orelse is_list(OneRes) -> |
|
|
|
cntSmall(Cs, P, S, W, Other + eFmt:charsLen(OneRes)); |
|
|
|
is_integer(OneRes) -> |
|
|
|
cntSmall(Cs, P, S, W, Other + 1); |
|
|
|
true -> |
|
|
|
cntSmall(Cs, P, S, W, Other) |
|
|
|
end |
|
|
|
end. |
|
|
|
|
|
|
|
buildLimited([], _, _, _, _, Acc) -> Acc; |
|
|
|
buildLimited([OneCA | Cs], NumOfPs, Count, MaxLen, I, Acc) -> |
|
|
|
case OneCA of |
|
|
|
#fmtSpec{ctlChar = CtlChar, args = Args, width = Width, adjust = Adjust, precision = Precision, padChar = PadChar, encoding = Encoding, strings = Strings} -> |
|
|
|
MaxChars = if MaxLen < 0 -> MaxLen; true -> MaxLen div Count end, |
|
|
|
IoListStr = ctlLimited(CtlChar, Args, Width, Adjust, Precision, PadChar, Encoding, Strings, MaxChars, I), |
|
|
|
NewNumOfPs = decrPc(CtlChar, NumOfPs), |
|
|
|
NewCount = Count - 1, |
|
|
|
MaxLen = ?IIF(MaxLen < 0, MaxLen, remainChars(MaxLen, eFmt:charsLen(IoListStr))), |
|
|
|
if |
|
|
|
NewNumOfPs > 0 -> |
|
|
|
buildLimited(Cs, NewNumOfPs, NewCount, MaxLen, I, [IoListStr | Acc]); |
|
|
|
true -> |
|
|
|
buildLimited(Cs, NewNumOfPs, NewCount, MaxLen, I, [IoListStr | Acc]) |
|
|
|
end; |
|
|
|
_ -> |
|
|
|
buildLimited(Cs, NumOfPs, Count, MaxLen, I + 1, [OneCA | Acc]) |
|
|
|
end. |
|
|
|
|
|
|
|
decrPc($p, Pc) -> Pc - 1; |
|
|
|
decrPc($P, Pc) -> Pc - 1; |
|
|
|
decrPc(_, Pc) -> Pc. |
|
|
|
|
|
|
|
%% (CtlChar, Args, Width, Adjust, Precision, PadChar, Encoding, Strings, MaxChars, I) |
|
|
|
ctlLimited($s, Args, Width, Adjust, Precision, PadChar, Encoding, _Strings, CharsLimit, _I) -> |
|
|
|
case Encoding of |
|
|
|
latin1 -> |
|
|
|
BinStr = erlang:iolist_to_binary(Args); |
|
|
|
|
|
|
|
_ -> |
|
|
|
BinStr = case catch unicode:characters_to_binary(Args, unicode) of |
|
|
|
Str when is_binary(Str) -> Str; |
|
|
|
_ -> toBinary(Args) |
|
|
|
end |
|
|
|
end, |
|
|
|
TemBinStr = strToChars(BinStr, Width, CharsLimit), |
|
|
|
string(TemBinStr, ?IIF(CharsLimit < 0 orelse Width =:= none, Width, max(3, min(Width, CharsLimit))), Adjust, Precision, PadChar, Encoding); |
|
|
|
ctlLimited($w, Args, Width, Adjust, Precision, PadChar, Encoding, _Strings, CharsLimit, _I) -> |
|
|
|
Chars = eFmt:doWrite(Args, -1, Encoding, CharsLimit), |
|
|
|
term(Chars, Width, Adjust, Precision, PadChar); |
|
|
|
ctlLimited($p, Args, Width, Adjust, Precision, PadChar, Encoding, Strings, CharsLimit, I) -> |
|
|
|
print(Args, -1, Width, Adjust, Precision, PadChar, Encoding, Strings, CharsLimit, I); |
|
|
|
ctlLimited($W, [Args, Depth], Width, Adjust, Precision, PadChar, Encoding, _Strings, CharsLimit, _I) -> |
|
|
|
Chars = eFmt:doWrite(Args, Depth, Encoding, CharsLimit), |
|
|
|
term(Chars, Width, Adjust, Precision, PadChar); |
|
|
|
ctlLimited($P, [Args, Depth], Width, Adjust, Precision, PadChar, Encoding, Strings, CharsLimit, I) -> |
|
|
|
print(Args, Depth, Width, Adjust, Precision, PadChar, Encoding, Strings, CharsLimit, I). |
|
|
|
|
|
|
|
%% term(TermList, Field, Adjust, Precision, PadChar) |
|
|
|
%% Output the characters in a term. |
|
|
|
%% Adjust the characters within the field if length less than Max padding |
|
|
|
%% with PadChar. |
|
|
|
|
|
|
|
term(BinStrOrIoList, Width, Adjust, Precision, PadChar) -> |
|
|
|
if |
|
|
|
Width == none andalso Precision == none -> |
|
|
|
BinStrOrIoList; |
|
|
|
Width == none -> |
|
|
|
StrLen = eFmt:charsLen(BinStrOrIoList), |
|
|
|
NewPrecision = erlang:min(StrLen, Precision), |
|
|
|
if |
|
|
|
StrLen > NewPrecision -> |
|
|
|
adjust(Adjust, makePadChars($*, NewPrecision, <<>>), <<>>); |
|
|
|
true -> |
|
|
|
adjust(Adjust, BinStrOrIoList, makePadChars(PadChar, Precision - StrLen, <<>>)) |
|
|
|
end; |
|
|
|
true -> |
|
|
|
io:format("IMY****************1111 ~p ~n", [PadChar]), |
|
|
|
StrLen = eFmt:charsLen(BinStrOrIoList), |
|
|
|
NewPrecision = erlang:min(StrLen, case Precision of none -> Width; _ -> min(Precision, Width) end), |
|
|
|
if |
|
|
|
StrLen > NewPrecision -> |
|
|
|
adjust(Adjust, makePadChars($*, NewPrecision, <<>>), makePadChars(PadChar, Width - NewPrecision, <<>>)); |
|
|
|
true -> |
|
|
|
io:format("IMY****************22222~p ~p ~n", [BinStrOrIoList, PadChar]), |
|
|
|
A = adjust(Adjust, BinStrOrIoList, makePadChars(PadChar, Width - StrLen, <<>>)), |
|
|
|
io:format("IMY****************333 ~p ~p ~n", [A, PadChar]), |
|
|
|
A |
|
|
|
end |
|
|
|
end. |
|
|
|
|
|
|
|
%% print(Term, Depth, Field, Adjust, Precision, PadChar, Encoding, |
|
|
|
%% Indentation) |
|
|
|
%% Print a term. Field width sets maximum line length, Precision sets |
|
|
|
%% initial indentation. |
|
|
|
print(Term, Depth, Width, _Adjust, Precision, _PadChar, Encoding, Strings, CharsLimit, I) -> |
|
|
|
if |
|
|
|
Width == none -> NewWidth = 80; |
|
|
|
true -> NewWidth = Width |
|
|
|
end, |
|
|
|
if |
|
|
|
Precision == none -> NewPrecision = I + 1; |
|
|
|
true -> NewPrecision = Precision |
|
|
|
end, |
|
|
|
Options = [ |
|
|
|
{chars_limit, CharsLimit}, |
|
|
|
{column, Precision}, |
|
|
|
{line_length, Width}, |
|
|
|
{depth, Depth}, |
|
|
|
{encoding, Encoding}, |
|
|
|
{strings, Strings} |
|
|
|
], |
|
|
|
io_lib_pretty:print(Term, Options). |
|
|
|
|
|
|
|
print(Term, Options) when is_list(Options) -> |
|
|
|
Col = get_option(column, Options, 1), |
|
|
|
Ll = get_option(line_length, Options, 80), |
|
|
|
D = get_option(depth, Options, -1), |
|
|
|
M = get_option(line_max_chars, Options, -1), |
|
|
|
T = get_option(chars_limit, Options, -1), |
|
|
|
RecDefFun = get_option(record_print_fun, Options, no_fun), |
|
|
|
Encoding = get_option(encoding, Options, epp:default_encoding()), |
|
|
|
Strings = get_option(strings, Options, true), |
|
|
|
print(Term, Col, Ll, D, M, T, RecDefFun, Encoding, Strings); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
floatE(Float, Width, Adjust, Precision, PadChar) -> |
|
|
|
case Precision of |
|
|
|
none -> |
|
|
|
NewPrecision = 6; |
|
|
|
_ -> |
|
|
|
NewPrecision = Precision |
|
|
|
end, |
|
|
|
case Width of |
|
|
|
none -> |
|
|
|
float_to_binary(Float, [{scientific, NewPrecision}]); |
|
|
|
_ -> |
|
|
|
term(float_to_binary(Float, [{scientific, NewPrecision}]), Width, Adjust, Width, PadChar) |
|
|
|
end. |
|
|
|
|
|
|
|
floatF(Float, Width, Adjust, Precision, PadChar) -> |
|
|
|
case Precision of |
|
|
|
none -> |
|
|
|
NewPrecision = 6; |
|
|
|
_ -> |
|
|
|
NewPrecision = Precision |
|
|
|
end, |
|
|
|
case Width of |
|
|
|
none -> |
|
|
|
float_to_binary(Float, [{decimals, NewPrecision}]); |
|
|
|
_ -> |
|
|
|
term(float_to_binary(Float, [{decimals, NewPrecision}]), Width, Adjust, Width, PadChar) |
|
|
|
end. |
|
|
|
|
|
|
|
%% fwrite_g(Float, Field, Adjust, Precision, PadChar) |
|
|
|
%% Use the f form if Float is >= 0.1 and < 1.0e4, |
|
|
|
%% and the prints correctly in the f form, else the e form. |
|
|
|
%% Precision always means the # of significant digits. |
|
|
|
floatG(Float, Width, Adjust, Precision, PadChar) -> |
|
|
|
case Float > -10000.0 andalso Float < 10000.0 of |
|
|
|
true -> |
|
|
|
floatF(Float, Width, Adjust, Precision, PadChar); |
|
|
|
_ -> |
|
|
|
floatE(Float, Width, Adjust, Precision, PadChar) |
|
|
|
end. |
|
|
|
|
|
|
|
floatG(Float) -> |
|
|
|
float_to_binary(Float, [{decimals, 6}]). |
|
|
|
|
|
|
|
strToChars(BinStr, Width, CharsLimit) -> |
|
|
|
ByteSize = byte_size(BinStr), |
|
|
|
if |
|
|
|
Width == none -> |
|
|
|
case CharsLimit < 0 orelse CharsLimit >= ByteSize of |
|
|
|
true -> |
|
|
|
BinStr; |
|
|
|
_ -> |
|
|
|
<<(binary:part(BinStr, 0, CharsLimit))/binary, "...">> |
|
|
|
end; |
|
|
|
CharsLimit < 0 orelse CharsLimit >= Width -> |
|
|
|
BinStr; |
|
|
|
true -> |
|
|
|
<<(binary:part(BinStr, 0, CharsLimit))/binary, "...">> |
|
|
|
end. |
|
|
|
|
|
|
|
string(Str, Width, Adjust, Precision, PadChar, Encoding) -> |
|
|
|
if |
|
|
|
Width == none andalso Precision == none -> |
|
|
|
Str; |
|
|
|
Precision == none -> |
|
|
|
strField(Str, Width, Adjust, eFmt:charsLen(Str), PadChar, Encoding); |
|
|
|
Width == none -> |
|
|
|
strField(Str, Precision, left, eFmt:charsLen(Str), PadChar, Encoding); |
|
|
|
true -> |
|
|
|
StrLen = eFmt:charsLen(Str), |
|
|
|
if |
|
|
|
Width > Precision -> |
|
|
|
if StrLen > Precision -> |
|
|
|
adjust(Adjust, flatTrunc(Str, Precision, Encoding), makePadChars(PadChar, Width - Precision, <<>>)); |
|
|
|
StrLen < Precision -> |
|
|
|
adjust(Adjust, [Str | makePadChars(PadChar, Precision - StrLen, <<>>)], makePadChars(PadChar, Width - Precision, <<>>)); |
|
|
|
true -> % N == P |
|
|
|
adjust(Adjust, Str, makePadChars(PadChar, Width - Precision, <<>>)) |
|
|
|
end; |
|
|
|
true -> % F == P |
|
|
|
strField(Str, Width, Adjust, StrLen, PadChar, Encoding) |
|
|
|
end |
|
|
|
end. |
|
|
|
|
|
|
|
strField(Str, Width, Adjust, StrLen, PadChar, Encoding) when StrLen > Width -> |
|
|
|
if |
|
|
|
StrLen > Width -> |
|
|
|
flatTrunc(Str, Width, Encoding); |
|
|
|
StrLen < Width -> |
|
|
|
adjust(Adjust, Str, makePadChars(PadChar, Width - StrLen, <<>>)); |
|
|
|
true -> |
|
|
|
Str |
|
|
|
end. |
|
|
|
|
|
|
|
flatTrunc(List, Width, _Encoding) -> |
|
|
|
binary:part(iolist_to_binary(List), 0, Width). |
|
|
|
|
|
|
|
makePadChars(PadChar, Cnt, BinStr) -> |
|
|
|
case Cnt > 0 of |
|
|
|
true -> |
|
|
|
makePadChars(PadChar, Cnt - 1, <<BinStr/binary, PadChar:8>>); |
|
|
|
_ -> |
|
|
|
BinStr |
|
|
|
end. |
|
|
|
|
|
|
|
adjust(left, Data, Pad) -> [Data, Pad]; |
|
|
|
adjust(right, Data, Pad) -> [Pad, Data]. |
|
|
|
|
|
|
|
unPrefixedInt(Int, Width, Adjust, Base, PadChar, Lowercase) -> |
|
|
|
case Lowercase of |
|
|
|
true -> |
|
|
|
term(toLowerStr(integer_to_binary(Int, Base)), Width, Adjust, none, PadChar); |
|
|
|
_ -> |
|
|
|
term(integer_to_binary(Int, Base), Width, Adjust, none, PadChar) |
|
|
|
end. |
|
|
|
|
|
|
|
prefixedInt(Int, Width, Adjust, Base, PadChar, Prefix, Lowercase) -> |
|
|
|
case Int < 0 of |
|
|
|
true -> |
|
|
|
case Lowercase of |
|
|
|
true -> |
|
|
|
term(<<"-", (toBinary(Prefix))/binary, (toLowerStr(integer_to_binary(-Int, Base)))/binary>>, Width, Adjust, none, PadChar); |
|
|
|
_ -> |
|
|
|
term(<<"-", (toBinary(Prefix))/binary, (integer_to_binary(-Int, Base))/binary>>, Width, Adjust, none, PadChar) |
|
|
|
end; |
|
|
|
_ -> |
|
|
|
case Lowercase of |
|
|
|
true -> |
|
|
|
term(<<(toBinary(Prefix))/binary, (toLowerStr(integer_to_binary(Int, Base)))/binary>>, Width, Adjust, none, PadChar); |
|
|
|
_ -> |
|
|
|
term(<<(toBinary(Prefix))/binary, (integer_to_binary(Int, Base))/binary>>, Width, Adjust, none, PadChar) |
|
|
|
end |
|
|
|
end. |
|
|
|
|
|
|
|
prefixedInt(Int, Width, Adjust, Base, PadChar, Prefix, Prefix2, Lowercase) -> |
|
|
|
case Int < 0 of |
|
|
|
true -> |
|
|
|
case Lowercase of |
|
|
|
true -> |
|
|
|
term(<<"-", (toBinary(Prefix))/binary, Prefix2:8, (toLowerStr(integer_to_binary(-Int, Base)))/binary>>, Width, Adjust, none, PadChar); |
|
|
|
_ -> |
|
|
|
term(<<"-", (toBinary(Prefix))/binary, Prefix2:8, (integer_to_binary(-Int, Base))/binary>>, Width, Adjust, none, PadChar) |
|
|
|
end; |
|
|
|
_ -> |
|
|
|
case Lowercase of |
|
|
|
true -> |
|
|
|
term(<<(toBinary(Prefix))/binary, Prefix2:8, (toLowerStr(integer_to_binary(Int, Base)))/binary>>, Width, Adjust, none, PadChar); |
|
|
|
_ -> |
|
|
|
term(<<(toBinary(Prefix))/binary, Prefix2:8, (integer_to_binary(Int, Base))/binary>>, Width, Adjust, none, PadChar) |
|
|
|
end |
|
|
|
end. |
|
|
|
|
|
|
|
char(Char, Width, Adjust, Precision, PadChar) -> |
|
|
|
if |
|
|
|
Width == none andalso Precision == none -> |
|
|
|
Char; |
|
|
|
Precision == none -> |
|
|
|
makePadChars(Char, Width, <<>>); |
|
|
|
Width == none -> |
|
|
|
makePadChars(Char, Precision, <<>>); |
|
|
|
true -> |
|
|
|
adjust(Adjust, makePadChars(Char, Precision, <<>>), makePadChars(PadChar, Width - Precision, <<>>)) |
|
|
|
end. |
|
|
|
|
|
|
|
newline(none, _Adjust, _Precision, _PadChar) -> <<"\n">>; |
|
|
|
newline(Width, Adjust, _Precision, _PadChar) -> |
|
|
|
case Adjust of |
|
|
|
right -> |
|
|
|
makePadChars($\n, Width, <<>>); |
|
|
|
_ -> |
|
|
|
<<"\n">> |
|
|
|
end. |
|
|
|
|
|
|
|
remainChars(T, E) -> |
|
|
|
if |
|
|
|
T < 0 -> |
|
|
|
T; |
|
|
|
T >= E -> |
|
|
|
T - E; |
|
|
|
true -> |
|
|
|
0 |
|
|
|
end. |
|
|
|
|
|
|
|
getOpt(Key, TupleList, Default) -> |
|
|
|
case lists:keyfind(Key, 1, TupleList) of |
|
|
|
{_, Value} -> |
|
|
|
Value; |
|
|
|
_ -> |
|
|
|
Default |
|
|
|
end. |
|
|
|
|
|
|
|
toLowerStr(BinStr) -> |
|
|
|
<< begin |
|
|
|
case C >= $A andalso C =< $Z of |
|
|
|
true -> |
|
|
|
<<(C + 32)>>; |
|
|
|
_ -> |
|
|
|
<<C>> |
|
|
|
end |
|
|
|
end || <<C:8>> <= BinStr |
|
|
|
>>. |
|
|
|
|
|
|
|
toUpperStr(BinStr) -> |
|
|
|
<< begin |
|
|
|
case C >= $a andalso C =< $z of |
|
|
|
true -> |
|
|
|
<<(C - 32)>>; |
|
|
|
_ -> |
|
|
|
<<C>> |
|
|
|
end |
|
|
|
end || <<C:8>> <= BinStr |
|
|
|
>>. |
|
|
|
|
|
|
|
toBinary(Value) when is_integer(Value) -> integer_to_binary(Value); |
|
|
|
toBinary(Value) when is_list(Value) -> list_to_binary(Value); |
|
|
|
toBinary(Value) when is_float(Value) -> float_to_binary(Value, [{decimals, 6}, compact]); |
|
|
|
toBinary(Value) when is_atom(Value) -> atom_to_binary(Value, utf8); |
|
|
|
toBinary(Value) when is_binary(Value) -> Value; |
|
|
|
toBinary([Tuple | PropList] = Value) when is_list(PropList) and is_tuple(Tuple) -> |
|
|
|
lists:map(fun({K, V}) -> {toBinary(K), toBinary(V)} end, Value); |
|
|
|
toBinary(Value) -> term_to_binary(Value). |