From eece23d7f6b225a6abc3807f9af44d1f742f7eee Mon Sep 17 00:00:00 2001 From: Lukas Larsson Date: Fri, 21 Apr 2017 14:50:43 +0200 Subject: erts: Polish off erlang:list_to_ref/1 --- erts/doc/src/erlang.xml | 18 ++++++++++++++++++ erts/preloaded/src/erlang.erl | 2 +- lib/compiler/src/erl_bifs.erl | 1 + lib/stdlib/src/erl_internal.erl | 1 + lib/tools/emacs/erlang.el | 1 + 5 files changed, 22 insertions(+), 1 deletion(-) diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml index cb2cdec606..a8836d3cbb 100644 --- a/erts/doc/src/erlang.xml +++ b/erts/doc/src/erlang.xml @@ -2498,6 +2498,24 @@ os_prompt% + + + Convert from text representation to a ref. + +

Returns a reference whose text representation is a + String, for example:

+
+> list_to_ref("#Ref<0.4192537678.4073193475.71181>").
+#Ref<0.4192537678.4073193475.71181>
+

Failure: badarg if String contains a bad + representation of a reference.

+ +

This BIF is intended for debugging and is not to be used + in application programs.

+
+
+
+ Convert a list to a tuple. diff --git a/erts/preloaded/src/erlang.erl b/erts/preloaded/src/erlang.erl index 888d2beee0..12b8afb53e 100644 --- a/erts/preloaded/src/erlang.erl +++ b/erts/preloaded/src/erlang.erl @@ -1161,7 +1161,7 @@ list_to_pid(_String) -> erlang:nif_error(undefined). %% list_to_ref/1 --spec erlang:list_to_ref(String) -> reference() when +-spec list_to_ref(String) -> reference() when String :: string(). list_to_ref(_String) -> erlang:nif_error(undefined). diff --git a/lib/compiler/src/erl_bifs.erl b/lib/compiler/src/erl_bifs.erl index d60f73d421..3ee789e2ab 100644 --- a/lib/compiler/src/erl_bifs.erl +++ b/lib/compiler/src/erl_bifs.erl @@ -108,6 +108,7 @@ is_pure(erlang, list_to_binary, 1) -> true; is_pure(erlang, list_to_float, 1) -> true; is_pure(erlang, list_to_integer, 1) -> true; is_pure(erlang, list_to_pid, 1) -> true; +is_pure(erlang, list_to_ref, 1) -> true; is_pure(erlang, list_to_tuple, 1) -> true; is_pure(erlang, max, 2) -> true; is_pure(erlang, min, 2) -> true; diff --git a/lib/stdlib/src/erl_internal.erl b/lib/stdlib/src/erl_internal.erl index 006e7946af..6bf4eea843 100644 --- a/lib/stdlib/src/erl_internal.erl +++ b/lib/stdlib/src/erl_internal.erl @@ -331,6 +331,7 @@ bif(list_to_float, 1) -> true; bif(list_to_integer, 1) -> true; bif(list_to_integer, 2) -> true; bif(list_to_pid, 1) -> true; +bif(list_to_ref, 1) -> true; bif(list_to_tuple, 1) -> true; bif(load_module, 2) -> true; bif(make_ref, 0) -> true; diff --git a/lib/tools/emacs/erlang.el b/lib/tools/emacs/erlang.el index 59b20c552e..8025f25b43 100644 --- a/lib/tools/emacs/erlang.el +++ b/lib/tools/emacs/erlang.el @@ -836,6 +836,7 @@ resulting regexp is surrounded by \\_< and \\_>." "list_to_float" "list_to_integer" "list_to_pid" + "list_to_ref" "list_to_tuple" "load_module" "make_ref" -- cgit v1.2.3 From ab048d66c59fa827bf4129fc95bec21488a931a4 Mon Sep 17 00:00:00 2001 From: Lukas Larsson Date: Fri, 21 Apr 2017 14:53:52 +0200 Subject: erts: Auto-import port_to_list for consistency Follow the same pattern as pid_to_list --- erts/preloaded/src/erlang.erl | 4 ++-- lib/compiler/src/erl_bifs.erl | 1 + lib/stdlib/src/erl_internal.erl | 2 ++ lib/tools/emacs/erlang.el | 4 ++-- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/erts/preloaded/src/erlang.erl b/erts/preloaded/src/erlang.erl index 12b8afb53e..31ea683ff1 100644 --- a/erts/preloaded/src/erlang.erl +++ b/erts/preloaded/src/erlang.erl @@ -1337,7 +1337,7 @@ pid_to_list(_Pid) -> erlang:nif_error(undefined). %% port_to_list/1 --spec erlang:port_to_list(Port) -> string() when +-spec port_to_list(Port) -> string() when Port :: port(). port_to_list(_Port) -> erlang:nif_error(undefined). @@ -1547,7 +1547,7 @@ read_timer(_TimerRef, _Options) -> erlang:nif_error(undefined). %% ref_to_list/1 --spec erlang:ref_to_list(Ref) -> string() when +-spec ref_to_list(Ref) -> string() when Ref :: reference(). ref_to_list(_Ref) -> erlang:nif_error(undefined). diff --git a/lib/compiler/src/erl_bifs.erl b/lib/compiler/src/erl_bifs.erl index 3ee789e2ab..2eff9b4efb 100644 --- a/lib/compiler/src/erl_bifs.erl +++ b/lib/compiler/src/erl_bifs.erl @@ -114,6 +114,7 @@ is_pure(erlang, max, 2) -> true; is_pure(erlang, min, 2) -> true; is_pure(erlang, phash, 2) -> false; is_pure(erlang, pid_to_list, 1) -> true; +is_pure(erlang, port_to_list, 1) -> true; is_pure(erlang, round, 1) -> true; is_pure(erlang, setelement, 3) -> true; is_pure(erlang, size, 1) -> true; diff --git a/lib/stdlib/src/erl_internal.erl b/lib/stdlib/src/erl_internal.erl index 6bf4eea843..11d02c0999 100644 --- a/lib/stdlib/src/erl_internal.erl +++ b/lib/stdlib/src/erl_internal.erl @@ -349,6 +349,7 @@ bif(nodes, 1) -> true; bif(now, 0) -> true; bif(open_port, 2) -> true; bif(pid_to_list, 1) -> true; +bif(port_to_list, 1) -> true; bif(port_close, 1) -> true; bif(port_command, 2) -> true; bif(port_command, 3) -> true; @@ -362,6 +363,7 @@ bif(process_info, 2) -> true; bif(processes, 0) -> true; bif(purge_module, 1) -> true; bif(put, 2) -> true; +bif(ref_to_list, 1) -> true; bif(register, 2) -> true; bif(registered, 0) -> true; bif(round, 1) -> true; diff --git a/lib/tools/emacs/erlang.el b/lib/tools/emacs/erlang.el index 8025f25b43..14c21d7dad 100644 --- a/lib/tools/emacs/erlang.el +++ b/lib/tools/emacs/erlang.el @@ -855,12 +855,14 @@ resulting regexp is surrounded by \\_< and \\_>." "port_command" "port_connect" "port_control" + "port_to_list" "pre_loaded" "process_flag" "process_info" "processes" "purge_module" "put" + "ref_to_list" "register" "registered" "round" @@ -968,14 +970,12 @@ resulting regexp is surrounded by \\_< and \\_>." "port_get_data" "port_info" "port_set_data" - "port_to_list" "ports" "posixtime_to_universaltime" "prepare_loading" "process_display" "raise" "read_timer" - "ref_to_list" "resume_process" "send" "send_after" -- cgit v1.2.3 From eec41eeed17682a4e1f8ca15d92a2b469f0c39b8 Mon Sep 17 00:00:00 2001 From: Lukas Larsson Date: Fri, 21 Apr 2017 14:54:33 +0200 Subject: erts: Add erlang:list_to_port/1 debug bif --- erts/doc/src/erlang.xml | 18 +++++++++ erts/emulator/beam/bif.c | 69 +++++++++++++++++++++++++++++++++++ erts/emulator/beam/bif.tab | 1 + erts/emulator/test/list_bif_SUITE.erl | 21 +++++++++-- erts/preloaded/src/erlang.erl | 8 +++- lib/compiler/src/erl_bifs.erl | 1 + lib/stdlib/src/erl_internal.erl | 1 + lib/tools/emacs/erlang.el | 1 + 8 files changed, 116 insertions(+), 4 deletions(-) diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml index a8836d3cbb..a26a695f2e 100644 --- a/erts/doc/src/erlang.xml +++ b/erts/doc/src/erlang.xml @@ -2498,6 +2498,24 @@ os_prompt% + + + Convert from text representation to a port. + +

