<commit_before>#define STATIC_ERLANG_NIF 1

#include <assert.h>
#include <bsp.h>
#include <erl_nif.h>
#include <errno.h>
#include <fcntl.h>
#include <rtems.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>

#include <dev/i2c/i2c.h>
#include <erl_nif.h>

#include <bsp.h>
#if defined LIBBSP_ARM_IMX_BSP_H
#define GRISP_I2C_REGISTER(path, alias) i2c_bus_register_imx((path), (alias))
#endif

/* NIF interface declarations */
int i2c_load(ErlNifEnv *env, void **priv_data, ERL_NIF_TERM load_info);
int i2c_upgrade(ErlNifEnv *env, void **priv_data, void **old_priv_data,
                ERL_NIF_TERM load_info);

static ERL_NIF_TERM am_bus_open_failed;
static ERL_NIF_TERM am_error;
static ERL_NIF_TERM am_invalid_alias;
static ERL_NIF_TERM am_invalid_bus;
static ERL_NIF_TERM am_invalid_device_name;
static ERL_NIF_TERM am_invalid_message;
static ERL_NIF_TERM am_invalid_message_addr;
static ERL_NIF_TERM am_invalid_message_buf;
static ERL_NIF_TERM am_invalid_message_flags;
static ERL_NIF_TERM am_invalid_message_len;
static ERL_NIF_TERM am_invalid_message_list;
static ERL_NIF_TERM am_invalid_message_type;
static ERL_NIF_TERM am_ioctl_failed;
static ERL_NIF_TERM am_ok;
static ERL_NIF_TERM am_read;
static ERL_NIF_TERM am_register_failed;
static ERL_NIF_TERM am_reverse_failed;
static ERL_NIF_TERM am_write;

#define RAISE(msg)                                                             \
  enif_raise_exception(                                                        \
      env, enif_make_tuple2(env, am_error, enif_make_atom(env, msg)))
#define RAISE_TERM(type, term)                                                 \
  enif_raise_exception(env, enif_make_tuple3(env, am_error, type, term))
#define RAISE_STRERROR(msg)                                                    \
  RAISE_TERM(msg, enif_make_string(env, strerror(errno), ERL_NIF_LATIN1))

static ErlNifResourceType *i2c_data;

typedef struct {
  int fd;
} grisp_i2c_data;

static void i2c_data_dtor(ErlNifEnv *env, void *obj) {
  close(((grisp_i2c_data *)obj)->fd);
}

int i2c_load(ErlNifEnv *env, void **priv_data, ERL_NIF_TERM load_info) {
  i2c_data = enif_open_resource_type(env, NULL, "i2c_data",
                                     (ErlNifResourceDtor *)i2c_data_dtor,
                                     ERL_NIF_RT_CREATE, NULL);
  assert(i2c_data != NULL);

  am_bus_open_failed = enif_make_atom(env, "bus_open_failed");
  am_error = enif_make_atom(env, "error");
  am_invalid_alias = enif_make_atom(env, "invalid_alias");
  am_invalid_bus = enif_make_atom(env, "invalid_bus");
  am_invalid_device_name = enif_make_atom(env, "invalid_device_name");
  am_invalid_message = enif_make_atom(env, "invalid_message");
  am_invalid_message_addr = enif_make_atom(env, "invalid_message_addr");
  am_invalid_message_buf = enif_make_atom(env, "invalid_message_buf");
  am_invalid_message_flags = enif_make_atom(env, "invalid_message_flags");
  am_invalid_message_len = enif_make_atom(env, "invalid_message_len");
  am_invalid_message_list = enif_make_atom(env, "invalid_message_list");
  am_invalid_message_type = enif_make_atom(env, "invalid_message_type");
  am_ioctl_failed = enif_make_atom(env, "ioctl_failed");
  am_ok = enif_make_atom(env, "ok");
  am_read = enif_make_atom(env, "read");
  am_register_failed = enif_make_atom(env, "register_failed");
  am_reverse_failed = enif_make_atom(env, "reverse_failed");
  am_write = enif_make_atom(env, "write");

  return 0;
}

int i2c_upgrade(ErlNifEnv *env, void **priv_data, void **old_priv_data,
                ERL_NIF_TERM load_info) {
  return 0;
}

