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