Removed gestalt options from C ohcount (use ruby/gestalt.rb).
[ohcount] / src / licenses.c
1 // licenses.c written by Mitchell Foral. mitchell<att>caladbolg.net.
2 // See COPYING for license information.
3
4 #include <ctype.h>
5 #include <string.h>
6
7 #include "licenses.h"
8 #include "parser.h"
9
10 // Holds licenses and their associated details and patterns.
11 License license_map[] = {
12   {
13     LIC_ACADEMIC,
14     "http://www.opensource.org/licenses/afl-3.0.php",
15     "Academic Free License",
16     "\\bAcademic\\s*Free\\s*License\\b",
17     PCRE_CASELESS,
18     NULL,
19     0,
20     NULL, NULL
21   },
22   {
23     LIC_ADAPTIVE,
24     "http://www.opensource.org/licenses/apl1.0.php",
25     "Adaptive Public License",
26     "\\bAdaptive\\s*Public\\s*License\\b",
27     PCRE_CASELESS,
28     NULL,
29     0,
30     NULL, NULL
31   },
32   {
33     LIC_AFFERO,
34     "http://www.affero.org/oagpl.html",
35     "GNU Affero General Public License",
36     "\\bGNU\\s+Affero\\s+General\\s+Public\\s+License\\b",
37     PCRE_CASELESS,
38     NULL,
39     0,
40     NULL, NULL
41   },
42   {
43     LIC_APACHE,
44     "http://www.opensource.org/licenses/apachepl.php",
45     "Apache Software License",
46     "(\\bApache\\s*Software\\s*License(?![\\s,]*2))|(\\bapache\\s*license(?![\\s,]*2))",
47     PCRE_CASELESS,
48     NULL,
49     0,
50     NULL, NULL
51   },
52   {
53     LIC_APACHE2,
54     "http://www.opensource.org/licenses/apache2.0.php",
55     "Apache License, 2.0",
56     "\\bapache\\s+(software\\s+)?license,?\\s+(version\\s+)?2",
57     PCRE_CASELESS,
58     NULL,
59     0,
60     NULL, NULL
61   },
62   {
63     LIC_APPLE_OPEN_SOURCE,
64     "http://www.opensource.org/licenses/apsl-2.0.php",
65     "Apple Public Source License",
66     "\\bApple\\s*Public\\s*Source\\s*License\\b",
67     PCRE_CASELESS,
68     NULL,
69     0,
70     NULL, NULL
71   },
72   {
73     LIC_ARTISTIC,
74     "http://www.opensource.org/licenses/artistic-license.php",
75     "Artistic license",
76     "\\bartistic\\s*license\\b",
77     PCRE_CASELESS,
78     NULL,
79     0,
80     NULL, NULL
81   },
82   {
83     LIC_ATTRIBUTION_ASSURANCE,
84     "http://www.opensource.org/licenses/attribution.php",
85     "Attribution Assurance Licenses",
86     "\\battribution\\s*assurance\\s*license(s)?\\b",
87     PCRE_CASELESS,
88     NULL,
89     0,
90     NULL, NULL
91   },
92   {
93     LIC_BOOST,
94     "http://www.boost.org/LICENSE_1_0.txt",
95     "Boost Software License - Version 1.0 - August 17th, 2003",
96     "\\bboost\\s*software\\s*license\\b",
97     PCRE_CASELESS,
98     NULL,
99     0,
100     NULL, NULL
101   },
102   {
103     LIC_BSD,
104     "http://www.opensource.org/licenses/bsd-license.php",
105     "New BSD license",
106     "(\\bbsd\\s*license\\b)|(The Regents of the University of California)",
107     PCRE_CASELESS,
108     NULL,
109     0,
110     NULL, NULL
111   },
112   {
113     LIC_CECILL,
114     "http://www.cecill.info/licences/Licence_CeCILL_V2-en.html",
115     "CeCILL license",
116     "\\bcecill\\b",
117     PCRE_CASELESS,
118     NULL,
119     0,
120     NULL, NULL
121   },
122   {
123     LIC_CECILL_B,
124     "http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html",
125     "CeCILL-B license",
126     "\\bcecill-b\\b",
127     PCRE_CASELESS,
128     NULL,
129     0,
130     NULL, NULL
131   },
132   {
133     LIC_CECILL_C,
134     "http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.html",
135     "CeCILL-C license",
136     "\\bcecill-c\\b",
137     PCRE_CASELESS,
138     NULL,
139     0,
140     NULL, NULL
141   },
142   {
143     LIC_COMPUTER_ASSOCIATES_TRUSTED,
144     "http://www.opensource.org/licenses/ca-tosl1.1.php",
145     "Computer Associates Trusted Open Source License 1.1",
146     "\\bcomputer\\s*associates\\s*trusted\\s*open\\s*source\\s*license\\b",
147     PCRE_CASELESS,
148     NULL,
149     0,
150     NULL, NULL
151   },
152   {
153     LIC_COMMON_DEVELOPMENT_AND_DISTRIBUTION,
154     "http://www.opensource.org/licenses/cddl1.php",
155     "Common Development and Distribution License",
156     "\\bcommon\\s*development\\s*and\\s*distribution\\s*license\\b",
157     PCRE_CASELESS,
158     NULL,
159     0,
160     NULL, NULL
161   },
162   {
163     LIC_COMMON_PUBLIC,
164     "http://www.opensource.org/licenses/cpl1.0.php",
165     "Common Public License 1.0",
166     "\\bcommon\\s*public\\s*license\\b",
167     PCRE_CASELESS,
168     NULL,
169     0,
170     NULL, NULL
171   },
172   {
173     LIC_CUA_OFFICE,
174     "http://www.opensource.org/licenses/cuaoffice.php",
175     "CUA Office Public License Version 1.0",
176     "\\bCUA\\s*office\\s*public\\s*license\\b",
177     PCRE_CASELESS,
178     NULL,
179     0,
180     NULL, NULL
181   },
182   {
183     LIC_EU_DATAGRID,
184     "http://www.opensource.org/licenses/eudatagrid.php",
185     "EU DataGrid Software License",
186     "\\beu\\s*datagrid\\s*software\\s*license\\b",
187     PCRE_CASELESS,
188     NULL,
189     0,
190     NULL, NULL
191   },
192   {
193     LIC_ECLIPSE,
194     "http://www.opensource.org/licenses/eclipse-1.0.php",
195     "Eclipse Public License",
196     "\\beclipse\\s*public\\s*license\\b",
197     PCRE_CASELESS,
198     NULL,
199     0,
200     NULL, NULL
201   },
202   {
203     LIC_EDUCATIONAL,
204     "http://www.opensource.org/licenses/ecl1.php",
205     "Educational Community License",
206     "\\beducational\\s*community\\s*license\\b",
207     PCRE_CASELESS,
208     NULL,
209     0,
210     NULL, NULL
211   },
212   {
213     LIC_EIFFEL,
214     "http://www.opensource.org/licenses/eiffel.php",
215     "Eiffel Forum License",
216     "\\beiffel\\s*forum\\s*license(?![,V\\s]*2)\\b",
217     PCRE_CASELESS,
218     NULL,
219     0,
220     NULL, NULL
221   },
222   {
223     LIC_EIFFEL2,
224     "http://www.opensource.org/licenses/ver2_eiffel.php",
225     "Eiffel Forum License V2.0",
226     "\\beiffel\\s*forum\\s*license [,V\\s]*2",
227     PCRE_CASELESS,
228     NULL,
229     0,
230     NULL, NULL
231   },
232   {
233     LIC_ENTESSA,
234     "http://www.opensource.org/licenses/entessa.php",
235     "Entessa Public License",
236     "\\bentessa\\s*public\\s*license\\b",
237     PCRE_CASELESS,
238     NULL,
239     0,
240     NULL, NULL
241   },
242   {
243     LIC_FAIR,
244     "http://www.opensource.org/licenses/fair.php",
245     "Fair License",
246     "\\bfair\\s*license\\b",
247     PCRE_CASELESS,
248     NULL,
249     0,
250     NULL, NULL
251   },
252   {
253     LIC_FRAMEWORX,
254     "http://www.opensource.org/licenses/frameworx.php",
255     "Frameworx License",
256     "\\bframeworx\\s*license\\b",
257     PCRE_CASELESS,
258     NULL,
259     0,
260     NULL, NULL
261   },
262   {
263     LIC_GPL3_OR_LATER,
264     "http://www.gnu.org/licenses/gpl-3.0.html",
265     "GNU General Public License 3.0",
266     "\\b(GNU GENERAL PUBLIC LICENSE|GPL).{0,100}(Version)? 3.{0,50}later",
267     PCRE_CASELESS | PCRE_MULTILINE,
268     NULL,
269     0,
270     NULL, NULL
271   },
272   {
273     LIC_GPL3,
274     "http://www.gnu.org/licenses/gpl-3.0.html",
275     "GNU General Public License 3.0",
276     "GNU (GENERAL PUBLIC LICENSE|GPL).{0,100}(Version |v)3",
277     PCRE_CASELESS | PCRE_MULTILINE,
278     "((at your option) any later version)|(GENERAL PUBLIC LICENSE.*GENERAL PUBLIC LICENSE)",
279     PCRE_CASELESS,
280     NULL, NULL
281   },
282   {
283     LIC_LGPL3,
284     "http://www.gnu.org/licenses/lgpl-3.0.html",
285     "GNU Lesser General Public License 3.0",
286     "((\\blgpl\\b)|(\\bgnu\\s*(library|lesser)\\s*(general\\s*)?(public\\s*)?license\\b)|(\\b(lesser|library)\\s*gpl\\b)).{0,10}(\\bas published by the free software foundation\\b)?.{0,10}(\\bversion\\b)?.{0,10}\\b3(\\.0)?\\b",
287     PCRE_CASELESS,
288     NULL,
289     0,
290     NULL, NULL
291   },
292   {
293     LIC_GPL,
294     "http://www.opensource.org/licenses/gpl-license.php",
295     "GNU General Public License (GPL)",
296     "(\\bgpl\\b)|(\\bgplv2\\b)|(\\bgnu\\s*general\\s*public\\s*license\\b)|(\\bwww\\.gnu\\.org\\/licenses\\/gpl\\.txt\\b)",
297     PCRE_CASELESS,
298     NULL,
299     0,
300     NULL, NULL
301   },
302   {
303     LIC_LGPL,
304     "http://www.opensource.org/licenses/lgpl-license.php",
305     "GNU Library or \"Lesser\" GPL (LGPL)",
306     "(\\blgpl\\b)|(\\bgnu\\s*(library|lesser)\\s*(general\\s*)?(public\\s*)?license\\b)|(\\b(lesser|library)\\s*gpl\\b)",
307     PCRE_CASELESS,
308     NULL,
309     0,
310     NULL, NULL
311   },
312   {
313     LIC_HISTORICAL,
314     "http://www.opensource.org/licenses/historical.php",
315     "Historical Permission Notice and Disclaimer",
316     "\\bhistorical\\s*permission\\s*notice\\s*and\\s*disclaimer\\b",
317     PCRE_CASELESS,
318     NULL,
319     0,
320     NULL, NULL
321   },
322   {
323     LIC_I9,
324     "http://i9os.googlecode.com/svn/trunk/Documentation/Licenses/i9_License",
325     "i9 License",
326     "\\bi9\\s*\\s*license\\b",
327     PCRE_CASELESS,
328     NULL,
329     0,
330     NULL, NULL
331   },
332   {
333     LIC_IBM_PUBLIC,
334     "http://www.opensource.org/licenses/ibmpl.php",
335     "IBM Public License",
336     "\\bibm\\s*public\\s*license\\b",
337     PCRE_CASELESS,
338     NULL,
339     0,
340     NULL, NULL
341   },
342   {
343     LIC_INTEL_OPEN_SOURCE,
344     "http://www.opensource.org/licenses/intel-open-source-license.php",
345     "Intel Open Source License",
346     "\\bintel\\s*open\\s*source\\s*license\\b",
347     PCRE_CASELESS,
348     NULL,
349     0,
350     NULL, NULL
351   },
352   {
353     LIC_JABBER_OPEN_SOURCE,
354     "http://www.opensource.org/licenses/jabberpl.php",
355     "Jabber Open Source License",
356     "\\bjabber\\s*open\\s*source\\s*license\\b",
357     PCRE_CASELESS,
358     NULL,
359     0,
360     NULL, NULL
361   },
362   {
363     LIC_LUCENT_PLAN9,
364     "http://www.opensource.org/licenses/plan9.php",
365     "Lucent Public License (Plan9)",
366     "\\blucent\\s*public\\s*license[\\s(]*plan9",
367     PCRE_CASELESS,
368     NULL,
369     0,
370     NULL, NULL
371   },
372   {
373     LIC_LUCENT_PUBLIC,
374     "http://www.opensource.org/licenses/lucent1.02.php",
375     "Lucent Public License Version 1.02",
376     "\\blucent\\s*public\\s*license\\s*(version)?\\s+1",
377     PCRE_CASELESS,
378     NULL,
379     0,
380     NULL, NULL
381   },
382   {
383     LIC_MIT,
384     "http://www.opensource.org/licenses/mit-license.php",
385     "MIT license",
386     "(\\bmit\\s*license\\b)|(\\bMIT\\/X11\\s*license\\b)",
387     PCRE_CASELESS,
388     NULL,
389     0,
390     NULL, NULL
391   },
392   {
393     LIC_MITRE,
394     "http://www.opensource.org/licenses/mitrepl.php",
395     "MITRE Collaborative Virtual Workspace License (CVW License)",
396     "\\bmitre\\s*collaborative\\s*virtual\\s*workspace\\s*license\\b",
397     PCRE_CASELESS,
398     NULL,
399     0,
400     NULL, NULL
401   },
402   {
403     LIC_MOTOSOTO,
404     "http://www.opensource.org/licenses/motosoto.php",
405     "Motosoto License",
406     "\\bmotosoto\\s*license\\b",
407     PCRE_CASELESS,
408     NULL,
409     0,
410     NULL, NULL
411   },
412   {
413     LIC_MOZILLA_PUBLIC1,
414     "http://www.opensource.org/licenses/mozilla1.0.php",
415     "Mozilla Public License 1.0 (MPL)",
416     "\\bmozilla\\s*public\\s*license\\b",
417     PCRE_CASELESS,
418     NULL,
419     0,
420     NULL, NULL
421   },
422   {
423     LIC_MOZILLA_PUBLIC11,
424     "http://www.opensource.org/licenses/mozilla1.1.php",
425     "Mozilla Public License 1.1 (MPL)",
426     "\\bmozilla\\s*public\\s*license 1\\.1\\b",
427     PCRE_CASELESS,
428     NULL,
429     0,
430     NULL, NULL
431   },
432   {
433     LIC_NASA_OPEN,
434     "http://www.opensource.org/licenses/nasa1.3.php",
435     "NASA Open Source Agreement 1.3",
436     "\\bnasa\\s*open\\s*source\\s*agreement\\b",
437     PCRE_CASELESS,
438     NULL,
439     0,
440     NULL, NULL
441   },
442   {
443     LIC_NAUMEN,
444     "http://www.opensource.org/licenses/naumen.php",
445     "Naumen Public License",
446     "\\bnaumen\\s*public\\s*license\\b",
447     PCRE_CASELESS,
448     NULL,
449     0,
450     NULL, NULL
451   },
452   {
453     LIC_NETHACK,
454     "http://www.opensource.org/licenses/nethack.php",
455     "Nethack General Public License",
456     "\\bnethack\\s*general\\s*public\\s*license\\b",
457     PCRE_CASELESS,
458     NULL,
459     0,
460     NULL, NULL
461   },
462   {
463     LIC_NOKIA_OPEN_SOURCE,
464     "http://www.opensource.org/licenses/nokia.php",
465     "Nokia Open Source License",
466     "\\bnokia\\s*open\\s*source\\s*license\\b",
467     PCRE_CASELESS,
468     NULL,
469     0,
470     NULL, NULL
471   },
472   {
473     LIC_OCLC_RESEARCH,
474     "http://www.opensource.org/licenses/oclc2.php",
475     "OCLC Research Public License 2.0",
476     "\\boclc\\s*research\\s*public\\s*license\\b",
477     PCRE_CASELESS,
478     NULL,
479     0,
480     NULL, NULL
481   },
482   {
483     LIC_OPEN_GROUP_TEST,
484     "http://www.opensource.org/licenses/opengroup.php",
485     "Open Group Test Suite License",
486     "\\bopen\\s*group\\s*test\\s*suite\\s*license\\b",
487     PCRE_CASELESS,
488     NULL,
489     0,
490     NULL, NULL
491   },
492   {
493     LIC_OPEN_SOFTWARE,
494     "http://www.opensource.org/licenses/osl-3.0.php",
495     "Open Software License",
496     "\\bopen\\s*software\\s*license\\b",
497     PCRE_CASELESS,
498     NULL,
499     0,
500     NULL, NULL
501   },
502   {
503     LIC_PHP_LICENSE,
504     "http://www.opensource.org/licenses/php.php",
505     "PHP License",
506     "\\bphp\\s*license\\b",
507     PCRE_CASELESS,
508     NULL,
509     0,
510     NULL, NULL
511   },
512   {
513     LIC_PYTHON_LICENSE,
514     "http://www.opensource.org/licenses/pythonpl.php",
515     "Python license",
516     "\\bpython\\s*license\\b",
517     PCRE_CASELESS,
518     NULL,
519     0,
520     NULL, NULL
521   },
522   {
523     LIC_PYTHON_SOFTWARE_FOUNDATION,
524     "http://www.opensource.org/licenses/PythonSoftFoundation.php",
525     "Python Software Foundation License",
526     "\\bpython\\s*software\\s*foundation\\s*license\\b",
527     PCRE_CASELESS,
528     NULL,
529     0,
530     NULL, NULL
531   },
532   {
533     LIC_QT_PUBLIC,
534     "http://www.opensource.org/licenses/qtpl.php",
535     "Qt Public License (QPL)",
536     "\\bqt\\s*public\\s*license\\b",
537     PCRE_CASELESS,
538     NULL,
539     0,
540     NULL, NULL
541   },
542   {
543     LIC_REALNETWORKS_PUBLIC_SOURCE,
544     "http://www.opensource.org/licenses/real.php",
545     "RealNetworks Public Source License V1.0",
546     "\\brealnetworks\\s*public\\s*source\\s*license\\b",
547     PCRE_CASELESS,
548     NULL,
549     0,
550     NULL, NULL
551   },
552   {
553     LIC_RECIPROCAL_PUBLIC,
554     "http://www.opensource.org/licenses/rpl.php",
555     "Reciprocal Public License",
556     "\\breciprocal\\s*public\\s*license\\b",
557     PCRE_CASELESS,
558     NULL,
559     0,
560     NULL, NULL
561   },
562   {
563     LIC_RICOH_SOURCE,
564     "http://www.opensource.org/licenses/ricohpl.php",
565     "Ricoh Source Code Public License",
566     "\\bricoh\\s*source\\s*code\\s*public\\s*license\\b",
567     PCRE_CASELESS,
568     NULL,
569     0,
570     NULL, NULL
571   },
572   {
573     LIC_SLEEPYCAT,
574     "http://www.opensource.org/licenses/sleepycat.php",
575     "Sleepycat License",
576     "\\bsleepycat\\s*license\\b",
577     PCRE_CASELESS,
578     NULL,
579     0,
580     NULL, NULL
581   },
582   {
583     LIC_SUGARCRM113,
584     "http://www.sugarcrm.com/SPL",
585     "SugarCRM Public License 1.1.3",
586     "\\bsugar\\s*public\\s*license\\s*version\\s*1\\.1\\.3\\b",
587     PCRE_CASELESS,
588     NULL,
589     0,
590     NULL, NULL
591   },
592   {
593     LIC_SUN_INDUSTRY_STANDARDS,
594     "http://www.opensource.org/licenses/sisslpl.php",
595     "Sun Industry Standards Source License (SISSL)",
596     "\\bsun\\s*industry\\s*standards\\s*source\\s*license\\b",
597     PCRE_CASELESS,
598     NULL,
599     0,
600     NULL, NULL
601   },
602   {
603     LIC_SUN_PUBLIC,
604     "http://www.opensource.org/licenses/sunpublic.php",
605     "Sun Public License",
606     "\\bsun\\s*public\\s*license\\b",
607     PCRE_CASELESS,
608     NULL,
609     0,
610     NULL, NULL
611   },
612   {
613     LIC_SYBASE_OPEN_WATCOM,
614     "http://www.opensource.org/licenses/sybase.php",
615     "Sybase Open Watcom Public License 1.0",
616     "\\bsybase\\s*open\\s*watcom\\s*public\\s*license\\b",
617     PCRE_CASELESS,
618     NULL,
619     0,
620     NULL, NULL
621   },
622   {
623     LIC_U_OF_I_NCSA,
624     "http://www.opensource.org/licenses/UoI-NCSA.php",
625     "University of Illinois/NCSA Open Source License",
626     "\\buniversity\\s*of\\s*illinois\\/ncsa\\s*open\\s*source\\s*license\\b",
627     PCRE_CASELESS,
628     NULL,
629     0,
630     NULL, NULL
631   },
632   {
633     LIC_VOVIDA_SOFTWARE,
634     "http://www.opensource.org/licenses/vovidapl.php",
635     "Vovida Software License v. 1.0",
636     "\\bvovida\\s*software\\s*license\\b",
637     PCRE_CASELESS,
638     NULL,
639     0,
640     NULL, NULL
641   },
642   {
643     LIC_W3C,
644     "http://www.opensource.org/licenses/W3C.php",
645     "W3C License",
646     "\\bw3c\\s*license\\b",
647     PCRE_CASELESS,
648     NULL,
649     0,
650     NULL, NULL
651   },
652   {
653     LIC_WXWINDOWS,
654     "http://www.opensource.org/licenses/wxwindows.php",
655     "wxWindows Library License",
656     "\\bwxwindows\\s*library\\s*license\\b",
657     PCRE_CASELESS,
658     NULL,
659     0,
660     NULL, NULL
661   },
662   {
663     LIC_XNET,
664     "http://www.opensource.org/licenses/xnet.php",
665     "X.Net License",
666     "\\bx\\.net\\s*license\\b",
667     PCRE_CASELESS,
668     NULL,
669     0,
670     NULL, NULL
671   },
672   {
673     LIC_ZOPE,
674     "http://www.opensource.org/licenses/zpl.php",
675     "Zope Public License",
676     "\\bzope\\s*public\\s*license\\b",
677     PCRE_CASELESS,
678     NULL,
679     0,
680     NULL, NULL
681   },
682   {
683     LIC_ZLIB_LIBPNG,
684     "http://www.opensource.org/licenses/zlib-license.php",
685     "zlib/libpng license",
686     "\\bzlib\\/libpng\\s*license\\b",
687     PCRE_CASELESS,
688     NULL,
689     0,
690     NULL, NULL
691   },
692   {
693     LIC_APACHE_ISH,
694     "",
695     "Apache-ish License",
696     "(\\bapache-style.*license\\b)|(\\bapache-like.*license\\b)",
697     PCRE_CASELESS,
698     NULL,
699     0,
700     NULL, NULL
701   },
702   {
703     LIC_BSD_ISH,
704     "",
705     "BSD-ish License",
706     "Copyright\\s.{1,40}All rights reserved.{0,40}Redistribution and use in source and binary forms, with or without.{0,20}modification, are permitted provided that the following conditions.{0,20}\\sare met.{1,40}Redistributions of source code must retain the above copyright\\s.*notice, this list of conditions and the following disclaimer\\.\\s+.*Redistributions in binary form must reproduce the above.*copyright\\s+.{0,10}notice, this list of conditions and the following.*disclaimer in the\\s+.*documentation.*(The (name|names) of the (author|contributors) may not|Neither the name of the).*be used to endorse or promote\\s+.*products\\s+.*derived\\s+.*from this software without specific prior written\\s+.*permission.*HOWEVER\\s+.*CAUSED AND ON ANY.*THEORY OF LIABILITY, WHETHER IN CONTRACT",
707     PCRE_MULTILINE,
708     "The Regents of the University of California",
709     0,
710     NULL, NULL
711   },
712   {
713     LIC_BSD_2CLAUSE_ISH,
714     "",
715     "BSD-ish (2 clause) License",
716     "Copyright\\s.{1,60}All rights reserved.{1,40}Redistribution and use in source and binary forms, with or without.{0,20}modification, are permitted provided that the following conditions.{0,20}\\sare met.{0,20}\\s{1,20}.{0,20}Redistributions of source code must retain the above copyright\\s+.*notice, this list of conditions and the following disclaimer.\\s+.*Redistributions in binary form must reproduce the above copyright\\s+.*notice, this list of conditions and the following disclaimer in the\\s+.*documentation and\\/or other materials provided with the distribution\\.\\s+.*HOWEVER CAUSED AND ON ANY.*THEORY OF LIABILITY, WHETHER IN CONTRACT",
717     PCRE_MULTILINE,
718     "(The Regents of the University of California)|(used to endorse or promote\\s+.*products\\s+.*prior\\s+.*written\\s+.*permission\\.)",
719     PCRE_MULTILINE,
720     NULL, NULL
721   },
722   { NULL, NULL, NULL, NULL, 0, NULL, 0, NULL, NULL },
723 };
724 int license_map_length = 0; // will be set dynamically
725
726 /** Compiles the regular expressions defined in license_map. */
727 void compile_regexps() {
728   if (license_map_length == 0)
729     return;
730   const char *err;
731   int erroffset;
732   int i;
733   for (i = 0; i < license_map_length; i++) {
734     License *l = &license_map[i];
735     int flags;
736     if (l->re) {
737       flags = l->re_flags;
738       if (flags & PCRE_MULTILINE)
739         flags |= PCRE_DOTALL;
740       l->regexp = pcre_compile(l->re, flags, &err, &erroffset, NULL);
741     }
742     if (l->exclude_re) {
743       flags = l->exclude_re_flags;
744       if (flags & PCRE_MULTILINE)
745         flags |= PCRE_DOTALL;
746       l->exclude_regexp = pcre_compile(l->exclude_re, flags, &err, &erroffset,
747                                        NULL);
748     }
749   }
750 }
751
752 /**
753  * Overrides a less-specific license l with a more-specific one if the latter
754  * was detected.
755  */
756 #define OVERRIDE_LICENSE(l, with) { \
757   if (strcmp(license_map[i].name, l) == 0) { \
758     for (j = 0; j < license_map_length; j++) \
759       if (potential_licenses_s[j] > -1 && \
760           strcmp(license_map[j].name, with) == 0) { \
761         overridden = 1; \
762         break; \
763       } \
764   } \
765 }
766
767 LicenseList *ohcount_detect_license(SourceFile *sourcefile) {
768   LicenseList *list = ohcount_license_list_new();
769
770   // Get the size of this map and compile the REs. Only runs once.
771   if (license_map_length == 0) {
772     while (license_map[license_map_length].name) license_map_length++;
773     compile_regexps();
774   }
775
776   ohcount_sourcefile_parse(sourcefile);
777
778   char *p, *q;
779   int i, j, k;
780   int ovector[30]; // recommended by PCRE
781   ParsedLanguageList *iter;
782   iter = ohcount_sourcefile_get_parsed_language_list(sourcefile)->head;
783   if (iter) {
784     int potential_licenses_s[license_map_length];
785     int potential_licenses_e[license_map_length];
786
787     while (iter) {
788       char buffer[ohcount_sourcefile_get_contents_size(sourcefile)];
789       p = iter->pl->comments;
790       q = buffer;
791       char *eof = p + strlen(p);
792       while (p < eof) {
793         // Strip leading whitespace and punctuation.
794         while (*p == ' ' || *p == '\t' || ispunct(*p)) p++;
795         // Copy line contents.
796         while (p < eof && *p != '\r' && *p != '\n') *q++ = *p++;
797         // Strip newline characters.
798         while (*p == '\r' || *p == '\n') p++;
799         // Add a trailing space.
800         *q++ = ' ';
801       }
802       *q = '\0';
803
804       for (j = 0; j < license_map_length; j++) {
805         potential_licenses_s[j] = -1;
806         potential_licenses_e[j] = -1;
807         if (pcre_exec(license_map[j].regexp, NULL, buffer, q - buffer, 0, 0,
808                       ovector, 30) >= 0) {
809           int m0 = ovector[0], m1 = ovector[1];
810           // Exclude terms that may not exist in the license.
811           if (license_map[j].exclude_re &&
812               pcre_exec(license_map[j].exclude_regexp, NULL, buffer + m0, m1 - m0,
813                         0, 0, ovector, 30) >= 0)
814             continue;
815           potential_licenses_s[j] = m0;
816           potential_licenses_e[j] = m1;
817           for (k = 0; k < j; k++) {
818             // If this matched license is completely contained inside another one,
819             // do not include it.
820             if ((potential_licenses_s[k] < m0 && potential_licenses_e[k] >= m1) ||
821                 (potential_licenses_s[k] <= m0 && potential_licenses_e[k] > m1)) {
822               potential_licenses_s[j] = -1;
823               potential_licenses_e[j] = -1;
824             }
825             // If this matched license completely contains another one, do not
826             // include the latter.
827             if ((m0 < potential_licenses_s[k] && m1 >= potential_licenses_e[k]) ||
828                 (m0 <= potential_licenses_s[k] && m1 > potential_licenses_e[k])) {
829               potential_licenses_s[k] = -1;
830               potential_licenses_e[k] = -1;
831             }
832           }
833         }
834       }
835       iter = iter->next;
836     }
837
838     // Create the list of licenses from potential licenses.
839     for (i = 0; i < license_map_length; i++) {
840       if (potential_licenses_s[i] > -1) {
841         int overridden = 0;
842         OVERRIDE_LICENSE(LIC_GPL, LIC_GPL3);
843         OVERRIDE_LICENSE(LIC_GPL, LIC_GPL3_OR_LATER);
844         OVERRIDE_LICENSE(LIC_GPL3, LIC_GPL3_OR_LATER);
845         OVERRIDE_LICENSE(LIC_BSD_2CLAUSE_ISH, LIC_BSD_ISH);
846         if (!overridden) {
847           if (list->head == NULL) { // empty list
848             list->head = list;
849             list->tail = list;
850             list->head->lic = &license_map[i];
851             list->next = NULL;
852           } else {
853             LicenseList *item = ohcount_license_list_new();
854             item->lic = &license_map[i];
855             list->tail->next = item;
856             list->tail = item;
857           }
858         }
859       }
860     }
861   }
862
863   return list;
864 }
865
866 LicenseList *ohcount_license_list_new() {
867   LicenseList *list = malloc(sizeof(LicenseList));
868   list->lic = NULL;
869   list->next = NULL;
870   list->head = NULL;
871   list->tail = NULL;
872   return list;
873 }
874
875 void ohcount_license_list_free(LicenseList *list) {
876   if (list->head) {
877     LicenseList *iter = list->head;
878     while (iter) {
879       LicenseList *next = iter->next;
880       free(iter);
881       iter = next;
882     }
883   } else free(list);
884 }