static ERL_NIF_TERM i2c_register_bus_nif(ErlNifEnv *env, int argc,
                                         const ERL_NIF_TERM argv[]) {
  ErlNifBinary bus, alias;
  int rv;

  if (!enif_inspect_iolist_as_binary(env, argv[0], &bus)) {
    return RAISE_TERM(am_invalid_device_name, argv[0]);
  }
  if (!enif_inspect_iolist_as_binary(env, argv[1], &alias)) {
    return RAISE_TERM(am_invalid_alias, argv[1]);
  }

  rv = i2c_bus_register_imx((char *)bus.data, (char *)alias.data);
  if (rv != 0) {
    return RAISE_STRERROR(am_register_failed);
  }

  return am_ok;
}

static ERL_NIF_TERM i2c_open_nif(ErlNifEnv *env, int argc,
                                 const ERL_NIF_TERM argv[]) {
  ERL_NIF_TERM ret;
  ErlNifBinary bus;
  grisp_i2c_data *data;

  if (!enif_inspect_iolist_as_binary(env, argv[0], &bus)) {
    return RAISE_TERM(am_invalid_bus, argv[0]);
  }

  data = enif_alloc_resource(i2c_data, sizeof(grisp_i2c_data));

  data->fd = open((char *)bus.data, O_RDWR);

  if (data->fd < 0) {
    return RAISE_STRERROR(am_bus_open_failed);
  }

  ret = enif_make_resource(env, data);
  enif_release_resource(data);
  return ret;
}

