From 03e318d5d80b0cfda96efc58e270693eeabe9a79 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Wed, 27 Apr 2011 21:23:25 +0000 Subject: Fix memory leaks. Don't modify model while reading it. git-svn-id: http://svn.drobilla.net/lad/trunk/slv2@3199 a436a847-0d15-0410-975c-d299462d15a1 --- src/plugin.c | 18 ++++------- src/port.c | 18 +++++------ src/slv2_internal.h | 15 +++++++-- src/value.c | 9 ++++-- src/world.c | 93 ++++++++++++++++++++++++++++------------------------- 5 files changed, 85 insertions(+), 68 deletions(-) (limited to 'src') diff --git a/src/plugin.c b/src/plugin.c index 02fa051..7b22707 100644 --- a/src/plugin.c +++ b/src/plugin.c @@ -352,7 +352,7 @@ slv2_plugin_get_class(SLV2Plugin p) p->world->rdf_a_node, NULL); FOREACH_MATCH(results) { - SLV2Node class_node = slv2_node_copy(slv2_match_object(results)); + SLV2Node class_node = slv2_match_object(results); if (sord_node_get_type(class_node) != SORD_URI) { continue; } @@ -363,8 +363,6 @@ slv2_plugin_get_class(SLV2Plugin p) SLV2PluginClass plugin_class = slv2_plugin_classes_get_by_uri( p->world->plugin_classes, class); - slv2_node_free(p->world, class_node); - if (plugin_class) { p->plugin_class = plugin_class; slv2_value_free(class); @@ -480,14 +478,12 @@ slv2_plugin_get_value_for_subject(SLV2Plugin p, : sord_new_blank(p->world->world, (const uint8_t*)slv2_value_as_blank(subject)); - if (!subject_node) { - fprintf(stderr, "No such subject\n"); - return NULL; - } + SLV2Values ret = slv2_plugin_query_node(p, + subject_node, + predicate->val.uri_val); - return slv2_plugin_query_node(p, - subject_node, - predicate->val.uri_val); + slv2_node_free(p->world, subject_node); + return ret; } SLV2_API @@ -717,7 +713,7 @@ slv2_plugin_get_author(SLV2Plugin p) return NULL; } - SLV2Node author = slv2_node_copy(slv2_match_object(maintainers)); + SLV2Node author = slv2_match_object(maintainers); slv2_match_end(maintainers); return author; diff --git a/src/port.c b/src/port.c index 7408481..f1346b4 100644 --- a/src/port.c +++ b/src/port.c @@ -61,23 +61,23 @@ slv2_port_get_node(SLV2Plugin p, { SLV2Matches ports = slv2_plugin_find_statements( p, - slv2_node_copy(p->plugin_uri->val.uri_val), - slv2_node_copy(p->world->lv2_port_node), + p->plugin_uri->val.uri_val, + p->world->lv2_port_node, NULL); SLV2Node ret = NULL; FOREACH_MATCH(ports) { SLV2Node node = slv2_match_object(ports); SLV2Value symbol = slv2_plugin_get_unique( p, - slv2_node_copy(node), - slv2_node_copy(p->world->lv2_symbol_node)); + node, + p->world->lv2_symbol_node); const bool matches = slv2_value_equals(symbol, slv2_port_get_symbol(p, port)); slv2_value_free(symbol); if (matches) { - ret = slv2_node_copy(node); + ret = node; break; } } @@ -276,13 +276,13 @@ slv2_port_get_scale_points(SLV2Plugin p, SLV2Value value = slv2_plugin_get_unique( p, - slv2_node_copy(point), - slv2_node_copy(p->world->rdf_value_node)); + point, + p->world->rdf_value_node); SLV2Value label = slv2_plugin_get_unique( p, - slv2_node_copy(point), - slv2_node_copy(p->world->rdfs_label_node)); + point, + p->world->rdfs_label_node); if (value && label) { slv2_array_append(ret, slv2_scale_point_new(value, label)); diff --git a/src/slv2_internal.h b/src/slv2_internal.h index 9f1658b..539232a 100644 --- a/src/slv2_internal.h +++ b/src/slv2_internal.h @@ -98,6 +98,16 @@ struct _SLV2Port { SLV2Port slv2_port_new(SLV2World world, uint32_t index, const char* symbol); void slv2_port_free(SLV2Port port); +/* ********* Spec ********* */ + +struct _SLV2Spec { + SLV2Node spec; + SLV2Node bundle; + SLV2Values data_uris; +}; + +typedef struct _SLV2Spec* SLV2Spec; + /* ********* Plugin ********* */ /** Header of an SLV2Plugin, SLV2PluginClass, or SLV2UI. @@ -221,6 +231,7 @@ struct _SLV2World { unsigned n_read_files; SLV2PluginClass lv2_plugin_class; SLV2PluginClasses plugin_classes; + GSList* specs; SLV2Plugins plugins; SLV2Node dc_replaces_node; SLV2Node dyn_manifest_node; @@ -241,7 +252,6 @@ struct _SLV2World { SLV2Node rdfs_label_node; SLV2Node rdfs_seealso_node; SLV2Node rdfs_subclassof_node; - SLV2Node slv2_bundleuri_node; SLV2Node slv2_dmanifest_node; SLV2Node xsd_boolean_node; SLV2Node xsd_decimal_node; @@ -290,7 +300,7 @@ typedef enum _SLV2ValueType { } SLV2ValueType; struct _SLV2Value { - SLV2ValueType type; + SLV2World world; char* str_val; ///< always present union { int int_val; @@ -298,6 +308,7 @@ struct _SLV2Value { bool bool_val; SLV2Node uri_val; } val; + SLV2ValueType type; }; SLV2Value slv2_value_new(SLV2World world, SLV2ValueType type, const char* val); diff --git a/src/value.c b/src/value.c index fd53197..e39e860 100644 --- a/src/value.c +++ b/src/value.c @@ -68,7 +68,8 @@ SLV2Value slv2_value_new(SLV2World world, SLV2ValueType type, const char* str) { SLV2Value val = (SLV2Value)malloc(sizeof(struct _SLV2Value)); - val->type = type; + val->world = world; + val->type = type; switch (type) { case SLV2_VALUE_URI: @@ -101,6 +102,7 @@ slv2_value_new_from_node(SLV2World world, SordNode node) case SORD_URI: type = SLV2_VALUE_URI; result = (SLV2Value)malloc(sizeof(struct _SLV2Value)); + result->world = world; result->type = SLV2_VALUE_URI; result->val.uri_val = slv2_node_copy(node); result->str_val = (char*)sord_node_get_string(result->val.uri_val); @@ -192,6 +194,7 @@ slv2_value_duplicate(SLV2Value val) return val; SLV2Value result = (SLV2Value)malloc(sizeof(struct _SLV2Value)); + result->world = val->world; result->type = val->type; if (val->type == SLV2_VALUE_URI) { @@ -210,7 +213,9 @@ void slv2_value_free(SLV2Value val) { if (val) { - if (val->type != SLV2_VALUE_URI) { + if (val->type == SLV2_VALUE_URI) { + slv2_node_free(val->world, val->val.uri_val); + } else { free(val->str_val); } free(val); diff --git a/src/world.c b/src/world.c index bd515b4..26114e3 100644 --- a/src/world.c +++ b/src/world.c @@ -52,6 +52,7 @@ slv2_world_new() if (!world->model) goto fail; + world->specs = NULL; world->plugin_classes = slv2_plugin_classes_new(); world->plugins = slv2_plugins_new(); @@ -59,8 +60,7 @@ slv2_world_new() #define NS_DC (const uint8_t*)"http://dublincore.org/documents/dcmi-namespace/" #define NEW_URI(uri) sord_new_uri(world->world, uri) -#define NEW_URI_VAL(uri) slv2_value_new_from_node( \ - world, sord_new_uri(world->world, uri)); +#define NEW_URI_VAL(uri) slv2_value_new_uri(world, (const char*)(uri)); world->dc_replaces_node = NEW_URI(NS_DC "replaces"); world->dyn_manifest_node = NEW_URI(NS_DYNMAN "DynManifest"); @@ -81,7 +81,6 @@ slv2_world_new() world->rdfs_label_node = NEW_URI(SLV2_NS_RDFS "label"); world->rdfs_seealso_node = NEW_URI(SLV2_NS_RDFS "seeAlso"); world->rdfs_subclassof_node = NEW_URI(SLV2_NS_RDFS "subClassOf"); - world->slv2_bundleuri_node = NEW_URI(SLV2_NS_SLV2 "bundleURI"); world->slv2_dmanifest_node = NEW_URI(SLV2_NS_SLV2 "dynamic-manifest"); world->xsd_boolean_node = NEW_URI(SLV2_NS_XSD "boolean"); world->xsd_decimal_node = NEW_URI(SLV2_NS_XSD "decimal"); @@ -140,7 +139,6 @@ slv2_world_free(SLV2World world) slv2_node_free(world, world->rdfs_seealso_node); slv2_node_free(world, world->rdfs_subclassof_node); slv2_node_free(world, world->rdfs_class_node); - slv2_node_free(world, world->slv2_bundleuri_node); slv2_node_free(world, world->slv2_dmanifest_node); slv2_node_free(world, world->xsd_boolean_node); slv2_node_free(world, world->xsd_decimal_node); @@ -149,6 +147,16 @@ slv2_world_free(SLV2World world) slv2_value_free(world->doap_name_val); slv2_value_free(world->lv2_name_val); + for (GSList* l = world->specs; l; l = l->next) { + SLV2Spec spec = (SLV2Spec)l->data; + slv2_node_free(world, spec->spec); + slv2_node_free(world, spec->bundle); + slv2_values_free(spec->data_uris); + //free(spec); + } + g_slist_free_full(world->specs, free); + world->specs = NULL; + SLV2_FOREACH(i, world->plugins) { SLV2Plugin p = slv2_plugins_get(world->plugins, i); slv2_plugin_free(p); @@ -263,6 +271,34 @@ slv2_sequence_get_by_uri(GSequence* seq, return NULL; } +static void +slv2_world_add_spec(SLV2World world, + SLV2Node specification_node, + SLV2Node bundle_node) +{ + SLV2Spec spec = malloc(sizeof(struct _SLV2Spec)); + spec->spec = slv2_node_copy(specification_node); + spec->bundle = slv2_node_copy(bundle_node); + spec->data_uris = slv2_values_new(); + + // Add all plugin data files (rdfs:seeAlso) + SLV2Matches files = slv2_world_find_statements( + world, world->model, + specification_node, + world->rdfs_seealso_node, + NULL, + NULL); + FOREACH_MATCH(files) { + SLV2Node file_node = slv2_match_object(files); + slv2_array_append(spec->data_uris, + slv2_value_new_from_node(world, file_node)); + } + slv2_match_end(files); + + // Add specification to world specification sequence + world->specs = g_slist_prepend(world->specs, spec); +} + static void slv2_world_add_plugin(SLV2World world, SLV2Node plugin_node, @@ -351,7 +387,7 @@ slv2_world_load_dyn_manifest(SLV2World world, } // Get binary path - SLV2Node binary = slv2_node_copy(slv2_match_object(binaries)); + SLV2Node binary = slv2_match_object(binaries); const uint8_t* lib_uri = sord_node_get_string(binary); const char* lib_path = slv2_uri_to_path((const char*)lib_uri); if (!lib_path) { @@ -460,24 +496,7 @@ slv2_world_load_bundle(SLV2World world, SLV2Value bundle_uri) bundle_node); FOREACH_MATCH(spec_results) { SLV2Node spec = slv2_match_subject(spec_results); - - // Add ?specification rdfs:seeAlso - SordQuad see_also_tup = { - slv2_node_copy(spec), - slv2_node_copy(world->rdfs_seealso_node), - sord_new_uri(world->world, manifest_uri.buf), - NULL - }; - sord_add(world->model, see_also_tup); - - // Add ?specification slv2:bundleURI - SordQuad bundle_uri_tup = { - slv2_node_copy(spec), - slv2_node_copy(world->slv2_bundleuri_node), - slv2_node_copy(bundle_uri->val.uri_val), - NULL - }; - sord_add(world->model, bundle_uri_tup); + slv2_world_add_spec(world, spec, bundle_node); } slv2_match_end(spec_results); @@ -609,30 +628,16 @@ slv2_world_load_path(SLV2World world, static void slv2_world_load_specifications(SLV2World world) { - SLV2Matches specs = slv2_world_find_statements( - world, world->model, - NULL, - world->rdf_a_node, - world->lv2_specification_node, - NULL); - FOREACH_MATCH(specs) { - SLV2Node spec_node = slv2_match_subject(specs); - SLV2Matches files = slv2_world_find_statements( - world, world->model, - spec_node, - world->rdfs_seealso_node, - NULL, - NULL); - FOREACH_MATCH(files) { - SLV2Node file_node = slv2_match_object(files); + for (GSList* l = world->specs; l; l = l->next) { + SLV2Spec spec = (SLV2Spec)l->data; + SLV2_FOREACH(f, spec->data_uris) { + SLV2Value file = slv2_collection_get(spec->data_uris, f); sord_read_file(world->model, - (const uint8_t*)sord_node_get_string(file_node), + (const uint8_t*)slv2_value_as_uri(file), NULL, slv2_world_blank_node_prefix(world)); } - slv2_match_end(files); } - slv2_match_end(specs); } static void @@ -666,7 +671,7 @@ slv2_world_load_plugin_classes(SLV2World world) continue; } - SLV2Node parent_node = slv2_node_copy(slv2_match_object(parents)); + SLV2Node parent_node = slv2_match_object(parents); slv2_match_end(parents); if (!sord_node_get_type(parent_node) == SORD_URI) { @@ -687,7 +692,7 @@ slv2_world_load_plugin_classes(SLV2World world) continue; } - SLV2Node label_node = slv2_node_copy(slv2_match_object(labels)); + SLV2Node label_node = slv2_match_object(labels); const uint8_t* label = (const uint8_t*)sord_node_get_string(label_node); slv2_match_end(labels); -- cgit v1.2.1