#include #include #include #include #include #include #include #include #include struct mie_select_graph *mie_select_graph_create(struct mie_ctx *ctx) { struct mie_select_graph *out = malloc(sizeof *out); if (!out) { return NULL; } memset(out, 0x0, sizeof *out); enum mie_status status = MIE_SUCCESS; struct mie_select_node *entry; struct mie_type *entry_values[] = { mie_ctx_get_type(ctx, MIE_TYPE_OTHER), mie_ctx_get_type(ctx, MIE_TYPE_GLUE), }; const size_t nr_entry_values = sizeof entry_values / sizeof entry_values[0]; status = mie_select_graph_get_node( out, mie_target_builtin(), MIE_SELECT_OP_ENTRY, NULL, 0, entry_values, nr_entry_values, &entry); if (status != MIE_SUCCESS) { free(out); return NULL; } mie_select_node_get_value(entry, entry_values[0], 0, &out->g_entry); return out; } void mie_select_graph_destroy(struct mie_select_graph *graph) { b_queue_entry *entry = b_queue_first(&graph->g_nodes); while (entry) { struct mie_select_node *node = b_unbox(struct mie_select_node, entry, n_entry); b_queue_entry *next = b_queue_next(entry); b_queue_delete(&graph->g_nodes, entry); #if 0 if (node->n_value) { mie_value_destroy(node->n_value); } #endif free(node); entry = next; } free(graph); } enum mie_status mie_select_graph_get_node( struct mie_select_graph *graph, const struct mie_target *target, unsigned int op, struct mie_select_value **operands, size_t nr_operands, struct mie_type **values, size_t nr_values, struct mie_select_node **out) { struct mie_select_node *node = mie_select_node_create( mie_target_builtin(), op, values, nr_values); if (!node) { return MIE_ERR_NO_MEMORY; } struct mie_select_value *operands2 = calloc(nr_operands, sizeof *operands2); for (size_t i = 0; i < nr_operands; i++) { assert(operands[i]); memcpy(&operands2[i], operands[i], sizeof *operands2); } mie_select_node_set_operands(node, operands2, nr_operands); free(operands2); node->n_id = graph->g_node_id++; node->n_target = target; for (size_t i = 0; i < nr_values; i++) { if (values[i]->t_id == MIE_TYPE_OTHER) { graph->g_last_chain.v_node = node; graph->g_last_chain.v_index = i; } } b_queue_push_back(&graph->g_nodes, &node->n_entry); *out = node; return MIE_SUCCESS; }