]> git.ozlabs.org Git - ccan/blob - tools/ccanlint/licenses.c
ccanlint: remove argument to -k/--keep
[ccan] / tools / ccanlint / licenses.c
1 #include "licenses.h"
2 #include "ccanlint.h"
3 #include <ccan/talloc/talloc.h>
4 #include <ccan/str/str.h>
5 #include <ccan/str_talloc/str_talloc.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         { "Public domain", "Public domain",
69           { NULL, NULL, NULL  }
70         },
71         { "Unknown license", "Unknown license",
72           { NULL, NULL, NULL  }
73         },
74 };
75
76 /* License compatibilty chart (simplified: we don't test that licenses between
77  * files are compatible). */
78 bool license_compatible[LICENSE_UNKNOWN+1][LICENSE_UNKNOWN] = {
79 /*       LGPL2+ LGPL2 LGPL3 LGPL  GPL2+ GPL2  GPL3  GPL   BSD   MIT   PD   */
80 /* _info says: LGPL2+ */
81         { true, false,false,true, false,false,false,false,true, true, true },
82 /* _info says: LGPL2 only */
83         { true, true, false,true, false,false,false,false,true, true, true },
84 /* _info says: LGPL3 (or any later version) */
85         { true, false,true, true, false,false,false,false,true, true, true },
86 /* _info says: LGPL (no version specified) */
87         { true, true, true, true, false,false,false,false,true, true, true },
88 /* _info says: GPL2+ */
89         { true, true, true, true, true, false,false,true, true, true, true },
90 /* _info says: GPL2 only */
91         { true, true, true, true, true, true, false,true, true, true, true },
92 /* _info says: GPL3 (or any later version) */
93         { true, true, true, true, true, false,true, true, true, true, true },
94 /* _info says: GPL (unknown version) */
95         { true, true, true, true, true, true, true, true, true, true, true },
96 /* _info says: BSD (3-clause) */
97         { false,false,false,false,false,false,false,false,true, true, true },
98 /* _info says: MIT */
99         { false,false,false,false,false,false,false,false,false,true, true },
100 /* _info says: Public domain */
101         { false,false,false,false,false,false,false,false,false,false,true },
102 /* _info says something we don't understand */
103         { false,false,false,false,false,false,false,false,false,false,true }
104 };
105
106 /* See GPLv2 and v2 (basically same wording) for interpreting versions:
107  * the "any later version" means the recepient can choose. */
108 enum license which_license(struct doc_section *d)
109 {
110         if (!d)
111                 return LICENSE_UNKNOWN;
112
113         /* This means "user chooses what version", including GPLv1! */
114         if (streq(d->lines[0], "GPL"))
115                 return LICENSE_GPL;
116         /* This means "v2 only". */
117         if (streq(d->lines[0], "GPLv2"))
118                 return LICENSE_GPLv2;
119         /* This means "v2 or above" at user's choice. */
120         if (streq(d->lines[0], "GPL (v2 or any later version)"))
121                 return LICENSE_GPLv2_PLUS;
122         /* This means "v3 or above" at user's choice. */
123         if (streq(d->lines[0], "GPL (v3 or any later version)"))
124                 return LICENSE_GPLv3;
125
126         /* This means "user chooses what version" */
127         if (streq(d->lines[0], "LGPL"))
128                 return LICENSE_LGPL;
129         /* This means "v2.1 only". */
130         if (streq(d->lines[0], "LGPLv2.1"))
131                 return LICENSE_LGPLv2;
132         /* This means "v2.1 or above" at user's choice. */
133         if (streq(d->lines[0], "LGPL (v2.1 or any later version)"))
134                 return LICENSE_LGPLv2_PLUS;
135         /* This means "v3 or above" at user's choice. */
136         if (streq(d->lines[0], "LGPL (v3 or any later version)"))
137                 return LICENSE_LGPLv3;
138
139         if (streq(d->lines[0], "BSD-MIT") || streq(d->lines[0], "MIT"))
140                 return LICENSE_MIT;
141         if (streq(d->lines[0], "BSD (3 clause)"))
142                 return LICENSE_BSD;
143         if (strreg(NULL, d->lines[0], "[Pp]ublic [Dd]omain"))
144                 return LICENSE_PUBLIC_DOMAIN;
145
146         return LICENSE_UNKNOWN;
147 }
148
149 const char *get_ccan_simplified(struct ccan_file *f)
150 {
151         if (!f->simplified) {
152                 unsigned int i, j;
153
154                 /* Simplify for easy matching: only alnum and single spaces. */
155                 f->simplified = talloc_strdup(f, get_ccan_file_contents(f));
156                 for (i = 0, j = 0; f->simplified[i]; i++) {
157                         if (cisupper(f->simplified[i]))
158                                 f->simplified[j++] = tolower(f->simplified[i]);
159                         else if (cislower(f->simplified[i]))
160                                 f->simplified[j++] = f->simplified[i];
161                         else if (cisdigit(f->simplified[i]))
162                                 f->simplified[j++] = f->simplified[i];
163                         else if (cisspace(f->simplified[i])) {
164                                 if (j != 0 && f->simplified[j-1] != ' ')
165                                         f->simplified[j++] = ' ';
166                         }
167                 }
168                 f->simplified[j] = '\0';
169         }
170         return f->simplified;
171 }
172
173 bool find_boilerplate(struct ccan_file *f, enum license license)
174 {
175         unsigned int i;
176
177         for (i = 0; i < NUM_CLAUSES; i++) {
178                 if (!licenses[license].clause[i])
179                         break;
180
181                 if (!strstr(get_ccan_simplified(f),
182                             licenses[license].clause[i])) {
183                         return false;
184                 }
185         }
186         return true;
187 }
188
189 struct doc_section *find_license_tag(const struct manifest *m)
190 {
191         struct doc_section *d;
192
193         list_for_each(get_ccan_file_docs(m->info_file), d, list) {
194                 if (!streq(d->function, m->basename))
195                         continue;
196                 if (streq(d->type, "license"))
197                         return d;
198         }
199         return NULL;
200 }