Skip to content
This repository was archived by the owner on Apr 24, 2022. It is now read-only.

Commit bfd3791

Browse files
committedSep 3, 2018
Travis: Introduce code format check.
1 parent 7ee708a commit bfd3791

File tree

2 files changed

+203
-1
lines changed

2 files changed

+203
-1
lines changed
 

‎.travis.yml

+7-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,13 @@ matrix:
2323
cache:
2424
directories:
2525
- $HOME/.local
26-
before_install: |
26+
before_install:
27+
- |
28+
if [ "$TRAVIS_OS_NAME" = linux ]; then
29+
echo "Checking format of sourcecode..."
30+
find . -type f -name '*.cpp' -print0 -name '*.h' -print0 | xargs -r0 ./scripts/check_code_format.py --all
31+
fi
32+
- |
2733
if [ "$TRAVIS_OS_NAME" = linux ]; then
2834
sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
2935
sudo apt-get -q update

‎scripts/check_code_format.py

+196
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
#! /usr/bin/env python
2+
## vim:set ts=4 sw=4 et: -*- coding: utf-8 -*-
3+
#
4+
#
5+
# Find all the whitespace format issues in the source
6+
# 1.) No trailing whitespace
7+
# 2.) No tab indentation
8+
# 3.) No CR/LF or CR lineendings
9+
#
10+
# sample run:
11+
# find .. -type f -name '*.cpp' -print0 -name '*.h' -print0 | xargs -r0 ./check_code_format.py
12+
13+
import getopt, os, re, sys
14+
15+
class opts:
16+
verbose = 1
17+
recursive = False
18+
warn = False
19+
display_all = False # if true, display all lines with tab indent and trailing whitespace
20+
21+
22+
class globs:
23+
whitespace_on_line_end = re.compile("[ \t\f\v][\r\n]")
24+
tab_indent = re.compile("^\t", re.MULTILINE)
25+
crlf_lineend = re.compile("\r\n") # windows
26+
cr_lineend = re.compile("\r") # classicc MAC
27+
binary = re.compile("[\x00\x01\x02\xfe\xff]") # some binary
28+
29+
30+
# try to find a correct linenumber - even if lines are CR/LF, CR or LF terminated
31+
def determine_linenumber(data, pos):
32+
lineend = "\n"
33+
34+
crlf = data.find("\r\n")
35+
if crlf != -1:
36+
lineend = "\r\n"
37+
else:
38+
cr = data.find("\r")
39+
if cr != -1:
40+
lineend = "\r"
41+
42+
line = 1
43+
p = 0
44+
while True:
45+
p = data.find(lineend, p)
46+
if p == -1:
47+
return line
48+
if p >= pos:
49+
return line
50+
line += 1
51+
p += len(lineend)
52+
53+
54+
def print_error(filename, data, match_objects, errormessage):
55+
linenumbers = []
56+
#print match_objects, type(match_objects)
57+
for match in match_objects:
58+
linenumbers.append("%d" % determine_linenumber(data, match.start()))
59+
if not linenumbers:
60+
return
61+
if opts.warn:
62+
m = "Warning:"
63+
else:
64+
m = "Error:"
65+
print m, filename, errormessage + " (line %s)" % ",".join(linenumbers)
66+
# we could make an early exit here
67+
68+
69+
def do_one_file(filename):
70+
r = 0
71+
if opts.verbose >= 3:
72+
print "checking", filename
73+
74+
fp = open(filename, "rb")
75+
data = fp.read()
76+
fp.close()
77+
78+
if globs.binary.search(data):
79+
if opts.verbose >= 2:
80+
print filename, " is a binary"
81+
return r
82+
83+
# check for unix line endings (just \n)
84+
crlf = globs.crlf_lineend.search(data)
85+
cr = globs.cr_lineend.search(data)
86+
if crlf or cr:
87+
r = 1
88+
if crlf and cr:
89+
if crlf.start() <= cr.start():
90+
cr = None
91+
else:
92+
crlf = None
93+
if crlf:
94+
if opts.verbose > 0:
95+
print_error(filename, data, [crlf], "contains CR/LF linefeed")
96+
else:
97+
if opts.verbose > 0:
98+
print_error(filename, data, [cr], "contains CR linefeed")
99+
100+
# TAB as indent
101+
if opts.display_all:
102+
tab_indent = globs.tab_indent.finditer(data)
103+
else:
104+
tab_indent = globs.tab_indent.search(data)
105+
if tab_indent:
106+
tab_indent = [tab_indent]
107+
if tab_indent:
108+
r = 1
109+
if opts.verbose > 0:
110+
print_error(filename, data, tab_indent, "contains tab indent")
111+
112+
# Whitespace before lineendings
113+
if opts.display_all:
114+
whitespace_on_line_end = globs.whitespace_on_line_end.finditer(data)
115+
else:
116+
whitespace_on_line_end = globs.whitespace_on_line_end.search(data)
117+
if whitespace_on_line_end:
118+
whitespace_on_line_end = [whitespace_on_line_end]
119+
if whitespace_on_line_end:
120+
if filename.endswith(".md"):
121+
pass # currently skip .md files
122+
else:
123+
r = 1
124+
if opts.verbose > 0:
125+
print_error(filename, data, whitespace_on_line_end, "contains whitespaces at the line end")
126+
127+
return r
128+
129+
130+
def do_one_directory(directory):
131+
r = 0
132+
133+
for root, dirs, files in os.walk(directory, topdown=True):
134+
for name in files:
135+
#print(os.path.join(root, name))
136+
if do_one_file(os.path.join(root, name)):
137+
r = 1
138+
if not opts.recursive:
139+
break
140+
return r
141+
142+
143+
def display_usage(argv):
144+
print "USAGE: %s [options] files/directories" % os.path.basename(argv[0])
145+
print " -v, --verbose increase logging level"
146+
print " -q, --quiet decrease logging level"
147+
print " -h, --help display this page"
148+
print
149+
print " -a, --all display all lines with tab indent and trailing whitespace"
150+
print " -r, --recursive if given a directory check all recursive"
151+
print " -w, --warn just warn, don't exit with an error"
152+
153+
154+
def main(argv):
155+
try: assert 0
156+
except AssertionError: pass
157+
else: raise Exception("fatal error - assertions not enabled")
158+
shortopts, longopts = "hqvarw", [
159+
"help", "quiet","verbose",
160+
"all", "recusrive", "warn",
161+
]
162+
xopts, args = getopt.gnu_getopt(argv[1:], shortopts, longopts)
163+
for opt, optarg in xopts:
164+
if opt in ["-q", "--quiet"]:
165+
opts.verbose = opts.verbose - 1
166+
elif opt in ["-v", "--verbose"]:
167+
opts.verbose = opts.verbose + 1
168+
elif opt in ["-h", "--help"]:
169+
display_usage(argv)
170+
return 0
171+
elif opt in ["-a", "--all"]:
172+
opts.display_all = True
173+
elif opt in ["-r", "--recursive"]:
174+
opts.recursive = True
175+
elif opt in ["-w", "--warn"]:
176+
opts.warn = True
177+
178+
if not args:
179+
r = do_one_directory(".")
180+
else:
181+
r = 0
182+
for arg in args:
183+
if os.path.isdir(arg):
184+
if do_one_directory(arg):
185+
r = 1
186+
else:
187+
if do_one_file(arg):
188+
r = 1
189+
190+
if opts.warn:
191+
return 0
192+
return r
193+
194+
195+
if __name__ == "__main__":
196+
sys.exit(main(sys.argv))

0 commit comments

Comments
 (0)
This repository has been archived.