diff options
Diffstat (limited to 'cli/spdxtool/core.c')
| -rw-r--r-- | cli/spdxtool/core.c | 113 |
1 files changed, 111 insertions, 2 deletions
diff --git a/cli/spdxtool/core.c b/cli/spdxtool/core.c index 5cf7f10e81e1..7dc7a8b41cce 100644 --- a/cli/spdxtool/core.c +++ b/cli/spdxtool/core.c @@ -222,8 +222,15 @@ spdxtool_core_creation_info_to_object(pkgconf_client_t *client, const spdxtool_c if (!(spdxtool_serialize_object_add_string(object_list, "type", creation->type) && spdxtool_serialize_object_add_string(object_list, "@id", creation->id) && - spdxtool_serialize_object_add_string(object_list, "created", creation->created) && - spdxtool_serialize_object_add_array(object_list, "createdBy", created_by) && + spdxtool_serialize_object_add_string(object_list, "created", creation->created))) + { + /* created_by has not been handed to the object list yet */ + spdxtool_serialize_array_free(created_by); + goto err; + } + + /* object_add_array takes ownership of created_by, freeing it on failure */ + if (!(spdxtool_serialize_object_add_array(object_list, "createdBy", created_by) && spdxtool_serialize_object_add_string(object_list, "specVersion", creation->spec_version))) { goto err; @@ -329,6 +336,13 @@ spdxtool_core_spdx_document_free(spdxtool_core_spdx_document_t *spdx) free(iter); } + PKGCONF_FOREACH_LIST_ENTRY_SAFE(spdx->maintainers.head, iter_next, iter) + { + spdxtool_core_agent_t *maintainer = iter->data; + spdxtool_core_agent_free(maintainer); + free(iter); + } + PKGCONF_FOREACH_LIST_ENTRY_SAFE(spdx->packages.head, iter_next, iter) { free(iter); @@ -547,6 +561,60 @@ spdxtool_core_spdx_document_add_element(pkgconf_client_t *client, spdxtool_core_ /* * !doc * + * .. c:function:: const char *spdxtool_core_spdx_document_add_maintainer(pkgconf_client_t *client, spdxtool_core_spdx_document_t *spdx, const char *name) + * + * Register a package maintainer as an Agent and add it to the SpdxDocument so that + * packages may reference it via their ``suppliedBy`` field. Maintainers are + * deduplicated by their spdxId, so a maintainer shared between packages is only + * emitted once. The first time a maintainer is seen, its spdxId is also added to + * the document element list. + * + * :param pkgconf_client_t *client: The pkgconf client being accessed. + * :param spdxtool_core_spdx_document_t *spdx: SpdxDocument struct being used. + * :param const char *name: Maintainer name as declared in the package. + * :return: the maintainer Agent spdxId (owned by the document) on success, NULL on failure + */ +const char * +spdxtool_core_spdx_document_add_maintainer(pkgconf_client_t *client, spdxtool_core_spdx_document_t *spdx, const char *name) +{ + pkgconf_node_t *iter = NULL; + + if (!client || !spdx || !name) + return NULL; + + spdxtool_core_agent_t *agent = spdxtool_core_agent_new(client, spdx->creation_info, name); + if (!agent) + return NULL; + + PKGCONF_FOREACH_LIST_ENTRY(spdx->maintainers.head, iter) + { + spdxtool_core_agent_t *existing = iter->data; + if (!strcmp(existing->spdx_id, agent->spdx_id)) + { + spdxtool_core_agent_free(agent); + return existing->spdx_id; + } + } + + pkgconf_node_t *node = calloc(1, sizeof(pkgconf_node_t)); + if (!node) + { + pkgconf_error(client, "spdxtool_core_spdx_document_add_maintainer: out of memory"); + spdxtool_core_agent_free(agent); + return NULL; + } + + pkgconf_node_insert_tail(node, agent, &spdx->maintainers); + + if (!spdxtool_core_spdx_document_add_element(client, spdx, agent->spdx_id)) + return NULL; + + return agent->spdx_id; +} + +/* + * !doc + * * .. c:function:: bool spdxtool_core_spdx_document_add_relationship(pkgconf_client_t *client, spdxtool_core_spdx_document_t *spdx, spdxtool_core_relationship_t *relationship) * * Add relationship rel to SpdxDocument @@ -650,6 +718,40 @@ err: /* * !doc * + * .. c:function:: bool spdxtool_core_relationship_set_scope(pkgconf_client_t *client, spdxtool_core_relationship_t *relationship, const char *scope) + * + * Promote a relationship to a /Core/LifecycleScopedRelationship by attaching a lifecycle + * scope (for example, ``development`` for a private build dependency). This is the SPDX 3.0 + * representation of SPDX 2.x's ``*_DEPENDENCY_OF`` relationship variants. + * + * :param pkgconf_client_t *client: The pkgconf client being accessed. + * :param spdxtool_core_relationship_t *relationship: Relationship struct to scope. + * :param const char *scope: LifecycleScopeType value, e.g. "development". + * :return: true on success, false on failure + */ +bool +spdxtool_core_relationship_set_scope(pkgconf_client_t *client, spdxtool_core_relationship_t *relationship, const char *scope) +{ + if (!relationship || !scope) + return false; + + char *scope_copy = strdup(scope); + if (!scope_copy) + { + pkgconf_error(client, "spdxtool_core_relationship_set_scope: out of memory"); + return false; + } + + free(relationship->scope); + relationship->scope = scope_copy; + relationship->type = "LifecycleScopedRelationship"; + + return true; +} + +/* + * !doc + * * .. c:function:: void spdxtool_core_relationship_free(spdxtool_core_relationship_t *relationship) * * Free /Core/Relationship struct @@ -669,6 +771,7 @@ spdxtool_core_relationship_free(spdxtool_core_relationship_t *relationship) pkgconf_license_free(relationship->to); free(relationship->to); free(relationship->relationship_type); + free(relationship->scope); free(relationship); } @@ -717,6 +820,12 @@ spdxtool_core_relationship_to_object(pkgconf_client_t *client, const spdxtool_co goto err; } + if (relationship->scope != NULL && + !spdxtool_serialize_object_add_string(object_list, "scope", relationship->scope)) + { + goto err; + } + ret = spdxtool_serialize_value_object(object_list); object_list = NULL; |
