SOL_API struct sol_flow_node * sol_flow_node_new(struct sol_flow_node *parent, const char *id, const struct sol_flow_node_type *type, const struct sol_flow_node_options *options) { struct sol_flow_node *node; int err; SOL_NULL_CHECK(type, NULL); SOL_FLOW_NODE_TYPE_API_CHECK(type, SOL_FLOW_NODE_TYPE_API_VERSION, NULL); node = calloc(1, sizeof(*node) + type->data_size); SOL_NULL_CHECK(node, NULL); if (!options) options = type->default_options; if (!options) options = &sol_flow_node_options_empty; err = sol_flow_node_init(node, parent, id, type, options); if (err < 0) { free(node); node = NULL; errno = -err; } return node; }
SOL_API struct sol_flow_node * sol_flow_node_new(struct sol_flow_node *parent, const char *id, const struct sol_flow_node_type *type, const struct sol_flow_node_options *options) { struct sol_flow_node *node; int err; bool free_opts = false; SOL_NULL_CHECK(type, NULL); SOL_FLOW_NODE_TYPE_API_CHECK(type, SOL_FLOW_NODE_TYPE_API_VERSION, NULL); node = calloc(1, sizeof(*node) + type->data_size); SOL_NULL_CHECK(node, NULL); if (!options) { options = sol_flow_node_get_options(type, NULL); free_opts = true; } err = sol_flow_node_init(node, parent, id, type, options); if (err < 0) { free(node); node = NULL; errno = -err; } if (free_opts) sol_flow_node_free_options(type, (struct sol_flow_node_options *)options); return node; }
/* Update libsoletta-gdb.py before changing the function and parameters below. */ int sol_flow_node_init(struct sol_flow_node *node, struct sol_flow_node *parent, const char *name, const struct sol_flow_node_type *type, const struct sol_flow_node_options *options) { struct sol_flow_node_container_type *parent_type = NULL; SOL_NULL_CHECK(type, -EINVAL); SOL_NULL_CHECK(node, -EINVAL); SOL_NULL_CHECK(type->get_ports_counts, -EINVAL); SOL_FLOW_NODE_TYPE_API_CHECK(type, SOL_FLOW_NODE_TYPE_API_VERSION, -EINVAL); SOL_FLOW_NODE_OPTIONS_API_CHECK(options, SOL_FLOW_NODE_OPTIONS_API_VERSION, -EINVAL); if (type->init_type) type->init_type(); node->type = type; if (parent) { SOL_FLOW_NODE_TYPE_IS_CONTAINER_CHECK(parent, -EINVAL); node->parent = parent; parent_type = (struct sol_flow_node_container_type *)parent->type; if (parent_type->add) parent_type->add(parent, node); } if (name) node->id = strdup(name); if (type->open) { int r = type->open(node, node->data, options); if (r < 0) { if (parent_type) { if (parent_type->remove) parent_type->remove(parent, node); } SOL_WRN("failed to create node of type=%p: %s", type, sol_util_strerrora(-r)); free(node->id); node->id = NULL; return r; } } inspector_did_open_node(node, options); return 0; }
static bool resolve_module_type_foreach(void *data, const struct sol_flow_node_type *type) { struct resolve_module_type_foreach_ctx *ctx = data; SOL_FLOW_NODE_TYPE_API_CHECK(type, SOL_FLOW_NODE_TYPE_API_VERSION, true); if (!type->description || !type->description->name) return true; if (!streq(type->description->name, ctx->name)) return true; ctx->found = type; return false; }
SOL_API int sol_flow_node_options_new( const struct sol_flow_node_type *type, const struct sol_flow_node_named_options *named_opts, struct sol_flow_node_options **out_opts) { #ifndef SOL_FLOW_NODE_TYPE_DESCRIPTION_ENABLED SOL_WRN("This function needs NODE_DESCRIPTION=y in the build config."); return -ENOTSUP; #else struct sol_flow_node_options *tmp_opts; const struct sol_flow_node_type_description *desc; bool has_options; SOL_NULL_CHECK(type, -EINVAL); SOL_NULL_CHECK(named_opts, -EINVAL); SOL_FLOW_NODE_TYPE_API_CHECK(type, SOL_FLOW_NODE_TYPE_API_VERSION, -EINVAL); #ifndef SOL_NO_API_VERSION SOL_INT_CHECK(type->options_size, < sizeof(struct sol_flow_node_options), -EINVAL); #endif if (type->init_type) type->init_type(); SOL_NULL_CHECK(type->description, -EINVAL); desc = type->description; has_options = desc->options && desc->options->members; if (!has_options && named_opts->count > 0) { /* TODO: improve the error handling here so caller knows more * details about this. */ return -EINVAL; } tmp_opts = malloc(type->options_size); if (!tmp_opts) return -errno; if (type->default_options) { const struct sol_flow_node_options_member_description *member; memcpy(tmp_opts, type->default_options, type->options_size); if (has_options) { /* Copy the strings because options_from_strv may override * some of the strings and we can't distinguish between * them at deletion time. */ for (member = type->description->options->members; member->name; member++) { if (streq(member->data_type, "string")) { char **s = (char **)((char *)(tmp_opts) + member->offset); if (*s) *s = strdup(*s); } } if (!fill_options_with_named_options(tmp_opts, desc->options, named_opts)) { sol_flow_node_options_del(type, tmp_opts); return -EINVAL; } } } else { memset(tmp_opts, 0, type->options_size); memcpy(tmp_opts, &sol_flow_node_options_empty, sizeof(sol_flow_node_options_empty)); } *out_opts = tmp_opts; return 0; #endif }