aboutsummaryrefslogtreecommitdiffstats
path: root/erts
diff options
context:
space:
mode:
authorLukas Larsson <[email protected]>2017-04-25 14:18:00 +0200
committerLukas Larsson <[email protected]>2017-04-25 14:18:00 +0200
commit483e3fb7b81e352944226b7d230e6a8685576982 (patch)
treeafb1e99b530c4d4ff52166ee0ed7f7b8cc466f8a /erts
parent8ca868848600702696828d729387343d73311a50 (diff)
parenteec41eeed17682a4e1f8ca15d92a2b469f0c39b8 (diff)
downloadotp-483e3fb7b81e352944226b7d230e6a8685576982.tar.gz
otp-483e3fb7b81e352944226b7d230e6a8685576982.tar.bz2
otp-483e3fb7b81e352944226b7d230e6a8685576982.zip
Merge branch 'lukas/erts/list_to_port/OTP-14348'
* lukas/erts/list_to_port/OTP-14348: erts: Add erlang:list_to_port/1 debug bif erts: Auto-import port_to_list for consistency erts: Polish off erlang:list_to_ref/1
Diffstat (limited to 'erts')
-rw-r--r--erts/doc/src/erlang.xml36
-rw-r--r--erts/emulator/beam/bif.c69
-rw-r--r--erts/emulator/beam/bif.tab1
-rw-r--r--erts/emulator/test/list_bif_SUITE.erl21
-rw-r--r--erts/preloaded/src/erlang.erl14
5 files changed, 134 insertions, 7 deletions
diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml
index cb2cdec606..a26a695f2e 100644
--- a/erts/doc/src/erlang.xml
+++ b/erts/doc/src/erlang.xml
@@ -2499,6 +2499,42 @@ os_prompt%</pre>
</func>
<func>
+ <name name="list_to_port" arity="1"/>
+ <fsummary>Convert from text representation to a port.</fsummary>
+ <desc>
+ <p>Returns a port identifier whose text representation is a
+ <c><anno>String</anno></c>, for example:</p>
+ <pre>
+> <input>list_to_port("#Port&lt;0.4>").</input>
+#Port&lt;0.4></pre>
+ <p>Failure: <c>badarg</c> if <c><anno>String</anno></c> contains a bad
+ representation of a port identifier.</p>
+ <warning>
+ <p>This BIF is intended for debugging and is not to be used
+ in application programs.</p>
+ </warning>
+ </desc>
+ </func>
+
+ <func>
+ <name name="list_to_ref" arity="1"/>
+ <fsummary>Convert from text representation to a ref.</fsummary>
+ <desc>
+ <p>Returns a reference whose text representation is a
+ <c><anno>String</anno></c>, for example:</p>
+ <pre>
+> <input>list_to_ref("#Ref&lt;0.4192537678.4073193475.71181>").</input>
+#Ref&lt;0.4192537678.4073193475.71181></pre>
+ <p>Failure: <c>badarg</c> if <c><anno>String</anno></c> contains a bad
+ representation of a reference.</p>
+ <warning>
+ <p>This BIF is intended for debugging and is not to be used
+ in application programs.</p>
+ </warning>
+ </desc>
+ </func>
+
+ <func>
<name name="list_to_tuple" arity="1"/>
<fsummary>Convert a list to a tuple.</fsummary>
<desc>
diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c
index 075909a881..84c9f9d7c4 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<N.P>" 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 5aee795088..3f6d82d65c 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 9c40929926..08574bff71 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 888d2beee0..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,9 +1159,15 @@ 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 erlang:list_to_ref(String) -> reference() when
+-spec list_to_ref(String) -> reference() when
String :: string().
list_to_ref(_String) ->
erlang:nif_error(undefined).
@@ -1337,7 +1343,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 +1553,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).