]> git.ozlabs.org Git - ccan/blob - tools/ccanlint/licenses.c
ccanlint: check for incompatible license boilerplates within subfiles.
[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
6 const struct license_info licenses[] = {
7         { "LGPLv2+", "LGPL",
8           { "gnu lesser general public license",
9             "version 2",
10             "or at your option any later version"
11           }
12         },
13         { "LGPLv2", "LGPL",
14           { "gnu lesser general public license",
15             "version 2",
16             NULL
17           }
18         },
19         { "LGPLv3", "LGPL",
20           { "gnu lesser general public license",
21             "version 3",
22             NULL
23           }
24         },
25         { "LGPL", "LGPL",
26           { "gnu lesser general public license",
27             NULL,
28             NULL
29           }
30         },
31         { "GPLv2+", "GPL",
32           { "gnu general public license",
33             "version 2",
34             "or at your option any later version"
35           }
36         },
37         { "GPLv2", "GPL",
38           { "gnu general public license",
39             "version 2",
40             NULL
41           }
42         },
43         { "GPLv3", "GPL",
44           { "gnu general public license",
45             "version 3",
46             NULL
47           }
48         },
49         { "GPL", "GPL",
50           { "gnu general public license",
51             NULL,
52             NULL
53           }
54         },
55         { "BSD-3CLAUSE", "BSD",
56           { "redistributions of source code must retain",
57             "redistributions in binary form must reproduce",
58             "endorse or promote"
59           }
60         },
61         { "BSD-MIT", "MIT",
62           { "without restriction",
63             "above copyright notice",
64             "without warranty"
65           }
66         },
67         { "Public domain", "Public domain",
68           { NULL, NULL, NULL  }
69         },
70         { "Unknown license", "Unknown license",
71           { NULL, NULL, NULL  }
72         },
73 };
74
75 /* License compatibilty chart (simplified: we don't test that licenses between
76  * files are compatible). */
77 bool license_compatible[LICENSE_UNKNOWN+1][LICENSE_UNKNOWN] = {
78 /*       LGPL2+ LGPL2 LGPL3 LGPL  GPL2+ GPL2  GPL3  GPL   BSD   MIT   PD   */
79 /* _info says: LGPL2+ */
80         { true, false,false,true, false,false,false,false,true, true, true },
81 /* _info says: LGPL2 only */
82         { true, true, false,true, false,false,false,false,true, true, true },
83 /* _info says: LGPL3 (or any later version) */
84         { true, false,true, true, false,false,false,false,true, true, true },
85 /* _info says: LGPL (no version specified) */
86         { true, true, true, true, false,false,false,false,true, true, true },
87 /* _info says: GPL2+ */
88         { true, true, true, true, true, false,false,true, true, true, true },
89 /* _info says: GPL2 only */
90         { true, true, true, true, true, true, false,true, true, true, true },
91 /* _info says: GPL3 (or any later version) */
92         { true, true, true, true, true, false,true, true, true, true, true },
93 /* _info says: GPL (unknown version) */
94         { true, true, true, true, true, true, true, true, true, true, true },
95 /* _info says: BSD (3-clause) */
96         { false,false,false,false,false,false,false,false,true, true, true },
97 /* _info says: MIT */
98         { false,false,false,false,false,false,false,false,false,true, true },
99 /* _info says: Public domain */
100         { false,false,false,false,false,false,false,false,false,false,true },
101 /* _info says something we don't understand */
102         { false,false,false,false,false,false,false,false,false,false,true }
103 };
104
105 const char *get_ccan_simplified(struct ccan_file *f)
106 {
107         if (!f->simplified) {
108                 unsigned int i, j;
109
110                 /* Simplify for easy matching: only alnum and single spaces. */
111                 f->simplified = talloc_strdup(f, get_ccan_file_contents(f));
112                 for (i = 0, j = 0; f->simplified[i]; i++) {
113                         if (cisupper(f->simplified[i]))
114                                 f->simplified[j++] = tolower(f->simplified[i]);
115                         else if (cislower(f->simplified[i]))
116                                 f->simplified[j++] = f->simplified[i];
117                         else if (cisdigit(f->simplified[i]))
118                                 f->simplified[j++] = f->simplified[i];
119                         else if (cisspace(f->simplified[i])) {
120                                 if (j != 0 && f->simplified[j-1] != ' ')
121                                         f->simplified[j++] = ' ';
122                         }
123                 }
124                 f->simplified[j] = '\0';
125         }
126         return f->simplified;
127 }
128
129 bool find_boilerplate(struct ccan_file *f, enum license license)
130 {
131         unsigned int i;
132
133         for (i = 0; i < NUM_CLAUSES; i++) {
134                 if (!licenses[license].clause[i])
135                         break;
136
137                 if (!strstr(get_ccan_simplified(f),
138                             licenses[license].clause[i])) {
139                         return false;
140                 }
141         }
142         return true;
143 }