Repository navigation
Expand file tree
/
Copy pathmulti_line_checks.py
More file actions
155 lines (129 loc) · 6.06 KB
/
Copy pathmulti_line_checks.py
File metadata and controls
155 lines (129 loc) · 6.06 KB
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
from cpplint import GetPreviousNonBlankLine
from style_grader_classes import DataStructureTracker
from style_grader_functions import check_if_function, check_if_function_prototype, indent_helper, check_if_struct_or_class, check_if_cout_block
import re
def check_statements_per_line(self, clean_lines):
cleansed_line = clean_lines.lines[self.current_line_num]
# This code is taken directly from cpplint lines 3430-3440
if (cleansed_line.count(';') > 1 and
# for loops are allowed two ;'s (and may run over two lines).
cleansed_line.find('for') == -1 and
(GetPreviousNonBlankLine(clean_lines, self.current_line_num)[0].find('for') == -1 or
GetPreviousNonBlankLine(clean_lines, self.current_line_num)[0].find(';') != -1) and
# It's ok to have many commands in a switch case that fits in 1 line
not ((cleansed_line.find('case ') != -1 or
cleansed_line.find('default:') != -1) and
cleansed_line.find('break;') != -1)):
self.add_error(label="STATEMENTS_PER_LINE")
def check_brace_consistency(self, clean_lines):
code = clean_lines.lines[self.current_line_num]
stripped_code = code.strip()
function = check_if_function(code)
if_statement = re.search(r'^if\s*\(\s*', stripped_code)
else_if_statement = re.search(r'^else\s*\(', code)
else_statement = re.search(r'^else\s+', code)
switch_statement = re.search(r'^switch\s*\(', stripped_code)
indentation = re.search(r'^( *)\S', code)
if indentation:
indentation = indentation.group()
indentation_size = len(indentation) - len(indentation.strip())
else:
indentation_size = 0
current = self.current_line_num
if function or if_statement or else_statement or switch_statement:
try:
if function or \
else_if_statement or\
else_statement or\
switch_statement or\
if_statement:
if deep_egyptian_check(clean_lines.lines, indentation_size, current):
self.egyptian = True
else:
self.not_egyptian = True
elif not self.outside_main:
if not self.braces_error:
self.add_error(label="BRACE_CONSISTENCY")
self.braces_error = True
if self.not_egyptian and self.egyptian and not self.braces_error:
self.add_error(label="BRACE_CONSISTENCY")
self.braces_error = True
#if both of these are true, they are not consistent, therefore error.
if self.not_egyptian:
if self.egyptian and not self.braces_error:
self.add_error(label="BRACE_CONSISTENCY")
self.braces_error = True
except IndexError:
# cannot access next line of end of file, rubric properties don't matter
return
def check_block_indentation(self, clean_lines):
#TODO: Load from config file?
tab_size = 4
code = clean_lines.lines[self.current_line_num]
print code
if check_if_struct_or_class(code):
self.global_in_object = True
if self.global_in_object and code.find('{') != -1:
self.add_global_brace('{')
elif self.global_in_object and code.find('}') != -1:
self.pop_global_brace()
function = check_if_function(code)
prototype = check_if_function_prototype(code)
struct_or_class = check_if_struct_or_class(code)
indentation = re.search(r'^( *)\S', code)
if indentation:
indentation = indentation.group()
indentation_size = len(indentation) - len(indentation.strip())
else:
return
if function and indentation_size != 0 and not self.global_in_object and code.find('else if') == -1:
data = {'expected': 0, 'found': indentation_size}
self.add_error(label="BLOCK_INDENTATION", data=data)
if function and not prototype:
self.current_line_num = find_function_end(clean_lines.lines, self.current_line_num)
if (function and not self.outside_main) or struct_or_class:
#if not egyptian style
if code.find('{') == -1:
if code.find('{'):
temp_line_num = self.current_line_num + 1
data_structure_tracker = DataStructureTracker()
data_structure_tracker.brace_stack.append('{')
if check_if_struct_or_class(code):
data_structure_tracker.in_class_or_struct = True
if self.global_in_object:
self.add_global_brace('{')
data_structure_tracker.add_object_brace('{')
results = indent_helper(indentation, tab_size, clean_lines,
data_structure_tracker, temp_line_num)
for error in results:
self.add_error(**error)
else:
#TODO Figure out what it means to not have braces in the right place
pass
else:
temp_line_num = self.current_line_num
data_structure_tracker = DataStructureTracker()
if check_if_struct_or_class(code):
data_structure_tracker.add_object_brace("{")
data_structure_tracker.in_class_or_struct = True
data_structure_tracker.brace_stack.append('{')
results = indent_helper(indentation, tab_size, clean_lines,
data_structure_tracker, temp_line_num)
for error in results:
self.add_error(**error)
else:
return
def find_function_end(code, current_line):
while code[current_line] and code[current_line].find('{') == -1:
current_line += 1
if len(code[current_line].strip()) == 1:
current_line -= 1
return current_line
def deep_egyptian_check(code, indentation_size, current_line):
while code[current_line].find('{') == -1:
current_line += 1
indent = code[current_line].find('{')
if code[current_line].find('{') != indentation_size:
return True
else:
return False