1*c8dee2aaSAndroid Build Coastguard Worker''' 2*c8dee2aaSAndroid Build Coastguard WorkerCopyright 2011 Google Inc. 3*c8dee2aaSAndroid Build Coastguard Worker 4*c8dee2aaSAndroid Build Coastguard WorkerUse of this source code is governed by a BSD-style license that can be 5*c8dee2aaSAndroid Build Coastguard Workerfound in the LICENSE file. 6*c8dee2aaSAndroid Build Coastguard Worker''' 7*c8dee2aaSAndroid Build Coastguard Worker 8*c8dee2aaSAndroid Build Coastguard Workerimport datetime 9*c8dee2aaSAndroid Build Coastguard Workerimport re 10*c8dee2aaSAndroid Build Coastguard Worker 11*c8dee2aaSAndroid Build Coastguard Workerdef CreateParser(filepath): 12*c8dee2aaSAndroid Build Coastguard Worker """Returns a Parser as appropriate for the file at this filepath. 13*c8dee2aaSAndroid Build Coastguard Worker """ 14*c8dee2aaSAndroid Build Coastguard Worker if (filepath.endswith('.cpp') or 15*c8dee2aaSAndroid Build Coastguard Worker filepath.endswith('.h') or 16*c8dee2aaSAndroid Build Coastguard Worker filepath.endswith('.c')): 17*c8dee2aaSAndroid Build Coastguard Worker return CParser() 18*c8dee2aaSAndroid Build Coastguard Worker else: 19*c8dee2aaSAndroid Build Coastguard Worker return None 20*c8dee2aaSAndroid Build Coastguard Worker 21*c8dee2aaSAndroid Build Coastguard Worker 22*c8dee2aaSAndroid Build Coastguard Workerclass Parser(object): 23*c8dee2aaSAndroid Build Coastguard Worker """Base class for all language-specific parsers. 24*c8dee2aaSAndroid Build Coastguard Worker """ 25*c8dee2aaSAndroid Build Coastguard Worker 26*c8dee2aaSAndroid Build Coastguard Worker def __init__(self): 27*c8dee2aaSAndroid Build Coastguard Worker self._copyright_pattern = re.compile('copyright', re.IGNORECASE) 28*c8dee2aaSAndroid Build Coastguard Worker self._attribute_pattern = re.compile( 29*c8dee2aaSAndroid Build Coastguard Worker 'copyright.*\D(\d{4})\W*(\w.*[\w.])', re.IGNORECASE) 30*c8dee2aaSAndroid Build Coastguard Worker 31*c8dee2aaSAndroid Build Coastguard Worker def FindCopyrightBlock(self, comment_blocks): 32*c8dee2aaSAndroid Build Coastguard Worker """Given a list of comment block strings, return the one that seems 33*c8dee2aaSAndroid Build Coastguard Worker like the most likely copyright block. 34*c8dee2aaSAndroid Build Coastguard Worker 35*c8dee2aaSAndroid Build Coastguard Worker Returns None if comment_blocks was empty, or if we couldn't find 36*c8dee2aaSAndroid Build Coastguard Worker a comment block that contains copyright info.""" 37*c8dee2aaSAndroid Build Coastguard Worker if not comment_blocks: 38*c8dee2aaSAndroid Build Coastguard Worker return None 39*c8dee2aaSAndroid Build Coastguard Worker for block in comment_blocks: 40*c8dee2aaSAndroid Build Coastguard Worker if self._copyright_pattern.search(block): 41*c8dee2aaSAndroid Build Coastguard Worker return block 42*c8dee2aaSAndroid Build Coastguard Worker 43*c8dee2aaSAndroid Build Coastguard Worker def GetCopyrightBlockAttributes(self, comment_block): 44*c8dee2aaSAndroid Build Coastguard Worker """Given a comment block, return a tuple of attributes: (year, holder). 45*c8dee2aaSAndroid Build Coastguard Worker 46*c8dee2aaSAndroid Build Coastguard Worker If comment_block is None, or none of the attributes are found, 47*c8dee2aaSAndroid Build Coastguard Worker this will return (None, None).""" 48*c8dee2aaSAndroid Build Coastguard Worker if not comment_block: 49*c8dee2aaSAndroid Build Coastguard Worker return (None, None) 50*c8dee2aaSAndroid Build Coastguard Worker matches = self._attribute_pattern.findall(comment_block) 51*c8dee2aaSAndroid Build Coastguard Worker if not matches: 52*c8dee2aaSAndroid Build Coastguard Worker return (None, None) 53*c8dee2aaSAndroid Build Coastguard Worker first_match = matches[0] 54*c8dee2aaSAndroid Build Coastguard Worker return (first_match[0], first_match[1]) 55*c8dee2aaSAndroid Build Coastguard Worker 56*c8dee2aaSAndroid Build Coastguard Worker 57*c8dee2aaSAndroid Build Coastguard Workerclass CParser(Parser): 58*c8dee2aaSAndroid Build Coastguard Worker """Parser that knows how to parse C/C++ files. 59*c8dee2aaSAndroid Build Coastguard Worker """ 60*c8dee2aaSAndroid Build Coastguard Worker 61*c8dee2aaSAndroid Build Coastguard Worker DEFAULT_YEAR = datetime.date.today().year 62*c8dee2aaSAndroid Build Coastguard Worker DEFAULT_HOLDER = 'Google Inc.' 63*c8dee2aaSAndroid Build Coastguard Worker COPYRIGHT_BLOCK_FORMAT = ''' 64*c8dee2aaSAndroid Build Coastguard Worker/* 65*c8dee2aaSAndroid Build Coastguard Worker * Copyright %s %s 66*c8dee2aaSAndroid Build Coastguard Worker * 67*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be 68*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file. 69*c8dee2aaSAndroid Build Coastguard Worker */ 70*c8dee2aaSAndroid Build Coastguard Worker''' 71*c8dee2aaSAndroid Build Coastguard Worker 72*c8dee2aaSAndroid Build Coastguard Worker def __init__(self): 73*c8dee2aaSAndroid Build Coastguard Worker super(CParser, self).__init__() 74*c8dee2aaSAndroid Build Coastguard Worker self._comment_pattern = re.compile('/\*.*?\*/', re.DOTALL) 75*c8dee2aaSAndroid Build Coastguard Worker 76*c8dee2aaSAndroid Build Coastguard Worker def FindAllCommentBlocks(self, file_contents): 77*c8dee2aaSAndroid Build Coastguard Worker """Returns a list of all comment blocks within these file contents. 78*c8dee2aaSAndroid Build Coastguard Worker """ 79*c8dee2aaSAndroid Build Coastguard Worker return self._comment_pattern.findall(file_contents) 80*c8dee2aaSAndroid Build Coastguard Worker 81*c8dee2aaSAndroid Build Coastguard Worker def CreateCopyrightBlock(self, year, holder): 82*c8dee2aaSAndroid Build Coastguard Worker """Returns a copyright block suitable for this language, with the 83*c8dee2aaSAndroid Build Coastguard Worker given attributes. 84*c8dee2aaSAndroid Build Coastguard Worker 85*c8dee2aaSAndroid Build Coastguard Worker @param year year in which to hold copyright (defaults to DEFAULT_YEAR) 86*c8dee2aaSAndroid Build Coastguard Worker @param holder holder of copyright (defaults to DEFAULT_HOLDER) 87*c8dee2aaSAndroid Build Coastguard Worker """ 88*c8dee2aaSAndroid Build Coastguard Worker if not year: 89*c8dee2aaSAndroid Build Coastguard Worker year = self.DEFAULT_YEAR 90*c8dee2aaSAndroid Build Coastguard Worker if not holder: 91*c8dee2aaSAndroid Build Coastguard Worker holder = self.DEFAULT_HOLDER 92*c8dee2aaSAndroid Build Coastguard Worker return self.COPYRIGHT_BLOCK_FORMAT % (year, holder) 93