瀏覽代碼

ft: 修改为二进制匹配

master
SisMaker 4 年之前
父節點
當前提交
ca800443bf
共有 2 個檔案被更改,包括 152 行新增135 行删除
  1. +2
    -0
      include/eFmt.hrl
  2. +150
    -135
      src/eFmtFormat.erl

+ 2
- 0
include/eFmt.hrl 查看文件

@ -1,4 +1,6 @@
-define(base(Precision), case Precision of none -> 10; _ -> Precision end). -define(base(Precision), case Precision of none -> 10; _ -> Precision end).
%%
-define(IIF(Cond, Ret1, Ret2), (case Cond of true -> Ret1; _ -> Ret2 end)).
-record(fmtSpec, { -record(fmtSpec, {
ctlChar :: char() %% $p $w ctlChar :: char() %% $p $w

+ 150
- 135
src/eFmtFormat.erl 查看文件

@ -128,8 +128,8 @@ doCollPadChar(LPart, Args, Width, Adjust, Precision, Acc) ->
doCollEncoding(LPart, Args, Width, Adjust, Precision, PadChar, Acc) -> doCollEncoding(LPart, Args, Width, Adjust, Precision, PadChar, Acc) ->
case LPart of case LPart of
<<"t", Char:8/integer, LeftLPart/binary>> ->
true = Char =/= $l,
<<"t", LeftLPart/binary>> ->
%true = Char =/= $l,
doCollStrings(LeftLPart, Args, Width, Adjust, Precision, PadChar, unicode, Acc); doCollStrings(LeftLPart, Args, Width, Adjust, Precision, PadChar, unicode, Acc);
_ -> _ ->
doCollStrings(LPart, Args, Width, Adjust, Precision, PadChar, latin1, Acc) doCollStrings(LPart, Args, Width, Adjust, Precision, PadChar, latin1, Acc)
@ -137,16 +137,16 @@ doCollEncoding(LPart, Args, Width, Adjust, Precision, PadChar, Acc) ->
doCollStrings(LPart, Args, Width, Adjust, Precision, PadChar, Encoding, Acc) -> doCollStrings(LPart, Args, Width, Adjust, Precision, PadChar, Encoding, Acc) ->
case LPart of case LPart of
<<"l", Char:8/integer, LeftLPart/binary>> ->
true = Char =/= $t,
<<"l", LeftLPart/binary>> ->
%true = Char =/= $t,
doCollCA(LeftLPart, Args, Width, Adjust, Precision, PadChar, Encoding, false, Acc); doCollCA(LeftLPart, Args, Width, Adjust, Precision, PadChar, Encoding, false, Acc);
_ -> _ ->
doCollCA(LPart, Args, Width, Adjust, Precision, PadChar, Encoding, true, Acc) doCollCA(LPart, Args, Width, Adjust, Precision, PadChar, Encoding, true, Acc)
end. end.
doCollCA(LPart, Args, Width, Adjust, Precision, PadChar, Encoding, Strings, Acc) -> doCollCA(LPart, Args, Width, Adjust, Precision, PadChar, Encoding, Strings, Acc) ->
<<Char:8/integer, LeftLPart/binary>> = LPart,
case Char of
<<CtlChar:8/integer, LeftLPart/binary>> = LPart,
case CtlChar of
$w -> [OneArgs | LeftArgs] = Args, As = OneArgs, NextArgs = LeftArgs; $w -> [OneArgs | LeftArgs] = Args, As = OneArgs, NextArgs = LeftArgs;
$p ->[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; $W ->[OneArgs | LeftArgs] = Args, [Depth | LastArgs] = LeftArgs, As = [OneArgs, Depth], NextArgs = LastArgs;
@ -166,7 +166,7 @@ doCollCA(LPart, Args, Width, Adjust, Precision, PadChar, Encoding, Strings, Acc)
$n -> As = undefined, NextArgs = Args; $n -> As = undefined, NextArgs = Args;
$i ->[OneArgs | LeftArgs] = Args, As = OneArgs, NextArgs = LeftArgs $i ->[OneArgs | LeftArgs] = Args, As = OneArgs, NextArgs = LeftArgs
end, end,
FmtSpec = #fmtSpec{ctlChar = Char, args = As, width = Width, adjust = Adjust, precision = Precision, padChar = PadChar, encoding = Encoding, strings = Strings},
FmtSpec = #fmtSpec{ctlChar = CtlChar, args = As, width = Width, adjust = Adjust, precision = Precision, padChar = PadChar, encoding = Encoding, strings = Strings},
doCollect(LeftLPart, NextArgs, [FmtSpec | Acc]). doCollect(LeftLPart, NextArgs, [FmtSpec | Acc]).
%% Build the output text for a pre-parsed format list. %% Build the output text for a pre-parsed format list.
@ -177,14 +177,14 @@ build(Cs) ->
-spec build(FormatList :: [char() | eFmt:fmtSpec()], Options :: [{'chars_limit', CharsLimit :: integer()}]) -> eFmt:chars(). -spec build(FormatList :: [char() | eFmt:fmtSpec()], Options :: [{'chars_limit', CharsLimit :: integer()}]) -> eFmt:chars().
build(Cs, Options) -> build(Cs, Options) ->
CharsLimit = getOpt(chars_limit, Options, -1), CharsLimit = getOpt(chars_limit, Options, -1),
Res1 = buildSmall(Cs, []),
{P, S, W, Other} = count_small(Res1, 0, 0, 0, 0),
ResList = buildSmall(Cs, []),
{P, S, W, Other} = cntSmall(ResList, 0, 0, 0, 0),
case P + S + W of case P + S + W of
0 -> 0 ->
Res1;
ResList;
NumOfLimited -> NumOfLimited ->
RemainingChars = sub(CharsLimit, Other),
build_limited(Res1, P, NumOfLimited, RemainingChars, 0)
RemainChars = remainChars(CharsLimit, Other),
buildLimited(ResList, P, NumOfLimited, RemainChars, 0, [])
end. end.
%% build_small([Control]) -> eFmt:chars(). %% build_small([Control]) -> eFmt:chars().
@ -193,20 +193,19 @@ build(Cs, Options) ->
%% Interpret the control structures. Count the number of print %% Interpret the control structures. Count the number of print
%% remaining and only calculate indentation when necessary. Must also %% remaining and only calculate indentation when necessary. Must also
%% be smart when calculating indentation for characters in format. %% be smart when calculating indentation for characters in format.
buildSmall([], Acc) -> Acc; buildSmall([], Acc) -> Acc;
buildSmall([OneCA | Cs], Acc) -> buildSmall([OneCA | Cs], Acc) ->
case OneCA of case OneCA of
#fmtSpec{ctlChar = C, args = Args, width = Width, adjust = Adjust, precision = Precision, padChar = PadChar, encoding = Encoding} ->
case ctlSmall(C, Args, Width, Adjust, Precision, PadChar, Encoding) 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]); not_small -> buildSmall(Cs, [OneCA | Acc]);
ignore -> buildSmall(Cs, Acc);
Str -> buildSmall(Cs, [Str | Acc]) Str -> buildSmall(Cs, [Str | Acc])
end; end;
_ -> _ ->
buildSmall(Cs, [OneCA | Acc]) buildSmall(Cs, [OneCA | Acc])
end. end.
%% control_small(FormatChar, [Argument], FieldWidth, Adjust, Precision, %% control_small(FormatChar, [Argument], FieldWidth, Adjust, Precision,
%% PadChar, Encoding) -> String %% PadChar, Encoding) -> String
%% control_limited(FormatChar, [Argument], FieldWidth, Adjust, Precision, %% control_limited(FormatChar, [Argument], FieldWidth, Adjust, Precision,
@ -245,63 +244,72 @@ ctlSmall($+, Args, Width, Adjust, Precision, PadChar, _Encoding) when is_integer
ctlSmall($#, Args, Width, Adjust, Precision, PadChar, _Encoding) when is_integer(Args) -> ctlSmall($#, Args, Width, Adjust, Precision, PadChar, _Encoding) when is_integer(Args) ->
Base = ?base(Precision), Base = ?base(Precision),
prefixedInt(Args, Width, Adjust, Base, PadChar, integer_to_binary(Base), $#, false); prefixedInt(Args, Width, Adjust, Base, PadChar, integer_to_binary(Base), $#, false);
ctlSmall($c,Args, Width, Adjust, Precision, PadChar, _Encoding) when is_integer(Args) ->
char(Args, Width, Adjust, Precision, PadChar);
ctlSmall($c, Args, Width, Adjust, Precision, PadChar, _Enc) when is_integer(Args) ->
char(Args band 255, Width, Adjust, Precision, PadChar);
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($~, _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($n, _Args, Width, Adjust, Precision, PadChar, _Encoding) -> newline(Width, Adjust, Precision, PadChar);
ctlSmall($i, _Args, _Width, _Adjust, _Precision, _PadChar, _Encoding) -> [];
ctlSmall($i, _Args, _Width, _Adjust, _Precision, _PadChar, _Encoding) -> ignore;
ctlSmall(_C, _Args, _Width, _Adjust, _Precision, _PadChar, _Encoding) -> not_small. ctlSmall(_C, _Args, _Width, _Adjust, _Precision, _PadChar, _Encoding) -> not_small.
%% count_small[ControlC]->pPwWsS
count_small([#{control_char := $p} | Cs], P, S, W, Other) ->
count_small(Cs, P + 1, S, W, Other);
count_small([#{control_char := $P} | Cs], P, S, W, Other) ->
count_small(Cs, P + 1, S, W, Other);
count_small([#{control_char := $w} | Cs], P, S, W, Other) ->
count_small(Cs, P, S, W + 1, Other);
count_small([#{control_char := $W} | Cs], P, S, W, Other) ->
count_small(Cs, P, S, W + 1, Other);
count_small([#{control_char := $s} | Cs], P, S, W, Other) ->
count_small(Cs, P, S, W + 1, Other);
count_small([S | Cs], P, S, W, Other) when is_list(S);is_binary(S) ->
count_small(Cs, P, S, W, Other + eFmt:charsLen(S));
count_small([C | Cs], P, S, W, Other) when is_integer(C) ->
count_small(Cs, P, S, W, Other + 1);
count_small([], P, S, W, Other) ->
{P, S, W, Other}.
build_limited([#{control_char := C, args := As, width := F, adjust := Ad, precision := P, pad_char := Pad, encoding := Enc, strings := Str} | Cs], NumOfPs0, Count0, MaxLen0, I) ->
MaxChars = if
MaxLen0 < 0 -> MaxLen0;
true -> MaxLen0 div Count0
end,
S = control_limited(C, As, F, Ad, P, Pad, Enc, Str, MaxChars, I),
NumOfPs = decr_pc(C, NumOfPs0),
Count = Count0 - 1,
MaxLen = if
MaxLen0 < 0 -> % optimization
MaxLen0;
true ->
Len = eFmt:charsLen(S),
sub(MaxLen0, Len)
end,
if
NumOfPs > 0 -> [S | build_limited(Cs, NumOfPs, Count,
MaxLen, indentation(S, I))];
true -> [S | build_limited(Cs, NumOfPs, Count, MaxLen, I)]
end;
build_limited([$\n | Cs], NumOfPs, Count, MaxLen, _I) ->
[$\n | build_limited(Cs, NumOfPs, Count, MaxLen, 0)];
build_limited([$\t | Cs], NumOfPs, Count, MaxLen, I) ->
[$\t | build_limited(Cs, NumOfPs, Count, MaxLen, ((I + 8) div 8) * 8)];
build_limited([C | Cs], NumOfPs, Count, MaxLen, I) ->
[C | build_limited(Cs, NumOfPs, Count, MaxLen, I + 1)];
build_limited([], _, _, _, _) -> [].
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(S));
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,
S = ctlLimited(CtlChar, Args, Width, Adjust, Precision, PadChar, Encoding, Strings, MaxChars, I),
NewNumOfPs = decr_pc(CtlChar, NumOfPs),
NewCount = Count - 1,
MaxLen = if
MaxLen < 0 -> % optimization
MaxLen;
true ->
Len = eFmt:charsLen(S),
remainChars(MaxLen, Len)
end,
if
NewNumOfPs > 0 -> [S | buildLimited(Cs, NewNumOfPs, NewCount,
MaxLen, indentation(S, I))];
true -> [S | buildLimited(Cs, NewNumOfPs, NewCount, MaxLen, I)]
end;
_ ->
buildLimited(Cs, NewNumOfPs, NewCount, MaxLen, I + 1, [OneCA | Acc])
end.
decr_pc($p, Pc) -> Pc - 1; decr_pc($p, Pc) -> Pc - 1;
decr_pc($P, Pc) -> Pc - 1; decr_pc($P, Pc) -> Pc - 1;
@ -323,25 +331,32 @@ indentation([C | Cs], I) ->
indentation([], I) -> I. indentation([], I) -> I.
%% (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);
control_limited($s, [L0], F, Adj, P, Pad, latin1 = Enc, _Str, CL, _I) ->
L = iolist_to_chars(L0, F, CL),
string(L, limit_field(F, CL), Adj, P, Pad, Enc);
control_limited($s, [L0], F, Adj, P, Pad, unicode = Enc, _Str, CL, _I) ->
L = cdata_to_chars(L0, F, CL),
uniconv(string(L, limit_field(F, CL), Adj, P, Pad, Enc));
control_limited($w, [A], F, Adj, P, Pad, Enc, _Str, CL, _I) ->
Chars = eFmt:write(A, [{depth, -1}, {encoding, Enc}, {chars_limit, CL}]),
term(Chars, F, Adj, P, Pad);
control_limited($p, [A], F, Adj, P, Pad, Enc, Str, CL, I) ->
print(A, -1, F, Adj, P, Pad, Enc, Str, CL, I);
control_limited($W, [A, Depth], F, Adj, P, Pad, Enc, _Str, CL, _I)
_ ->
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:write(Args, [{depth, -1}, {encoding, Encoding}, {chars_limit, 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)
when is_integer(Depth) -> when is_integer(Depth) ->
Chars = eFmt:write(A, [{depth, Depth}, {encoding, Enc}, {chars_limit, CL}]),
term(Chars, F, Adj, P, Pad);
control_limited($P, [A, Depth], F, Adj, P, Pad, Enc, Str, CL, I)
Chars = eFmt:write(Args, [{depth, Depth}, {encoding, Encoding}, {chars_limit, CharsLimit}]),
term(Chars, Width, Adjust, Precision, PadChar);
ctlLimited($P, [Args, Depth], Width, Adjust, Precision, PadChar, Encoding, Strings, CharsLimit, I)
when is_integer(Depth) -> when is_integer(Depth) ->
print(A, Depth, F, Adj, P, Pad, Enc, Str, CL, I).
print(Args, Depth, Width, Adjust, Precision, PadChar, Encoding, Strings, CharsLimit, I).
-ifdef(UNICODE_AS_BINARIES). -ifdef(UNICODE_AS_BINARIES).
uniconv(C) -> uniconv(C) ->
@ -611,7 +626,7 @@ log2floor(Int, N) ->
iolist_to_chars(Cs, F, CharsLimit) when CharsLimit < 0; CharsLimit >= F -> iolist_to_chars(Cs, F, CharsLimit) when CharsLimit < 0; CharsLimit >= F ->
iolist_to_chars(Cs); iolist_to_chars(Cs);
iolist_to_chars(Cs, _, CharsLimit) -> iolist_to_chars(Cs, _, CharsLimit) ->
limit_iolist_to_chars(Cs, sub(CharsLimit, 3), [], normal). % three dots
limit_iolist_to_chars(Cs, remainChars(CharsLimit, 3), [], normal). % three dots
iolist_to_chars([C | Cs]) when is_integer(C), C >= $\000, C =< $\377 -> iolist_to_chars([C | Cs]) when is_integer(C), C >= $\000, C =< $\377 ->
[C | iolist_to_chars(Cs)]; [C | iolist_to_chars(Cs)];
@ -622,6 +637,9 @@ iolist_to_chars([]) ->
iolist_to_chars(B) when is_binary(B) -> iolist_to_chars(B) when is_binary(B) ->
binary_to_list(B). binary_to_list(B).
limit_iolist_to_chars(Cs, 0, S, normal) -> limit_iolist_to_chars(Cs, 0, S, normal) ->
L = limit_iolist_to_chars(Cs, 4, S, final), L = limit_iolist_to_chars(Cs, 4, S, final),
case iolist_size(L) of case iolist_size(L) of
@ -646,22 +664,26 @@ limit_iolist_to_chars(B, Limit, S, Mode) when is_binary(B) ->
[binary_to_list(B) | limit_iolist_to_chars([], Limit - Sz, S, Mode)] [binary_to_list(B) | limit_iolist_to_chars([], Limit - Sz, S, Mode)]
end. end.
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.
cdata_to_chars(Cs, F, CharsLimit) when CharsLimit < 0; CharsLimit >= F -> cdata_to_chars(Cs, F, CharsLimit) when CharsLimit < 0; CharsLimit >= F ->
cdata_to_chars(Cs); cdata_to_chars(Cs);
cdata_to_chars(Cs, _, CharsLimit) -> cdata_to_chars(Cs, _, CharsLimit) ->
limit_cdata_to_chars(Cs, sub(CharsLimit, 3), normal). % three dots
cdata_to_chars([C | Cs]) when is_integer(C), C >= $\000 ->
[C | cdata_to_chars(Cs)];
cdata_to_chars([I | Cs]) ->
[cdata_to_chars(I) | cdata_to_chars(Cs)];
cdata_to_chars([]) ->
[];
cdata_to_chars(B) when is_binary(B) ->
case catch unicode:characters_to_list(B) of
L when is_list(L) -> L;
_ -> binary_to_list(B)
end.
limit_cdata_to_chars(Cs, remainChars(CharsLimit, 3), normal). % three dots
limit_cdata_to_chars(Cs, 0, normal) -> limit_cdata_to_chars(Cs, 0, normal) ->
L = limit_cdata_to_chars(Cs, 4, final), L = limit_cdata_to_chars(Cs, 4, final),
@ -729,7 +751,7 @@ flatTrunc(List, Width, _Encoding) ->
makePadChars(Char, Cnt, BinStr) -> makePadChars(Char, Cnt, BinStr) ->
case Cnt > 0 of case Cnt > 0 of
true -> true ->
makePadChars(Cnt - 1, Char, <<BinStr/binary, Char>>);
makePadChars(Cnt - 1, Char, <<BinStr/binary, (integer_to_binary(Char))/binary>>);
_ -> _ ->
BinStr BinStr
end. end.
@ -781,43 +803,36 @@ prefixedInt(Int, Width, Adjust, Base, PadChar, Prefix, Prefix2, Lowercase) ->
end end
end. end.
%% char(Char, Field, Adjust, Precision, PadChar) -> chars().
char(C, none, _Adj, none, _Pad) -> [C];
char(C, F, _Adj, none, _Pad) -> makePadChars(C, F, <<>>);
char(C, none, _Adj, P, _Pad) -> makePadChars(C, P, <<>>);
char(C, F, Adj, P, Pad) when F >= P ->
adjust(Adj, makePadChars(C, P, <<>>), makePadChars(Pad, F - P, <<>>)).
%% newline(Field, Adjust, Precision, PadChar) -> [Char].
newline(none, _Adj, _P, _Pad) -> "\n";
newline(F, right, _P, _Pad) -> makePadChars($\n, F, <<>>).
%chars(C, N, Tail) ->
% [chars(C, N)|Tail].
%% Lowercase conversion
cond_lowercase(String, true) ->
lowercase(String);
cond_lowercase(String, false) ->
String.
char(Char, Width, Adjust, Precision, PadChar) ->
if
Width == none andalso Precision == none ->
integer_to_binary(Char);
Precision == none ->
makePadChars(Char, Width, <<>>);
Width == none ->
makePadChars(Char, Precision, <<>>);
true ->
adjust(Adjust, makePadChars(Char, Precision, <<>>), makePadChars(PadChar, Width - Precision, <<>>))
end.
lowercase([H | T]) when is_integer(H), H >= $A, H =< $Z ->
[(H - $A + $a) | lowercase(T)];
lowercase([H | T]) ->
[H | lowercase(T)];
lowercase([]) ->
[].
newline(none, _Adjust, _Precision, _PadChar) -> <<"\n">>;
newline(Width, Adjust, _Precision, _PadChar) ->
case Adjust of
right ->
makePadChars($\n, Width, <<>>);
_ ->
<<"\n">>
end.
%% Make sure T does change sign.
sub(T, _) when T < 0 -> T;
sub(T, E) when T >= E -> T - E;
sub(_, _) -> 0.
remainChars(T, E) ->
if
T < 0 ->
T;
T >= E ->
T - E;
true ->
0
end.
getOpt(Key, TupleList, Default) -> getOpt(Key, TupleList, Default) ->
case lists:keyfind(Key, 1, TupleList) of case lists:keyfind(Key, 1, TupleList) of

Loading…
取消
儲存