diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/compiler/src/beam_kernel_to_ssa.erl | 13 | ||||
-rw-r--r-- | lib/compiler/src/beam_ssa_pre_codegen.erl | 128 | ||||
-rw-r--r-- | lib/compiler/src/beam_validator.erl | 13 | ||||
-rw-r--r-- | lib/compiler/src/v3_core.erl | 2 | ||||
-rw-r--r-- | lib/compiler/src/v3_kernel.erl | 49 | ||||
-rw-r--r-- | lib/compiler/test/beam_except_SUITE.erl | 8 | ||||
-rw-r--r-- | lib/compiler/test/bs_match_SUITE.erl | 7 | ||||
-rw-r--r-- | lib/compiler/test/guard_SUITE.erl | 3 | ||||
-rw-r--r-- | lib/compiler/test/inline_SUITE.erl | 2 | ||||
-rw-r--r-- | lib/crypto/src/crypto.erl | 6 | ||||
-rw-r--r-- | lib/crypto/test/crypto_SUITE.erl | 5 | ||||
-rw-r--r-- | lib/eldap/src/eldap.erl | 4 | ||||
-rw-r--r-- | lib/eldap/test/eldap_basic_SUITE.erl | 85 | ||||
-rw-r--r-- | lib/stdlib/doc/src/peer.xml | 24 | ||||
-rwxr-xr-x | lib/stdlib/scripts/update_deprecations | 6 | ||||
-rw-r--r-- | lib/stdlib/src/otp_internal.erl | 12 |
16 files changed, 285 insertions, 82 deletions
diff --git a/lib/compiler/src/beam_kernel_to_ssa.erl b/lib/compiler/src/beam_kernel_to_ssa.erl index c2e22f4b6d..7722078206 100644 --- a/lib/compiler/src/beam_kernel_to_ssa.erl +++ b/lib/compiler/src/beam_kernel_to_ssa.erl @@ -25,7 +25,7 @@ -export([module/2]). -import(lists, [all/2,append/1,flatmap/2,foldl/3, - keysort/2,mapfoldl/3,member/2, + keyfind/3,keysort/2,mapfoldl/3,member/2, reverse/1,sort/1]). -include("v3_kernel.hrl"). @@ -672,7 +672,7 @@ call_cg(Func, As, [#k_var{name=R}|MoreRs]=Rs, Le, St0) -> %% Ordinary function call in a function body. Args = ssa_args([Func|As], St0), {Ret,St1} = new_ssa_var(R, St0), - Call = #b_set{anno=line_anno(Le),op=call,dst=Ret,args=Args}, + Call = #b_set{anno=call_anno(Le),op=call,dst=Ret,args=Args}, %% If this is a call to erlang:error(), MoreRs could be a %% nonempty list of variables that each need a value. @@ -685,9 +685,16 @@ call_cg(Func, As, [#k_var{name=R}|MoreRs]=Rs, Le, St0) -> enter_cg(Func, As0, Le, St0) -> As = ssa_args([Func|As0], St0), {Ret,St} = new_ssa_var('@ssa_ret', St0), - Call = #b_set{anno=line_anno(Le),op=call,dst=Ret,args=As}, + Call = #b_set{anno=call_anno(Le),op=call,dst=Ret,args=As}, {[Call,#b_ret{arg=Ret}],St}. +call_anno(Le) -> + Anno = line_anno(Le), + case keyfind(inlined, 1, Le) of + false -> Anno; + {inlined,NameArity} -> Anno#{inlined => NameArity} + end. + %% bif_cg(#k_bif{}, Le,State) -> {[Ainstr],State}. %% Generate code for a guard BIF or primop. diff --git a/lib/compiler/src/beam_ssa_pre_codegen.erl b/lib/compiler/src/beam_ssa_pre_codegen.erl index 3567fb4210..f5ad81f760 100644 --- a/lib/compiler/src/beam_ssa_pre_codegen.erl +++ b/lib/compiler/src/beam_ssa_pre_codegen.erl @@ -73,14 +73,16 @@ -import(lists, [all/2,any/2,append/1,duplicate/2, foldl/3,last/1,member/2,partition/2, - reverse/1,reverse/2,sort/1,splitwith/2,zip/2]). + reverse/1,reverse/2,seq/2,sort/1, + splitwith/2,usort/1,zip/2]). -spec module(beam_ssa:b_module(), [compile:option()]) -> {'ok',beam_ssa:b_module()}. module(#b_module{body=Fs0}=Module, Opts) -> Ps = passes(Opts), - Fs = functions(Fs0, Ps), + Fs1 = functions(Fs0, Ps), + Fs = fc_stubs(Fs1, Module), {ok,Module#b_module{body=Fs}}. functions([F|Fs], Ps) -> @@ -835,19 +837,21 @@ match_fail_instrs_1([{L,#b_blk{is=Is0}=Blk}|Bs], Arity, Blocks0) -> match_fail_instrs_1([], _Arity, Blocks) -> Blocks. match_fail_instrs_blk([#b_set{op=put_tuple,dst=Dst, - args=[#b_literal{val=Tag},Val]}, + args=[#b_literal{val=Tag}|Values]}, #b_set{op=call, args=[#b_remote{mod=#b_literal{val=erlang}, name=#b_literal{val=error}}, Dst]}=Call|Is], _Arity, Acc) -> - match_fail_instr(Call, Tag, Val, Is, Acc); + match_fail_instr(Call, Tag, Values, Is, Acc); match_fail_instrs_blk([#b_set{op=call, args=[#b_remote{mod=#b_literal{val=erlang}, name=#b_literal{val=error}}, - #b_literal{val={Tag,Val}}]}=Call|Is], - _Arity, Acc) -> - match_fail_instr(Call, Tag, #b_literal{val=Val}, Is, Acc); + #b_literal{val=Tuple}]}=Call|Is], + _Arity, Acc) when tuple_size(Tuple) >= 1 -> + [Tag|Values0] = tuple_to_list(Tuple), + Values = [#b_literal{val=V} || V <- Values0], + match_fail_instr(Call, Tag, Values, Is, Acc); match_fail_instrs_blk([#b_set{op=call, args=[#b_remote{mod=#b_literal{val=erlang}, name=#b_literal{val=error}}, @@ -860,34 +864,29 @@ match_fail_instrs_blk([#b_set{op=call,anno=Anno, name=#b_literal{val=error}}, #b_literal{val=function_clause}, Stk]}=Call], - {Arity,Location}, Acc) -> - case match_fail_stk(Stk, Acc, [], []) of - {[_|_]=Vars,Is} when length(Vars) =:= Arity -> - case maps:get(location, Anno, none) of - Location -> - I = Call#b_set{op=match_fail, - args=[#b_literal{val=function_clause}|Vars]}, - Is ++ [I]; - _ -> - %% erlang:error/2 has a different location than the - %% func_info instruction at the beginning of the function - %% (probably because of inlining). Keep the original call. - reverse(Acc, [Call]) - end; - _ -> - %% Either the stacktrace could not be picked apart (for example, - %% if the call to erlang:error/2 was handwritten) or the number - %% of arguments in the stacktrace was different from the arity - %% of the host function (because it is the implementation of a - %% fun). Keep the original call. - reverse(Acc, [Call]) - end; + Arity, Acc) -> + match_fail_fc(Anno, Call, Stk, Arity, Acc); match_fail_instrs_blk([I|Is], Arity, Acc) -> match_fail_instrs_blk(Is, Arity, [I|Acc]); match_fail_instrs_blk(_, _, _) -> none. -match_fail_instr(Call, Tag, Val, Is, Acc) -> +match_fail_instr(Call, function_clause, Values, Is, Acc) -> + case beam_ssa:get_anno(inlined, Call, none) of + none -> + %% If there is no `inlined` annotation, it implies that + %% the call to erlang:error/1 was handwritten. + none; + {Name,Arity} -> + %% A `function_clause` in inlined code. Convert it to + %% a call to a stub function that will raise a proper + %% `function_clause` exception. (The stub function will + %% be created later by fc_stubs/2.) + Target = #b_local{name=#b_literal{val=Name},arity=Arity}, + I = Call#b_set{args=[Target|Values]}, + reverse(Acc, [I|Is]) + end; +match_fail_instr(Call, Tag, [Val], Is, Acc) -> Op = case Tag of badmatch -> Tag; case_clause -> case_end; @@ -900,19 +899,84 @@ match_fail_instr(Call, Tag, Val, Is, Acc) -> _ -> I = Call#b_set{op=match_fail,args=[#b_literal{val=Op},Val]}, reverse(Acc, [I|Is]) + end; +match_fail_instr(_, _, _, _, _) -> none. + +match_fail_fc(Anno, Call, Stk, {Arity,Location}, Acc) -> + case match_fail_stk(Stk, Acc, [], []) of + {[_|_]=Vars,Is} when length(Vars) =:= Arity -> + case maps:get(location, Anno, none) of + Location -> + I = Call#b_set{op=match_fail, + args=[#b_literal{val=function_clause}|Vars]}, + Is ++ [I]; + _ -> + %% erlang:error/2 has a different location than + %% the func_info instruction at the beginning of + %% the function (probably because of + %% inlining). Keep the original call. + reverse(Acc, [Call]) + end; + _ -> + %% Either the stacktrace could not be picked apart (for + %% example, if the call to erlang:error/2 was handwritten) + %% or the number of arguments in the stacktrace was + %% different from the arity of the host function (because + %% it is the implementation of a fun). Keep the original + %% call. + reverse(Acc, [Call]) end. match_fail_stk(#b_var{}=V, [#b_set{op=put_list,dst=V,args=[H,T]}|Is], IAcc, VAcc) -> match_fail_stk(T, Is, IAcc, [H|VAcc]); match_fail_stk(#b_literal{val=[H|T]}, Is, IAcc, VAcc) -> match_fail_stk(#b_literal{val=T}, Is, IAcc, [#b_literal{val=H}|VAcc]); -match_fail_stk(#b_literal{val=[]}, [], IAcc, VAcc) -> - {reverse(VAcc),IAcc}; +match_fail_stk(#b_literal{val=[]}, Is, IAcc, VAcc) -> + {reverse(VAcc),reverse(Is, IAcc)}; match_fail_stk(T, [#b_set{op=Op}=I|Is], IAcc, VAcc) when Op =:= bs_get_tail; Op =:= bs_set_position -> match_fail_stk(T, Is, [I|IAcc], VAcc); match_fail_stk(_, _, _, _) -> none. +%% Create stubs for `function_clause` exceptions generated by +%% inlined code. +fc_stubs(Fs, #b_module{name=Mod}) -> + Stubs0 = usort(find_fc_calls(Fs, [])), + Stubs = [begin + Seq = seq(0, Arity-1), + Args = [#b_var{name=V} || V <- Seq], + XRegs = [{x,V} || V <- Seq], + Ret = #b_var{name='@ssa_ret'}, + Regs = maps:from_list([{Ret,{x,0}}|zip(Args, XRegs)]), + Anno = #{func_info => {Mod,Name,Arity}, + location => Location, + parameter_info => #{}, + registers => Regs}, + Fc = #b_set{op=match_fail,dst=Ret, + args=[#b_literal{val=function_clause}|Args]}, + Blk = #b_blk{is=[Fc],last=#b_ret{arg=Ret}}, + #b_function{anno=Anno,args=Args, + bs=#{0 => Blk}, + cnt=1} + end || {{Name,Arity},Location} <- Stubs0], + Fs ++ Stubs. + +find_fc_calls([#b_function{bs=Blocks}|Fs], Acc0) -> + F = fun(#b_set{anno=Anno,op=call}, A) -> + case Anno of + #{inlined := FA} -> + [{FA,maps:get(location, Anno, [])}|A]; + #{} -> + A + end; + (_, A) -> + A + end, + Acc = beam_ssa:fold_instrs(F, maps:keys(Blocks), Acc0, Blocks), + find_fc_calls(Fs, Acc); +find_fc_calls([], Acc) -> Acc. + + %%% %%% Introduce the set_tuple_element instructions to make %%% multiple-field record updates faster. diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl index 125c01c6a6..adbddc7059 100644 --- a/lib/compiler/src/beam_validator.erl +++ b/lib/compiler/src/beam_validator.erl @@ -245,7 +245,8 @@ build_function_table([{function,Name,Arity,Entry,Code0}|Fs], Acc) -> [{label,Entry} | Is] -> Info = #{ name => Name, arity => Arity, - parameter_info => find_parameter_info(Is, #{}) }, + parameter_info => find_parameter_info(Is, #{}), + always_fails => always_fails(Is) }, build_function_table(Fs, Acc#{ Entry => Info }); _ -> %% Something is seriously wrong. Ignore it for now. @@ -262,6 +263,9 @@ find_parameter_info([{'%', _} | Is], Acc) -> find_parameter_info(_, Acc) -> Acc. +always_fails([{jump,_}|_]) -> true; +always_fails(_) -> false. + validate_1(Is, MFA0, Entry, Level, Ft) -> {Offset, MFA, Header, Body} = extract_header(Is, MFA0, Entry, 1, []), @@ -3078,6 +3082,13 @@ will_call_succeed(bs_init_writable, _Vst) -> yes; will_call_succeed(raw_raise, _Vst) -> no; +will_call_succeed({f,Lbl}, #vst{ft=Ft}) -> + case Ft of + #{Lbl := #{always_fails := true}} -> + no; + #{} -> + maybe + end; will_call_succeed(_Call, _Vst) -> maybe. diff --git a/lib/compiler/src/v3_core.erl b/lib/compiler/src/v3_core.erl index 6bf87e131c..8e89c88318 100644 --- a/lib/compiler/src/v3_core.erl +++ b/lib/compiler/src/v3_core.erl @@ -264,7 +264,7 @@ body(Cs0, Name, Arity, St0) -> Args = reverse(Args0), %Nicer order {Cs1,St2} = clauses(Cs0, St1), {Ps,St3} = new_vars(Arity, St2), %Need new variables here - Fc = function_clause(Ps, Anno), + Fc = function_clause(Ps, FunAnno), {#ifun{anno=#a{anno=FunAnno},id=[],vars=Args,clauses=Cs1,fc=Fc},St3}. %% clause(Clause, State) -> {Cclause,State}. diff --git a/lib/compiler/src/v3_kernel.erl b/lib/compiler/src/v3_kernel.erl index aa3fc033eb..aa8a906ca7 100644 --- a/lib/compiler/src/v3_kernel.erl +++ b/lib/compiler/src/v3_kernel.erl @@ -405,36 +405,51 @@ letrec_goto([{#c_var{name={Label,0}},Cfail}], Cb, Sub0, %% erlang:error/2. translate_match_fail(Arg, Sub, Anno, St0) -> - Cargs = case {cerl:data_type(Arg),cerl:data_es(Arg)} of - {tuple,[#c_literal{val=function_clause}|As]} -> - translate_fc_args(As, Sub, St0); - {_,_} -> - [Arg] - end, - {Kargs,Ap,St} = atomic_list(Cargs, Sub, St0), + {Cargs,ExtraAnno,St1} = + case {cerl:data_type(Arg),cerl:data_es(Arg)} of + {tuple,[#c_literal{val=function_clause}|As]} -> + translate_fc_args(As, Sub, Anno, St0); + {_,_} -> + {[Arg],[],St0} + end, + {Kargs,Ap,St} = atomic_list(Cargs, Sub, St1), Ar = length(Cargs), - Call = #k_call{anno=Anno, + Call = #k_call{anno=ExtraAnno++Anno, op=#k_remote{mod=#k_literal{val=erlang}, name=#k_literal{val=error}, arity=Ar},args=Kargs}, {Call,Ap,St}. -translate_fc_args(As, Sub, #kern{fargs=Fargs}) -> +translate_fc_args(As, Sub, Anno, #kern{fargs=Fargs}=St0) -> case same_args(As, Fargs, Sub) of true -> %% The arguments for the `function_clause` exception are %% the arguments for the current function in the correct %% order. - [#c_literal{val=function_clause},cerl:make_list(As)]; + {[#c_literal{val=function_clause},cerl:make_list(As)], + [], + St0}; false -> %% The arguments in the `function_clause` exception don't - %% match the arguments for the current function because - %% of inlining. Keeping the `function_clause` - %% exception reason would be confusing. Rewrite it to - %% a `case_clause` exception with the arguments in a - %% tuple. - [cerl:c_tuple([#c_literal{val=case_clause}, - cerl:c_tuple(As)])] + %% match the arguments for the current function because of + %% inlining. + Args = [cerl:c_tuple([#c_literal{val=function_clause}|As])], + case keyfind(function, 1, Anno) of + false -> + %% This is probably a fun that has been inlined + %% by sys_core_fold. + {Name,St1} = new_fun_name("inlined", St0), + {Args, + [{inlined,{Name,length(As)}}], + St1}; + {_,{Name0,Arity}} -> + %% This is function that has been inlined. + Name1 = ["-inlined-",Name0,"/",Arity,"-"], + Name = list_to_atom(lists:concat(Name1)), + {Args, + [{inlined,{Name,Arity}}], + St0} + end end. same_args([#c_var{name=Cv}|Vs], [#k_var{name=Kv}|As], Sub) -> diff --git a/lib/compiler/test/beam_except_SUITE.erl b/lib/compiler/test/beam_except_SUITE.erl index 95e5989081..2bc805be71 100644 --- a/lib/compiler/test/beam_except_SUITE.erl +++ b/lib/compiler/test/beam_except_SUITE.erl @@ -135,14 +135,18 @@ coverage(_) -> {'EXIT',{function_clause,[{?MODULE,foobar,[[fail],1,2], [{file,"fake.erl"},{line,16}]}|_]}} = (catch foobar([fail], 1, 2)), + {'EXIT',{function_clause,[{?MODULE,fake_function_clause1,[{a,b},42.0],_}|_]}} = (catch fake_function_clause1({a,b})), {'EXIT',{function_clause,[{?MODULE,fake_function_clause2,[42|bad_tl],_}|_]}} = (catch fake_function_clause2(42, bad_tl)), + {'EXIT',{function_clause,[{?MODULE,fake_function_clause3,[x,y],_}|_]}} = (catch fake_function_clause3(42, id([x,y]))), + {'EXIT',{{function_clause,a,b,c}, _}} = catch fake_function_clause4(), + {'EXIT',{{badmatch,0.0},_}} = (catch coverage_1(id(42))), {'EXIT',{badarith,_}} = (catch coverage_1(id(a))), @@ -153,9 +157,13 @@ coverage_1(X) -> true = 0 / X. fake_function_clause1(A) -> error(function_clause, [A,42.0]). + fake_function_clause2(A, Tl) -> error(function_clause, [A|Tl]). + fake_function_clause3(_, Stk) -> error(function_clause, Stk). +fake_function_clause4() -> error({function_clause,a,b,c}). + binary_construction_allocation(_Config) -> ok = do_binary_construction_allocation("PUT"), ok. diff --git a/lib/compiler/test/bs_match_SUITE.erl b/lib/compiler/test/bs_match_SUITE.erl index f7542be568..96ae549b28 100644 --- a/lib/compiler/test/bs_match_SUITE.erl +++ b/lib/compiler/test/bs_match_SUITE.erl @@ -1468,10 +1468,11 @@ haystack_2(Haystack) -> fc({'EXIT',{function_clause,_}}) -> ok; fc({'EXIT',{{case_clause,_},_}}) when ?MODULE =:= bs_match_inline_SUITE -> ok. -fc(Name, Args, {'EXIT',{function_clause,[{?MODULE,Name,Args,_}|_]}}) -> ok; -fc(_, Args, {'EXIT',{{case_clause,ActualArgs},_}}) +fc(Name, Args, {'EXIT',{function_clause,[{?MODULE,Name,Args,_}|_]}}) -> + ok; +fc(Name, Args, {'EXIT',{function_clause,[{?MODULE,_,Args,_}|_]}}) when ?MODULE =:= bs_match_inline_SUITE -> - Args = tuple_to_list(ActualArgs). + ok. %% Cover the clause handling bs_context to binary in %% beam_block:initialized_regs/2. diff --git a/lib/compiler/test/guard_SUITE.erl b/lib/compiler/test/guard_SUITE.erl index 6699d82262..6a42453654 100644 --- a/lib/compiler/test/guard_SUITE.erl +++ b/lib/compiler/test/guard_SUITE.erl @@ -3070,5 +3070,4 @@ check(F, Result) -> ct:fail(check_failed) end. -fc({'EXIT',{function_clause,_}}) -> ok; -fc({'EXIT',{{case_clause,_},_}}) when ?MODULE =:= guard_inline_SUITE -> ok. +fc({'EXIT',{function_clause,_}}) -> ok. diff --git a/lib/compiler/test/inline_SUITE.erl b/lib/compiler/test/inline_SUITE.erl index 7482f53ed4..b2778bebcd 100644 --- a/lib/compiler/test/inline_SUITE.erl +++ b/lib/compiler/test/inline_SUITE.erl @@ -332,7 +332,7 @@ badarg(Reply, _A) -> Reply. otp_7223(Config) when is_list(Config) -> - {'EXIT', {{case_clause,{1}},_}} = (catch otp_7223_1(1)), + {'EXIT', {function_clause, [{?MODULE,_,[1],_}|_]}} = (catch otp_7223_1(1)), ok. -compile({inline,[{otp_7223_1,1}]}). diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl index 248442532a..70edc257f6 100644 --- a/lib/crypto/src/crypto.erl +++ b/lib/crypto/src/crypto.erl @@ -46,6 +46,12 @@ -export([pbkdf2_hmac/5]). %%%---------------------------------------------------------------- +%% Deprecated functions +-deprecated([crypto_dyn_iv_init/3, + crypto_dyn_iv_update/3 + ]). + +%%%---------------------------------------------------------------- %% Removed functions. %% %% Old interface. Now implemented with the New interface. diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl index 58614d9b0a..37bcecf4eb 100644 --- a/lib/crypto/test/crypto_SUITE.erl +++ b/lib/crypto/test/crypto_SUITE.erl @@ -170,6 +170,11 @@ rsa_oaep_label/0 ]). + +-compile({nowarn_deprecated_function, [{crypto, crypto_dyn_iv_init, 3}, + {crypto, crypto_dyn_iv_update, 3} + ]}). + %%-------------------------------------------------------------------- %% Common Test interface functions ----------------------------------- %%-------------------------------------------------------------------- diff --git a/lib/eldap/src/eldap.erl b/lib/eldap/src/eldap.erl index 24562eb790..dfdcfccf55 100644 --- a/lib/eldap/src/eldap.erl +++ b/lib/eldap/src/eldap.erl @@ -418,9 +418,9 @@ mra([{matchingRule,Val}|T], Ack) when is_list(Val) -> mra([{type,Val}|T], Ack) when is_list(Val) -> mra(T, Ack#'MatchingRuleAssertion'{type=Val}); mra([{dnAttributes,true}|T], Ack) -> - mra(T, Ack#'MatchingRuleAssertion'{dnAttributes="TRUE"}); + mra(T, Ack#'MatchingRuleAssertion'{dnAttributes=true}); mra([{dnAttributes,false}|T], Ack) -> - mra(T, Ack#'MatchingRuleAssertion'{dnAttributes="FALSE"}); + mra(T, Ack#'MatchingRuleAssertion'{dnAttributes=false}); mra([H|_], _) -> throw({error,{extensibleMatch_arg,H}}); mra([], Ack) -> diff --git a/lib/eldap/test/eldap_basic_SUITE.erl b/lib/eldap/test/eldap_basic_SUITE.erl index 15cf6a9039..6d90158050 100644 --- a/lib/eldap/test/eldap_basic_SUITE.erl +++ b/lib/eldap/test/eldap_basic_SUITE.erl @@ -59,6 +59,8 @@ search_non_existant/1, search_referral/1, search_two_hits/1, + search_extensible_match_with_dn/1, + search_extensible_match_without_dn/1, ssl_connection/1, start_tls_on_ssl_should_fail/1, start_tls_twice_should_fail/1, @@ -129,6 +131,8 @@ groups() -> search_filter_or, search_filter_and_not, search_two_hits, + search_extensible_match_with_dn, + search_extensible_match_without_dn, search_referral, search_filter_or_sizelimit_ok, search_filter_or_sizelimit_exceeded, @@ -722,6 +726,87 @@ search_two_hits(Config) -> [ok=eldap:delete(H,DN) || DN <- ExpectedDNs]. %%%---------------------------------------------------------------- +search_extensible_match_with_dn(Config) -> + H = proplists:get_value(handle, Config), + BasePath = proplists:get_value(eldap_path, Config), + + %% Create intermediate tree + OU1 = "o=Designers," ++ BasePath, + ok = eldap:add(H, OU1, [{"objectclass", ["top", "organization"]}, {"o", ["Designers"]}]), + OU2 = "o=Graphics," ++ BasePath, + ok = eldap:add(H, OU2, [{"objectclass", ["top", "organization"]}, {"o", ["Graphics"]}]), + + %% Add objects, they belongs to different trees + DN1 = "cn=Bob Noorda,o=Designers," ++ BasePath, + DN2 = "cn=Bob Noorda,o=Graphics," ++ BasePath, + ok = eldap:add(H, DN1, + [{"objectclass", ["person"]}, + {"cn", ["Bob Noorda"]}, + {"sn", ["Noorda"]}, + {"description", ["Amsterdam"]}]), + ok = eldap:add(H, DN2, + [{"objectclass", ["person"]}, + {"cn", ["Bob Noorda"]}, + {"sn", ["Noorda"]}, + {"description", ["Milan"]}]), + + %% Search using extensible filter only in Designers tree + Filter = eldap:'and'([ + eldap:extensibleMatch("Designers", [{type, "o"}, {dnAttributes, true}]), + eldap:equalityMatch("sn", "Noorda") + ]), + {ok, #eldap_search_result{entries=Es}} = + eldap:search(H, #eldap_search{base = BasePath, + filter = Filter, + scope=eldap:wholeSubtree()}), + + %% Check + [DN1] = [D || #eldap_entry{object_name=D} <- Es], + + %% Restore the database + [ok=eldap:delete(H,DN) || DN <- [DN1, DN2, OU1, OU2]]. + +%%%---------------------------------------------------------------- +search_extensible_match_without_dn(Config) -> + H = proplists:get_value(handle, Config), + BasePath = proplists:get_value(eldap_path, Config), + + %% Create intermediate tree + OU1 = "o=Teachers," ++ BasePath, + ok = eldap:add(H, OU1, [{"objectclass", ["top", "organization"]}, {"o", ["Teachers"]}]), + OU2 = "o=Designers," ++ BasePath, + ok = eldap:add(H, OU2, [{"objectclass", ["top", "organization"]}, {"o", ["Designers"]}]), + + %% Add objects, they belongs to different trees + DN1 = "cn=Max Huber,o=Teachers," ++ BasePath, + DN2 = "cn=Max Huber,o=Designers," ++ BasePath, + ok = eldap:add(H, DN1, + [{"objectclass", ["person"]}, + {"cn", ["Max Huber"]}, + {"sn", ["Huber"]}, + {"description", ["Baar"]}]), + ok = eldap:add(H, DN2, + [{"objectclass", ["person"]}, + {"cn", ["Max Huber"]}, + {"sn", ["Huber"]}, + {"description", ["Milan"]}]), + + %% Search using extensible filter without dn attribute + Filter = eldap:extensibleMatch("Huber", [{type, "sn"}]), + {ok, #eldap_search_result{entries=Es}} = + eldap:search(H, #eldap_search{base = BasePath, + filter = Filter, + scope = eldap:wholeSubtree() + }), + + %% And check that they are the expected ones: + ExpectedDNs = lists:sort([DN1, DN2]), + ExpectedDNs = lists:sort([D || #eldap_entry{object_name=D} <- Es]), + + %% Restore the database: + [ok=eldap:delete(H,DN) || DN <- [DN1, DN2, OU1, OU2]]. + +%%%---------------------------------------------------------------- search_referral(Config) -> H = proplists:get_value(handle, Config), BasePath = proplists:get_value(eldap_path, Config), diff --git a/lib/stdlib/doc/src/peer.xml b/lib/stdlib/doc/src/peer.xml index d67385157f..a5b513d810 100644 --- a/lib/stdlib/doc/src/peer.xml +++ b/lib/stdlib/doc/src/peer.xml @@ -31,7 +31,7 @@ <rev></rev> <file>peer.xml</file> </header> - <module since="OTP 25.0">peer</module> + <module since="OTP @OTP-17720@">peer</module> <modulesummary>Start and control linked Erlang nodes. </modulesummary> <description> @@ -384,8 +384,8 @@ <funcs> <func> - <name name="call" arity="4" since="OTP 25.0"/> - <name name="call" arity="5" since="OTP 25.0"/> + <name name="call" arity="4" since="OTP @OTP-17720@"/> + <name name="call" arity="5" since="OTP @OTP-17720@"/> <fsummary>Evaluates a function call on a peer node.</fsummary> <desc> <p> @@ -407,7 +407,7 @@ </func> <func> - <name name="cast" arity="4" since="OTP 25.0"/> + <name name="cast" arity="4" since="OTP @OTP-17720@"/> <fsummary>Evaluates a function call on a peer node ignoring the result.</fsummary> <desc> <p> @@ -425,7 +425,7 @@ </func> <func> - <name name="send" arity="3" since="OTP 25.0"/> + <name name="send" arity="3" since="OTP @OTP-17720@"/> <fsummary>Sends a message to a process on the peer node.</fsummary> <desc> <p> @@ -437,7 +437,7 @@ </func> <func> - <name name="get_state" arity="1" since="OTP 25.0"/> + <name name="get_state" arity="1" since="OTP @OTP-17720@"/> <fsummary>Returns peer node state.</fsummary> <desc> <p>Returns the peer node state. Th initial state is <c>booting</c>; the node stays in that @@ -448,7 +448,7 @@ </func> <func> - <name name="random_name" arity="0" since="OTP 25.0"/> + <name name="random_name" arity="0" since="OTP @OTP-17720@"/> <fsummary>Creates a sufficiently unique node name.</fsummary> <desc> <p> @@ -458,7 +458,7 @@ </func> <func> - <name name="random_name" arity="1" since="OTP 25.0"/> + <name name="random_name" arity="1" since="OTP @OTP-17720@"/> <fsummary>Creates a sufficiently unique node name given a prefix.</fsummary> <desc> <p> @@ -478,7 +478,7 @@ </func> <func> - <name name="start" arity="1" since="OTP 25.0"/> + <name name="start" arity="1" since="OTP @OTP-17720@"/> <fsummary>Starts a peer node.</fsummary> <desc> <p> @@ -491,7 +491,7 @@ </func> <func> - <name name="start_link" arity="0" since="OTP 25.0"/> + <name name="start_link" arity="0" since="OTP @OTP-17720@"/> <fsummary>Starts a peer node, and links controlling process to caller process.</fsummary> <desc> <p> @@ -502,7 +502,7 @@ </func> <func> - <name name="start_link" arity="1" since="OTP 25.0"/> + <name name="start_link" arity="1" since="OTP @OTP-17720@"/> <fsummary>Starts a peer node, and links controlling process to caller process.</fsummary> <desc> <p>Starts a peer node in the same way as <seemfa marker="#start/1"><c>start/1</c></seemfa>, @@ -523,7 +523,7 @@ </func> <func> - <name name="stop" arity="1" since="OTP 25.0"/> + <name name="stop" arity="1" since="OTP @OTP-17720@"/> <fsummary>Stop controlling process and terminate peer node.</fsummary> <desc> <p>Depending on the <c>shutdown</c> option used to start the peer, diff --git a/lib/stdlib/scripts/update_deprecations b/lib/stdlib/scripts/update_deprecations index ef6be3b5af..8d359da050 100755 --- a/lib/stdlib/scripts/update_deprecations +++ b/lib/stdlib/scripts/update_deprecations @@ -238,12 +238,10 @@ make_xml(Top, Type, OutFile, InfoText0) -> Collected = make_xml_collect(Depr, RelKey, InfoTextMap, []), All = make_xml_gen(lists:reverse(Collected), Type, OutDir), - file:write_file(OutFile, All), - - ok. + ok = file:write_file(OutFile, All). make_xml_info([{Tag,M,F,A,Text} | Attributes], Tag) -> - [{{M,F,A}, Text} | make_xml_info(Attributes, Tag)]; + [{{M,F,A}, info_string(Text)} | make_xml_info(Attributes, Tag)]; make_xml_info([_ | Attributes], Tag) -> make_xml_info(Attributes, Tag); make_xml_info([], _Tag) -> diff --git a/lib/stdlib/src/otp_internal.erl b/lib/stdlib/src/otp_internal.erl index fed37f3953..2332df5315 100644 --- a/lib/stdlib/src/otp_internal.erl +++ b/lib/stdlib/src/otp_internal.erl @@ -35,6 +35,10 @@ obsolete(code, is_module_native, 1) -> {deprecated, "HiPE has been removed", "OTP 26"}; obsolete(code, rehash, 0) -> {deprecated, "the code path cache feature has been removed", "OTP 26"}; +obsolete(crypto, crypto_dyn_iv_init, 3) -> + {deprecated, "see the documentation for details", "OTP 27"}; +obsolete(crypto, crypto_dyn_iv_update, 3) -> + {deprecated, "see the documentation for details", "OTP 27"}; obsolete(crypto, rand_uniform, 2) -> {deprecated, "use rand:uniform/1 instead"}; obsolete(disk_log, accessible_logs, 0) -> @@ -180,9 +184,9 @@ obsolete(erlang, hash, 2) -> obsolete(httpd_conf, check_enum, 2) -> {removed, "use lists:member/2 instead"}; obsolete(httpd_conf, clean, 1) -> - {removed, "use sting:strip/1 instead or possibly the re module"}; + {removed, "use string:strip/1 instead or possibly the re module"}; obsolete(httpd_conf, custom_clean, 3) -> - {removed, "use sting:strip/1 instead or possibly the re module"}; + {removed, "use string:strip/1 instead or possibly the re module"}; obsolete(httpd_conf, is_directory, 1) -> {removed, "use filelib:is_dir/1 instead"}; obsolete(httpd_conf, is_file, 1) -> @@ -221,14 +225,14 @@ obsolete(filename, find_src, _) -> {removed, "use filelib:find_source/1,3 instead"}; obsolete(ssl, ssl_accept, _) -> {removed, "use ssl_handshake/1,2,3 instead"}; +obsolete(ct_slave, _, _) -> + {deprecated, "use ?CT_PEER(), or the 'peer' module instead", "OTP 27"}; obsolete(gen_fsm, _, _) -> {deprecated, "use the 'gen_statem' module instead"}; obsolete(random, _, _) -> {deprecated, "use the 'rand' module instead"}; obsolete(slave, _, _) -> {deprecated, "use the 'peer' module instead", "OTP 27"}; -obsolete(ct_slave, _, _) -> - {deprecated, "use ?CT_PEER(), or the 'peer' module instead", "OTP 27"}; obsolete(os_mon_mib, _, _) -> {removed, "this module was removed in OTP 22.0"}; obsolete(pg2, _, _) -> |