Ejemplo n.º 1
0
static void _devio_destroy_smio (devio_t *self, uint32_t smio_id)
{
    assert (self);

    /* Stringify ID */
    char *key_c = halutils_stringify_key (smio_id);
    ASSERT_ALLOC (key_c, err_key_alloc);

    /* Lookup SMIO reference in hash table */
    void *pipe = zhash_lookup (self->sm_io_h, key_c);
    ASSERT_TEST (pipe != NULL, "Could not find SMIO registered with this ID",
            err_hash_lookup);

    /* Send message to SMIO informing it to destroy itself */
    /* This cannot fail at this point... but it can */
    zmsg_t *send_msg = zmsg_new ();
    ASSERT_ALLOC (send_msg, err_msg_alloc);
    /* An empty message means to selfdestruct */
    zmsg_pushstr (send_msg, "");
    int zerr = zmsg_send (&send_msg, pipe);
    ASSERT_TEST (zerr == 0, "Could not send self-destruct message to SMIO instance",
            err_send_msg);

    /* Finally, remove the pipe from hash */
    zhash_delete (self->sm_io_h, key_c);

err_send_msg:
    zmsg_destroy (&send_msg);
err_msg_alloc:
err_hash_lookup:
    free (key_c);
err_key_alloc:
    return;
}
Ejemplo n.º 2
0
/* Creates a new instance of the SMCH PCA9547 */
smch_pca9547_t * smch_pca9547_new (smio_t *parent, uint64_t base, uint32_t addr,
        int verbose)
{
    (void) verbose;
    assert (parent);

    smch_pca9547_t *self = (smch_pca9547_t *) zmalloc (sizeof *self);
    ASSERT_ALLOC(self, err_self_alloc);

    self->i2c = smpr_new (SMCH_PCA9547_NAME, parent, SMPR_I2C, verbose);
    ASSERT_ALLOC(self->i2c, err_i2c_alloc);

    /* Initalize the I2C protocol */
    int smpr_err = smpr_open (self->i2c, base, NULL /* Default parameters are fine */);
    ASSERT_TEST(smpr_err == 0, "Could not initialize SMPR protocol", err_smpr_init);

    self->addr = addr;

    DBE_DEBUG (DBG_SM_CH | DBG_LVL_INFO, "[sm_ch:pca9547] Created instance of SMCH\n");
    return self;

err_smpr_init:
    smpr_destroy (&self->i2c);
err_i2c_alloc:
    free (self);
err_self_alloc:
    return NULL;
}
Ejemplo n.º 3
0
/* Creates a new instance of the SMCH RFFE */
smch_rffe_t * smch_rffe_new (smio_t *parent, int verbose)
{
    (void) verbose;
    assert (parent);

    smch_rffe_t *self = (smch_rffe_t *) zmalloc (sizeof *self);
    ASSERT_ALLOC(self, err_self_alloc);

    self->bsmp = smpr_new (SMCH_RFFE_NAME, parent, SMPR_BSMP, verbose);
    ASSERT_ALLOC(self->bsmp, err_bsmp_alloc);

    /* Initalize the BSMP protocol */
    int smpr_err = smpr_open (self->bsmp, 0, NULL /* Default parameters are fine */);
    ASSERT_TEST(smpr_err == 0, "Could not initialize SMPR protocol", err_smpr_init);

    DBE_DEBUG (DBG_SM_CH | DBG_LVL_INFO, "[sm_ch:rffe] Created instance of SMCH\n");
    return self;

err_smpr_init:
    smpr_destroy (&self->bsmp);
err_bsmp_alloc:
    free (self);
err_self_alloc:
    return NULL;
}
smio_err_e fmc130m_4ch_init (smio_t * self)
{
    DBE_DEBUG (DBG_SM_IO | DBG_LVL_TRACE, "[sm_io:fmc130m_4ch_exp] Initializing fmc130m_4ch\n");

    smio_err_e err = SMIO_ERR_ALLOC;

    self->id = FMC130M_4CH_SDB_DEVID;
    self->name = strdup (FMC130M_4CH_SDB_NAME);
    ASSERT_ALLOC(self->name, err_name_alloc);

    /* Set SMIO ops pointers */
    self->ops = &fmc130m_4ch_ops;
    self->thsafe_client_ops = &smio_thsafe_client_zmq_ops;
    self->exp_ops = fmc130m_exp_ops;

    /* Initialize specific structure */
    self->smio_handler = smio_fmc130m_4ch_new (0);
    ASSERT_ALLOC(self->smio_handler, err_smio_handler_alloc);

    err = SMIO_SUCCESS;
    return err;

err_smio_handler_alloc:
    free (self->name);
err_name_alloc:
    return err;
}
Ejemplo n.º 5
0
static halutils_err_e _disp_table_insert (disp_table_t *self, uint32_t key,
        disp_table_func_fp func_fp)
{
    if (func_fp == NULL) {
        return HALUTILS_ERR_NULL_POINTER;
    }

    DBE_DEBUG (DBG_HAL_UTILS | DBG_LVL_TRACE,
            "[halutils:disp_table] Registering function (%p) opcode (%u) into dispatch table\n",
            func_fp, key);

    func_fp_wrapper_t *func_fp_wrapper = zmalloc (sizeof *func_fp_wrapper);
    ASSERT_ALLOC (func_fp_wrapper, err_func_wrapper_alloc);

    /* Initialize func_p_wrapper struct */
    func_fp_wrapper->func_fp = func_fp;

    char *key_c = halutils_stringify_key (key);
    ASSERT_ALLOC (key_c, err_key_c_alloc);
    int zerr = zhash_insert (self->table_h, key_c, func_fp_wrapper);
    ASSERT_TEST(zerr == 0, "Could not insert item into dispatch table", err_insert_hash);
    /* Setup free function */
    zhash_freefn (self->table_h, key_c, _disp_table_free_item);

    free (key_c);
    return HALUTILS_SUCCESS;

err_insert_hash:
    free (key_c);
err_key_c_alloc:
    free (func_fp_wrapper);
err_func_wrapper_alloc:
    return HALUTILS_ERR_ALLOC;
}
Ejemplo n.º 6
0
/* Creates a new instance of the dev_pcie */
static llio_dev_pcie_t * llio_dev_pcie_new (const char *dev_entry)
{
    llio_dev_pcie_t *self = (llio_dev_pcie_t *) zmalloc (sizeof *self);
    ASSERT_ALLOC (self, err_llio_dev_pcie_alloc);

    self->dev = (pd_device_t *) zmalloc (sizeof *self->dev);
    ASSERT_ALLOC (self->dev, err_dev_pcie_alloc);

    /* FIXME: hardcoded dev number */
    /* TODO: should we use llio_endpoint_get to get the endpoint name? */
    int err = pd_open (0, self->dev, dev_entry);

    if (err != 0) {
        perror ("pd_open");
    }
    ASSERT_TEST(err==0, "Error opening device", err_dev_pcie_open);

    /* Map all available BARs */
    self->bar0 = (uint32_t *) pd_mapBAR (self->dev, BAR0NO);
    ASSERT_TEST(self->bar0!=NULL, "Could not allocate bar0", err_bar0_alloc);
    self->bar2 = (uint32_t *) pd_mapBAR (self->dev, BAR2NO);
    ASSERT_TEST(self->bar2!=NULL, "Could not allocate bar2", err_bar2_alloc);
    DBE_DEBUG (DBG_LL_IO | DBG_LVL_TRACE, "[ll_io_pcie] BAR2 addr = %p\n",
            self->bar2);
    self->bar4 = (uint64_t *) pd_mapBAR (self->dev, BAR4NO);
    ASSERT_TEST(self->bar4!=NULL, "Could not allocate bar4", err_bar4_alloc);
    DBE_DEBUG (DBG_LL_IO | DBG_LVL_TRACE, "[ll_io_pcie] BAR4 addr = %p\n",
            self->bar4);

    self->bar0_size = pd_getBARsize (self->dev, BAR0NO);
    ASSERT_TEST(self->bar0_size > 0, "Could not get bar0 size", err_bar0_size);
    self->bar2_size = pd_getBARsize (self->dev, BAR2NO);
    ASSERT_TEST(self->bar2_size > 0, "Could not get bar2 size", err_bar2_size);
    self->bar4_size = pd_getBARsize (self->dev, BAR4NO);
    ASSERT_TEST(self->bar4_size > 0, "Could not get bar4 size", err_bar4_size);

    /* Initialize PCIE timeout pattern */
    memset (&pcie_timeout_patt, PCIE_TIMEOUT_PATT_INIT, sizeof (pcie_timeout_patt));
    DBE_DEBUG (DBG_LL_IO | DBG_LVL_TRACE, "[ll_io_pcie] Created instance of llio_dev_pcie\n");

    return self;

err_bar4_size:
err_bar2_size:
err_bar0_size:
    pd_unmapBAR (self->dev, BAR4NO, self->bar4);
err_bar4_alloc:
    pd_unmapBAR (self->dev, BAR2NO, self->bar2);
err_bar2_alloc:
    pd_unmapBAR (self->dev, BAR0NO, self->bar0);
err_bar0_alloc:
    pd_close (self->dev);
err_dev_pcie_open:
    free (self->dev);
err_dev_pcie_alloc:
    free (self);
err_llio_dev_pcie_alloc:
    return NULL;
}
Ejemplo n.º 7
0
static void _devio_destroy_smio_all (devio_t *self)
{
#if 0
    unsigned i;
    for (i = 0; i < self->nnodes; ++i) {
        /* This cannot fail at this point... but it can */
        zmsg_t *msg = zmsg_new ();
        /* An empty message means to selfdestruct */
        zmsg_pushstr (msg, "");
        zmsg_send (&msg, self->pipes [i]);
    }
#endif
    /* Get all hash keys */
    zlist_t *hash_keys = zhash_keys (self->sm_io_h);
    ASSERT_ALLOC (hash_keys, err_hash_keys_alloc);
    char *hash_item = zlist_first (hash_keys);

    /* Iterate over all keys removing each of one */
    for (; hash_item != NULL; hash_item = zlist_next (hash_keys)) {
        /* FIXME: Usage of stroul fucntion for reconverting the string
         * into a uint32_t */
        _devio_destroy_smio (self, (uint32_t) strtoul (hash_item,
                    (char **) NULL, 16));
    }

    zlist_destroy (&hash_keys);

err_hash_keys_alloc:
    return;
}
Ejemplo n.º 8
0
/* TODO: Avoid exporting the functions before we have initialized
 * our server with the default values */
