aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--erts/doc/src/erl_nif.xml8
-rw-r--r--erts/emulator/beam/erl_nif.c10
-rw-r--r--erts/emulator/beam/erl_nif_api_funcs.h4
-rw-r--r--erts/emulator/test/nif_SUITE.erl12
-rw-r--r--erts/emulator/test/nif_SUITE_data/nif_SUITE.c33
5 files changed, 63 insertions, 4 deletions
diff --git a/erts/doc/src/erl_nif.xml b/erts/doc/src/erl_nif.xml
index 5ec844e2ad..dda6354c61 100644
--- a/erts/doc/src/erl_nif.xml
+++ b/erts/doc/src/erl_nif.xml
@@ -597,6 +597,14 @@ typedef enum {
<fsummary>Determine if a term is a reference</fsummary>
<desc><p>Return true if <c>term</c> is a reference.</p></desc>
</func>
+ <func><name><ret>int</ret><nametext>enif_is_tuple(ErlNifEnv* env, ERL_NIF_TERM term)</nametext></name>
+ <fsummary>Determine if a term is a tuple</fsummary>
+ <desc><p>Return true if <c>term</c> is a tuple.</p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_is_list(ErlNifEnv* env, ERL_NIF_TERM term)</nametext></name>
+ <fsummary>Determine if a term is a list</fsummary>
+ <desc><p>Return true if <c>term</c> is a list.</p></desc>
+ </func>
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_atom(ErlNifEnv* env, const char* name)</nametext></name>
<fsummary>Create an atom term</fsummary>
<desc><p>Create an atom term from the C-string <c>name</c>. Unlike other terms, atom
diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c
index cee4df72a2..a07aa2e81f 100644
--- a/erts/emulator/beam/erl_nif.c
+++ b/erts/emulator/beam/erl_nif.c
@@ -248,6 +248,16 @@ int enif_is_ref(ErlNifEnv* env, ERL_NIF_TERM term)
return is_ref(term);
}
+int enif_is_tuple(ErlNifEnv* env, ERL_NIF_TERM term)
+{
+ return is_tuple(term);
+}
+
+int enif_is_list(ErlNifEnv* env, ERL_NIF_TERM term)
+{
+ return is_list(term) || is_nil(term);
+}
+
static void aligned_binary_dtor(struct enif_tmp_obj_t* obj)
{
erts_free_aligned_binary_bytes_extra((byte*)obj,ERTS_ALC_T_TMP);
diff --git a/erts/emulator/beam/erl_nif_api_funcs.h b/erts/emulator/beam/erl_nif_api_funcs.h
index fe8d2664e1..1ef27c3df3 100644
--- a/erts/emulator/beam/erl_nif_api_funcs.h
+++ b/erts/emulator/beam/erl_nif_api_funcs.h
@@ -106,6 +106,8 @@ ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_resource,(ErlNifEnv*, void* obj));
ERL_NIF_API_FUNC_DECL(int,enif_get_resource,(ErlNifEnv*, ERL_NIF_TERM term, ErlNifResourceType* type, void** objp));
ERL_NIF_API_FUNC_DECL(unsigned,enif_sizeof_resource,(ErlNifEnv*, void* obj));
ERL_NIF_API_FUNC_DECL(unsigned char*,enif_make_new_binary,(ErlNifEnv*,unsigned size,ERL_NIF_TERM* termp));
+ERL_NIF_API_FUNC_DECL(int,enif_is_list,(ErlNifEnv*, ERL_NIF_TERM term));
+ERL_NIF_API_FUNC_DECL(int,enif_is_tuple,(ErlNifEnv*, ERL_NIF_TERM term));
/*
** Add last to keep compatibility on Windows!!!
@@ -198,6 +200,8 @@ ERL_NIF_API_FUNC_DECL(unsigned char*,enif_make_new_binary,(ErlNifEnv*,unsigned s
# define enif_get_resource ERL_NIF_API_FUNC_MACRO(enif_get_resource)
# define enif_sizeof_resource ERL_NIF_API_FUNC_MACRO(enif_sizeof_resource)
# define enif_make_new_binary ERL_NIF_API_FUNC_MACRO(enif_make_new_binary)
+# define enif_is_list ERL_NIF_API_FUNC_MACRO(enif_is_list)
+# define enif_is_tuple ERL_NIF_API_FUNC_MACRO(enif_is_tuple)
#endif
#ifndef enif_make_list1
diff --git a/erts/emulator/test/nif_SUITE.erl b/erts/emulator/test/nif_SUITE.erl
index 522caec8f1..36bcfe26cc 100644
--- a/erts/emulator/test/nif_SUITE.erl
+++ b/erts/emulator/test/nif_SUITE.erl
@@ -28,7 +28,7 @@
-export([all/1, fin_per_testcase/2, basic/1, reload/1, upgrade/1, heap_frag/1,
types/1, many_args/1, binaries/1, get_string/1, get_atom/1, api_macros/1,
from_array/1, iolist_as_binary/1, resource/1, resource_takeover/1,
- threading/1, neg/1]).
+ threading/1, neg/1, is_checks/1]).
-export([many_args_100/100]).
-define(nif_stub,nif_stub_error(?LINE)).
@@ -36,7 +36,7 @@
all(suite) ->
[basic, reload, upgrade, heap_frag, types, many_args, binaries, get_string,
get_atom, api_macros, from_array, iolist_as_binary, resource,
- resource_takeover, threading, neg].
+ resource_takeover, threading, neg, is_checks].
%%init_per_testcase(_Case, Config) ->
%% ?line Dog = ?t:timetrap(?t:seconds(60*60*24)),
@@ -759,7 +759,12 @@ neg(Config) when is_list(Config) ->
?line verify_tmpmem(TmpMem),
?line ok.
-
+is_checks(doc) -> ["Test all enif_is functions"];
+is_checks(Config) when is_list(Config) ->
+ ?line ensure_lib_loaded(Config, 1),
+ ?line ok = check_is(hejsan, <<19,98>>, make_ref(), ok, fun() -> ok end,
+ self(), hd(erlang:ports()), [], [1,9,9,8],
+ {hejsan, "hejsan", [$h,"ejs",<<"an">>]}).
ensure_lib_loaded(Config) ->
ensure_lib_loaded(Config, 1).
@@ -855,6 +860,7 @@ get_resource(_,_) -> ?nif_stub.
release_resource(_) -> ?nif_stub.
last_resource_dtor_call() -> ?nif_stub.
make_new_resource(_,_) -> ?nif_stub.
+check_is(_,_,_,_,_,_,_,_,_,_) -> ?nif_stub.
nif_stub_error(Line) ->
exit({nif_not_loaded,module,?MODULE,line,Line}).
diff --git a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
index 3ad4f93374..22d0d5a93b 100644
--- a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
+++ b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
@@ -630,6 +630,36 @@ static ERL_NIF_TERM release_resource(ErlNifEnv* env, int argc, const ERL_NIF_TER
return enif_make_atom(env,"ok");
}
+/*
+ * argv[0] an atom
+ * argv[1] a binary
+ * argv[2] a ref
+ * argv[3] 'ok'
+ * argv[4] a fun
+ * argv[5] a pid
+ * argv[6] a port
+ * argv[7] an empty list
+ * argv[8] a non-empty list
+ * argv[9] a tuple
+ */
+static ERL_NIF_TERM check_is(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ ERL_NIF_TERM ok_atom = enif_make_atom(env, "ok");
+
+ if (!enif_is_atom(env, argv[0])) return enif_make_badarg(env);
+ if (!enif_is_binary(env, argv[1])) return enif_make_badarg(env);
+ if (!enif_is_ref(env, argv[2])) return enif_make_badarg(env);
+ if (!enif_is_identical(env, argv[3], ok_atom)) return enif_make_badarg(env);
+ if (!enif_is_fun(env, argv[4])) return enif_make_badarg(env);
+ if (!enif_is_pid(env, argv[5])) return enif_make_badarg(env);
+ if (!enif_is_port(env, argv[6])) return enif_make_badarg(env);
+ if (!enif_is_empty_list(env, argv[7])) return enif_make_badarg(env);
+ if (!enif_is_list(env, argv[7])) return enif_make_badarg(env);
+ if (!enif_is_list(env, argv[8])) return enif_make_badarg(env);
+ if (!enif_is_tuple(env, argv[9])) return enif_make_badarg(env);
+
+ return ok_atom;
+}
static ErlNifFunc nif_funcs[] =
{
@@ -656,7 +686,8 @@ static ErlNifFunc nif_funcs[] =
{"get_resource", 2, get_resource},
{"release_resource", 1, release_resource},
{"last_resource_dtor_call", 0, last_resource_dtor_call},
- {"make_new_resource", 2, make_new_resource}
+ {"make_new_resource", 2, make_new_resource},
+ {"check_is", 10, check_is}
};