FOSSology  4.4.0
Open Source License Compliance by Open Source Software
license.c
1 /*
2  Author: Daniele Fognini, Andreas Wuerl
3  SPDX-FileCopyrightText: © 2013-2015 Siemens AG
4 
5  SPDX-License-Identifier: GPL-2.0-only
6 */
7 
8 #include <glib.h>
9 
10 #include "license.h"
11 #include "string_operations.h"
12 #include "monk.h"
13 
14 static char* ignoredLicenseNames[] = {"Void", "No_license_found"};
15 static char* ignoredLicenseTexts[] = {"License by Nomos.", "License by Ninka."};
16 
17 int isIgnoredLicense(const License* license) {
18 
19  int ignoredLicenseNamesCount = sizeof(ignoredLicenseNames)/sizeof(char*);
20  for (int i = 0; i < ignoredLicenseNamesCount; i++) {
21  if (strcmp(license->shortname, ignoredLicenseNames[i]) == 0)
22  return 1;
23  }
24 
25  int ignoredLicenseTextsCount = sizeof(ignoredLicenseTexts)/sizeof(char*);
26  for (int i = 0; i < ignoredLicenseTextsCount; i++) {
27  GArray* ignoredTokens = tokenize(ignoredLicenseTexts[i], DELIMITERS);
28  if (tokensEquals(license->tokens, ignoredTokens)) {
29  tokens_free(ignoredTokens);
30  return 1;
31  }
32  tokens_free(ignoredTokens);
33  }
34 
35  return 0;
36 }
37 
38 Licenses* extractLicenses(fo_dbManager* dbManager, PGresult* licensesResult, unsigned minAdjacentMatches, unsigned maxLeadingDiff) {
39  GArray* licenses = g_array_new(TRUE, FALSE, sizeof (License));
40 
41  for (int j = 0; j < PQntuples(licensesResult); j++) {
42  long refId = atol(PQgetvalue(licensesResult, j, 0));
43  char* licShortName = PQgetvalue(licensesResult, j, 1);
44 
46  license.refId = refId;
47  license.shortname = g_strdup(licShortName);
48 
49  char* licenseText = getLicenseTextForLicenseRefId(dbManager, refId);
50  GArray* licenseTokens = tokenize(licenseText, DELIMITERS);
51 
52  free(licenseText);
53  license.tokens = licenseTokens;
54 
55  if (!isIgnoredLicense(&license))
56  g_array_append_val(licenses, license);
57  else {
58  tokens_free(license.tokens);
59  g_free(license.shortname);
60  }
61  }
62 
63  return buildLicenseIndexes(licenses, minAdjacentMatches, maxLeadingDiff);
64 }
65 
66 void licenses_free(Licenses* licenses) {
67  if (licenses) {
68  GArray* licenseArray = licenses->licenses;
69  for (guint i = 0; i < licenseArray->len; i++) {
70  License* license = license_index(licenseArray, i);
71  tokens_free(license->tokens);
72  if (license->shortname) {
73  g_free(license->shortname);
74  }
75  }
76 
77  g_array_free(licenseArray, TRUE);
78 
79  g_array_free(licenses->shortLicenses, TRUE);
80 
81  GArray* indexes = licenses->indexes;
82  for (guint i = 0; i < indexes->len; i++) {
83  GHashTable* index = g_array_index(indexes, GHashTable*, i);
84  g_hash_table_unref(index);
85  }
86  g_array_free(indexes, TRUE);
87 
88  free(licenses);
89  }
90 }
91 
92 guint uint32_hash (gconstpointer v) {
93  uint32_t u = *(uint32_t*)v;
94  return u;
95 }
96 
97 gboolean uint32_equal (gconstpointer v1, gconstpointer v2) {
98  uint32_t u1 = *(uint32_t*)v1;
99  uint32_t u2 = *(uint32_t*)v2;
100 
101  return u1 == u2;
102 }
103 
104 static void g_array_free_true(void* ptr) {
105  g_array_free(ptr, TRUE);
106 }
107 
108 uint32_t getKey(const GArray* tokens, unsigned minAdjacentMatches, unsigned searchedStart) {
109  uint32_t result = 1;
110  for (guint i = 0; (i < minAdjacentMatches) && (i+searchedStart < tokens->len); i++)
111  {
112  Token* nToken = tokens_index(tokens, i+searchedStart);
113  result = (result << 1) + nToken->hashedContent;
114  }
115 
116  return result;
117 }
118 
119 Licenses* buildLicenseIndexes(GArray* licenses, unsigned minAdjacentMatches, unsigned maxLeadingDiff) {
120  Licenses* result = malloc(sizeof(Licenses));
121  if (!result)
122  return NULL;
123 
124 #define is_short(license) ( (license)->tokens->len <= minAdjacentMatches )
125  GArray* shortLicenses = g_array_new(FALSE, FALSE, sizeof(License));
126  for (guint i = 0; i < licenses->len; i++) {
127  License* license = license_index(licenses, i);
128  if (is_short(license)) {
129  g_array_append_val(shortLicenses, *license);
130  }
131  }
132 
133  GArray* indexes = g_array_new(FALSE, FALSE, sizeof(GHashTable*));
134 
135  for (unsigned sPos = 0; sPos <= maxLeadingDiff; sPos++) {
136  GHashTable* index = g_hash_table_new_full(uint32_hash, uint32_equal, free, g_array_free_true);
137  g_array_append_val(indexes, index);
138 
139  for (guint i = 0; i < licenses->len; i++) {
140  License* license = license_index(licenses, i);
141  if (!is_short(license)) {
142  uint32_t* key = malloc(sizeof(uint32_t));
143  *key = getKey(license->tokens, minAdjacentMatches, sPos);
144 
145  GArray* indexedLicenses = g_hash_table_lookup(index, key);
146  if (!indexedLicenses)
147  {
148  indexedLicenses = g_array_new(FALSE, FALSE, sizeof(License));
149  g_hash_table_replace(index, key, indexedLicenses);
150  } else {
151  free(key);
152  }
153  g_array_append_val(indexedLicenses, *license);
154  }
155  }
156  }
157 #undef is_short
158 
159  result->licenses = licenses;
160  result->shortLicenses = shortLicenses;
161  result->indexes = indexes;
162  result->minAdjacentMatches = minAdjacentMatches;
163 
164  return result;
165 }
166 
167 const GArray* getShortLicenseArray(const Licenses* licenses) {
168  return licenses->shortLicenses;
169 }
170 
171 const GArray* getLicenseArrayFor(const Licenses* licenses, unsigned searchPos, const GArray* searchedTokens, unsigned searchedStart) {
172  const GArray* indexes = licenses->indexes;
173 
174  guint minAdjacentMatches = licenses->minAdjacentMatches;
175 
176  if (indexes->len <= searchPos) {
177  return licenses->licenses;
178  }
179 
180  GHashTable* index = g_array_index(indexes, GHashTable*, searchPos);
181  uint32_t key = getKey(searchedTokens, minAdjacentMatches, searchedStart);
182  GArray* result = g_hash_table_lookup(index, &key);
183  return result;
184 }
fo_dbManager * dbManager
fo_dbManager object
Definition: process.c:16
Definition: monk.h:55
Definition: monk.h:67
Definition: nomos.h:426