|
#!/usr/bin/python |
|
# Run with directory arguments from any directory, with no special setup required. |
|
# Or: |
|
# for i in libc libdl libm linker libstdc++ ; do ./libc/tools/generate-NOTICE.py $i > $i/NOTICE ; done |
|
|
|
import ftplib |
|
import hashlib |
|
import os |
|
import re |
|
import shutil |
|
import string |
|
import subprocess |
|
import sys |
|
import tarfile |
|
import tempfile |
|
|
|
def IsUninteresting(path): |
|
path = path.lower() |
|
if path.endswith(".mk") or path.endswith(".py") or path.endswith(".pyc") or path.endswith(".txt") or path.endswith(".3"): |
|
return True |
|
if path.endswith("/notice") or path.endswith("/readme") or path.endswith("/caveats"): |
|
return True |
|
if path.endswith("/tzdata") or path.endswith("/zoneinfo/generate"): |
|
return True |
|
return False |
|
|
|
def IsAutoGenerated(content): |
|
if "Generated by gensyscalls.py" in content or "generated by genserv.py" in content: |
|
return True |
|
if "This header was automatically generated from a Linux kernel header" in content: |
|
return True |
|
return False |
|
|
|
copyrights = set() |
|
|
|
def ExtractCopyrightAt(lines, i): |
|
hash = lines[i].startswith("#") |
|
|
|
# Do we need to back up to find the start of the copyright header? |
|
start = i |
|
if not hash: |
|
while start > 0: |
|
if "/*" in lines[start - 1]: |
|
break |
|
start -= 1 |
|
|
|
# Read comment lines until we hit something that terminates a |
|
# copyright header. |
|
while i < len(lines): |
|
if "*/" in lines[i]: |
|
break |
|
if hash and len(lines[i]) == 0: |
|
break |
|
if "\t@(#)" in lines[i] or "\tfrom: @(#)" in lines[i] or "From: @(#)" in lines[i] or "from OpenBSD:" in lines[i]: |
|
break |
|
if "\tcitrus Id: " in lines[i]: |
|
break |
|
if "\t$Citrus: " in lines[i] or "\t$OpenBSD: " in lines[i] or " $FreeBSD: " in lines[i] or "\t$NetBSD: " in lines[i]: |
|
break |
|
if "$FreeBSD$" in lines[i] or "$Citrus$" in lines[i]: |
|
break |
|
# OpenBSD likes to say where stuff originally came from: |
|
if "Original version ID:" in lines[i]: |
|
break |
|
i += 1 |
|
|
|
end = i |
|
|
|
# Trim trailing cruft. |
|
while end > 0: |
|
if lines[end - 1] != " *" and lines[end - 1] != " * ====================================================": |
|
break |
|
end -= 1 |
|
|
|
# Remove C/assembler comment formatting, pulling out just the text. |
|
clean_lines = [] |
|
for line in lines[start:end]: |
|
line = line.replace("\t", " ") |
|
line = line.replace("/* ", "") |
|
line = re.sub("^ \* ", "", line) |
|
line = line.replace("** ", "") |
|
line = line.replace("# ", "") |
|
if line.startswith("++Copyright++"): |
|
continue |
|
line = line.replace("--Copyright--", "") |
|
line = line.rstrip() |
|
# These come last and take care of "blank" comment lines. |
|
if line == "#" or line == " *" or line == "**" or line == "-": |
|
line = "" |
|
clean_lines.append(line) |
|
|
|
# Trim blank lines from head and tail. |
|
while clean_lines[0] == "": |
|
clean_lines = clean_lines[1:] |
|
while clean_lines[len(clean_lines) - 1] == "": |
|
clean_lines = clean_lines[0:(len(clean_lines) - 1)] |
|
|
|
copyright = "\n".join(clean_lines) |
|
copyrights.add(copyright) |
|
|
|
return i |
|
|
|
args = sys.argv[1:] |
|
if len(args) == 0: |
|
args = [ "." ] |
|
|
|
for arg in args: |
|
sys.stderr.write('Searching for source files in "%s"...\n' % arg) |
|
|
|
for directory, sub_directories, filenames in os.walk(arg): |
|
if ".git" in sub_directories: |
|
sub_directories.remove(".git") |
|
sub_directories = sorted(sub_directories) |
|
|
|
for filename in sorted(filenames): |
|
path = os.path.join(directory, filename) |
|
if IsUninteresting(path): |
|
#print "ignoring uninteresting file %s" % path |
|
continue |
|
|
|
try: |
|
content = open(path, 'r').read().decode('utf-8') |
|
except: |
|
sys.stderr.write('warning: bad UTF-8 in %s\n' % path) |
|
content = open(path, 'r').read().decode('iso-8859-1') |
|
|
|
lines = content.split("\n") |
|
|
|
if len(lines) <= 4: |
|
#print "ignoring short file %s" % path |
|
continue |
|
|
|
if IsAutoGenerated(content): |
|
#print "ignoring auto-generated file %s" % path |
|
continue |
|
|
|
if not "Copyright" in content: |
|
if "public domain" in content.lower(): |
|
#print "ignoring public domain file %s" % path |
|
continue |
|
sys.stderr.write('warning: no copyright notice found in "%s" (%d lines)\n' % (path, len(lines))) |
|
continue |
|
|
|
i = 0 |
|
while i < len(lines): |
|
if "Copyright" in lines[i] and not "@(#) Copyright" in lines[i]: |
|
i = ExtractCopyrightAt(lines, i) |
|
i += 1 |
|
|
|
#print path |
|
|
|
for copyright in sorted(copyrights): |
|
print copyright.encode('utf-8') |
|
print |
|
print '-------------------------------------------------------------------' |
|
print |
|
|
|
sys.exit(0) |