smio_err_e trigger_iface_config_defaults (char *broker_endp, char *service,
       const char *log_file_name)
{
    (void) log_file_name;
    DBE_DEBUG (DBG_SM_IO | DBG_LVL_INFO, "[sm_io:trigger_iface_defaults] Configuring SMIO "
            "TRIGGER_IFACE with default values ...\n");
    bpm_client_err_e client_err = BPM_CLIENT_SUCCESS;
    smio_err_e err = SMIO_SUCCESS;

    bpm_client_t *config_client = bpm_client_new_log_mode (broker_endp, 0,
            log_file_name, SMIO_TRIGGER_IFACE_LIBBPMCLIENT_LOG_MODE);
    ASSERT_ALLOC(config_client, err_alloc_client);

    uint32_t chan;
    for (chan = 0; chan < SMIO_TRIGGER_IFACE_MAX_CHAN; ++chan) {
        client_err = bpm_set_trigger_dir (config_client, service, chan, TRIGGER_IFACE_DFLT_DIR);
        client_err |= bpm_set_trigger_dir_pol (config_client, service, chan, TRIGGER_IFACE_DFLT_DIR_POL);
        client_err |= bpm_set_trigger_rcv_count_rst (config_client, service, chan, TRIGGER_IFACE_DFLT_RCV_RST);
        client_err |= bpm_set_trigger_transm_count_rst (config_client, service, chan, TRIGGER_IFACE_DFLT_TRANSM_RST);
        client_err |= bpm_set_trigger_rcv_len (config_client, service, chan, TRIGGER_IFACE_DFLT_RCV_LEN);
        client_err |= bpm_set_trigger_transm_len (config_client, service, chan, TRIGGER_IFACE_DFLT_TRANSM_LEN);
    }

    ASSERT_TEST(client_err == BPM_CLIENT_SUCCESS, "Could set trigger defaults",
            err_param_set, SMIO_ERR_CONFIG_DFLT);

err_param_set:
    bpm_client_destroy (&config_client);
err_alloc_client:
    DBE_DEBUG (DBG_SM_IO | DBG_LVL_INFO, "[sm_io:trigger_iface_defaults] Exiting Config thread %s\n",
        service);
    return err;
}
Ejemplo n.º 9
0
Archivo: bs.c Proyecto: MSch/MacRuby
static inline const char *
_bs_main_bundle_bs_path(void)
{
  static bool done = false;
  static char *path = NULL;
  /* XXX not thread-safe */
  if (!done) {
    CFBundleRef bundle;

    done = true;
    bundle = CFBundleGetMainBundle();
    if (bundle != NULL) {
      CFURLRef url;

      url = CFBundleCopyResourceURL(bundle, CFSTR("BridgeSupport"), 
                                    NULL, NULL);
      if (url != NULL) {
        CFStringRef str = CFURLCopyPath(url);
        path = (char *)malloc(sizeof(char) * PATH_MAX);
	ASSERT_ALLOC(path);
        CFStringGetFileSystemRepresentation(str, path, PATH_MAX);
        CFRelease(str);
        CFRelease(url);
      }
    }
  }
  return path;
}
Ejemplo n.º 10
0
Archivo: bs.c Proyecto: MSch/MacRuby
static inline char *
get_framework_name(const char *path)
{
  char *base;
  char *name;
  char *p;
  
  base = basename((char *)path);
  if (base == NULL)
    return NULL;
    
  p = strrchr(base, '.');
  if (p == NULL)
    return NULL;

  if (strcmp(p + 1, "framework") != 0)
    return NULL;
  
  assert(p - base > 0);
  
  name = (char *)malloc(p - base + 1);
  ASSERT_ALLOC(name);
  strncpy(name, base, p - base);
  name[p - base] = '\0';

  return name;
}
Ejemplo n.º 11
0
disp_table_t *disp_table_new (void)
{
    disp_table_t *self = zmalloc (sizeof *self);
    ASSERT_ALLOC (self, err_self_alloc);
    self->table_h = zhash_new ();
    ASSERT_ALLOC (self->table_h, err_table_h_alloc);
    /* Only work for strings
    zhash_autofree (self->table_h);*/

    return self;

err_table_h_alloc:
    free (self);
err_self_alloc:
    return NULL;
}
static ssize_t _thsafe_zmq_client_read_generic (smio_t *self, loff_t offs, uint8_t *data,
        uint32_t size)
{
    assert (self);
    ssize_t ret_size = -1;
    zmsg_t *send_msg = zmsg_new ();
    ASSERT_ALLOC(send_msg, err_msg_alloc);
    uint32_t opcode;

    DBE_DEBUG (DBG_MSG | DBG_LVL_TRACE, "[smio_thsafe_client:zmq] Calling _thsafe_read_generic\n");

    switch (size) {
        case THSAFE_READ_16_DSIZE:
            opcode = THSAFE_READ_16;
        break;

        case THSAFE_READ_32_DSIZE:
            opcode = THSAFE_READ_32;
        break;

        case THSAFE_READ_64_DSIZE:
            opcode = THSAFE_READ_64;
        break;

        default:
            opcode = THSAFE_READ_32;
    }

    /* Message is:
     * frame 0: READ<size> opcode
     * frame 1: offset */
    int zerr = zmsg_addmem (send_msg, &opcode, sizeof (opcode));
    ASSERT_TEST(zerr == 0, "Could not add READ opcode in message",
            err_add_opcode);
    zerr = zmsg_addmem (send_msg, &offs, sizeof (offs));
    ASSERT_TEST(zerr == 0, "Could not add offset in message",
            err_add_offset);

    DBE_DEBUG (DBG_MSG | DBG_LVL_TRACE, "[smio_thsafe_client:zmq] Sending message:\n");
#ifdef LOCAL_MSG_DBG
    zmsg_print (send_msg);
#endif

    zerr = zmsg_send (&send_msg, self->pipe);
    ASSERT_TEST(zerr == 0, "Could not send message", err_send_msg);

    /* Message is:
     * frame 0: reply code
     * frame 1: return code
     * frame 2: data */
    ret_size = _thsafe_zmq_client_recv_read (self, data, size);

err_send_msg:
err_add_offset:
err_add_opcode:
    zmsg_destroy (&send_msg);
err_msg_alloc:
    return ret_size;
}
Ejemplo n.º 13
0
void *disp_table_call (disp_table_t *self, uint32_t key, void *owner, void *args)
{
    char *key_c = halutils_stringify_key (key);
    ASSERT_ALLOC (key_c, err_key_c_alloc);
    func_fp_wrapper_t *func_fp_wrapper = zhash_lookup (self->table_h, key_c);
    ASSERT_ALLOC (func_fp_wrapper, err_func_p_wrapper_null);

    free (key_c);

    /* DBE_DEBUG (DBG_HAL_UTILS | DBG_LVL_TRACE,
            "[halutils:disp_table] Calling function (key = %u, addr = %p) from dispatch table\n",
            key, func_fp_wrapper->func_fp); */
    /* The function pointer is never NULL */
    return func_fp_wrapper->func_fp (owner, args);

err_func_p_wrapper_null:
    free (key_c);
err_key_c_alloc:
    return NULL;
}
Ejemplo n.º 14
0
/* Creates a new instance of Device Information */
llio_dev_info_t * llio_dev_info_new ()
{
    llio_dev_info_t *self = (llio_dev_info_t *) zmalloc (sizeof *self);
    ASSERT_ALLOC(self, err_self_alloc);

    /* Initilialize llio_dev_info */
    /* Put some default values as these are going to be filled
       later by read_dev_info() */
    self->sdb_addr = 0x0;
    self->parsed = false;
    self->sdb = zlist_new (); /* HASH!? */
    ASSERT_ALLOC(self->sdb, err_sdb_alloc);

    return self;

err_sdb_alloc:
    free (self);
err_self_alloc:
    return NULL;
}
Ejemplo n.º 15
0
Archivo: bs.c Proyecto: MSch/MacRuby
bs_parser_t *
bs_parser_new(void)
{
  struct _bs_parser *parser;

  parser = (struct _bs_parser *)malloc(sizeof(struct _bs_parser));
  ASSERT_ALLOC(parser);
  parser->loaded_paths = 
    CFArrayCreateMutable(kCFAllocatorMalloc, 0, &kCFTypeArrayCallBacks);

  return parser;
}
Ejemplo n.º 16
0
DefineFunction(Array, void, enlarge, size_t min_count)
{
    if (this->m_size >= min_count)
        return;

    this->m_size = min_count * 15 / 10;
    if (this->m_size < min_count)
        this->m_size = min_count;

    this->m_elements = realloc(this->m_elements, this->m_size * sizeof(this->m_elements[0]));
    ASSERT_ALLOC(this->m_elements);
}
Ejemplo n.º 17
0
/* Creates a new instance of Device Information */
smio_trigger_mux_t * smio_trigger_mux_new (smio_t *parent)
{
    (void) parent;

    smio_trigger_mux_t *self = (smio_trigger_mux_t *) zmalloc (sizeof *self);
    ASSERT_ALLOC(self, err_self_alloc);

    return self;

err_self_alloc:
    return NULL;
}
Ejemplo n.º 18
0
halutils_err_e disp_table_remove (disp_table_t *self, uint32_t key)
{
    char *key_c = halutils_stringify_key (key);
    ASSERT_ALLOC (key_c, err_key_c_alloc);

    DBE_DEBUG (DBG_HAL_UTILS | DBG_LVL_TRACE,
        "[halutils:disp_table] Removing function (key = %u) into dispatch table\n",
        key);
    /* This will trigger the free fucntion previously registered */
    zhash_delete (self->table_h, key_c);

    free (key_c);
    return HALUTILS_SUCCESS;

err_key_c_alloc:
    return HALUTILS_ERR_ALLOC;
}
/**** Read data block from device function pointer, size in bytes ****/
ssize_t thsafe_zmq_client_read_block (smio_t *self, loff_t offs, size_t size, uint32_t *data)
{
    assert (self);
    ssize_t ret_size = -1;
    zmsg_t *send_msg = zmsg_new ();
    ASSERT_ALLOC(send_msg, err_msg_alloc);
    uint32_t opcode = THSAFE_READ_BLOCK;

    DBE_DEBUG (DBG_MSG | DBG_LVL_TRACE, "[smio_thsafe_client:zmq] Calling thsafe_read_block\n");

    /* Message is:
     * frame 0: READ_BLOCK opcode
     * frame 1: offset
     * frame 2: number of bytes to be read */
    int zerr = zmsg_addmem (send_msg, &opcode, sizeof (opcode));
    ASSERT_TEST(zerr == 0, "Could not add READ opcode in message",
            err_add_opcode);
    zerr = zmsg_addmem (send_msg, &offs, sizeof (offs));
    ASSERT_TEST(zerr == 0, "Could not add offset in message",
            err_add_offset);
    zerr = zmsg_addmem (send_msg, &size, sizeof (size));
    ASSERT_TEST(zerr == 0, "Could not add size in message",
            err_add_size);

    DBE_DEBUG (DBG_MSG | DBG_LVL_TRACE, "[smio_thsafe_client:zmq] Sending message:\n");
#ifdef LOCAL_MSG_DBG
    zmsg_print (send_msg);
#endif

    zerr = zmsg_send (&send_msg, self->pipe);
    ASSERT_TEST(zerr == 0, "Could not send message", err_send_msg);

    /* Message is:
     * frame 0: reply code
     * frame 1: return code
     * frame 2: data */
    ret_size = _thsafe_zmq_client_recv_read (self, (uint8_t *) data, size);

err_send_msg:
err_add_size:
err_add_offset:
err_add_opcode:
    zmsg_destroy (&send_msg);
err_msg_alloc:
    return ret_size;
}
/**** Write data block from device function pointer, size in bytes ****/
ssize_t thsafe_zmq_client_write_block (smio_t *self, loff_t offs, size_t size, const uint32_t *data)
{
    assert (self);
    ssize_t ret_size = -1;
    zmsg_t *send_msg = zmsg_new ();
    ASSERT_ALLOC(send_msg, err_msg_alloc);
    uint32_t opcode = THSAFE_WRITE_BLOCK;

    DBE_DEBUG (DBG_MSG | DBG_LVL_TRACE, "[smio_thsafe_client:zmq] Calling thsafe_write_block\n");

    /* Message is:
     * frame 0: WRITE_BLOCK opcode
     * frame 1: offset
     * frame 2: data to be written
     * */
    int zerr = zmsg_addmem (send_msg, &opcode, sizeof (opcode));
    ASSERT_TEST(zerr == 0, "Could not add WRITE opcode in message",
            err_add_opcode);
    zerr = zmsg_addmem (send_msg, &offs, sizeof (offs));
    ASSERT_TEST(zerr == 0, "Could not add offset in message",
            err_add_offset);
    zerr = zmsg_addmem (send_msg, data, size);
    ASSERT_TEST(zerr == 0, "Could not add data in message",
            err_add_data);

    DBE_DEBUG (DBG_MSG | DBG_LVL_TRACE, "[smio_thsafe_client:zmq] Sending message:\n");
#ifdef LOCAL_MSG_DBG
    zmsg_print (send_msg);
#endif

    zerr = zmsg_send (&send_msg, self->pipe);
    ASSERT_TEST(zerr == 0, "Could not send message", err_send_msg);

    /* Message is:
     * frame 0: reply code
     * frame 1: return code */
    ret_size = _thsafe_zmq_client_recv_write (self);

err_send_msg:
err_add_data:
err_add_offset:
err_add_opcode:
    zmsg_destroy (&send_msg);
err_msg_alloc:
    return ret_size;
}
Ejemplo n.º 21
0
/**************** FMC130M SMIO Functions ****************/
bpm_client_err_e bpm_blink_leds (bpm_client_t *self, char *service, uint32_t leds)
{
    assert (self);
    assert (service);

    bpm_client_err_e err = BPM_CLIENT_SUCCESS;
    FMC130M_4CH_REPLY_TYPE operation = FMC130M_4CH_OPCODE_LEDS;

    zmsg_t *request = zmsg_new ();
    err = (request == NULL) ? BPM_CLIENT_ERR_ALLOC : err;
    ASSERT_ALLOC(request, err_send_msg_alloc);
    zmsg_addmem (request, &operation, sizeof (operation));
    zmsg_addmem (request, &leds, sizeof (leds));
    mdp_client_send (self->mdp_client, service, &request);

err_send_msg_alloc:
    return err;
}
Ejemplo n.º 22
0
bpm_client_t *bpm_client_new (char *broker_endp, int verbose)
{
    bpm_client_t *self = zmalloc (sizeof *self);
    ASSERT_ALLOC(self, err_self_alloc);
    self->mdp_client = mdp_client_new (broker_endp, verbose);
    ASSERT_TEST(self->mdp_client!=NULL, "Could not create MDP client",
            err_mdp_client);

    /* Initialize acquisition table. Defined in hal/smio/modules/
     * acq/ddr3_map.h */
    self->acq_buf = __acq_buf;

    return self;

err_mdp_client:
    free (self);
err_self_alloc:
    return NULL;
}
Ejemplo n.º 23
0
/* Creates a new instance of Device Information */
devio_t * devio_new (char *name, char *endpoint_dev,
        llio_type_e type, char *endpoint_broker, int verbose)
{
    devio_t *self = (devio_t *) zmalloc (sizeof *self);
    ASSERT_ALLOC(self, err_self_alloc);

    /* Initialize the sockets structure to talk to nodes */
    self->pipes = zmalloc (sizeof (void *) * NODES_MAX_LEN);
    ASSERT_ALLOC(self->pipes, err_pipes_alloc);
    /* 0 nodes for now... */
    self->nnodes = 0;

    /* Nullify poller */
    self->poller = zpoller_new (NULL);
    ASSERT_ALLOC(self->poller, err_poller_alloc);

    /* Initilize mdp_worrker last, as we need to have everything ready
     * when we attemp to register in broker. Actually, we still need
     * to parse the SDB strucutres and register the operations in the
     * hash tables... * TODO (FIXME?): Find a better initialitazion routine before registering
     * to the broker the request from clients */
    self->name = strdup (name);
    ASSERT_ALLOC(self->name, err_name_alloc);
    self->endpoint_broker = strdup (endpoint_broker);
    ASSERT_ALLOC(self->endpoint_broker, err_endp_broker_alloc);
    self->verbose = verbose;

    /* Concatenate recv'ed name with a llio identifier */
    char *llio_name = zmalloc (sizeof (char)*(strlen(name)+strlen(LLIO_STR)+1));
    ASSERT_ALLOC(llio_name, err_llio_name_alloc);
    strcat (llio_name, name);
    strcat (llio_name, LLIO_STR);
    self->llio = llio_new (llio_name, endpoint_dev, type,
            verbose);
    ASSERT_ALLOC(self->llio, err_llio_alloc);

    /* We try to open the device */
    int err = llio_open (self->llio, NULL);
    ASSERT_TEST(err==0, "Error opening device!", err_llio_open);

    /* We can free llio_name now, as llio copies the string */
    free (llio_name);
    llio_name = NULL; /* Avoid double free error */

    /* Init sm_io_thsafe_server_ops_h. For now, we assume we want zmq
     * for exchanging messages between smio and devio instances */
    self->thsafe_server_ops = &smio_thsafe_zmq_server_ops;

    /* Init sm_io_h hash */
    self->sm_io_h = zhash_new ();
    ASSERT_ALLOC(self->sm_io_h, err_sm_io_h_alloc);

    /* Init sm_io_thsafe_ops_h dispatch table */
    self->disp_table_thsafe_ops = disp_table_new ();
    ASSERT_ALLOC(self->disp_table_thsafe_ops, err_disp_table_thsafe_ops_alloc);

    disp_table_func_fp *thsafe_server_fp = (disp_table_func_fp *) (self->thsafe_server_ops);
    const uint32_t *thsafe_opcodes_p = thsafe_opcodes;
    halutils_err_e halutils_err = disp_table_insert_all (self->disp_table_thsafe_ops,
            thsafe_server_fp, thsafe_opcodes_p, THSAFE_OPCODE_END);
    ASSERT_TEST(halutils_err==HALUTILS_SUCCESS, "Could not initialize dispatch table",
            err_disp_table_init);

    /* Finally, initialize mdp_worker with service being the BPM<board_number> */
    /* self->worker = mdp_worker_new (endpoint_broker, name, verbose);
    ASSERT_ALLOC(self->worker, err_worker_alloc); */
    /* Finally, initialize out zeroMQ context */
    self->ctx = zctx_new ();
    ASSERT_ALLOC(self->ctx, err_ctx_alloc);

    /* Adjust linger time for Majordomo protocol (MDP) */
    /* A non-zero linger value is required for DISCONNECT to be sent
     * when the worker is destroyed.  100 is arbitrary but chosen to be
     * sufficient for common cases without significant delay in broken ones. */
    zctx_set_linger (self->ctx, 100);

    return self;

err_ctx_alloc:
err_disp_table_init:
    disp_table_destroy (&self->disp_table_thsafe_ops);
err_disp_table_thsafe_ops_alloc:
    zhash_destroy (&self->sm_io_h);
err_sm_io_h_alloc:
    llio_release (self->llio, NULL);
err_llio_open:
    llio_destroy (&self->llio);
err_llio_alloc:
    free (llio_name);
err_llio_name_alloc:
    free (self->endpoint_broker);
err_endp_broker_alloc:
    free (self->name);
err_name_alloc:
    zpoller_destroy (&self->poller);
err_poller_alloc:
    free (self->pipes);
err_pipes_alloc:
    free (self);
err_self_alloc:
    return NULL;
}
Ejemplo n.º 24
0
/* Register an specific sm_io modules to this device */
devio_err_e devio_register_sm (devio_t *self, uint32_t smio_id, void *priv)
{
    assert (self);

    /* Search the sm_io_mod_dsapatch table for the smio_id and,
     * if found, call the correspondent bootstrap code to initilize
     * the sm_io module */
    th_boot_args_t *th_args = NULL;

    /* For now, just do a simple linear search. We can afford this, as
     * we don't expect to insert new sm_io modules often */
    unsigned int i;

    DBE_DEBUG (DBG_DEV_IO | DBG_LVL_TRACE,
            "[dev_io_core:register_sm] smio_mod_dispatch table size = %ld\n",
            ARRAY_SIZE(smio_mod_dispatch));

    for (i = 0; i < ARRAY_SIZE(smio_mod_dispatch); ++i) {
        if (smio_mod_dispatch[i].id == smio_id) {
            /* Found! Call bootstrap code and insert in
             * hash table */
            /* FIXME: Why do I need this? smio always gets initilized
             * after smio_mod_dispatch[i].bootstrap_ops->smio_boot (self); */
            /* smio_t *smio = NULL; */
            /* It is expected tha after the boot () call the operations
             * this sm_io inscate can handle are already registered! */
            DBE_DEBUG (DBG_DEV_IO | DBG_LVL_TRACE,
                    "[dev_io_core:register_sm] Allocating thread args\n");

            /* Alloacate thread arguments struct and pass it to the
             * thread. It is the responsability of the calling thread
             * to clear this structure after using it! */
            th_boot_args_t *th_args = zmalloc (sizeof *th_args);
            ASSERT_ALLOC (th_args, err_th_args_alloc);
            th_args->parent = self;
            /* FIXME: weak identifier */
            th_args->smio_id = i;
            th_args->broker = self->endpoint_broker;
            th_args->service = self->name;
            th_args->verbose = self->verbose;
            th_args->priv = priv;

            DBE_DEBUG (DBG_DEV_IO | DBG_LVL_TRACE,
                    "[dev_io_core:register_sm] Calling boot func\n");

            uint32_t pipe_idx = self->nnodes++;
            self->pipes [pipe_idx] = zthread_fork (self->ctx, smio_startup,
                    th_args);
            /* self->pipes [pipe_idx] = zthread_fork (self->ctx,
                   smio_mod_dispatch[i].bootstrap_ops->thread_boot, th_args); */
            /*smio = smio_mod_dispatch[i].bootstrap_ops->boot (self);*/
            /*ASSERT_ALLOC (smio, err_smio_alloc); */

            /* Stringify ID */
            DBE_DEBUG (DBG_DEV_IO | DBG_LVL_TRACE,
                    "[dev_io_core:register_sm] Stringify hash ID\n");
            char *key = halutils_stringify_key (smio_mod_dispatch[i].id);
            ASSERT_ALLOC (key, err_key_alloc);

            DBE_DEBUG (DBG_DEV_IO | DBG_LVL_TRACE,
                    "[dev_io_core:register_sm] Inserting hash with key: %s\n", key);
            zhash_insert (self->sm_io_h, key, self->pipes [pipe_idx]);
            free (key);

            /* stop on first match */
            break;
        }
    }

    //free (th_args);
    return DEVIO_SUCCESS;

err_key_alloc:
    free (th_args);
err_th_args_alloc:
    return DEVIO_ERR_ALLOC;
}
int _thsafe_zmq_client_open_release (smio_t *self, llio_endpoint_t *endpoint, uint32_t opcode)
{
    assert (self);
    int ret = -1;
    zmsg_t *send_msg = zmsg_new ();
    ASSERT_ALLOC(send_msg, err_msg_alloc);

    DBE_DEBUG (DBG_MSG | DBG_LVL_TRACE, "[smio_thsafe_client:zmq] Calling thsafe_release\n");
    /* Message is:
     * frame 0: RELEASE opcode
     * frame 1: endpopint struct (FIXME?) */
    int zerr = zmsg_addmem (send_msg, &opcode, sizeof (opcode));
    ASSERT_TEST(zerr == 0, "Could not add OPEN opcode in message",
            err_add_opcode);
    zerr = zmsg_addmem (send_msg, endpoint, sizeof (*endpoint));
    ASSERT_TEST(zerr == 0, "Could not add endpoint in message",
            err_add_endpoint);

    DBE_DEBUG (DBG_MSG | DBG_LVL_TRACE, "[smio_thsafe_client:zmq] Sending message:\n");
#ifdef LOCAL_MSG_DBG
    zmsg_print (send_msg);
#endif
    zerr = zmsg_send (&send_msg, self->pipe);
    ASSERT_TEST(zerr == 0, "Could not send message", err_send_msg);

    /* Message is:
     * frame 0: reply code
     * frame 1: return code */
    /* Returns NULL if confirmation was not OK or in case of error.
     * Returns the original message if the confirmation was OK */
    zmsg_t *recv_msg = _thsafe_zmq_client_recv_confirmation (self);
    ASSERT_TEST(recv_msg != NULL, "Could not receive confirmation code", err_null_raw_data);

    /* If we are here the message got a OK reply code.
     * Just return the return code */
    zframe_t *reply_frame = zmsg_pop (recv_msg);
    zframe_destroy (&reply_frame); /* Don't do anything with the reply code */
    zframe_t *ret_code_frame = zmsg_pop (recv_msg);

    if (ret_code_frame == NULL) {
        DBE_DEBUG (DBG_MSG | DBG_LVL_TRACE, "[smio_thsafe_client:zmq] Interrupted or malformed message\n");
        /* Interrupted or malformed message */
        goto err_recv_data;
    }

    /* Check if the frame has the number of bytes requested.
     * For now, we consider a success only when the number of
     * bytes requested is the same as the actually read*/
    if (zframe_size (ret_code_frame) != THSAFE_REPLY_SIZE) {
        DBE_DEBUG (DBG_MSG | DBG_LVL_TRACE, "[smio_thsafe_client:zmq] Frame size is wrong\n");
        goto err_recv_data_size;
    }

    ret = *(THSAFE_REPLY_TYPE *) zframe_data (ret_code_frame);

    DBE_DEBUG (DBG_MSG | DBG_LVL_TRACE, "[smio_thsafe_client:zmq] Received return code: %08X\n", ret);

err_recv_data_size:
    zframe_destroy (&ret_code_frame);
err_recv_data:
err_null_raw_data:
    zmsg_destroy (&recv_msg);
err_send_msg:
err_add_endpoint:
err_add_opcode:
    zmsg_destroy (&send_msg);
err_msg_alloc:
    return ret;
}
Ejemplo n.º 26
0
Archivo: bs.c Proyecto: MSch/MacRuby
bool 
bs_parser_parse(bs_parser_t *parser, const char *path, 
                const char *framework_path, bs_parse_options_t options, 
                bs_parse_callback_t callback, void *context, char **error)
{
  xmlTextReaderPtr reader;
  bs_element_function_t *func;
  bs_element_class_t *klass;
  bs_element_method_t *method;
  unsigned int i;
#define MAX_ARGS 128
  bs_element_arg_t args[MAX_ARGS];
  bs_element_arg_t fptr_args[MAX_ARGS];
  char *protocol_name = NULL;
  int func_ptr_arg_depth;
  bs_element_function_pointer_t *func_ptr;
  bool success;
  CFStringRef cf_path;
  bool nested_func_ptr;
  unsigned int version_number = 0;

  if (callback == NULL)
    return false;

  /* check if the given framework path has not been loaded already */
  cf_path = CFStringCreateWithFileSystemRepresentation(kCFAllocatorMalloc, 
    path);
  CFMakeCollectable(cf_path);
  for (unsigned i = 0, count = CFArrayGetCount(parser->loaded_paths);
       i < count; i++) {
    CFStringRef s = CFArrayGetValueAtIndex(parser->loaded_paths, i);
    if (CFStringCompare(cf_path, s, kCFCompareCaseInsensitive)
        == kCFCompareEqualTo) {
      /* already loaded */
      return true;
    }
  }

  CFArrayAppendValue(parser->loaded_paths, cf_path);

  //printf("parsing %s\n", path);

#define BAIL(fmt, args...)                      \
  do {                                          \
    if (error != NULL) {                        \
      char buf[1024];                           \
      snprintf(buf, sizeof buf,                 \
               "%s:%ld - "fmt, path,            \
               xmlGetLineNo(xmlTextReaderCurrentNode(reader)), \
               ##args);                         \
      *error = strdup(buf);                     \
    }                                           \
    success = false;                            \
    goto bails;                                 \
  }                                             \
  while (0)

#if __LP64__
# define CHECK_TYPE_ATTRIBUTE(var) CHECK_ATTRIBUTE(var, "type")
#else
# define CHECK_TYPE_ATTRIBUTE(var) \
    if (var == NULL && get_type64_attribute(reader) != NULL) { \
	break; \
    } \
    CHECK_ATTRIBUTE(var, "type")
#endif

#define CHECK_ATTRIBUTE_CAN_BE_EMPTY(a, name) \
  CHECK_ATTRIBUTE0(a, name, true)

#define CHECK_ATTRIBUTE(a, name) \
  CHECK_ATTRIBUTE0(a, name, false)

#define CHECK_ATTRIBUTE0(a, name, can_be_empty)         \
  do {                                                  \
    if (a == NULL)                                      \
      BAIL("expected attribute `%s' for element `%s'",  \
           name, xmlTextReaderConstName(reader));       \
    if (!can_be_empty && *a == '\0') {                  \
      free(a);                                          \
      BAIL("empty attribute `%s' for element `%s'",     \
           name, xmlTextReaderConstName(reader));       \
    }                                                   \
  } while (0)                                           \

  reader = xmlNewTextReaderFilename(path);
  if (reader == NULL)
    BAIL("cannot create XML text reader for file at path `%s'", path);

  func = NULL;
  func_ptr = NULL;
  func_ptr_arg_depth = -1;
  nested_func_ptr = false;
  klass = NULL;
  method = NULL;
  protocol_name = NULL;

  while (true) {
    const char *name;
    unsigned int namelen;
    int node_type = -1;
    bool eof = false;
    struct bs_xml_atom *atom;
    void *bs_element;
    bs_element_type_t bs_element_type = 0;

    do {
      int retval = xmlTextReaderRead(reader);
      if (retval == 0) {
        eof = true;
        break;
      }
      else if (retval < 0)
        BAIL("parsing error: %d", retval);

      node_type = xmlTextReaderNodeType(reader);
    }
    while (node_type != XML_READER_TYPE_ELEMENT 
           && node_type != XML_READER_TYPE_END_ELEMENT);    
    
    if (eof)
      break;

    name = (const char *)xmlTextReaderConstName(reader);
    namelen = strlen(name); 

    bs_element = NULL;

    atom = bs_xml_element(name, namelen);
    if (atom == NULL) {
      // TODO: we should include the "signatures" string into the gperf
      // function.
      if (version_number == 0 && strcmp(name, "signatures") == 0) {
        char *str = get_attribute(reader, "version");
        if (str != NULL) {
          char *p = strchr(str, '.');
          if (p != NULL) {
            *p = '\0';
            int major = atoi(str);
            int minor = atoi(&p[1]);
            assert(major < 10 && minor < 10);
            version_number = (major * 10) + minor;
            parser->version_number = version_number;
          }
          free(str);
        }
      }
      continue;
    }

    if (nested_func_ptr) {
      // FIXME: elements nesting function_pointers aren't supported yet by the
      // parser, so we just ignore them.
      if (node_type == XML_READER_TYPE_END_ELEMENT
          && (atom->val == BS_XML_FUNCTION || atom->val == BS_XML_METHOD)) {
        nested_func_ptr = false;
      }
      continue;
    }

    if (node_type == XML_READER_TYPE_ELEMENT) {
      switch (atom->val) {
        case BS_XML_DEPENDS_ON:
        {
          char *depends_on_path;
          char bs_path[PATH_MAX];
          bool bs_path_found;
          
          depends_on_path = get_attribute(reader, "path");
          CHECK_ATTRIBUTE(depends_on_path, "path");

//printf("depends of %s\n", depends_on_path);
          
          bs_path_found = bs_find_path(depends_on_path, bs_path, 
                                       sizeof bs_path);
          if (bs_path_found) {
            if (!bs_parser_parse(parser, bs_path, depends_on_path, options, 
                                 callback, context, error)) {
              free(depends_on_path);
              return false;
	    }
          }
          free(depends_on_path);
          break;
        }

        case BS_XML_CONSTANT: 
        { 
          bs_element_constant_t *bs_const;
          char *const_name;
          char *const_type;

          const_name = get_attribute(reader, "name");
          CHECK_ATTRIBUTE(const_name, "name");
          const_type = get_type_attribute(reader);
          CHECK_TYPE_ATTRIBUTE(const_type);

          bs_const = (bs_element_constant_t *)
            malloc(sizeof(bs_element_constant_t));
          ASSERT_ALLOC(bs_const);

          bs_const->name = const_name;
          bs_const->type = const_type;
          bs_const->ignore = false;
          bs_const->suggestion = NULL;
          bs_const->magic_cookie = get_boolean_attribute(reader,
            "magic_cookie", false);

          bs_element = bs_const;
          bs_element_type = BS_ELEMENT_CONSTANT;
          break;
        }

        case BS_XML_STRING_CONSTANT:
        {
          bs_element_string_constant_t *bs_strconst;
          char *strconst_name;
          char *strconst_value;

          strconst_name = get_attribute(reader, "name");
          CHECK_ATTRIBUTE(strconst_name, "name");
          strconst_value = get_attribute(reader, "value");
          CHECK_ATTRIBUTE_CAN_BE_EMPTY(strconst_value, "value");

          bs_strconst = (bs_element_string_constant_t *)
            malloc(sizeof(bs_element_string_constant_t));
          ASSERT_ALLOC(bs_strconst);

          bs_strconst->name = strconst_name;
          bs_strconst->value = strconst_value;
          bs_strconst->nsstring = get_boolean_attribute(reader, "nsstring", 
            false);

          bs_element = bs_strconst;
          bs_element_type = BS_ELEMENT_STRING_CONSTANT;
          break;
        }

        case BS_XML_ENUM: 
        { 
          char *enum_name;
          char *enum_value;        

          enum_name = get_attribute(reader, "name");
          CHECK_ATTRIBUTE(enum_name, "name");

#if __LP64__
	  enum_value = get_attribute(reader, "value64");
	  if (enum_value == NULL)
#endif
	    enum_value = get_attribute(reader, "value");

#if BYTE_ORDER == BIG_ENDIAN
# define BYTE_ORDER_VALUE_ATTR_NAME "be_value"
#else
# define BYTE_ORDER_VALUE_ATTR_NAME "le_value"
#endif

          if (enum_value == NULL)
            enum_value = get_attribute(reader, BYTE_ORDER_VALUE_ATTR_NAME); 
          
          if (enum_value != NULL) {
            bs_element_enum_t *bs_enum;
   
            bs_enum = (bs_element_enum_t *)malloc(sizeof(bs_element_enum_t));
            ASSERT_ALLOC(bs_enum);

            bs_enum->name = enum_name;
            bs_enum->value = enum_value;
            bs_enum->ignore = get_boolean_attribute(reader, "ignore", false);
            bs_enum->suggestion = get_attribute(reader, "suggestion");
            
            bs_element = bs_enum;
            bs_element_type = BS_ELEMENT_ENUM;
          }
          break;
        }

        case BS_XML_STRUCT: 
        {
          bs_element_struct_t *bs_struct;
          char *struct_decorated_type;
          char *struct_name;
          char type[MAX_ENCODE_LEN];
          bs_element_struct_field_t fields[128];
          int field_count;

          struct_decorated_type = get_type_attribute(reader);
          CHECK_TYPE_ATTRIBUTE(struct_decorated_type);
          struct_name = get_attribute(reader, "name");
          CHECK_ATTRIBUTE(struct_name, "name");

          if (!undecorate_struct_type(struct_decorated_type, type, 
                                      sizeof type, fields, 128, 
                                      &field_count)) {
            BAIL("Can't handle structure '%s' with type '%s'", 
                 struct_name, struct_decorated_type);
          }

          free(struct_decorated_type);

          bs_struct = 
            (bs_element_struct_t *)malloc(sizeof(bs_element_struct_t));
          ASSERT_ALLOC(bs_struct);

          bs_struct->name = struct_name;
          bs_struct->type = strdup(type);
          
          bs_struct->fields = (bs_element_struct_field_t *)malloc(
            sizeof(bs_element_struct_field_t) * field_count);
          ASSERT_ALLOC(bs_struct->fields);
          memcpy(bs_struct->fields, fields, 
                 sizeof(bs_element_struct_field_t) * field_count); 
          
          bs_struct->fields_count = field_count;
          bs_struct->opaque = get_boolean_attribute(reader, "opaque", false);

          bs_element = bs_struct;
          bs_element_type = BS_ELEMENT_STRUCT;
          break;
        }

        case BS_XML_OPAQUE:
        {
          bs_element_opaque_t *bs_opaque;
          char *opaque_name;
          char *opaque_type;

          opaque_name = get_attribute(reader, "name");
          CHECK_ATTRIBUTE(opaque_name, "name");
          opaque_type = get_type_attribute(reader);
          CHECK_TYPE_ATTRIBUTE(opaque_type);

          bs_opaque = 
            (bs_element_opaque_t *)malloc(sizeof(bs_element_opaque_t));
          ASSERT_ALLOC(bs_opaque);
          
          bs_opaque->name = opaque_name;
          bs_opaque->type = opaque_type;
          
          bs_element = bs_opaque;
          bs_element_type = BS_ELEMENT_OPAQUE;
          break;
        }
        
        case BS_XML_CFTYPE:
        {
          bs_element_cftype_t *bs_cftype;
          char *cftype_name;
          char *cftype_type;

          cftype_name = get_attribute(reader, "name");
          CHECK_ATTRIBUTE(cftype_name, "name");
          cftype_type = get_type_attribute(reader);
          CHECK_TYPE_ATTRIBUTE(cftype_type);

          bs_cftype = 
            (bs_element_cftype_t *)malloc(sizeof(bs_element_cftype_t));
          ASSERT_ALLOC(bs_cftype);

          bs_cftype->name = cftype_name;
          bs_cftype->type = cftype_type;

#if 1
          /* the type_id field isn't used in MacRuby */
          bs_cftype->type_id = 0;
#else
          char *cftype_gettypeid_func_name;
          cftype_gettypeid_func_name = get_attribute(reader, "gettypeid_func");
          if (cftype_gettypeid_func_name != NULL) {
            void *sym;

            sym = dlsym(RTLD_DEFAULT, cftype_gettypeid_func_name);
            if (sym == NULL) {
              BAIL("cannot locate gettypeid_func function `%s'",
                   cftype_gettypeid_func_name);
            }
            else {
              CFTypeID (*cb)(void) = sym;
              bs_cftype->type_id = (*cb)();
            }
          }
          else {
            bs_cftype->type_id = 0;
          }
#endif

          bs_cftype->tollfree = get_attribute(reader, "tollfree");

          bs_element = bs_cftype;
          bs_element_type = BS_ELEMENT_CFTYPE;
          break;
        }
        
        case BS_XML_INFORMAL_PROTOCOL: 
        {
	  if (protocol_name != NULL)
	    free(protocol_name);
          protocol_name = get_attribute(reader, "name");
          CHECK_ATTRIBUTE(protocol_name, "name");
          break;
        }

        case BS_XML_FUNCTION: 
        {
          char *func_name;
          
          func_name = get_attribute(reader, "name");
          CHECK_ATTRIBUTE(func_name, "name");

          func = 
            (bs_element_function_t *)malloc(sizeof(bs_element_function_t));
          ASSERT_ALLOC(func);

          func->name = func_name;
          func->variadic = get_boolean_attribute(reader, "variadic", false);
          func->args_count = 0;
          func->args = NULL;
          func->retval = NULL;

          if (xmlTextReaderIsEmptyElement(reader)) {
            bs_element = func;
            bs_element_type = BS_ELEMENT_FUNCTION;
            func = NULL;
          }
          break;
        }

        case BS_XML_FUNCTION_ALIAS: 
        {
          bs_element_function_alias_t *bs_func_alias;
          char *alias_name;
          char *alias_original;

          alias_name = get_attribute(reader, "name"); 
          CHECK_ATTRIBUTE(alias_name, "name");
          alias_original = get_attribute(reader, "original");
          CHECK_ATTRIBUTE(alias_original, "original");

          bs_func_alias = (bs_element_function_alias_t *)malloc(
            sizeof(bs_element_function_alias_t));
          ASSERT_ALLOC(bs_func_alias);
          
          bs_func_alias->name = alias_name;
          bs_func_alias->original = alias_original;

          bs_element = bs_func_alias;
          bs_element_type = BS_ELEMENT_FUNCTION_ALIAS;
          break;
        }

        case BS_XML_CLASS: 
        {
          char *class_name;
          
          class_name = get_attribute(reader, "name");
          CHECK_ATTRIBUTE(class_name, "name");
        
          klass = (bs_element_class_t *)malloc(sizeof(bs_element_class_t));
          ASSERT_ALLOC(klass);
            
          klass->name = class_name;
          klass->class_methods = klass->instance_methods = NULL;
          klass->class_methods_count = klass->instance_methods_count = 0;
          break;
        }

        case BS_XML_ARG:
        {
          if (func != NULL || method != NULL || func_ptr != NULL) {
            bs_element_arg_t *bs_arg; 
            unsigned *argc;

            argc = func_ptr != NULL
              ? &func_ptr->args_count
              : func != NULL 
                ? &func->args_count 
                : &method->args_count;

            if (*argc >= MAX_ARGS) {
              if (func_ptr != NULL)
                BAIL("maximum number of arguments (%d) reached " \
                     "for function pointer", MAX_ARGS);
              else if (func != NULL)
                BAIL("maximum number of arguments (%d) reached " \
                     "for function '%s'", MAX_ARGS, func->name);
              else
                BAIL("maximum number of arguments (%d) reached " \
                     "for method '%s'", MAX_ARGS, (char *)method->name);
            } 

	    bs_element_arg_t *args_from =
		(func_ptr == NULL ? args : fptr_args);
	    bs_arg = &args_from[(*argc)++];

            if (method != NULL && func_ptr == NULL) {
              char *index = get_attribute(reader, "index");
              CHECK_ATTRIBUTE(index, "index");
              bs_arg->index = strtol(index, NULL, 10);
              free(index);
            }
            else {
              bs_arg->index = -1;
            }
            
            get_type_modifier_attribute(reader, &bs_arg->type_modifier);

#if __LP64__
            bs_arg->sel_of_type = get_attribute(reader, "sel_of_type64");
            if (bs_arg->sel_of_type == NULL)
#endif
              bs_arg->sel_of_type = get_attribute(reader, "sel_of_type");

            bs_arg->printf_format = get_boolean_attribute(reader, 
                "printf_format", false); 
            bs_arg->null_accepted = get_boolean_attribute(reader, 
                "null_accepted", true);
            get_c_ary_type_attribute(reader, 
                &bs_arg->carray_type, &bs_arg->carray_type_value); 
  
            bs_arg->type = get_type_attribute(reader);

            if (get_boolean_attribute(reader, "function_pointer", false)) {
              if (func_ptr != NULL) {
                func_ptr = NULL; 
		nested_func_ptr = true;
		break;
	      }
              bs_arg->function_pointer = (bs_element_function_pointer_t *)
                calloc(1, sizeof(bs_element_function_pointer_t));
              ASSERT_ALLOC(bs_arg->function_pointer);
              func_ptr = bs_arg->function_pointer;
              func_ptr_arg_depth = xmlTextReaderDepth(reader);
            }
	    else {
              bs_arg->function_pointer = NULL;
	    }
          }
          else {
            BAIL("argument defined outside of a " \
                 "function/method/function_pointer");
          }
          break;
        }

        case BS_XML_RETVAL: 
        {
          if (func != NULL || method != NULL || func_ptr != NULL) {
            bs_element_retval_t *bs_retval;  

            if (func_ptr != NULL) {
              if (func_ptr->retval != NULL)
                BAIL("function pointer return value defined more than once");
            }
            else if (func != NULL) {
              if (func->retval != NULL)
                BAIL("function '%s' return value defined more than once", 
                     func->name);
            }
            else if (method != NULL) {
              if (method->retval != NULL)
                BAIL("method '%s' return value defined more than once", 
                     (char *)method->name);
            }
    
            bs_retval = 
              (bs_element_retval_t *)malloc(sizeof(bs_element_retval_t));
            ASSERT_ALLOC(bs_retval);

            get_c_ary_type_attribute(reader, &bs_retval->carray_type, 
              &bs_retval->carray_type_value);

            bs_retval->type = get_type_attribute(reader);
            if (bs_retval->type != NULL)
              bs_retval->already_retained = 
                get_boolean_attribute(reader, "already_retained", false);

            if (func_ptr != NULL) {
              if (bs_retval->type != NULL) {
                func_ptr->retval = bs_retval;
              }
              else {
                free(bs_retval);
                BAIL("function pointer return value defined without type"); 
              }
            }
            else if (func != NULL) {
              if (bs_retval->type != NULL) {
                func->retval = bs_retval;
              }
              else {
                free(bs_retval);
#if !defined(__LP64__)
		if (get_type64_attribute(reader) != NULL) {
		    // The function has no 32-bit return value type and we
		    // run in 32-bit mode. We just ignore it.
		    func = NULL;
		    break;
		}
#endif
                BAIL("function '%s' return value defined without type", 
                     func->name);
              }
            }
            else {
              method->retval = bs_retval;
            }

            if (get_boolean_attribute(reader, "function_pointer", false)) {
              if (func_ptr != NULL) {
                func_ptr = NULL; 
		nested_func_ptr = true;
		break;
              }
              bs_retval->function_pointer = (bs_element_function_pointer_t *)
                calloc(1, sizeof(bs_element_function_pointer_t));
              ASSERT_ALLOC(bs_retval->function_pointer);
              func_ptr = bs_retval->function_pointer;
              func_ptr_arg_depth = xmlTextReaderDepth(reader);
            }
	    else {
              bs_retval->function_pointer = NULL;
	    }
          }
          else {
            BAIL("return value defined outside a function/method");
          }
          break;
        }

        case BS_XML_METHOD: 
        {
          if (protocol_name != NULL) {
            bs_element_informal_protocol_method_t *bs_informal_method;
            char *selector;
            char *method_type;

            selector = get_attribute(reader, "selector");
            CHECK_ATTRIBUTE(selector, "selector");
            
            method_type = get_type_attribute(reader);
            CHECK_TYPE_ATTRIBUTE(method_type);

            bs_informal_method = (bs_element_informal_protocol_method_t *)
              malloc(sizeof(bs_element_informal_protocol_method_t));
            ASSERT_ALLOC(bs_informal_method);

            bs_informal_method->name = sel_registerName(selector);
	    free(selector);
            bs_informal_method->class_method = 
              get_boolean_attribute(reader, "class_method", false);
            bs_informal_method->type = method_type;
            bs_informal_method->protocol_name = strdup(protocol_name);

            bs_element = bs_informal_method;
            bs_element_type = BS_ELEMENT_INFORMAL_PROTOCOL_METHOD;
          }
          else if (klass != NULL) {  
            char *selector;

            selector = get_attribute(reader, "selector");
            CHECK_ATTRIBUTE(selector, "selector");

            method = 
              (bs_element_method_t *)malloc(sizeof(bs_element_method_t));
            ASSERT_ALLOC(method);

            method->name = sel_registerName(selector);
	    free(selector);
            method->class_method = 
              get_boolean_attribute(reader, "class_method", false);
            method->variadic = 
              get_boolean_attribute(reader, "variadic", false);
            method->ignore = 
              get_boolean_attribute(reader, "ignore", false);
            method->suggestion = get_attribute(reader, "suggestion");
            method->args_count = 0;
            method->args = NULL;
            method->retval = NULL;

            if (xmlTextReaderIsEmptyElement(reader)) {
              goto index_method;
            }
          }
          else {
            BAIL("method defined outside a class or informal protocol");
          }
          break;
        }
      }
    }
    else if (node_type == XML_READER_TYPE_END_ELEMENT) {
      switch (atom->val) {
        case BS_XML_INFORMAL_PROTOCOL: 
        {
          protocol_name = NULL;
          break;
        }

        case BS_XML_RETVAL:
        case BS_XML_ARG: 
        {
          if (func_ptr != NULL 
              && func_ptr_arg_depth == xmlTextReaderDepth(reader)) {

	      bs_element_retval_t *retval = NULL;
	      bs_element_arg_t *arg = NULL;
	      unsigned args_count;

	      if (atom->val == BS_XML_RETVAL) {
		  retval = func != NULL ? func->retval : method->retval;
	      }
	      else {
		  args_count = func != NULL ? func->args_count
		      : method->args_count;
		  arg = &args[args_count - 1];
	      }

              // Determine if we deal with a block or a function pointer.
	      const char *old_type = (retval ? retval->type : arg->type);
              const char lambda_type = *old_type == '@'
		? _MR_C_LAMBDA_BLOCK
		: _MR_C_LAMBDA_FUNCPTR;

	      char tmp_type[1025]; // 3 less to fit <, type and >
	      char new_type[1028];

	      // Function ptr return type
	      strlcpy(tmp_type, func_ptr->retval->type, sizeof(tmp_type));
	      // Function ptr args
	      for (i = 0; i < func_ptr->args_count; i++) {
		  strlcat(tmp_type, fptr_args[i].type, sizeof(tmp_type));
	      }
	      // Clear the final type string
	      memset(new_type, 0, sizeof(new_type));
	      // Append the function pointer type
	      snprintf(new_type, sizeof(new_type), "%c%c%s%c",
		      _MR_C_LAMBDA_B, lambda_type, tmp_type, _MR_C_LAMBDA_E);

	      // Free the old values
	      if (retval) {
		  free(retval->type);
		  retval->type = strdup(new_type);
	      }
	      else {
		  free(arg->type);
		  arg->type = strdup(new_type);
	      }
            
	      if (func_ptr->args_count > 0) {
		  size_t len;
      
		  len = sizeof(bs_element_arg_t) * func_ptr->args_count;
		  func_ptr->args = (bs_element_arg_t *)malloc(len);
		  ASSERT_ALLOC(func_ptr->args);
		  memcpy(func_ptr->args, fptr_args, len);
	      }
	      else {
		  func_ptr->args = NULL;
	      }
                        
	      func_ptr = NULL;
	      func_ptr_arg_depth = -1;
          }
          break;
        }
 
        case BS_XML_FUNCTION: 
        {
          if (func == NULL) {
            break;
          }
          for (i = 0; i < func->args_count; i++) {
            if (args[i].type == NULL)
              BAIL("function '%s' argument #%d type not provided", 
                   func->name, i);
          }
    
          if (func->args_count > 0) {
            size_t len;
    
            len = sizeof(bs_element_arg_t) * func->args_count;
            func->args = (bs_element_arg_t *)malloc(len);
            ASSERT_ALLOC(func->args);
            memcpy(func->args, args, len);
          }

          bs_element = func;
          bs_element_type = BS_ELEMENT_FUNCTION;
          func = NULL;
          break;
        }

        case BS_XML_METHOD: 
        {
          bs_element_method_t *methods;
          unsigned *methods_count;
          
          if (method->args_count > 0) {
            size_t len;
      
            len = sizeof(bs_element_arg_t) * method->args_count;
            method->args = (bs_element_arg_t *)malloc(len);
            ASSERT_ALLOC(method->args);
            memcpy(method->args, args, len);
          }

index_method:
          methods = method->class_method 
            ? klass->class_methods : klass->instance_methods;

          methods_count = method->class_method
            ? &klass->class_methods_count : &klass->instance_methods_count;

          if (methods == NULL) {
            methods = (bs_element_method_t *)malloc(
              sizeof(bs_element_method_t) * (*methods_count + 1));
          }
          else {
            methods = (bs_element_method_t *)realloc(methods, 
              sizeof(bs_element_method_t) * (*methods_count + 1));
          }
          ASSERT_ALLOC(methods);

    //      methods[*methods_count] = method;
    // FIXME this is inefficient
          memcpy(&methods[*methods_count], method, 
            sizeof(bs_element_method_t));

          (*methods_count)++;
          
          if (method->class_method)
            klass->class_methods = methods;
          else
            klass->instance_methods = methods;
         
          free(method);
          method = NULL;
          break;
        }

        case BS_XML_CLASS: 
        {
          bs_element = klass;
          bs_element_type = BS_ELEMENT_CLASS;
          klass = NULL;
          break;
        }
      }
    }

    if (bs_element != NULL)
      (*callback)(parser, path, bs_element_type, bs_element, context);
  }
  
  success = true;

bails:
  if (protocol_name != NULL)
    free(protocol_name);

  xmlFreeTextReader(reader);

  if (!success) {
      for (unsigned i = 0, count = CFArrayGetCount(parser->loaded_paths);
	      i < count; i++) {
	  CFStringRef s = CFArrayGetValueAtIndex(parser->loaded_paths, i);
	  if (CFStringCompare(cf_path, s, kCFCompareCaseInsensitive)
		  == kCFCompareEqualTo) {
	      CFArrayRemoveValueAtIndex(parser->loaded_paths, i);
	      break;
	  }
      }
  }

  if (success && options == BS_PARSE_OPTIONS_LOAD_DYLIBS && framework_path != NULL) {
    char buf[PATH_MAX];

    if (_bs_find_path(framework_path, buf, sizeof buf, "dylib")) {
      if (dlopen(buf, RTLD_LAZY) == NULL) {
        if (error != NULL) {
          *error = dlerror();
        }
        success = false;
      }
    }
  }

  return success;
}
Ejemplo n.º 27
0
Archivo: bs.c Proyecto: MSch/MacRuby
static bool 
undecorate_struct_type(const char *src, char *dest, size_t dest_len, 
                       bs_element_struct_field_t *fields, 
                       size_t fields_count, int *out_fields_count)
{
  const char *p_src;
  char *p_dst;
  char *pos;
  size_t src_len;
  unsigned field_idx;
  unsigned i;

  p_src = src;
  p_dst = dest;
  src_len = strlen(src);
  field_idx = 0;
  if (out_fields_count != NULL)
    *out_fields_count = 0;

  for (;;) {
    bs_element_struct_field_t *field;
    size_t len;

    field = field_idx < fields_count ? &fields[field_idx] : NULL;

    /* Locate the first field, if any. */
    pos = strchr(p_src, '"');

    /* Copy what's before the first field, or the rest of the source. */
    len = MIN(pos == NULL ? src_len - (p_src - src) + 1 : pos - p_src, dest_len - (p_dst - dest));
    strncpy(p_dst, p_src, len);
    p_dst += len;

    /* We can break if there wasn't any field. */
    if (pos == NULL)
      break;

    /* Jump to the end of the field, saving the field name if necessary. */
    p_src = pos + 1;
    pos = strchr(p_src, '"');
    if (pos == NULL) {
      fprintf(stderr, "Can't find the end of field delimiter starting at %d\n", (int)(p_src - src));
      goto bails; 
    }
    if (field != NULL) {
      field->name = (char *)malloc((sizeof(char) * (pos - p_src)) + 1);
      ASSERT_ALLOC(field->name);
      strncpy(field->name, p_src, pos - p_src);
      field->name[pos - p_src] = '\0';
      field_idx++; 
    }
    p_src = pos + 1; 
    pos = NULL;

    /* Save the field encoding if necessary. */
    if (field != NULL) {
      char opposite;
      bool ok;
      int nested;

      opposite = 
	  *p_src == '{' ? '}' :
	  *p_src == '(' ? ')' :
	  *p_src == '[' ? ']' : 0;

      for (i = 0, ok = false, nested = 0;
           i < src_len - (p_src - src) && !ok; 
           i++) {

        char c = p_src[i];

        if (opposite != 0) {
          /* Encoding is a structure, we need to match the closing '}',
           * taking into account that other structures can be nested in it.
           */
          if (c == opposite) {
            if (nested == 0)
              ok = true;
            else
              nested--;  
          }
          else if (c == *p_src && i > 0)
            nested++;
        }
        else {
          /* Easy case, just match another field delimiter, or the end
           * of the encoding.
           */
          if (c == '"' || c == '}') {
            i--;
            ok = true;
          } 
        }
      }

      if (ok == false) {
        fprintf(stderr, "Can't find the field encoding starting at %d\n", (int)(p_src - src));
        goto bails;
      }

      if (opposite == '}' || opposite == ')') {
        char buf[MAX_ENCODE_LEN];
        char buf2[MAX_ENCODE_LEN];
 
        strncpy(buf, p_src, MIN(sizeof buf, i));
        buf[MIN(sizeof buf, i)] = '\0';        
     
        if (!undecorate_struct_type(buf, buf2, sizeof buf2, NULL, 0, NULL)) {
          fprintf(stderr, "Can't un-decode the field encoding '%s'\n", buf);
          goto bails;
        }

        len = strlen(buf2); 
        field->type = (char *)malloc((sizeof(char) * len) + 1);
        ASSERT_ALLOC(field->type);
        strncpy(field->type, buf2, len);
        field->type[len] = '\0';
      }
      else {
        field->type = (char *)malloc((sizeof(char) * i) + 1);
        ASSERT_ALLOC(field->type);
        strncpy(field->type, p_src, i);
        field->type[i] = '\0';
        len = i;
      }

      strncpy(p_dst, field->type, len);

      p_src += i;
      p_dst += len;
    }
  }

  *p_dst = '\0';
  if (out_fields_count != NULL)
    *out_fields_count = field_idx;
  return true;

bails:
  /* Free what we allocated! */
  for (i = 0; i < field_idx; i++) {
    free(fields[i].name);
    free(fields[i].type);
  }
  return false;
}