aboutsummaryrefslogtreecommitdiffstats
path: root/lib/erl_interface
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2019-05-21 09:02:00 +0200
committerBjörn Gustavsson <[email protected]>2019-05-29 16:31:06 +0200
commit5fef9df3faf0504c5c281a5720b992c19c94a6c2 (patch)
tree6722280600acf117b75148507b710eb28ee213e2 /lib/erl_interface
parent3d7b35dcc7852ec735f39a66566f80f8dad65701 (diff)
downloadotp-5fef9df3faf0504c5c281a5720b992c19c94a6c2.tar.gz
otp-5fef9df3faf0504c5c281a5720b992c19c94a6c2.tar.bz2
otp-5fef9df3faf0504c5c281a5720b992c19c94a6c2.zip
Teach ei_print_term() to print funs
Diffstat (limited to 'lib/erl_interface')
-rw-r--r--lib/erl_interface/src/misc/ei_printterm.c18
-rw-r--r--lib/erl_interface/test/ei_print_SUITE.erl15
-rw-r--r--lib/erl_interface/test/ei_print_SUITE_data/ei_print_test.c75
3 files changed, 97 insertions, 11 deletions
diff --git a/lib/erl_interface/src/misc/ei_printterm.c b/lib/erl_interface/src/misc/ei_printterm.c
index 52ab8cd504..a94d6e2ad8 100644
--- a/lib/erl_interface/src/misc/ei_printterm.c
+++ b/lib/erl_interface/src/misc/ei_printterm.c
@@ -121,6 +121,7 @@ static int print_term(FILE* fp, ei_x_buff* x,
erlang_pid pid;
erlang_port port;
erlang_ref ref;
+ erlang_fun fun;
double d;
long l;
@@ -329,6 +330,23 @@ static int print_term(FILE* fp, ei_x_buff* x,
*index = tindex;
xputc('}', fp, x); ch_written++;
break;
+ case ERL_FUN_EXT:
+ case ERL_NEW_FUN_EXT:
+ case ERL_EXPORT_EXT:
+ if (ei_decode_fun(buf, &tindex, &fun) < 0) goto err;
+ if (fun.type == EI_FUN_EXPORT) {
+ ch_written += xprintf(fp, x, "fun %s:%s/%ld",
+ fun.module,
+ fun.u.exprt.func,
+ fun.arity);
+ } else {
+ ch_written += xprintf(fp, x, "#Fun{%s.%ld.%lu}",
+ fun.module,
+ fun.u.closure.index,
+ fun.u.closure.uniq);
+ }
+ *index = tindex;
+ break;
default:
goto err;
}
diff --git a/lib/erl_interface/test/ei_print_SUITE.erl b/lib/erl_interface/test/ei_print_SUITE.erl
index 9d88a28102..f2a2548183 100644
--- a/lib/erl_interface/test/ei_print_SUITE.erl
+++ b/lib/erl_interface/test/ei_print_SUITE.erl
@@ -26,7 +26,8 @@
-export([all/0, suite/0,
init_per_testcase/2,
- atoms/1, tuples/1, lists/1, strings/1, maps/1]).
+ atoms/1, tuples/1, lists/1, strings/1,
+ maps/1, funs/1]).
-import(runner, [get_term/1]).
@@ -37,7 +38,7 @@ suite() ->
[{ct_hooks,[ts_install_cth]}].
all() ->
- [atoms, tuples, lists, strings, maps].
+ [atoms, tuples, lists, strings, maps, funs].
init_per_testcase(Case, Config) ->
runner:init_per_testcase(?MODULE, Case, Config).
@@ -152,3 +153,13 @@ maps(Config) ->
runner:recv_eot(P),
ok.
+
+funs(Config) ->
+ P = runner:start(Config, ?funs),
+
+ {term, "#Fun{some_module.42.3735928559}"} = get_term(P),
+ {term, "#Fun{some_module.37.195935983}"} = get_term(P),
+ {term, "fun erlang:abs/1"} = get_term(P),
+
+ runner:recv_eot(P),
+ ok.
diff --git a/lib/erl_interface/test/ei_print_SUITE_data/ei_print_test.c b/lib/erl_interface/test/ei_print_SUITE_data/ei_print_test.c
index 685596e34a..0e2b24e45a 100644
--- a/lib/erl_interface/test/ei_print_SUITE_data/ei_print_test.c
+++ b/lib/erl_interface/test/ei_print_SUITE_data/ei_print_test.c
@@ -49,15 +49,22 @@ send_printed_buf(ei_x_buff* x)
f = fopen(fn, "w+");
ei_decode_version(x->buff, &index, &ver);
n = ei_print_term(f, x->buff, &index);
- fseek(f, 0, SEEK_SET);
- b = malloc(n+1);
- fread(b, 1, n, f);
- b[n] = '\0';
- fclose(f);
- x->index = 0;
- ei_x_format(x, "~s", b);
- send_bin_term(x);
- free(b);
+ if (n < 0) {
+ fclose(f);
+ x->index = 0;
+ ei_x_format(x, "~s", "ERROR: term decoding failed");
+ send_bin_term(x);
+ } else {
+ fseek(f, 0, SEEK_SET);
+ b = malloc(n+1);
+ fread(b, 1, n, f);
+ b[n] = '\0';
+ fclose(f);
+ x->index = 0;
+ ei_x_format(x, "~s", b);
+ send_bin_term(x);
+ free(b);
+ }
}
@@ -231,3 +238,53 @@ TESTCASE(maps)
report(1);
}
+TESTCASE(funs)
+{
+ ei_x_buff x;
+ erlang_pid self;
+ erlang_fun fun;
+
+ strcpy(self.node, "node@host");
+ self.num = 9;
+ self.serial = 99;
+ self.creation = 1;
+
+ ei_init();
+
+ ei_x_new_with_version(&x);
+ fun.arity = -1; /* Will encode as FUN_EXT */
+ strcpy(fun.module, "some_module");
+ fun.type = EI_FUN_CLOSURE;
+ fun.u.closure.pid = self;
+ fun.u.closure.index = fun.u.closure.old_index = 42;
+ fun.u.closure.uniq = 0xDEADBEEF;
+ fun.u.closure.n_free_vars = 0;
+ fun.u.closure.free_var_len = 0;
+ ei_x_encode_fun(&x, &fun);
+ send_printed_buf(&x);
+ ei_x_free(&x);
+
+ ei_x_new_with_version(&x);
+ fun.arity = 0; /* Will encode as NEW_FUN_EXT */
+ strcpy(fun.module, "some_module");
+ fun.type = EI_FUN_CLOSURE;
+ fun.u.closure.pid = self;
+ fun.u.closure.index = fun.u.closure.old_index = 37;
+ fun.u.closure.uniq = 0xBADBEEF;
+ fun.u.closure.n_free_vars = 0;
+ fun.u.closure.free_var_len = 0;
+ ei_x_encode_fun(&x, &fun);
+ send_printed_buf(&x);
+ ei_x_free(&x);
+
+ ei_x_new_with_version(&x);
+ fun.arity = 1;
+ strcpy(fun.module, "erlang");
+ fun.type = EI_FUN_EXPORT;
+ fun.u.exprt.func = "abs";
+ ei_x_encode_fun(&x, &fun);
+ send_printed_buf(&x);
+ ei_x_free(&x);
+
+ report(1);
+}