Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) #!/usr/bin/env python
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) # SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) # Copyright Thomas Gleixner <tglx@linutronix.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) from argparse import ArgumentParser
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) from ply import lex, yacc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) import locale
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) import traceback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) import sys
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) import git
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) import re
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) import os
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) class ParserException(Exception):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)     def __init__(self, tok, txt):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)         self.tok = tok
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)         self.txt = txt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) class SPDXException(Exception):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)     def __init__(self, el, txt):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)         self.el = el
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)         self.txt = txt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) class SPDXdata(object):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)     def __init__(self):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)         self.license_files = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)         self.exception_files = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)         self.licenses = [ ]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)         self.exceptions = { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) # Read the spdx data from the LICENSES directory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) def read_spdxdata(repo):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)     # The subdirectories of LICENSES in the kernel source
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)     # Note: exceptions needs to be parsed as last directory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)     license_dirs = [ "preferred", "dual", "deprecated", "exceptions" ]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)     lictree = repo.head.commit.tree['LICENSES']
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)     spdx = SPDXdata()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)     for d in license_dirs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42)         for el in lictree[d].traverse():
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43)             if not os.path.isfile(el.path):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44)                 continue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46)             exception = None
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47)             for l in open(el.path).readlines():
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48)                 if l.startswith('Valid-License-Identifier:'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49)                     lid = l.split(':')[1].strip().upper()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50)                     if lid in spdx.licenses:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51)                         raise SPDXException(el, 'Duplicate License Identifier: %s' %lid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52)                     else:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53)                         spdx.licenses.append(lid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)                 elif l.startswith('SPDX-Exception-Identifier:'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56)                     exception = l.split(':')[1].strip().upper()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57)                     spdx.exceptions[exception] = []
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59)                 elif l.startswith('SPDX-Licenses:'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60)                     for lic in l.split(':')[1].upper().strip().replace(' ', '').replace('\t', '').split(','):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61)                         if not lic in spdx.licenses:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62)                             raise SPDXException(None, 'Exception %s missing license %s' %(exception, lic))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63)                         spdx.exceptions[exception].append(lic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65)                 elif l.startswith("License-Text:"):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66)                     if exception:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67)                         if not len(spdx.exceptions[exception]):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68)                             raise SPDXException(el, 'Exception %s is missing SPDX-Licenses' %exception)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69)                         spdx.exception_files += 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70)                     else:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71)                         spdx.license_files += 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72)                     break
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73)     return spdx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) class id_parser(object):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77)     reserved = [ 'AND', 'OR', 'WITH' ]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78)     tokens = [ 'LPAR', 'RPAR', 'ID', 'EXC' ] + reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80)     precedence = ( ('nonassoc', 'AND', 'OR'), )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82)     t_ignore = ' \t'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84)     def __init__(self, spdx):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85)         self.spdx = spdx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86)         self.lasttok = None
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87)         self.lastid = None
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88)         self.lexer = lex.lex(module = self, reflags = re.UNICODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89)         # Initialize the parser. No debug file and no parser rules stored on disk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90)         # The rules are small enough to be generated on the fly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91)         self.parser = yacc.yacc(module = self, write_tables = False, debug = False)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92)         self.lines_checked = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93)         self.checked = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94)         self.spdx_valid = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95)         self.spdx_errors = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96)         self.curline = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97)         self.deepest = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99)     # Validate License and Exception IDs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)     def validate(self, tok):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)         id = tok.value.upper()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)         if tok.type == 'ID':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)             if not id in self.spdx.licenses:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)                 raise ParserException(tok, 'Invalid License ID')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)             self.lastid = id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)         elif tok.type == 'EXC':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)             if id not in self.spdx.exceptions:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)                 raise ParserException(tok, 'Invalid Exception ID')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)             if self.lastid not in self.spdx.exceptions[id]:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)                 raise ParserException(tok, 'Exception not valid for license %s' %self.lastid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)             self.lastid = None
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)         elif tok.type != 'WITH':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)             self.lastid = None
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)     # Lexer functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)     def t_RPAR(self, tok):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)         r'\)'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)         self.lasttok = tok.type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)         return tok
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)     def t_LPAR(self, tok):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)         r'\('
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)         self.lasttok = tok.type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)         return tok
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)     def t_ID(self, tok):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)         r'[A-Za-z.0-9\-+]+'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)         if self.lasttok == 'EXC':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)             print(tok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)             raise ParserException(tok, 'Missing parentheses')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)         tok.value = tok.value.strip()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)         val = tok.value.upper()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)         if val in self.reserved:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)             tok.type = val
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)         elif self.lasttok == 'WITH':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)             tok.type = 'EXC'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)         self.lasttok = tok.type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)         self.validate(tok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)         return tok
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)     def t_error(self, tok):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)         raise ParserException(tok, 'Invalid token')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)     def p_expr(self, p):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)         '''expr : ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)                 | ID WITH EXC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)                 | expr AND expr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)                 | expr OR expr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)                 | LPAR expr RPAR'''
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)         pass
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)     def p_error(self, p):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)         if not p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)             raise ParserException(None, 'Unfinished license expression')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)         else:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)             raise ParserException(p, 'Syntax error')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)     def parse(self, expr):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)         self.lasttok = None
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)         self.lastid = None
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)         self.parser.parse(expr, lexer = self.lexer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)     def parse_lines(self, fd, maxlines, fname):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)         self.checked += 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)         self.curline = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)         try:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)             for line in fd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)                 line = line.decode(locale.getpreferredencoding(False), errors='ignore')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)                 self.curline += 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)                 if self.curline > maxlines:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)                     break
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)                 self.lines_checked += 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)                 if line.find("SPDX-License-Identifier:") < 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)                     continue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)                 expr = line.split(':')[1].strip()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)                 # Remove trailing comment closure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)                 if line.strip().endswith('*/'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)                     expr = expr.rstrip('*/').strip()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)                 # Remove trailing xml comment closure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)                 if line.strip().endswith('-->'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)                     expr = expr.rstrip('-->').strip()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)                 # Special case for SH magic boot code files
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)                 if line.startswith('LIST \"'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)                     expr = expr.rstrip('\"').strip()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)                 self.parse(expr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)                 self.spdx_valid += 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)                 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)                 # Should we check for more SPDX ids in the same file and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)                 # complain if there are any?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)                 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)                 break
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)         except ParserException as pe:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)             if pe.tok:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)                 col = line.find(expr) + pe.tok.lexpos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)                 tok = pe.tok.value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)                 sys.stdout.write('%s: %d:%d %s: %s\n' %(fname, self.curline, col, pe.txt, tok))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)             else:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)                 sys.stdout.write('%s: %d:0 %s\n' %(fname, self.curline, col, pe.txt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)             self.spdx_errors += 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) def scan_git_tree(tree):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)     for el in tree.traverse():
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)         # Exclude stuff which would make pointless noise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)         # FIXME: Put this somewhere more sensible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)         if el.path.startswith("LICENSES"):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)             continue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)         if el.path.find("license-rules.rst") >= 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)             continue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)         if not os.path.isfile(el.path):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)             continue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)         with open(el.path, 'rb') as fd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)             parser.parse_lines(fd, args.maxlines, el.path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) def scan_git_subtree(tree, path):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)     for p in path.strip('/').split('/'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)         tree = tree[p]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)     scan_git_tree(tree)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if __name__ == '__main__':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)     ap = ArgumentParser(description='SPDX expression checker')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)     ap.add_argument('path', nargs='*', help='Check path or file. If not given full git tree scan. For stdin use "-"')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)     ap.add_argument('-m', '--maxlines', type=int, default=15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)                     help='Maximum number of lines to scan in a file. Default 15')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)     ap.add_argument('-v', '--verbose', action='store_true', help='Verbose statistics output')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)     args = ap.parse_args()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)     # Sanity check path arguments
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)     if '-' in args.path and len(args.path) > 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)         sys.stderr.write('stdin input "-" must be the only path argument\n')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)         sys.exit(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)     try:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)         # Use git to get the valid license expressions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)         repo = git.Repo(os.getcwd())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)         assert not repo.bare
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)         # Initialize SPDX data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)         spdx = read_spdxdata(repo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)         # Initilize the parser
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)         parser = id_parser(spdx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)     except SPDXException as se:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)         if se.el:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)             sys.stderr.write('%s: %s\n' %(se.el.path, se.txt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)         else:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)             sys.stderr.write('%s\n' %se.txt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)         sys.exit(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)     except Exception as ex:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)         sys.stderr.write('FAIL: %s\n' %ex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)         sys.stderr.write('%s\n' %traceback.format_exc())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)         sys.exit(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)     try:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)         if len(args.path) and args.path[0] == '-':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)             stdin = os.fdopen(sys.stdin.fileno(), 'rb')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)             parser.parse_lines(stdin, args.maxlines, '-')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)         else:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)             if args.path:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)                 for p in args.path:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)                     if os.path.isfile(p):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)                         parser.parse_lines(open(p, 'rb'), args.maxlines, p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)                     elif os.path.isdir(p):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)                         scan_git_subtree(repo.head.reference.commit.tree, p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)                     else:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)                         sys.stderr.write('path %s does not exist\n' %p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)                         sys.exit(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)             else:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)                 # Full git tree scan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)                 scan_git_tree(repo.head.commit.tree)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)             if args.verbose:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)                 sys.stderr.write('\n')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)                 sys.stderr.write('License files:     %12d\n' %spdx.license_files)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)                 sys.stderr.write('Exception files:   %12d\n' %spdx.exception_files)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)                 sys.stderr.write('License IDs        %12d\n' %len(spdx.licenses))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)                 sys.stderr.write('Exception IDs      %12d\n' %len(spdx.exceptions))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)                 sys.stderr.write('\n')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)                 sys.stderr.write('Files checked:     %12d\n' %parser.checked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)                 sys.stderr.write('Lines checked:     %12d\n' %parser.lines_checked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)                 sys.stderr.write('Files with SPDX:   %12d\n' %parser.spdx_valid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)                 sys.stderr.write('Files with errors: %12d\n' %parser.spdx_errors)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)             sys.exit(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)     except Exception as ex:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)         sys.stderr.write('FAIL: %s\n' %ex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)         sys.stderr.write('%s\n' %traceback.format_exc())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)         sys.exit(1)