aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools/copyright/fileparser.py
blob: a4051e25b9a125e69c7209f95323874ad00e83d3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
'''
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)