File: simple_checks.py

package info (click to toggle)
seqan2 2.4.0%2Bdfsg-16
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 224,180 kB
  • sloc: cpp: 256,886; ansic: 91,672; python: 8,330; sh: 995; xml: 570; makefile: 252; awk: 51; javascript: 21
file content (117 lines) | stat: -rwxr-xr-x 4,109 bytes parent folder | download | duplicates (3)
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#!/usr/bin/env python3
"""Simple source code checks, e.g. trailing whitespace."""



import bisect
import re
import sys

from . import violations

RULE_TRAILING_WHITESPACE = 'whitespace.trailing'
RULE_TEXT_TRAILING_WHITESPACE = 'Trailing whitespace is not allowed.'
 
RULE_TODO_ONE_SPACE = 'whitespace.todo'
RULE_TEXT_TODO_ONE_SPACE= 'There should be exactly one space before TODO.'

RULE_TODO_USERNAME = 'readability.todo'
RULE_TEXT_TODO_USERNAME = 'TODO comments should look like this: "// TODO(username): Text".'

RULE_TODO_SPACE_AFTER = 'whitespace.todo'
RULE_TEXT_TODO_SPACE_AFTER = '"TODO (username):" should be followed by a space.'

RE_TODO = r'^//(\s*)TODO(\(.+?\))?:?(\s|$)?'

class WhitespaceChecker(object):
    """Performs simple white space checks."""

    # TODO(holtgrew): Do not allow tabs.

    def check(self, filename):
        vs = []
        with open(filename, 'rb') as f:
            line_no = 0
            for line in f:
                line_no += 1
                if line.rstrip() == line.rstrip('\r\n'):
                    continue
                v = violations.SimpleRuleViolation(
                    RULE_TRAILING_WHITESPACE, filename, line_no,
                    len(line.rstrip()) + 1, RULE_TEXT_TRAILING_WHITESPACE)
                vs.append(v)
        return dict([(v.key(), v) for v in vs])


class SourceFile(object):
    def __init__(self, name):
        self.name = name


class SourceLocation(object):
    def __init__(self, filename, line, column, offset):
        self.file = SourceFile(filename)
        self.line = line
        self.column = column
        self.offset = offset

    def __str__(self):
        return '%s:%d/%d (@%d)' % (self.file.name, self.line, self.column,
                                   self.offset)

    def __repr__(self):
        return str(self)


def enumerateComments(filename):
    # Read file.
    with open (filename, 'rb') as f:
        lines = f.readlines()
        fcontents = ''.join(lines)
    # Build line break index.
    line_starts = [0]
    for line in lines:
        line_starts.append(line_starts[-1] + len(line))
    #print line_starts
    # Search for all comments.
    pattern = re.compile(
        r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"',
        re.DOTALL | re.MULTILINE)
    for match in re.finditer(pattern, fcontents):
        line_start = bisect.bisect(line_starts, match.start(0))
        line_end = bisect.bisect(line_starts, match.end(0) - 1)
        column_start = match.start(0) - line_starts[line_start - 1]
        column_end = match.end(0) - line_starts[line_end - 1]
        yield (SourceLocation(filename, line_start, column_start + 1, match.start(0)),
               SourceLocation(filename, line_end, column_end + 1, match.end(0)),
               match.group(0))


class CommentChecker(object):
    """Performs the checks on comments."""

    def check(self, filename):
        vs = []
        for cstart, cend, comment in enumerateComments(filename):
            if comment.startswith('//'):
                # Check TODO comments.
                match = re.match(RE_TODO, comment)
                if match:
                    if len(match.group(1)) > 1:
                        print(comment)
                        v = violations.SimpleRuleViolation(
                            RULE_TODO_ONE_SPACE, filename, cstart.line,
                            cstart.column, RULE_TEXT_TODO_ONE_SPACE)
                        vs.append(v)
                    if not match.group(2):
                        v = violations.SimpleRuleViolation(
                            RULE_TODO_USERNAME, filename, cstart.line,
                            cstart.column, RULE_TEXT_TODO_USERNAME)
                        vs.append(v)
                    if match.group(3) != ' ' and match.group(3) != '':
                        v = violations.SimpleRuleViolation(
                            RULE_TODO_SPACE_AFTER, filename, cstart.line,
                            cstart.column, RULE_TEXT_TODO_SPACE_AFTER)
                        vs.append(v)
        return dict([(v.key(), v) for v in vs])