blob: a4051e25b9a125e69c7209f95323874ad00e83d3 [file] [log] [blame]
epoger@google.com935d9452011-07-28 14:29:58 +00001'''
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)