]> git.ozlabs.org Git - ccan/blob - tools/ccanlint/licenses.c
tools: manifest.c should use path_canon.
[ccan] / tools / ccanlint / licenses.c
1 #include "licenses.h"
2 #include "ccanlint.h"
3 #include <ccan/str/str.h>
4 #include <ccan/tal/tal.h>
5 #include <ccan/tal/str/str.h>
6
7 const struct license_info licenses[] = {
8         { "LGPLv2+", "LGPL",
9           { "gnu lesser general public license",
10             "version 2",
11             "or at your option any later version"
12           }
13         },
14         { "LGPLv2", "LGPL",
15           { "gnu lesser general public license",
16             "version 2",
17             NULL
18           }
19         },
20         { "LGPLv3", "LGPL",
21           { "gnu lesser general public license",
22             "version 3",
23             NULL
24           }
25         },
26         { "LGPL", "LGPL",
27           { "gnu lesser general public license",
28             NULL,
29             NULL
30           }
31         },
32         { "GPLv2+", "GPL",
33           { "gnu general public license",
34             "version 2",
35             "or at your option any later version"
36           }
37         },
38         { "GPLv2", "GPL",
39           { "gnu general public license",
40             "version 2",
41             NULL
42           }
43         },
44         { "GPLv3", "GPL",
45           { "gnu general public license",
46             "version 3",
47             NULL
48           }
49         },
50         { "GPL", "GPL",
51           { "gnu general public license",
52             NULL,
53             NULL
54           }
55         },
56         { "BSD-3CLAUSE", "BSD",
57           { "redistributions of source code must retain",
58             "redistributions in binary form must reproduce",
59             "endorse or promote"
60           }
61         },
62         { "BSD-MIT", "MIT",
63           { "without restriction",
64             "above copyright notice",
65             "without warranty"
66           }
67         },
68         { "CC0", "CC0",
69           { "Waiver.",
70             "unconditionally waives",
71             NULL
72           }
73         },
74         { "Public domain", "Public domain",
75           { NULL, NULL, NULL  }
76         },
77         { "Unknown license", "Unknown license",
78           { NULL, NULL, NULL  }
79         },
80 };
81
82 /* License compatibilty chart (simplified: we don't test that licenses between
83  * files are compatible). */
84 #define O true
85 #define X false
86 bool license_compatible[LICENSE_UNKNOWN+1][LICENSE_UNKNOWN] = {
87 /*     LGPL2+   LGPL3   GPL2+   GPL3     BSD     CC0
88             LGPL2    LGPL   GPL2     GPL     MIT     PD   */
89 /* _info says: LGPL2+ */
90         { O,  X,  X,  O,  X,  X,  X,  X,  O,  O,  O,  O },
91 /* _info says: LGPL2 only */
92         { O,  O,  X,  O,  X,  X,  X,  X,  O,  O,  O,  O },
93 /* _info says: LGPL3 (or any later version) */
94         { O,  X,  O,  O,  X,  X,  X,  X,  O,  O,  O,  O },
95 /* _info says: LGPL (no version specified) */
96         { O,  O,  O,  O,  X,  X,  X,  X,  O,  O,  O,  O },
97 /* _info says: GPL2+ */
98         { O,  O,  O,  O,  O,  X,  X,  O,  O,  O,  O,  O },
99 /* _info says: GPL2 only */
100         { O,  O,  O,  O,  O,  O,  X,  O,  O,  O,  O,  O },
101 /* _info says: GPL3 (or any later version) */
102         { O,  O,  O,  O,  O,  X,  O,  O,  O,  O,  O,  O },
103 /* _info says: GPL (unknown version) */
104         { O,  O,  O,  O,  O,  O,  O,  O,  O,  O,  O,  O },
105 /* _info says: BSD (3-clause) */
106         { X,  X,  X,  X,  X,  X,  X,  X,  O,  O,  O,  O },
107 /* _info says: MIT */
108         { X,  X,  X,  X,  X,  X,  X,  X,  X,  O,  O,  O },
109 /* _info says: CC0 */
110         { X,  X,  X,  X,  X,  X,  X,  X,  X,  X,  O,  O },
111 /* _info says: Public domain */
112         { X,  X,  X,  X,  X,  X,  X,  X,  X,  X,  O,  O },
113 /* _info says something we don't understand */
114         { X,  X,  X,  X,  X,  X,  X,  X,  X,  X,  O,  O }
115 };
116 #undef X
117 #undef O
118
119 /* See GPLv2 and v2 (basically same wording) for interpreting versions:
120  * the "any later version" means the recepient can choose. */
121 enum license which_license(struct doc_section *d)
122 {
123         if (!d)
124                 return LICENSE_UNKNOWN;
125
126         /* This means "user chooses what version", including GPLv1! */
127         if (streq(d->lines[0], "GPL"))
128                 return LICENSE_GPL;
129         /* This means "v2 only". */
130         if (streq(d->lines[0], "GPLv2"))
131                 return LICENSE_GPLv2;
132         /* This means "v2 or above" at user's choice. */
133         if (streq(d->lines[0], "GPL (v2 or any later version)"))
134                 return LICENSE_GPLv2_PLUS;
135         /* This means "v3 or above" at user's choice. */
136         if (streq(d->lines[0], "GPL (v3 or any later version)"))
137                 return LICENSE_GPLv3;
138
139         /* This means "user chooses what version" */
140         if (streq(d->lines[0], "LGPL"))
141                 return LICENSE_LGPL;
142         /* This means "v2.1 only". */
143         if (streq(d->lines[0], "LGPLv2.1"))
144                 return LICENSE_LGPLv2;
145         /* This means "v2.1 or above" at user's choice. */
146         if (streq(d->lines[0], "LGPL (v2.1 or any later version)"))
147                 return LICENSE_LGPLv2_PLUS;
148         /* This means "v3 or above" at user's choice. */
149         if (streq(d->lines[0], "LGPL (v3 or any later version)"))
150                 return LICENSE_LGPLv3;
151
152         if (streq(d->lines[0], "BSD-MIT") || streq(d->lines[0], "MIT"))
153                 return LICENSE_MIT;
154         if (streq(d->lines[0], "BSD (3 clause)"))
155                 return LICENSE_BSD;
156         if (streq(d->lines[0], "CC0"))
157                 return LICENSE_CC0;
158         if (tal_strreg(NULL, d->lines[0], "CC0 \\([Pp]ublic [Dd]omain\\)",
159                        NULL))
160                 return LICENSE_CC0;
161         if (tal_strreg(NULL, d->lines[0], "[Pp]ublic [Dd]omain"))
162                 return LICENSE_PUBLIC_DOMAIN;
163
164         return LICENSE_UNKNOWN;
165 }
166
167 const char *get_ccan_simplified(struct ccan_file *f)
168 {
169         if (!f->simplified) {
170                 unsigned int i, j;
171
172                 /* Simplify for easy matching: only alnum and single spaces. */
173                 f->simplified = tal_strdup(f, get_ccan_file_contents(f));
174                 for (i = 0, j = 0; f->simplified[i]; i++) {
175                         if (cisupper(f->simplified[i]))
176                                 f->simplified[j++] = tolower(f->simplified[i]);
177                         else if (cislower(f->simplified[i]))
178                                 f->simplified[j++] = f->simplified[i];
179                         else if (cisdigit(f->simplified[i]))
180                                 f->simplified[j++] = f->simplified[i];
181                         else if (cisspace(f->simplified[i])) {
182                                 if (j != 0 && f->simplified[j-1] != ' ')
183                                         f->simplified[j++] = ' ';
184                         }
185                 }
186                 f->simplified[j] = '\0';
187         }
188         return f->simplified;
189 }
190
191 bool find_boilerplate(struct ccan_file *f, enum license license)
192 {
193         unsigned int i;
194
195         for (i = 0; i < NUM_CLAUSES; i++) {
196                 if (!licenses[license].clause[i])
197                         break;
198
199                 if (!strstr(get_ccan_simplified(f),
200                             licenses[license].clause[i])) {
201                         return false;
202                 }
203         }
204         return true;
205 }
206
207 struct doc_section *find_license_tag(const struct manifest *m)
208 {
209         struct doc_section *d;
210
211         list_for_each(get_ccan_file_docs(m->info_file), d, list) {
212                 if (!streq(d->function, m->modname))
213                         continue;
214                 if (streq(d->type, "license"))
215                         return d;
216         }
217         return NULL;
218 }