aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/c_src.mk
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2015-10-26 22:40:04 +0100
committerLoïc Hoguin <[email protected]>2015-10-26 22:40:04 +0100
commit9bd5ec4f4797f0c11df4e75f78b10208e1287c03 (patch)
tree21633adfaf469be73c01595a0c4f6787f3ac2873 /plugins/c_src.mk
parentd7b4e589f1716e2de5087a491ea1701d294dccbc (diff)
downloaderlang.mk-9bd5ec4f4797f0c11df4e75f78b10208e1287c03.tar.gz
erlang.mk-9bd5ec4f4797f0c11df4e75f78b10208e1287c03.tar.bz2
erlang.mk-9bd5ec4f4797f0c11df4e75f78b10208e1287c03.zip
Add new-nif target and related tests
Pushing this now so I can figure out Windows.
Diffstat (limited to 'plugins/c_src.mk')
-rw-r--r--plugins/c_src.mk95
1 files changed, 95 insertions, 0 deletions
diff --git a/plugins/c_src.mk b/plugins/c_src.mk
index a74d945..5cfdeef 100644
--- a/plugins/c_src.mk
+++ b/plugins/c_src.mk
@@ -115,3 +115,98 @@ distclean-c_src-env:
-include $(C_SRC_ENV)
endif
+
+# Templates.
+
+define bs_c_nif
+#include "erl_nif.h"
+
+static int loads = 0;
+
+static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
+{
+ /* Initialize private data. */
+ *priv_data = NULL;
+
+ loads++;
+
+ return 0;
+}
+
+static int upgrade(ErlNifEnv* env, void** priv_data, void** old_priv_data, ERL_NIF_TERM load_info)
+{
+ /* Convert the private data to the new version. */
+ *priv_data = *old_priv_data;
+
+ loads++;
+
+ return 0;
+}
+
+static void unload(ErlNifEnv* env, void* priv_data)
+{
+ if (loads == 1) {
+ /* Destroy the private data. */
+ }
+
+ loads--;
+}
+
+static ERL_NIF_TERM hello(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ if (enif_is_atom(env, argv[0])) {
+ return enif_make_tuple2(env,
+ enif_make_atom(env, "hello"),
+ argv[0]);
+ }
+
+ return enif_make_tuple2(env,
+ enif_make_atom(env, "error"),
+ enif_make_atom(env, "badarg"));
+}
+
+static ErlNifFunc nif_funcs[] = {
+ {"hello", 1, hello}
+};
+
+ERL_NIF_INIT($n, nif_funcs, load, NULL, upgrade, unload)
+endef
+
+define bs_erl_nif
+-module($n).
+
+-export([hello/1]).
+
+-on_load(on_load/0).
+on_load() ->
+ PrivDir = case code:priv_dir(?MODULE) of
+ {error, _} ->
+ AppPath = filename:dirname(filename:dirname(code:which(?MODULE))),
+ filename:join(AppPath, "priv");
+ Path ->
+ Path
+ end,
+ erlang:load_nif(filename:join(PrivDir, atom_to_list(?MODULE)), 0).
+
+hello(_) ->
+ erlang:nif_error({not_loaded, ?MODULE}).
+endef
+
+$(foreach template,bs_c_nif bs_erl_nif, \
+ $(eval _$(template) = $$(subst $$(tab),$$(WS),$$($(template)))) \
+ $(eval export _$(template)))
+
+new-nif:
+ifneq ($(wildcard $(C_SRC_DIR)/$n.c),)
+ $(error Error: $(C_SRC_DIR)/$n.c already exists)
+endif
+ifneq ($(wildcard src/$n.erl),)
+ $(error Error: src/$n.erl already exists)
+endif
+ifdef in
+ $(verbose) $(MAKE) -C $(APPS_DIR)/$(in)/ new-nif n=$n in=
+else
+ $(verbose) mkdir -p $(C_SRC_DIR) src/
+ $(call render_template,bs_c_nif,$(C_SRC_DIR)/$n.c)
+ $(call render_template,bs_erl_nif,src/$n.erl)
+endif