From 5fef9df3faf0504c5c281a5720b992c19c94a6c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Tue, 21 May 2019 09:02:00 +0200 Subject: Teach ei_print_term() to print funs --- lib/erl_interface/src/misc/ei_printterm.c | 18 ++++++ lib/erl_interface/test/ei_print_SUITE.erl | 15 ++++- .../test/ei_print_SUITE_data/ei_print_test.c | 75 +++++++++++++++++++--- 3 files changed, 97 insertions(+), 11 deletions(-) (limited to 'lib') 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); +} -- cgit v1.2.3