diff options
Diffstat (limited to 'lib/stdlib')
-rw-r--r-- | lib/stdlib/doc/src/gen_statem.xml | 12 | ||||
-rw-r--r-- | lib/stdlib/doc/src/maps.xml | 2 | ||||
-rw-r--r-- | lib/stdlib/doc/src/supervisor_bridge.xml | 8 | ||||
-rw-r--r-- | lib/stdlib/src/erl_lint.erl | 3 | ||||
-rw-r--r-- | lib/stdlib/src/erl_stdlib_errors.erl | 28 | ||||
-rw-r--r-- | lib/stdlib/src/gen_statem.erl | 41 | ||||
-rw-r--r-- | lib/stdlib/src/supervisor.erl | 6 | ||||
-rw-r--r-- | lib/stdlib/src/supervisor_bridge.erl | 5 | ||||
-rw-r--r-- | lib/stdlib/test/re_SUITE.erl | 24 | ||||
-rw-r--r-- | lib/stdlib/uc_spec/gen_unicode_mod.escript | 2 |
10 files changed, 91 insertions, 40 deletions
diff --git a/lib/stdlib/doc/src/gen_statem.xml b/lib/stdlib/doc/src/gen_statem.xml index c6790c1d48..2d64680412 100644 --- a/lib/stdlib/doc/src/gen_statem.xml +++ b/lib/stdlib/doc/src/gen_statem.xml @@ -1452,7 +1452,8 @@ handle_event(_, _, State, Data) -> </desc> </datatype> <datatype> - <name name="init_result"/> + <name name="init_result" n_vars="1"/> + <name name="init_result" n_vars="2"/> <desc> <p> For a succesful initialization, @@ -1479,7 +1480,8 @@ handle_event(_, _, State, Data) -> </desc> </datatype> <datatype> - <name name="state_enter_result"/> + <name name="state_enter_result" n_vars="1"/> + <name name="state_enter_result" n_vars="2"/> <desc> <p> <c><anno>State</anno></c> is the current state @@ -1502,7 +1504,8 @@ handle_event(_, _, State, Data) -> </desc> </datatype> <datatype> - <name name="event_handler_result"/> + <name name="event_handler_result" n_vars="1"/> + <name name="event_handler_result" n_vars="2"/> <desc> <p> <c><anno>StateType</anno></c> is @@ -1532,7 +1535,8 @@ handle_event(_, _, State, Data) -> </desc> </datatype> <datatype> - <name name="state_callback_result"/> + <name name="state_callback_result" n_vars="1"/> + <name name="state_callback_result" n_vars="2"/> <desc> <p> <c><anno>ActionType</anno></c> is diff --git a/lib/stdlib/doc/src/maps.xml b/lib/stdlib/doc/src/maps.xml index fdca524153..7c4fb9eaec 100644 --- a/lib/stdlib/doc/src/maps.xml +++ b/lib/stdlib/doc/src/maps.xml @@ -92,7 +92,7 @@ <p>The call fails with a <c>{badmap,Map}</c> exception if <c><anno>MapOrIter</anno></c> is not a map or valid iterator, or with <c>badarg</c> if <c><anno>Fun</anno></c> is not a - function of arity 3.</p> + function of arity 2.</p> <p><em>Example:</em></p> <code type="none"> > Fun = fun(K,V) when is_atom(K) -> {true, V*2}; (_,V) -> (V rem 2) =:= 0 end, diff --git a/lib/stdlib/doc/src/supervisor_bridge.xml b/lib/stdlib/doc/src/supervisor_bridge.xml index 97d0ae292a..97dac7cc07 100644 --- a/lib/stdlib/doc/src/supervisor_bridge.xml +++ b/lib/stdlib/doc/src/supervisor_bridge.xml @@ -72,16 +72,16 @@ <c><anno>Name</anno></c> using <c>register/2</c>.</p> </item> <item> - <p>If <c><anno>SupBridgeName</anno>={global,<anno>Name</anno>}</c>, + <p>If <c><anno>SupBridgeName</anno>={global,<anno>GlobalName</anno>}</c>, the supervisor bridge is registered globally as - <c><anno>Name</anno></c> using + <c><anno>GlobalName</anno></c> using <seemfa marker="kernel:global#register_name/2"> <c>global:register_name/2</c></seemfa>.</p> </item> <item> <p>If - <c><anno>SupBridgeName</anno>={via,<anno>Module</anno>,<anno>Name</anno>}</c>, - the supervisor bridge is registered as <c><anno>Name</anno></c> + <c><anno>SupBridgeName</anno>={via,<anno>Module</anno>,<anno>ViaName</anno>}</c>, + the supervisor bridge is registered as <c><anno>ViaName</anno></c> using a registry represented by <anno>Module</anno>. The <c>Module</c> callback is to export functions <c>register_name/2</c>, <c>unregister_name/1</c>, and <c>send/2</c>, diff --git a/lib/stdlib/src/erl_lint.erl b/lib/stdlib/src/erl_lint.erl index 7cafc9ce73..2eaf3d3d4a 100644 --- a/lib/stdlib/src/erl_lint.erl +++ b/lib/stdlib/src/erl_lint.erl @@ -2895,7 +2895,8 @@ type_def(Attr, Anno, TypeName, ProtoType, Args, St0) -> CheckType = {type, nowarn(), product, [ProtoType|Args]}, check_type(CheckType, St#lint{types=NewDefs}) end, - case is_default_type(TypePair) of + case is_default_type(TypePair) andalso + not member(no_auto_import_types, St0#lint.compile) of true -> case is_obsolete_builtin_type(TypePair) of true -> StoreType(St0); diff --git a/lib/stdlib/src/erl_stdlib_errors.erl b/lib/stdlib/src/erl_stdlib_errors.erl index 92518d058f..f9b1eb2126 100644 --- a/lib/stdlib/src/erl_stdlib_errors.erl +++ b/lib/stdlib/src/erl_stdlib_errors.erl @@ -296,7 +296,9 @@ format_re_error(compile, [_], _) -> [not_iodata]; format_re_error(compile, [Re, _Options], Cause) -> ReError = try re:compile(Re) of - _ -> [] + {ok, _} -> []; + {error, Reason} -> + {bad_regexp, Reason} catch _:_ -> not_iodata end, @@ -957,10 +959,21 @@ must_be_position(Pos) when is_integer(Pos) -> range; must_be_position(_) -> not_integer. must_be_regexp(Term) -> - try re:run("", Term) of - _ -> [] - catch - error:_ -> not_regexp + %% First check if we can compile the regexp as this + %% returns better error messages + try re:compile(Term) of + {ok, _} -> + []; + {error, Reason} -> + {bad_regexp, Reason} + catch error:_ -> + %% Then check if we can run it as this also allows + %% compiled reg exps + try re:run("", Term) of + _ -> [] + catch + error:_ -> not_regexp + end end. expand_error(already_owner) -> @@ -1052,6 +1065,11 @@ expand_error(not_pid) -> <<"not a pid">>; expand_error(not_regexp) -> <<"neither an iodata term nor a compiled regular expression">>; +expand_error({bad_regexp, {Reason,Column}}) -> + unicode:characters_to_binary( + io_lib:format("could not parse regular expression~n" + "~ts on character ~p", + [Reason, Column])); expand_error(not_tuple) -> <<"not a tuple">>; expand_error(not_tuple_or_list) -> diff --git a/lib/stdlib/src/gen_statem.erl b/lib/stdlib/src/gen_statem.erl index e91a24fd53..e206a826ea 100644 --- a/lib/stdlib/src/gen_statem.erl +++ b/lib/stdlib/src/gen_statem.erl @@ -63,8 +63,11 @@ from/0, callback_mode_result/0, init_result/1, + init_result/2, state_enter_result/1, + state_enter_result/2, event_handler_result/1, + event_handler_result/2, reply_action/0, enter_action/0, action/0 @@ -204,9 +207,10 @@ {'reply', % Reply to a caller From :: from(), Reply :: term()}. --type init_result(StateType) :: - {ok, State :: StateType, Data :: data()} | - {ok, State :: StateType, Data :: data(), +-type init_result(StateType) :: init_result(StateType, term()). +-type init_result(StateType, DataType) :: + {ok, State :: StateType, Data :: DataType} | + {ok, State :: StateType, Data :: DataType, Actions :: [action()] | action()} | 'ignore' | {'stop', Reason :: term()}. @@ -217,38 +221,43 @@ -type handle_event_result() :: event_handler_result(state()). %% --type state_enter_result(State) :: - {'next_state', % {next_state,NextState,NewData,[]} +-type state_enter_result(State) :: state_enter_result(State, term()). +-type state_enter_result(State, DataType) :: + {'next_state', % {next_state,State,NewData,[]} State, - NewData :: data()} | - {'next_state', % State transition, maybe to the same state + NewData :: DataType} | + {'next_state', % State entry for state State State, - NewData :: data(), + NewData :: DataType, Actions :: [enter_action()] | enter_action()} | state_callback_result(enter_action()). -type event_handler_result(StateType) :: + event_handler_result(StateType, term()). +-type event_handler_result(StateType, DataType) :: {'next_state', % {next_state,NextState,NewData,[]} NextState :: StateType, - NewData :: data()} | + NewData :: DataType} | {'next_state', % State transition, maybe to the same state NextState :: StateType, - NewData :: data(), + NewData :: DataType, Actions :: [action()] | action()} | state_callback_result(action()). -type state_callback_result(ActionType) :: + state_callback_result(ActionType, term()). +-type state_callback_result(ActionType, DataType) :: {'keep_state', % {keep_state,NewData,[]} - NewData :: data()} | + NewData :: DataType} | {'keep_state', % Keep state, change data - NewData :: data(), + NewData :: DataType, Actions :: [ActionType] | ActionType} | 'keep_state_and_data' | % {keep_state_and_data,[]} {'keep_state_and_data', % Keep state and data -> only actions Actions :: [ActionType] | ActionType} | %% {'repeat_state', % {repeat_state,NewData,[]} - NewData :: data()} | + NewData :: DataType} | {'repeat_state', % Repeat state, change data - NewData :: data(), + NewData :: DataType, Actions :: [ActionType] | ActionType} | 'repeat_state_and_data' | % {repeat_state_and_data,[]} {'repeat_state_and_data', % Repeat state and data -> only actions @@ -259,7 +268,7 @@ Reason :: term()} | {'stop', % Stop the server Reason :: term(), - NewData :: data()} | + NewData :: DataType} | %% {'stop_and_reply', % Reply then stop the server Reason :: term(), @@ -267,7 +276,7 @@ {'stop_and_reply', % Reply then stop the server Reason :: term(), Replies :: [reply_action()] | reply_action(), - NewData :: data()}. + NewData :: DataType}. -type request_id() :: term(). diff --git a/lib/stdlib/src/supervisor.erl b/lib/stdlib/src/supervisor.erl index 0d8b5a5ef4..7208068f4e 100644 --- a/lib/stdlib/src/supervisor.erl +++ b/lib/stdlib/src/supervisor.erl @@ -926,6 +926,8 @@ shutdown(#child{pid=Pid, shutdown=brutal_kill} = Child) -> case unlink_flush(Pid, Reason0) of killed -> ok; + shutdown when not (?is_permanent(Child)) -> + ok; {shutdown, _} when not (?is_permanent(Child)) -> ok; normal when not (?is_permanent(Child)) -> @@ -1041,6 +1043,10 @@ wait_dynamic_children(#child{shutdown=brutal_kill} = Child, Pids, Sz, wait_dynamic_children(Child, maps:remove({Pid, Mon}, Pids), Sz-1, TRef, EStack); + shutdown when not (?is_permanent(Child)) -> + wait_dynamic_children(Child, maps:remove({Pid, Mon}, Pids), + Sz-1, TRef, EStack); + {shutdown, _} when not (?is_permanent(Child)) -> wait_dynamic_children(Child, maps:remove({Pid, Mon}, Pids), Sz-1, TRef, EStack); diff --git a/lib/stdlib/src/supervisor_bridge.erl b/lib/stdlib/src/supervisor_bridge.erl index abbfb404a5..b796af30dc 100644 --- a/lib/stdlib/src/supervisor_bridge.erl +++ b/lib/stdlib/src/supervisor_bridge.erl @@ -64,8 +64,11 @@ start_link(Mod, StartArgs) -> gen_server:start_link(supervisor_bridge, [Mod, StartArgs, self], []). -spec start_link(SupBridgeName, Module, Args) -> Result when - SupBridgeName :: {local, Name} | {global, Name}, + SupBridgeName :: {local, Name} | {global, GlobalName} | + {via, Module, ViaName}, Name :: atom(), + GlobalName :: term(), + ViaName :: term(), Module :: module(), Args :: term(), Result :: {ok, Pid} | ignore | {error, Error}, diff --git a/lib/stdlib/test/re_SUITE.erl b/lib/stdlib/test/re_SUITE.erl index 5eef8ae48d..8e154cd829 100644 --- a/lib/stdlib/test/re_SUITE.erl +++ b/lib/stdlib/test/re_SUITE.erl @@ -1003,7 +1003,10 @@ bad_utf8_subject(Config) when is_list(Config) -> error_info(_Config) -> BadRegexp = {re_pattern,0,0,0,<<"xyz">>}, + BadErr = "neither an iodata term", {ok,GoodRegexp} = re:compile(".*"), + InvalidRegexp = <<"(.*))">>, + InvalidErr = "could not parse regular expression\n.*unmatched parentheses.*", L = [{compile, [not_iodata]}, {compile, [not_iodata, not_list],[{1,".*"},{2,".*"}]}, @@ -1021,28 +1024,35 @@ error_info(_Config) -> {internal_run, 4}, %Internal. {replace, [{a,b}, {x,y}, {z,z}],[{1,".*"},{2,".*"},{3,".*"}]}, - {replace, [{a,b}, BadRegexp, {z,z}],[{1,".*"},{2,".*"},{3,".*"}]}, + {replace, [{a,b}, BadRegexp, {z,z}],[{1,".*"},{2,BadErr},{3,".*"}]}, + {replace, [{a,b}, InvalidRegexp, {z,z}],[{1,".*"},{2,InvalidErr},{3,".*"}]}, {replace, [{a,b}, {x,y}, {z,z}, [a|b]],[{1,".*"},{2,".*"},{3,".*"},{4,".*"}]}, - {replace, [{a,b}, BadRegexp, [bad_option]],[{1,".*"},{2,".*"},{3,".*"}]}, + {replace, [{a,b}, BadRegexp, [bad_option]],[{1,".*"},{2,BadErr},{3,".*"}]}, + {replace, [{a,b}, InvalidRegexp, [bad_option]],[{1,".*"},{2,InvalidErr},{3,".*"}]}, {replace, ["", "", {z,z}, not_a_list],[{3,".*"},{4,".*"}]}, {run, [{a,b}, {x,y}],[{1,".*"},{2,".*"}]}, {run, [{a,b}, ".*"]}, {run, ["abc", {x,y}]}, - {run, ["abc", BadRegexp]}, + {run, ["abc", BadRegexp],[{2,BadErr}]}, + {run, ["abc", InvalidRegexp],[{2,InvalidErr}]}, {run, [{a,b}, {x,y}, []],[{1,".*"},{2,".*"}]}, - {run, ["abc", BadRegexp, []]}, + {run, ["abc", BadRegexp, []],[{2,BadErr}]}, + {run, ["abc", InvalidRegexp, []],[{2,InvalidErr}]}, {run, [{a,b}, {x,y}, [a|b]],[{1,".*"},{2,".*"},{3,".*"}]}, {run, [{a,b}, ".*", bad_options],[{1,".*"},{3,".*"}]}, {run, ["abc", {x,y}, [bad_option]],[{2,".*"},{3,".*"}]}, - {run, ["abc", BadRegexp, 9999],[{2,".*"},{3,".*"}]}, + {run, ["abc", BadRegexp, 9999],[{2,BadErr},{3,".*"}]}, + {run, ["abc", InvalidRegexp, 9999],[{2,InvalidErr},{3,".*"}]}, - {split, ["abc", BadRegexp]}, + {split, ["abc", BadRegexp],[{2,BadErr}]}, + {split, ["abc", InvalidRegexp],[{2,InvalidErr}]}, {split, [{a,b}, ".*"]}, - {split, ["abc", BadRegexp, [a|b]],[{2,".*"},{3,".*"}]}, + {split, ["abc", BadRegexp, [a|b]],[{2,BadErr},{3,".*"}]}, + {split, ["abc", InvalidRegexp, [a|b]],[{2,InvalidErr},{3,".*"}]}, {split, [{a,b}, ".*", [bad_option]]}, {ucompile, 2}, %Internal. diff --git a/lib/stdlib/uc_spec/gen_unicode_mod.escript b/lib/stdlib/uc_spec/gen_unicode_mod.escript index f7c13f0fab..22d21b903b 100644 --- a/lib/stdlib/uc_spec/gen_unicode_mod.escript +++ b/lib/stdlib/uc_spec/gen_unicode_mod.escript @@ -173,7 +173,7 @@ gen_header(Fd) -> io:put_chars(Fd, "-export([whitespace/0, is_whitespace/1]).\n"), io:put_chars(Fd, "-export([uppercase/1, lowercase/1, titlecase/1, casefold/1]).\n\n"), io:put_chars(Fd, "-export([spec_version/0, lookup/1, get_case/1]).\n"), - io:put_chars(Fd, "-inline([class/1]).\n"), + io:put_chars(Fd, "-compile({inline, [class/1]}).\n"), io:put_chars(Fd, "-compile(nowarn_unused_vars).\n"), io:put_chars(Fd, "-dialyzer({no_improper_lists, [cp/1, gc/1, gc_prepend/2]}).\n"), io:put_chars(Fd, "-type gc() :: char()|[char()].\n\n\n"), |