static ERL_NIF_TERM i2c_transfer_nif(ErlNifEnv *env, int argc,
                                     const ERL_NIF_TERM argv[]) {
  grisp_i2c_data *data;
  unsigned int nmsgs;
  int rv;
  ERL_NIF_TERM head, tail, list, resps, rev_resps, resp;
  int arity = -1;
  const ERL_NIF_TERM *elems;
  int i = 0;
  i2c_msg *msgs;
  unsigned int chip_addr, flags, len;
  ErlNifBinary buf;
  uint8_t *readbuf;

  if (!enif_get_resource(env, argv[0], i2c_data, (void **)&data)) {
    return RAISE_TERM(am_invalid_bus, argv[0]);
  }
  if (!enif_get_list_length(env, argv[1], &nmsgs)) {
    return RAISE_TERM(am_invalid_message_list, argv[1]);
  }
  if (nmsgs <= 0) {
    return enif_make_list(env, 0);
  }<commit_msg>Safe initialization of return value variable<commit_after>#define STATIC_ERLANG_NIF 1

#include <assert.h>
#include <bsp.h>
#include <erl_nif.h>
#include <errno.h>
#include <fcntl.h>
#include <rtems.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>

#include <dev/i2c/i2c.h>
#include <erl_nif.h>

#include <bsp.h>
#if defined LIBBSP_ARM_IMX_BSP_H
#define GRISP_I2C_REGISTER(path, alias) i2c_bus_register_imx((path), (alias))
#endif

/* NIF interface declarations */
int i2c_load(ErlNifEnv *env, void **priv_data, ERL_NIF_TERM load_info);
int i2c_upgrade(ErlNifEnv *env, void **priv_data, void **old_priv_data,
                ERL_NIF_TERM load_info);

static ERL_NIF_TERM am_bus_open_failed;
static ERL_NIF_TERM am_error;
static ERL_NIF_TERM am_invalid_alias;
static ERL_NIF_TERM am_invalid_bus;
static ERL_NIF_TERM am_invalid_device_name;
static ERL_NIF_TERM am_invalid_message;
static ERL_NIF_TERM am_invalid_message_addr;
static ERL_NIF_TERM am_invalid_message_buf;
static ERL_NIF_TERM am_invalid_message_flags;
static ERL_NIF_TERM am_invalid_message_len;
static ERL_NIF_TERM am_invalid_message_list;
static ERL_NIF_TERM am_invalid_message_type;
static ERL_NIF_TERM am_ioctl_failed;
static ERL_NIF_TERM am_ok;
static ERL_NIF_TERM am_read;
static ERL_NIF_TERM am_register_failed;
static ERL_NIF_TERM am_reverse_failed;
static ERL_NIF_TERM am_write;

#define RAISE(msg)                                                             \
  enif_raise_exception(                                                        \
      env, enif_make_tuple2(env, am_error, enif_make_atom(env, msg)))
#define RAISE_TERM(type, term)                                                 \
  enif_raise_exception(env, enif_make_tuple3(env, am_error, type, term))
#define RAISE_STRERROR(msg)                                                    \
  RAISE_TERM(msg, enif_make_string(env, strerror(errno), ERL_NIF_LATIN1))

static ErlNifResourceType *i2c_data;

typedef struct {
  int fd;
} grisp_i2c_data;

static void i2c_data_dtor(ErlNifEnv *env, void *obj) {
  close(((grisp_i2c_data *)obj)->fd);
}

int i2c_load(ErlNifEnv *env, void **priv_data, ERL_NIF_TERM load_info) {
  i2c_data = enif_open_resource_type(env, NULL, "i2c_data",
                                     (ErlNifResourceDtor *)i2c_data_dtor,
                                     ERL_NIF_RT_CREATE, NULL);
  assert(i2c_data != NULL);

  am_bus_open_failed = enif_make_atom(env, "bus_open_failed");
  am_error = enif_make_atom(env, "error");
  am_invalid_alias = enif_make_atom(env, "invalid_alias");
  am_invalid_bus = enif_make_atom(env, "invalid_bus");
  am_invalid_device_name = enif_make_atom(env, "invalid_device_name");
  am_invalid_message = enif_make_atom(env, "invalid_message");
  am_invalid_message_addr = enif_make_atom(env, "invalid_message_addr");
  am_invalid_message_buf = enif_make_atom(env, "invalid_message_buf");
  am_invalid_message_flags = enif_make_atom(env, "invalid_message_flags");
  am_invalid_message_len = enif_make_atom(env, "invalid_message_len");
  am_invalid_message_list = enif_make_atom(env, "invalid_message_list");
  am_invalid_message_type = enif_make_atom(env, "invalid_message_type");
  am_ioctl_failed = enif_make_atom(env, "ioctl_failed");
  am_ok = enif_make_atom(env, "ok");
  am_read = enif_make_atom(env, "read");
  am_register_failed = enif_make_atom(env, "register_failed");
  am_reverse_failed = enif_make_atom(env, "reverse_failed");
  am_write = enif_make_atom(env, "write");

  return 0;
}

int i2c_upgrade(ErlNifEnv *env, void **priv_data, void **old_priv_data,
                ERL_NIF_TERM load_info) {
  return 0;
}

static ERL_NIF_TERM i2c_register_bus_nif(ErlNifEnv *env, int argc,
                                         const ERL_NIF_TERM argv[]) {
  ErlNifBinary bus, alias;
  int rv = -1;

  if (!enif_inspect_iolist_as_binary(env, argv[0], &bus)) {
    return RAISE_TERM(am_invalid_device_name, argv[0]);
  }
  if (!enif_inspect_iolist_as_binary(env, argv[1], &alias)) {
    return RAISE_TERM(am_invalid_alias, argv[1]);
  }

  rv = i2c_bus_register_imx((char *)bus.data, (char *)alias.data);
  if (rv != 0) {
    return RAISE_STRERROR(am_register_failed);
  }

  return am_ok;
}

static ERL_NIF_TERM i2c_open_nif(ErlNifEnv *env, int argc,
                                 const ERL_NIF_TERM argv[]) {
  ERL_NIF_TERM ret;
  ErlNifBinary bus;
  grisp_i2c_data *data;

  if (!enif_inspect_iolist_as_binary(env, argv[0], &bus)) {
    return RAISE_TERM(am_invalid_bus, argv[0]);
  }

  data = enif_alloc_resource(i2c_data, sizeof(grisp_i2c_data));

  data->fd = open((char *)bus.data, O_RDWR);

  if (data->fd < 0) {
    return RAISE_STRERROR(am_bus_open_failed);
  }

  ret = enif_make_resource(env, data);
  enif_release_resource(data);
  return ret;
}

static ERL_NIF_TERM i2c_transfer_nif(ErlNifEnv *env, int argc,
                                     const ERL_NIF_TERM argv[]) {
  grisp_i2c_data *data;
  unsigned int nmsgs;
  int rv = -1;
  ERL_NIF_TERM head, tail, list, resps, rev_resps, resp;
  int arity = -1;
  const ERL_NIF_TERM *elems;
  int i = 0;
  i2c_msg *msgs;
  unsigned int chip_addr, flags, len;
  ErlNifBinary buf;
  uint8_t *readbuf;

  if (!enif_get_resource(env, argv[0], i2c_data, (void **)&data)) {
    return RAISE_TERM(am_invalid_bus, argv[0]);
  }
  if (!enif_get_list_length(env, argv[1], &nmsgs)) {
    return RAISE_TERM(am_invalid_message_list, argv[1]);
  }
  if (nmsgs <= 0) {
    return enif_make_list(env, 0);
  }
{'fraction_non_alphanumeric': 0.10504316219900045, 'fraction_numerical': 0.009086778736937756, 'mean_word_length': 3.966606498194946, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 28, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '927574', 'n_tokens_mistral': 4456, 'n_tokens_neox': 4364, 'n_words': 771}