static ERL_NIF_TERM format_error(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { unsigned len; int res; if (!enif_get_atom_length(env, argv[0], &len, ERL_NIF_LATIN1)) return enif_make_badarg(env); char *atom = malloc(len+1); if (!enif_get_atom(env, argv[0], atom, len+1, ERL_NIF_LATIN1)) { free(atom); return enif_make_badarg(env); } if (!strcmp("done", atom)) res = RS_DONE; else if (!strcmp("blocked", atom)) res = RS_BLOCKED; else if (!strcmp("running", atom)) res = RS_RUNNING; else if (!strcmp("test_skipped", atom)) res = RS_TEST_SKIPPED; else if (!strcmp("io_error", atom)) res = RS_IO_ERROR; else if (!strcmp("syntax_error", atom)) res = RS_SYNTAX_ERROR; else if (!strcmp("mem_error", atom)) res = RS_MEM_ERROR; else if (!strcmp("input_ended", atom)) res = RS_INPUT_ENDED; else if (!strcmp("bad_magic", atom)) res = RS_BAD_MAGIC; else if (!strcmp("unimplemented", atom)) res = RS_UNIMPLEMENTED; else if (!strcmp("corrupt", atom)) res = RS_CORRUPT; else if (!strcmp("internal_error", atom)) res = RS_INTERNAL_ERROR; else if (!strcmp("param_error", atom)) res = RS_PARAM_ERROR; else res = -1; free(atom); return enif_make_string(env, rs_strerror(res), ERL_NIF_LATIN1); }
static ERL_NIF_TERM ex_slp_open(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { char *lang; char *ret_code; int isasync; unsigned int term_len; SLPHandle *hslp; SLPEXP SLPError SLPAPI error; if (enif_get_atom_length(env, argv[0], &term_len, ERL_NIF_LATIN1) < 0) { return enif_make_badarg(env); } if (enif_get_atom(env, argv[0], lang, term_len, ERL_NIF_LATIN1) < 0) { return enif_make_badarg(env); } if ( ! enif_get_int(env, argv[1], &isasync)) return enif_make_badarg(env); hslp = enif_alloc_resource(NIF_SLP_HANDLE, sizeof(SLPHandle)); if (hslp == NULL) return enif_make_badarg(env); //error = SLPOpen(lang, isasync > 0 ? SLP_TRUE : SLP_FALSE, hslp); error = SLPOpen(lang, isasync > 0 ? SLP_TRUE : SLP_FALSE, hslp); ERL_NIF_TERM term = enif_make_resource(env, hslp); enif_release_resource(hslp); return enif_make_tuple2(env, enif_make_int(env, error), term); }
static char* alloc_atom(ErlNifEnv* env, const ERL_NIF_TERM atom, unsigned* len) { unsigned atom_len; if (!enif_get_atom_length(env, atom, &atom_len, ERL_NIF_LATIN1)) return NULL; atom_len++; *len = atom_len; return (char*)enif_alloc(atom_len); }
static void *TestCall(void *ptr) { TCall *call = (TCall *)ptr; ERL_NIF_TERM result = ErlangCall(call->env, call->fun, call->args); int length; char *buffer; enif_get_atom_length(call->env, result, &length, ERL_NIF_LATIN1); buffer = (char *)malloc((length + 1) * sizeof(char)); enif_get_atom(call->env, result, buffer, length + 1, ERL_NIF_LATIN1); printf("THIS IS YOUR RESULT(%d)! %s\n", length, buffer); return NULL; }
/* * argv[0] atom with length of 6 * argv[1] list with length of 6 * argv[2] empty list * argv[3] not an atom * argv[4] not a list */ static ERL_NIF_TERM length_test(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { unsigned len; if (!enif_get_atom_length(env, argv[0], &len, ERL_NIF_LATIN1) || len != 6) return enif_make_badarg(env); if (!enif_get_list_length(env, argv[1], &len) || len != 6) return enif_make_badarg(env); if (!enif_get_list_length(env, argv[2], &len) || len != 0) return enif_make_badarg(env); if (enif_get_atom_length(env, argv[3], &len, ERL_NIF_LATIN1)) return enif_make_badarg(env); if (enif_get_list_length(env, argv[4], &len)) return enif_make_badarg(env); return enif_make_atom(env, "ok"); }
/** * Erlang Wrapper for geonum_neighbor */ ERL_NIF_TERM erl_geonum_neighbor(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { long long bin_neighbor[1]; long long geonum; char dir[2]; int dir_val; unsigned int dir_len; if(!enif_get_int64(env, argv[0], &geonum)) { return enif_make_badarg(env); } if(!enif_get_atom_length(env, argv[1], &dir_len, ERL_NIF_LATIN1)) { return enif_make_badarg(env); } if(dir_len > sizeof(dir)) { return enif_make_badarg(env); } if(!enif_get_atom(env, argv[1], dir, sizeof(dir), ERL_NIF_LATIN1)) { return enif_make_badarg(env); } switch (dir[0]) { case 'w': dir_val = 0; break; case 'e': dir_val = 1; break; case 'n': dir_val = 2; break; case 's': dir_val = 3; break; default: return enif_make_badarg(env); } geonum_neighbor(geonum, dir_val, bin_neighbor); return make_ok(env, enif_make_int64(env, bin_neighbor[0])); }
static int atom_to_string(ErlNifEnv* env, ERL_NIF_TERM atom_term, char **bin_str) { unsigned atom_len; char *atom_string; *bin_str = NULL; if(!enif_is_atom(env, atom_term) || !enif_get_atom_length(env, atom_term, &atom_len, ERL_NIF_LATIN1)) return 0; if(!(atom_string = (char*)malloc(atom_len+1))) return 0; if(!enif_get_atom(env, atom_term, atom_string, atom_len+1, ERL_NIF_LATIN1)){ free(atom_string); return 0; } *bin_str = atom_string; return 1; }
char* fetch_string(ErlNifEnv* env, ERL_NIF_TERM* items) { ERL_NIF_TERM head; char* buffer; // Fetch head if possible if (! enif_get_list_cell(env, *items, &head, items)) { buffer = (char*) malloc(1); buffer[0] = 0; return buffer; } unsigned int bodylen = 0; // Try to fetch atom if (enif_get_atom_length(env, head, &bodylen, ERL_NIF_LATIN1)) { buffer = (char*) malloc(bodylen + 1); buffer[0] = 0; enif_get_atom(env, head, buffer, bodylen + 1, ERL_NIF_LATIN1); return buffer; } // If it is not atom, try to fetch iolist. Strings, deep lists, binaries should fit well here ErlNifBinary bin; if (enif_inspect_iolist_as_binary(env, head, &bin)) { bodylen = bin.size; buffer = (char*) malloc(bodylen + 1); memcpy(buffer, bin.data, bodylen); buffer[bodylen] = 0; return buffer; } // If we get here there is no string-like term in the head, so just allocate and return "\0" buffer = (char*) malloc(1); buffer[0] = 0; return buffer; };
static mrb_value erl2mruby(ErlNifEnv* env, mrb_state* mrb, ERL_NIF_TERM term) { if (enif_is_atom(env, term)) { unsigned len; enif_get_atom_length(env, term, &len, ERL_NIF_LATIN1); char * atom_str = (char *)malloc(sizeof(char)*(len+1)); int r = enif_get_atom(env, term, atom_str, len+1, ERL_NIF_LATIN1); mrb_value value; if(strncmp(atom_str, "nil", r) == 0){ value = mrb_nil_value(); }else if(strncmp(atom_str, "true", r) == 0){ value = mrb_true_value(); }else if(strncmp(atom_str, "false", r) == 0){ value = mrb_false_value(); }else{ value = mrb_symbol_value(mrb_intern_cstr(mrb, atom_str)); } free(atom_str); return value; } else if (enif_is_binary(env, term)) { ErlNifBinary bin; enif_inspect_binary(env, term, &bin); return mrb_str_new(mrb, (const char *)bin.data, bin.size); } else if (enif_is_number(env, term)) { double d; if (enif_get_double(env, term, &d)) { return mrb_float_value(mrb, (mrb_float)d); } else { ErlNifSInt64 i; enif_get_int64(env, term, &i); return mrb_fixnum_value((mrb_int)i); } } else if (enif_is_empty_list(env, term)) { return mrb_ary_new(mrb); } else if (enif_is_list(env, term)) { unsigned len; enif_get_list_length(env, term, &len); mrb_value ary = mrb_ary_new(mrb); ERL_NIF_TERM cur; for (cur = term; !enif_is_empty_list(env, cur); ) { ERL_NIF_TERM head, tail; enif_get_list_cell(env, cur, &head, &tail); mrb_ary_push(mrb, ary, erl2mruby(env, mrb, head)); cur = tail; } return ary; } else if (enif_is_tuple(env, term)) { int arity; const ERL_NIF_TERM * array; enif_get_tuple(env, term, &arity, &array); unsigned len = 0; enif_get_list_length(env, array[0], &len); mrb_value hash = mrb_hash_new(mrb); ERL_NIF_TERM cur; for(cur = array[0]; !enif_is_empty_list(env, cur); ){ ERL_NIF_TERM head, tail; enif_get_list_cell(env, cur, &head, &tail); const ERL_NIF_TERM * array0; int arity0; enif_get_tuple(env, head, &arity0, &array0); mrb_hash_set(mrb, hash, erl2mruby(env, mrb, array0[0]), erl2mruby(env, mrb, array0[1])); cur = tail; } return hash; } else { return mrb_nil_value(); } }
static void ks_selector_arg(ks_returner_t *ret, ks_pattern_t *pattern, ERL_NIF_TERM arg) { unsigned size; char *string; int result; ErlNifSInt64 integer; if (ret->ready != B_TRUE) { if (enif_is_atom(ret->env, arg)) { enif_get_atom_length(ret->env, arg, &size, ERL_NIF_LATIN1); string = (char *)(malloc(sizeof (char) * (size + 1))); if (string == NULL) { ret->term = EKSTAT_ERROR("atom malloc"); ret->ready = B_TRUE; return; } result = enif_get_atom(ret->env, arg, string, size + 1, ERL_NIF_LATIN1); if (result == 0) { ret->term = enif_make_badarg(ret->env); ret->ready = B_TRUE; } else { if (strncmp(string, "_", result) == 0) { pattern->pstr = "*"; pattern->free = B_FALSE; } else { ret->term = enif_make_badarg(ret->env); ret->ready = B_TRUE; } free(string); } } else if (enif_is_list(ret->env, arg)) { enif_get_list_length(ret->env, arg, &size); string = (char *)(malloc(sizeof (char) * (size + 1))); if (string == NULL) { ret->term = EKSTAT_ERROR("list malloc"); ret->ready = B_TRUE; return; } result = enif_get_string(ret->env, arg, string, size + 1, ERL_NIF_LATIN1); if (result == 0) { ret->term = enif_make_badarg(ret->env); ret->ready = B_TRUE; } else { pattern->pstr = (char *)(ks_safe_strdup(ret, string)); pattern->free = B_TRUE; } free(string); } else if (enif_is_number(ret->env, arg)) { if (enif_get_int64(ret->env, arg, &integer)) { (void) asprintf(&string, "%d", integer); pattern->pstr = (char *)(ks_safe_strdup(ret, string)); pattern->free = B_TRUE; } else { ret->term = enif_make_badarg(ret->env); ret->ready = B_TRUE; } free(string); } else { ret->term = enif_make_badarg(ret->env); ret->ready = B_TRUE; } } }