static int on_load(ErlNifEnv *env, void **priv_data, ERL_NIF_TERM load_info) { gmperl_privdata_t *priv; priv = (gmperl_privdata_t *)enif_alloc(sizeof(gmperl_privdata_t)); priv->gmperl_mpz_rt = NULL; priv->gmperl_mpq_rt = NULL; priv->gmperl_mpf_rt = NULL; *priv_data = priv; /* Use Erlang NIF memory allocation/deallocation */ mp_set_memory_functions(gmperl_allocate, gmperl_reallocate, gmperl_free); /* Create resource types */ ErlNifResourceFlags flags = (ErlNifResourceFlags)(ERL_NIF_RT_CREATE | ERL_NIF_RT_TAKEOVER); priv->gmperl_mpz_rt = enif_open_resource_type(env, "gmperl_nifs", "gmperl_mpz_resource", gmperl_mpz_t_dtor, flags, NULL); priv->gmperl_mpq_rt = enif_open_resource_type(env, "gmperl_nifs", "gmperl_mpq_resource", gmperl_mpq_t_dtor, flags, NULL); priv->gmperl_mpf_rt = enif_open_resource_type(env, "gmperl_nifs", "gmperl_mpf_resource", gmperl_mpf_t_dtor, flags, NULL); if (!enif_make_existing_atom(env, "ok", &priv->atom_ok, ERL_NIF_LATIN1) || !enif_make_existing_atom(env, "true", &priv->atom_true, ERL_NIF_LATIN1) || !enif_make_existing_atom(env, "false", &priv->atom_false, ERL_NIF_LATIN1)) { return -1; } return 0; }
static ERL_NIF_TERM make_atoms(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { ERL_NIF_TERM arr[7]; ERL_NIF_TERM existingatom0a, existingatom0b; ERL_NIF_TERM existing0atom0; const char * const an0atom = "an0atom"; const char an0atom0[8] = {'a','n','\0','a','t','o','m',0}; arr[0] = enif_make_atom(env, "an0atom"); arr[1] = enif_make_atom_len(env, "an0atom", 7); arr[2] = enif_make_atom_len(env, an0atom, 7); arr[3] = enif_make_atom_len(env, an0atom0, 8); if (!enif_make_existing_atom(env, "an0atom", &existingatom0a, ERL_NIF_LATIN1)) return enif_make_atom(env, "error"); arr[4] = existingatom0a; if (!enif_make_existing_atom_len(env, an0atom, 7, &existingatom0b, ERL_NIF_LATIN1)) return enif_make_atom(env, "error"); arr[5] = existingatom0b; if (!enif_make_existing_atom_len(env, an0atom0, 8, &existing0atom0, ERL_NIF_LATIN1)) return enif_make_atom(env, "error"); arr[6] = existing0atom0; return enif_make_tuple7(env, arr[0],arr[1],arr[2],arr[3],arr[4],arr[5],arr[6]); }
static ERL_NIF_TERM make_term_existing_atom(struct make_term_info* mti, int n) { ERL_NIF_TERM res; int exist = enif_make_existing_atom(mti->dst_env, "nif_SUITE", &res, ERL_NIF_LATIN1); assert(exist); return res; }
ERL_NIF_TERM make_atom(ErlNifEnv* env, const char* name) { ERL_NIF_TERM ret; if(enif_make_existing_atom(env, name, &ret, ERL_NIF_LATIN1)) return ret; return enif_make_atom(env, name); }
ERL_NIF_TERM mk_atom(ErlNifEnv* env, const char* atom) { ERL_NIF_TERM ret; if(!enif_make_existing_atom(env, atom, &ret, ERL_NIF_LATIN1)) { return enif_make_atom(env, atom); } return ret; }
static ERL_NIF_TERM make_atom(ErlNifEnv *env, const char *atom_name) { ERL_NIF_TERM atom; if(enif_make_existing_atom(env, atom_name, &atom, ERL_NIF_LATIN1)) return atom; return enif_make_atom(env, atom_name); }
//-- static ERL_NIF_TERM erlang_produce_atom(ErlNifEnv* env, const char* name) { ERL_NIF_TERM ret; if(enif_make_existing_atom(env, name, &ret, ERL_NIF_LATIN1)) { return(ret); } return(enif_make_atom(env, name)); }
static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info){ PrivData *pdata = enif_alloc(sizeof(PrivData)); if(pdata == NULL) return 1; pdata->encoder_RSTYPE = enif_open_resource_type(env, NULL, "encoder_RSTYPE", enc_rt_dtor, ERL_NIF_RT_CREATE, NULL); if (pdata->encoder_RSTYPE == NULL) return 1; pdata->decoder_RSTYPE = enif_open_resource_type(env, NULL, "decoder_RSTYPE", NULL, ERL_NIF_RT_CREATE, NULL); if (pdata->decoder_RSTYPE == NULL) return 1; if(!enif_make_existing_atom(env, "true", &(pdata->am_true), ERL_NIF_LATIN1)) return 1; if(!enif_make_existing_atom(env, "false", &(pdata->am_false), ERL_NIF_LATIN1)) return 1; if(!enif_make_existing_atom(env, "null", &(pdata->am_null), ERL_NIF_LATIN1)) return 1; if(!enif_make_existing_atom(env, "error", &(pdata->am_error), ERL_NIF_LATIN1)) return 1; if(!enif_make_existing_atom(env, "big_num", &(pdata->am_erange), ERL_NIF_LATIN1)) return 1; if(!enif_make_existing_atom(env, "invalid_string", &(pdata->am_estr), ERL_NIF_LATIN1)) return 1; if(!enif_make_existing_atom(env, "invalid_json", &(pdata->am_esyntax), ERL_NIF_LATIN1)) return 1; if(!enif_make_existing_atom(env, "trailing_data", &(pdata->am_etrailing), ERL_NIF_LATIN1)) return 1; if(!enif_make_existing_atom(env, "undefined_record", &(pdata->am_undefined_record),ERL_NIF_LATIN1)) return 1; if(!enif_make_existing_atom(env, "json", &(pdata->am_json), ERL_NIF_LATIN1)) return 1; if(!enif_make_existing_atom(env, "struct", &(pdata->am_struct), ERL_NIF_LATIN1)) return 1; if(!enif_make_existing_atom(env, "proplist", &(pdata->am_proplist), ERL_NIF_LATIN1)) return 1; if(!enif_make_existing_atom(env, "eep18", &(pdata->am_eep18), ERL_NIF_LATIN1)) return 1; if(!enif_make_existing_atom(env, "no_match", &(pdata->am_no_match), ERL_NIF_LATIN1)) return 1; if(!enif_make_existing_atom(env, "decimal", &(pdata->am_decimal), ERL_NIF_LATIN1)) return 1; if(!enif_make_existing_atom(env, "float", &(pdata->am_float), ERL_NIF_LATIN1)) return 1; *priv_data = (void*)pdata; return 0; }
static ERL_NIF_TERM type_test(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { int i; int sint; unsigned uint; long slong; unsigned long ulong; ErlNifSInt64 sint64; ErlNifUInt64 uint64; double d; ERL_NIF_TERM atom, ref1, ref2; sint = INT_MIN; do { if (!test_int(env,sint)) { goto error; } sint += ~sint / 3 + 1; } while (sint < 0); sint = INT_MAX; do { if (!test_int(env,sint)) { goto error; } sint -= sint / 3 + 1; } while (sint >= 0); slong = LONG_MIN; do { if (!test_long(env,slong)) { goto error; } slong += ~slong / 3 + 1; } while (slong < 0); slong = LONG_MAX; do { if (!test_long(env,slong)) { goto error; } slong -= slong / 3 + 1; } while (slong >= 0); sint64 = ((ErlNifSInt64)1 << 63); /* INT64_MIN */ do { if (!test_int64(env,sint64)) { goto error; } sint64 += ~sint64 / 3 + 1; } while (sint64 < 0); sint64 = ((ErlNifUInt64)1 << 63) - 1; /* INT64_MAX */ do { if (!test_int64(env,sint64)) { goto error; } sint64 -= sint64 / 3 + 1; } while (sint64 >= 0); uint = UINT_MAX; for (;;) { if (!test_uint(env,uint)) { goto error; } if (uint == 0) break; uint -= uint / 3 + 1; } ulong = ULONG_MAX; for (;;) { if (!test_ulong(env,ulong)) { goto error; } if (ulong == 0) break; ulong -= ulong / 3 + 1; } uint64 = (ErlNifUInt64)-1; /* UINT64_MAX */ for (;;) { if (!test_uint64(env,uint64)) { goto error; } if (uint64 == 0) break; uint64 -= uint64 / 3 + 1; } if (MAX_SMALL < INT_MAX) { /* 32-bit */ for (i=-10 ; i <= 10; i++) { if (!test_int(env,MAX_SMALL+i)) { goto error; } } for (i=-10 ; i <= 10; i++) { if (!test_int(env,MIN_SMALL+i)) { goto error; } } for (i=-10 ; i <= 10; i++) { if (!test_uint(env,MAX_SMALL+i)) { goto error; } } } assert((MAX_SMALL < INT_MAX) == (MIN_SMALL > INT_MIN)); for (i=-10 ; i < 10; i++) { if (!test_long(env,MAX_SMALL+i) || !test_ulong(env,MAX_SMALL+i) || !test_long(env,MIN_SMALL+i) || !test_int64(env,MAX_SMALL+i) || !test_uint64(env,MAX_SMALL+i) || !test_int64(env,MIN_SMALL+i)) { goto error; } if (MAX_SMALL < INT_MAX) { if (!test_int(env,MAX_SMALL+i) || !test_uint(env,MAX_SMALL+i) || !test_int(env,MIN_SMALL+i)) { goto error; } } } for (d=3.141592e-100 ; d < 1e100 ; d *= 9.97) { if (!test_double(env,d) || !test_double(env,-d)) { goto error; } } if (!enif_make_existing_atom(env,"nif_SUITE", &atom, ERL_NIF_LATIN1) || !enif_is_identical(atom,enif_make_atom(env,"nif_SUITE"))) { fprintf(stderr, "nif_SUITE not an atom?\r\n"); goto error; } for (i=2; i; i--) { if (enif_make_existing_atom(env,"nif_SUITE_pink_unicorn", &atom, ERL_NIF_LATIN1)) { fprintf(stderr, "pink unicorn exist?\r\n"); goto error; } } ref1 = enif_make_ref(env); ref2 = enif_make_ref(env); if (!enif_is_ref(env,ref1) || !enif_is_ref(env,ref2) || enif_is_identical(ref1,ref2) || enif_compare(ref1,ref2)==0) { fprintf(stderr, "strange refs?\r\n"); goto error; } return enif_make_atom(env,"ok"); error: return enif_make_atom(env,"error"); }