|  | ''' | 
|  | Copyright 2011 Google Inc. | 
|  |  | 
|  | Use of this source code is governed by a BSD-style license that can be | 
|  | found in the LICENSE file. | 
|  | ''' | 
|  |  | 
|  | import datetime | 
|  | import re | 
|  |  | 
|  | def CreateParser(filepath): | 
|  | """Returns a Parser as appropriate for the file at this filepath. | 
|  | """ | 
|  | if (filepath.endswith('.cpp') or | 
|  | filepath.endswith('.h') or | 
|  | filepath.endswith('.c')): | 
|  | return CParser() | 
|  | else: | 
|  | return None | 
|  |  | 
|  |  | 
|  | class Parser(object): | 
|  | """Base class for all language-specific parsers. | 
|  | """ | 
|  |  | 
|  | def __init__(self): | 
|  | self._copyright_pattern = re.compile('copyright', re.IGNORECASE) | 
|  | self._attribute_pattern = re.compile( | 
|  | 'copyright.*\D(\d{4})\W*(\w.*[\w.])', re.IGNORECASE) | 
|  |  | 
|  | def FindCopyrightBlock(self, comment_blocks): | 
|  | """Given a list of comment block strings, return the one that seems | 
|  | like the most likely copyright block. | 
|  |  | 
|  | Returns None if comment_blocks was empty, or if we couldn't find | 
|  | a comment block that contains copyright info.""" | 
|  | if not comment_blocks: | 
|  | return None | 
|  | for block in comment_blocks: | 
|  | if self._copyright_pattern.search(block): | 
|  | return block | 
|  |  | 
|  | def GetCopyrightBlockAttributes(self, comment_block): | 
|  | """Given a comment block, return a tuple of attributes: (year, holder). | 
|  |  | 
|  | If comment_block is None, or none of the attributes are found, | 
|  | this will return (None, None).""" | 
|  | if not comment_block: | 
|  | return (None, None) | 
|  | matches = self._attribute_pattern.findall(comment_block) | 
|  | if not matches: | 
|  | return (None, None) | 
|  | first_match = matches[0] | 
|  | return (first_match[0], first_match[1]) | 
|  |  | 
|  |  | 
|  | class CParser(Parser): | 
|  | """Parser that knows how to parse C/C++ files. | 
|  | """ | 
|  |  | 
|  | DEFAULT_YEAR = datetime.date.today().year | 
|  | DEFAULT_HOLDER = 'Google Inc.' | 
|  | COPYRIGHT_BLOCK_FORMAT = ''' | 
|  | /* | 
|  | * Copyright %s %s | 
|  | * | 
|  | * Use of this source code is governed by a BSD-style license that can be | 
|  | * found in the LICENSE file. | 
|  | */ | 
|  | ''' | 
|  |  | 
|  | def __init__(self): | 
|  | super(CParser, self).__init__() | 
|  | self._comment_pattern = re.compile('/\*.*?\*/', re.DOTALL) | 
|  |  | 
|  | def FindAllCommentBlocks(self, file_contents): | 
|  | """Returns a list of all comment blocks within these file contents. | 
|  | """ | 
|  | return self._comment_pattern.findall(file_contents) | 
|  |  | 
|  | def CreateCopyrightBlock(self, year, holder): | 
|  | """Returns a copyright block suitable for this language, with the | 
|  | given attributes. | 
|  |  | 
|  | @param year year in which to hold copyright (defaults to DEFAULT_YEAR) | 
|  | @param holder holder of copyright (defaults to DEFAULT_HOLDER) | 
|  | """ | 
|  | if not year: | 
|  | year = self.DEFAULT_YEAR | 
|  | if not holder: | 
|  | holder = self.DEFAULT_HOLDER | 
|  | return self.COPYRIGHT_BLOCK_FORMAT % (year, holder) |