Returns a port identifier whose text representation is a + String, for example:

+
+> list_to_port("#Port<0.4>").
+#Port<0.4>
+

Failure: badarg if String contains a bad + representation of a port identifier.

+ +

This BIF is intended for debugging and is not to be used + in application programs.

+
+
+
+ Convert from text representation to a ref. diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c index 214de3652f..d7a18e8d88 100644 --- a/erts/emulator/beam/bif.c +++ b/erts/emulator/beam/bif.c @@ -4254,6 +4254,75 @@ BIF_RETTYPE list_to_pid_1(BIF_ALIST_1) BIF_ERROR(BIF_P, BADARG); } +BIF_RETTYPE list_to_port_1(BIF_ALIST_1) +{ + /* + * A valid port identifier is on the format + * "#Port" where N is node and P is + * the port id. Both N and P are of type Uint32. + */ + Uint32 n, p; + char* cp; + int i; + DistEntry *dep = NULL; + char buf[6 /* #Port< */ + + (2)*(10 + 1) /* N.P> */ + + 1 /* \0 */]; + + /* walk down the list and create a C string */ + if ((i = intlist_to_buf(BIF_ARG_1, buf, sizeof(buf)-1)) < 0) + goto bad; + + buf[i] = '\0'; /* null terminal */ + + cp = &buf[0]; + if (strncmp("#Port<", cp, 6) != 0) + goto bad; + + cp += 6; /* strlen("#Port<") */ + + if (sscanf(cp, "%u.%u>", &n, &p) < 2) + goto bad; + + if (p > ERTS_MAX_PORT_NUMBER) + goto bad; + + dep = erts_channel_no_to_dist_entry(n); + + if (!dep) + goto bad; + + if(dep == erts_this_dist_entry) { + erts_deref_dist_entry(dep); + BIF_RET(make_internal_port(p)); + } + else { + ExternalThing *etp; + ErlNode *enp; + + if (is_nil(dep->cid)) + goto bad; + + enp = erts_find_or_insert_node(dep->sysname, dep->creation); + ASSERT(enp != erts_this_node); + + etp = (ExternalThing *) HAlloc(BIF_P, EXTERNAL_THING_HEAD_SIZE + 1); + etp->header = make_external_port_header(1); + etp->next = MSO(BIF_P).first; + etp->node = enp; + etp->data.ui[0] = p; + + MSO(BIF_P).first = (struct erl_off_heap_header*) etp; + erts_deref_dist_entry(dep); + BIF_RET(make_external_port(etp)); + } + + bad: + if (dep) + erts_deref_dist_entry(dep); + BIF_ERROR(BIF_P, BADARG); +} + BIF_RETTYPE list_to_ref_1(BIF_ALIST_1) { /* diff --git a/erts/emulator/beam/bif.tab b/erts/emulator/beam/bif.tab index 66e5dc2988..56d656a173 100644 --- a/erts/emulator/beam/bif.tab +++ b/erts/emulator/beam/bif.tab @@ -88,6 +88,7 @@ bif erlang:list_to_binary/1 bif erlang:list_to_float/1 bif erlang:list_to_integer/1 bif erlang:list_to_pid/1 +bif erlang:list_to_port/1 bif erlang:list_to_ref/1 bif erlang:list_to_tuple/1 bif erlang:loaded/0 diff --git a/erts/emulator/test/list_bif_SUITE.erl b/erts/emulator/test/list_bif_SUITE.erl index 514dd2f412..9e1e351cd2 100644 --- a/erts/emulator/test/list_bif_SUITE.erl +++ b/erts/emulator/test/list_bif_SUITE.erl @@ -23,7 +23,7 @@ -export([all/0, suite/0]). -export([hd_test/1,tl_test/1,t_length/1,t_list_to_pid/1, - t_list_to_float/1,t_list_to_integer/1]). + t_list_to_port/1,t_list_to_float/1,t_list_to_integer/1]). suite() -> @@ -32,7 +32,7 @@ suite() -> all() -> - [hd_test, tl_test, t_length, t_list_to_pid, + [hd_test, tl_test, t_length, t_list_to_pid, t_list_to_port, t_list_to_float, t_list_to_integer]. %% Tests list_to_integer and string:to_integer @@ -106,10 +106,25 @@ t_list_to_pid(Config) when is_list(Config) -> {'EXIT', {badarg, _}} -> ok; Res -> - ct:fail("list_to_pid/1 with incorrect arg succeeded.~nResult: ~p", [Res]) + ct:fail("list_to_pid/1 with incorrect arg succeeded.~n" + "Result: ~p", [Res]) end, ok. +%% Test list_to_port/1 with correct and incorrect arguments. + +t_list_to_port(Config) when is_list(Config) -> + Me = hd(erlang:ports()), + MyListedPid = port_to_list(Me), + Me = list_to_port(MyListedPid), + case catch list_to_port(id("Incorrect list")) of + {'EXIT', {badarg, _}} -> + ok; + Res -> + ct:fail("list_to_port/1 with incorrect arg succeeded.~n" + "Result: ~p", [Res]) + end, + ok. %% Test list_to_float/1 with correct and incorrect arguments. diff --git a/erts/preloaded/src/erlang.erl b/erts/preloaded/src/erlang.erl index 31ea683ff1..8499d40c9a 100644 --- a/erts/preloaded/src/erlang.erl +++ b/erts/preloaded/src/erlang.erl @@ -129,7 +129,7 @@ -export([list_to_atom/1, list_to_binary/1]). -export([list_to_bitstring/1, list_to_existing_atom/1, list_to_float/1]). -export([list_to_integer/1, list_to_integer/2]). --export([list_to_pid/1, list_to_ref/1, list_to_tuple/1, loaded/0]). +-export([list_to_pid/1, list_to_port/1, list_to_ref/1, list_to_tuple/1, loaded/0]). -export([localtime/0, make_ref/0]). -export([map_size/1, match_spec_test/3, md5/1, md5_final/1]). -export([md5_init/0, md5_update/2, module_loaded/1, monitor/2]). @@ -1159,6 +1159,12 @@ list_to_integer(_String,_Base) -> String :: string(). list_to_pid(_String) -> erlang:nif_error(undefined). + +%% list_to_port/1 +-spec list_to_port(String) -> port() when + String :: string(). +list_to_port(_String) -> + erlang:nif_error(undefined). %% list_to_ref/1 -spec list_to_ref(String) -> reference() when diff --git a/lib/compiler/src/erl_bifs.erl b/lib/compiler/src/erl_bifs.erl index 2eff9b4efb..b1f1db6fa3 100644 --- a/lib/compiler/src/erl_bifs.erl +++ b/lib/compiler/src/erl_bifs.erl @@ -108,6 +108,7 @@ is_pure(erlang, list_to_binary, 1) -> true; is_pure(erlang, list_to_float, 1) -> true; is_pure(erlang, list_to_integer, 1) -> true; is_pure(erlang, list_to_pid, 1) -> true; +is_pure(erlang, list_to_port, 1) -> true; is_pure(erlang, list_to_ref, 1) -> true; is_pure(erlang, list_to_tuple, 1) -> true; is_pure(erlang, max, 2) -> true; diff --git a/lib/stdlib/src/erl_internal.erl b/lib/stdlib/src/erl_internal.erl index 11d02c0999..9a1b17fdb7 100644 --- a/lib/stdlib/src/erl_internal.erl +++ b/lib/stdlib/src/erl_internal.erl @@ -331,6 +331,7 @@ bif(list_to_float, 1) -> true; bif(list_to_integer, 1) -> true; bif(list_to_integer, 2) -> true; bif(list_to_pid, 1) -> true; +bif(list_to_port, 1) -> true; bif(list_to_ref, 1) -> true; bif(list_to_tuple, 1) -> true; bif(load_module, 2) -> true; diff --git a/lib/tools/emacs/erlang.el b/lib/tools/emacs/erlang.el index 14c21d7dad..5dff4e6e2f 100644 --- a/lib/tools/emacs/erlang.el +++ b/lib/tools/emacs/erlang.el @@ -836,6 +836,7 @@ resulting regexp is surrounded by \\_< and \\_>." "list_to_float" "list_to_integer" "list_to_pid" + "list_to_port" "list_to_ref" "list_to_tuple" "load_module" -- cgit v1.2.3