void print_exception(VM *vm, VALUE result) { // TODO: fprintf to stderr and teach dump_titled to optionally fprintf to stderr too printf("====== Exception of type '%s' ======\n", obj_to_cstring(NGS_TYPE_NAME(NORMAL_TYPE_INSTANCE_TYPE(result)))); // TODO: maybe macro to iterate attributes VALUE fields = NGS_TYPE_FIELDS(NORMAL_TYPE_INSTANCE_TYPE(result)); HASH_OBJECT_ENTRY *e; for(e=HASH_HEAD(fields); e; e=e->insertion_order_next) { if(obj_is_of_type(ARRAY_ITEMS(NORMAL_TYPE_INSTANCE_FIELDS(result))[GET_INT(e->val)], vm->Backtrace)) { printf("=== [ backtrace ] ===\n"); // Backtrace.frames = [{"closure": ..., "ip": ...}, ...] VALUE backtrace = ARRAY_ITEMS(NORMAL_TYPE_INSTANCE_FIELDS(result))[GET_INT(e->val)]; VALUE frames; assert(get_normal_type_instace_attribute(backtrace, make_string("frames"), &frames) == METHOD_OK); unsigned int i; for(i = 0; i < OBJ_LEN(frames); i++) { VALUE frame, resolved_ip, ip; frame = ARRAY_ITEMS(frames)[i]; H(ip, frame, "ip"); resolved_ip = resolve_ip(vm, (IP)(GET_INT(ip) - 1)); if(IS_HASH(resolved_ip)) { VALUE file, first_line, first_column, last_line, last_column; HASH_OBJECT_ENTRY *closure_entry; char *closure_name = "<anonymous>"; H(file, resolved_ip, "file"); H(first_line, resolved_ip, "first_line"); H(first_column, resolved_ip, "first_column"); H(last_line, resolved_ip, "last_line"); H(last_column, resolved_ip, "last_column"); closure_entry = get_hash_key(frame, make_string("closure")); if(closure_entry && IS_CLOSURE(closure_entry->val) && (IS_HASH(CLOSURE_OBJ_ATTRS(closure_entry->val)))) { HASH_OBJECT_ENTRY *name_entry; name_entry = get_hash_key(CLOSURE_OBJ_ATTRS(closure_entry->val), make_string("name")); if(name_entry) { closure_name = obj_to_cstring(name_entry->val); } } // TODO: fix types printf("[Frame #%u] %s:%d:%d - %d:%d [in %s]\n", i, obj_to_cstring(file), (int) GET_INT(first_line), (int) GET_INT(first_column), (int) GET_INT(last_line), (int) GET_INT(last_column), closure_name); } else { printf("[Frame #%u] (no source location)\n", i); } } continue; } if(obj_is_of_type(ARRAY_ITEMS(NORMAL_TYPE_INSTANCE_FIELDS(result))[GET_INT(e->val)], vm->Exception)) { assert(IS_STRING(e->key)); printf("---8<--- %s - start ---8<---\n", obj_to_cstring(e->key)); print_exception(vm, ARRAY_ITEMS(NORMAL_TYPE_INSTANCE_FIELDS(result))[GET_INT(e->val)]); printf("---8<--- %s - end ---8<---\n", obj_to_cstring(e->key)); continue; } if(IS_STRING(e->key)) { dump_titled(obj_to_cstring(e->key), ARRAY_ITEMS(NORMAL_TYPE_INSTANCE_FIELDS(result))[GET_INT(e->val)]); } else { // Should not happen dump_titled("attribute key", e->key); dump_titled("attribute value", ARRAY_ITEMS(NORMAL_TYPE_INSTANCE_FIELDS(result))[GET_INT(e->val)]); } } }
int *get_adrcmd_from_key(int cxt, struct key_entry *key, int create) { flrn_assoc_key_cmd *pc; unsigned char hash; int i; if (key==NULL) return NULL; if (key->entry==ENTRY_ERROR_KEY) return NULL; hash=get_hash_key(key); pc=Flcmd_rev[hash]; if (pc==NULL) { if (create) pc=Flcmd_rev[hash]=safe_calloc(1,sizeof(flrn_assoc_key_cmd)); else return NULL; } else { while (pc->next) { if (key_are_equal(&(pc->key),key)) break; pc=pc->next; } if (key_are_equal(&(pc->key),key)) return &(pc->cmd[cxt]); if (create==0) return NULL; pc->next=safe_calloc(1,sizeof(flrn_assoc_key_cmd)); pc=pc->next; } /* create = 1 */ for (i=0;i<NUMBER_OF_CONTEXTS;i++) pc->cmd[i]=FLCMD_UNDEF; memcpy(&(pc->key),key,sizeof(struct key_entry)); if (key->entry==ENTRY_ALLOCATED_STRING) pc->key.value.allocstr=safe_flstrdup(key->value.allocstr); return &(pc->cmd[cxt]); }
/* retourne la commande supprimée */ int del_cmd_for_key (int cxt,struct key_entry *key) { flrn_assoc_key_cmd *pc,**pere; unsigned char hash; int oldcmd,i; if (key==NULL) return -2; if (key->entry==ENTRY_ERROR_KEY) return -2; hash=get_hash_key(key); pc=Flcmd_rev[hash]; if (pc==NULL) return FLCMD_UNDEF; if (key_are_equal(&(pc->key),key)) pere=&(Flcmd_rev[hash]); else { while (pc->next) { if (key_are_equal(&(pc->next->key),key)) break; pc=pc->next; } if (pc->next==NULL) return FLCMD_UNDEF; pere=&(pc->next); pc=pc->next; } oldcmd=pc->cmd[cxt]; pc->cmd[cxt]=FLCMD_UNDEF; for (i=0;i<NUMBER_OF_CONTEXTS;i++) if (pc->cmd[i]!=FLCMD_UNDEF) break; if (i==NUMBER_OF_CONTEXTS) { if (key->entry==ENTRY_ALLOCATED_STRING) free(pc->key.value.allocstr); (*pere)=pc->next; free(pc); } return oldcmd; }
void set_normal_type_instance_attribute(VALUE obj, VALUE attr, VALUE v) { VALUE ut; HASH_OBJECT_ENTRY *e; size_t n; ut = NORMAL_TYPE_INSTANCE_TYPE(obj); e = get_hash_key(NGS_TYPE_FIELDS(ut), attr); if(e) { n = GET_INT(e->val); } else { n = OBJ_LEN(NGS_TYPE_FIELDS(ut)); set_hash_key(NGS_TYPE_FIELDS(ut), attr, MAKE_INT(n)); } // TODO: more optimized while(OBJ_LEN(NORMAL_TYPE_INSTANCE_FIELDS(obj)) < n) { array_push(NORMAL_TYPE_INSTANCE_FIELDS(obj), (VALUE){.num = V_UNDEF}); }
METHOD_RESULT get_normal_type_instace_attribute(VALUE obj, VALUE attr, VALUE *result) { VALUE ut; HASH_OBJECT_ENTRY *e; size_t n; ut = NORMAL_TYPE_INSTANCE_TYPE(obj); e = get_hash_key(NGS_TYPE_FIELDS(ut), attr); if(!e) { return METHOD_EXCEPTION; } n = GET_INT(e->val); if(n >= OBJ_LEN(NORMAL_TYPE_INSTANCE_FIELDS(obj))) { return METHOD_EXCEPTION; } *result = ARRAY_ITEMS(NORMAL_TYPE_INSTANCE_FIELDS(obj))[n]; if(IS_UNDEF(*result)) { return METHOD_EXCEPTION; } return METHOD_OK; }
MMPort * mm_base_modem_get_port (MMBaseModem *self, const gchar *subsys, const gchar *name) { MMPort *port; gchar *key; g_return_val_if_fail (MM_IS_BASE_MODEM (self), NULL); g_return_val_if_fail (name != NULL, NULL); g_return_val_if_fail (subsys != NULL, NULL); /* Only 'net' or 'tty' should be given */ g_return_val_if_fail (g_str_equal (subsys, "net") || g_str_equal (subsys, "tty"), NULL); key = get_hash_key (subsys, name); port = g_hash_table_lookup (self->priv->ports, key); g_free (key); return port; }
void mm_base_modem_release_port (MMBaseModem *self, const gchar *subsys, const gchar *name) { gchar *key; MMPort *port; GList *l; g_return_if_fail (MM_IS_BASE_MODEM (self)); g_return_if_fail (name != NULL); g_return_if_fail (subsys != NULL); if (!g_str_equal (subsys, "tty") && !g_str_equal (subsys, "net")) return; key = get_hash_key (subsys, name); /* Find the port */ port = g_hash_table_lookup (self->priv->ports, key); if (!port) { mm_warn ("(%s/%s): cannot release port, not found", subsys, name); g_free (key); return; } if (port == (MMPort *)self->priv->primary) { /* Cancel modem-wide cancellable; no further actions can be done * without a primary port. */ g_cancellable_cancel (self->priv->cancellable); g_clear_object (&self->priv->primary); } l = g_list_find (self->priv->data, port); if (l) { g_object_unref (l->data); self->priv->data = g_list_delete_link (self->priv->data, l); } if (port == (MMPort *)self->priv->secondary) g_clear_object (&self->priv->secondary); if (port == (MMPort *)self->priv->qcdm) g_clear_object (&self->priv->qcdm); if (port == (MMPort *)self->priv->gps_control) g_clear_object (&self->priv->gps_control); if (port == (MMPort *)self->priv->gps) g_clear_object (&self->priv->gps); #if defined WITH_QMI l = g_list_find (self->priv->qmi, port); if (l) { g_object_unref (l->data); self->priv->qmi = g_list_delete_link (self->priv->qmi, l); } #endif /* Remove it from the tracking HT */ mm_dbg ("(%s/%s) type %s released from %s", subsys, name, mm_port_type_get_string (mm_port_get_port_type (port)), mm_port_get_device (port)); g_hash_table_remove (self->priv->ports, key); g_free (key); }
gboolean mm_base_modem_grab_port (MMBaseModem *self, const gchar *subsys, const gchar *name, MMPortType ptype, MMAtPortFlag at_pflags, GError **error) { MMPort *port; gchar *key; g_return_val_if_fail (MM_IS_BASE_MODEM (self), FALSE); g_return_val_if_fail (subsys != NULL, FALSE); g_return_val_if_fail (name != NULL, FALSE); /* Only allow 'tty', 'net' and 'cdc-wdm' ports */ if (!g_str_equal (subsys, "net") && !g_str_equal (subsys, "tty") && !(g_str_has_prefix (subsys, "usb") && g_str_has_prefix (name, "cdc-wdm"))) { g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED, "Cannot add port '%s/%s', unhandled subsystem", subsys, name); return FALSE; } /* Check whether we already have it stored */ key = get_hash_key (subsys, name); port = g_hash_table_lookup (self->priv->ports, key); if (port) { g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED, "Cannot add port '%s/%s', already exists", subsys, name); g_free (key); return FALSE; } /* Serial ports... */ if (g_str_equal (subsys, "tty")) { if (ptype == MM_PORT_TYPE_QCDM) /* QCDM port */ port = MM_PORT (mm_qcdm_serial_port_new (name)); else if (ptype == MM_PORT_TYPE_AT) { /* AT port */ port = MM_PORT (mm_at_serial_port_new (name)); /* Set common response parser */ mm_at_serial_port_set_response_parser (MM_AT_SERIAL_PORT (port), mm_serial_parser_v1_parse, mm_serial_parser_v1_new (), mm_serial_parser_v1_destroy); /* Store flags already */ mm_at_serial_port_set_flags (MM_AT_SERIAL_PORT (port), at_pflags); } else if (ptype == MM_PORT_TYPE_GPS) { /* Raw GPS port */ port = MM_PORT (mm_gps_serial_port_new (name)); } else { g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED, "Cannot add port '%s/%s', unhandled serial type", subsys, name); g_free (key); return FALSE; } /* For serial ports, enable port timeout checks */ g_signal_connect (port, "timed-out", G_CALLBACK (serial_port_timed_out_cb), self); } /* Net ports... */ else if (g_str_equal (subsys, "net")) { port = MM_PORT (g_object_new (MM_TYPE_PORT, MM_PORT_DEVICE, name, MM_PORT_SUBSYS, MM_PORT_SUBSYS_NET, MM_PORT_TYPE, MM_PORT_TYPE_NET, NULL)); } /* QMI ports... */ else if (g_str_has_prefix (subsys, "usb") && g_str_has_prefix (name, "cdc-wdm")) { #if defined WITH_QMI port = MM_PORT (mm_qmi_port_new (name)); #else g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED, "Cannot add port '%s/%s', QMI support not available", subsys, name); g_free (key); return FALSE; #endif } else /* We already filter out before all non-tty, non-net, non-qmi ports */ g_assert_not_reached(); mm_dbg ("(%s) type '%s' claimed by %s", name, mm_port_type_get_string (ptype), mm_base_modem_get_device (self)); /* Add it to the tracking HT. * Note: 'key' and 'port' now owned by the HT. */ g_hash_table_insert (self->priv->ports, key, port); return TRUE; }